@manifesto-ai/core 0.3.0 → 1.0.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.
- package/README.md +129 -499
- package/dist/core/apply.d.ts +16 -0
- package/dist/core/apply.d.ts.map +1 -0
- package/dist/core/apply.js +52 -0
- package/dist/core/apply.js.map +1 -0
- package/dist/core/compute.d.ts +17 -0
- package/dist/core/compute.d.ts.map +1 -0
- package/dist/core/compute.js +197 -0
- package/dist/core/compute.js.map +1 -0
- package/dist/core/compute.test.d.ts +2 -0
- package/dist/core/compute.test.d.ts.map +1 -0
- package/dist/core/compute.test.js +400 -0
- package/dist/core/compute.test.js.map +1 -0
- package/dist/core/explain.d.ts +14 -0
- package/dist/core/explain.d.ts.map +1 -0
- package/dist/core/explain.js +74 -0
- package/dist/core/explain.js.map +1 -0
- package/dist/core/index.d.ts +5 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +5 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/validate.d.ts +15 -0
- package/dist/core/validate.d.ts.map +1 -0
- package/dist/core/validate.js +143 -0
- package/dist/core/validate.js.map +1 -0
- package/dist/core/validate.test.d.ts +2 -0
- package/dist/core/validate.test.d.ts.map +1 -0
- package/dist/core/validate.test.js +450 -0
- package/dist/core/validate.test.js.map +1 -0
- package/dist/errors.d.ts +30 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +51 -0
- package/dist/errors.js.map +1 -0
- package/dist/evaluator/computed.d.ts +14 -0
- package/dist/evaluator/computed.d.ts.map +1 -0
- package/dist/evaluator/computed.js +57 -0
- package/dist/evaluator/computed.js.map +1 -0
- package/dist/evaluator/context.d.ts +46 -0
- package/dist/evaluator/context.d.ts.map +1 -0
- package/dist/evaluator/context.js +35 -0
- package/dist/evaluator/context.js.map +1 -0
- package/dist/evaluator/dag.d.ts +30 -0
- package/dist/evaluator/dag.d.ts.map +1 -0
- package/dist/evaluator/dag.js +121 -0
- package/dist/evaluator/dag.js.map +1 -0
- package/dist/evaluator/expr.d.ts +11 -0
- package/dist/evaluator/expr.d.ts.map +1 -0
- package/dist/evaluator/expr.js +498 -0
- package/dist/evaluator/expr.js.map +1 -0
- package/dist/evaluator/expr.test.d.ts +2 -0
- package/dist/evaluator/expr.test.d.ts.map +1 -0
- package/dist/evaluator/expr.test.js +426 -0
- package/dist/evaluator/expr.test.js.map +1 -0
- package/dist/evaluator/flow.d.ts +35 -0
- package/dist/evaluator/flow.d.ts.map +1 -0
- package/dist/evaluator/flow.js +234 -0
- package/dist/evaluator/flow.js.map +1 -0
- package/dist/evaluator/flow.test.d.ts +2 -0
- package/dist/evaluator/flow.test.d.ts.map +1 -0
- package/dist/evaluator/flow.test.js +446 -0
- package/dist/evaluator/flow.test.js.map +1 -0
- package/dist/evaluator/index.d.ts +6 -0
- package/dist/evaluator/index.d.ts.map +1 -0
- package/dist/evaluator/index.js +6 -0
- package/dist/evaluator/index.js.map +1 -0
- package/dist/factories.d.ts +20 -0
- package/dist/factories.d.ts.map +1 -0
- package/dist/factories.js +43 -0
- package/dist/factories.js.map +1 -0
- package/dist/index.d.ts +46 -11
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +30 -45
- package/dist/index.js.map +1 -1
- package/dist/index.test.d.ts +2 -0
- package/dist/index.test.d.ts.map +1 -0
- package/dist/index.test.js +13 -0
- package/dist/index.test.js.map +1 -0
- package/dist/schema/action.d.ts +14 -0
- package/dist/schema/action.d.ts.map +1 -0
- package/dist/schema/action.js +30 -0
- package/dist/schema/action.js.map +1 -0
- package/dist/schema/common.d.ts +37 -0
- package/dist/schema/common.d.ts.map +1 -0
- package/dist/schema/common.js +20 -0
- package/dist/schema/common.js.map +1 -0
- package/dist/schema/computed.d.ts +23 -0
- package/dist/schema/computed.d.ts.map +1 -0
- package/dist/schema/computed.js +34 -0
- package/dist/schema/computed.js.map +1 -0
- package/dist/schema/domain.d.ts +46 -0
- package/dist/schema/domain.d.ts.map +1 -0
- package/dist/schema/domain.js +54 -0
- package/dist/schema/domain.js.map +1 -0
- package/dist/schema/expr.d.ts +260 -0
- package/dist/schema/expr.d.ts.map +1 -0
- package/dist/schema/expr.js +247 -0
- package/dist/schema/expr.js.map +1 -0
- package/dist/schema/field.d.ts +48 -0
- package/dist/schema/field.d.ts.map +1 -0
- package/dist/schema/field.js +31 -0
- package/dist/schema/field.js.map +1 -0
- package/dist/schema/flow.d.ts +103 -0
- package/dist/schema/flow.d.ts.map +1 -0
- package/dist/schema/flow.js +82 -0
- package/dist/schema/flow.js.map +1 -0
- package/dist/schema/index.d.ts +11 -2
- package/dist/schema/index.d.ts.map +1 -1
- package/dist/schema/index.js +22 -2
- package/dist/schema/index.js.map +1 -1
- package/dist/schema/patch.d.ts +59 -0
- package/dist/schema/patch.d.ts.map +1 -0
- package/dist/schema/patch.js +60 -0
- package/dist/schema/patch.js.map +1 -0
- package/dist/schema/result.d.ts +130 -0
- package/dist/schema/result.d.ts.map +1 -0
- package/dist/schema/result.js +90 -0
- package/dist/schema/result.js.map +1 -0
- package/dist/schema/snapshot.d.ts +151 -0
- package/dist/schema/snapshot.d.ts.map +1 -0
- package/dist/schema/snapshot.js +156 -0
- package/dist/schema/snapshot.js.map +1 -0
- package/dist/schema/trace.d.ts +87 -0
- package/dist/schema/trace.d.ts.map +1 -0
- package/dist/schema/trace.js +79 -0
- package/dist/schema/trace.js.map +1 -0
- package/dist/utils/canonical.d.ts +29 -0
- package/dist/utils/canonical.d.ts.map +1 -0
- package/dist/utils/canonical.js +56 -0
- package/dist/utils/canonical.js.map +1 -0
- package/dist/utils/canonical.test.d.ts +2 -0
- package/dist/utils/canonical.test.d.ts.map +1 -0
- package/dist/utils/canonical.test.js +153 -0
- package/dist/utils/canonical.test.js.map +1 -0
- package/dist/utils/hash.d.ts +20 -0
- package/dist/utils/hash.d.ts.map +1 -0
- package/dist/utils/hash.js +38 -0
- package/dist/utils/hash.js.map +1 -0
- package/dist/utils/hash.test.d.ts +2 -0
- package/dist/utils/hash.test.d.ts.map +1 -0
- package/dist/utils/hash.test.js +146 -0
- package/dist/utils/hash.test.js.map +1 -0
- package/dist/utils/index.d.ts +4 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +4 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/path.d.ts +40 -0
- package/dist/utils/path.d.ts.map +1 -0
- package/dist/utils/path.js +132 -0
- package/dist/utils/path.js.map +1 -0
- package/dist/utils/path.test.d.ts +2 -0
- package/dist/utils/path.test.d.ts.map +1 -0
- package/dist/utils/path.test.js +191 -0
- package/dist/utils/path.test.js.map +1 -0
- package/package.json +25 -39
- package/LICENSE +0 -21
- package/dist/dag/graph.d.ts +0 -62
- package/dist/dag/graph.d.ts.map +0 -1
- package/dist/dag/graph.js +0 -244
- package/dist/dag/graph.js.map +0 -1
- package/dist/dag/index.d.ts +0 -4
- package/dist/dag/index.d.ts.map +0 -1
- package/dist/dag/index.js +0 -4
- package/dist/dag/index.js.map +0 -1
- package/dist/dag/propagation.d.ts +0 -58
- package/dist/dag/propagation.d.ts.map +0 -1
- package/dist/dag/propagation.js +0 -224
- package/dist/dag/propagation.js.map +0 -1
- package/dist/dag/topological.d.ts +0 -33
- package/dist/dag/topological.d.ts.map +0 -1
- package/dist/dag/topological.js +0 -173
- package/dist/dag/topological.js.map +0 -1
- package/dist/domain/define.d.ts +0 -82
- package/dist/domain/define.d.ts.map +0 -1
- package/dist/domain/define.js +0 -105
- package/dist/domain/define.js.map +0 -1
- package/dist/domain/index.d.ts +0 -4
- package/dist/domain/index.d.ts.map +0 -1
- package/dist/domain/index.js +0 -4
- package/dist/domain/index.js.map +0 -1
- package/dist/domain/types.d.ts +0 -203
- package/dist/domain/types.d.ts.map +0 -1
- package/dist/domain/types.js +0 -2
- package/dist/domain/types.js.map +0 -1
- package/dist/domain/validate.d.ts +0 -17
- package/dist/domain/validate.d.ts.map +0 -1
- package/dist/domain/validate.js +0 -204
- package/dist/domain/validate.js.map +0 -1
- package/dist/effect/index.d.ts +0 -4
- package/dist/effect/index.d.ts.map +0 -1
- package/dist/effect/index.js +0 -4
- package/dist/effect/index.js.map +0 -1
- package/dist/effect/result.d.ts +0 -100
- package/dist/effect/result.d.ts.map +0 -1
- package/dist/effect/result.js +0 -163
- package/dist/effect/result.js.map +0 -1
- package/dist/effect/runner.d.ts +0 -98
- package/dist/effect/runner.d.ts.map +0 -1
- package/dist/effect/runner.js +0 -321
- package/dist/effect/runner.js.map +0 -1
- package/dist/effect/types.d.ts +0 -169
- package/dist/effect/types.d.ts.map +0 -1
- package/dist/effect/types.js +0 -28
- package/dist/effect/types.js.map +0 -1
- package/dist/expression/analyzer.d.ts +0 -42
- package/dist/expression/analyzer.d.ts.map +0 -1
- package/dist/expression/analyzer.js +0 -166
- package/dist/expression/analyzer.js.map +0 -1
- package/dist/expression/evaluator.d.ts +0 -16
- package/dist/expression/evaluator.d.ts.map +0 -1
- package/dist/expression/evaluator.js +0 -382
- package/dist/expression/evaluator.js.map +0 -1
- package/dist/expression/index.d.ts +0 -5
- package/dist/expression/index.d.ts.map +0 -1
- package/dist/expression/index.js +0 -5
- package/dist/expression/index.js.map +0 -1
- package/dist/expression/parser.d.ts +0 -37
- package/dist/expression/parser.d.ts.map +0 -1
- package/dist/expression/parser.js +0 -201
- package/dist/expression/parser.js.map +0 -1
- package/dist/expression/types.d.ts +0 -123
- package/dist/expression/types.d.ts.map +0 -1
- package/dist/expression/types.js +0 -10
- package/dist/expression/types.js.map +0 -1
- package/dist/policy/field-policy.d.ts +0 -63
- package/dist/policy/field-policy.d.ts.map +0 -1
- package/dist/policy/field-policy.js +0 -138
- package/dist/policy/field-policy.js.map +0 -1
- package/dist/policy/index.d.ts +0 -3
- package/dist/policy/index.d.ts.map +0 -1
- package/dist/policy/index.js +0 -3
- package/dist/policy/index.js.map +0 -1
- package/dist/policy/precondition.d.ts +0 -58
- package/dist/policy/precondition.d.ts.map +0 -1
- package/dist/policy/precondition.js +0 -115
- package/dist/policy/precondition.js.map +0 -1
- package/dist/runtime/index.d.ts +0 -4
- package/dist/runtime/index.d.ts.map +0 -1
- package/dist/runtime/index.js +0 -4
- package/dist/runtime/index.js.map +0 -1
- package/dist/runtime/runtime.d.ts +0 -94
- package/dist/runtime/runtime.d.ts.map +0 -1
- package/dist/runtime/runtime.js +0 -294
- package/dist/runtime/runtime.js.map +0 -1
- package/dist/runtime/snapshot.d.ts +0 -39
- package/dist/runtime/snapshot.d.ts.map +0 -1
- package/dist/runtime/snapshot.js +0 -264
- package/dist/runtime/snapshot.js.map +0 -1
- package/dist/runtime/subscription.d.ts +0 -82
- package/dist/runtime/subscription.d.ts.map +0 -1
- package/dist/runtime/subscription.js +0 -222
- package/dist/runtime/subscription.js.map +0 -1
- package/dist/schema/integration.d.ts +0 -89
- package/dist/schema/integration.d.ts.map +0 -1
- package/dist/schema/integration.js +0 -171
- package/dist/schema/integration.js.map +0 -1
- package/dist/schema/validation.d.ts +0 -51
- package/dist/schema/validation.d.ts.map +0 -1
- package/dist/schema/validation.js +0 -212
- package/dist/schema/validation.js.map +0 -1
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { sortKeys, toCanonical, fromCanonical, canonicalEqual } from "./canonical.js";
|
|
3
|
+
describe("Canonical Utilities", () => {
|
|
4
|
+
describe("sortKeys", () => {
|
|
5
|
+
it("should sort object keys alphabetically", () => {
|
|
6
|
+
const obj = { c: 1, a: 2, b: 3 };
|
|
7
|
+
const result = sortKeys(obj);
|
|
8
|
+
expect(Object.keys(result)).toEqual(["a", "b", "c"]);
|
|
9
|
+
});
|
|
10
|
+
it("should sort nested object keys", () => {
|
|
11
|
+
const obj = { z: { c: 1, a: 2 }, a: { z: 1, a: 2 } };
|
|
12
|
+
const result = sortKeys(obj);
|
|
13
|
+
expect(Object.keys(result)).toEqual(["a", "z"]);
|
|
14
|
+
expect(Object.keys(result.z)).toEqual(["a", "c"]);
|
|
15
|
+
expect(Object.keys(result.a)).toEqual(["a", "z"]);
|
|
16
|
+
});
|
|
17
|
+
it("should remove undefined values", () => {
|
|
18
|
+
const obj = { a: 1, b: undefined, c: 3 };
|
|
19
|
+
const result = sortKeys(obj);
|
|
20
|
+
expect(result).toEqual({ a: 1, c: 3 });
|
|
21
|
+
});
|
|
22
|
+
it("should preserve null values", () => {
|
|
23
|
+
const obj = { a: 1, b: null, c: 3 };
|
|
24
|
+
const result = sortKeys(obj);
|
|
25
|
+
expect(result).toEqual({ a: 1, b: null, c: 3 });
|
|
26
|
+
});
|
|
27
|
+
it("should handle arrays", () => {
|
|
28
|
+
const obj = [{ b: 1, a: 2 }, { d: 3, c: 4 }];
|
|
29
|
+
const result = sortKeys(obj);
|
|
30
|
+
expect(result).toHaveLength(2);
|
|
31
|
+
expect(Object.keys(result[0])).toEqual(["a", "b"]);
|
|
32
|
+
expect(Object.keys(result[1])).toEqual(["c", "d"]);
|
|
33
|
+
});
|
|
34
|
+
it("should handle arrays inside objects", () => {
|
|
35
|
+
const obj = { items: [{ z: 1, a: 2 }] };
|
|
36
|
+
const result = sortKeys(obj);
|
|
37
|
+
expect(Object.keys(result.items[0])).toEqual(["a", "z"]);
|
|
38
|
+
});
|
|
39
|
+
it("should return null for null input", () => {
|
|
40
|
+
expect(sortKeys(null)).toBeNull();
|
|
41
|
+
});
|
|
42
|
+
it("should return undefined for undefined input", () => {
|
|
43
|
+
expect(sortKeys(undefined)).toBeUndefined();
|
|
44
|
+
});
|
|
45
|
+
it("should return primitives unchanged", () => {
|
|
46
|
+
expect(sortKeys(42)).toBe(42);
|
|
47
|
+
expect(sortKeys("hello")).toBe("hello");
|
|
48
|
+
expect(sortKeys(true)).toBe(true);
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
describe("toCanonical", () => {
|
|
52
|
+
it("should produce sorted JSON string", () => {
|
|
53
|
+
const obj = { c: 1, a: 2, b: 3 };
|
|
54
|
+
expect(toCanonical(obj)).toBe('{"a":2,"b":3,"c":1}');
|
|
55
|
+
});
|
|
56
|
+
it("should produce consistent output for same data", () => {
|
|
57
|
+
const obj1 = { a: 1, b: 2 };
|
|
58
|
+
const obj2 = { b: 2, a: 1 };
|
|
59
|
+
expect(toCanonical(obj1)).toBe(toCanonical(obj2));
|
|
60
|
+
});
|
|
61
|
+
it("should remove undefined values", () => {
|
|
62
|
+
const obj = { a: 1, b: undefined };
|
|
63
|
+
expect(toCanonical(obj)).toBe('{"a":1}');
|
|
64
|
+
});
|
|
65
|
+
it("should preserve null values", () => {
|
|
66
|
+
const obj = { a: null };
|
|
67
|
+
expect(toCanonical(obj)).toBe('{"a":null}');
|
|
68
|
+
});
|
|
69
|
+
it("should handle nested structures", () => {
|
|
70
|
+
const obj = { z: { b: 1, a: 2 }, a: 3 };
|
|
71
|
+
expect(toCanonical(obj)).toBe('{"a":3,"z":{"a":2,"b":1}}');
|
|
72
|
+
});
|
|
73
|
+
it("should handle arrays", () => {
|
|
74
|
+
const obj = [3, 1, 2];
|
|
75
|
+
expect(toCanonical(obj)).toBe("[3,1,2]"); // Arrays preserve order
|
|
76
|
+
});
|
|
77
|
+
it("should handle primitives", () => {
|
|
78
|
+
expect(toCanonical(42)).toBe("42");
|
|
79
|
+
expect(toCanonical("hello")).toBe('"hello"');
|
|
80
|
+
expect(toCanonical(true)).toBe("true");
|
|
81
|
+
expect(toCanonical(null)).toBe("null");
|
|
82
|
+
});
|
|
83
|
+
});
|
|
84
|
+
describe("fromCanonical", () => {
|
|
85
|
+
it("should parse canonical JSON string", () => {
|
|
86
|
+
const canonical = '{"a":1,"b":2}';
|
|
87
|
+
expect(fromCanonical(canonical)).toEqual({ a: 1, b: 2 });
|
|
88
|
+
});
|
|
89
|
+
it("should handle arrays", () => {
|
|
90
|
+
const canonical = "[1,2,3]";
|
|
91
|
+
expect(fromCanonical(canonical)).toEqual([1, 2, 3]);
|
|
92
|
+
});
|
|
93
|
+
it("should handle primitives", () => {
|
|
94
|
+
expect(fromCanonical("42")).toBe(42);
|
|
95
|
+
expect(fromCanonical('"hello"')).toBe("hello");
|
|
96
|
+
expect(fromCanonical("true")).toBe(true);
|
|
97
|
+
expect(fromCanonical("null")).toBeNull();
|
|
98
|
+
});
|
|
99
|
+
});
|
|
100
|
+
describe("canonicalEqual", () => {
|
|
101
|
+
it("should return true for equal objects with different key order", () => {
|
|
102
|
+
const a = { x: 1, y: 2 };
|
|
103
|
+
const b = { y: 2, x: 1 };
|
|
104
|
+
expect(canonicalEqual(a, b)).toBe(true);
|
|
105
|
+
});
|
|
106
|
+
it("should return false for different objects", () => {
|
|
107
|
+
const a = { x: 1, y: 2 };
|
|
108
|
+
const b = { x: 1, y: 3 };
|
|
109
|
+
expect(canonicalEqual(a, b)).toBe(false);
|
|
110
|
+
});
|
|
111
|
+
it("should treat undefined as missing", () => {
|
|
112
|
+
const a = { x: 1 };
|
|
113
|
+
const b = { x: 1, y: undefined };
|
|
114
|
+
expect(canonicalEqual(a, b)).toBe(true);
|
|
115
|
+
});
|
|
116
|
+
it("should handle nested objects", () => {
|
|
117
|
+
const a = { outer: { b: 1, a: 2 } };
|
|
118
|
+
const b = { outer: { a: 2, b: 1 } };
|
|
119
|
+
expect(canonicalEqual(a, b)).toBe(true);
|
|
120
|
+
});
|
|
121
|
+
it("should distinguish null from undefined", () => {
|
|
122
|
+
const a = { x: null };
|
|
123
|
+
const b = { x: undefined };
|
|
124
|
+
expect(canonicalEqual(a, b)).toBe(false);
|
|
125
|
+
});
|
|
126
|
+
});
|
|
127
|
+
describe("Deterministic Hashing", () => {
|
|
128
|
+
it("should produce same canonical form regardless of property order", () => {
|
|
129
|
+
// Simulate objects created in different orders
|
|
130
|
+
const obj1 = {};
|
|
131
|
+
obj1.alpha = 1;
|
|
132
|
+
obj1.beta = 2;
|
|
133
|
+
obj1.gamma = 3;
|
|
134
|
+
const obj2 = {};
|
|
135
|
+
obj2.gamma = 3;
|
|
136
|
+
obj2.alpha = 1;
|
|
137
|
+
obj2.beta = 2;
|
|
138
|
+
expect(toCanonical(obj1)).toBe(toCanonical(obj2));
|
|
139
|
+
});
|
|
140
|
+
it("should handle deeply nested structures consistently", () => {
|
|
141
|
+
const obj1 = {
|
|
142
|
+
z: { y: { x: { w: 1 } } },
|
|
143
|
+
a: { b: { c: 2 } },
|
|
144
|
+
};
|
|
145
|
+
const obj2 = {
|
|
146
|
+
a: { b: { c: 2 } },
|
|
147
|
+
z: { y: { x: { w: 1 } } },
|
|
148
|
+
};
|
|
149
|
+
expect(toCanonical(obj1)).toBe(toCanonical(obj2));
|
|
150
|
+
});
|
|
151
|
+
});
|
|
152
|
+
});
|
|
153
|
+
//# sourceMappingURL=canonical.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"canonical.test.js","sourceRoot":"","sources":["../../src/utils/canonical.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { DomainSchema } from "../schema/domain.js";
|
|
2
|
+
/**
|
|
3
|
+
* SHA-256 hash using Web Crypto API
|
|
4
|
+
* Works in both browser and Node.js
|
|
5
|
+
*/
|
|
6
|
+
export declare function sha256(message: string): Promise<string>;
|
|
7
|
+
/**
|
|
8
|
+
* Hash a schema in canonical form
|
|
9
|
+
*/
|
|
10
|
+
export declare function hashSchema(schema: Omit<DomainSchema, "hash">): Promise<string>;
|
|
11
|
+
/**
|
|
12
|
+
* Generate deterministic requirement ID
|
|
13
|
+
* Based on: schemaHash, intentId, actionId, flowNodePath
|
|
14
|
+
*/
|
|
15
|
+
export declare function generateRequirementId(schemaHash: string, intentId: string, actionId: string, flowNodePath: string): Promise<string>;
|
|
16
|
+
/**
|
|
17
|
+
* Generate a trace node ID
|
|
18
|
+
*/
|
|
19
|
+
export declare function generateTraceId(): string;
|
|
20
|
+
//# sourceMappingURL=hash.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hash.d.ts","sourceRoot":"","sources":["../../src/utils/hash.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAExD;;;GAGG;AACH,wBAAsB,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAS7D;AAED;;GAEG;AACH,wBAAsB,UAAU,CAAC,MAAM,EAAE,IAAI,CAAC,YAAY,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAIpF;AAED;;;GAGG;AACH,wBAAsB,qBAAqB,CACzC,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,MAAM,CAAC,CAKjB;AAED;;GAEG;AACH,wBAAgB,eAAe,IAAI,MAAM,CAExC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { toCanonical } from "./canonical.js";
|
|
2
|
+
/**
|
|
3
|
+
* SHA-256 hash using Web Crypto API
|
|
4
|
+
* Works in both browser and Node.js
|
|
5
|
+
*/
|
|
6
|
+
export async function sha256(message) {
|
|
7
|
+
const msgBuffer = new TextEncoder().encode(message);
|
|
8
|
+
// Use Web Crypto API
|
|
9
|
+
const hashBuffer = await crypto.subtle.digest("SHA-256", msgBuffer);
|
|
10
|
+
// Convert to hex string
|
|
11
|
+
const hashArray = Array.from(new Uint8Array(hashBuffer));
|
|
12
|
+
return hashArray.map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Hash a schema in canonical form
|
|
16
|
+
*/
|
|
17
|
+
export async function hashSchema(schema) {
|
|
18
|
+
// Create canonical form without the hash field
|
|
19
|
+
const canonical = toCanonical(schema);
|
|
20
|
+
return sha256(canonical);
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Generate deterministic requirement ID
|
|
24
|
+
* Based on: schemaHash, intentId, actionId, flowNodePath
|
|
25
|
+
*/
|
|
26
|
+
export async function generateRequirementId(schemaHash, intentId, actionId, flowNodePath) {
|
|
27
|
+
const input = `${schemaHash}:${intentId}:${actionId}:${flowNodePath}`;
|
|
28
|
+
const hash = await sha256(input);
|
|
29
|
+
// Return first 16 characters for brevity
|
|
30
|
+
return `req-${hash.slice(0, 16)}`;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Generate a trace node ID
|
|
34
|
+
*/
|
|
35
|
+
export function generateTraceId() {
|
|
36
|
+
return `trace-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=hash.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hash.js","sourceRoot":"","sources":["../../src/utils/hash.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAG7C;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,OAAe;IAC1C,MAAM,SAAS,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAEpD,qBAAqB;IACrB,MAAM,UAAU,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;IAEpE,wBAAwB;IACxB,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC;IACzD,OAAO,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AACxE,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,MAAkC;IACjE,+CAA+C;IAC/C,MAAM,SAAS,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;IACtC,OAAO,MAAM,CAAC,SAAS,CAAC,CAAC;AAC3B,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,UAAkB,EAClB,QAAgB,EAChB,QAAgB,EAChB,YAAoB;IAEpB,MAAM,KAAK,GAAG,GAAG,UAAU,IAAI,QAAQ,IAAI,QAAQ,IAAI,YAAY,EAAE,CAAC;IACtE,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,CAAC;IACjC,yCAAyC;IACzC,OAAO,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC;AACpC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,eAAe;IAC7B,OAAO,SAAS,IAAI,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;AACzE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hash.test.d.ts","sourceRoot":"","sources":["../../src/utils/hash.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { sha256, hashSchema, generateRequirementId, generateTraceId } from "./hash.js";
|
|
3
|
+
describe("Hash Utilities", () => {
|
|
4
|
+
describe("sha256", () => {
|
|
5
|
+
it("should produce consistent hash for same input", async () => {
|
|
6
|
+
const hash1 = await sha256("hello world");
|
|
7
|
+
const hash2 = await sha256("hello world");
|
|
8
|
+
expect(hash1).toBe(hash2);
|
|
9
|
+
});
|
|
10
|
+
it("should produce different hash for different input", async () => {
|
|
11
|
+
const hash1 = await sha256("hello");
|
|
12
|
+
const hash2 = await sha256("world");
|
|
13
|
+
expect(hash1).not.toBe(hash2);
|
|
14
|
+
});
|
|
15
|
+
it("should produce 64 character hex string", async () => {
|
|
16
|
+
const hash = await sha256("test");
|
|
17
|
+
expect(hash).toHaveLength(64);
|
|
18
|
+
expect(hash).toMatch(/^[a-f0-9]{64}$/);
|
|
19
|
+
});
|
|
20
|
+
it("should handle empty string", async () => {
|
|
21
|
+
const hash = await sha256("");
|
|
22
|
+
expect(hash).toHaveLength(64);
|
|
23
|
+
});
|
|
24
|
+
it("should handle unicode characters", async () => {
|
|
25
|
+
const hash = await sha256("안녕하세요");
|
|
26
|
+
expect(hash).toHaveLength(64);
|
|
27
|
+
});
|
|
28
|
+
it("should match known SHA-256 hash", async () => {
|
|
29
|
+
// "test" hashes to this known value
|
|
30
|
+
const hash = await sha256("test");
|
|
31
|
+
expect(hash).toBe("9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08");
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
describe("hashSchema", () => {
|
|
35
|
+
it("should produce consistent hash for same schema", async () => {
|
|
36
|
+
const schema = {
|
|
37
|
+
id: "test",
|
|
38
|
+
version: "1.0.0",
|
|
39
|
+
state: { fields: {} },
|
|
40
|
+
computed: { fields: {} },
|
|
41
|
+
actions: {},
|
|
42
|
+
};
|
|
43
|
+
const hash1 = await hashSchema(schema);
|
|
44
|
+
const hash2 = await hashSchema(schema);
|
|
45
|
+
expect(hash1).toBe(hash2);
|
|
46
|
+
});
|
|
47
|
+
it("should produce same hash regardless of key order", async () => {
|
|
48
|
+
const schema1 = {
|
|
49
|
+
id: "test",
|
|
50
|
+
version: "1.0.0",
|
|
51
|
+
state: { fields: {} },
|
|
52
|
+
computed: { fields: {} },
|
|
53
|
+
actions: {},
|
|
54
|
+
};
|
|
55
|
+
const schema2 = {
|
|
56
|
+
actions: {},
|
|
57
|
+
computed: { fields: {} },
|
|
58
|
+
state: { fields: {} },
|
|
59
|
+
version: "1.0.0",
|
|
60
|
+
id: "test",
|
|
61
|
+
};
|
|
62
|
+
const hash1 = await hashSchema(schema1);
|
|
63
|
+
const hash2 = await hashSchema(schema2);
|
|
64
|
+
expect(hash1).toBe(hash2);
|
|
65
|
+
});
|
|
66
|
+
it("should produce different hash for different schemas", async () => {
|
|
67
|
+
const schema1 = {
|
|
68
|
+
id: "test1",
|
|
69
|
+
version: "1.0.0",
|
|
70
|
+
state: { fields: {} },
|
|
71
|
+
computed: { fields: {} },
|
|
72
|
+
actions: {},
|
|
73
|
+
};
|
|
74
|
+
const schema2 = {
|
|
75
|
+
id: "test2",
|
|
76
|
+
version: "1.0.0",
|
|
77
|
+
state: { fields: {} },
|
|
78
|
+
computed: { fields: {} },
|
|
79
|
+
actions: {},
|
|
80
|
+
};
|
|
81
|
+
const hash1 = await hashSchema(schema1);
|
|
82
|
+
const hash2 = await hashSchema(schema2);
|
|
83
|
+
expect(hash1).not.toBe(hash2);
|
|
84
|
+
});
|
|
85
|
+
it("should detect changes in nested structures", async () => {
|
|
86
|
+
const schema1 = {
|
|
87
|
+
id: "test",
|
|
88
|
+
version: "1.0.0",
|
|
89
|
+
state: { fields: { count: { type: "number", required: true } } },
|
|
90
|
+
computed: { fields: {} },
|
|
91
|
+
actions: {},
|
|
92
|
+
};
|
|
93
|
+
const schema2 = {
|
|
94
|
+
id: "test",
|
|
95
|
+
version: "1.0.0",
|
|
96
|
+
state: { fields: { count: { type: "string", required: true } } },
|
|
97
|
+
computed: { fields: {} },
|
|
98
|
+
actions: {},
|
|
99
|
+
};
|
|
100
|
+
const hash1 = await hashSchema(schema1);
|
|
101
|
+
const hash2 = await hashSchema(schema2);
|
|
102
|
+
expect(hash1).not.toBe(hash2);
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
describe("generateRequirementId", () => {
|
|
106
|
+
it("should produce consistent ID for same inputs", async () => {
|
|
107
|
+
const id1 = await generateRequirementId("schema-hash", "intent-1", "action", "path");
|
|
108
|
+
const id2 = await generateRequirementId("schema-hash", "intent-1", "action", "path");
|
|
109
|
+
expect(id1).toBe(id2);
|
|
110
|
+
});
|
|
111
|
+
it("should produce different ID for different inputs", async () => {
|
|
112
|
+
const id1 = await generateRequirementId("schema-hash", "intent-1", "action", "path");
|
|
113
|
+
const id2 = await generateRequirementId("schema-hash", "intent-2", "action", "path");
|
|
114
|
+
expect(id1).not.toBe(id2);
|
|
115
|
+
});
|
|
116
|
+
it("should produce ID with req- prefix", async () => {
|
|
117
|
+
const id = await generateRequirementId("hash", "intent", "action", "path");
|
|
118
|
+
expect(id).toMatch(/^req-[a-f0-9]{16}$/);
|
|
119
|
+
});
|
|
120
|
+
it("should produce 20 character ID (req- + 16 hex chars)", async () => {
|
|
121
|
+
const id = await generateRequirementId("hash", "intent", "action", "path");
|
|
122
|
+
expect(id).toHaveLength(20);
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
describe("generateTraceId", () => {
|
|
126
|
+
it("should produce unique IDs", () => {
|
|
127
|
+
const id1 = generateTraceId();
|
|
128
|
+
const id2 = generateTraceId();
|
|
129
|
+
expect(id1).not.toBe(id2);
|
|
130
|
+
});
|
|
131
|
+
it("should produce ID with trace- prefix", () => {
|
|
132
|
+
const id = generateTraceId();
|
|
133
|
+
expect(id).toMatch(/^trace-\d+-[a-z0-9]+$/);
|
|
134
|
+
});
|
|
135
|
+
it("should include timestamp", () => {
|
|
136
|
+
const before = Date.now();
|
|
137
|
+
const id = generateTraceId();
|
|
138
|
+
const after = Date.now();
|
|
139
|
+
const parts = id.split("-");
|
|
140
|
+
const timestamp = parseInt(parts[1], 10);
|
|
141
|
+
expect(timestamp).toBeGreaterThanOrEqual(before);
|
|
142
|
+
expect(timestamp).toBeLessThanOrEqual(after);
|
|
143
|
+
});
|
|
144
|
+
});
|
|
145
|
+
});
|
|
146
|
+
//# sourceMappingURL=hash.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hash.test.js","sourceRoot":"","sources":["../../src/utils/hash.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC;AAC1B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,WAAW,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC;AAC1B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,WAAW,CAAC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { SemanticPath } from "../schema/common.js";
|
|
2
|
+
/**
|
|
3
|
+
* Parse a dot-separated path into segments
|
|
4
|
+
*/
|
|
5
|
+
export declare function parsePath(path: SemanticPath): string[];
|
|
6
|
+
/**
|
|
7
|
+
* Join path segments into a semantic path
|
|
8
|
+
*/
|
|
9
|
+
export declare function joinPath(...segments: string[]): SemanticPath;
|
|
10
|
+
/**
|
|
11
|
+
* Get value at path from object
|
|
12
|
+
* Returns undefined for non-existent paths (never throws)
|
|
13
|
+
*/
|
|
14
|
+
export declare function getByPath(obj: unknown, path: SemanticPath): unknown;
|
|
15
|
+
/**
|
|
16
|
+
* Immutably set value at path
|
|
17
|
+
* Creates intermediate objects as needed
|
|
18
|
+
*/
|
|
19
|
+
export declare function setByPath(obj: unknown, path: SemanticPath, value: unknown): unknown;
|
|
20
|
+
/**
|
|
21
|
+
* Immutably remove value at path
|
|
22
|
+
*/
|
|
23
|
+
export declare function unsetByPath(obj: unknown, path: SemanticPath): unknown;
|
|
24
|
+
/**
|
|
25
|
+
* Immutably shallow merge at path
|
|
26
|
+
*/
|
|
27
|
+
export declare function mergeAtPath(obj: unknown, path: SemanticPath, value: Record<string, unknown>): unknown;
|
|
28
|
+
/**
|
|
29
|
+
* Check if a path exists in an object
|
|
30
|
+
*/
|
|
31
|
+
export declare function hasPath(obj: unknown, path: SemanticPath): boolean;
|
|
32
|
+
/**
|
|
33
|
+
* Get parent path
|
|
34
|
+
*/
|
|
35
|
+
export declare function parentPath(path: SemanticPath): SemanticPath;
|
|
36
|
+
/**
|
|
37
|
+
* Get last segment of path
|
|
38
|
+
*/
|
|
39
|
+
export declare function lastSegment(path: SemanticPath): string;
|
|
40
|
+
//# sourceMappingURL=path.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"path.d.ts","sourceRoot":"","sources":["../../src/utils/path.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAExD;;GAEG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,EAAE,CAGtD;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,GAAG,QAAQ,EAAE,MAAM,EAAE,GAAG,YAAY,CAE5D;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,YAAY,GAAG,OAAO,CAmBnE;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAKnF;AAmBD;;GAEG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,YAAY,GAAG,OAAO,CAKrE;AAsBD;;GAEG;AACH,wBAAgB,WAAW,CACzB,GAAG,EAAE,OAAO,EACZ,IAAI,EAAE,YAAY,EAClB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC7B,OAAO,CAQT;AAED;;GAEG;AACH,wBAAgB,OAAO,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,YAAY,GAAG,OAAO,CAuBjE;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,YAAY,GAAG,YAAY,CAG3D;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,CAGtD"}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parse a dot-separated path into segments
|
|
3
|
+
*/
|
|
4
|
+
export function parsePath(path) {
|
|
5
|
+
if (!path)
|
|
6
|
+
return [];
|
|
7
|
+
return path.split(".");
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Join path segments into a semantic path
|
|
11
|
+
*/
|
|
12
|
+
export function joinPath(...segments) {
|
|
13
|
+
return segments.filter(Boolean).join(".");
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Get value at path from object
|
|
17
|
+
* Returns undefined for non-existent paths (never throws)
|
|
18
|
+
*/
|
|
19
|
+
export function getByPath(obj, path) {
|
|
20
|
+
if (!path)
|
|
21
|
+
return obj;
|
|
22
|
+
const segments = parsePath(path);
|
|
23
|
+
let current = obj;
|
|
24
|
+
for (const segment of segments) {
|
|
25
|
+
if (current === null || current === undefined) {
|
|
26
|
+
return undefined;
|
|
27
|
+
}
|
|
28
|
+
if (typeof current === "object") {
|
|
29
|
+
current = current[segment];
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
return undefined;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return current;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Immutably set value at path
|
|
39
|
+
* Creates intermediate objects as needed
|
|
40
|
+
*/
|
|
41
|
+
export function setByPath(obj, path, value) {
|
|
42
|
+
if (!path)
|
|
43
|
+
return value;
|
|
44
|
+
const segments = parsePath(path);
|
|
45
|
+
return setByPathSegments(obj, segments, value);
|
|
46
|
+
}
|
|
47
|
+
function setByPathSegments(obj, segments, value) {
|
|
48
|
+
if (segments.length === 0)
|
|
49
|
+
return value;
|
|
50
|
+
const [head, ...tail] = segments;
|
|
51
|
+
const current = obj !== null && typeof obj === "object" ? obj : {};
|
|
52
|
+
if (tail.length === 0) {
|
|
53
|
+
return { ...current, [head]: value };
|
|
54
|
+
}
|
|
55
|
+
const nested = current[head];
|
|
56
|
+
return {
|
|
57
|
+
...current,
|
|
58
|
+
[head]: setByPathSegments(nested, tail, value),
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Immutably remove value at path
|
|
63
|
+
*/
|
|
64
|
+
export function unsetByPath(obj, path) {
|
|
65
|
+
if (!path)
|
|
66
|
+
return undefined;
|
|
67
|
+
const segments = parsePath(path);
|
|
68
|
+
return unsetByPathSegments(obj, segments);
|
|
69
|
+
}
|
|
70
|
+
function unsetByPathSegments(obj, segments) {
|
|
71
|
+
if (segments.length === 0 || obj === null || typeof obj !== "object") {
|
|
72
|
+
return obj;
|
|
73
|
+
}
|
|
74
|
+
const [head, ...tail] = segments;
|
|
75
|
+
const current = obj;
|
|
76
|
+
if (tail.length === 0) {
|
|
77
|
+
const { [head]: _, ...rest } = current;
|
|
78
|
+
return rest;
|
|
79
|
+
}
|
|
80
|
+
const nested = current[head];
|
|
81
|
+
return {
|
|
82
|
+
...current,
|
|
83
|
+
[head]: unsetByPathSegments(nested, tail),
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Immutably shallow merge at path
|
|
88
|
+
*/
|
|
89
|
+
export function mergeAtPath(obj, path, value) {
|
|
90
|
+
const existing = getByPath(obj, path);
|
|
91
|
+
const merged = existing !== null && typeof existing === "object"
|
|
92
|
+
? { ...existing, ...value }
|
|
93
|
+
: value;
|
|
94
|
+
return setByPath(obj, path, merged);
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Check if a path exists in an object
|
|
98
|
+
*/
|
|
99
|
+
export function hasPath(obj, path) {
|
|
100
|
+
if (!path)
|
|
101
|
+
return obj !== undefined;
|
|
102
|
+
const segments = parsePath(path);
|
|
103
|
+
let current = obj;
|
|
104
|
+
for (const segment of segments) {
|
|
105
|
+
if (current === null || current === undefined) {
|
|
106
|
+
return false;
|
|
107
|
+
}
|
|
108
|
+
if (typeof current !== "object") {
|
|
109
|
+
return false;
|
|
110
|
+
}
|
|
111
|
+
if (!(segment in current)) {
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
current = current[segment];
|
|
115
|
+
}
|
|
116
|
+
return true;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Get parent path
|
|
120
|
+
*/
|
|
121
|
+
export function parentPath(path) {
|
|
122
|
+
const segments = parsePath(path);
|
|
123
|
+
return segments.slice(0, -1).join(".");
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Get last segment of path
|
|
127
|
+
*/
|
|
128
|
+
export function lastSegment(path) {
|
|
129
|
+
const segments = parsePath(path);
|
|
130
|
+
return segments[segments.length - 1] ?? "";
|
|
131
|
+
}
|
|
132
|
+
//# sourceMappingURL=path.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"path.js","sourceRoot":"","sources":["../../src/utils/path.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"path.test.d.ts","sourceRoot":"","sources":["../../src/utils/path.test.ts"],"names":[],"mappings":""}
|