notes
This commit is contained in:
@@ -3,7 +3,15 @@
|
||||
# to 'bootstrap' the system.
|
||||
|
||||
# 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
|
||||
# TODO: Do we want the scripted install or the winget install?
|
||||
winget install -e --id Oven-sh.Bun
|
||||
|
||||
17
bun.lock
17
bun.lock
@@ -14,7 +14,6 @@
|
||||
"@biomejs/biome": "2.3.8",
|
||||
"@effect/language-service": "^0.57.1",
|
||||
"@types/bun": "latest",
|
||||
"@typescript/native-preview": "^7.0.0-dev.20251130.1",
|
||||
"quicktype": "^23.2.6",
|
||||
"turbo": "^2.6.1",
|
||||
"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=="],
|
||||
|
||||
"@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=="],
|
||||
|
||||
"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",
|
||||
"lint:biome": "biome check . --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": {
|
||||
"@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 { BunContext, BunRuntime } from '@effect/platform-bun';
|
||||
import { Effect, Logger, LogLevel, 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));
|
||||
|
||||
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 })),
|
||||
);
|
||||
import { Effect, Logger, LogLevel } from 'effect';
|
||||
import { jsonSchemaToEffectSchema, runCommand } from './lib/script-utils';
|
||||
|
||||
const getDscJsonSchema = (schemaType: string) =>
|
||||
Effect.gen(function* () {
|
||||
@@ -62,28 +40,6 @@ const getPossibleDscSchemaTypes = () =>
|
||||
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* () {
|
||||
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 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', {}, () =>
|
||||
Effect.gen(function* () {
|
||||
yield* Effect.log('diff');
|
||||
|
||||
Reference in New Issue
Block a user