@amritk/generate-parsers 0.20.0 → 0.21.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.
@@ -1,6 +1,7 @@
1
1
  import { regexLiteral } from "@amritk/helpers/escape-regex-pattern";
2
2
  import { getMjstInstanceOf, getMjstPrimitive } from "@amritk/helpers/mjst-extension";
3
3
  import { multipleOfPassExpr } from "@amritk/helpers/multiple-of-check";
4
+ import { boundPassExpr } from "@amritk/helpers/numeric-bound-check";
4
5
  import { hasOwnCheck } from "@amritk/helpers/safe-accessor";
5
6
  import { hasAdditionalProperties, hasConst, hasEnum, hasExclusiveMaximum, hasExclusiveMinimum, hasMaxItems, hasMaximum, hasMaxLength, hasMaxProperties, hasMinItems, hasMinimum, hasMinLength, hasMinProperties, hasMultipleOf, hasPattern, hasProperties, hasRequired, hasType, hasUniqueItems, isSchemaObject } from "@amritk/helpers/schema-guards";
6
7
  import { maxLengthPassExpr, minLengthPassExpr } from "@amritk/helpers/string-length-check";
@@ -106,16 +107,16 @@ const generateInferredChecks = (accessor, schema, type) => {
106
107
  case "number":
107
108
  checks.push(`typeof ${accessor} === "number"`);
108
109
  if (hasMinimum(schema)) {
109
- checks.push(`${accessor} >= ${schema.minimum}`);
110
+ checks.push(boundPassExpr(accessor, "minimum", schema.minimum));
110
111
  }
111
112
  if (hasMaximum(schema)) {
112
- checks.push(`${accessor} <= ${schema.maximum}`);
113
+ checks.push(boundPassExpr(accessor, "maximum", schema.maximum));
113
114
  }
114
115
  if (hasExclusiveMinimum(schema)) {
115
- checks.push(`${accessor} > ${schema.exclusiveMinimum}`);
116
+ checks.push(boundPassExpr(accessor, "minimum", schema.exclusiveMinimum, true));
116
117
  }
117
118
  if (hasExclusiveMaximum(schema)) {
118
- checks.push(`${accessor} < ${schema.exclusiveMaximum}`);
119
+ checks.push(boundPassExpr(accessor, "maximum", schema.exclusiveMaximum, true));
119
120
  }
120
121
  if (hasMultipleOf(schema)) {
121
122
  checks.push(`${accessor} % ${schema.multipleOf} === 0`);
@@ -191,16 +192,16 @@ const generateSchemaChecks = (accessor, schema) => {
191
192
  checks.push(`Number.isInteger(${accessor})`);
192
193
  }
193
194
  if (hasMinimum(schema)) {
194
- checks.push(`${accessor} >= ${schema.minimum}`);
195
+ checks.push(boundPassExpr(accessor, "minimum", schema.minimum));
195
196
  }
196
197
  if (hasMaximum(schema)) {
197
- checks.push(`${accessor} <= ${schema.maximum}`);
198
+ checks.push(boundPassExpr(accessor, "maximum", schema.maximum));
198
199
  }
199
200
  if (hasExclusiveMinimum(schema)) {
200
- checks.push(`${accessor} > ${schema.exclusiveMinimum}`);
201
+ checks.push(boundPassExpr(accessor, "minimum", schema.exclusiveMinimum, true));
201
202
  }
202
203
  if (hasExclusiveMaximum(schema)) {
203
- checks.push(`${accessor} < ${schema.exclusiveMaximum}`);
204
+ checks.push(boundPassExpr(accessor, "maximum", schema.exclusiveMaximum, true));
204
205
  }
205
206
  if (hasMultipleOf(schema)) {
206
207
  checks.push(multipleOfPassExpr(accessor, schema.multipleOf));
@@ -1,3 +1,4 @@
1
+ import type { UnknownKeysStrategy } from '@amritk/helpers/unknown-keys-strategy';
1
2
  import type { JSONSchema } from 'json-schema-typed/draft-2020-12';
2
3
  /**
3
4
  * Context for assertions that reach beyond the property's own schema: union
@@ -13,6 +14,11 @@ export type StrictAssertionContext = {
13
14
  readonly suffix?: string;
14
15
  readonly rootSchema?: Record<string, unknown>;
15
16
  readonly stripUnknown?: boolean;
17
+ /**
18
+ * The parser's `unknownKeys` option, carried so every object parser one of
19
+ * these contexts reaches counts keys on its fast path the same way.
20
+ */
21
+ readonly unknownKeys?: UnknownKeysStrategy;
16
22
  /**
17
23
  * Whether the parser these assertions run inside also emits the private
18
24
  * sub-parsers for its inline object properties (and inline-object array
@@ -1,6 +1,7 @@
1
1
  import { regexLiteral } from "@amritk/helpers/escape-regex-pattern";
2
2
  import { getMjstInstanceOf, getMjstPrimitive } from "@amritk/helpers/mjst-extension";
3
3
  import { multipleOfFailExpr } from "@amritk/helpers/multiple-of-check";
4
+ import { boundFailExpr } from "@amritk/helpers/numeric-bound-check";
4
5
  import { quoteJsString } from "@amritk/helpers/quote-js-string";
5
6
  import { resolveRef } from "@amritk/helpers/resolve-ref";
6
7
  import { hasOwnCheck, missingCheck, safeAccessor } from "@amritk/helpers/safe-accessor";
@@ -156,16 +157,16 @@ const generateConstraintChecks = (acc, propSchema, field, context = {}) => {
156
157
  }
157
158
  if (t === "number" || t === "integer") {
158
159
  if (hasMinimum(propSchema)) {
159
- lines.push(` if (typeof ${acc} === "number" && !(${acc} >= ${propSchema.minimum})) ${throwError(`${field} must be >= ${propSchema.minimum}`)};`);
160
+ lines.push(` if (typeof ${acc} === "number" && ${boundFailExpr(acc, "minimum", propSchema.minimum)}) ${throwError(`${field} must be >= ${propSchema.minimum}`)};`);
160
161
  }
161
162
  if (hasMaximum(propSchema)) {
162
- lines.push(` if (typeof ${acc} === "number" && !(${acc} <= ${propSchema.maximum})) ${throwError(`${field} must be <= ${propSchema.maximum}`)};`);
163
+ lines.push(` if (typeof ${acc} === "number" && ${boundFailExpr(acc, "maximum", propSchema.maximum)}) ${throwError(`${field} must be <= ${propSchema.maximum}`)};`);
163
164
  }
164
165
  if (hasExclusiveMinimum(propSchema)) {
165
- lines.push(` if (typeof ${acc} === "number" && !(${acc} > ${propSchema.exclusiveMinimum})) ${throwError(`${field} must be > ${propSchema.exclusiveMinimum}`)};`);
166
+ lines.push(` if (typeof ${acc} === "number" && ${boundFailExpr(acc, "minimum", propSchema.exclusiveMinimum, true)}) ${throwError(`${field} must be > ${propSchema.exclusiveMinimum}`)};`);
166
167
  }
167
168
  if (hasExclusiveMaximum(propSchema)) {
168
- lines.push(` if (typeof ${acc} === "number" && !(${acc} < ${propSchema.exclusiveMaximum})) ${throwError(`${field} must be < ${propSchema.exclusiveMaximum}`)};`);
169
+ lines.push(` if (typeof ${acc} === "number" && ${boundFailExpr(acc, "maximum", propSchema.exclusiveMaximum, true)}) ${throwError(`${field} must be < ${propSchema.exclusiveMaximum}`)};`);
169
170
  }
170
171
  if (hasMultipleOf(propSchema)) {
171
172
  lines.push(` if (typeof ${acc} === "number" && ${multipleOfFailExpr(acc, propSchema.multipleOf)}) ${throwError(`${field} must be a multiple of ${propSchema.multipleOf}`)};`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@amritk/generate-parsers",
3
- "version": "0.20.0",
3
+ "version": "0.21.0",
4
4
  "description": "Generate TypeScript parsers and type definitions from JSON Schemas.",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.js",
@@ -41,7 +41,11 @@
41
41
  "types:check": "tsgo -p . --noEmit",
42
42
  "test": "NODE_ENV=production vitest run --root ../.. generate-parsers",
43
43
  "generate-readme": "bun run ./scripts/generate-readme.ts",
44
- "bench": "bun --conditions development ./bench/run.ts"
44
+ "prebench": "bun run --filter='@amritk/helpers' build && bun run build",
45
+ "bench": "bun --conditions development ./bench/run.ts",
46
+ "prebench:node": "bun run --filter='@amritk/helpers' build && bun run build",
47
+ "bench:node": "node ./bench/run.ts",
48
+ "bench:moltar": "bun --conditions development ./bench/moltar.ts"
45
49
  },
46
50
  "imports": {
47
51
  "#generators/*": "./src/generators/*.ts",
@@ -56,12 +60,13 @@
56
60
  },
57
61
  "dependencies": {
58
62
  "json-schema-typed": "^8.0.1",
59
- "@amritk/helpers": "^0.17.0"
63
+ "@amritk/helpers": "^0.19.0"
60
64
  },
61
65
  "devDependencies": {
62
- "@amritk/generate-markdown": "^0.5.0",
66
+ "@amritk/generate-markdown": "^0.6.0",
63
67
  "@sinclair/typebox": "^0.34.49",
64
68
  "ajv": "^8.17.1",
69
+ "benny": "^3.7.1",
65
70
  "zod": "^4.4.3"
66
71
  }
67
72
  }