@amritk/mjst 0.1.0 → 0.2.1

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
@@ -68,7 +68,8 @@ npx mjst --config ./mjst.config.json
68
68
  | 🏷️ | `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. |
69
69
  | 🔨 | `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. |
70
70
  | ⚠️ | `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. |
71
- | ⚙️ | `config` | `--config <path>` | `string` | — | — | Path to a JSON config file. Keys match the option names in this schema (schema, outDir, typesOnly, build, logWarnings). CLI flags take precedence over config file values. |
71
+ | 🚫 | `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. |
72
+ | ⚙️ | `config` | `--config <path>` | `string` | — | — | Path to a JSON config file. Keys match the option names in this schema (schema, outDir, typesOnly, build, logWarnings, strict). CLI flags take precedence over config file values. |
72
73
  <!-- config-table-end -->
73
74
 
74
75
  ---
@@ -22,4 +22,10 @@ export type CliConfig = {
22
22
  * that is not declared in the schema's properties.
23
23
  */
24
24
  readonly logWarnings?: boolean;
25
+ /**
26
+ * When true, the generated parsers throw on type/shape mismatches
27
+ * (wrong type, missing required property, enum/pattern/min/max violations)
28
+ * instead of coercing invalid input to default values.
29
+ */
30
+ readonly strict?: boolean;
25
31
  };
package/dist/cli.js CHANGED
@@ -1122,6 +1122,117 @@ var getDefaultValue = (schema) => {
1122
1122
  return "undefined";
1123
1123
  }
1124
1124
  };
1125
+ var wrongTypeCondition = (accessor, type) => {
1126
+ switch (type) {
1127
+ case "string":
1128
+ return `typeof ${accessor} !== "string"`;
1129
+ case "number":
1130
+ case "integer":
1131
+ return `typeof ${accessor} !== "number"`;
1132
+ case "boolean":
1133
+ return `typeof ${accessor} !== "boolean"`;
1134
+ case "array":
1135
+ return `!Array.isArray(${accessor})`;
1136
+ case "object":
1137
+ return `!isObject(${accessor})`;
1138
+ default:
1139
+ return null;
1140
+ }
1141
+ };
1142
+ var typeLabel = (type) => type === "integer" ? "number" : type;
1143
+ var escapeRegexPattern = (pattern) => {
1144
+ return pattern.replace(/\\/g, "\\\\").replace(/\//g, "\\/");
1145
+ };
1146
+ var generateConstraintChecks = (acc, propSchema, typeName, key) => {
1147
+ if (!isSchemaObject3(propSchema) || !hasType(propSchema))
1148
+ return [];
1149
+ const t = propSchema.type;
1150
+ const lines = [];
1151
+ if (t === "string") {
1152
+ if (hasPattern(propSchema)) {
1153
+ const pattern = escapeRegexPattern(propSchema.pattern);
1154
+ lines.push(` if (typeof ${acc} === "string" && !/${pattern}/.test(${acc})) throw new Error('[${typeName}] field "${key}" must match pattern ${propSchema.pattern}');`);
1155
+ }
1156
+ if (hasMinLength(propSchema)) {
1157
+ lines.push(` if (typeof ${acc} === "string" && ${acc}.length < ${propSchema.minLength}) throw new Error('[${typeName}] field "${key}" must have at least ${propSchema.minLength} characters');`);
1158
+ }
1159
+ if (hasMaxLength(propSchema)) {
1160
+ lines.push(` if (typeof ${acc} === "string" && ${acc}.length > ${propSchema.maxLength}) throw new Error('[${typeName}] field "${key}" must have at most ${propSchema.maxLength} characters');`);
1161
+ }
1162
+ }
1163
+ if (t === "number" || t === "integer") {
1164
+ if (hasMinimum(propSchema)) {
1165
+ lines.push(` if (typeof ${acc} === "number" && ${acc} < ${propSchema.minimum}) throw new Error('[${typeName}] field "${key}" must be >= ${propSchema.minimum}');`);
1166
+ }
1167
+ if (hasMaximum(propSchema)) {
1168
+ lines.push(` if (typeof ${acc} === "number" && ${acc} > ${propSchema.maximum}) throw new Error('[${typeName}] field "${key}" must be <= ${propSchema.maximum}');`);
1169
+ }
1170
+ if (hasExclusiveMinimum(propSchema)) {
1171
+ lines.push(` if (typeof ${acc} === "number" && ${acc} <= ${propSchema.exclusiveMinimum}) throw new Error('[${typeName}] field "${key}" must be > ${propSchema.exclusiveMinimum}');`);
1172
+ }
1173
+ if (hasExclusiveMaximum(propSchema)) {
1174
+ lines.push(` if (typeof ${acc} === "number" && ${acc} >= ${propSchema.exclusiveMaximum}) throw new Error('[${typeName}] field "${key}" must be < ${propSchema.exclusiveMaximum}');`);
1175
+ }
1176
+ if (hasMultipleOf(propSchema)) {
1177
+ lines.push(` if (typeof ${acc} === "number" && ${acc} % ${propSchema.multipleOf} !== 0) throw new Error('[${typeName}] field "${key}" must be a multiple of ${propSchema.multipleOf}');`);
1178
+ }
1179
+ }
1180
+ return lines;
1181
+ };
1182
+ var generatePropertyAssertion = (key, propSchema, isRequired, typeName) => {
1183
+ const acc = safeAccessor("input", key);
1184
+ const lines = [];
1185
+ if (isRequired) {
1186
+ lines.push(` if (!(${JSON.stringify(key)} in input)) throw new Error('[${typeName}] missing required property "${key}"');`);
1187
+ }
1188
+ if (!isSchemaObject3(propSchema))
1189
+ return lines;
1190
+ if (hasRef(propSchema))
1191
+ return lines;
1192
+ if (hasEnum(propSchema)) {
1193
+ const allowed = JSON.stringify(propSchema.enum);
1194
+ const label = propSchema.enum.map((v) => JSON.stringify(v)).join(", ");
1195
+ if (isRequired) {
1196
+ lines.push(` if (!(${allowed} as readonly unknown[]).includes(${acc})) throw new Error('[${typeName}] field "${key}" must be one of: ${label}');`);
1197
+ } else {
1198
+ lines.push(` if (${acc} !== undefined && !(${allowed} as readonly unknown[]).includes(${acc})) throw new Error('[${typeName}] field "${key}" must be one of: ${label}');`);
1199
+ }
1200
+ return lines;
1201
+ }
1202
+ if (hasType(propSchema)) {
1203
+ const t = propSchema.type;
1204
+ const wrongType = wrongTypeCondition(acc, t);
1205
+ if (wrongType) {
1206
+ if (isRequired) {
1207
+ lines.push(` if (${wrongType}) throw new Error(\`[${typeName}] field "${key}" expected ${typeLabel(t)}, got \${typeof ${acc}}\`);`);
1208
+ } else {
1209
+ lines.push(` if (${acc} !== undefined && (${wrongType})) throw new Error(\`[${typeName}] field "${key}" expected ${typeLabel(t)}, got \${typeof ${acc}}\`);`);
1210
+ }
1211
+ }
1212
+ lines.push(...generateConstraintChecks(acc, propSchema, typeName, key));
1213
+ }
1214
+ return lines;
1215
+ };
1216
+ var generateObjectStrictAssertion = (schema, typeName) => {
1217
+ const lines = [];
1218
+ lines.push(` if (!isObject(input)) throw new Error(\`[${typeName}] expected object, got \${input === null ? "null" : typeof input}\`);`);
1219
+ if (!hasProperties(schema) || !isSchemaObject3(schema))
1220
+ return lines;
1221
+ const required = new Set(hasRequired(schema) ? schema.required : []);
1222
+ for (const [key, propSchema] of Object.entries(schema.properties)) {
1223
+ lines.push(...generatePropertyAssertion(key, propSchema, required.has(key), typeName));
1224
+ }
1225
+ return lines;
1226
+ };
1227
+ var generateScalarStrictAssertion = (schema, typeName) => {
1228
+ if (!isSchemaObject3(schema) || !hasType(schema))
1229
+ return null;
1230
+ const t = schema.type;
1231
+ const wrongType = wrongTypeCondition("input", t);
1232
+ if (!wrongType)
1233
+ return null;
1234
+ return ` if (${wrongType}) throw new Error(\`[${typeName}] expected ${typeLabel(t)}, got \${input === null ? "null" : typeof input}\`);`;
1235
+ };
1125
1236
  var findDiscriminator = (schemas) => {
1126
1237
  const propertyValues = new Map;
1127
1238
  for (const schema of schemas) {
@@ -1677,11 +1788,22 @@ var generateFallbackObject = (schema, useRefImports, typeName) => {
1677
1788
  }`;
1678
1789
  return result;
1679
1790
  };
1680
- var generateNonObjectParser = (typeName, schema) => {
1791
+ var generateNonObjectParser = (typeName, schema, strict) => {
1681
1792
  const functionName = generateParserName(typeName);
1682
1793
  if (!isSchemaObject3(schema) || !hasType(schema)) {
1683
1794
  return `export const ${functionName} = (input: unknown): ${typeName} => input as ${typeName};`;
1684
1795
  }
1796
+ if (strict) {
1797
+ const assertion = generateScalarStrictAssertion(schema, typeName);
1798
+ if (assertion === null) {
1799
+ return `export const ${functionName} = (input: unknown): ${typeName} => input as ${typeName};`;
1800
+ }
1801
+ const returnExpr = schema.type === "array" ? `[...(input as readonly unknown[])] as ${typeName}` : `input as ${typeName}`;
1802
+ return `export const ${functionName} = (input: unknown): ${typeName} => {
1803
+ ${assertion}
1804
+ return ${returnExpr};
1805
+ };`;
1806
+ }
1685
1807
  switch (schema.type) {
1686
1808
  case "string":
1687
1809
  return `export const ${functionName} = (input: unknown): ${typeName} => typeof input === "string" ? input as ${typeName} : "" as ${typeName};`;
@@ -1696,8 +1818,14 @@ var generateNonObjectParser = (typeName, schema) => {
1696
1818
  return `export const ${functionName} = (input: unknown): ${typeName} => input as ${typeName};`;
1697
1819
  }
1698
1820
  };
1699
- var generateEmptyObjectParser = (typeName) => {
1821
+ var generateEmptyObjectParser = (typeName, strict) => {
1700
1822
  const functionName = generateParserName(typeName);
1823
+ if (strict) {
1824
+ return `export const ${functionName} = (input: unknown): ${typeName} => {
1825
+ if (!isObject(input)) throw new Error(\`[${typeName}] expected object, got \${input === null ? "null" : typeof input}\`);
1826
+ return { ...input } as ${typeName};
1827
+ };`;
1828
+ }
1701
1829
  return `export const ${functionName} = (input: unknown): ${typeName} => isObject(input) ? { ...input } as ${typeName} : {} as ${typeName};`;
1702
1830
  };
1703
1831
  var toVarName = (key) => {
@@ -1726,7 +1854,7 @@ var generatePropertyTypeCheck = (varName, schema, useRefImports) => {
1726
1854
  case "string": {
1727
1855
  checks.push(`typeof ${varName} === "string"`);
1728
1856
  if (hasPattern(schema))
1729
- checks.push(`/${escapeRegexPattern(schema.pattern)}/.test(${varName})`);
1857
+ checks.push(`/${escapeRegexPattern2(schema.pattern)}/.test(${varName})`);
1730
1858
  if (hasMinLength(schema))
1731
1859
  checks.push(`${varName}.length >= ${schema.minLength}`);
1732
1860
  if (hasMaxLength(schema))
@@ -1779,16 +1907,28 @@ var generatePropertyTypeCheck = (varName, schema, useRefImports) => {
1779
1907
  var shouldCacheVariable = (propSchema, _canFastPath, _useRefImports) => {
1780
1908
  return isSchemaObject3(propSchema);
1781
1909
  };
1782
- var generateObjectParser = (schema, typeName, useRefImports, logWarnings) => {
1910
+ var generateObjectParser = (schema, typeName, useRefImports, logWarnings, strict) => {
1783
1911
  const functionName = generateParserName(typeName);
1784
1912
  if (!hasProperties(schema)) {
1913
+ if (strict) {
1914
+ return `export const ${functionName} = (input: unknown): ${typeName} => {
1915
+ if (!isObject(input)) throw new Error(\`[${typeName}] expected object, got \${input === null ? "null" : typeof input}\`);
1916
+ return input as ${typeName};
1917
+ };`;
1918
+ }
1785
1919
  return `export const ${functionName} = (input: unknown): ${typeName} => isObject(input) ? input as ${typeName} : {} as ${typeName};`;
1786
1920
  }
1787
1921
  const fallbackObject = generateFallbackObject(schema, useRefImports, typeName);
1788
1922
  const properties = Object.entries(schema.properties);
1789
1923
  const lines = [];
1790
1924
  lines.push(`export const ${functionName} = (input: unknown): ${typeName} => {`);
1791
- lines.push(` if (!isObject(input)) return ${fallbackObject};`);
1925
+ if (strict) {
1926
+ for (const assertionLine of generateObjectStrictAssertion(schema, typeName)) {
1927
+ lines.push(assertionLine);
1928
+ }
1929
+ } else {
1930
+ lines.push(` if (!isObject(input)) return ${fallbackObject};`);
1931
+ }
1792
1932
  const propInfo = [];
1793
1933
  const hasAllOfRefParsers = useRefImports && isSchemaObject3(schema) && hasAllOf(schema) && schema.allOf.some((entry) => isSchemaObject3(entry) && hasRef(entry));
1794
1934
  let canFastPath = !hasAllOfRefParsers;
@@ -1911,7 +2051,7 @@ var generateObjectParser = (schema, typeName, useRefImports, logWarnings) => {
1911
2051
  }
1912
2052
  return result;
1913
2053
  };
1914
- var generateCombinedObjectParser = (schema, typeName, useRefImports, logWarnings) => {
2054
+ var generateCombinedObjectParser = (schema, typeName, useRefImports, logWarnings, strict) => {
1915
2055
  const functionName = generateParserName(typeName);
1916
2056
  const entries = generatePropertyEntries(schema, useRefImports);
1917
2057
  const propertyLines = entries.map((entry) => {
@@ -1921,19 +2061,19 @@ var generateCombinedObjectParser = (schema, typeName, useRefImports, logWarnings
1921
2061
  return ` ${safeKey2(entry.key)}: ${entry.value},`;
1922
2062
  });
1923
2063
  if (!isSchemaObject3(schema) || !("patternProperties" in schema)) {
1924
- return generateObjectParser(schema, typeName, useRefImports, logWarnings);
2064
+ return generateObjectParser(schema, typeName, useRefImports, logWarnings, strict);
1925
2065
  }
1926
2066
  const patternProps = schema.patternProperties;
1927
2067
  const patterns = Object.entries(patternProps);
1928
2068
  const refPattern = patterns.find(([, ps]) => isSchemaObject3(ps) && hasRef(ps));
1929
2069
  if (!refPattern || !useRefImports) {
1930
- return generateObjectParser(schema, typeName, useRefImports, logWarnings);
2070
+ return generateObjectParser(schema, typeName, useRefImports, logWarnings, strict);
1931
2071
  }
1932
2072
  const [pattern, patternSchema] = refPattern;
1933
2073
  const ref = patternSchema.$ref;
1934
2074
  const parserName = generateParserName(refToName(ref));
1935
2075
  const assignmentCode = `(result as Record<string, unknown>)[key] = ${parserName}(value);`;
1936
- const escapedPattern = escapeRegexPattern(pattern);
2076
+ const escapedPattern = escapeRegexPattern2(pattern);
1937
2077
  const inputSpread = " ...input,";
1938
2078
  let objectProperties = inputSpread;
1939
2079
  if (propertyLines.length > 0) {
@@ -1942,9 +2082,10 @@ var generateCombinedObjectParser = (schema, typeName, useRefImports, logWarnings
1942
2082
  ` + line;
1943
2083
  }
1944
2084
  }
2085
+ const notObjectBranch = strict ? ` throw new Error(\`[${typeName}] expected object, got \${input === null ? "null" : typeof input}\`);` : ` return {} as unknown as ${typeName};`;
1945
2086
  return `export const ${functionName} = (input: unknown): ${typeName} => {
1946
2087
  if (!isObject(input)) {
1947
- return {} as unknown as ${typeName};
2088
+ ${notObjectBranch}
1948
2089
  }
1949
2090
  const result = {
1950
2091
  ${objectProperties}
@@ -1958,23 +2099,41 @@ ${objectProperties}
1958
2099
  return result;
1959
2100
  };`;
1960
2101
  };
1961
- var generateAdditionalPropertiesParser = (schema, typeName, useRefImports) => {
2102
+ var generateAdditionalPropertiesParser = (schema, typeName, useRefImports, strict) => {
1962
2103
  const functionName = generateParserName(typeName);
1963
2104
  const additionalProps = schema.additionalProperties;
1964
2105
  if (!additionalProps) {
1965
- return generateEmptyObjectParser(typeName);
2106
+ return generateEmptyObjectParser(typeName, strict);
1966
2107
  }
1967
2108
  if (useRefImports && isSchemaObject3(additionalProps) && hasRef(additionalProps)) {
1968
2109
  const ref = additionalProps.$ref;
1969
2110
  const parserName = generateParserName(refToName(ref));
2111
+ if (strict) {
2112
+ return `export const ${functionName} = (input: unknown): ${typeName} => {
2113
+ if (!isObject(input)) throw new Error(\`[${typeName}] expected object, got \${input === null ? "null" : typeof input}\`);
2114
+ return validateRecord(input, ${parserName}) as ${typeName};
2115
+ };`;
2116
+ }
1970
2117
  return `export const ${functionName} = (input: unknown): ${typeName} => validateRecord(input, ${parserName}) as ${typeName};`;
1971
2118
  }
1972
2119
  if (isSchemaObject3(additionalProps) && hasType(additionalProps)) {
1973
2120
  const inlineParser = generateInlineValueParser(additionalProps);
1974
2121
  if (inlineParser) {
2122
+ if (strict) {
2123
+ return `export const ${functionName} = (input: unknown): ${typeName} => {
2124
+ if (!isObject(input)) throw new Error(\`[${typeName}] expected object, got \${input === null ? "null" : typeof input}\`);
2125
+ return validateRecord(input, ${inlineParser}) as ${typeName};
2126
+ };`;
2127
+ }
1975
2128
  return `export const ${functionName} = (input: unknown): ${typeName} => validateRecord(input, ${inlineParser}) as ${typeName};`;
1976
2129
  }
1977
2130
  }
2131
+ if (strict) {
2132
+ return `export const ${functionName} = (input: unknown): ${typeName} => {
2133
+ if (!isObject(input)) throw new Error(\`[${typeName}] expected object, got \${input === null ? "null" : typeof input}\`);
2134
+ return { ...input } as ${typeName};
2135
+ };`;
2136
+ }
1978
2137
  return `export const ${functionName} = (input: unknown): ${typeName} => isObject(input) ? { ...input } as ${typeName} : {};`;
1979
2138
  };
1980
2139
  var generateInlineValueParser = (schema) => {
@@ -1995,18 +2154,18 @@ var generateInlineValueParser = (schema) => {
1995
2154
  return null;
1996
2155
  }
1997
2156
  };
1998
- var escapeRegexPattern = (pattern) => {
2157
+ var escapeRegexPattern2 = (pattern) => {
1999
2158
  return pattern.replace(/\\/g, "\\\\").replace(/\//g, "\\/");
2000
2159
  };
2001
- var generatePatternPropertiesParser = (schema, typeName, useRefImports) => {
2160
+ var generatePatternPropertiesParser = (schema, typeName, useRefImports, strict) => {
2002
2161
  const functionName = generateParserName(typeName);
2003
2162
  if (!("patternProperties" in schema) || typeof schema.patternProperties !== "object") {
2004
- return generateEmptyObjectParser(typeName);
2163
+ return generateEmptyObjectParser(typeName, strict);
2005
2164
  }
2006
2165
  const patternProps = schema.patternProperties;
2007
2166
  const patterns = Object.entries(patternProps);
2008
2167
  if (patterns.length === 0) {
2009
- return generateEmptyObjectParser(typeName);
2168
+ return generateEmptyObjectParser(typeName, strict);
2010
2169
  }
2011
2170
  const [pattern, patternSchema] = patterns[0];
2012
2171
  let patternAssignment = "(result as Record<string, unknown>)[key] = value;";
@@ -2017,10 +2176,11 @@ var generatePatternPropertiesParser = (schema, typeName, useRefImports) => {
2017
2176
  } else if (patternSchema === false) {
2018
2177
  patternAssignment = "";
2019
2178
  }
2020
- const escapedPattern = escapeRegexPattern(pattern);
2179
+ const escapedPattern = escapeRegexPattern2(pattern);
2180
+ const notObjectBranch = strict ? ` throw new Error(\`[${typeName}] expected object, got \${input === null ? "null" : typeof input}\`);` : ` return {} as unknown as ${typeName};`;
2021
2181
  return `export const ${functionName} = (input: unknown): ${typeName} => {
2022
2182
  if (!isObject(input)) {
2023
- return {} as unknown as ${typeName};
2183
+ ${notObjectBranch}
2024
2184
  }
2025
2185
  const result = {
2026
2186
  ...input,
@@ -2132,43 +2292,44 @@ var generateSchemaObjectParser = (typeName) => {
2132
2292
  var selectParserStrategy = (schema, typeName, options) => {
2133
2293
  const useRefImports = options?.useRefImports ?? false;
2134
2294
  const logWarnings = options?.logWarnings ?? false;
2295
+ const strict = options?.strict ?? false;
2135
2296
  if (typeName === "SchemaObject") {
2136
2297
  return generateSchemaObjectParser(typeName);
2137
2298
  }
2138
2299
  const isObjectLikeSchema2 = isObjectSchema2(schema) || isSchemaObject3(schema) && (("patternProperties" in schema) || ("additionalProperties" in schema));
2139
2300
  if (!isObjectLikeSchema2 && !isSchemaObject3(schema)) {
2140
- return generateNonObjectParser(typeName, schema);
2301
+ return generateNonObjectParser(typeName, schema, strict);
2141
2302
  }
2142
2303
  if (hasProperties(schema) && isSchemaObject3(schema) && "patternProperties" in schema) {
2143
- return generateCombinedObjectParser(schema, typeName, useRefImports, logWarnings);
2304
+ return generateCombinedObjectParser(schema, typeName, useRefImports, logWarnings, strict);
2144
2305
  }
2145
2306
  if (hasProperties(schema)) {
2146
- return generateObjectParser(schema, typeName, useRefImports, logWarnings);
2307
+ return generateObjectParser(schema, typeName, useRefImports, logWarnings, strict);
2147
2308
  }
2148
2309
  if (isSchemaObject3(schema) && "if" in schema && "then" in schema && "else" in schema) {
2149
2310
  return generateConditionalParser(schema, typeName);
2150
2311
  }
2151
2312
  const conditionalObjectSchema = getConditionalObjectSchema2(schema);
2152
2313
  if (conditionalObjectSchema) {
2153
- return generateObjectParser(conditionalObjectSchema, typeName, useRefImports, logWarnings);
2314
+ return generateObjectParser(conditionalObjectSchema, typeName, useRefImports, logWarnings, strict);
2154
2315
  }
2155
2316
  if (!isObjectLikeSchema2) {
2156
- return generateNonObjectParser(typeName, schema);
2317
+ return generateNonObjectParser(typeName, schema, strict);
2157
2318
  }
2158
2319
  if ("patternProperties" in schema) {
2159
- return generatePatternPropertiesParser(schema, typeName, useRefImports);
2320
+ return generatePatternPropertiesParser(schema, typeName, useRefImports, strict);
2160
2321
  }
2161
2322
  if ("additionalProperties" in schema && !hasProperties(schema)) {
2162
2323
  const additionalProps = schema.additionalProperties;
2163
2324
  if (additionalProps === true || additionalProps === false) {
2164
- return generateEmptyObjectParser(typeName);
2325
+ return generateEmptyObjectParser(typeName, strict);
2165
2326
  }
2166
- return generateAdditionalPropertiesParser(schema, typeName, useRefImports);
2327
+ return generateAdditionalPropertiesParser(schema, typeName, useRefImports, strict);
2167
2328
  }
2168
2329
  if ("type" in schema && schema.type === "object" && !hasProperties(schema)) {
2169
- return generateEmptyObjectParser(typeName);
2330
+ return generateEmptyObjectParser(typeName, strict);
2170
2331
  }
2171
- return generateEmptyObjectParser(typeName);
2332
+ return generateEmptyObjectParser(typeName, strict);
2172
2333
  };
2173
2334
  var generateParserFunction = (schema, typeName, options) => {
2174
2335
  return selectParserStrategy(schema, typeName, options);
@@ -2236,7 +2397,8 @@ var generateFile = (schema, typeName, options) => {
2236
2397
  }
2237
2398
  const parserFunction = generateParserFunction(schema, typeName, {
2238
2399
  useRefImports: true,
2239
- ...options?.logWarnings !== undefined ? { logWarnings: options.logWarnings } : {}
2400
+ ...options?.logWarnings !== undefined ? { logWarnings: options.logWarnings } : {},
2401
+ ...options?.strict !== undefined ? { strict: options.strict } : {}
2240
2402
  });
2241
2403
  const shapeValidator = generateShapeValidator(schema, typeName, true);
2242
2404
  const combinedFunctions = `${shapeValidator}
@@ -2277,7 +2439,7 @@ var extractDynamicAnchorDefs = (schema) => {
2277
2439
  }
2278
2440
  return refs;
2279
2441
  };
2280
- var buildSchema = async (rootSchema, rootTypeName, extensions, typesOnly, logWarnings) => {
2442
+ var buildSchema = async (rootSchema, rootTypeName, extensions, typesOnly, logWarnings, strict) => {
2281
2443
  rootSchema = upgradeDraft07Schema(rootSchema);
2282
2444
  const files = [];
2283
2445
  const processedRefs = new Set;
@@ -2289,7 +2451,8 @@ var buildSchema = async (rootSchema, rootTypeName, extensions, typesOnly, logWar
2289
2451
  const rootContent = generateFile(extendedRootSchema, rootTypeName, {
2290
2452
  typesOnly: typesOnly ?? false,
2291
2453
  rootSchema,
2292
- ...logWarnings !== undefined ? { logWarnings } : {}
2454
+ ...logWarnings !== undefined ? { logWarnings } : {},
2455
+ ...strict !== undefined ? { strict } : {}
2293
2456
  });
2294
2457
  const rootFilename = rootTypeName.toLowerCase();
2295
2458
  processedFilenames.add(rootFilename);
@@ -2320,7 +2483,8 @@ var buildSchema = async (rootSchema, rootTypeName, extensions, typesOnly, logWar
2320
2483
  typesOnly: typesOnly ?? false,
2321
2484
  selfRef: ref,
2322
2485
  rootSchema,
2323
- ...logWarnings !== undefined ? { logWarnings } : {}
2486
+ ...logWarnings !== undefined ? { logWarnings } : {},
2487
+ ...strict !== undefined ? { strict } : {}
2324
2488
  });
2325
2489
  if (!processedFilenames.has(filename)) {
2326
2490
  processedFilenames.add(filename);
@@ -2385,7 +2549,8 @@ var loadConfig = async (configPath) => {
2385
2549
  ...typeof obj["outDir"] === "string" && { outDir: obj["outDir"] },
2386
2550
  ...typeof obj["typesOnly"] === "boolean" && { typesOnly: obj["typesOnly"] },
2387
2551
  ...typeof obj["build"] === "boolean" && { build: obj["build"] },
2388
- ...typeof obj["logWarnings"] === "boolean" && { logWarnings: obj["logWarnings"] }
2552
+ ...typeof obj["logWarnings"] === "boolean" && { logWarnings: obj["logWarnings"] },
2553
+ ...typeof obj["strict"] === "boolean" && { strict: obj["strict"] }
2389
2554
  };
2390
2555
  };
2391
2556
 
@@ -2411,6 +2576,8 @@ var parseCliArgs = (args) => {
2411
2576
  config.build = value !== "false";
2412
2577
  } else if (key === "log-warnings") {
2413
2578
  config.logWarnings = value !== "false";
2579
+ } else if (key === "strict") {
2580
+ config.strict = value !== "false";
2414
2581
  }
2415
2582
  continue;
2416
2583
  }
@@ -2432,6 +2599,8 @@ var parseCliArgs = (args) => {
2432
2599
  config.build = true;
2433
2600
  } else if (arg === "--log-warnings") {
2434
2601
  config.logWarnings = true;
2602
+ } else if (arg === "--strict") {
2603
+ config.strict = true;
2435
2604
  }
2436
2605
  }
2437
2606
  return config;
@@ -2468,7 +2637,7 @@ var run = async () => {
2468
2637
  const schemaPath = resolve2(config.schema);
2469
2638
  const raw = await readFile2(schemaPath, "utf-8");
2470
2639
  const schema = JSON.parse(raw);
2471
- const files = await buildSchema(schema, "Document", undefined, config.typesOnly, config.logWarnings);
2640
+ const files = await buildSchema(schema, "Document", undefined, config.typesOnly, config.logWarnings, config.strict);
2472
2641
  const outputDir = resolve2(config.outDir);
2473
2642
  await mkdir(outputDir, { recursive: true });
2474
2643
  for (const file of files) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@amritk/mjst",
3
- "version": "0.1.0",
3
+ "version": "0.2.1",
4
4
  "description": "Generate TypeScript parsers and type definitions from JSON Schemas.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -29,6 +29,9 @@
29
29
  "files": [
30
30
  "dist"
31
31
  ],
32
+ "publishConfig": {
33
+ "access": "public"
34
+ },
32
35
  "scripts": {
33
36
  "dev": "bun run --conditions=development ./src/cli.ts",
34
37
  "start": "bun run ./src/cli.ts",