@amritk/mjst 0.14.8 → 0.15.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/AI.md CHANGED
@@ -36,8 +36,11 @@ mjst compile-api ./routes.ts --out ./dist/handler.ts
36
36
  4. **The root type name comes from the schema `title`/filename**, not
37
37
  `Document`. Override with `--root-type <name>` (single-schema only; rejected
38
38
  with `--schema-dir`).
39
- 5. **Non-JSON input** (`--input typebox|zod|valibot|effect`) works for a single
40
- `--schema`; `--schema-dir` only accepts `json`.
39
+ 5. **Non-JSON input** (`--input typebox|zod|valibot|effect|avro`) works for a
40
+ single `--schema`; `--schema-dir` only accepts `json`. The library formats
41
+ point `--schema` at a JS/TS **module**; `avro` points it at a `.avsc` JSON
42
+ document, which is read as data (no `import()`, so `--export` does not
43
+ apply).
41
44
 
42
45
  ## Common flags
43
46
 
package/README.md CHANGED
@@ -295,7 +295,7 @@ The exit code is `0` on success, `1` when compilation fails (unloadable module,
295
295
  <td align="center"><code>"json"</code></td>
296
296
  </tr>
297
297
  <tr>
298
- <td colspan="4">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.<br><strong>Allowed:</strong> <code>"json"</code>, <code>"typebox"</code>, <code>"zod"</code>, <code>"valibot"</code>, <code>"effect"</code></td>
298
+ <td colspan="4">Source format of the schema. 'json' (default) reads a JSON Schema file directly. 'avro' reads an Apache Avro '.avsc' JSON document and converts it, needing no extra library. 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.<br><strong>Allowed:</strong> <code>"json"</code>, <code>"typebox"</code>, <code>"zod"</code>, <code>"valibot"</code>, <code>"effect"</code>, <code>"avro"</code></td>
299
299
  </tr>
300
300
  <tr>
301
301
  <td>📦 <code>export</code></td>
@@ -304,7 +304,7 @@ The exit code is `0` on success, `1` when compilation fails (unloadable module,
304
304
  <td align="center"></td>
305
305
  </tr>
306
306
  <tr>
307
- <td colspan="4">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.</td>
307
+ <td colspan="4">Which export of the schema module to use when 'input' names a module format (anything but 'json' and 'avro', which are read as data). Defaults to the default export, or the sole named export when the module has exactly one.</td>
308
308
  </tr>
309
309
  <tr>
310
310
  <td>📁 <code>outDir</code></td>
@@ -16,11 +16,15 @@ export type CliConfig = {
16
16
  readonly schemaDir?: string;
17
17
  /**
18
18
  * The source format of the schema. Defaults to `'json'` (a plain JSON Schema file).
19
- * Any other format loads `schema` as a module and converts it via the matching adapter.
19
+ *
20
+ * `'avro'` reads `schema` as a `.avsc` JSON document and converts it — no module
21
+ * is loaded, so `export` does not apply. Every other format loads `schema` as a
22
+ * module and converts the exported value via the matching adapter.
20
23
  */
21
24
  readonly input?: SourceFormat;
22
25
  /**
23
- * Which export of the schema module to use when `input` is not `'json'`.
26
+ * Which export of the schema module to use when `input` names a module format
27
+ * (anything but `'json'` and `'avro'`, which are parsed as data).
24
28
  * Defaults to the default export, or the sole named export when there is exactly one.
25
29
  */
26
30
  readonly export?: string;
@@ -4,4 +4,4 @@
4
4
  * documents these flags (config.schema.json) is not shipped in the published
5
5
  * package; the help-text test cross-checks that every flag is listed.
6
6
  */
7
- export declare const HELP_TEXT = "mjst \u2014 generate TypeScript parsers and type definitions from JSON Schemas\n\nUsage:\n mjst --schema <path> --out-dir <dir> [options]\n mjst --schema-dir <dir> --out-dir <dir> [options]\n mjst --schema <path> --out-file <file> --types-only [options]\n\nSubcommands (each with its own flags and --help):\n mjst lint <files> Lint JSON/YAML documents against a ruleset\n mjst compile-api <module> --out <file> Compile @amritk/api route contracts into a fetch-handler module\n\nInput:\n --schema <path> Schema to process: a JSON Schema file, or a module when --input is set\n --schema-dir <dir> Directory of JSON Schemas, processed recursively (instead of --schema)\n --input <format> Schema source format: json (default), typebox, zod, valibot, effect\n --export <name> Which export of the schema module to use when --input is not json\n\nOutput:\n --out-dir <dir> Output directory for the generated files\n --out-file <file> Single-file output instead of a directory (requires --types-only)\n --types-only Generate type definitions only, without parser functions\n --validators Also emit validateX/isX validators into a validators/ subdir\n --examples Also emit fast-check arbitraries + example values under examples/\n --build Compile the generated files to .js/.d.ts (implies --import-ext js)\n --force Overwrite pre-existing files in the output destination\n --import-ext <ext> Extension on generated relative imports: ts (default) or js\n --helpers <mode> Runtime helpers: package or embedded (default: auto-detect from package.json)\n --root-type <name> Root type name for a single --schema run (default: schema title or filename)\n --type-suffix <s> Suffix appended to every $ref-derived type name\n --banner [text] Prepend a header comment to every generated file\n --readonly Emit deeply readonly type definitions\n\nValidation:\n --strict Throw on type/shape mismatches instead of coercing to defaults\n --strip-unknown Silently drop undeclared input keys at every nesting level\n --case-insensitive Normalize mis-cased enum/const strings to their exact casing\n --log-warnings console.warn on input keys not declared in the schema\n\nReference resolution:\n --resolve-remote Fetch http(s) $refs while resolving cross-file/remote refs (off by default)\n --allowed-hosts <h> Restrict remote $ref fetches to these hosts (comma-separated; implies --resolve-remote)\n --allow-private-hosts Permit remote $refs to private/loopback hosts (SSRF guard, off by default)\n --allowed-roots <d> Extra directories a local $ref may resolve into, on top of the schema's own\n (comma-separated; relative to the current directory)\n\nMisc:\n --config <path> JSON config file with the same keys; CLI flags take precedence\n --version, -v Print the CLI version\n --help, -h Print this help\n\nDocs: https://github.com/amritk/mjst/tree/main/packages/cli#readme\n";
7
+ export declare const HELP_TEXT = "mjst \u2014 generate TypeScript parsers and type definitions from JSON Schemas\n\nUsage:\n mjst --schema <path> --out-dir <dir> [options]\n mjst --schema-dir <dir> --out-dir <dir> [options]\n mjst --schema <path> --out-file <file> --types-only [options]\n\nSubcommands (each with its own flags and --help):\n mjst lint <files> Lint JSON/YAML documents against a ruleset\n mjst compile-api <module> --out <file> Compile @amritk/api route contracts into a fetch-handler module\n\nInput:\n --schema <path> Schema to process: a JSON Schema file, or a module when --input is set\n --schema-dir <dir> Directory of JSON Schemas, processed recursively (instead of --schema)\n --input <format> Schema source format: json (default), typebox, zod, valibot, effect, avro\n --export <name> Which export of the schema module to use when --input names a module format\n\nOutput:\n --out-dir <dir> Output directory for the generated files\n --out-file <file> Single-file output instead of a directory (requires --types-only)\n --types-only Generate type definitions only, without parser functions\n --validators Also emit validateX/isX validators into a validators/ subdir\n --examples Also emit fast-check arbitraries + example values under examples/\n --build Compile the generated files to .js/.d.ts (implies --import-ext js)\n --force Overwrite pre-existing files in the output destination\n --import-ext <ext> Extension on generated relative imports: ts (default) or js\n --helpers <mode> Runtime helpers: package or embedded (default: auto-detect from package.json)\n --root-type <name> Root type name for a single --schema run (default: schema title or filename)\n --type-suffix <s> Suffix appended to every $ref-derived type name\n --banner [text] Prepend a header comment to every generated file\n --readonly Emit deeply readonly type definitions\n\nValidation:\n --strict Throw on type/shape mismatches instead of coercing to defaults\n --strip-unknown Silently drop undeclared input keys at every nesting level\n --case-insensitive Normalize mis-cased enum/const strings to their exact casing\n --log-warnings console.warn on input keys not declared in the schema\n\nReference resolution:\n --resolve-remote Fetch http(s) $refs while resolving cross-file/remote refs (off by default)\n --allowed-hosts <h> Restrict remote $ref fetches to these hosts (comma-separated; implies --resolve-remote)\n --allow-private-hosts Permit remote $refs to private/loopback hosts (SSRF guard, off by default)\n --allowed-roots <d> Extra directories a local $ref may resolve into, on top of the schema's own\n (comma-separated; relative to the current directory)\n\nMisc:\n --config <path> JSON config file with the same keys; CLI flags take precedence\n --version, -v Print the CLI version\n --help, -h Print this help\n\nDocs: https://github.com/amritk/mjst/tree/main/packages/cli#readme\n";
package/dist/help-text.js CHANGED
@@ -12,8 +12,8 @@ Subcommands (each with its own flags and --help):
12
12
  Input:
13
13
  --schema <path> Schema to process: a JSON Schema file, or a module when --input is set
14
14
  --schema-dir <dir> Directory of JSON Schemas, processed recursively (instead of --schema)
15
- --input <format> Schema source format: json (default), typebox, zod, valibot, effect
16
- --export <name> Which export of the schema module to use when --input is not json
15
+ --input <format> Schema source format: json (default), typebox, zod, valibot, effect, avro
16
+ --export <name> Which export of the schema module to use when --input names a module format
17
17
 
18
18
  Output:
19
19
  --out-dir <dir> Output directory for the generated files
@@ -1,7 +1,7 @@
1
1
  import { readFile } from "node:fs/promises";
2
2
  import { resolve } from "node:path";
3
3
  import { validateConfig } from "./validate-config.js";
4
- const SOURCE_FORMATS = ["json", "typebox", "zod", "valibot", "effect"];
4
+ const SOURCE_FORMATS = ["json", "typebox", "zod", "valibot", "effect", "avro"];
5
5
  const isSourceFormat = (value) => typeof value === "string" && SOURCE_FORMATS.includes(value);
6
6
  const isHelpersMode = (value) => value === "package" || value === "embedded";
7
7
  const isImportExt = (value) => value === "js" || value === "ts";
@@ -10,5 +10,13 @@ import type { CliConfig } from './cli-config.js';
10
10
  * `@amritk/resolve-refs`, inlining every external target into a single document.
11
11
  * Any resolve failures are surfaced as a CLI error rather than silently yielding
12
12
  * a half-resolved schema.
13
+ *
14
+ * Avro splits the difference, and is the reason this is not a plain
15
+ * json/not-json branch: a `.avsc` is a JSON *document*, not a module exporting a
16
+ * value, so it is read and parsed like a JSON Schema and only the conversion is
17
+ * delegated to the adapter. Nothing is imported, which also means an Avro schema
18
+ * — unlike a Zod or TypeBox one — never reaches module evaluation. Its `$ref`s
19
+ * are Avro names resolved by the adapter, not JSON Pointers, so the resolver
20
+ * does not run over it either.
13
21
  */
14
22
  export declare const loadSchema: (config: Partial<CliConfig>, schemaPath: string) => Promise<unknown>;
@@ -32,6 +32,10 @@ const loadSchema = async (config, schemaPath) => {
32
32
  return resolved;
33
33
  }
34
34
  console.log(`Input format: ${inputFormat}`);
35
+ if (inputFormat === "avro") {
36
+ const source2 = JSON.parse(await readFile(schemaPath, "utf-8"));
37
+ return getAdapter(inputFormat).toJSONSchema(source2);
38
+ }
35
39
  const source = await loadSchemaModule(schemaPath, config.export);
36
40
  return getAdapter(inputFormat).toJSONSchema(source);
37
41
  };
@@ -1,4 +1,4 @@
1
- const SOURCE_FORMATS = ["json", "typebox", "zod", "valibot", "effect"];
1
+ const SOURCE_FORMATS = ["json", "typebox", "zod", "valibot", "effect", "avro"];
2
2
  const LIST_KEYS = /* @__PURE__ */ new Set(["allowedHosts", "allowedRoots"]);
3
3
  const BOOLEAN_KEYS = /* @__PURE__ */ new Set([
4
4
  "typesOnly",
@@ -30,7 +30,8 @@ export declare const CONFIG_KEYS: Record<string, ConfigKeySpec>;
30
30
  * file has to be at least as strict as the flags it stands in for.
31
31
  *
32
32
  * Note what this does *not* buy: a config is still trusted code. `schema` plus a
33
- * non-`json` `input` makes `load-schema-module.ts` `import()` whatever path the
33
+ * module-loading `input` (every format except `json` and `avro`, both of which
34
+ * are parsed as data) makes `load-schema-module.ts` `import()` whatever path the
34
35
  * config names, so an untrusted `mjst.config.json` still reaches arbitrary module
35
36
  * evaluation. Validating the shape does not change that — do not run mjst against
36
37
  * a config file you would not run as a script.
@@ -1,7 +1,8 @@
1
+ import { readKey } from "@amritk/helpers/read-key";
1
2
  const CONFIG_KEYS = {
2
3
  schema: { type: "string" },
3
4
  schemaDir: { type: "string" },
4
- input: { type: "string", enum: ["json", "typebox", "zod", "valibot", "effect"] },
5
+ input: { type: "string", enum: ["json", "typebox", "zod", "valibot", "effect", "avro"] },
5
6
  export: { type: "string" },
6
7
  outDir: { type: "string" },
7
8
  outFile: { type: "string" },
@@ -49,7 +50,7 @@ const validateConfig = (parsed, configPath) => {
49
50
  const problems = [];
50
51
  const knownKeys = Object.keys(CONFIG_KEYS);
51
52
  for (const [key, value] of Object.entries(parsed)) {
52
- const spec = CONFIG_KEYS[key];
53
+ const spec = readKey(CONFIG_KEYS, key);
53
54
  if (!spec) {
54
55
  if (key === "$schema")
55
56
  continue;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@amritk/mjst",
3
- "version": "0.14.8",
3
+ "version": "0.15.0",
4
4
  "description": "Generate TypeScript parsers and type definitions from JSON Schemas.",
5
5
  "type": "module",
6
6
  "engines": {
@@ -49,21 +49,21 @@
49
49
  "./package.json": "./package.json"
50
50
  },
51
51
  "dependencies": {
52
- "@amritk/adapters": "^0.4.3",
53
- "@amritk/api": "^0.15.1",
54
- "@amritk/generate-examples": "^0.6.3",
55
- "@amritk/generate-parsers": "^0.19.3",
56
- "@amritk/generate-validators": "^0.13.0",
57
- "@amritk/helpers": "^0.15.3",
58
- "@amritk/lint": "^0.4.7",
59
- "@amritk/resolve-refs": "^0.6.0",
60
- "@amritk/yaml": "^0.7.1",
52
+ "@amritk/adapters": "^0.5.0",
53
+ "@amritk/api": "^0.16.0",
54
+ "@amritk/generate-examples": "^0.7.0",
55
+ "@amritk/generate-parsers": "^0.19.5",
56
+ "@amritk/generate-validators": "^0.14.0",
57
+ "@amritk/helpers": "^0.16.0",
58
+ "@amritk/lint": "^0.5.0",
59
+ "@amritk/resolve-refs": "^0.7.1",
60
+ "@amritk/yaml": "^0.7.2",
61
61
  "fast-glob": "^3.3.2",
62
62
  "json-schema-typed": "^8.0.1",
63
63
  "yargs": "^17.7.2"
64
64
  },
65
65
  "devDependencies": {
66
- "@amritk/generate-markdown": "^0.4.8",
66
+ "@amritk/generate-markdown": "^0.5.0",
67
67
  "@types/yargs": "^17.0.33"
68
68
  }
69
69
  }