@vibe-agent-toolkit/resources 0.1.34 → 0.1.36

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.
@@ -0,0 +1,154 @@
1
+ /**
2
+ * Pure schema/data traversal that captures every string value sitting at a
3
+ * JSON Schema position whose `format` is in the URI family.
4
+ *
5
+ * Handles:
6
+ * - `properties` (recursion)
7
+ * - `items` (single-schema and tuple)
8
+ * - `oneOf` / `anyOf` / `allOf` (every branch walked) AND sibling keywords
9
+ * in the same node (JSON Schema AND semantics)
10
+ * - `$ref` (resolved against schema root via JSON Pointer; cycle-protected)
11
+ * - `definitions` and `$defs` as ref targets
12
+ *
13
+ * Does NOT handle (intentional, see spec §"Non-Goals"):
14
+ * - `if`/`then`/`else`, `dependentSchemas`
15
+ * - `patternProperties`, schema-form `additionalProperties`
16
+ * - `prefixItems` (JSON Schema 2020-12)
17
+ *
18
+ * Captures are deduplicated by `(pointer, value)` before return so that
19
+ * multiple matching composite branches don't produce duplicate issues.
20
+ *
21
+ * No I/O. No side effects.
22
+ */
23
+ import { decodeJsonPointerSegment, encodeJsonPointerSegment, formatJsonPointerAsDotted } from './utils.js';
24
+ const URI_FAMILY_FORMATS = new Set([
25
+ 'uri-reference',
26
+ 'uri',
27
+ 'iri-reference',
28
+ 'iri',
29
+ ]);
30
+ /**
31
+ * Walk a frontmatter document against a JSON Schema and return every value
32
+ * whose schema position has a URI-family `format` keyword.
33
+ */
34
+ export function walkFrontmatterUriReferences(data, schema) {
35
+ if (data === undefined || data === null)
36
+ return [];
37
+ const captures = [];
38
+ walk(data, schema, schema, [], new Set(), captures);
39
+ return dedupe(captures);
40
+ }
41
+ function walkComposites(data, node, root, pointerSegments, visitedRefs, captures) {
42
+ for (const branchList of [node.oneOf, node.anyOf, node.allOf]) {
43
+ if (Array.isArray(branchList)) {
44
+ for (const branch of branchList) {
45
+ walk(data, branch, root, pointerSegments, visitedRefs, captures);
46
+ }
47
+ }
48
+ }
49
+ }
50
+ function walkProperties(data, node, root, pointerSegments, visitedRefs, captures) {
51
+ if (!node.properties || data === null || typeof data !== 'object' || Array.isArray(data))
52
+ return;
53
+ const dataObj = data;
54
+ for (const [key, propSchema] of Object.entries(node.properties)) {
55
+ if (key in dataObj) {
56
+ walk(dataObj[key], propSchema, root, [...pointerSegments, encodeJsonPointerSegment(key)], visitedRefs, captures);
57
+ }
58
+ }
59
+ }
60
+ function walkItems(data, node, root, pointerSegments, visitedRefs, captures) {
61
+ if (!node.items || !Array.isArray(data))
62
+ return;
63
+ if (Array.isArray(node.items)) {
64
+ const tupleSchemas = node.items;
65
+ for (const [i, itemValue] of data.entries()) {
66
+ if (i >= tupleSchemas.length)
67
+ break;
68
+ walk(itemValue, tupleSchemas[i], root, [...pointerSegments, String(i)], visitedRefs, captures);
69
+ }
70
+ }
71
+ else {
72
+ for (const [i, itemValue] of data.entries()) {
73
+ walk(itemValue, node.items, root, [...pointerSegments, String(i)], visitedRefs, captures);
74
+ }
75
+ }
76
+ }
77
+ function walk(data, node, root, pointerSegments, visitedRefs, captures) {
78
+ if (!node || typeof node !== 'object')
79
+ return;
80
+ // Resolve $ref against schema root. Cycle protection: skip if already on the
81
+ // recursion stack. Pop after recursion.
82
+ if (typeof node.$ref === 'string') {
83
+ if (visitedRefs.has(node.$ref))
84
+ return;
85
+ const resolved = resolveRef(node.$ref, root);
86
+ if (!resolved)
87
+ return;
88
+ visitedRefs.add(node.$ref);
89
+ walk(data, resolved, root, pointerSegments, visitedRefs, captures);
90
+ visitedRefs.delete(node.$ref);
91
+ return;
92
+ }
93
+ // Composite schemas: walk every branch. CRITICAL: do NOT short-circuit;
94
+ // sibling `properties`/`items` are AND-combined with the composite.
95
+ walkComposites(data, node, root, pointerSegments, visitedRefs, captures);
96
+ // URI-family format leaf
97
+ if (typeof node.format === 'string' &&
98
+ URI_FAMILY_FORMATS.has(node.format) &&
99
+ typeof data === 'string') {
100
+ const pointer = pointerSegments.length === 0 ? '' : '/' + pointerSegments.join('/');
101
+ captures.push({
102
+ value: data,
103
+ pointer,
104
+ dottedPath: formatJsonPointerAsDotted(pointer),
105
+ format: node.format,
106
+ });
107
+ // Fall through — schemas with both `format` and sibling object/array
108
+ // structure are unusual but possible; let recursion proceed.
109
+ }
110
+ // Object recursion
111
+ walkProperties(data, node, root, pointerSegments, visitedRefs, captures);
112
+ // Array recursion
113
+ walkItems(data, node, root, pointerSegments, visitedRefs, captures);
114
+ // Intentionally NOT handled: if/then/else, dependentSchemas, patternProperties,
115
+ // schema-form additionalProperties, prefixItems (2020-12). See spec §"Non-Goals".
116
+ }
117
+ /**
118
+ * Resolve a local $ref (e.g., "#/$defs/Foo") against the schema root using a
119
+ * generic JSON Pointer walk. Returns null for unresolvable refs or non-local
120
+ * refs (no cross-file support in v1).
121
+ */
122
+ function resolveRef(ref, root) {
123
+ if (!ref.startsWith('#/'))
124
+ return null;
125
+ // eslint-disable-next-line local/no-hardcoded-path-split -- RFC 6901 JSON Pointer segment splitting, not a file path
126
+ const segments = ref.slice(2).split('/').map(decodeJsonPointerSegment);
127
+ let cursor = root;
128
+ for (const seg of segments) {
129
+ if (cursor === null || typeof cursor !== 'object')
130
+ return null;
131
+ cursor = cursor[seg];
132
+ if (cursor === undefined)
133
+ return null;
134
+ }
135
+ return cursor ?? null;
136
+ }
137
+ /**
138
+ * Remove duplicate captures by (pointer, value). Multiple matching branches
139
+ * of `oneOf`/`anyOf`/`allOf` can produce duplicates; users should see one
140
+ * issue per field, not one per branch.
141
+ */
142
+ function dedupe(captures) {
143
+ const seen = new Set();
144
+ const out = [];
145
+ for (const c of captures) {
146
+ const key = c.pointer + ' ' + c.value;
147
+ if (seen.has(key))
148
+ continue;
149
+ seen.add(key);
150
+ out.push(c);
151
+ }
152
+ return out;
153
+ }
154
+ //# sourceMappingURL=schema-uri-walker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema-uri-walker.js","sourceRoot":"","sources":["../src/schema-uri-walker.ts"],"names":[],"mappings":"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"}