notes
This commit is contained in:
@@ -3,7 +3,15 @@
|
|||||||
# to 'bootstrap' the system.
|
# to 'bootstrap' the system.
|
||||||
|
|
||||||
# Install DSC
|
# Install DSC
|
||||||
winget install DesiredStateConfiguration
|
# https://learn.microsoft.com/en-us/powershell/dsc/overview?view=dsc-3.0&preserveView=true#install-dsc-on-windows-with-winget
|
||||||
|
|
||||||
|
# winget search DesiredStateConfiguration --source msstore
|
||||||
|
# Name Id Version Source
|
||||||
|
# ---------------------------------------------------------------
|
||||||
|
# DesiredStateConfiguration 9NVTPZWRC6KQ Unknown msstore
|
||||||
|
# DesiredStateConfiguration-Preview 9PCX3HX4HZ0Z Unknown msstore
|
||||||
|
|
||||||
|
winget install --id 9NVTPZWRC6KQ --source msstore
|
||||||
# Install Bun
|
# Install Bun
|
||||||
# TODO: Do we want the scripted install or the winget install?
|
# TODO: Do we want the scripted install or the winget install?
|
||||||
winget install -e --id Oven-sh.Bun
|
winget install -e --id Oven-sh.Bun
|
||||||
|
|||||||
17
bun.lock
17
bun.lock
@@ -14,7 +14,6 @@
|
|||||||
"@biomejs/biome": "2.3.8",
|
"@biomejs/biome": "2.3.8",
|
||||||
"@effect/language-service": "^0.57.1",
|
"@effect/language-service": "^0.57.1",
|
||||||
"@types/bun": "latest",
|
"@types/bun": "latest",
|
||||||
"@typescript/native-preview": "^7.0.0-dev.20251130.1",
|
|
||||||
"quicktype": "^23.2.6",
|
"quicktype": "^23.2.6",
|
||||||
"turbo": "^2.6.1",
|
"turbo": "^2.6.1",
|
||||||
"typescript": "^5.9.3",
|
"typescript": "^5.9.3",
|
||||||
@@ -145,22 +144,6 @@
|
|||||||
|
|
||||||
"@types/node": ["@types/node@24.10.1", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-GNWcUTRBgIRJD5zj+Tq0fKOJ5XZajIiBroOF0yvj2bSU1WvNdYS/dn9UxwsujGW4JX06dnHyjV2y9rRaybH0iQ=="],
|
"@types/node": ["@types/node@24.10.1", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-GNWcUTRBgIRJD5zj+Tq0fKOJ5XZajIiBroOF0yvj2bSU1WvNdYS/dn9UxwsujGW4JX06dnHyjV2y9rRaybH0iQ=="],
|
||||||
|
|
||||||
"@typescript/native-preview": ["@typescript/native-preview@7.0.0-dev.20251130.1", "", { "optionalDependencies": { "@typescript/native-preview-darwin-arm64": "7.0.0-dev.20251130.1", "@typescript/native-preview-darwin-x64": "7.0.0-dev.20251130.1", "@typescript/native-preview-linux-arm": "7.0.0-dev.20251130.1", "@typescript/native-preview-linux-arm64": "7.0.0-dev.20251130.1", "@typescript/native-preview-linux-x64": "7.0.0-dev.20251130.1", "@typescript/native-preview-win32-arm64": "7.0.0-dev.20251130.1", "@typescript/native-preview-win32-x64": "7.0.0-dev.20251130.1" }, "bin": { "tsgo": "bin/tsgo.js" } }, "sha512-0DcbBJM5xMvbUWl5ZNprFno6ZlGmkI1RHN4hW1jJza7D5Um0kSs4CU0fx2Z4uNxhY7a37Y6px5LkM3WF6gePQg=="],
|
|
||||||
|
|
||||||
"@typescript/native-preview-darwin-arm64": ["@typescript/native-preview-darwin-arm64@7.0.0-dev.20251130.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-j0h3dgtd/te0r6CKiJWxkb/hrtudWjEbTpuxF3Iki1E87oPtig0mNJyzTgzZFLLWaXM16Iuwb/6Y79j/dWwWmw=="],
|
|
||||||
|
|
||||||
"@typescript/native-preview-darwin-x64": ["@typescript/native-preview-darwin-x64@7.0.0-dev.20251130.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-ZjKkYNjzw8XJtai/R7eUIlRA1MK3xleNEHn+lrI5WJjZqzmOeKHc0xhbzW3E9aIDTd1/9cyt9AcPLvrx5FFvMw=="],
|
|
||||||
|
|
||||||
"@typescript/native-preview-linux-arm": ["@typescript/native-preview-linux-arm@7.0.0-dev.20251130.1", "", { "os": "linux", "cpu": "arm" }, "sha512-ovlaIVqiJqtuXaP4R/o+ljcFA3pIIMHJ1LN2bqEQYhJJR3nTbx/xvmGtXG2EC3xzrZCgEMY974izascjaziqEg=="],
|
|
||||||
|
|
||||||
"@typescript/native-preview-linux-arm64": ["@typescript/native-preview-linux-arm64@7.0.0-dev.20251130.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-FLsbHH4ZqjdZ9t6zawbvt0zx/4YO+XB3+eGBkorTY6uhK66UKkXn4ar9k7ovLjRf1C6Ozjb6qvptf0k9mEJl0Q=="],
|
|
||||||
|
|
||||||
"@typescript/native-preview-linux-x64": ["@typescript/native-preview-linux-x64@7.0.0-dev.20251130.1", "", { "os": "linux", "cpu": "x64" }, "sha512-Z7qOyRxiyQUPaLPb6VA4FtXLkIj/AOSIgaP1zguaIYXJAkfMkQbhMaViLwFziMIxlH3ysr6jbZsBmsdYhVa9cQ=="],
|
|
||||||
|
|
||||||
"@typescript/native-preview-win32-arm64": ["@typescript/native-preview-win32-arm64@7.0.0-dev.20251130.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-a3xBzkixBqg3a2KnYZLPvGlPEbxNXFdfFimiYXx4CJVeiXqJX5U9zhZ2uAxh3oMMW6pDzQmn87AfM4F3FyxDAA=="],
|
|
||||||
|
|
||||||
"@typescript/native-preview-win32-x64": ["@typescript/native-preview-win32-x64@7.0.0-dev.20251130.1", "", { "os": "win32", "cpu": "x64" }, "sha512-1rJCAv76ScP7inMJPWTN28BuDe55po3BcjQR0/j07hViJPVMn4bI+VlgLV0oZpYOuaM9Uk0ex0e14mr0fwcgQA=="],
|
|
||||||
|
|
||||||
"abort-controller": ["abort-controller@3.0.0", "", { "dependencies": { "event-target-shim": "^5.0.0" } }, "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg=="],
|
"abort-controller": ["abort-controller@3.0.0", "", { "dependencies": { "event-target-shim": "^5.0.0" } }, "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg=="],
|
||||||
|
|
||||||
"acorn": ["acorn@8.15.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg=="],
|
"acorn": ["acorn@8.15.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg=="],
|
||||||
|
|||||||
3
docs/TODO.md
Normal file
3
docs/TODO.md
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
Based on https://learn.microsoft.com/en-us/powershell/dsc/reference/schemas/schema-uris?view=dsc-3.0#pinning-to-a-version-folder we should probably rework how we are doing type gen.
|
||||||
|
|
||||||
|
The cli does not expose all the schemas we need.
|
||||||
@@ -10,7 +10,9 @@
|
|||||||
"typecheck": "tsc --noEmit",
|
"typecheck": "tsc --noEmit",
|
||||||
"lint:biome": "biome check . --write",
|
"lint:biome": "biome check . --write",
|
||||||
"lint:biome:unsafe": "biome check . --unsafe --write",
|
"lint:biome:unsafe": "biome check . --unsafe --write",
|
||||||
"lint:biome:check": "biome check ."
|
"lint:biome:check": "biome check .",
|
||||||
|
"gen:dsc-types": "bun run scripts/gen-dsc-types.ts",
|
||||||
|
"gen:dsc-resources-types": "bun run scripts/gen-dsc-resources-types.ts"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@effect/cli": "^0.72.1",
|
"@effect/cli": "^0.72.1",
|
||||||
|
|||||||
91
scripts/gen-dsc-resources-types.ts
Normal file
91
scripts/gen-dsc-resources-types.ts
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
import { Command, FileSystem, Path } from '@effect/platform';
|
||||||
|
import { BunContext, BunRuntime } from '@effect/platform-bun';
|
||||||
|
import { Effect, Logger, LogLevel } from 'effect';
|
||||||
|
import { jsonSchemaToEffectSchema, runCommand } from './lib/script-utils';
|
||||||
|
|
||||||
|
const getDscResourceJsonSchema = (resourceType: string) =>
|
||||||
|
Effect.gen(function* () {
|
||||||
|
const commandParts = [
|
||||||
|
'dsc',
|
||||||
|
'resource',
|
||||||
|
'schema',
|
||||||
|
'--resource',
|
||||||
|
resourceType,
|
||||||
|
] as const;
|
||||||
|
yield* Effect.logDebug(`Running command: ${commandParts.join(' ')}`);
|
||||||
|
const schemaString = yield* Command.make(...commandParts).pipe(
|
||||||
|
Command.string,
|
||||||
|
);
|
||||||
|
return schemaString.trim();
|
||||||
|
});
|
||||||
|
|
||||||
|
const getAvailableDscResources = () =>
|
||||||
|
Effect.gen(function* () {
|
||||||
|
yield* Effect.logDebug('Getting available DSC resources...');
|
||||||
|
|
||||||
|
const dscrResourcesListOutput = yield* Command.make(
|
||||||
|
'dsc',
|
||||||
|
'resource',
|
||||||
|
'list',
|
||||||
|
'-o',
|
||||||
|
'json',
|
||||||
|
).pipe(Command.string);
|
||||||
|
|
||||||
|
yield* Effect.logDebug(
|
||||||
|
`DSC resources list output: ${dscrResourcesListOutput}`,
|
||||||
|
);
|
||||||
|
|
||||||
|
return [] as Array<string>;
|
||||||
|
});
|
||||||
|
|
||||||
|
const genDscResourcesTypes = Effect.gen(function* () {
|
||||||
|
yield* Effect.log('Starting DSC resources types generation...');
|
||||||
|
|
||||||
|
const availableResourceTypes = yield* getAvailableDscResources();
|
||||||
|
yield* Effect.log(
|
||||||
|
`Found available resource types: ${availableResourceTypes.join(', ')}`,
|
||||||
|
);
|
||||||
|
|
||||||
|
const fs = yield* FileSystem.FileSystem;
|
||||||
|
const path = yield* Path.Path;
|
||||||
|
|
||||||
|
const outputDir = path.join(
|
||||||
|
process.cwd(),
|
||||||
|
'src',
|
||||||
|
'dsc-resource-schema-types',
|
||||||
|
);
|
||||||
|
|
||||||
|
yield* Effect.logDebug(`Output directory: ${outputDir}`);
|
||||||
|
|
||||||
|
if (yield* fs.exists(outputDir)) {
|
||||||
|
yield* Effect.log('Removing existing output directory...');
|
||||||
|
yield* fs.remove(outputDir, { recursive: true, force: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
yield* fs.makeDirectory(outputDir, { recursive: true });
|
||||||
|
|
||||||
|
for (const schemaType of availableResourceTypes) {
|
||||||
|
yield* Effect.logDebug(`Processing: ${schemaType}`);
|
||||||
|
|
||||||
|
const jsonSchema = yield* getDscResourceJsonSchema(schemaType);
|
||||||
|
const effectSchema = yield* jsonSchemaToEffectSchema({
|
||||||
|
jsonSchema,
|
||||||
|
name: schemaType,
|
||||||
|
});
|
||||||
|
|
||||||
|
const outputPath = path.join(outputDir, `${schemaType}.gen.ts`);
|
||||||
|
yield* fs.writeFileString(outputPath, effectSchema);
|
||||||
|
|
||||||
|
yield* Effect.log(`Generated: ${schemaType}.gen.ts`);
|
||||||
|
}
|
||||||
|
|
||||||
|
yield* Effect.log('DSC types generation complete!');
|
||||||
|
});
|
||||||
|
|
||||||
|
BunRuntime.runMain(
|
||||||
|
genDscResourcesTypes.pipe(
|
||||||
|
Effect.provide(BunContext.layer),
|
||||||
|
Logger.withMinimumLogLevel(LogLevel.Debug),
|
||||||
|
Effect.scoped,
|
||||||
|
),
|
||||||
|
);
|
||||||
@@ -1,29 +1,7 @@
|
|||||||
import { Command, FileSystem, Path } from '@effect/platform';
|
import { Command, FileSystem, Path } from '@effect/platform';
|
||||||
import { BunContext, BunRuntime } from '@effect/platform-bun';
|
import { BunContext, BunRuntime } from '@effect/platform-bun';
|
||||||
import { Effect, Logger, LogLevel, pipe, Stream, String } from 'effect';
|
import { Effect, Logger, LogLevel } from 'effect';
|
||||||
import { convertFromString } from './json-schema-to-effect';
|
import { jsonSchemaToEffectSchema, runCommand } from './lib/script-utils';
|
||||||
|
|
||||||
// Helper function to collect stream output as a string
|
|
||||||
const runString = <E, R>(
|
|
||||||
stream: Stream.Stream<Uint8Array, E, R>,
|
|
||||||
): Effect.Effect<string, E, R> =>
|
|
||||||
stream.pipe(Stream.decodeText(), Stream.runFold(String.empty, String.concat));
|
|
||||||
|
|
||||||
const runCommand = (command: Command.Command) =>
|
|
||||||
pipe(
|
|
||||||
Command.start(command),
|
|
||||||
Effect.flatMap((process) =>
|
|
||||||
Effect.all(
|
|
||||||
[
|
|
||||||
process.exitCode,
|
|
||||||
runString(process.stdout),
|
|
||||||
runString(process.stderr),
|
|
||||||
],
|
|
||||||
{ concurrency: 3 },
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Effect.map(([exitCode, stdout, stderr]) => ({ exitCode, stdout, stderr })),
|
|
||||||
);
|
|
||||||
|
|
||||||
const getDscJsonSchema = (schemaType: string) =>
|
const getDscJsonSchema = (schemaType: string) =>
|
||||||
Effect.gen(function* () {
|
Effect.gen(function* () {
|
||||||
@@ -62,28 +40,6 @@ const getPossibleDscSchemaTypes = () =>
|
|||||||
return possibleTypes;
|
return possibleTypes;
|
||||||
});
|
});
|
||||||
|
|
||||||
const jsonSchemaToEffectSchema = (params: {
|
|
||||||
jsonSchema: string;
|
|
||||||
name: string;
|
|
||||||
}) =>
|
|
||||||
Effect.gen(function* () {
|
|
||||||
yield* Effect.logDebug(`Converting schema: ${params.name}`);
|
|
||||||
|
|
||||||
const result = convertFromString(params.jsonSchema, params.name);
|
|
||||||
|
|
||||||
yield* Effect.logDebug(
|
|
||||||
`Converted "${params.name}" - types: ${result.typeNames.join(', ')}`,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (result.recursiveTypes.length > 0) {
|
|
||||||
yield* Effect.logInfo(
|
|
||||||
`Recursive types in ${params.name}: ${result.recursiveTypes.join(', ')}`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result.code;
|
|
||||||
});
|
|
||||||
|
|
||||||
const genDscTypes = Effect.gen(function* () {
|
const genDscTypes = Effect.gen(function* () {
|
||||||
yield* Effect.log('Starting DSC types generation...');
|
yield* Effect.log('Starting DSC types generation...');
|
||||||
|
|
||||||
|
|||||||
47
scripts/lib/script-utils.ts
Normal file
47
scripts/lib/script-utils.ts
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
import { Command } from '@effect/platform';
|
||||||
|
import { Effect, pipe, Stream, String } from 'effect';
|
||||||
|
import { convertFromString } from './json-schema-to-effect';
|
||||||
|
|
||||||
|
// Helper function to collect stream output as a string
|
||||||
|
const runString = <E, R>(
|
||||||
|
stream: Stream.Stream<Uint8Array, E, R>,
|
||||||
|
): Effect.Effect<string, E, R> =>
|
||||||
|
stream.pipe(Stream.decodeText(), Stream.runFold(String.empty, String.concat));
|
||||||
|
|
||||||
|
export const runCommand = (command: Command.Command) =>
|
||||||
|
pipe(
|
||||||
|
Command.start(command),
|
||||||
|
Effect.flatMap((process) =>
|
||||||
|
Effect.all(
|
||||||
|
[
|
||||||
|
process.exitCode,
|
||||||
|
runString(process.stdout),
|
||||||
|
runString(process.stderr),
|
||||||
|
],
|
||||||
|
{ concurrency: 3 },
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Effect.map(([exitCode, stdout, stderr]) => ({ exitCode, stdout, stderr })),
|
||||||
|
);
|
||||||
|
|
||||||
|
export const jsonSchemaToEffectSchema = (params: {
|
||||||
|
jsonSchema: string;
|
||||||
|
name: string;
|
||||||
|
}) =>
|
||||||
|
Effect.gen(function* () {
|
||||||
|
yield* Effect.logDebug(`Converting schema: ${params.name}`);
|
||||||
|
|
||||||
|
const result = convertFromString(params.jsonSchema, params.name);
|
||||||
|
|
||||||
|
yield* Effect.logDebug(
|
||||||
|
`Converted "${params.name}" - types: ${result.typeNames.join(', ')}`,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (result.recursiveTypes.length > 0) {
|
||||||
|
yield* Effect.logInfo(
|
||||||
|
`Recursive types in ${params.name}: ${result.recursiveTypes.join(', ')}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.code;
|
||||||
|
});
|
||||||
19
src/bin.ts
19
src/bin.ts
@@ -3,6 +3,25 @@ import { BunContext, BunRuntime } from '@effect/platform-bun';
|
|||||||
import { Effect } from 'effect';
|
import { Effect } from 'effect';
|
||||||
import pkg from '../package.json' with { type: 'json' };
|
import pkg from '../package.json' with { type: 'json' };
|
||||||
|
|
||||||
|
// import type { Configuration } from './dsc-schema-types/configuration.gen';
|
||||||
|
|
||||||
|
// const machineConfig: typeof Configuration.Type = {
|
||||||
|
// $schema: 'https://aka.ms/dsc/schemas/v3/config/document.json',
|
||||||
|
// resources: [
|
||||||
|
// {
|
||||||
|
// name: 'must be unique',
|
||||||
|
// type: 'Microsoft.Windows/Registry',
|
||||||
|
// properties: {
|
||||||
|
// keyPath: 'HKCU\\example\\key',
|
||||||
|
// valueName: 'Example',
|
||||||
|
// valueData: {
|
||||||
|
// String: 'Example Value',
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
// ],
|
||||||
|
// };
|
||||||
|
|
||||||
const diffCommand = Command.make('diff', {}, () =>
|
const diffCommand = Command.make('diff', {}, () =>
|
||||||
Effect.gen(function* () {
|
Effect.gen(function* () {
|
||||||
yield* Effect.log('diff');
|
yield* Effect.log('diff');
|
||||||
|
|||||||
Reference in New Issue
Block a user