@zhin.js/config-yaml 1.0.2 → 1.0.4
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/lib/yaml-config-document.js +45 -3
- package/package.json +3 -3
|
@@ -2,7 +2,7 @@ import { createHash, randomUUID } from 'node:crypto';
|
|
|
2
2
|
import { readFile, rename, rm, stat, writeFile } from 'node:fs/promises';
|
|
3
3
|
import { basename, dirname, resolve } from 'node:path';
|
|
4
4
|
import { ConfigPatchPathError, } from '@zhin.js/runtime';
|
|
5
|
-
import { parseDocument } from 'yaml';
|
|
5
|
+
import { isMap, isSeq, parseDocument } from 'yaml';
|
|
6
6
|
export class YamlConfigDocumentError extends Error {
|
|
7
7
|
constructor(message, options) {
|
|
8
8
|
super(message, options);
|
|
@@ -125,9 +125,51 @@ function applyPatch(document, patch) {
|
|
|
125
125
|
return;
|
|
126
126
|
}
|
|
127
127
|
if (patch.op === 'set')
|
|
128
|
-
document.setIn(patch.path, structuredClone(patch.value));
|
|
128
|
+
document.setIn(resolvePath(document, patch.path), structuredClone(patch.value));
|
|
129
129
|
else
|
|
130
|
-
document.deleteIn(patch.path);
|
|
130
|
+
document.deleteIn(resolvePath(document, patch.path));
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Walks the AST so numeric segments address sequence elements (`endpoints.0.url`).
|
|
134
|
+
* Non-numeric segments on a sequence and out-of-bounds indexes are rejected
|
|
135
|
+
* with the same errors as the Runtime planner; missing intermediates are left
|
|
136
|
+
* for `setIn` to create as mappings (matching planner semantics).
|
|
137
|
+
*/
|
|
138
|
+
function resolvePath(document, path) {
|
|
139
|
+
const resolved = [];
|
|
140
|
+
let node = document.contents;
|
|
141
|
+
for (const [index, segment] of path.entries()) {
|
|
142
|
+
const isLast = index === path.length - 1;
|
|
143
|
+
if (isSeq(node)) {
|
|
144
|
+
if (!/^(0|[1-9]\d*)$/.test(segment)) {
|
|
145
|
+
throw new ConfigPatchPathError(`Config path ${pointer(path.slice(0, index + 1))} requires an array index, got "${segment}"`);
|
|
146
|
+
}
|
|
147
|
+
const arrayIndex = Number(segment);
|
|
148
|
+
if (arrayIndex >= node.items.length) {
|
|
149
|
+
throw new ConfigPatchPathError(`Config path ${pointer(path.slice(0, index + 1))} is out of bounds (array length ${node.items.length})`);
|
|
150
|
+
}
|
|
151
|
+
resolved.push(arrayIndex);
|
|
152
|
+
node = isLast ? undefined : node.get(arrayIndex, false);
|
|
153
|
+
}
|
|
154
|
+
else if (isMap(node)) {
|
|
155
|
+
resolved.push(segment);
|
|
156
|
+
node = isLast ? undefined : node.get(segment, false);
|
|
157
|
+
}
|
|
158
|
+
else if (node == null) {
|
|
159
|
+
// Missing intermediate mapping (setIn creates it).
|
|
160
|
+
resolved.push(segment);
|
|
161
|
+
node = undefined;
|
|
162
|
+
}
|
|
163
|
+
else {
|
|
164
|
+
throw new ConfigPatchPathError(`Config path ${pointer(path.slice(0, index + 1))} is not an object`);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
return resolved;
|
|
168
|
+
}
|
|
169
|
+
function pointer(path) {
|
|
170
|
+
if (path.length === 0)
|
|
171
|
+
return '/';
|
|
172
|
+
return `/${path.map((segment) => segment.replaceAll('~', '~0').replaceAll('/', '~1')).join('/')}`;
|
|
131
173
|
}
|
|
132
174
|
function assertPath(path) {
|
|
133
175
|
for (const segment of path) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zhin.js/config-yaml",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.4",
|
|
4
4
|
"description": "Comment-preserving YAML ConfigDocument adapter for the Zhin Plugin Runtime",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./lib/index.js",
|
|
@@ -17,12 +17,12 @@
|
|
|
17
17
|
],
|
|
18
18
|
"dependencies": {
|
|
19
19
|
"yaml": "2.9.0",
|
|
20
|
-
"@zhin.js/runtime": "1.0.
|
|
20
|
+
"@zhin.js/runtime": "1.0.4"
|
|
21
21
|
},
|
|
22
22
|
"devDependencies": {
|
|
23
23
|
"@types/node": "^26.1.0",
|
|
24
24
|
"typescript": "^6.0.3",
|
|
25
|
-
"@zhin.js/plugin-runtime": "1.1.
|
|
25
|
+
"@zhin.js/plugin-runtime": "1.1.1"
|
|
26
26
|
},
|
|
27
27
|
"engines": {
|
|
28
28
|
"node": "^20.19.0 || >=22.12.0"
|