@amritk/mjst 0.7.8 โ†’ 0.7.10

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
@@ -207,6 +207,16 @@ npx mjst --config ./mjst.config.json
207
207
  <td colspan="5">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. When a schema sets additionalProperties: false, undeclared keys throw too; otherwise they are still allowed.</td>
208
208
  </tr>
209
209
  <tr>
210
+ <td>๐Ÿงน <code>stripUnknown</code></td>
211
+ <td><code>--strip-unknown</code></td>
212
+ <td><code>boolean</code></td>
213
+ <td align="center">โ€”</td>
214
+ <td align="center"><code>false</code></td>
215
+ </tr>
216
+ <tr>
217
+ <td colspan="5">Build each parser's result from the schema's declared properties only, silently dropping undeclared input keys at every nesting level (zod's .strip()). Extras are never a validation error, so this composes with strict (which still throws on wrong types and missing required properties) and yields to additionalProperties: false, which rejects rather than strips in strict mode.</td>
218
+ </tr>
219
+ <tr>
210
220
  <td>๐Ÿ”’ <code>readonly</code></td>
211
221
  <td><code>--readonly</code></td>
212
222
  <td><code>boolean</code></td>
@@ -52,6 +52,15 @@ export type CliConfig = {
52
52
  * instead of coercing invalid input to default values.
53
53
  */
54
54
  readonly strict?: boolean;
55
+ /**
56
+ * When true, generated parsers build their result from declared properties
57
+ * only, silently dropping any undeclared input key at every nesting level
58
+ * (zod's `.strip()`). Extras are never a validation error, so this composes
59
+ * with `strict` (which still throws on wrong types and missing required
60
+ * properties) and yields to `additionalProperties: false`, which rejects
61
+ * rather than strips in strict mode.
62
+ */
63
+ readonly stripUnknown?: boolean;
55
64
  /**
56
65
  * Controls how generated parsers reference their runtime helpers.
57
66
  * - `'package'`: emit `import ... from '@amritk/helpers/...'`.
package/dist/cli.js CHANGED
@@ -120,7 +120,7 @@ const runSingle = async (config, schemaPath, outputDir) => {
120
120
  console.log(`Helpers mode: ${helpersMode}${config.helpers ? ' (explicit)' : ' (auto-detected)'}`);
121
121
  const rootTypeName = deriveRootTypeName(schema);
122
122
  console.log(`Root type: ${rootTypeName}`);
123
- const files = await buildSchema(schema, rootTypeName, undefined, config.typesOnly, config.logWarnings, config.strict, helpersMode, undefined, config.readonly, config.typeSuffix);
123
+ const files = await buildSchema(schema, rootTypeName, undefined, config.typesOnly, config.logWarnings, config.strict, helpersMode, undefined, config.readonly, config.stripUnknown, config.typeSuffix);
124
124
  for (const file of files) {
125
125
  const isHelper = file.filename.startsWith('_helpers/');
126
126
  const content = config.banner && !isHelper ? resolveBanner(config.banner) + file.content : file.content;
@@ -145,7 +145,7 @@ const runSingleFile = async (config, schemaPath, outFilePath) => {
145
145
  await mkdir(outputDir, { recursive: true });
146
146
  const rootTypeName = deriveRootTypeName(schema);
147
147
  console.log(`Root type: ${rootTypeName}`);
148
- const files = await buildSchema(schema, rootTypeName, undefined, config.typesOnly, config.logWarnings, config.strict, config.helpers ?? 'package', undefined, config.readonly, config.typeSuffix);
148
+ const files = await buildSchema(schema, rootTypeName, undefined, config.typesOnly, config.logWarnings, config.strict, config.helpers ?? 'package', undefined, config.readonly, config.stripUnknown, config.typeSuffix);
149
149
  const combined = combineGeneratedFiles(files);
150
150
  await writeFile(outFilePath, config.banner ? resolveBanner(config.banner) + combined : combined, 'utf-8');
151
151
  console.log(`Generated: ${relative(process.cwd(), outFilePath)}`);
@@ -190,7 +190,7 @@ const runRecursive = async (config, schemaDir, outputDir) => {
190
190
  const schema = await loadSchema(config, schemaFile);
191
191
  const rootTypeName = deriveRootTypeName(schema);
192
192
  console.log(`\n${relPath} โ†’ ${relNoExt}/ (root type: ${rootTypeName})`);
193
- const files = await buildSchema(schema, rootTypeName, undefined, config.typesOnly, config.logWarnings, config.strict, helpersMode, helpersImportPrefix, config.readonly, config.typeSuffix);
193
+ const files = await buildSchema(schema, rootTypeName, undefined, config.typesOnly, config.logWarnings, config.strict, helpersMode, helpersImportPrefix, config.readonly, config.stripUnknown, config.typeSuffix);
194
194
  for (const file of files) {
195
195
  if (file.filename.startsWith('_helpers/')) {
196
196
  sharedHelpers.set(file.filename, file.content);
@@ -25,6 +25,7 @@ export const loadConfig = async (configPath) => {
25
25
  ...(typeof obj['build'] === 'boolean' && { build: obj['build'] }),
26
26
  ...(typeof obj['logWarnings'] === 'boolean' && { logWarnings: obj['logWarnings'] }),
27
27
  ...(typeof obj['strict'] === 'boolean' && { strict: obj['strict'] }),
28
+ ...(typeof obj['stripUnknown'] === 'boolean' && { stripUnknown: obj['stripUnknown'] }),
28
29
  ...(typeof obj['readonly'] === 'boolean' && { readonly: obj['readonly'] }),
29
30
  };
30
31
  };
@@ -1,6 +1,13 @@
1
1
  const SOURCE_FORMATS = ['json', 'typebox', 'zod', 'valibot', 'effect'];
2
2
  // Boolean flags toggle on by presence and accept `--flag=false` to opt out.
3
- const BOOLEAN_KEYS = new Set(['typesOnly', 'build', 'logWarnings', 'strict', 'readonly']);
3
+ const BOOLEAN_KEYS = new Set([
4
+ 'typesOnly',
5
+ 'build',
6
+ 'logWarnings',
7
+ 'strict',
8
+ 'stripUnknown',
9
+ 'readonly',
10
+ ]);
4
11
  // Value flags consume the following argument (or `--flag=value`).
5
12
  const VALUE_KEYS = new Set([
6
13
  'schema',
@@ -76,6 +83,9 @@ const assignBoolean = (config, key, value) => {
76
83
  case 'strict':
77
84
  config.strict = value;
78
85
  return true;
86
+ case 'stripUnknown':
87
+ config.stripUnknown = value;
88
+ return true;
79
89
  case 'readonly':
80
90
  config.readonly = value;
81
91
  return true;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@amritk/mjst",
3
- "version": "0.7.8",
3
+ "version": "0.7.10",
4
4
  "description": "Generate TypeScript parsers and type definitions from JSON Schemas.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -42,7 +42,7 @@
42
42
  },
43
43
  "dependencies": {
44
44
  "@amritk/adapters": "0.2.10",
45
- "@amritk/generate-parsers": "0.9.0",
45
+ "@amritk/generate-parsers": "0.11.0",
46
46
  "@amritk/generate-markdown": "0.2.4",
47
47
  "@amritk/helpers": "0.10.0"
48
48
  },