@kalada/core 0.2.0 → 0.3.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 (79) hide show
  1. package/dist/kalada-v1/canonical-input.cjs +133 -0
  2. package/dist/kalada-v1/canonical-input.cjs.map +1 -0
  3. package/dist/kalada-v1/canonical-input.d.cts +25 -0
  4. package/dist/kalada-v1/canonical-input.d.ts +25 -0
  5. package/dist/kalada-v1/canonical-input.js +122 -0
  6. package/dist/kalada-v1/canonical-input.js.map +1 -0
  7. package/dist/kalada-v1/canonicalize.cjs +78 -130
  8. package/dist/kalada-v1/canonicalize.cjs.map +1 -1
  9. package/dist/kalada-v1/canonicalize.d.cts +1 -0
  10. package/dist/kalada-v1/canonicalize.d.ts +1 -0
  11. package/dist/kalada-v1/canonicalize.js +56 -108
  12. package/dist/kalada-v1/canonicalize.js.map +1 -1
  13. package/dist/kalada-v1/codec.cjs +24 -0
  14. package/dist/kalada-v1/codec.cjs.map +1 -1
  15. package/dist/kalada-v1/codec.d.cts +5 -0
  16. package/dist/kalada-v1/codec.d.ts +5 -0
  17. package/dist/kalada-v1/codec.js +24 -0
  18. package/dist/kalada-v1/codec.js.map +1 -1
  19. package/dist/kalada-v1/compile.cjs +15 -1
  20. package/dist/kalada-v1/compile.cjs.map +1 -1
  21. package/dist/kalada-v1/compile.d.cts +1 -0
  22. package/dist/kalada-v1/compile.d.ts +1 -0
  23. package/dist/kalada-v1/compile.js +15 -1
  24. package/dist/kalada-v1/compile.js.map +1 -1
  25. package/dist/kalada-v1/dependencies.cjs +7 -1
  26. package/dist/kalada-v1/dependencies.cjs.map +1 -1
  27. package/dist/kalada-v1/dependencies.d.cts +1 -0
  28. package/dist/kalada-v1/dependencies.d.ts +1 -0
  29. package/dist/kalada-v1/dependencies.js +7 -1
  30. package/dist/kalada-v1/dependencies.js.map +1 -1
  31. package/dist/kalada-v1/diagnostics.cjs +6 -1
  32. package/dist/kalada-v1/diagnostics.cjs.map +1 -1
  33. package/dist/kalada-v1/diagnostics.d.cts +1 -0
  34. package/dist/kalada-v1/diagnostics.d.ts +1 -0
  35. package/dist/kalada-v1/diagnostics.js +6 -1
  36. package/dist/kalada-v1/diagnostics.js.map +1 -1
  37. package/dist/kalada-v1/evaluate.cjs +38 -3
  38. package/dist/kalada-v1/evaluate.cjs.map +1 -1
  39. package/dist/kalada-v1/evaluate.d.cts +3 -2
  40. package/dist/kalada-v1/evaluate.d.ts +3 -2
  41. package/dist/kalada-v1/evaluate.js +39 -4
  42. package/dist/kalada-v1/evaluate.js.map +1 -1
  43. package/dist/kalada-v1/factories.cjs +18 -0
  44. package/dist/kalada-v1/factories.cjs.map +1 -1
  45. package/dist/kalada-v1/factories.d.cts +8 -0
  46. package/dist/kalada-v1/factories.d.ts +8 -0
  47. package/dist/kalada-v1/factories.js +18 -0
  48. package/dist/kalada-v1/factories.js.map +1 -1
  49. package/dist/kalada-v1/index.cjs +17 -0
  50. package/dist/kalada-v1/index.d.cts +2 -1
  51. package/dist/kalada-v1/index.d.ts +2 -1
  52. package/dist/kalada-v1/index.js +1 -0
  53. package/dist/kalada-v1/limits.d.cts +1 -0
  54. package/dist/kalada-v1/limits.d.ts +1 -0
  55. package/dist/kalada-v1/schemas.cjs +29 -1
  56. package/dist/kalada-v1/schemas.cjs.map +1 -1
  57. package/dist/kalada-v1/schemas.js +29 -1
  58. package/dist/kalada-v1/schemas.js.map +1 -1
  59. package/dist/kalada-v1/temporal-evaluation.cjs +74 -0
  60. package/dist/kalada-v1/temporal-evaluation.cjs.map +1 -0
  61. package/dist/kalada-v1/temporal-evaluation.d.cts +13 -0
  62. package/dist/kalada-v1/temporal-evaluation.d.ts +13 -0
  63. package/dist/kalada-v1/temporal-evaluation.js +71 -0
  64. package/dist/kalada-v1/temporal-evaluation.js.map +1 -0
  65. package/dist/kalada-v1/temporal.cjs +42 -0
  66. package/dist/kalada-v1/temporal.cjs.map +1 -0
  67. package/dist/kalada-v1/temporal.d.cts +22 -0
  68. package/dist/kalada-v1/temporal.d.ts +22 -0
  69. package/dist/kalada-v1/temporal.js +37 -0
  70. package/dist/kalada-v1/temporal.js.map +1 -0
  71. package/dist/kalada-v1/types.d.cts +33 -4
  72. package/dist/kalada-v1/types.d.ts +33 -4
  73. package/dist/kalada-v1/values.cjs +13 -1
  74. package/dist/kalada-v1/values.cjs.map +1 -1
  75. package/dist/kalada-v1/values.d.cts +2 -1
  76. package/dist/kalada-v1/values.d.ts +2 -1
  77. package/dist/kalada-v1/values.js +13 -1
  78. package/dist/kalada-v1/values.js.map +1 -1
  79. package/package.json +1 -1
@@ -0,0 +1,133 @@
1
+ 'use strict';
2
+
3
+ var diagnostics_js = require('./diagnostics.js');
4
+ var json_js = require('./json.js');
5
+
6
+ function properties(input, path, allowed, requireExact = true) {
7
+ if (typeof input !== "object" || input === null || Array.isArray(input)) {
8
+ throw new diagnostics_js.KaladaFailure("KALADA_INVALID_INPUT", path);
9
+ }
10
+ let keys;
11
+ try {
12
+ keys = Reflect.ownKeys(input);
13
+ } catch {
14
+ throw new diagnostics_js.KaladaFailure("KALADA_INVALID_INPUT", path);
15
+ }
16
+ const output = {};
17
+ for (const key of keys) {
18
+ if (typeof key !== "string" || !allowed.has(key)) {
19
+ throw new diagnostics_js.KaladaFailure("KALADA_INVALID_INPUT", [...path, String(key)]);
20
+ }
21
+ try {
22
+ output[key] = json_js.dataValue(input, key);
23
+ } catch {
24
+ throw new diagnostics_js.KaladaFailure("KALADA_INVALID_INPUT", [...path, key]);
25
+ }
26
+ }
27
+ if (requireExact && keys.length !== allowed.size) {
28
+ throw new diagnostics_js.KaladaFailure("KALADA_INVALID_INPUT", path);
29
+ }
30
+ return output;
31
+ }
32
+ function exact(raw, path, keys, optionalLast = false) {
33
+ const minimum = optionalLast ? keys.length - 1 : keys.length;
34
+ if (Object.keys(raw).length < minimum || Object.keys(raw).length > keys.length) {
35
+ throw new diagnostics_js.KaladaFailure("KALADA_INVALID_INPUT", path);
36
+ }
37
+ for (let index = 0; index < minimum; index += 1) {
38
+ const key = keys[index];
39
+ if (key !== void 0 && !(key in raw)) {
40
+ throw new diagnostics_js.KaladaFailure("KALADA_INVALID_INPUT", [...path, key]);
41
+ }
42
+ }
43
+ for (const key of Object.keys(raw)) {
44
+ if (!keys.includes(key)) throw new diagnostics_js.KaladaFailure("KALADA_INVALID_INPUT", [...path, key]);
45
+ }
46
+ }
47
+ function strictArray(input, path) {
48
+ let keys;
49
+ try {
50
+ keys = Reflect.ownKeys(input);
51
+ } catch {
52
+ throw new diagnostics_js.KaladaFailure("KALADA_INVALID_INPUT", path);
53
+ }
54
+ if (keys.length !== input.length + 1) throw new diagnostics_js.KaladaFailure("KALADA_INVALID_INPUT", path);
55
+ return Array.from({ length: input.length }, (_, index) => {
56
+ try {
57
+ return json_js.dataValue(input, String(index));
58
+ } catch {
59
+ throw new diagnostics_js.KaladaFailure("KALADA_INVALID_INPUT", [...path, index]);
60
+ }
61
+ });
62
+ }
63
+ function safeJson(input, path, state) {
64
+ try {
65
+ const result = json_js.cloneJsonWithStats(input, {
66
+ maxDepth: state.limits.maxValueDepth,
67
+ maxNodes: state.limits.maxValueNodes - state.valueNodes,
68
+ maxStringLength: state.limits.maxStringLength
69
+ });
70
+ state.valueNodes += result.nodes;
71
+ return result.value;
72
+ } catch (error) {
73
+ if (error instanceof RangeError) throw new diagnostics_js.KaladaFailure("KALADA_LIMIT_EXCEEDED", path);
74
+ throw new diagnostics_js.KaladaFailure("KALADA_INVALID_INPUT", path);
75
+ }
76
+ }
77
+ function inspectJson(input, path, state) {
78
+ try {
79
+ return json_js.cloneJson(input, {
80
+ maxDepth: state.limits.maxValueDepth,
81
+ maxNodes: state.limits.maxValueNodes,
82
+ maxStringLength: state.limits.maxStringLength
83
+ });
84
+ } catch (error) {
85
+ if (error instanceof RangeError) throw new diagnostics_js.KaladaFailure("KALADA_LIMIT_EXCEEDED", path);
86
+ throw new diagnostics_js.KaladaFailure("KALADA_INVALID_INPUT", path);
87
+ }
88
+ }
89
+ function referenceLength(reference) {
90
+ return typeof reference === "string" ? [...reference].length : [...json_js.canonicalJsonIdentity(reference)].length;
91
+ }
92
+ function bindingName(input, path, limits) {
93
+ if (typeof input !== "string" || input.length === 0) {
94
+ throw new diagnostics_js.KaladaFailure("KALADA_INVALID_INPUT", path);
95
+ }
96
+ if ([...input].length > limits.maxReferenceLength) {
97
+ throw new diagnostics_js.KaladaFailure("KALADA_LIMIT_EXCEEDED", path);
98
+ }
99
+ return input;
100
+ }
101
+ function safeValidate(validate, input) {
102
+ try {
103
+ return validate(input) === true;
104
+ } catch {
105
+ return false;
106
+ }
107
+ }
108
+ function safeCanonicalize(canonicalize, input, path) {
109
+ try {
110
+ return canonicalize(input);
111
+ } catch {
112
+ throw new diagnostics_js.KaladaFailure("KALADA_INVALID_REFERENCE", path);
113
+ }
114
+ }
115
+ function count(path, depth, state) {
116
+ state.astNodes += 1;
117
+ if (depth > state.limits.maxAstDepth || state.astNodes > state.limits.maxAstNodes) {
118
+ throw new diagnostics_js.KaladaFailure("KALADA_LIMIT_EXCEEDED", path);
119
+ }
120
+ }
121
+
122
+ exports.bindingName = bindingName;
123
+ exports.count = count;
124
+ exports.exact = exact;
125
+ exports.inspectJson = inspectJson;
126
+ exports.properties = properties;
127
+ exports.referenceLength = referenceLength;
128
+ exports.safeCanonicalize = safeCanonicalize;
129
+ exports.safeJson = safeJson;
130
+ exports.safeValidate = safeValidate;
131
+ exports.strictArray = strictArray;
132
+ //# sourceMappingURL=canonical-input.cjs.map
133
+ //# sourceMappingURL=canonical-input.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/kalada-v1/canonical-input.ts"],"names":["KaladaFailure","dataValue","cloneJsonWithStats","cloneJson","canonicalJsonIdentity"],"mappings":"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","file":"canonical-input.cjs","sourcesContent":["import { KaladaFailure } from \"./diagnostics.js\";\nimport {\n canonicalJsonIdentity,\n cloneJson,\n cloneJsonWithStats,\n dataValue,\n type JsonValue,\n} from \"./json.js\";\nimport type { KaladaV1Limits, KaladaV1Options } from \"./types.js\";\n\nexport type Path = readonly (string | number)[];\nexport interface CanonicalState<R extends JsonValue> {\n readonly limits: KaladaV1Limits;\n readonly options: KaladaV1Options<R>;\n readonly active: WeakSet<object>;\n astNodes: number;\n valueNodes: number;\n}\n\nexport function properties(\n input: unknown,\n path: Path,\n allowed: ReadonlySet<string>,\n requireExact = true,\n): Record<string, unknown> {\n if (typeof input !== \"object\" || input === null || Array.isArray(input)) {\n throw new KaladaFailure(\"KALADA_INVALID_INPUT\", path);\n }\n let keys: PropertyKey[];\n try {\n keys = Reflect.ownKeys(input);\n } catch {\n throw new KaladaFailure(\"KALADA_INVALID_INPUT\", path);\n }\n const output: Record<string, unknown> = {};\n for (const key of keys) {\n if (typeof key !== \"string\" || !allowed.has(key)) {\n throw new KaladaFailure(\"KALADA_INVALID_INPUT\", [...path, String(key)]);\n }\n try {\n output[key] = dataValue(input, key);\n } catch {\n throw new KaladaFailure(\"KALADA_INVALID_INPUT\", [...path, key]);\n }\n }\n if (requireExact && keys.length !== allowed.size) {\n throw new KaladaFailure(\"KALADA_INVALID_INPUT\", path);\n }\n return output;\n}\n\nexport function exact(\n raw: Record<string, unknown>,\n path: Path,\n keys: readonly string[],\n optionalLast = false,\n): void {\n const minimum = optionalLast ? keys.length - 1 : keys.length;\n if (Object.keys(raw).length < minimum || Object.keys(raw).length > keys.length) {\n throw new KaladaFailure(\"KALADA_INVALID_INPUT\", path);\n }\n for (let index = 0; index < minimum; index += 1) {\n const key = keys[index];\n if (key !== undefined && !(key in raw)) {\n throw new KaladaFailure(\"KALADA_INVALID_INPUT\", [...path, key]);\n }\n }\n for (const key of Object.keys(raw)) {\n if (!keys.includes(key)) throw new KaladaFailure(\"KALADA_INVALID_INPUT\", [...path, key]);\n }\n}\n\nexport function strictArray(input: unknown[], path: Path): unknown[] {\n let keys: PropertyKey[];\n try {\n keys = Reflect.ownKeys(input);\n } catch {\n throw new KaladaFailure(\"KALADA_INVALID_INPUT\", path);\n }\n if (keys.length !== input.length + 1) throw new KaladaFailure(\"KALADA_INVALID_INPUT\", path);\n return Array.from({ length: input.length }, (_, index) => {\n try {\n return dataValue(input, String(index));\n } catch {\n throw new KaladaFailure(\"KALADA_INVALID_INPUT\", [...path, index]);\n }\n });\n}\n\nexport function safeJson<R extends JsonValue>(\n input: unknown,\n path: Path,\n state: CanonicalState<R>,\n): JsonValue {\n try {\n const result = cloneJsonWithStats(input, {\n maxDepth: state.limits.maxValueDepth,\n maxNodes: state.limits.maxValueNodes - state.valueNodes,\n maxStringLength: state.limits.maxStringLength,\n });\n state.valueNodes += result.nodes;\n return result.value;\n } catch (error) {\n if (error instanceof RangeError) throw new KaladaFailure(\"KALADA_LIMIT_EXCEEDED\", path);\n throw new KaladaFailure(\"KALADA_INVALID_INPUT\", path);\n }\n}\n\nexport function inspectJson<R extends JsonValue>(\n input: unknown,\n path: Path,\n state: CanonicalState<R>,\n): JsonValue {\n try {\n return cloneJson(input, {\n maxDepth: state.limits.maxValueDepth,\n maxNodes: state.limits.maxValueNodes,\n maxStringLength: state.limits.maxStringLength,\n });\n } catch (error) {\n if (error instanceof RangeError) throw new KaladaFailure(\"KALADA_LIMIT_EXCEEDED\", path);\n throw new KaladaFailure(\"KALADA_INVALID_INPUT\", path);\n }\n}\n\nexport function referenceLength(reference: JsonValue): number {\n return typeof reference === \"string\"\n ? [...reference].length\n : [...canonicalJsonIdentity(reference)].length;\n}\n\nexport function bindingName(input: unknown, path: Path, limits: KaladaV1Limits): string {\n if (typeof input !== \"string\" || input.length === 0) {\n throw new KaladaFailure(\"KALADA_INVALID_INPUT\", path);\n }\n if ([...input].length > limits.maxReferenceLength) {\n throw new KaladaFailure(\"KALADA_LIMIT_EXCEEDED\", path);\n }\n return input;\n}\n\nexport function safeValidate<R>(\n validate: (input: unknown) => input is R,\n input: unknown,\n): input is R {\n try {\n return validate(input) === true;\n } catch {\n return false;\n }\n}\n\nexport function safeCanonicalize<R>(canonicalize: (input: R) => R, input: R, path: Path): R {\n try {\n return canonicalize(input);\n } catch {\n throw new KaladaFailure(\"KALADA_INVALID_REFERENCE\", path);\n }\n}\n\nexport function count<R extends JsonValue>(\n path: Path,\n depth: number,\n state: CanonicalState<R>,\n): void {\n state.astNodes += 1;\n if (depth > state.limits.maxAstDepth || state.astNodes > state.limits.maxAstNodes) {\n throw new KaladaFailure(\"KALADA_LIMIT_EXCEEDED\", path);\n }\n}\n"]}
@@ -0,0 +1,25 @@
1
+ import { JsonValue } from './json.cjs';
2
+ import { KaladaV1Limits, KaladaV1Options } from './types.cjs';
3
+ import './temporal.cjs';
4
+ import './values.cjs';
5
+
6
+ type Path = readonly (string | number)[];
7
+ interface CanonicalState<R extends JsonValue> {
8
+ readonly limits: KaladaV1Limits;
9
+ readonly options: KaladaV1Options<R>;
10
+ readonly active: WeakSet<object>;
11
+ astNodes: number;
12
+ valueNodes: number;
13
+ }
14
+ declare function properties(input: unknown, path: Path, allowed: ReadonlySet<string>, requireExact?: boolean): Record<string, unknown>;
15
+ declare function exact(raw: Record<string, unknown>, path: Path, keys: readonly string[], optionalLast?: boolean): void;
16
+ declare function strictArray(input: unknown[], path: Path): unknown[];
17
+ declare function safeJson<R extends JsonValue>(input: unknown, path: Path, state: CanonicalState<R>): JsonValue;
18
+ declare function inspectJson<R extends JsonValue>(input: unknown, path: Path, state: CanonicalState<R>): JsonValue;
19
+ declare function referenceLength(reference: JsonValue): number;
20
+ declare function bindingName(input: unknown, path: Path, limits: KaladaV1Limits): string;
21
+ declare function safeValidate<R>(validate: (input: unknown) => input is R, input: unknown): input is R;
22
+ declare function safeCanonicalize<R>(canonicalize: (input: R) => R, input: R, path: Path): R;
23
+ declare function count<R extends JsonValue>(path: Path, depth: number, state: CanonicalState<R>): void;
24
+
25
+ export { type CanonicalState, type Path, bindingName, count, exact, inspectJson, properties, referenceLength, safeCanonicalize, safeJson, safeValidate, strictArray };
@@ -0,0 +1,25 @@
1
+ import { JsonValue } from './json.js';
2
+ import { KaladaV1Limits, KaladaV1Options } from './types.js';
3
+ import './temporal.js';
4
+ import './values.js';
5
+
6
+ type Path = readonly (string | number)[];
7
+ interface CanonicalState<R extends JsonValue> {
8
+ readonly limits: KaladaV1Limits;
9
+ readonly options: KaladaV1Options<R>;
10
+ readonly active: WeakSet<object>;
11
+ astNodes: number;
12
+ valueNodes: number;
13
+ }
14
+ declare function properties(input: unknown, path: Path, allowed: ReadonlySet<string>, requireExact?: boolean): Record<string, unknown>;
15
+ declare function exact(raw: Record<string, unknown>, path: Path, keys: readonly string[], optionalLast?: boolean): void;
16
+ declare function strictArray(input: unknown[], path: Path): unknown[];
17
+ declare function safeJson<R extends JsonValue>(input: unknown, path: Path, state: CanonicalState<R>): JsonValue;
18
+ declare function inspectJson<R extends JsonValue>(input: unknown, path: Path, state: CanonicalState<R>): JsonValue;
19
+ declare function referenceLength(reference: JsonValue): number;
20
+ declare function bindingName(input: unknown, path: Path, limits: KaladaV1Limits): string;
21
+ declare function safeValidate<R>(validate: (input: unknown) => input is R, input: unknown): input is R;
22
+ declare function safeCanonicalize<R>(canonicalize: (input: R) => R, input: R, path: Path): R;
23
+ declare function count<R extends JsonValue>(path: Path, depth: number, state: CanonicalState<R>): void;
24
+
25
+ export { type CanonicalState, type Path, bindingName, count, exact, inspectJson, properties, referenceLength, safeCanonicalize, safeJson, safeValidate, strictArray };
@@ -0,0 +1,122 @@
1
+ import { KaladaFailure } from './diagnostics.js';
2
+ import { dataValue, cloneJsonWithStats, cloneJson, canonicalJsonIdentity } from './json.js';
3
+
4
+ function properties(input, path, allowed, requireExact = true) {
5
+ if (typeof input !== "object" || input === null || Array.isArray(input)) {
6
+ throw new KaladaFailure("KALADA_INVALID_INPUT", path);
7
+ }
8
+ let keys;
9
+ try {
10
+ keys = Reflect.ownKeys(input);
11
+ } catch {
12
+ throw new KaladaFailure("KALADA_INVALID_INPUT", path);
13
+ }
14
+ const output = {};
15
+ for (const key of keys) {
16
+ if (typeof key !== "string" || !allowed.has(key)) {
17
+ throw new KaladaFailure("KALADA_INVALID_INPUT", [...path, String(key)]);
18
+ }
19
+ try {
20
+ output[key] = dataValue(input, key);
21
+ } catch {
22
+ throw new KaladaFailure("KALADA_INVALID_INPUT", [...path, key]);
23
+ }
24
+ }
25
+ if (requireExact && keys.length !== allowed.size) {
26
+ throw new KaladaFailure("KALADA_INVALID_INPUT", path);
27
+ }
28
+ return output;
29
+ }
30
+ function exact(raw, path, keys, optionalLast = false) {
31
+ const minimum = optionalLast ? keys.length - 1 : keys.length;
32
+ if (Object.keys(raw).length < minimum || Object.keys(raw).length > keys.length) {
33
+ throw new KaladaFailure("KALADA_INVALID_INPUT", path);
34
+ }
35
+ for (let index = 0; index < minimum; index += 1) {
36
+ const key = keys[index];
37
+ if (key !== void 0 && !(key in raw)) {
38
+ throw new KaladaFailure("KALADA_INVALID_INPUT", [...path, key]);
39
+ }
40
+ }
41
+ for (const key of Object.keys(raw)) {
42
+ if (!keys.includes(key)) throw new KaladaFailure("KALADA_INVALID_INPUT", [...path, key]);
43
+ }
44
+ }
45
+ function strictArray(input, path) {
46
+ let keys;
47
+ try {
48
+ keys = Reflect.ownKeys(input);
49
+ } catch {
50
+ throw new KaladaFailure("KALADA_INVALID_INPUT", path);
51
+ }
52
+ if (keys.length !== input.length + 1) throw new KaladaFailure("KALADA_INVALID_INPUT", path);
53
+ return Array.from({ length: input.length }, (_, index) => {
54
+ try {
55
+ return dataValue(input, String(index));
56
+ } catch {
57
+ throw new KaladaFailure("KALADA_INVALID_INPUT", [...path, index]);
58
+ }
59
+ });
60
+ }
61
+ function safeJson(input, path, state) {
62
+ try {
63
+ const result = cloneJsonWithStats(input, {
64
+ maxDepth: state.limits.maxValueDepth,
65
+ maxNodes: state.limits.maxValueNodes - state.valueNodes,
66
+ maxStringLength: state.limits.maxStringLength
67
+ });
68
+ state.valueNodes += result.nodes;
69
+ return result.value;
70
+ } catch (error) {
71
+ if (error instanceof RangeError) throw new KaladaFailure("KALADA_LIMIT_EXCEEDED", path);
72
+ throw new KaladaFailure("KALADA_INVALID_INPUT", path);
73
+ }
74
+ }
75
+ function inspectJson(input, path, state) {
76
+ try {
77
+ return cloneJson(input, {
78
+ maxDepth: state.limits.maxValueDepth,
79
+ maxNodes: state.limits.maxValueNodes,
80
+ maxStringLength: state.limits.maxStringLength
81
+ });
82
+ } catch (error) {
83
+ if (error instanceof RangeError) throw new KaladaFailure("KALADA_LIMIT_EXCEEDED", path);
84
+ throw new KaladaFailure("KALADA_INVALID_INPUT", path);
85
+ }
86
+ }
87
+ function referenceLength(reference) {
88
+ return typeof reference === "string" ? [...reference].length : [...canonicalJsonIdentity(reference)].length;
89
+ }
90
+ function bindingName(input, path, limits) {
91
+ if (typeof input !== "string" || input.length === 0) {
92
+ throw new KaladaFailure("KALADA_INVALID_INPUT", path);
93
+ }
94
+ if ([...input].length > limits.maxReferenceLength) {
95
+ throw new KaladaFailure("KALADA_LIMIT_EXCEEDED", path);
96
+ }
97
+ return input;
98
+ }
99
+ function safeValidate(validate, input) {
100
+ try {
101
+ return validate(input) === true;
102
+ } catch {
103
+ return false;
104
+ }
105
+ }
106
+ function safeCanonicalize(canonicalize, input, path) {
107
+ try {
108
+ return canonicalize(input);
109
+ } catch {
110
+ throw new KaladaFailure("KALADA_INVALID_REFERENCE", path);
111
+ }
112
+ }
113
+ function count(path, depth, state) {
114
+ state.astNodes += 1;
115
+ if (depth > state.limits.maxAstDepth || state.astNodes > state.limits.maxAstNodes) {
116
+ throw new KaladaFailure("KALADA_LIMIT_EXCEEDED", path);
117
+ }
118
+ }
119
+
120
+ export { bindingName, count, exact, inspectJson, properties, referenceLength, safeCanonicalize, safeJson, safeValidate, strictArray };
121
+ //# sourceMappingURL=canonical-input.js.map
122
+ //# sourceMappingURL=canonical-input.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/kalada-v1/canonical-input.ts"],"names":[],"mappings":"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","file":"canonical-input.js","sourcesContent":["import { KaladaFailure } from \"./diagnostics.js\";\nimport {\n canonicalJsonIdentity,\n cloneJson,\n cloneJsonWithStats,\n dataValue,\n type JsonValue,\n} from \"./json.js\";\nimport type { KaladaV1Limits, KaladaV1Options } from \"./types.js\";\n\nexport type Path = readonly (string | number)[];\nexport interface CanonicalState<R extends JsonValue> {\n readonly limits: KaladaV1Limits;\n readonly options: KaladaV1Options<R>;\n readonly active: WeakSet<object>;\n astNodes: number;\n valueNodes: number;\n}\n\nexport function properties(\n input: unknown,\n path: Path,\n allowed: ReadonlySet<string>,\n requireExact = true,\n): Record<string, unknown> {\n if (typeof input !== \"object\" || input === null || Array.isArray(input)) {\n throw new KaladaFailure(\"KALADA_INVALID_INPUT\", path);\n }\n let keys: PropertyKey[];\n try {\n keys = Reflect.ownKeys(input);\n } catch {\n throw new KaladaFailure(\"KALADA_INVALID_INPUT\", path);\n }\n const output: Record<string, unknown> = {};\n for (const key of keys) {\n if (typeof key !== \"string\" || !allowed.has(key)) {\n throw new KaladaFailure(\"KALADA_INVALID_INPUT\", [...path, String(key)]);\n }\n try {\n output[key] = dataValue(input, key);\n } catch {\n throw new KaladaFailure(\"KALADA_INVALID_INPUT\", [...path, key]);\n }\n }\n if (requireExact && keys.length !== allowed.size) {\n throw new KaladaFailure(\"KALADA_INVALID_INPUT\", path);\n }\n return output;\n}\n\nexport function exact(\n raw: Record<string, unknown>,\n path: Path,\n keys: readonly string[],\n optionalLast = false,\n): void {\n const minimum = optionalLast ? keys.length - 1 : keys.length;\n if (Object.keys(raw).length < minimum || Object.keys(raw).length > keys.length) {\n throw new KaladaFailure(\"KALADA_INVALID_INPUT\", path);\n }\n for (let index = 0; index < minimum; index += 1) {\n const key = keys[index];\n if (key !== undefined && !(key in raw)) {\n throw new KaladaFailure(\"KALADA_INVALID_INPUT\", [...path, key]);\n }\n }\n for (const key of Object.keys(raw)) {\n if (!keys.includes(key)) throw new KaladaFailure(\"KALADA_INVALID_INPUT\", [...path, key]);\n }\n}\n\nexport function strictArray(input: unknown[], path: Path): unknown[] {\n let keys: PropertyKey[];\n try {\n keys = Reflect.ownKeys(input);\n } catch {\n throw new KaladaFailure(\"KALADA_INVALID_INPUT\", path);\n }\n if (keys.length !== input.length + 1) throw new KaladaFailure(\"KALADA_INVALID_INPUT\", path);\n return Array.from({ length: input.length }, (_, index) => {\n try {\n return dataValue(input, String(index));\n } catch {\n throw new KaladaFailure(\"KALADA_INVALID_INPUT\", [...path, index]);\n }\n });\n}\n\nexport function safeJson<R extends JsonValue>(\n input: unknown,\n path: Path,\n state: CanonicalState<R>,\n): JsonValue {\n try {\n const result = cloneJsonWithStats(input, {\n maxDepth: state.limits.maxValueDepth,\n maxNodes: state.limits.maxValueNodes - state.valueNodes,\n maxStringLength: state.limits.maxStringLength,\n });\n state.valueNodes += result.nodes;\n return result.value;\n } catch (error) {\n if (error instanceof RangeError) throw new KaladaFailure(\"KALADA_LIMIT_EXCEEDED\", path);\n throw new KaladaFailure(\"KALADA_INVALID_INPUT\", path);\n }\n}\n\nexport function inspectJson<R extends JsonValue>(\n input: unknown,\n path: Path,\n state: CanonicalState<R>,\n): JsonValue {\n try {\n return cloneJson(input, {\n maxDepth: state.limits.maxValueDepth,\n maxNodes: state.limits.maxValueNodes,\n maxStringLength: state.limits.maxStringLength,\n });\n } catch (error) {\n if (error instanceof RangeError) throw new KaladaFailure(\"KALADA_LIMIT_EXCEEDED\", path);\n throw new KaladaFailure(\"KALADA_INVALID_INPUT\", path);\n }\n}\n\nexport function referenceLength(reference: JsonValue): number {\n return typeof reference === \"string\"\n ? [...reference].length\n : [...canonicalJsonIdentity(reference)].length;\n}\n\nexport function bindingName(input: unknown, path: Path, limits: KaladaV1Limits): string {\n if (typeof input !== \"string\" || input.length === 0) {\n throw new KaladaFailure(\"KALADA_INVALID_INPUT\", path);\n }\n if ([...input].length > limits.maxReferenceLength) {\n throw new KaladaFailure(\"KALADA_LIMIT_EXCEEDED\", path);\n }\n return input;\n}\n\nexport function safeValidate<R>(\n validate: (input: unknown) => input is R,\n input: unknown,\n): input is R {\n try {\n return validate(input) === true;\n } catch {\n return false;\n }\n}\n\nexport function safeCanonicalize<R>(canonicalize: (input: R) => R, input: R, path: Path): R {\n try {\n return canonicalize(input);\n } catch {\n throw new KaladaFailure(\"KALADA_INVALID_REFERENCE\", path);\n }\n}\n\nexport function count<R extends JsonValue>(\n path: Path,\n depth: number,\n state: CanonicalState<R>,\n): void {\n state.astNodes += 1;\n if (depth > state.limits.maxAstDepth || state.astNodes > state.limits.maxAstNodes) {\n throw new KaladaFailure(\"KALADA_LIMIT_EXCEEDED\", path);\n }\n}\n"]}
@@ -1,15 +1,28 @@
1
1
  'use strict';
2
2
 
3
+ var canonicalInput_js = require('./canonical-input.js');
3
4
  var diagnostics_js = require('./diagnostics.js');
4
- var json_js = require('./json.js');
5
5
  var limits_js = require('./limits.js');
6
6
 
7
- const NODE_KEYS = /* @__PURE__ */ new Set(["kind", "value", "ref", "name", "body", "variant", "type", "arms"]);
7
+ const NODE_KEYS = /* @__PURE__ */ new Set([
8
+ "kind",
9
+ "value",
10
+ "ref",
11
+ "name",
12
+ "body",
13
+ "variant",
14
+ "type",
15
+ "arms",
16
+ "milliseconds",
17
+ "operator",
18
+ "left",
19
+ "right"
20
+ ]);
8
21
  const ARM_ORDER = Object.freeze({ Option: ["some", "none"], Result: ["ok", "err"] });
9
22
  function canonicalizeKaladaV1Program(input, options = {}) {
10
23
  try {
11
24
  const limits = limits_js.resolveLimits(options.limits);
12
- const fields = properties(input, [], /* @__PURE__ */ new Set(["format", "version", "profile", "expression"]));
25
+ const fields = canonicalInput_js.properties(input, [], /* @__PURE__ */ new Set(["format", "version", "profile", "expression"]));
13
26
  if (fields.format !== "kalada-program" || fields.version !== 1 || fields.profile !== "kalada-v1") {
14
27
  throw new diagnostics_js.KaladaFailure("KALADA_INVALID_INPUT", []);
15
28
  }
@@ -30,50 +43,91 @@ function canonicalizeKaladaV1Program(input, options = {}) {
30
43
  }
31
44
  }
32
45
  function canonicalNode(input, path, depth, state) {
33
- count(path, depth, state);
46
+ canonicalInput_js.count(path, depth, state);
34
47
  if (typeof input !== "object" || input === null || state.active.has(input)) {
35
48
  throw new diagnostics_js.KaladaFailure("KALADA_INVALID_INPUT", path);
36
49
  }
37
50
  state.active.add(input);
38
51
  try {
39
- const raw = properties(input, path, NODE_KEYS, false);
52
+ const raw = canonicalInput_js.properties(input, path, NODE_KEYS, false);
40
53
  if (raw.kind === "literal") return canonicalLiteral(raw, path, state);
41
54
  if (raw.kind === "ref") return canonicalReference(raw, path, state);
42
55
  if (raw.kind === "binding") return canonicalBinding(raw, path, depth, state);
43
56
  if (raw.kind === "option") return canonicalOption(raw, path, depth, state);
44
57
  if (raw.kind === "result") return canonicalResult(raw, path, depth, state);
45
58
  if (raw.kind === "match") return canonicalMatch(raw, path, depth, state);
59
+ if (raw.kind === "instant" || raw.kind === "duration") return canonicalTemporal(raw, path);
60
+ if (raw.kind === "current-instant") return canonicalCurrentInstant(raw, path);
61
+ if (raw.kind === "temporal-arithmetic") {
62
+ return canonicalTemporalOperation(raw, path, depth, state, ["add", "subtract"]);
63
+ }
64
+ if (raw.kind === "temporal-comparison") {
65
+ return canonicalTemporalOperation(raw, path, depth, state, [
66
+ "equal",
67
+ "not-equal",
68
+ "less-than",
69
+ "less-than-or-equal",
70
+ "greater-than",
71
+ "greater-than-or-equal"
72
+ ]);
73
+ }
46
74
  throw new diagnostics_js.KaladaFailure("KALADA_INVALID_INPUT", [...path, "kind"]);
47
75
  } finally {
48
76
  state.active.delete(input);
49
77
  }
50
78
  }
79
+ function canonicalTemporal(raw, path) {
80
+ canonicalInput_js.exact(raw, path, ["kind", "milliseconds"]);
81
+ if (!Number.isSafeInteger(raw.milliseconds)) {
82
+ throw new diagnostics_js.KaladaFailure("KALADA_INVALID_INPUT", [...path, "milliseconds"]);
83
+ }
84
+ return Object.freeze({
85
+ kind: raw.kind,
86
+ milliseconds: Object.is(raw.milliseconds, -0) ? 0 : raw.milliseconds
87
+ });
88
+ }
89
+ function canonicalCurrentInstant(raw, path) {
90
+ canonicalInput_js.exact(raw, path, ["kind"]);
91
+ return Object.freeze({ kind: "current-instant" });
92
+ }
93
+ function canonicalTemporalOperation(raw, path, depth, state, operators) {
94
+ canonicalInput_js.exact(raw, path, ["kind", "operator", "left", "right"]);
95
+ if (typeof raw.operator !== "string" || !operators.includes(raw.operator)) {
96
+ throw new diagnostics_js.KaladaFailure("KALADA_INVALID_INPUT", [...path, "operator"]);
97
+ }
98
+ return Object.freeze({
99
+ kind: raw.kind,
100
+ operator: raw.operator,
101
+ left: canonicalNode(raw.left, [...path, "left"], depth + 1, state),
102
+ right: canonicalNode(raw.right, [...path, "right"], depth + 1, state)
103
+ });
104
+ }
51
105
  function canonicalLiteral(raw, path, state) {
52
- exact(raw, path, ["kind", "value"]);
106
+ canonicalInput_js.exact(raw, path, ["kind", "value"]);
53
107
  return Object.freeze({
54
108
  kind: "literal",
55
- value: safeJson(raw.value, [...path, "value"], state)
109
+ value: canonicalInput_js.safeJson(raw.value, [...path, "value"], state)
56
110
  });
57
111
  }
58
112
  function canonicalReference(raw, path, state) {
59
- exact(raw, path, ["kind", "ref"]);
113
+ canonicalInput_js.exact(raw, path, ["kind", "ref"]);
60
114
  const refPath = [...path, "ref"];
61
115
  const codec = state.options.reference;
62
- const ref = codec ? inspectJson(raw.ref, refPath, state) : safeJson(raw.ref, refPath, state);
63
- if (codec ? !safeValidate(codec.validate, ref) : typeof ref !== "string" || ref.length === 0) {
116
+ const ref = codec ? canonicalInput_js.inspectJson(raw.ref, refPath, state) : canonicalInput_js.safeJson(raw.ref, refPath, state);
117
+ if (codec ? !canonicalInput_js.safeValidate(codec.validate, ref) : typeof ref !== "string" || ref.length === 0) {
64
118
  throw new diagnostics_js.KaladaFailure("KALADA_INVALID_REFERENCE", refPath);
65
119
  }
66
- const replacement = codec?.canonicalize ? safeCanonicalize(codec.canonicalize, ref, refPath) : ref;
67
- const output = codec ? safeJson(replacement, refPath, state) : replacement;
68
- if (codec && !safeValidate(codec.validate, output))
120
+ const replacement = codec?.canonicalize ? canonicalInput_js.safeCanonicalize(codec.canonicalize, ref, refPath) : ref;
121
+ const output = codec ? canonicalInput_js.safeJson(replacement, refPath, state) : replacement;
122
+ if (codec && !canonicalInput_js.safeValidate(codec.validate, output))
69
123
  throw new diagnostics_js.KaladaFailure("KALADA_INVALID_REFERENCE", refPath);
70
- if (referenceLength(output) > state.limits.maxReferenceLength)
124
+ if (canonicalInput_js.referenceLength(output) > state.limits.maxReferenceLength)
71
125
  throw new diagnostics_js.KaladaFailure("KALADA_LIMIT_EXCEEDED", refPath);
72
126
  return Object.freeze({ kind: "ref", ref: output });
73
127
  }
74
128
  function canonicalBinding(raw, path, depth, state) {
75
- exact(raw, path, ["kind", "name", "value", "body"]);
76
- const name = bindingName(raw.name, [...path, "name"], state.limits);
129
+ canonicalInput_js.exact(raw, path, ["kind", "name", "value", "body"]);
130
+ const name = canonicalInput_js.bindingName(raw.name, [...path, "name"], state.limits);
77
131
  return Object.freeze({
78
132
  kind: "binding",
79
133
  name,
@@ -83,11 +137,11 @@ function canonicalBinding(raw, path, depth, state) {
83
137
  }
84
138
  function canonicalOption(raw, path, depth, state) {
85
139
  if (raw.variant === "none") {
86
- exact(raw, path, ["kind", "variant"]);
140
+ canonicalInput_js.exact(raw, path, ["kind", "variant"]);
87
141
  return Object.freeze({ kind: "option", variant: "none" });
88
142
  }
89
143
  if (raw.variant !== "some") throw new diagnostics_js.KaladaFailure("KALADA_INVALID_INPUT", [...path, "variant"]);
90
- exact(raw, path, ["kind", "variant", "value"]);
144
+ canonicalInput_js.exact(raw, path, ["kind", "variant", "value"]);
91
145
  return Object.freeze({
92
146
  kind: "option",
93
147
  variant: "some",
@@ -97,7 +151,7 @@ function canonicalOption(raw, path, depth, state) {
97
151
  function canonicalResult(raw, path, depth, state) {
98
152
  if (raw.variant !== "ok" && raw.variant !== "err")
99
153
  throw new diagnostics_js.KaladaFailure("KALADA_INVALID_INPUT", [...path, "variant"]);
100
- exact(raw, path, ["kind", "variant", "value"]);
154
+ canonicalInput_js.exact(raw, path, ["kind", "variant", "value"]);
101
155
  return Object.freeze({
102
156
  kind: "result",
103
157
  variant: raw.variant,
@@ -105,7 +159,7 @@ function canonicalResult(raw, path, depth, state) {
105
159
  });
106
160
  }
107
161
  function canonicalMatch(raw, path, depth, state) {
108
- exact(raw, path, ["kind", "type", "value", "arms"]);
162
+ canonicalInput_js.exact(raw, path, ["kind", "type", "value", "arms"]);
109
163
  if (raw.type !== "Option" && raw.type !== "Result")
110
164
  throw new diagnostics_js.KaladaFailure("KALADA_INVALID_INPUT", [...path, "type"]);
111
165
  const value = canonicalNode(raw.value, [...path, "value"], depth + 1, state);
@@ -114,7 +168,7 @@ function canonicalMatch(raw, path, depth, state) {
114
168
  }
115
169
  function canonicalArms(input, type, path, depth, state) {
116
170
  if (!Array.isArray(input)) throw new diagnostics_js.KaladaFailure("KALADA_INVALID_INPUT", [...path, "arms"]);
117
- const entries = strictArray(input, [...path, "arms"]);
171
+ const entries = canonicalInput_js.strictArray(input, [...path, "arms"]);
118
172
  const expected = ARM_ORDER[type];
119
173
  const found = /* @__PURE__ */ new Map();
120
174
  entries.forEach((entry, index) => {
@@ -126,7 +180,7 @@ function canonicalArms(input, type, path, depth, state) {
126
180
  }
127
181
  function addArm(input, index, type, expected, found, path, depth, state) {
128
182
  const armPath = [...path, "arms", index];
129
- const raw = properties(input, armPath, /* @__PURE__ */ new Set(["variant", "binding", "body"]), false);
183
+ const raw = canonicalInput_js.properties(input, armPath, /* @__PURE__ */ new Set(["variant", "binding", "body"]), false);
130
184
  if (found.size === expected.length)
131
185
  throw new diagnostics_js.KaladaFailure("KALADA_MATCH_UNREACHABLE_ARM", armPath);
132
186
  if (typeof raw.variant !== "string" || !expected.includes(raw.variant))
@@ -136,13 +190,13 @@ function addArm(input, index, type, expected, found, path, depth, state) {
136
190
  const allowsBinding = raw.variant !== "none";
137
191
  if (!allowsBinding && "binding" in raw)
138
192
  throw new diagnostics_js.KaladaFailure("KALADA_INVALID_INPUT", [...armPath, "binding"]);
139
- exact(
193
+ canonicalInput_js.exact(
140
194
  raw,
141
195
  armPath,
142
196
  allowsBinding ? ["variant", "body", "binding"] : ["variant", "body"],
143
197
  allowsBinding
144
198
  );
145
- const binding = raw.binding === void 0 ? void 0 : bindingName(raw.binding, [...armPath, "binding"], state.limits);
199
+ const binding = raw.binding === void 0 ? void 0 : canonicalInput_js.bindingName(raw.binding, [...armPath, "binding"], state.limits);
146
200
  const body = canonicalNode(raw.body, [...armPath, "body"], depth + 1, state);
147
201
  found.set(
148
202
  raw.variant,
@@ -154,112 +208,6 @@ function requiredArm(found, variant, path) {
154
208
  if (!arm) throw new diagnostics_js.KaladaFailure("KALADA_MATCH_MISSING_ARM", [...path, "arms"]);
155
209
  return arm;
156
210
  }
157
- function properties(input, path, allowed, requireExact = true) {
158
- if (typeof input !== "object" || input === null || Array.isArray(input))
159
- throw new diagnostics_js.KaladaFailure("KALADA_INVALID_INPUT", path);
160
- let keys;
161
- try {
162
- keys = Reflect.ownKeys(input);
163
- } catch {
164
- throw new diagnostics_js.KaladaFailure("KALADA_INVALID_INPUT", path);
165
- }
166
- const output = {};
167
- for (const key of keys) {
168
- if (typeof key !== "string" || !allowed.has(key))
169
- throw new diagnostics_js.KaladaFailure("KALADA_INVALID_INPUT", [...path, String(key)]);
170
- try {
171
- output[key] = json_js.dataValue(input, key);
172
- } catch {
173
- throw new diagnostics_js.KaladaFailure("KALADA_INVALID_INPUT", [...path, key]);
174
- }
175
- }
176
- if (requireExact && keys.length !== allowed.size)
177
- throw new diagnostics_js.KaladaFailure("KALADA_INVALID_INPUT", path);
178
- return output;
179
- }
180
- function exact(raw, path, keys, optionalLast = false) {
181
- const minimum = optionalLast ? keys.length - 1 : keys.length;
182
- if (Object.keys(raw).length < minimum || Object.keys(raw).length > keys.length)
183
- throw new diagnostics_js.KaladaFailure("KALADA_INVALID_INPUT", path);
184
- for (let index = 0; index < minimum; index += 1) {
185
- const key = keys[index];
186
- if (key !== void 0 && !(key in raw))
187
- throw new diagnostics_js.KaladaFailure("KALADA_INVALID_INPUT", [...path, key]);
188
- }
189
- for (const key of Object.keys(raw))
190
- if (!keys.includes(key)) throw new diagnostics_js.KaladaFailure("KALADA_INVALID_INPUT", [...path, key]);
191
- }
192
- function strictArray(input, path) {
193
- let keys;
194
- try {
195
- keys = Reflect.ownKeys(input);
196
- } catch {
197
- throw new diagnostics_js.KaladaFailure("KALADA_INVALID_INPUT", path);
198
- }
199
- if (keys.length !== input.length + 1) throw new diagnostics_js.KaladaFailure("KALADA_INVALID_INPUT", path);
200
- return Array.from({ length: input.length }, (_, index) => {
201
- try {
202
- return json_js.dataValue(input, String(index));
203
- } catch {
204
- throw new diagnostics_js.KaladaFailure("KALADA_INVALID_INPUT", [...path, index]);
205
- }
206
- });
207
- }
208
- function safeJson(input, path, state) {
209
- try {
210
- const result = json_js.cloneJsonWithStats(input, {
211
- maxDepth: state.limits.maxValueDepth,
212
- maxNodes: state.limits.maxValueNodes - state.valueNodes,
213
- maxStringLength: state.limits.maxStringLength
214
- });
215
- state.valueNodes += result.nodes;
216
- return result.value;
217
- } catch (error) {
218
- if (error instanceof RangeError) throw new diagnostics_js.KaladaFailure("KALADA_LIMIT_EXCEEDED", path);
219
- throw new diagnostics_js.KaladaFailure("KALADA_INVALID_INPUT", path);
220
- }
221
- }
222
- function inspectJson(input, path, state) {
223
- try {
224
- return json_js.cloneJson(input, {
225
- maxDepth: state.limits.maxValueDepth,
226
- maxNodes: state.limits.maxValueNodes,
227
- maxStringLength: state.limits.maxStringLength
228
- });
229
- } catch (error) {
230
- if (error instanceof RangeError) throw new diagnostics_js.KaladaFailure("KALADA_LIMIT_EXCEEDED", path);
231
- throw new diagnostics_js.KaladaFailure("KALADA_INVALID_INPUT", path);
232
- }
233
- }
234
- function referenceLength(reference) {
235
- return typeof reference === "string" ? [...reference].length : [...json_js.canonicalJsonIdentity(reference)].length;
236
- }
237
- function bindingName(input, path, limits) {
238
- if (typeof input !== "string" || input.length === 0)
239
- throw new diagnostics_js.KaladaFailure("KALADA_INVALID_INPUT", path);
240
- if ([...input].length > limits.maxReferenceLength)
241
- throw new diagnostics_js.KaladaFailure("KALADA_LIMIT_EXCEEDED", path);
242
- return input;
243
- }
244
- function safeValidate(validate, input) {
245
- try {
246
- return validate(input) === true;
247
- } catch {
248
- return false;
249
- }
250
- }
251
- function safeCanonicalize(canonicalize, input, path) {
252
- try {
253
- return canonicalize(input);
254
- } catch {
255
- throw new diagnostics_js.KaladaFailure("KALADA_INVALID_REFERENCE", path);
256
- }
257
- }
258
- function count(path, depth, state) {
259
- state.astNodes += 1;
260
- if (depth > state.limits.maxAstDepth || state.astNodes > state.limits.maxAstNodes)
261
- throw new diagnostics_js.KaladaFailure("KALADA_LIMIT_EXCEEDED", path);
262
- }
263
211
 
264
212
  exports.canonicalizeKaladaV1Program = canonicalizeKaladaV1Program;
265
213
  //# sourceMappingURL=canonicalize.cjs.map