Skip to content

Commit 28c3e73

Browse files
committed
Treat vendored schema compiler as internal code
1 parent 5088996 commit 28c3e73

11 files changed

Lines changed: 43 additions & 83 deletions

File tree

packages/core/sdk/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@
5959
}
6060
},
6161
"scripts": {
62-
"build": "tsup && mkdir -p dist/vendor/json-schema-to-typescript && cp src/vendor/json-schema-to-typescript/LICENCE.md dist/vendor/json-schema-to-typescript/LICENCE.md && (tsc --declaration --emitDeclarationOnly --outDir dist --rootDir src || true)",
62+
"build": "tsup && (tsc --declaration --emitDeclarationOnly --outDir dist --rootDir src || true)",
6363
"typecheck": "tsgo --noEmit",
6464
"test": "vitest run",
6565
"typecheck:slow": "tsc --noEmit"

packages/core/sdk/src/schema-types.test.ts

Lines changed: 16 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
import { readFileSync } from "node:fs";
2-
import { execFileSync } from "node:child_process";
3-
import { fileURLToPath } from "node:url";
42
import { describe, expect, it } from "@effect/vitest";
53
import { Schema } from "effect";
64

@@ -24,15 +22,6 @@ const stripeBalanceTransactionsFixture = Schema.decodeUnknownSync(
2422
),
2523
);
2624

27-
const sdkPackageRoot = fileURLToPath(new URL("..", import.meta.url));
28-
const TypeScriptPreviewOutput = Schema.Struct({
29-
inputTypeScript: Schema.String,
30-
outputTypeScript: Schema.String,
31-
});
32-
const decodeTypeScriptPreviewOutput = Schema.decodeUnknownSync(
33-
Schema.fromJsonString(TypeScriptPreviewOutput),
34-
);
35-
3625
describe("schema-types", () => {
3726
it("reuses referenced definitions instead of inlining them", async () => {
3827
const schema = {
@@ -383,33 +372,22 @@ describe("schema-types", () => {
383372
});
384373
});
385374

386-
it("loads the vendored compiler through Bun's TypeScript loader", () => {
387-
const output = execFileSync(
388-
"bun",
389-
[
390-
"-e",
391-
`
392-
import { buildToolTypeScriptPreview } from "./src/schema-types.ts";
393-
const preview = await buildToolTypeScriptPreview({
394-
inputSchema: {
395-
type: "object",
396-
properties: {
397-
account_id: { type: "string" },
398-
body: {}
399-
},
400-
required: ["account_id", "body"],
401-
additionalProperties: false
402-
},
403-
outputSchema: {},
404-
defs: new Map()
405-
});
406-
console.log(JSON.stringify(preview));
407-
`,
408-
],
409-
{ cwd: sdkPackageRoot, encoding: "utf8" },
410-
);
411-
412-
expect(decodeTypeScriptPreviewOutput(output)).toEqual({
375+
it("renders unconstrained schemas as unknown", async () => {
376+
await expect(
377+
buildToolTypeScriptPreview({
378+
inputSchema: {
379+
type: "object",
380+
properties: {
381+
account_id: { type: "string" },
382+
body: {},
383+
},
384+
required: ["account_id", "body"],
385+
additionalProperties: false,
386+
},
387+
outputSchema: {},
388+
defs: new Map(),
389+
}),
390+
).resolves.toEqual({
413391
inputTypeScript: "{ account_id: string; body: unknown; }",
414392
outputTypeScript: "unknown",
415393
});

packages/core/sdk/src/schema-types.ts

Lines changed: 2 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { hoistDefinitions, normalizeRefs } from "./schema-refs";
2+
import { compile } from "./vendor/json-schema-to-typescript";
23

34
type JsonSchemaRecord = Record<string, unknown>;
45
type CompilerJsonSchema = JsonSchemaRecord | boolean;
@@ -19,13 +20,6 @@ type SchemaCompilerOptions = {
1920
unknownAny?: boolean;
2021
unreachableDefinitions?: boolean;
2122
};
22-
type SchemaCompiler = {
23-
compile: (
24-
schema: CompilerJsonSchema,
25-
name: string,
26-
options: Partial<SchemaCompilerOptions>,
27-
) => Promise<string>;
28-
};
2923

3024
export type TypeScriptRenderOptions = {
3125
compilerOptions?: Partial<SchemaCompilerOptions>;
@@ -56,16 +50,6 @@ const DEFAULT_COMPILER_OPTIONS = {
5650
},
5751
} satisfies Partial<SchemaCompilerOptions>;
5852

59-
const schemaCompilerModulePath = (): string =>
60-
import.meta.url.endsWith(".ts")
61-
? "./vendor/json-schema-to-typescript/index.ts"
62-
: "./vendor/json-schema-to-typescript/index.js";
63-
64-
const loadSchemaCompiler = async (): Promise<SchemaCompiler> => {
65-
const compilerModule: unknown = await import(schemaCompilerModulePath());
66-
return compilerModule as SchemaCompiler;
67-
};
68-
6953
const DEFINITION_REF_PATTERN = /^#\/definitions\/(.+)$/;
7054
const IDENTIFIER_PATTERN = /^[A-Za-z_$][A-Za-z0-9_$]*$/;
7155

@@ -764,7 +748,6 @@ const compileSchemaPreview = async (
764748
options: TypeScriptRenderOptions,
765749
): Promise<TypeScriptSchemaPreview> => {
766750
const wrappedSchema = buildWrappedSchema(schema, defs);
767-
const { compile } = await loadSchemaCompiler();
768751
const source = await compile(wrappedSchema, ROOT_WRAPPER_NAME, compilerOptionsFrom(options));
769752
return previewFromCompiledTypeScript(source);
770753
};
@@ -816,10 +799,7 @@ export const buildToolTypeScriptPreview = async (input: {
816799
}
817800

818801
const wrappedSchema = buildWrappedObjectSchema(properties, input.defs);
819-
return loadSchemaCompiler()
820-
.then(({ compile }) =>
821-
compile(wrappedSchema, ROOT_WRAPPER_NAME, compilerOptionsFrom(input.options ?? {})),
822-
)
802+
return compile(wrappedSchema, ROOT_WRAPPER_NAME, compilerOptionsFrom(input.options ?? {}))
823803
.then(
824804
(source) => previewToolFromCompiledTypeScript(source),
825805
() => ({

packages/core/sdk/src/vendor/json-schema-to-typescript/compat.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,16 @@ export const isPlainObject = (value: unknown): value is Record<string, unknown>
1010

1111
export const cloneDeep = <T>(value: T): T => structuredClone(value);
1212

13-
export const merge = <T extends Record<string, unknown>>(
13+
export const merge = <T extends object>(
1414
target: T,
15-
...sources: ReadonlyArray<Record<string, unknown> | undefined>
15+
...sources: ReadonlyArray<object | undefined>
1616
): T => {
17+
const output = target as Record<string, unknown>;
1718
for (const source of sources) {
1819
if (!source) continue;
19-
for (const [key, value] of Object.entries(source)) {
20-
const current = target[key];
21-
target[key] =
20+
for (const [key, value] of Object.entries(source as Record<string, unknown>)) {
21+
const current = output[key];
22+
output[key] =
2223
isPlainObject(current) && isPlainObject(value)
2324
? merge({ ...current }, value)
2425
: cloneDeep(value);

packages/core/sdk/src/vendor/json-schema-to-typescript/generator.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -377,7 +377,7 @@ function generateStandaloneType(ast: ASTWithStandaloneName, options: Options): s
377377
return (
378378
(hasComment(ast) ? generateComment(ast.comment) + "\n" : "") +
379379
`export type ${toSafeString(ast.standaloneName)} = ${generateType(
380-
omit<AST>(ast, "standaloneName") as AST /* TODO */,
380+
omit(ast, "standaloneName") as AST /* TODO */,
381381
options,
382382
)}`
383383
);

packages/core/sdk/src/vendor/json-schema-to-typescript/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ export async function compile(
164164
): Promise<string> {
165165
validateOptions(options);
166166

167-
const _options = merge({}, DEFAULT_OPTIONS, options);
167+
const _options = merge({} as Options, DEFAULT_OPTIONS, options);
168168

169169
const start = Date.now();
170170
function time() {

packages/core/sdk/src/vendor/json-schema-to-typescript/parser.ts

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,9 @@ export function parse(
4747
return parseLiteral(schema, keyName);
4848
}
4949

50-
const intersection = schema[Intersection];
51-
const types = schema[Types];
50+
const normalizedSchema = schema as NormalizedJSONSchema;
51+
const intersection = normalizedSchema[Intersection];
52+
const types = normalizedSchema[Types];
5253

5354
if (intersection) {
5455
const ast = parseAsTypeWithCache(
@@ -61,17 +62,19 @@ export function parse(
6162
) as TIntersection;
6263

6364
types.forEach((type) => {
64-
ast.params.push(parseAsTypeWithCache(schema, type, options, keyName, processed, usedNames));
65+
ast.params.push(
66+
parseAsTypeWithCache(normalizedSchema, type, options, keyName, processed, usedNames),
67+
);
6568
});
6669

67-
log("blue", "parser", "Types:", [...types], "Input:", schema, "Output:", ast);
70+
log("blue", "parser", "Types:", [...types], "Input:", normalizedSchema, "Output:", ast);
6871
return ast;
6972
}
7073

7174
if (types.size === 1) {
7275
const type = [...types][0];
73-
const ast = parseAsTypeWithCache(schema, type, options, keyName, processed, usedNames);
74-
log("blue", "parser", "Type:", type, "Input:", schema, "Output:", ast);
76+
const ast = parseAsTypeWithCache(normalizedSchema, type, options, keyName, processed, usedNames);
77+
log("blue", "parser", "Type:", type, "Input:", normalizedSchema, "Output:", ast);
7578
return ast;
7679
}
7780

packages/core/sdk/src/vendor/json-schema-to-typescript/types/json-schema.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,11 @@ export type JSONSchema4Type =
1717
| JSONSchema4Type[];
1818

1919
export interface JSONSchema4Object {
20-
readonly [key: string]: unknown;
20+
[key: string]: any;
2121
}
2222

2323
export interface JSONSchema4 {
24-
readonly [key: string]: unknown;
24+
[key: string]: any;
2525
$id?: string;
2626
$ref?: string;
2727
$schema?: string;
@@ -44,7 +44,7 @@ export interface JSONSchema4 {
4444
oneOf?: JSONSchema4[];
4545
patternProperties?: Record<string, JSONSchema4>;
4646
properties?: Record<string, JSONSchema4>;
47-
required?: string[];
47+
required?: string[] | false;
4848
title?: string;
4949
type?: JSONSchema4TypeName | JSONSchema4TypeName[];
5050
}

packages/core/sdk/src/vendor/json-schema-to-typescript/utils.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -148,10 +148,10 @@ export function traverse(
148148
}
149149
}
150150
if (schema.definitions) {
151-
traverseObjectKeys(schema.definitions, callback, processed);
151+
traverseObjectKeys(schema.definitions as Record<string, LinkedJSONSchema>, callback, processed);
152152
}
153153
if (schema.$defs) {
154-
traverseObjectKeys(schema.$defs, callback, processed);
154+
traverseObjectKeys(schema.$defs as Record<string, LinkedJSONSchema>, callback, processed);
155155
}
156156
if (schema.not) {
157157
traverse(schema.not, callback, processed);
@@ -360,7 +360,7 @@ export function isSchemaLike(schema: any): schema is LinkedJSONSchema {
360360
}
361361

362362
// top-level schema
363-
const parent = schema[Parent];
363+
const parent = (schema as LinkedJSONSchema)[Parent] as LinkedJSONSchema | null;
364364
if (parent === null) {
365365
return true;
366366
}

packages/core/sdk/tsconfig.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,5 @@
2020
}
2121
]
2222
},
23-
"include": ["src"],
24-
"exclude": ["src/vendor/json-schema-to-typescript"]
23+
"include": ["src"]
2524
}

0 commit comments

Comments
 (0)