@maroonedog/luq 2.4.4 → 2.5.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.
Files changed (40) hide show
  1. package/README.md +41 -3
  2. package/dist/json-schema/array-keyword-guards.d.ts +31 -0
  3. package/dist/json-schema/array-keyword-guards.js +120 -0
  4. package/dist/json-schema/array-keyword-guards.mjs +114 -0
  5. package/dist/json-schema/assert-object-keyword-values.d.ts +59 -0
  6. package/dist/json-schema/assert-object-keyword-values.js +149 -0
  7. package/dist/json-schema/assert-object-keyword-values.mjs +141 -0
  8. package/dist/json-schema/collect-definitions.d.ts +7 -0
  9. package/dist/json-schema/collect-definitions.js +9 -0
  10. package/dist/json-schema/collect-definitions.mjs +10 -1
  11. package/dist/json-schema/declare-additional-properties.d.ts +11 -1
  12. package/dist/json-schema/declare-additional-properties.js +13 -1
  13. package/dist/json-schema/declare-additional-properties.mjs +13 -1
  14. package/dist/json-schema/declare-object-keywords.d.ts +4 -0
  15. package/dist/json-schema/declare-object-keywords.js +11 -4
  16. package/dist/json-schema/declare-object-keywords.mjs +11 -4
  17. package/dist/json-schema/declare-required-properties.js +6 -0
  18. package/dist/json-schema/declare-required-properties.mjs +6 -0
  19. package/dist/json-schema/declare-value-keywords.d.ts +10 -1
  20. package/dist/json-schema/declare-value-keywords.js +43 -4
  21. package/dist/json-schema/declare-value-keywords.mjs +43 -4
  22. package/dist/json-schema/extensions/json-schema/index.d.ts +1 -1
  23. package/dist/json-schema/extensions/json-schema/index.js +2 -1
  24. package/dist/json-schema/extensions/json-schema/index.mjs +1 -1
  25. package/dist/json-schema/flatten-array-schema.d.ts +11 -1
  26. package/dist/json-schema/flatten-array-schema.js +20 -7
  27. package/dist/json-schema/flatten-array-schema.mjs +20 -7
  28. package/dist/json-schema/index.d.ts +1 -0
  29. package/dist/json-schema/index.js +3 -1
  30. package/dist/json-schema/index.mjs +1 -0
  31. package/dist/json-schema/keyword-map-string.js +30 -1
  32. package/dist/json-schema/keyword-map-string.mjs +30 -1
  33. package/dist/json-schema/keyword-map.js +2 -0
  34. package/dist/json-schema/keyword-map.mjs +2 -0
  35. package/dist/json-schema/malformed-schema-error.d.ts +38 -0
  36. package/dist/json-schema/malformed-schema-error.js +103 -0
  37. package/dist/json-schema/malformed-schema-error.mjs +98 -0
  38. package/dist/plugins/one-of/one-of.js +18 -4
  39. package/dist/plugins/one-of/one-of.mjs +18 -4
  40. package/package.json +3 -3
@@ -36,7 +36,10 @@ function describeAllowed(allowed) {
36
36
  function areAllMembersPrimitive(allowed) {
37
37
  return allowed.every((member) => member === null || typeof member !== "object");
38
38
  }
39
- /** One membership test, decided ONCE at build time and never re-decided. */
39
+ /** One membership test, decided ONCE at build time and never re-decided. The
40
+ * list must already be a snapshot: the linear path CLOSES OVER it rather than
41
+ * copying it into a Set, so a caller-owned array reaching here would stay
42
+ * readable — and mutable — through the returned validator. */
40
43
  function createMembershipTest(allowed) {
41
44
  if (allowed.length > SET_MEMBERSHIP_THRESHOLD &&
42
45
  areAllMembersPrimitive(allowed)) {
@@ -53,13 +56,24 @@ exports.oneOfPlugin = (0, plugin_definition_1.definePlugin)()({
53
56
  if (!(0, types_1.isArray)(allowed) || allowed.length === 0) {
54
57
  throw new plugin_definition_1.PluginArgumentError(ctx.pluginName, "allowed", allowed);
55
58
  }
56
- const isMember = createMembershipTest(allowed);
57
- const rendered = describeAllowed(allowed);
59
+ // A built validator is a SNAPSHOT of what it was built from, and this list
60
+ // arrives BY REFERENCE: reached through the `enum` keyword it is the very
61
+ // array inside the caller's schema document. Without this copy, appending
62
+ // to that array in place after build() — a config reload that mutates the
63
+ // document rather than replacing it — silently widens a validator that is
64
+ // already serving traffic. It would also do so only SOMETIMES: the Set
65
+ // path in createMembershipTest copies and the linear path does not, so the
66
+ // behaviour would flip at a member count the caller has no reason to know
67
+ // about. Copying here, at the one point where the caller's array enters
68
+ // the plugin, is what makes both paths and the reported `expected` agree.
69
+ const members = Object.freeze(allowed.slice());
70
+ const isMember = createMembershipTest(members);
71
+ const rendered = describeAllowed(members);
58
72
  return (0, create_rule_1.check)({
59
73
  code: ctx.code,
60
74
  messageFactory: ctx.messageFactory,
61
75
  severity: ctx.severity,
62
- run: (value) => isMember(value) ? types_1.PASS : (0, types_1.fail)({ expected: allowed, actual: value }),
76
+ run: (value) => isMember(value) ? types_1.PASS : (0, types_1.fail)({ expected: members, actual: value }),
63
77
  describe: () => `Value must be one of: ${rendered}`,
64
78
  buildMessageContext: () => ({}),
65
79
  });
@@ -33,7 +33,10 @@ function describeAllowed(allowed) {
33
33
  function areAllMembersPrimitive(allowed) {
34
34
  return allowed.every((member) => member === null || typeof member !== "object");
35
35
  }
36
- /** One membership test, decided ONCE at build time and never re-decided. */
36
+ /** One membership test, decided ONCE at build time and never re-decided. The
37
+ * list must already be a snapshot: the linear path CLOSES OVER it rather than
38
+ * copying it into a Set, so a caller-owned array reaching here would stay
39
+ * readable — and mutable — through the returned validator. */
37
40
  function createMembershipTest(allowed) {
38
41
  if (allowed.length > SET_MEMBERSHIP_THRESHOLD &&
39
42
  areAllMembersPrimitive(allowed)) {
@@ -50,13 +53,24 @@ export const oneOfPlugin = /*#__PURE__*/ definePlugin()({
50
53
  if (!isArray(allowed) || allowed.length === 0) {
51
54
  throw new PluginArgumentError(ctx.pluginName, "allowed", allowed);
52
55
  }
53
- const isMember = createMembershipTest(allowed);
54
- const rendered = describeAllowed(allowed);
56
+ // A built validator is a SNAPSHOT of what it was built from, and this list
57
+ // arrives BY REFERENCE: reached through the `enum` keyword it is the very
58
+ // array inside the caller's schema document. Without this copy, appending
59
+ // to that array in place after build() — a config reload that mutates the
60
+ // document rather than replacing it — silently widens a validator that is
61
+ // already serving traffic. It would also do so only SOMETIMES: the Set
62
+ // path in createMembershipTest copies and the linear path does not, so the
63
+ // behaviour would flip at a member count the caller has no reason to know
64
+ // about. Copying here, at the one point where the caller's array enters
65
+ // the plugin, is what makes both paths and the reported `expected` agree.
66
+ const members = Object.freeze(allowed.slice());
67
+ const isMember = createMembershipTest(members);
68
+ const rendered = describeAllowed(members);
55
69
  return check({
56
70
  code: ctx.code,
57
71
  messageFactory: ctx.messageFactory,
58
72
  severity: ctx.severity,
59
- run: (value) => isMember(value) ? PASS : fail({ expected: allowed, actual: value }),
73
+ run: (value) => isMember(value) ? PASS : fail({ expected: members, actual: value }),
60
74
  describe: () => `Value must be one of: ${rendered}`,
61
75
  buildMessageContext: () => ({}),
62
76
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@maroonedog/luq",
3
- "version": "2.4.4",
3
+ "version": "2.5.0",
4
4
  "description": "Universal Model & API Definition Platform - TypeScript validation library evolving into cross-language code generation",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -538,9 +538,9 @@
538
538
  "ts-node": "^10.9.2",
539
539
  "tsx": "^4.20.3",
540
540
  "typescript": "^5.8.3",
541
- "valibot": "^1.4.2",
541
+ "valibot": "^1.5.0",
542
542
  "yup": "^1.7.1",
543
- "zod": "^4.0.14"
543
+ "zod": "^4.6.2"
544
544
  },
545
545
  "sideEffects": false
546
546
  }