@amritk/mjst 0.5.1 → 0.6.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.
package/README.md CHANGED
@@ -44,9 +44,43 @@ The package ships a `mjst` bin that runs under Node ≥ 20 (or Bun), so you can
44
44
  ### CLI
45
45
 
46
46
  ```bash
47
- npx mjst --schema ./schema.json --outDir ./generated
47
+ npx mjst --schema ./schema.json --out-dir ./generated
48
48
  ```
49
49
 
50
+ > [!NOTE]
51
+ > Every flag accepts both kebab-case and camelCase, so `--out-dir` and `--outDir` are equivalent.
52
+
53
+ ### Single file
54
+
55
+ Pass `--out-file` instead of `--out-dir` to concatenate every generated definition into one
56
+ self-contained file. This is currently supported together with `--types-only`:
57
+
58
+ ```bash
59
+ npx mjst --schema ./schema.json --out-file ./generated/schema.ts --types-only
60
+ ```
61
+
62
+ ### Recursive — a whole folder of schemas
63
+
64
+ Point `--schema-dir` at a directory of JSON Schemas and mjst generates parsers for every
65
+ `*.json` file it finds, mirroring the directory layout under `--out-dir`:
66
+
67
+ ```bash
68
+ npx mjst --schema-dir ./schemas --out-dir ./generated
69
+ ```
70
+
71
+ ```
72
+ schemas/ generated/
73
+ user.json ─▶ user/
74
+ api/ document.ts, index.ts
75
+ order.json ─▶ api/order/
76
+ document.ts, index.ts
77
+ _helpers/ ← shared runtime helpers (embedded mode)
78
+ ```
79
+
80
+ Each schema lands in its own subdirectory so generated files never collide, and in embedded
81
+ mode the runtime helpers are emitted **once** into `outDir/_helpers/` — every nested parser
82
+ imports from that single shared location. `--build` compiles the whole tree in place.
83
+
50
84
  ### Config file
51
85
 
52
86
  ```bash
@@ -63,16 +97,19 @@ npx mjst --config ./mjst.config.json
63
97
  <!-- config-table-start -->
64
98
  | | Property | CLI Flag | Type | Required | Default | Description |
65
99
  |:---:|:---|:---|:---:|:---:|:---:|:---|
66
- | 📄 | `schema` | `--schema <path>` | `string` | ✅ | — | Path to the schema to process. With the default 'json' input this is a JSON Schema file that is read and parsed. With any other input format it is a JS/TS module that exports a schema, which is loaded and converted to JSON Schema via the matching adapter. |
100
+ | 📄 | `schema` | `--schema <path>` | `string` | — | — | Path to the schema to process. With the default 'json' input this is a JSON Schema file that is read and parsed. With any other input format it is a JS/TS module that exports a schema, which is loaded and converted to JSON Schema via the matching adapter. Either 'schema' or 'schemaDir' is required. |
101
+ | 🗂️ | `schemaDir` | `--schema-dir <dir>` | `string` | — | — | Path to a directory of JSON Schema files. When set, the CLI walks the directory recursively, generates parsers for every '*.json' schema it finds, and mirrors the directory layout under outDir (each schema lands in its own subdirectory). The runtime helpers are emitted once into a shared outDir/_helpers/ that every nested parser imports from. Mutually exclusive with 'schema'; when both are present 'schemaDir' wins. Only JSON Schema input is supported in this mode. |
67
102
  | 🔌 | `input` | `--input <format>` | `string` | — | `"json"` | Source format of the schema. 'json' (default) reads a JSON Schema file directly. Any other format loads 'schema' as a module and converts it to JSON Schema with the matching adapter. Supported: 'typebox', 'zod' (zod v4+), 'valibot' (with @valibot/to-json-schema), and 'effect' — each requires the corresponding library installed in your project. |
68
103
  | 📦 | `export` | `--export <name>` | `string` | — | — | Which export of the schema module to use when 'input' is not 'json'. Defaults to the default export, or the sole named export when the module has exactly one. |
69
- | 📁 | `outDir` | `--outDir <dir>` | `string` | ✅ | — | Output directory for generated TypeScript files. The directory is created automatically if it does not exist. Subdirectories are created as needed when a generated file includes a nested path. |
104
+ | 📁 | `outDir` | `--out-dir <dir>` | `string` | — | — | Output directory for generated TypeScript files. The directory is created automatically if it does not exist. Subdirectories are created as needed when a generated file includes a nested path. Mutually exclusive with 'outFile'. |
105
+ | 📄 | `outFile` | `--out-file <file>` | `string` | — | — | Output everything to a single TypeScript file instead of a directory. Every generated definition is concatenated into one self-contained file and the cross-file imports are dropped. Mutually exclusive with 'outDir'. Currently supported only together with 'typesOnly'. |
70
106
  | 🏷️ | `typesOnly` | `--types-only` | `boolean` | — | `false` | Generate only TypeScript type definitions without parser functions. Useful when you only need the type shapes and do not need runtime validation. |
71
107
  | 🔨 | `build` | `--build` | `boolean` | — | `false` | Compile the generated TypeScript files to .js and .d.ts output. A temporary tsconfig is written to the output directory, tsc is invoked, and the intermediate .ts source files are removed when compilation succeeds. |
72
108
  | ⚠️ | `logWarnings` | `--log-warnings` | `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. |
73
109
  | 🚫 | `strict` | `--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. |
110
+ | 🔒 | `readonly` | `--readonly` | `boolean` | — | `false` | Emit every property, array, and record in the generated type definitions as readonly, producing deeply immutable types. Affects type definitions only; the generated parsers still build and return plain objects. |
74
111
  | 🧰 | `helpers` | `--helpers <mode>` | `string` | — | — | Controls how generated parsers reference their runtime helpers. 'package' emits imports from @amritk/helpers (requires it to be installed in the consumer project). 'embedded' ships the helper source under outDir/_helpers/ so the output is self-contained. When omitted, the CLI auto-detects: it picks 'package' if @amritk/helpers resolves from outDir, otherwise 'embedded'. |
75
- | ⚙️ | `config` | `--config <path>` | `string` | — | — | Path to a JSON config file. Keys match the option names in this schema (schema, outDir, typesOnly, build, logWarnings, strict, helpers). CLI flags take precedence over config file values. |
112
+ | ⚙️ | `config` | `--config <path>` | `string` | — | — | Path to a JSON config file. Keys match the option names in this schema (schema, schemaDir, outDir, outFile, typesOnly, build, logWarnings, strict, readonly, helpers). CLI flags take precedence over config file values. |
76
113
  <!-- config-table-end -->
77
114
 
78
115
  ---
@@ -5,7 +5,15 @@ import type { SourceFormat } from '@amritk/adapters/source-format';
5
5
  */
6
6
  export type CliConfig = {
7
7
  /** Path to the schema to process — a JSON Schema file, or a JS/TS module when `input` is set. */
8
- readonly schema: string;
8
+ readonly schema?: string;
9
+ /**
10
+ * Path to a directory of JSON Schema files. When set, the CLI walks the directory
11
+ * recursively, generates parsers for every `*.json` schema it finds, and mirrors the
12
+ * directory layout under `outDir`. A single shared `_helpers/` directory is emitted at
13
+ * the root of `outDir` (in embedded mode) and every nested parser imports from it.
14
+ * Mutually exclusive with `schema`; when both are present `schemaDir` wins.
15
+ */
16
+ readonly schemaDir?: string;
9
17
  /**
10
18
  * The source format of the schema. Defaults to `'json'` (a plain JSON Schema file).
11
19
  * Any other format loads `schema` as a module and converts it via the matching adapter.
@@ -16,8 +24,13 @@ export type CliConfig = {
16
24
  * Defaults to the default export, or the sole named export when there is exactly one.
17
25
  */
18
26
  readonly export?: string;
19
- /** Output directory for generated TypeScript files. */
20
- readonly outDir: string;
27
+ /** Output directory for generated TypeScript files. Mutually exclusive with `outFile`. */
28
+ readonly outDir?: string;
29
+ /**
30
+ * Output everything to a single TypeScript file instead of a directory of files.
31
+ * Mutually exclusive with `outDir`. Currently supported only with `typesOnly`.
32
+ */
33
+ readonly outFile?: string;
21
34
  /**
22
35
  * When true, only generate TypeScript type definitions without parser functions.
23
36
  * Useful when you only need the type shapes and do not need runtime validation.
@@ -49,4 +62,9 @@ export type CliConfig = {
49
62
  * resolves from outDir, otherwise falls back to `'embedded'`.
50
63
  */
51
64
  readonly helpers?: 'package' | 'embedded';
65
+ /**
66
+ * When true, every property, array, and record in the generated type
67
+ * definitions is emitted as `readonly`, producing deeply immutable types.
68
+ */
69
+ readonly readonly?: boolean;
52
70
  };