@poe-platform/safe-bash 0.1.816 → 0.1.817
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/dist/pdf-ast/content/evaluator.d.ts +4 -0
- package/dist/pdf-ast/cos/value-parser.d.ts +2 -0
- package/dist/pdf-ast/fonts/resolve.d.ts +5 -1
- package/dist/pdf-ast/index.js +172 -165
- package/dist/safe-bash/command-chunks/biff-KLS4T7FP-UO3CXFFF.js +5581 -0
- package/dist/safe-bash/command-chunks/chunk-2J4OQT3F.js +153 -0
- package/dist/safe-bash/command-chunks/{chunk-K7VDCBXW.js → chunk-ABL2DPJI.js} +20 -20
- package/dist/safe-bash/command-chunks/{chunk-RINR7XPR.js → chunk-E64ZI2YB.js} +121 -4
- package/dist/safe-bash/command-chunks/{chunk-GEDO5V32.js → chunk-FSG6UC2N.js} +243 -105
- package/dist/safe-bash/command-chunks/{chunk-4QEJPP3K.js → chunk-S5X7PBO4.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-IHLZ6HNQ.js → chunk-TSKJNCKD.js} +3 -2
- package/dist/safe-bash/command-chunks/{chunk-DBZCTL7C.js → chunk-UYZ6EFZE.js} +20 -18
- package/dist/safe-bash/command-chunks/{chunk-B2C3UPJS.js → chunk-W42SUPD6.js} +13 -1
- package/dist/safe-bash/command-chunks/chunk-ZHHALBM7.js +398 -0
- package/dist/safe-bash/command-chunks/{command-engine-GHE6QUHU.js → command-engine-2QXVRRH3.js} +8 -4
- package/dist/safe-bash/command-chunks/{engine-RG6HQCCB-FXYZS264.js → engine-T4GP6QOK-ECFKMR5V.js} +1 -1
- package/dist/safe-bash/command-chunks/odf-SL5TG4B3-XI3FNOTN.js +3041 -0
- package/dist/safe-bash/command-chunks/{xlsx-RE54MFCS-IQ6OXXKK.js → xlsx-RE54MFCS-4UZ5W3U7.js} +1 -1
- package/dist/safe-bash-command-apply-patch/apply.js +1 -1
- package/dist/safe-bash-command-apply-patch/index.js +1 -1
- package/dist/safe-bash-command-csvkit/index.js +1 -1
- package/dist/safe-bash-command-diff/diff.js +1 -1
- package/dist/safe-bash-command-diff/index.js +1 -1
- package/dist/safe-bash-command-pptx/engine.js +1 -1
- package/dist/safe-bash-command-ssconvert/index.js +5 -5
- package/dist/safe-bash-presentation-engine/index.js +1 -1
- package/dist/safe-bash-presentation-engine/retained-tags.d.ts +20 -0
- package/dist/safe-bash-presentation-engine/tags.d.ts +2 -0
- package/dist/safe-bash-presentation-engine/tags.js +11 -3
- package/dist/safe-bash-xml-engine/document.js +2 -2
- package/dist/safe-bash-xml-engine/index.js +2 -2
- package/dist/safe-bash-xml-engine/stored-document.d.ts +2 -0
- package/dist/safe-bash-xml-engine/stored-document.js +1 -1
- package/dist/safe-bash-xml-engine/stored-evaluate.js +2 -2
- package/dist/safe-bash-xml-engine/stored-namespaces.d.ts +21 -0
- package/dist/safe-bash-zip-engine/zip/safety.js +1 -1
- package/dist/safe-bash-zip-engine/zip/volumes.js +1 -1
- package/dist/spreadsheet-format-xls/biff-properties-merge.js +3 -3
- package/dist/spreadsheet-format-xls/biff-properties.d.ts +4 -2
- package/dist/spreadsheet-format-xls/biff-properties.js +141 -122
- package/dist/spreadsheet-format-xls/biff-property-names.d.ts +24 -0
- package/dist/spreadsheet-format-xls/biff-property-names.js +167 -0
- package/dist/xlsx-ast/comment-geometry.js +1 -1
- package/package.json +3 -2
- package/dist/safe-bash/command-chunks/biff-UBP2BZLK-JPODPKS3.js +0 -5448
- package/dist/safe-bash/command-chunks/chunk-O2HNOQQG.js +0 -161
- package/dist/safe-bash/command-chunks/chunk-ZUP5TBRG.js +0 -99
- package/dist/safe-bash/command-chunks/odf-3EA3EVSD-7B5GVNTC.js +0 -3097
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
|
+
StoredNamespaces,
|
|
2
3
|
StoredXmlDocument
|
|
3
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-E64ZI2YB.js";
|
|
4
5
|
import {
|
|
5
6
|
escape
|
|
6
7
|
} from "./chunk-IJE65P52.js";
|
|
@@ -139,7 +140,7 @@ function declaration(source) {
|
|
|
139
140
|
}
|
|
140
141
|
return result + "?>\n";
|
|
141
142
|
}
|
|
142
|
-
async function attributes(element, source, inherited, budget, exclusive, stored) {
|
|
143
|
+
async function attributes(element, source, namespaces, inherited, budget, exclusive, stored) {
|
|
143
144
|
const selected = stored ? new StoredAttributes(stored.storage, budget) : [];
|
|
144
145
|
for await (const attribute of source()) {
|
|
145
146
|
{
|
|
@@ -151,7 +152,7 @@ async function attributes(element, source, inherited, budget, exclusive, stored)
|
|
|
151
152
|
else await selected.append(attribute);
|
|
152
153
|
}
|
|
153
154
|
}
|
|
154
|
-
for (const [prefix, uri] of
|
|
155
|
+
for await (const [prefix, uri] of namespaces) {
|
|
155
156
|
{
|
|
156
157
|
const _p = budget.tick(uri.length + prefix.length + 1);
|
|
157
158
|
if (_p) await _p;
|
|
@@ -169,7 +170,7 @@ async function attributes(element, source, inherited, budget, exclusive, stored)
|
|
|
169
170
|
}
|
|
170
171
|
if (!used) continue;
|
|
171
172
|
}
|
|
172
|
-
if (uri === (inherited.get(prefix) ?? "")) continue;
|
|
173
|
+
if (uri === (await inherited.get(prefix) ?? "")) continue;
|
|
173
174
|
const attribute = {
|
|
174
175
|
name: prefix ? `xmlns:${prefix}` : "xmlns",
|
|
175
176
|
namespace: xmlns,
|
|
@@ -200,7 +201,6 @@ var StoredFrames = class {
|
|
|
200
201
|
}
|
|
201
202
|
document;
|
|
202
203
|
head = 0;
|
|
203
|
-
namespaces = /* @__PURE__ */ new WeakMap();
|
|
204
204
|
async store(value) {
|
|
205
205
|
const bytes = new TextEncoder().encode(JSON.stringify(value));
|
|
206
206
|
const header = new Uint8Array(8);
|
|
@@ -219,11 +219,8 @@ var StoredFrames = class {
|
|
|
219
219
|
for await (const frame of source) {
|
|
220
220
|
const checkpoint = this.document.budget.tick();
|
|
221
221
|
if (checkpoint) await checkpoint;
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
namespaces = await this.store([...frame.namespaces]);
|
|
225
|
-
this.namespaces.set(frame.namespaces, namespaces);
|
|
226
|
-
}
|
|
222
|
+
if (!(frame.namespaces instanceof StoredNamespaces)) throw new TypeError("Stored frames require backed namespace scopes");
|
|
223
|
+
const namespaces = frame.namespaces.reference;
|
|
227
224
|
const value = await this.store({ ...frame, namespaces });
|
|
228
225
|
const link = new Uint8Array(16), view = new DataView(link.buffer);
|
|
229
226
|
view.setFloat64(0, reversed, true);
|
|
@@ -247,8 +244,7 @@ var StoredFrames = class {
|
|
|
247
244
|
const view = new DataView(link.buffer, link.byteOffset, 16);
|
|
248
245
|
this.head = view.getFloat64(0, true);
|
|
249
246
|
const frame = await this.load(view.getFloat64(8, true));
|
|
250
|
-
const namespaces = new
|
|
251
|
-
this.namespaces.set(namespaces, frame.namespaces);
|
|
247
|
+
const namespaces = new StoredNamespaces(this.document.storage, this.document.budget, frame.namespaces);
|
|
252
248
|
return { ...frame, namespaces };
|
|
253
249
|
}
|
|
254
250
|
};
|
|
@@ -272,6 +268,9 @@ async function* serializeDocument(source, mode, budget, format = mode === "forma
|
|
|
272
268
|
if (typeof reference === "number") yield* stored.attributes(reference);
|
|
273
269
|
else if (reference.kind === "element") yield* reference.attributes;
|
|
274
270
|
}
|
|
271
|
+
async function namespaceScope(reference, element) {
|
|
272
|
+
return typeof reference === "number" ? stored.namespaceScope(reference) : element.namespaces;
|
|
273
|
+
}
|
|
275
274
|
const root = await load(rootReference);
|
|
276
275
|
const canonical = mode !== "format";
|
|
277
276
|
const documentDeclaration = options.declaration ?? root.declaration;
|
|
@@ -302,7 +301,7 @@ async function* serializeDocument(source, mode, budget, format = mode === "forma
|
|
|
302
301
|
const p = budget.tick();
|
|
303
302
|
if (p) await p;
|
|
304
303
|
}
|
|
305
|
-
for (const [prefix, uri] of element
|
|
304
|
+
for await (const [prefix, uri] of await namespaceScope(reference, element)) {
|
|
306
305
|
{
|
|
307
306
|
const p = budget.tick(uri.length + prefix.length + 1);
|
|
308
307
|
if (p) await p;
|
|
@@ -317,7 +316,7 @@ async function* serializeDocument(source, mode, budget, format = mode === "forma
|
|
|
317
316
|
}
|
|
318
317
|
}
|
|
319
318
|
} else yield declaration(documentDeclaration);
|
|
320
|
-
const namespaces = /* @__PURE__ */ new Map([["xml", xml]]);
|
|
319
|
+
const namespaces = stored ? await new StoredNamespaces(stored.storage, budget).set("xml", xml) : /* @__PURE__ */ new Map([["xml", xml]]);
|
|
321
320
|
async function* siblings() {
|
|
322
321
|
if (stored) yield* stored.children(stored.document);
|
|
323
322
|
else {
|
|
@@ -430,7 +429,7 @@ async function* serializeDocument(source, mode, budget, format = mode === "forma
|
|
|
430
429
|
count++;
|
|
431
430
|
mixed = child.mixed;
|
|
432
431
|
}
|
|
433
|
-
const ordered = canonical ? await attributes(current, () => elementAttributes(reference), frame.namespaces, budget, mode === "exc-c14n", stored) : [];
|
|
432
|
+
const ordered = canonical ? await attributes(current, () => elementAttributes(reference), await namespaceScope(reference, current), frame.namespaces, budget, mode === "exc-c14n", stored) : [];
|
|
434
433
|
async function* outputAttributes() {
|
|
435
434
|
if (canonical) yield* ordered;
|
|
436
435
|
else for (const namespace of [true, false]) for await (const attribute of elementAttributes(reference)) {
|
|
@@ -444,9 +443,12 @@ async function* serializeDocument(source, mode, budget, format = mode === "forma
|
|
|
444
443
|
yield `<${current.name}`;
|
|
445
444
|
for await (const attribute of outputAttributes()) {
|
|
446
445
|
if (canonical && attribute.namespace === xmlns) {
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
446
|
+
if (childNamespaces instanceof StoredNamespaces) childNamespaces = await childNamespaces.set(attribute.localName, attribute.value);
|
|
447
|
+
else {
|
|
448
|
+
changed ??= new Map(childNamespaces);
|
|
449
|
+
changed.set(attribute.localName, attribute.value);
|
|
450
|
+
childNamespaces = changed;
|
|
451
|
+
}
|
|
450
452
|
}
|
|
451
453
|
{
|
|
452
454
|
const p = budget.tick();
|
|
@@ -18,6 +18,7 @@ import {
|
|
|
18
18
|
// packages/safe-bash-command-apply-patch/src/apply.ts
|
|
19
19
|
import { PagedStorage as PagedStorage2 } from "@poe-platform/safe-fs/storage";
|
|
20
20
|
import {
|
|
21
|
+
collectBytes,
|
|
21
22
|
createOutputOperation,
|
|
22
23
|
dirname,
|
|
23
24
|
readBytes,
|
|
@@ -398,7 +399,7 @@ var Invocation = class {
|
|
|
398
399
|
for (const file of files) for (const path of [file.path, file.destination]) {
|
|
399
400
|
if (!path) continue;
|
|
400
401
|
const capabilities = await this.work.fs(path, async () => await this.fs.capabilitiesFor?.(path, { signal: this.context.signal }) ?? this.fs.capabilities);
|
|
401
|
-
if (capabilities.atomicFileMutation !== true || capabilities.retainedStagingWrite !== true || capabilities.retainedStagingCleanup !== true || capabilities.atomicStagedFileMutation !== true) throw new PatchError("filesystem does not support atomic conditional patch mutations");
|
|
402
|
+
if (capabilities.atomicFileMutation !== true || !this.fs.writeFileConditional && (capabilities.retainedStagingWrite !== true || capabilities.retainedStagingCleanup !== true || capabilities.atomicStagedFileMutation !== true)) throw new PatchError("filesystem does not support atomic conditional patch mutations");
|
|
402
403
|
let parent = dirname(path);
|
|
403
404
|
while (!await this.inspect(parent, false)) {
|
|
404
405
|
await this.work.charge(1);
|
|
@@ -609,6 +610,17 @@ var Invocation = class {
|
|
|
609
610
|
async write(path, output, parent, expected) {
|
|
610
611
|
let staging;
|
|
611
612
|
const signal = this.context.signal;
|
|
613
|
+
const capabilities = await this.work.fs(path, async () => await this.fs.capabilitiesFor?.(path, { signal }) ?? this.fs.capabilities);
|
|
614
|
+
if (capabilities.retainedStagingWrite !== true || capabilities.retainedStagingCleanup !== true || capabilities.atomicStagedFileMutation !== true) {
|
|
615
|
+
const bytes = await collectBytes(output.range(0, output.size), { signal, maxBytes: this.work.limits.maxFileBytes });
|
|
616
|
+
await this.work.fs(path, () => this.fs.writeFileConditional(path, bytes, {
|
|
617
|
+
parent,
|
|
618
|
+
expected: expected ?? null,
|
|
619
|
+
signal,
|
|
620
|
+
...expected ? { mode: expected.mode & 4095 } : {}
|
|
621
|
+
}));
|
|
622
|
+
return;
|
|
623
|
+
}
|
|
612
624
|
try {
|
|
613
625
|
await this.work.fs(path, async () => {
|
|
614
626
|
staging = await this.fs.createStagedFile(
|
|
@@ -0,0 +1,398 @@
|
|
|
1
|
+
import {
|
|
2
|
+
openRetainedPresentationIndex,
|
|
3
|
+
stageRetainedOutput,
|
|
4
|
+
streamJson
|
|
5
|
+
} from "./chunk-FB2WPI3M.js";
|
|
6
|
+
import {
|
|
7
|
+
attr,
|
|
8
|
+
child,
|
|
9
|
+
escape,
|
|
10
|
+
invalid,
|
|
11
|
+
loadShared,
|
|
12
|
+
nextRel,
|
|
13
|
+
relPart
|
|
14
|
+
} from "./chunk-A5SPMSKD.js";
|
|
15
|
+
import {
|
|
16
|
+
SelectionError,
|
|
17
|
+
decodeSelectionToken
|
|
18
|
+
} from "./chunk-NCNHJRIY.js";
|
|
19
|
+
import {
|
|
20
|
+
openRetainedPresentationValidation
|
|
21
|
+
} from "./chunk-6W4RMBFH.js";
|
|
22
|
+
import {
|
|
23
|
+
dialects
|
|
24
|
+
} from "./chunk-6KJDTKE4.js";
|
|
25
|
+
import {
|
|
26
|
+
parseXmlPart
|
|
27
|
+
} from "./chunk-7PYDVQPB.js";
|
|
28
|
+
import {
|
|
29
|
+
relativePartReference
|
|
30
|
+
} from "./chunk-MOUCMZZP.js";
|
|
31
|
+
import {
|
|
32
|
+
OfficeError,
|
|
33
|
+
RetainedValues,
|
|
34
|
+
equal,
|
|
35
|
+
folded,
|
|
36
|
+
literal,
|
|
37
|
+
openRetainedXmlDocument,
|
|
38
|
+
resolveOfficeResources
|
|
39
|
+
} from "./chunk-KM2SMMXZ.js";
|
|
40
|
+
|
|
41
|
+
// packages/safe-bash-presentation-engine/src/retained-tags.ts
|
|
42
|
+
import { PagedStorage } from "@poe-platform/safe-fs/storage";
|
|
43
|
+
async function openRetainedTags(archive, fingerprint, options, settings) {
|
|
44
|
+
validateTagOptions(options);
|
|
45
|
+
const query = { ...options, ...options.selection ? { selection: { ...options.selection, ...options.selection.position ? { position: { ...options.selection.position } } : {} } } : {} };
|
|
46
|
+
const context = resolveOfficeResources(settings), working = { ...settings.workingStorage }, signal = context.signal ?? new AbortController().signal;
|
|
47
|
+
const index = await openRetainedPresentationIndex(archive, fingerprint, { ...context, workingStorage: working });
|
|
48
|
+
const pages = new PagedStorage({ fs: working.fs, cwd: working.directory, env: {}, signal }, (working.cacheBytes ?? 1024 * 1024) / 16384);
|
|
49
|
+
let closed = false, closing, head = 0, tail = 0;
|
|
50
|
+
const check = () => {
|
|
51
|
+
if (closed) throw new OfficeError("invalid-handle", "Tags are closed.", "index");
|
|
52
|
+
if (signal.aborted) throw new OfficeError("cancelled", "Operation cancelled.", "index");
|
|
53
|
+
};
|
|
54
|
+
const close = () => {
|
|
55
|
+
closed = true;
|
|
56
|
+
return closing ??= (async () => {
|
|
57
|
+
const outcomes = await Promise.allSettled([index.close(), pages.close()]);
|
|
58
|
+
for (const outcome of outcomes) if (outcome.status === "rejected") throw outcome.reason;
|
|
59
|
+
})();
|
|
60
|
+
};
|
|
61
|
+
const values = new RetainedValues(pages, check, signal);
|
|
62
|
+
const range = (row2, offset) => ({ start: row2[offset], length: row2[offset + 1] });
|
|
63
|
+
async function row(pointer) {
|
|
64
|
+
check();
|
|
65
|
+
const bytes = await pages.read(pointer, 7 /* Count */ * 8), view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
66
|
+
return Array.from({ length: 7 /* Count */ }, (_, n) => view.getFloat64(n * 8, true));
|
|
67
|
+
}
|
|
68
|
+
async function write(pointer, numbers) {
|
|
69
|
+
check();
|
|
70
|
+
const bytes = new Uint8Array(numbers.length * 8), view = new DataView(bytes.buffer);
|
|
71
|
+
numbers.forEach((number, n) => view.setFloat64(n * 8, number, true));
|
|
72
|
+
await pages.write(pointer, bytes);
|
|
73
|
+
}
|
|
74
|
+
async function bounded(value) {
|
|
75
|
+
const decoder = new TextDecoder();
|
|
76
|
+
let result = "";
|
|
77
|
+
for await (const bytes of values.read(value)) result += decoder.decode(bytes, { stream: true });
|
|
78
|
+
return result + decoder.decode();
|
|
79
|
+
}
|
|
80
|
+
const invalid2 = (message) => {
|
|
81
|
+
throw new OfficeError("invalid-value", message, "usage");
|
|
82
|
+
};
|
|
83
|
+
async function is(document, node, local, namespace) {
|
|
84
|
+
return await equal(document.raw(node.localName), literal(local)) && await equal(document.namespace(node), namespace);
|
|
85
|
+
}
|
|
86
|
+
async function child2(document, parent, local) {
|
|
87
|
+
let found;
|
|
88
|
+
for await (const node of document.children(parent)) if (node.kind === "element" && await is(document, node, local, document.namespace(parent))) {
|
|
89
|
+
if (found) invalid2("Ambiguous shared structure.");
|
|
90
|
+
found = node;
|
|
91
|
+
}
|
|
92
|
+
return found;
|
|
93
|
+
}
|
|
94
|
+
async function attribute(document, node, local, namespace = "") {
|
|
95
|
+
for await (const attr2 of document.attributes(node)) if (await is(document, attr2, local, literal(namespace))) return attr2;
|
|
96
|
+
return void 0;
|
|
97
|
+
}
|
|
98
|
+
try {
|
|
99
|
+
const validation = await openRetainedPresentationValidation(archive, { ...context, workingStorage: working }, { ...context.xmlLimits, ...context.relationshipLimits, maxBytes: Math.min(context.xmlLimits.maxBytes, context.relationshipLimits.maxBytes), maxEntries: context.archiveLimits.maxMembers });
|
|
100
|
+
const valid = validation.valid;
|
|
101
|
+
try {
|
|
102
|
+
await validation.close();
|
|
103
|
+
} catch (error) {
|
|
104
|
+
if (valid) await Promise.reject(error);
|
|
105
|
+
}
|
|
106
|
+
if (!valid) throw new OfficeError("invalid-opc", "Invalid presentation graph.", "validate-intent");
|
|
107
|
+
for await (const part of archive.parts()) {
|
|
108
|
+
const key = await values.store(folded(literal(part))), value = await values.store(literal(part));
|
|
109
|
+
await values.insert("parts", key, value);
|
|
110
|
+
}
|
|
111
|
+
const main = await openRetainedXmlDocument(archive.read(index.records.main), { ...context, workingStorage: working });
|
|
112
|
+
let dialect = dialects[0], failed = false;
|
|
113
|
+
try {
|
|
114
|
+
for (const candidate of dialects) if (await equal(main.namespace(main.root), literal(candidate.p))) dialect = candidate;
|
|
115
|
+
} catch (error) {
|
|
116
|
+
failed = true;
|
|
117
|
+
throw error;
|
|
118
|
+
} finally {
|
|
119
|
+
try {
|
|
120
|
+
await main.close();
|
|
121
|
+
} catch (error) {
|
|
122
|
+
if (!failed) await Promise.reject(error);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
let token;
|
|
126
|
+
if (query.selection?.token) {
|
|
127
|
+
if (Object.keys(query.selection).some((key) => key !== "token")) throw new SelectionError("invalid-selection");
|
|
128
|
+
token = decodeSelectionToken(query.selection.token);
|
|
129
|
+
if (token.fingerprint !== fingerprint) throw new SelectionError("stale-selection");
|
|
130
|
+
if (token.scope !== "slides" && token.scope !== "presentation" || query.scope !== void 0 && query.scope !== token.scope) throw new SelectionError("invalid-selection");
|
|
131
|
+
}
|
|
132
|
+
async function* owners2() {
|
|
133
|
+
if ((token?.scope ?? query.scope) === "presentation") {
|
|
134
|
+
yield { part: index.records.main, slide: null };
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
const selected = token ? void 0 : query.selection;
|
|
138
|
+
for await (const record of selected ? index.records.select({ kind: "slide", ...selected }) : index.records.records("slide")) {
|
|
139
|
+
if (record.kind !== "slide") throw new SelectionError("invalid-selection");
|
|
140
|
+
yield { part: record.part, slide: record.position };
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
for await (const ignoredOwner of owners2()) check();
|
|
144
|
+
for await (const owner of owners2()) {
|
|
145
|
+
const document = await openRetainedXmlDocument(archive.read(owner.part), { ...context, workingStorage: working });
|
|
146
|
+
let failed2 = false, reference;
|
|
147
|
+
try {
|
|
148
|
+
const base = owner.part === index.records.main ? document.root : await child2(document, document.root, "cSld");
|
|
149
|
+
if (!base) invalid2("Tag owner lacks common slide data.");
|
|
150
|
+
const list = await child2(document, base, "custDataLst"), tags2 = list ? await child2(document, list, "tags") : void 0;
|
|
151
|
+
if (tags2) {
|
|
152
|
+
const id = await attribute(document, tags2, "id", dialect.r);
|
|
153
|
+
let count = 0;
|
|
154
|
+
if (id) {
|
|
155
|
+
for await (const edge of index.graph.outgoing(owner.part)) if (edge.owner === owner.part && !edge.external && await equal(edge.type(), literal(`${dialect.r}/tags`)) && await equal(edge.id(), document.text(id))) {
|
|
156
|
+
count++;
|
|
157
|
+
if (edge.targetPart) reference = await values.store(edge.targetPart());
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
if (count !== 1 || !reference) invalid2("Invalid tag association.");
|
|
161
|
+
}
|
|
162
|
+
} catch (error) {
|
|
163
|
+
failed2 = true;
|
|
164
|
+
throw error;
|
|
165
|
+
} finally {
|
|
166
|
+
try {
|
|
167
|
+
await document.close();
|
|
168
|
+
} catch (error) {
|
|
169
|
+
if (!failed2) await Promise.reject(error);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
if (!reference) continue;
|
|
173
|
+
const original = await values.find("parts", () => folded(values.read(reference)));
|
|
174
|
+
if (!original) throw new OfficeError("missing-binding", "Package member is absent.", "index");
|
|
175
|
+
const part = await bounded(reference), tags = await openRetainedXmlDocument(archive.read(await bounded(original)), { ...context, workingStorage: working });
|
|
176
|
+
let failedTags = false;
|
|
177
|
+
try {
|
|
178
|
+
if (!await is(tags, tags.root, "tagLst", literal(dialect.p))) invalid2("Invalid tag list.");
|
|
179
|
+
let childIndex = 0;
|
|
180
|
+
for await (const node of tags.children(tags.root)) {
|
|
181
|
+
if (node.kind !== "element") continue;
|
|
182
|
+
const position = childIndex++;
|
|
183
|
+
if (!await is(tags, node, "tag", literal(dialect.p))) continue;
|
|
184
|
+
const name = await attribute(tags, node, "name"), value = await attribute(tags, node, "val");
|
|
185
|
+
if (!name || !value) invalid2("Tag requires name and value attributes.");
|
|
186
|
+
const location = { fingerprint, scope: owner.slide === null ? "presentation" : "slides", owner: owner.part, objectId: `tag:${part}:${position}`, coordinateSystem: "identity" };
|
|
187
|
+
const metadata = await values.store(literal(JSON.stringify({ part, owner: owner.part, slide: owner.slide, selector: JSON.stringify(location), location })));
|
|
188
|
+
const key = await values.store(tags.text(name)), text = await values.store(tags.text(value));
|
|
189
|
+
const pointer = pages.allocate(7 /* Count */ * 8);
|
|
190
|
+
await write(pointer, [0, metadata.start, metadata.length, key.start, key.length, text.start, text.length]);
|
|
191
|
+
if (tail) await write(tail, [pointer]);
|
|
192
|
+
else head = pointer;
|
|
193
|
+
tail = pointer;
|
|
194
|
+
}
|
|
195
|
+
} catch (error) {
|
|
196
|
+
failedTags = true;
|
|
197
|
+
throw error;
|
|
198
|
+
} finally {
|
|
199
|
+
try {
|
|
200
|
+
await tags.close();
|
|
201
|
+
} catch (error) {
|
|
202
|
+
if (!failedTags) await Promise.reject(error);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
await index.close();
|
|
207
|
+
return Object.freeze({ close, async *records() {
|
|
208
|
+
check();
|
|
209
|
+
for (let pointer = head; pointer; ) {
|
|
210
|
+
const data = await row(pointer);
|
|
211
|
+
pointer = data[0 /* Next */];
|
|
212
|
+
const metadata = JSON.parse(await bounded(range(data, 1 /* Metadata */)));
|
|
213
|
+
if (token && metadata.selector !== query.selection.token) continue;
|
|
214
|
+
yield { name: () => values.read(range(data, 3 /* Name */)), value: () => values.read(range(data, 5 /* Value */)), ...metadata };
|
|
215
|
+
}
|
|
216
|
+
check();
|
|
217
|
+
} });
|
|
218
|
+
} catch (error) {
|
|
219
|
+
await close().catch(() => {
|
|
220
|
+
});
|
|
221
|
+
throw error instanceof OfficeError ? error : new OfficeError(signal.aborted ? "cancelled" : "io-failure", "Tag storage operation failed.", "index");
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
async function stageRetainedTags(archive, fingerprint, query, settings, output) {
|
|
225
|
+
const format = { ...output };
|
|
226
|
+
if (!["tags.list", "tags.get"].includes(format.operation)) throw new OfficeError("invalid-value", "Invalid tag read operation.", "usage");
|
|
227
|
+
const tags = await openRetainedTags(archive, fingerprint, query, settings);
|
|
228
|
+
let staged;
|
|
229
|
+
try {
|
|
230
|
+
if (format.operation === "tags.get") {
|
|
231
|
+
let count = 0;
|
|
232
|
+
for await (const ignoredRecord of tags.records()) count++;
|
|
233
|
+
if (count !== 1) throw new SelectionError(count ? "ambiguous-selection" : "missing-selection");
|
|
234
|
+
}
|
|
235
|
+
async function* locations() {
|
|
236
|
+
for await (const tag of tags.records()) yield tag.location;
|
|
237
|
+
}
|
|
238
|
+
async function* render() {
|
|
239
|
+
if (format.json) {
|
|
240
|
+
yield* streamJson({ version: 1, operation: format.operation, ok: true, data: { tags: tags.records() }, affected: 0, warnings: [], errors: [], locations: locations() });
|
|
241
|
+
yield* literal("\n");
|
|
242
|
+
} else for await (const tag of tags.records()) {
|
|
243
|
+
yield* streamJson(tag.name);
|
|
244
|
+
yield* literal(": ");
|
|
245
|
+
yield* streamJson(tag.value);
|
|
246
|
+
yield* literal("\n");
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
staged = await stageRetainedOutput(render(), settings, format.maxOutputBytes);
|
|
250
|
+
await tags.close();
|
|
251
|
+
return staged;
|
|
252
|
+
} catch (error) {
|
|
253
|
+
await Promise.allSettled([tags.close(), staged?.close()]);
|
|
254
|
+
throw error;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
// packages/safe-bash-presentation-engine/src/tags.ts
|
|
259
|
+
var relns = "http://schemas.openxmlformats.org/package/2006/relationships";
|
|
260
|
+
function validateTagOptions(options, action) {
|
|
261
|
+
if (!options || ![Object.prototype, null].includes(Object.getPrototypeOf(options)) || Object.keys(options).some((key) => !["scope", "selection", "name", "value", "allowEmpty"].includes(key)) || options.scope !== void 0 && !["presentation", "slides"].includes(options.scope) || options.allowEmpty !== void 0 && typeof options.allowEmpty !== "boolean") invalid("Invalid tag options.");
|
|
262
|
+
if (options.scope === "presentation" && options.selection && Object.keys(options.selection).some((key) => key !== "all" && key !== "token")) invalid("Presentation tags do not accept slide selectors.");
|
|
263
|
+
if (action === "add" && (options.name === void 0 || options.value === void 0)) invalid("New tags require name and value.");
|
|
264
|
+
if (action === "set" && options.name === void 0 && options.value === void 0) invalid("A tag edit requires name or value.");
|
|
265
|
+
for (const value of [options.name, options.value]) {
|
|
266
|
+
if (value === void 0) continue;
|
|
267
|
+
if (typeof value !== "string") invalid("Tag fields require strings.");
|
|
268
|
+
for (const c of value) {
|
|
269
|
+
const n = c.codePointAt(0);
|
|
270
|
+
if (n < 32 && ![9, 10, 13].includes(n) || n >= 55296 && n <= 57343 || n === 65534 || n === 65535) invalid("Tag fields require XML characters.");
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
if (options.name === "") invalid("Tag names cannot be empty.");
|
|
274
|
+
if (!action && (options.name !== void 0 || options.value !== void 0 || options.allowEmpty !== void 0)) invalid("Tag reads accept selection and scope only.");
|
|
275
|
+
if (action === "remove" && (options.name !== void 0 || options.value !== void 0)) invalid("Tag removal does not accept edit fields.");
|
|
276
|
+
}
|
|
277
|
+
function owners(s, options) {
|
|
278
|
+
if (options.scope === "presentation") return [{ part: s.main, slide: null }];
|
|
279
|
+
const selection = options.selection;
|
|
280
|
+
return (selection ? s.index.select({ kind: "slide", ...selection }) : s.index.slides).map((record) => {
|
|
281
|
+
if (record.kind !== "slide") throw new SelectionError("invalid-selection");
|
|
282
|
+
return { part: record.part, slide: record.position };
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
function association(s, owner) {
|
|
286
|
+
const doc = s.doc(owner);
|
|
287
|
+
const base = owner === s.main ? doc.root : child(doc.root, "cSld");
|
|
288
|
+
if (!base) invalid("Tag owner lacks common slide data.");
|
|
289
|
+
const list = child(base, "custDataLst");
|
|
290
|
+
const tags = list ? child(list, "tags") : void 0;
|
|
291
|
+
if (!tags) return void 0;
|
|
292
|
+
const id = tags.attributes.find((a) => a.name.namespace === s.r && a.name.localName === "id")?.value;
|
|
293
|
+
const edges = s.index.inventory.relationships.filter((e) => e.owner === owner && e.id === id && e.type === `${s.r}/tags` && !e.external);
|
|
294
|
+
if (edges.length !== 1 || !edges[0].targetPart) invalid("Invalid tag association.");
|
|
295
|
+
return edges[0].targetPart;
|
|
296
|
+
}
|
|
297
|
+
function records(s, options) {
|
|
298
|
+
let token;
|
|
299
|
+
if (options.selection?.token) {
|
|
300
|
+
if (Object.keys(options.selection).some((key) => key !== "token")) throw new SelectionError("invalid-selection");
|
|
301
|
+
token = decodeSelectionToken(options.selection.token);
|
|
302
|
+
if (token.fingerprint !== s.index.fingerprint) throw new SelectionError("stale-selection");
|
|
303
|
+
if (token.scope !== "slides" && token.scope !== "presentation") throw new SelectionError("invalid-selection");
|
|
304
|
+
if (options.scope !== void 0 && options.scope !== token.scope) throw new SelectionError("invalid-selection");
|
|
305
|
+
}
|
|
306
|
+
const selected = owners(s, token ? { scope: token.scope } : options);
|
|
307
|
+
const result = selected.flatMap((owner) => {
|
|
308
|
+
const part = association(s, owner.part);
|
|
309
|
+
if (!part) return [];
|
|
310
|
+
const doc = s.doc(part);
|
|
311
|
+
if (doc.root.name.namespace !== s.p || doc.root.name.localName !== "tagLst") invalid("Invalid tag list.");
|
|
312
|
+
return doc.root.children.flatMap((node, index) => {
|
|
313
|
+
if (node.name.namespace !== s.p || node.name.localName !== "tag") return [];
|
|
314
|
+
const name = attr(node, "name"), value = attr(node, "val");
|
|
315
|
+
if (name === void 0 || value === void 0) invalid("Tag requires name and value attributes.");
|
|
316
|
+
const location = { fingerprint: s.index.fingerprint, scope: owner.slide === null ? "presentation" : "slides", owner: owner.part, objectId: `tag:${part}:${index}`, coordinateSystem: "identity" };
|
|
317
|
+
return [{ name, value, part, owner: owner.part, slide: owner.slide, selector: JSON.stringify(location), location }];
|
|
318
|
+
});
|
|
319
|
+
});
|
|
320
|
+
return token ? result.filter((r) => r.selector === options.selection.token) : result;
|
|
321
|
+
}
|
|
322
|
+
async function readTags(input, options, context) {
|
|
323
|
+
validateTagOptions(options);
|
|
324
|
+
return records(await loadShared(input, context, false), options);
|
|
325
|
+
}
|
|
326
|
+
function createAssociation(s, owner, context) {
|
|
327
|
+
let n = 1;
|
|
328
|
+
while (s.reader.has(`/ppt/tags/tag${n}.xml`) || s.changes.has(`/ppt/tags/tag${n}.xml`)) n++;
|
|
329
|
+
const part = `/ppt/tags/tag${n}.xml`;
|
|
330
|
+
s.save(part, parseXmlPart(new TextEncoder().encode(`<p:tagLst xmlns:p="${s.p}"/>`), context.xmlLimits));
|
|
331
|
+
const types = s.doc("/[Content_Types].xml");
|
|
332
|
+
s.save("/[Content_Types].xml", types.spliceChildren(types.root, types.root.children.length, 0, [`<Override xmlns="${types.root.name.namespace}" PartName="${part}" ContentType="application/vnd.openxmlformats-officedocument.presentationml.tags+xml"/>`]));
|
|
333
|
+
const relName = relPart(owner);
|
|
334
|
+
const rels = s.reader.has(relName) ? s.doc(relName) : parseXmlPart(new TextEncoder().encode(`<Relationships xmlns="${relns}"/>`), context.xmlLimits);
|
|
335
|
+
const id = nextRel(rels);
|
|
336
|
+
s.save(relName, rels.spliceChildren(rels.root, rels.root.children.length, 0, [`<Relationship xmlns="${relns}" Id="${id}" Type="${s.r}/tags" Target="${escape(relativePartReference(part, owner.slice(0, owner.lastIndexOf("/"))))}"/>`]));
|
|
337
|
+
let doc = s.doc(owner);
|
|
338
|
+
let base = owner === s.main ? doc.root : child(doc.root, "cSld");
|
|
339
|
+
let list = child(base, "custDataLst");
|
|
340
|
+
if (!list) {
|
|
341
|
+
const order = owner === s.main ? ["sldMasterIdLst", "notesMasterIdLst", "handoutMasterIdLst", "sldIdLst", "sldSz", "notesSz", "smartTags", "embeddedFontLst", "custShowLst", "photoAlbum", "custDataLst", "kinsoku", "defaultTextStyle", "modifyVerifier", "extLst"] : ["bg", "spTree", "custDataLst", "controls", "extLst"];
|
|
342
|
+
doc = doc.merge(base, { children: { sequence: order.map((localName) => ({ namespace: s.p, localName })), upsert: [{ name: { namespace: s.p, localName: "custDataLst" }, merge: {} }] } });
|
|
343
|
+
base = owner === s.main ? doc.root : child(doc.root, "cSld");
|
|
344
|
+
list = child(base, "custDataLst");
|
|
345
|
+
}
|
|
346
|
+
s.save(owner, doc.spliceChildren(list, list.children.length, 0, [`<p:tags xmlns:p="${s.p}" xmlns:r="${s.r}" r:id="${id}"/>`]));
|
|
347
|
+
return part;
|
|
348
|
+
}
|
|
349
|
+
async function mutateTags(input, action, options, context) {
|
|
350
|
+
if (!["add", "set", "remove"].includes(action)) invalid("Invalid tag action.");
|
|
351
|
+
validateTagOptions(options, action);
|
|
352
|
+
if ((options.name?.length ?? 0) + (options.value?.length ?? 0) > context.xmlLimits.maxBytes) throw new OfficeError("resource-limit", "Tag exceeds XML limits.", "usage");
|
|
353
|
+
if (!options.selection && options.scope !== "presentation") throw new SelectionError("missing-selection");
|
|
354
|
+
const s = await loadShared(input, context);
|
|
355
|
+
const existing = records(s, options);
|
|
356
|
+
const locations = [];
|
|
357
|
+
if (action === "add") {
|
|
358
|
+
if (options.selection?.token) throw new SelectionError("invalid-selection");
|
|
359
|
+
const selected = owners(s, options);
|
|
360
|
+
if (!selected.length && !options.allowEmpty) throw new SelectionError("missing-selection");
|
|
361
|
+
for (const owner of selected) {
|
|
362
|
+
if (existing.some((r) => r.owner === owner.part && r.name === options.name)) invalid("Duplicate tag name.");
|
|
363
|
+
const part = association(s, owner.part) ?? createAssociation(s, owner.part, context);
|
|
364
|
+
if (s.index.inventory.relationships.filter((e) => e.targetPart === part).length > 1) throw new OfficeError("unsupported-edit", "Shared tag lists cannot be edited.", "validate-intent");
|
|
365
|
+
const doc = s.doc(part);
|
|
366
|
+
const location = { fingerprint: s.index.fingerprint, scope: owner.slide === null ? "presentation" : "slides", owner: owner.part, objectId: `tag:${part}:${doc.root.children.length}`, coordinateSystem: "identity" };
|
|
367
|
+
s.save(part, doc.spliceChildren(doc.root, doc.root.children.length, 0, [`<p:tag xmlns:p="${s.p}" name="${escape(options.name)}" val="${escape(options.value)}"/>`]));
|
|
368
|
+
locations.push(location);
|
|
369
|
+
}
|
|
370
|
+
} else {
|
|
371
|
+
if (!existing.length && !options.allowEmpty) throw new SelectionError("missing-selection");
|
|
372
|
+
if (existing.length > 1 && !options.selection?.all) throw new SelectionError("ambiguous-selection");
|
|
373
|
+
if (options.name !== void 0) {
|
|
374
|
+
const all = records(s, { scope: existing[0]?.location.scope });
|
|
375
|
+
for (const record of existing) if (all.some((r) => r.owner === record.owner && r.name === options.name && r.selector !== record.selector)) invalid("Duplicate tag name.");
|
|
376
|
+
if (existing.some((r, i) => existing.slice(0, i).some((v) => v.owner === r.owner))) invalid("Duplicate tag name.");
|
|
377
|
+
}
|
|
378
|
+
for (const record of [...existing].reverse()) {
|
|
379
|
+
if (s.index.inventory.relationships.filter((e) => e.targetPart === record.part).length > 1) throw new OfficeError("unsupported-edit", "Shared tag lists cannot be edited.", "validate-intent");
|
|
380
|
+
const doc = s.doc(record.part);
|
|
381
|
+
const index = Number(record.location.objectId.slice(record.location.objectId.lastIndexOf(":") + 1));
|
|
382
|
+
const node = doc.root.children[index];
|
|
383
|
+
if (action === "remove" && (node.children.length || node.attributes.some((a) => a.name.namespace !== "" || !["name", "val"].includes(a.name.localName)))) throw new OfficeError("unsupported-edit", "Decorated tags are preserved on removal.", "validate-intent");
|
|
384
|
+
s.save(record.part, action === "remove" ? doc.spliceChildren(doc.root, index, 1, []) : doc.merge(doc.root.children[index], { attributes: [...options.name === void 0 ? [] : [{ namespace: "", localName: "name", value: options.name }], ...options.value === void 0 ? [] : [{ namespace: "", localName: "val", value: options.value }]] }));
|
|
385
|
+
locations.push(record.location);
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
const result = await s.finish(s.main, []);
|
|
389
|
+
return { bytes: result.bytes, affected: locations.length, locations };
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
export {
|
|
393
|
+
openRetainedTags,
|
|
394
|
+
stageRetainedTags,
|
|
395
|
+
validateTagOptions,
|
|
396
|
+
readTags,
|
|
397
|
+
mutateTags
|
|
398
|
+
};
|
package/dist/safe-bash/command-chunks/{command-engine-GHE6QUHU.js → command-engine-2QXVRRH3.js}
RENAMED
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
import "./chunk-65DS4IOB.js";
|
|
13
13
|
|
|
14
14
|
// packages/safe-bash-command-pptx/src/command-engine.ts
|
|
15
|
+
import { stageRetainedTags } from "../../safe-bash-presentation-engine/tags.js";
|
|
15
16
|
import { stageRetainedProperties } from "../../safe-bash-presentation-engine/properties.js";
|
|
16
17
|
import { stageRetainedNotes } from "../../safe-bash-presentation-engine/notes.js";
|
|
17
18
|
|
|
@@ -12113,8 +12114,8 @@ async function executeRequest(request, options2, owned) {
|
|
|
12113
12114
|
publication = { inputPath: args.input, outputPath: destination, bytes: staged.bytes(), originalBytes: input, inPlace: args.inPlace ?? false, force: args.force ?? false, dryRun };
|
|
12114
12115
|
}
|
|
12115
12116
|
result = success(operation2, null);
|
|
12116
|
-
} else if ((args.operation === "inspect" || args.operation === "text.get" || args.operation === "fields.list" || args.operation === "fields.get" || args.operation === "text.frames.list" || args.operation === "text.frames.get" || args.operation === "notes.list" || args.operation === "notes.get" || args.operation === "properties.list" || args.operation === "properties.get" || args.operation === "xml.get") && request.streaming) {
|
|
12117
|
-
if (args.token && args.operation !== "notes.list" && args.operation !== "notes.get") decodeSelectionToken2(args.token);
|
|
12117
|
+
} else if ((args.operation === "inspect" || args.operation === "text.get" || args.operation === "fields.list" || args.operation === "fields.get" || args.operation === "text.frames.list" || args.operation === "text.frames.get" || args.operation === "notes.list" || args.operation === "notes.get" || args.operation === "properties.list" || args.operation === "properties.get" || args.operation === "tags.list" || args.operation === "tags.get" || args.operation === "xml.get") && request.streaming) {
|
|
12118
|
+
if (args.token && args.operation !== "notes.list" && args.operation !== "notes.get" && args.operation !== "tags.list" && args.operation !== "tags.get") decodeSelectionToken2(args.token);
|
|
12118
12119
|
const input = await request.streaming.openInput(args.input, Math.min(options2.context.limits.maxBytes, options2.context.archiveLimits.maxArchiveBytes));
|
|
12119
12120
|
const hash = sha2564.create();
|
|
12120
12121
|
for await (const bytes of input.stream()) {
|
|
@@ -12126,8 +12127,11 @@ async function executeRequest(request, options2, owned) {
|
|
|
12126
12127
|
const archive = await openPackageArchive(input, context);
|
|
12127
12128
|
let failed = false;
|
|
12128
12129
|
try {
|
|
12129
|
-
const scope = args.operation === "notes.list" || args.operation === "notes.get" ? void 0 : args.token ? decodeSelectionToken2(args.token).scope : args.scope;
|
|
12130
|
-
stagedOutput = args.operation === "
|
|
12130
|
+
const scope = args.operation === "notes.list" || args.operation === "notes.get" || args.operation === "tags.list" || args.operation === "tags.get" ? void 0 : args.token ? decodeSelectionToken2(args.token).scope : args.scope;
|
|
12131
|
+
stagedOutput = args.operation === "tags.list" || args.operation === "tags.get" ? await stageRetainedTags(archive, fingerprint, {
|
|
12132
|
+
...args.scope === void 0 ? {} : { scope: args.scope },
|
|
12133
|
+
...args.token ? { selection: { token: args.token } } : args.slide === void 0 ? args.all ? { selection: { all: true } } : {} : { selection: { kind: "slide", position: { coordinateSystem: "one-based", value: args.slide }, ...args.all ? { all: true } : {} } }
|
|
12134
|
+
}, context, { operation: args.operation, json: args.json, maxOutputBytes: options2.maxOutputBytes }) : args.operation === "properties.list" || args.operation === "properties.get" ? await stageRetainedProperties(archive, fingerprint, args.metadataName === void 0 ? {} : { name: args.metadataName }, context, { operation: args.operation, json: args.json, maxOutputBytes: options2.maxOutputBytes }) : args.operation === "notes.list" || args.operation === "notes.get" ? await stageRetainedNotes(archive, fingerprint, { selection: {
|
|
12131
12135
|
kind: "slide",
|
|
12132
12136
|
...args.token ? { token: args.token } : {},
|
|
12133
12137
|
...args.slide === void 0 ? {} : { position: { coordinateSystem: "one-based", value: args.slide } },
|