@amritk/generate-parsers 0.1.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/README.md +3 -1
  2. package/dist/generators/build-schema.d.ts +8 -1
  3. package/dist/generators/generate-files.d.ts +20 -2
  4. package/dist/generators/generate-parser-function.d.ts +6 -0
  5. package/dist/generators/generate-strict-assertion.d.ts +18 -0
  6. package/dist/helpers/collect-helpers.d.ts +16 -2
  7. package/dist/index.js +261 -50
  8. package/package.json +6 -2
  9. package/src/generators/build-schema.test.ts +830 -0
  10. package/src/generators/build-schema.ts +280 -0
  11. package/src/generators/generate-default-from-pattern.test.ts +81 -0
  12. package/src/generators/generate-default-from-pattern.ts +39 -0
  13. package/src/generators/generate-discriminated-union-validation.test.ts +84 -0
  14. package/src/generators/generate-discriminated-union-validation.ts +54 -0
  15. package/src/generators/generate-enum-check.test.ts +45 -0
  16. package/src/generators/generate-enum-check.ts +8 -0
  17. package/src/generators/generate-files.test.ts +435 -0
  18. package/src/generators/generate-files.ts +136 -0
  19. package/src/generators/generate-non-discriminated-union-validation.test.ts +74 -0
  20. package/src/generators/generate-non-discriminated-union-validation.ts +40 -0
  21. package/src/generators/generate-parser-function.test.ts +1798 -0
  22. package/src/generators/generate-parser-function.ts +1319 -0
  23. package/src/generators/generate-schema-checks.test.ts +322 -0
  24. package/src/generators/generate-schema-checks.ts +114 -0
  25. package/src/generators/generate-strict-assertion.ts +210 -0
  26. package/src/generators/generate-validation-expression.test.ts +794 -0
  27. package/src/generators/generate-validation-expression.ts +286 -0
  28. package/src/helpers/apply-schema-extensions.test.ts +194 -0
  29. package/src/helpers/apply-schema-extensions.ts +63 -0
  30. package/src/helpers/collect-helpers.test.ts +103 -0
  31. package/src/helpers/collect-helpers.ts +64 -0
  32. package/src/helpers/collect-imports.test.ts +587 -0
  33. package/src/helpers/collect-imports.ts +268 -0
  34. package/src/helpers/find-discriminator.test.ts +88 -0
  35. package/src/helpers/find-discriminator.ts +39 -0
  36. package/src/helpers/get-default-value.test.ts +135 -0
  37. package/src/helpers/get-default-value.ts +89 -0
  38. package/src/helpers/get-discriminator-value.test.ts +83 -0
  39. package/src/helpers/get-discriminator-value.ts +21 -0
  40. package/src/index.ts +1 -0
  41. package/src/types/schema-extensions.ts +35 -0
package/README.md CHANGED
@@ -75,7 +75,7 @@ Write them to disk however you like.
75
75
 
76
76
  ## API
77
77
 
78
- ### `buildSchema(rootSchema, rootTypeName, extensions?, typesOnly?, logWarnings?)`
78
+ ### `buildSchema(rootSchema, rootTypeName, extensions?, typesOnly?, logWarnings?, strict?)`
79
79
 
80
80
  | Parameter | Type | Description |
81
81
  |:---|:---|:---|
@@ -84,6 +84,7 @@ Write them to disk however you like.
84
84
  | `extensions` | `SchemaExtensions` _(optional)_ | Map of definition name → extra optional properties to merge in before generation. |
85
85
  | `typesOnly` | `boolean` _(optional)_ | When `true`, only emit `.ts` type definitions — skip parser functions and runtime helpers. |
86
86
  | `logWarnings` | `boolean` _(optional)_ | When `true`, generated parsers emit a `console.warn` for every input key not declared in the schema's properties. |
87
+ | `strict` | `boolean` _(optional)_ | When `true`, generated parsers throw on type/shape mismatches (wrong type, missing required property, enum/pattern/min/max violations) instead of coercing invalid input to default values. |
87
88
 
88
89
  Returns: `Promise<GeneratedFile[]>`.
89
90
 
@@ -96,6 +97,7 @@ Returns: `Promise<GeneratedFile[]>`.
96
97
  |:---:|:---|:---|:---:|:---:|:---:|:---|
97
98
  | 🏷️ | `typesOnly` | — | `boolean` | — | `false` | Generate only TypeScript type definitions without parser functions. Runtime helper files (validators, isObject) are also omitted since they are only needed for parsers. |
98
99
  | ⚠️ | `logWarnings` | — | `boolean` | — | `false` | Emit a console.warn in the generated parsers for every input key that is not declared in the schema's properties. Useful for detecting schema drift or unexpected data shapes at runtime. |
100
+ | 🚫 | `strict` | — | `boolean` | — | `false` | Generate parsers that throw on type/shape mismatches (wrong type, missing required property, enum/pattern/min/max violations) instead of coercing invalid input to default values. Unknown extra keys are still allowed. |
99
101
  <!-- config-table-end -->
100
102
 
101
103
  The generator handles:
@@ -1,4 +1,5 @@
1
1
  import type { JSONSchema } from 'json-schema-typed/draft-2020-12';
2
+ import type { HelpersMode } from '#helpers/collect-helpers';
2
3
  import type { SchemaExtensions } from '#types/schema-extensions';
3
4
  /**
4
5
  * Represents a generated file with its filename and content.
@@ -27,6 +28,12 @@ export type GeneratedFile = {
27
28
  * @param typesOnly - When true, only generate TypeScript type definitions without parser functions.
28
29
  * @param logWarnings - When true, the generated parsers emit a console.warn for every input key
29
30
  * that is not declared in the schema's properties.
31
+ * @param strict - When true, the generated parsers throw on type/shape mismatches
32
+ * (wrong type, missing required property, enum/pattern/min/max violations) instead
33
+ * of coercing invalid input to default values.
34
+ * @param helpersMode - `'package'` (default) emits `import ... from '@amritk/helpers/...'`.
35
+ * `'embedded'` emits `import ... from './_helpers/...'` and appends the helper sources
36
+ * as additional `GeneratedFile` entries so the output directory is self-contained.
30
37
  * @returns An array of generated TypeScript files
31
38
  *
32
39
  * @example
@@ -59,4 +66,4 @@ export type GeneratedFile = {
59
66
  * });
60
67
  * ```
61
68
  */
62
- export declare const buildSchema: (rootSchema: JSONSchema, rootTypeName: string, extensions?: SchemaExtensions, typesOnly?: boolean, logWarnings?: boolean) => Promise<GeneratedFile[]>;
69
+ export declare const buildSchema: (rootSchema: JSONSchema, rootTypeName: string, extensions?: SchemaExtensions, typesOnly?: boolean, logWarnings?: boolean, strict?: boolean, helpersMode?: HelpersMode) => Promise<GeneratedFile[]>;
@@ -1,4 +1,5 @@
1
1
  import type { JSONSchema } from 'json-schema-typed/draft-2020-12';
2
+ import { type HelpersMode, type RuntimeHelperName } from '#helpers/collect-helpers';
2
3
  /**
3
4
  * Options for controlling what gets generated in a file.
4
5
  */
@@ -24,6 +25,23 @@ type GenerateFileOptions = {
24
25
  * that is not declared in the schema's properties.
25
26
  */
26
27
  readonly logWarnings?: boolean;
28
+ /**
29
+ * When true, the generated parser throws on type/shape mismatches instead
30
+ * of coercing invalid input to default values.
31
+ */
32
+ readonly strict?: boolean;
33
+ /**
34
+ * Controls how runtime helpers are referenced.
35
+ * - `'package'` (default): emit imports from `@amritk/helpers/...`.
36
+ * - `'embedded'`: emit imports from `./_helpers/...` so the helper sources can
37
+ * be shipped alongside the generated files.
38
+ */
39
+ readonly helpersMode?: HelpersMode;
40
+ };
41
+ /** Result of generating a single parser file. */
42
+ export type GeneratedFileContent = {
43
+ readonly content: string;
44
+ readonly usedHelpers: ReadonlySet<RuntimeHelperName>;
27
45
  };
28
46
  /**
29
47
  * Generates a complete TypeScript file from a JSON Schema.
@@ -34,7 +52,7 @@ type GenerateFileOptions = {
34
52
  * @param schema - The JSON Schema to generate code from
35
53
  * @param typeName - The name to use for the generated TypeScript type
36
54
  * @param options - Optional settings to control what gets generated
37
- * @returns The complete TypeScript code
55
+ * @returns The generated file content and the set of runtime helpers it references
38
56
  *
39
57
  * @example
40
58
  * ```typescript
@@ -54,5 +72,5 @@ type GenerateFileOptions = {
54
72
  * // typesOnly contains only type-only imports and type User (no parser)
55
73
  * ```
56
74
  */
57
- export declare const generateFile: (schema: JSONSchema, typeName: string, options?: GenerateFileOptions) => string;
75
+ export declare const generateFile: (schema: JSONSchema, typeName: string, options?: GenerateFileOptions) => GeneratedFileContent;
58
76
  export {};
@@ -14,6 +14,12 @@ type GenerateParserOptions = {
14
14
  * that is not declared in the schema's properties.
15
15
  */
16
16
  readonly logWarnings?: boolean;
17
+ /**
18
+ * When true, the generated parser throws on type/shape mismatches instead
19
+ * of coercing invalid input to default values. Throws on the first violation
20
+ * with a path-aware Error. Unknown extra keys are still allowed.
21
+ */
22
+ readonly strict?: boolean;
17
23
  };
18
24
  /**
19
25
  * Generates a safe parser as an arrow function that never throws.
@@ -0,0 +1,18 @@
1
+ import type { JSONSchema } from 'json-schema-typed/draft-2020-12';
2
+ /**
3
+ * Generates strict-mode assertions for the body of an object parser.
4
+ * Throws on:
5
+ * - non-object input
6
+ * - missing required property
7
+ * - property of the wrong primitive type
8
+ * - enum / pattern / length / min / max / multipleOf violations
9
+ *
10
+ * Properties with a `$ref` are validated by the nested parser's own strict
11
+ * check when that parser is invoked downstream.
12
+ */
13
+ export declare const generateObjectStrictAssertion: (schema: JSONSchema, typeName: string) => string[];
14
+ /**
15
+ * Generates a single strict-mode assertion line for a non-object scalar parser.
16
+ * Returns null when the schema has no type information to assert on.
17
+ */
18
+ export declare const generateScalarStrictAssertion: (schema: JSONSchema, typeName: string) => string | null;
@@ -1,2 +1,16 @@
1
- /** A more foolproof way to generate imports from the parserFunction */
2
- export declare const collectHelpers: (parserFunction: string) => string[];
1
+ /** Names (without `.ts`) of runtime helpers that can be embedded into generated output. */
2
+ export type RuntimeHelperName = 'is-object' | 'validate-array' | 'validate-record' | 'has-ref';
3
+ /** Controls how generated parsers reference their runtime helpers. */
4
+ export type HelpersMode = 'package' | 'embedded';
5
+ export type CollectedHelpers = {
6
+ /** Import lines to splice into the generated file. */
7
+ readonly imports: string[];
8
+ /**
9
+ * Helper names that need to ship alongside the generated file in embedded mode.
10
+ * Includes transitive deps (e.g. `validate-record` pulls in `is-object`) so the
11
+ * orchestrator can emit a complete `_helpers/` directory.
12
+ */
13
+ readonly used: Set<RuntimeHelperName>;
14
+ };
15
+ /** Detects which runtime helpers a generated parser body references. */
16
+ export declare const collectHelpers: (parserFunction: string, mode: HelpersMode) => CollectedHelpers;