@daweifu/capability-menu 0.1.1 → 0.1.3
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.en.md +238 -0
- package/README.md +127 -63
- package/cordis.patch.yml +37 -46
- package/lib/client.d.ts +224 -19
- package/lib/client.d.ts.map +1 -1
- package/lib/client.js +1796 -226
- package/lib/constants.js +33 -0
- package/lib/constants.js.map +1 -0
- package/lib/index.js +1 -1
- package/lib/invoke.js +68 -96
- package/lib/invoke.js.map +1 -1
- package/lib/locations.js +541 -0
- package/lib/locations.js.map +1 -0
- package/lib/patch-file.js +192 -0
- package/lib/patch-file.js.map +1 -0
- package/lib/policy.js +422 -94
- package/lib/policy.js.map +1 -1
- package/lib/registry.js +410 -152
- package/lib/registry.js.map +1 -1
- package/lib/search.js +26 -9
- package/lib/search.js.map +1 -1
- package/lib/server/remote.js +219 -3
- package/lib/server/remote.js.map +1 -1
- package/lib/types/constants.d.ts +33 -0
- package/lib/types/constants.d.ts.map +1 -0
- package/lib/types/index.d.ts +1 -1
- package/lib/types/invoke.d.ts +7 -13
- package/lib/types/invoke.d.ts.map +1 -1
- package/lib/types/locations.d.ts +142 -0
- package/lib/types/locations.d.ts.map +1 -0
- package/lib/types/patch-file.d.ts +46 -0
- package/lib/types/patch-file.d.ts.map +1 -0
- package/lib/types/policy.d.ts +115 -53
- package/lib/types/policy.d.ts.map +1 -1
- package/lib/types/registry.d.ts +94 -25
- package/lib/types/registry.d.ts.map +1 -1
- package/lib/types/search.d.ts.map +1 -1
- package/lib/types/server/remote.d.ts +68 -2
- package/lib/types/server/remote.d.ts.map +1 -1
- package/package.json +23 -26
- package/lib/invariant.js +0 -22
- package/lib/invariant.js.map +0 -1
- package/lib/types/invariant.d.ts +0 -16
- package/lib/types/invariant.d.ts.map +0 -1
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Comment-preserving, loop-safe editing of a dsh patch file.
|
|
3
|
+
*
|
|
4
|
+
* dsh owns and composes these files (`~/.dsh/cordis.patch.yml` and per-profile
|
|
5
|
+
* `cordis.patch.yml`), and in a `patchReload: live` profile it *watches* them:
|
|
6
|
+
* any write triggers a transactional re-apply of the patch, which re-applies
|
|
7
|
+
* this very plugin. Two consequences drive everything below:
|
|
8
|
+
*
|
|
9
|
+
* - **A no-op must never write.** Writing on every startup/apply would make the
|
|
10
|
+
* plugin reload itself forever. So each mutation reports whether it actually
|
|
11
|
+
* changed the document, and nothing is written when it did not.
|
|
12
|
+
* - **A write must never damage the file.** The file is a hand-maintained asset
|
|
13
|
+
* (comments, `!!js` expressions, credentials). Edits go through `yaml`'s
|
|
14
|
+
* document API, which keeps comments, and every write is backed up, verified
|
|
15
|
+
* by re-parsing, and rolled back on failure.
|
|
16
|
+
*
|
|
17
|
+
* Note the round-trip is *not* byte-identical — `yaml` normalizes trailing
|
|
18
|
+
* comment spacing and quoting style. That is why "did this change anything?" is
|
|
19
|
+
* decided by the mutation, never by comparing before/after text.
|
|
20
|
+
*/
|
|
21
|
+
import { copyFile, readFile, rename, unlink, writeFile } from 'node:fs/promises';
|
|
22
|
+
import { randomUUID } from 'node:crypto';
|
|
23
|
+
import { homedir } from 'node:os';
|
|
24
|
+
import { join } from 'node:path';
|
|
25
|
+
import YAML from 'yaml';
|
|
26
|
+
/** Default patch file: the home-level layer shared by every profile. */
|
|
27
|
+
export function defaultPatchFile() {
|
|
28
|
+
const home = process.env['DSH_HOME'];
|
|
29
|
+
if (home !== undefined && home.length > 0)
|
|
30
|
+
return join(home, 'cordis.patch.yml');
|
|
31
|
+
return join(homedir(), '.dsh', 'cordis.patch.yml');
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Every entry row in the document: both bare top-level rows and rows nested in
|
|
35
|
+
* an `- insert:` block (the form dsh's own patches and this bundle use).
|
|
36
|
+
*/
|
|
37
|
+
function* entryNodes(doc) {
|
|
38
|
+
const root = doc.contents;
|
|
39
|
+
if (!YAML.isSeq(root))
|
|
40
|
+
return;
|
|
41
|
+
for (const item of root.items) {
|
|
42
|
+
if (!YAML.isMap(item))
|
|
43
|
+
continue;
|
|
44
|
+
const insert = item.get('insert');
|
|
45
|
+
if (insert !== undefined && insert !== null) {
|
|
46
|
+
if (!YAML.isSeq(insert))
|
|
47
|
+
continue;
|
|
48
|
+
for (const row of insert.items) {
|
|
49
|
+
if (YAML.isMap(row))
|
|
50
|
+
yield { node: row, parent: insert };
|
|
51
|
+
}
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
if (item.get('id') !== undefined)
|
|
55
|
+
yield { node: item, parent: root };
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
/** Find the entry row with `id`, if the file declares one. */
|
|
59
|
+
export function findEntry(doc, id) {
|
|
60
|
+
for (const { node } of entryNodes(doc)) {
|
|
61
|
+
if (node.get('id') === id)
|
|
62
|
+
return node;
|
|
63
|
+
}
|
|
64
|
+
return undefined;
|
|
65
|
+
}
|
|
66
|
+
/** Read every declared entry as plain data (never mutates the file). */
|
|
67
|
+
export async function readEntries(file) {
|
|
68
|
+
const source = await readFile(file, 'utf8');
|
|
69
|
+
const doc = YAML.parseDocument(source);
|
|
70
|
+
const entries = [];
|
|
71
|
+
for (const { node } of entryNodes(doc)) {
|
|
72
|
+
const value = node.toJSON();
|
|
73
|
+
if (typeof value.id !== 'string' || typeof value.name !== 'string')
|
|
74
|
+
continue;
|
|
75
|
+
entries.push(value);
|
|
76
|
+
}
|
|
77
|
+
return entries;
|
|
78
|
+
}
|
|
79
|
+
/** The last `- insert:` block in the document, if any. */
|
|
80
|
+
function lastInsertSeq(doc) {
|
|
81
|
+
const root = doc.contents;
|
|
82
|
+
if (!YAML.isSeq(root))
|
|
83
|
+
return undefined;
|
|
84
|
+
let found;
|
|
85
|
+
for (const item of root.items) {
|
|
86
|
+
if (!YAML.isMap(item))
|
|
87
|
+
continue;
|
|
88
|
+
const insert = item.get('insert');
|
|
89
|
+
if (YAML.isSeq(insert))
|
|
90
|
+
found = insert;
|
|
91
|
+
}
|
|
92
|
+
return found;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Append a row to the document. Reuses the last `- insert:` block so new rows
|
|
96
|
+
* land next to the existing ones; creates one when the file has none.
|
|
97
|
+
*/
|
|
98
|
+
export function addEntry(doc, entry) {
|
|
99
|
+
const root = doc.contents;
|
|
100
|
+
if (!YAML.isSeq(root))
|
|
101
|
+
throw new Error('patch file root is not a sequence');
|
|
102
|
+
const target = lastInsertSeq(doc) ?? (() => {
|
|
103
|
+
const block = doc.createNode({ insert: [] });
|
|
104
|
+
// `root` is narrowed to a parsed sequence; the freshly built map is not
|
|
105
|
+
// narrowed with it even though it is a real document node.
|
|
106
|
+
root.add(block);
|
|
107
|
+
return block.get('insert');
|
|
108
|
+
})();
|
|
109
|
+
target.add(doc.createNode({ ...entry }));
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Append a bare, id-targeted override row (`- id: … / name: … / config: …`) at
|
|
113
|
+
* the top level — a patch that *finds* a row instead of adding one.
|
|
114
|
+
*
|
|
115
|
+
* Deliberately not {@link addEntry}: the row being configured is usually
|
|
116
|
+
* contributed by another layer. This plugin's own bundle patch inserts
|
|
117
|
+
* `capability-menu-policy`, and a profile's home layer is applied *after* that
|
|
118
|
+
* layer, so inserting a second row with the same id here leaves the composed
|
|
119
|
+
* tree with two rows sharing an id — which dsh refuses outright with
|
|
120
|
+
* `duplicate loader entry id`, taking the whole profile down.
|
|
121
|
+
*/
|
|
122
|
+
export function addEntryOverride(doc, entry) {
|
|
123
|
+
const root = doc.contents;
|
|
124
|
+
if (!YAML.isSeq(root))
|
|
125
|
+
throw new Error('patch file root is not a sequence');
|
|
126
|
+
// `root` is narrowed to a parsed sequence; the freshly built map is not
|
|
127
|
+
// narrowed with it even though it is a real document node.
|
|
128
|
+
root.add(doc.createNode({ ...entry }));
|
|
129
|
+
}
|
|
130
|
+
/** Remove the row with `id`. Returns false when the file has no such row. */
|
|
131
|
+
export function removeEntry(doc, id) {
|
|
132
|
+
for (const { node, parent } of entryNodes(doc)) {
|
|
133
|
+
if (node.get('id') !== id)
|
|
134
|
+
continue;
|
|
135
|
+
parent.delete(parent.items.indexOf(node));
|
|
136
|
+
return true;
|
|
137
|
+
}
|
|
138
|
+
return false;
|
|
139
|
+
}
|
|
140
|
+
/** Set or clear `disabled:` on the row with `id`. */
|
|
141
|
+
export function setEntryDisabled(doc, id, disabled) {
|
|
142
|
+
const node = findEntry(doc, id);
|
|
143
|
+
if (node === undefined)
|
|
144
|
+
return false;
|
|
145
|
+
if (disabled)
|
|
146
|
+
node.set('disabled', true);
|
|
147
|
+
else
|
|
148
|
+
node.delete('disabled');
|
|
149
|
+
return true;
|
|
150
|
+
}
|
|
151
|
+
/** Replace the row's `config:` (patch semantics replace the whole value). */
|
|
152
|
+
export function setEntryConfig(doc, id, config) {
|
|
153
|
+
const node = findEntry(doc, id);
|
|
154
|
+
if (node === undefined)
|
|
155
|
+
return false;
|
|
156
|
+
node.set('config', doc.createNode(config));
|
|
157
|
+
return true;
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Load the patch file, apply `mutate`, and persist only when it reports a
|
|
161
|
+
* change. Returns whether a write happened (i.e. whether dsh will hot-reload).
|
|
162
|
+
*
|
|
163
|
+
* `mutate` must be pure apart from its edits to `doc`: it may be the only
|
|
164
|
+
* chance to change the file, and a thrown error leaves the file untouched.
|
|
165
|
+
*/
|
|
166
|
+
export async function mutatePatch(file, mutate) {
|
|
167
|
+
const original = await readFile(file, 'utf8');
|
|
168
|
+
const doc = YAML.parseDocument(original);
|
|
169
|
+
if (!mutate(doc))
|
|
170
|
+
return false;
|
|
171
|
+
const next = doc.toString();
|
|
172
|
+
const backup = `${file}.bak`;
|
|
173
|
+
const tmp = `${file}.tmp-${randomUUID()}`;
|
|
174
|
+
await copyFile(file, backup);
|
|
175
|
+
try {
|
|
176
|
+
await writeFile(tmp, next, 'utf8');
|
|
177
|
+
// Verify before it becomes the live file: a document that no longer parses
|
|
178
|
+
// would take the whole profile down on the next reload.
|
|
179
|
+
const check = YAML.parseDocument(await readFile(tmp, 'utf8'));
|
|
180
|
+
if (check.errors.length > 0) {
|
|
181
|
+
throw new Error(`rewritten patch file does not parse: ${check.errors[0]?.message ?? 'unknown error'}`);
|
|
182
|
+
}
|
|
183
|
+
await rename(tmp, file);
|
|
184
|
+
return true;
|
|
185
|
+
}
|
|
186
|
+
catch (error) {
|
|
187
|
+
await unlink(tmp).catch(() => { });
|
|
188
|
+
await copyFile(backup, file).catch(() => { });
|
|
189
|
+
throw error;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
//# sourceMappingURL=patch-file.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"patch-file.js","sourceRoot":"","sources":["../src/patch-file.ts"],"names":[],"mappings":"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"}
|