@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
|
@@ -15,19 +15,197 @@ import {
|
|
|
15
15
|
sideBySide
|
|
16
16
|
} from "./chunk-VXIC7SS3.js";
|
|
17
17
|
|
|
18
|
+
// packages/safe-bash-command-diff/src/stored-directory.ts
|
|
19
|
+
import { PagedStorage, PagedStorageCache } from "@poe-platform/safe-fs/storage";
|
|
20
|
+
import { closeDocumentResources } from "../../safe-bash-diff-engine/document.js";
|
|
21
|
+
import { host, ToolError } from "../../safe-bash-diff-engine/shared.js";
|
|
22
|
+
import { pathOf } from "../../safe-bash-io-engine/internal.js";
|
|
23
|
+
import { FsError } from "../../safe-bash-contracts/index.js";
|
|
24
|
+
var Rows = class {
|
|
25
|
+
constructor(budget, cache) {
|
|
26
|
+
this.budget = budget;
|
|
27
|
+
this.data = new PagedStorage(budget.context, 16, cache);
|
|
28
|
+
this.index = new PagedStorage(budget.context, 16, cache);
|
|
29
|
+
}
|
|
30
|
+
budget;
|
|
31
|
+
data;
|
|
32
|
+
index;
|
|
33
|
+
length = 0;
|
|
34
|
+
base = 8;
|
|
35
|
+
async append(row) {
|
|
36
|
+
const text = JSON.stringify(row), start = this.data.allocate(0);
|
|
37
|
+
for (let offset = 0; offset < text.length; ) {
|
|
38
|
+
let end = Math.min(text.length, offset + 4096);
|
|
39
|
+
const last = text.charCodeAt(end - 1);
|
|
40
|
+
if (last >= 55296 && last <= 56319 && end < text.length) end--;
|
|
41
|
+
await this.data.append(new TextEncoder().encode(text.slice(offset, end)));
|
|
42
|
+
offset = end;
|
|
43
|
+
}
|
|
44
|
+
const cell = new Uint8Array(24), view = new DataView(cell.buffer);
|
|
45
|
+
view.setFloat64(0, start, true);
|
|
46
|
+
view.setFloat64(8, this.data.allocate(0) - start, true);
|
|
47
|
+
await this.index.append(cell);
|
|
48
|
+
this.length++;
|
|
49
|
+
}
|
|
50
|
+
async read(position) {
|
|
51
|
+
this.budget.step();
|
|
52
|
+
const pause = this.budget.checkpoint();
|
|
53
|
+
if (pause) await pause;
|
|
54
|
+
const cell = await this.index.read(this.base + position * 24, 16), view = new DataView(cell.buffer, cell.byteOffset, cell.byteLength);
|
|
55
|
+
const start = view.getFloat64(0, true), end = start + view.getFloat64(8, true), decoder = new TextDecoder();
|
|
56
|
+
let text = "";
|
|
57
|
+
for (let offset = start; offset < end; offset += 16384) text += decoder.decode(await this.data.read(offset, Math.min(16384, end - offset)), { stream: true });
|
|
58
|
+
return JSON.parse(text + decoder.decode());
|
|
59
|
+
}
|
|
60
|
+
async mark(position) {
|
|
61
|
+
await this.index.write(this.base + position * 24 + 16, new Uint8Array([1]));
|
|
62
|
+
}
|
|
63
|
+
async marked(position) {
|
|
64
|
+
return (await this.index.read(this.base + position * 24 + 16, 1))[0] === 1;
|
|
65
|
+
}
|
|
66
|
+
async sort(compare) {
|
|
67
|
+
let target = this.index.allocate(this.length * 24);
|
|
68
|
+
for (let width = 1; width < this.length; width *= 2) {
|
|
69
|
+
for (let start = 0; start < this.length; start += width * 2) {
|
|
70
|
+
const middle = Math.min(start + width, this.length), end = Math.min(start + width * 2, this.length);
|
|
71
|
+
let left = start, right = middle, a = left < middle ? await this.read(left) : void 0, b = right < end ? await this.read(right) : void 0;
|
|
72
|
+
for (let position = start; position < end; position++) {
|
|
73
|
+
this.budget.step();
|
|
74
|
+
const pause = this.budget.checkpoint();
|
|
75
|
+
if (pause) await pause;
|
|
76
|
+
const takeLeft = b === void 0 || a !== void 0 && compare(a, b) <= 0;
|
|
77
|
+
const source = takeLeft ? left : right;
|
|
78
|
+
await this.index.write(target + position * 24, await this.index.read(this.base + source * 24, 24));
|
|
79
|
+
if (takeLeft) a = ++left < middle ? await this.read(left) : void 0;
|
|
80
|
+
else b = ++right < end ? await this.read(right) : void 0;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
const previous = this.base;
|
|
84
|
+
this.base = target;
|
|
85
|
+
target = previous;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
close() {
|
|
89
|
+
return closeDocumentResources([this.data, this.index]);
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
var compareText = (a, b) => a < b ? -1 : a > b ? 1 : 0;
|
|
93
|
+
async function* directoryMatches(left, right, budget, ignoreCase, maxEntries, excluded, startingFile) {
|
|
94
|
+
const cache = new PagedStorageCache(16), matches = new Rows(budget, cache);
|
|
95
|
+
let entries = new Rows(budget, cache);
|
|
96
|
+
const context = budget.context, key = (name) => ignoreCase ? name.replace(/[A-Z]/gu, (letter) => letter.toLowerCase()) : name;
|
|
97
|
+
try {
|
|
98
|
+
const restart = /* @__PURE__ */ Symbol("prepare directory backing storage");
|
|
99
|
+
for (let prepared = false; ; prepared = true) {
|
|
100
|
+
let admittedBytes = 0;
|
|
101
|
+
try {
|
|
102
|
+
for (const [side, path] of [["left", left], ["right", right]]) {
|
|
103
|
+
if (path === void 0) continue;
|
|
104
|
+
const absolute = pathOf(context, path);
|
|
105
|
+
if (Number.isFinite(maxEntries) && (!Number.isSafeInteger(maxEntries) || maxEntries < 0))
|
|
106
|
+
throw new FsError("EINVAL", { syscall: "readdir", path: absolute, message: "directory entry limit must be a nonnegative safe integer or Infinity" });
|
|
107
|
+
const source = context.fs.iterateDirectory ? context.fs.iterateDirectory(absolute, { signal: context.signal }) : await host(context, () => context.fs.readdir(absolute, { signal: context.signal, ...Number.isFinite(maxEntries) ? { maxEntries } : {} }));
|
|
108
|
+
let count2 = 0;
|
|
109
|
+
const iterator = Array.isArray(source) ? source[Symbol.iterator]() : source[Symbol.asyncIterator]();
|
|
110
|
+
try {
|
|
111
|
+
for (; ; ) {
|
|
112
|
+
const item = await host(context, async () => iterator.next());
|
|
113
|
+
if (item.done) break;
|
|
114
|
+
const entry = item.value;
|
|
115
|
+
if (++count2 > maxEntries) throw new FsError("EFBIG", { syscall: "readdir", path: absolute, message: "directory entry limit exceeded" });
|
|
116
|
+
budget.step();
|
|
117
|
+
const pause = budget.checkpoint();
|
|
118
|
+
if (pause) await pause;
|
|
119
|
+
if (!entry.name || entry.name === "." || entry.name === ".." || /[/\\\0\r\n\t]/u.test(entry.name)) throw new ToolError("unsafe directory entry name");
|
|
120
|
+
if (!await excluded(entry.name)) {
|
|
121
|
+
admittedBytes += entry.name.length * 6 + 128;
|
|
122
|
+
if (!prepared && admittedBytes > 128 * 1024) throw restart;
|
|
123
|
+
await entries.append({ name: entry.name, side });
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
} finally {
|
|
127
|
+
await iterator.return?.();
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
break;
|
|
131
|
+
} catch (error) {
|
|
132
|
+
if (error !== restart) throw error;
|
|
133
|
+
await entries.close();
|
|
134
|
+
entries = new Rows(budget, cache);
|
|
135
|
+
await entries.data.prepare();
|
|
136
|
+
await entries.index.prepare();
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
await entries.sort((a, b) => compareText(key(a.name), key(b.name)) || compareText(a.name, b.name) || compareText(a.side, b.side));
|
|
140
|
+
let count = 0;
|
|
141
|
+
for (let begin = 0; begin < entries.length; ) {
|
|
142
|
+
const group = key((await entries.read(begin)).name);
|
|
143
|
+
let end = begin, leftCount = 0, rightCount = 0;
|
|
144
|
+
while (end < entries.length) {
|
|
145
|
+
const entry = await entries.read(end);
|
|
146
|
+
if (key(entry.name) !== group) break;
|
|
147
|
+
if (entry.side === "left") leftCount++;
|
|
148
|
+
else rightCount++;
|
|
149
|
+
end++;
|
|
150
|
+
}
|
|
151
|
+
count += Math.max(leftCount, rightCount);
|
|
152
|
+
if (count > maxEntries) throw new ToolError("file/entry limit exceeded");
|
|
153
|
+
if (startingFile === void 0 || group >= key(startingFile)) {
|
|
154
|
+
const next = async (position, side, unmatched = false) => {
|
|
155
|
+
while (position < end) {
|
|
156
|
+
const entry = await entries.read(position);
|
|
157
|
+
if (entry.side === side && (!unmatched || !await entries.marked(position))) return { position, name: entry.name };
|
|
158
|
+
position++;
|
|
159
|
+
}
|
|
160
|
+
return void 0;
|
|
161
|
+
};
|
|
162
|
+
let a = await next(begin, "left"), b = await next(begin, "right");
|
|
163
|
+
while (a && b) {
|
|
164
|
+
budget.step();
|
|
165
|
+
const pause = budget.checkpoint();
|
|
166
|
+
if (pause) await pause;
|
|
167
|
+
const order = compareText(a.name, b.name);
|
|
168
|
+
if (order === 0) {
|
|
169
|
+
await matches.append({ left: a.name, right: b.name });
|
|
170
|
+
await entries.mark(a.position);
|
|
171
|
+
await entries.mark(b.position);
|
|
172
|
+
}
|
|
173
|
+
if (order <= 0) a = await next(a.position + 1, "left");
|
|
174
|
+
if (order >= 0) b = await next(b.position + 1, "right");
|
|
175
|
+
}
|
|
176
|
+
a = await next(begin, "left", true);
|
|
177
|
+
b = await next(begin, "right", true);
|
|
178
|
+
while (a || b) {
|
|
179
|
+
await matches.append({ ...a ? { left: a.name } : {}, ...b ? { right: b.name } : {} });
|
|
180
|
+
if (a) a = await next(a.position + 1, "left", true);
|
|
181
|
+
if (b) b = await next(b.position + 1, "right", true);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
begin = end;
|
|
185
|
+
}
|
|
186
|
+
await matches.sort((a, b) => {
|
|
187
|
+
const first = a.left ?? a.right, second = b.left ?? b.right;
|
|
188
|
+
return compareText(key(first), key(second)) || Number(a.left === void 0 || a.right === void 0) - Number(b.left === void 0 || b.right === void 0) || compareText(first, second);
|
|
189
|
+
});
|
|
190
|
+
for (let index = matches.length - 1; index >= 0; index--) yield await matches.read(index);
|
|
191
|
+
} finally {
|
|
192
|
+
await closeDocumentResources([entries, matches]);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
18
196
|
// packages/safe-bash-command-diff/src/diff.ts
|
|
19
|
-
import { closeDocumentResources as
|
|
20
|
-
import { PagedStorage as
|
|
197
|
+
import { closeDocumentResources as closeDocumentResources4 } from "../../safe-bash-diff-engine/document.js";
|
|
198
|
+
import { PagedStorage as PagedStorage5 } from "@poe-platform/safe-fs/storage";
|
|
21
199
|
|
|
22
200
|
// packages/safe-bash-command-diff/src/indexed.ts
|
|
23
201
|
import { writeDiagnostic } from "../../safe-bash-contracts/escaping.js";
|
|
24
202
|
|
|
25
203
|
// packages/safe-bash-command-diff/src/indexed-output.ts
|
|
26
|
-
import { ToolError } from "../../safe-bash-diff-engine/shared.js";
|
|
204
|
+
import { ToolError as ToolError2 } from "../../safe-bash-diff-engine/shared.js";
|
|
27
205
|
import { encodeBytes as encodeBytes2 } from "../../safe-bash-io-engine/byte-encoding.js";
|
|
28
206
|
|
|
29
207
|
// packages/safe-bash-command-diff/src/indexed-normalization.ts
|
|
30
|
-
import { PagedStorage } from "@poe-platform/safe-fs/storage";
|
|
208
|
+
import { PagedStorage as PagedStorage2 } from "@poe-platform/safe-fs/storage";
|
|
31
209
|
import { readBytes } from "../../safe-bash-contracts/index.js";
|
|
32
210
|
import { decodeBytes, encodeBytes } from "../../safe-bash-io-engine/byte-encoding.js";
|
|
33
211
|
async function* stripTrailingCr(source, signal) {
|
|
@@ -88,7 +266,7 @@ async function* expandedSource(document, start, end, utf8) {
|
|
|
88
266
|
if (pending) yield encodeBytes(pending, utf8 ? "utf8" : "latin1");
|
|
89
267
|
}
|
|
90
268
|
async function* comparisonSource(document, options, utf8) {
|
|
91
|
-
const storage = new
|
|
269
|
+
const storage = new PagedStorage2(document.budget.context, 16);
|
|
92
270
|
document.budget.context.registerCleanup?.(() => storage.close());
|
|
93
271
|
const encoder2 = new TextEncoder();
|
|
94
272
|
let position = 0;
|
|
@@ -221,7 +399,7 @@ async function renderSideBySide(old, next, count, group, options, budget, append
|
|
|
221
399
|
};
|
|
222
400
|
const row = async (left, right, common) => {
|
|
223
401
|
if (common && left !== void 0 && right !== void 0 && options.suppressCommon) return;
|
|
224
|
-
if (options.width > budget.limits.maxOutputBytes) throw new
|
|
402
|
+
if (options.width > budget.limits.maxOutputBytes) throw new ToolError2("output byte limit exceeded");
|
|
225
403
|
const leftLf = await terminated(old, left), rightLf = await terminated(next, right);
|
|
226
404
|
const marker = common ? left === void 0 ? ")" : right === void 0 ? "(" : " " : left === void 0 ? ">" : right === void 0 ? "<" : !leftLf && rightLf ? "\\" : leftLf && !rightLf ? "/" : "|";
|
|
227
405
|
const colored = options.color && (marker === "<" || marker === ">");
|
|
@@ -278,14 +456,14 @@ async function renderSideBySide(old, next, count, group, options, budget, append
|
|
|
278
456
|
import { encodeBytes as encodeBytes3 } from "../../safe-bash-io-engine/byte-encoding.js";
|
|
279
457
|
|
|
280
458
|
// packages/safe-bash-command-diff/src/indexed-pattern.ts
|
|
281
|
-
import { IntegerTable, PagedStorage as
|
|
282
|
-
import { closeDocumentResources } from "../../safe-bash-diff-engine/document.js";
|
|
459
|
+
import { IntegerTable, PagedStorage as PagedStorage3, PagedStorageCache as PagedStorageCache2 } from "@poe-platform/safe-fs/storage";
|
|
460
|
+
import { closeDocumentResources as closeDocumentResources2 } from "../../safe-bash-diff-engine/document.js";
|
|
283
461
|
async function matchesPattern(pattern, document, start, end, utf8, budget) {
|
|
284
462
|
if (await pattern.supportsStreamTest(budget)) return pattern.testStream(documentText(document, start, end, utf8), budget);
|
|
285
|
-
const cache = new
|
|
286
|
-
const text = new
|
|
287
|
-
const records = new
|
|
288
|
-
const index = new
|
|
463
|
+
const cache = new PagedStorageCache2(16);
|
|
464
|
+
const text = new PagedStorage3(budget.context, 16, cache);
|
|
465
|
+
const records = new PagedStorage3(budget.context, 16, cache);
|
|
466
|
+
const index = new PagedStorage3(budget.context, 16, cache);
|
|
289
467
|
const hashes = new IntegerTable(index, 256);
|
|
290
468
|
let length = 0, cursor = 8, tail = 8;
|
|
291
469
|
const record = async (offset) => {
|
|
@@ -344,14 +522,14 @@ async function matchesPattern(pattern, document, start, end, utf8, budget) {
|
|
|
344
522
|
}
|
|
345
523
|
}, budget);
|
|
346
524
|
} finally {
|
|
347
|
-
await
|
|
525
|
+
await closeDocumentResources2([text, records, index]);
|
|
348
526
|
}
|
|
349
527
|
}
|
|
350
528
|
|
|
351
529
|
// packages/safe-bash-command-diff/src/indexed.ts
|
|
352
|
-
import { PagedStorage as
|
|
353
|
-
import { IndexedDocument, closeDocumentResources as
|
|
354
|
-
import { ToolError as
|
|
530
|
+
import { PagedStorage as PagedStorage4 } from "@poe-platform/safe-fs/storage";
|
|
531
|
+
import { IndexedDocument, closeDocumentResources as closeDocumentResources3 } from "../../safe-bash-diff-engine/document.js";
|
|
532
|
+
import { ToolError as ToolError3 } from "../../safe-bash-diff-engine/shared.js";
|
|
355
533
|
var encoder = new TextEncoder();
|
|
356
534
|
async function buildGroups(old, next, matrix, groups, budget, admitLines = true) {
|
|
357
535
|
let prefix = 0, suffix = 0, count = 0;
|
|
@@ -361,7 +539,7 @@ async function buildGroups(old, next, matrix, groups, budget, admitLines = true)
|
|
|
361
539
|
while (suffix < Math.min(old.length, next.length) - prefix && await old.equal(old.length - suffix - 1, next, next.length - suffix - 1)) suffix++;
|
|
362
540
|
const oldCount = old.length - prefix - suffix, newCount = next.length - prefix - suffix;
|
|
363
541
|
const width = newCount + 1, cells = (oldCount + 1) * width;
|
|
364
|
-
if (oldCount && newCount && (cells > budget.limits.maxMatrixCells || !Number.isSafeInteger(cells * 4))) throw new
|
|
542
|
+
if (oldCount && newCount && (cells > budget.limits.maxMatrixCells || !Number.isSafeInteger(cells * 4))) throw new ToolError3("diff matrix cell limit exceeded");
|
|
365
543
|
const base = oldCount && newCount ? matrix.allocate(cells * 4) : 0;
|
|
366
544
|
const get = async (row2, column2) => {
|
|
367
545
|
const bytes = await matrix.read(base + (row2 * width + column2) * 4, 4);
|
|
@@ -459,7 +637,7 @@ async function indexedDiff(budget, options, left, right, nested, append, sources
|
|
|
459
637
|
else await document.load(input);
|
|
460
638
|
};
|
|
461
639
|
const keys = [];
|
|
462
|
-
const matrix = new
|
|
640
|
+
const matrix = new PagedStorage4(budget.context, 8), groups = new PagedStorage4(budget.context, 16);
|
|
463
641
|
budget.context.registerCleanup?.(() => matrix.close());
|
|
464
642
|
budget.context.registerCleanup?.(() => groups.close());
|
|
465
643
|
const text = async (value, color) => {
|
|
@@ -733,7 +911,7 @@ async function indexedDiff(budget, options, left, right, nested, append, sources
|
|
|
733
911
|
}
|
|
734
912
|
return { different: true, trouble };
|
|
735
913
|
} finally {
|
|
736
|
-
await
|
|
914
|
+
await closeDocumentResources3([
|
|
737
915
|
...rawOld === stdin.document ? [] : [rawOld],
|
|
738
916
|
...rawNext === stdin.document ? [] : [rawNext],
|
|
739
917
|
...keys,
|
|
@@ -806,9 +984,9 @@ import { createPrCommand } from "../../safe-bash-command-pr/index.js";
|
|
|
806
984
|
import { basename, createCommandArguments, isFsError, writeBytes } from "../../safe-bash-contracts/index.js";
|
|
807
985
|
import { publicDiagnosticMessage } from "../../safe-bash-contracts/diagnostics.js";
|
|
808
986
|
import { writeDiagnostic as writeDiagnostic2 } from "../../safe-bash-contracts/escaping.js";
|
|
809
|
-
import { ToolError as
|
|
987
|
+
import { ToolError as ToolError4, definition, host as host2, inspect, sameIdentity } from "../../safe-bash-diff-engine/shared.js";
|
|
810
988
|
import { byteLength, decodeBytes as decodeBytes2, encodeBytes as encodeBytes4 } from "../../safe-bash-io-engine/byte-encoding.js";
|
|
811
|
-
import { pathOf } from "../../safe-bash-io-engine/internal.js";
|
|
989
|
+
import { pathOf as pathOf2 } from "../../safe-bash-io-engine/internal.js";
|
|
812
990
|
import { Pattern } from "../../safe-bash-regex-engine/text/regex.js";
|
|
813
991
|
async function comparisonLines(lines, options, budget) {
|
|
814
992
|
const whitespace = options.whitespace;
|
|
@@ -860,7 +1038,7 @@ async function edits(oldLines, newLines, oldKeys, newKeys, budget) {
|
|
|
860
1038
|
const oldCount = oldLines.length - prefix - suffix;
|
|
861
1039
|
const newCount = newLines.length - prefix - suffix;
|
|
862
1040
|
const cells = (oldCount + 1) * (newCount + 1);
|
|
863
|
-
if (oldCount && newCount && cells > budget.limits.maxMatrixCells) throw new
|
|
1041
|
+
if (oldCount && newCount && cells > budget.limits.maxMatrixCells) throw new ToolError4("diff matrix cell limit exceeded");
|
|
864
1042
|
const width = newCount + 1;
|
|
865
1043
|
const matrix = oldCount && newCount ? new Uint32Array(cells) : void 0;
|
|
866
1044
|
const ids = /* @__PURE__ */ new Map();
|
|
@@ -937,19 +1115,19 @@ async function exclusionPatterns(options, budget) {
|
|
|
937
1115
|
const c = budget.checkpoint();
|
|
938
1116
|
if (c) await c;
|
|
939
1117
|
}
|
|
940
|
-
if (exclusions.length >= budget.limits.maxExcludePatterns) throw new
|
|
1118
|
+
if (exclusions.length >= budget.limits.maxExcludePatterns) throw new ToolError4("exclusion pattern count limit exceeded");
|
|
941
1119
|
const remaining = budget.limits.maxExcludePatternBytes - patternBytes;
|
|
942
|
-
if (end - start > remaining) throw new
|
|
1120
|
+
if (end - start > remaining) throw new ToolError4("exclusion pattern byte limit exceeded");
|
|
943
1121
|
const sourcePattern = source.slice(start, end);
|
|
944
1122
|
const bytes = byteLength(sourcePattern);
|
|
945
|
-
if (bytes > remaining) throw new
|
|
1123
|
+
if (bytes > remaining) throw new ToolError4("exclusion pattern byte limit exceeded");
|
|
946
1124
|
patternBytes += bytes;
|
|
947
1125
|
exclusions.push(globPattern(sourcePattern, ignoreCase));
|
|
948
1126
|
};
|
|
949
1127
|
for (const { pattern, ignoreCase } of options.excludes) await append(pattern, ignoreCase);
|
|
950
1128
|
for (const { path, ignoreCase } of options.excludeFiles) {
|
|
951
1129
|
if (path !== "-") await inspect(budget, path, "follow");
|
|
952
|
-
const contents = await (path === "-" ? budget.read("-") : budget.readDiff(
|
|
1130
|
+
const contents = await (path === "-" ? budget.read("-") : budget.readDiff(pathOf2(budget.context, path)));
|
|
953
1131
|
let start = 0;
|
|
954
1132
|
while (start < contents.length) {
|
|
955
1133
|
const newline = contents.indexOf("\n", start);
|
|
@@ -973,13 +1151,13 @@ function childPath(directory, name) {
|
|
|
973
1151
|
return `${directory.slice(0, end)}/${name}`;
|
|
974
1152
|
}
|
|
975
1153
|
async function run(context, budget) {
|
|
976
|
-
const storage = new
|
|
1154
|
+
const storage = new PagedStorage5(context, 32);
|
|
977
1155
|
const stdin = {};
|
|
978
1156
|
context.registerCleanup?.(() => storage.close());
|
|
979
1157
|
try {
|
|
980
1158
|
return await runStored(context, budget, storage, stdin);
|
|
981
1159
|
} finally {
|
|
982
|
-
await
|
|
1160
|
+
await closeDocumentResources4([storage, ...stdin.document ? [stdin.document] : []]);
|
|
983
1161
|
}
|
|
984
1162
|
}
|
|
985
1163
|
async function runStored(context, budget, storage, stdinDocument) {
|
|
@@ -1025,15 +1203,15 @@ async function runStored(context, budget, storage, stdinDocument) {
|
|
|
1025
1203
|
const pair = pending.pop();
|
|
1026
1204
|
let left = pair.left;
|
|
1027
1205
|
let right = pair.right;
|
|
1028
|
-
const isStdin = (path) => path === "-" || !options.noDereference && (
|
|
1206
|
+
const isStdin = (path) => path === "-" || !options.noDereference && (pathOf2(context, path) === "/dev/stdin" || pathOf2(context, path) === "/dev/fd/0");
|
|
1029
1207
|
let leftStat = pair.leftEntry === false ? void 0 : isStdin(left) ? { type: "file" } : await inspectOperand(left);
|
|
1030
1208
|
let rightStat = pair.rightEntry === false ? void 0 : isStdin(right) ? { type: "file" } : await inspectOperand(right);
|
|
1031
1209
|
if (inspectionFailed) continue;
|
|
1032
1210
|
if (options.format === "ifdef" && (leftStat?.type === "directory" || rightStat?.type === "directory")) {
|
|
1033
|
-
throw new
|
|
1211
|
+
throw new ToolError4("-D option not supported with directories");
|
|
1034
1212
|
}
|
|
1035
1213
|
if (!pair.nested && leftStat && rightStat && leftStat.type === "directory" !== (rightStat.type === "directory")) {
|
|
1036
|
-
if (isStdin(left) || isStdin(right)) throw new
|
|
1214
|
+
if (isStdin(left) || isStdin(right)) throw new ToolError4("cannot compare stdin with a directory");
|
|
1037
1215
|
if (leftStat.type === "directory") {
|
|
1038
1216
|
left = childPath(left, basename(right));
|
|
1039
1217
|
leftStat = await inspectOperand(left);
|
|
@@ -1070,10 +1248,10 @@ async function runStored(context, budget, storage, stdinDocument) {
|
|
|
1070
1248
|
continue;
|
|
1071
1249
|
}
|
|
1072
1250
|
if (leftStat?.type === "symlink" || rightStat?.type === "symlink") {
|
|
1073
|
-
if (!context.fs.readlink) throw new
|
|
1251
|
+
if (!context.fs.readlink) throw new ToolError4("filesystem cannot read symbolic links");
|
|
1074
1252
|
const readlink = context.fs.readlink.bind(context.fs);
|
|
1075
|
-
const oldTarget = await
|
|
1076
|
-
const newTarget = await
|
|
1253
|
+
const oldTarget = await host2(context, () => readlink(pathOf2(context, left), { signal: context.signal }));
|
|
1254
|
+
const newTarget = await host2(context, () => readlink(pathOf2(context, right), { signal: context.signal }));
|
|
1077
1255
|
if (!budget.equal(oldTarget, newTarget)) {
|
|
1078
1256
|
await append(`Symbolic links ${left} and ${right} differ
|
|
1079
1257
|
`);
|
|
@@ -1088,8 +1266,8 @@ async function runStored(context, budget, storage, stdinDocument) {
|
|
|
1088
1266
|
`);
|
|
1089
1267
|
continue;
|
|
1090
1268
|
}
|
|
1091
|
-
const leftIdentity = leftStat?.type !== "directory" ? void 0 : sameIdentity(leftStat, leftStat) ? leftStat : await
|
|
1092
|
-
const rightIdentity = rightStat?.type !== "directory" ? void 0 : sameIdentity(rightStat, rightStat) ? rightStat : await
|
|
1269
|
+
const leftIdentity = leftStat?.type !== "directory" ? void 0 : sameIdentity(leftStat, leftStat) ? leftStat : await host2(context, () => context.fs.realpath(pathOf2(context, left), { signal: context.signal }));
|
|
1270
|
+
const rightIdentity = rightStat?.type !== "directory" ? void 0 : sameIdentity(rightStat, rightStat) ? rightStat : await host2(context, () => context.fs.realpath(pathOf2(context, right), { signal: context.signal }));
|
|
1093
1271
|
const isLoop = (identity, parents) => identity !== void 0 && parents.some((parent) => typeof identity === "string" ? parent === identity : typeof parent !== "string" && sameIdentity(identity, parent));
|
|
1094
1272
|
const cycle = isLoop(leftIdentity, pair.leftParents) ? left : isLoop(rightIdentity, pair.rightParents) ? right : void 0;
|
|
1095
1273
|
if (cycle !== void 0) {
|
|
@@ -1100,74 +1278,34 @@ async function runStored(context, budget, storage, stdinDocument) {
|
|
|
1100
1278
|
}
|
|
1101
1279
|
const leftParents = leftIdentity === void 0 ? pair.leftParents : [...pair.leftParents, leftIdentity];
|
|
1102
1280
|
const rightParents = rightIdentity === void 0 ? pair.rightParents : [...pair.rightParents, rightIdentity];
|
|
1103
|
-
const
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
names.set(folded, group);
|
|
1126
|
-
}
|
|
1127
|
-
const before = Math.max(group.left.length, group.right.length);
|
|
1128
|
-
group[side].push(entry.name);
|
|
1129
|
-
count += Math.max(group.left.length, group.right.length) - before;
|
|
1130
|
-
if (count > maxEntries) throw new ToolError3("file/entry limit exceeded");
|
|
1131
|
-
}
|
|
1132
|
-
}
|
|
1133
|
-
for (const name of [...names.keys()].sort().reverse()) {
|
|
1134
|
-
if (!pair.nested && options.startingFile !== void 0 && name < key(options.startingFile)) continue;
|
|
1135
|
-
const group = names.get(name);
|
|
1136
|
-
group.left.sort();
|
|
1137
|
-
group.right.sort();
|
|
1138
|
-
const rightNames = new Set(group.right);
|
|
1139
|
-
const matches = [];
|
|
1140
|
-
const unmatchedLeft = [];
|
|
1141
|
-
for (const leftName of group.left) {
|
|
1142
|
-
if (rightNames.delete(leftName)) matches.push({ left: leftName, right: leftName });
|
|
1143
|
-
else unmatchedLeft.push(leftName);
|
|
1144
|
-
}
|
|
1145
|
-
const unmatchedRight = [...rightNames];
|
|
1146
|
-
for (let index = 0; index < Math.max(unmatchedLeft.length, unmatchedRight.length); index++) {
|
|
1147
|
-
const leftName = unmatchedLeft[index], rightName = unmatchedRight[index];
|
|
1148
|
-
matches.push({ ...leftName === void 0 ? {} : { left: leftName }, ...rightName === void 0 ? {} : { right: rightName } });
|
|
1149
|
-
}
|
|
1150
|
-
matches.sort((first, second) => {
|
|
1151
|
-
const unmatched = Number(first.left === void 0 || first.right === void 0) - Number(second.left === void 0 || second.right === void 0);
|
|
1152
|
-
const firstName = first.left ?? first.right, secondName = second.left ?? second.right;
|
|
1153
|
-
return unmatched || (firstName < secondName ? -1 : firstName > secondName ? 1 : 0);
|
|
1281
|
+
const excluded = async (name) => {
|
|
1282
|
+
const byteName = exclusions.length ? decodeBytes2(encodeBytes4(name), "latin1") : name;
|
|
1283
|
+
for (const pattern of exclusions) if (await pattern.find(byteName, budget)) return true;
|
|
1284
|
+
return false;
|
|
1285
|
+
};
|
|
1286
|
+
for await (const match of directoryMatches(
|
|
1287
|
+
leftStat ? left : void 0,
|
|
1288
|
+
rightStat ? right : void 0,
|
|
1289
|
+
budget,
|
|
1290
|
+
options.ignoreFileNameCase,
|
|
1291
|
+
budget.remainingFiles - pending.length,
|
|
1292
|
+
excluded,
|
|
1293
|
+
pair.nested ? void 0 : options.startingFile
|
|
1294
|
+
)) {
|
|
1295
|
+
pending.push({
|
|
1296
|
+
left: childPath(left, match.left ?? match.right),
|
|
1297
|
+
right: childPath(right, match.right ?? match.left),
|
|
1298
|
+
nested: true,
|
|
1299
|
+
leftParents,
|
|
1300
|
+
rightParents,
|
|
1301
|
+
leftEntry: match.left !== void 0,
|
|
1302
|
+
rightEntry: match.right !== void 0
|
|
1154
1303
|
});
|
|
1155
|
-
for (const match of matches.reverse()) {
|
|
1156
|
-
pending.push({
|
|
1157
|
-
left: childPath(left, match.left ?? match.right),
|
|
1158
|
-
right: childPath(right, match.right ?? match.left),
|
|
1159
|
-
nested: true,
|
|
1160
|
-
leftParents,
|
|
1161
|
-
rightParents,
|
|
1162
|
-
leftEntry: match.left !== void 0,
|
|
1163
|
-
rightEntry: match.right !== void 0
|
|
1164
|
-
});
|
|
1165
|
-
}
|
|
1166
1304
|
}
|
|
1167
1305
|
continue;
|
|
1168
1306
|
}
|
|
1169
1307
|
if (options.brief && options.whitespace === "exact" && !options.ignoreCase && !options.ignoreTabs && !options.ignoreTrailing && !options.stripTrailingCr && !options.ignoreBlank && options.ignorePatterns.length === 0 && leftStat?.type === "file" && rightStat?.type === "file" && !isStdin(left) && !isStdin(right)) {
|
|
1170
|
-
const same2 = await compareBrief(budget,
|
|
1308
|
+
const same2 = await compareBrief(budget, pathOf2(context, left), pathOf2(context, right), options.text, options.format === "side" || options.format === "ifdef");
|
|
1171
1309
|
if (!same2) {
|
|
1172
1310
|
different = true;
|
|
1173
1311
|
await append(`Files ${options.labels[0] ?? left} and ${options.labels[1] ?? right} differ
|
|
@@ -1179,7 +1317,7 @@ async function runStored(context, budget, storage, stdinDocument) {
|
|
|
1179
1317
|
const canIndex = async (path, stat) => {
|
|
1180
1318
|
if (!stat || stat.type === "file") return true;
|
|
1181
1319
|
if (pair.nested || !streamType(stat.type) || !context.fs.readStream) return false;
|
|
1182
|
-
const capabilities = await
|
|
1320
|
+
const capabilities = await host2(context, async () => await context.fs.capabilitiesFor?.(pathOf2(context, path), { signal: context.signal }) ?? context.fs.capabilities);
|
|
1183
1321
|
return capabilities.streamingRead !== false;
|
|
1184
1322
|
};
|
|
1185
1323
|
let storedPatterns = true;
|
|
@@ -1191,8 +1329,8 @@ async function runStored(context, budget, storage, stdinDocument) {
|
|
|
1191
1329
|
}
|
|
1192
1330
|
if (storedPatterns && await canIndex(left, leftStat) && await canIndex(right, rightStat)) {
|
|
1193
1331
|
const result = await indexedDiff(budget, options, left, right, pair.nested, appendBytes, {
|
|
1194
|
-
left: !leftStat ? void 0 : isStdin(left) ? "-" : streamType(leftStat.type) ? { stream:
|
|
1195
|
-
right: !rightStat ? void 0 : isStdin(right) ? "-" : streamType(rightStat.type) ? { stream:
|
|
1332
|
+
left: !leftStat ? void 0 : isStdin(left) ? "-" : streamType(leftStat.type) ? { stream: pathOf2(context, left) } : pathOf2(context, left),
|
|
1333
|
+
right: !rightStat ? void 0 : isStdin(right) ? "-" : streamType(rightStat.type) ? { stream: pathOf2(context, right) } : pathOf2(context, right)
|
|
1196
1334
|
}, stdinDocument);
|
|
1197
1335
|
different ||= result.different;
|
|
1198
1336
|
trouble ||= result.trouble;
|
|
@@ -1201,8 +1339,8 @@ async function runStored(context, budget, storage, stdinDocument) {
|
|
|
1201
1339
|
const read = async (path, stat) => {
|
|
1202
1340
|
if (!stat) return "";
|
|
1203
1341
|
if (isStdin(path)) return stdin ??= await budget.read("-", "latin1");
|
|
1204
|
-
if (!pair.nested && streamType(stat.type)) return budget.read(
|
|
1205
|
-
return budget.readDiff(
|
|
1342
|
+
if (!pair.nested && streamType(stat.type)) return budget.read(pathOf2(context, path), "latin1");
|
|
1343
|
+
return budget.readDiff(pathOf2(context, path), "latin1");
|
|
1206
1344
|
};
|
|
1207
1345
|
const oldBytes = await read(left, leftStat);
|
|
1208
1346
|
const newBytes = await read(right, rightStat);
|
|
@@ -1317,7 +1455,7 @@ async function runStored(context, budget, storage, stdinDocument) {
|
|
|
1317
1455
|
if (options.paginate && outputSize) {
|
|
1318
1456
|
const title = ["diff", ...context.args].join(" ");
|
|
1319
1457
|
const argumentValues = createCommandArguments(["-f", "-h", title]);
|
|
1320
|
-
const pages = new
|
|
1458
|
+
const pages = new PagedStorage5(context, 16);
|
|
1321
1459
|
context.registerCleanup?.(() => pages.close());
|
|
1322
1460
|
let pageBytes = 0;
|
|
1323
1461
|
try {
|
|
@@ -3503,7 +3503,7 @@ function readCommentGeometry(roots, charge) {
|
|
|
3503
3503
|
else if (name === "z-index" && value && Number.isSafeInteger(Number(value))) style[name] = value;
|
|
3504
3504
|
}
|
|
3505
3505
|
const flags = [];
|
|
3506
|
-
for (const name of ["MoveWithCells", "SizeWithCells", "Visible", "AutoFill"]) {
|
|
3506
|
+
for (const name of ["MoveWithCells", "SizeWithCells", "Visible", "AutoFill", "Locked", "LockText"]) {
|
|
3507
3507
|
const field = fields3.get(name);
|
|
3508
3508
|
if (!field) continue;
|
|
3509
3509
|
const text = field.text.trim();
|
|
@@ -202,6 +202,7 @@ async function stageZip(scope, prepared, consume) {
|
|
|
202
202
|
const capabilities = await scope.operation(() => fs.capabilitiesFor?.(prepared.parent, { signal }) ?? fs.capabilities);
|
|
203
203
|
if (capabilities.atomicFileStaging !== true && capabilities.trustedOwnedStaging !== true || !fs.createStagedFile || !fs.removeStagedFile) fail("ZIP temporary path requires atomic owned file staging");
|
|
204
204
|
if (prepared.source && (capabilities.atomicFileMutation !== true && capabilities.trustedOwnedStaging !== true || !fs.writeFileConditional)) fail("ZIP temporary path requires atomic conditional writes");
|
|
205
|
+
const buffered = prepared.source && capabilities.retainedStagingWrite !== true ? await collectBytes(prepared.source, { signal, maxBytes: scope.limits.maxArchiveBytes }) : void 0;
|
|
205
206
|
let staging;
|
|
206
207
|
let failure;
|
|
207
208
|
const close = retainFileSystemCleanup(fs, async (cleanup) => {
|
|
@@ -219,7 +220,7 @@ async function stageZip(scope, prepared, consume) {
|
|
|
219
220
|
if (path === prepared.reservedPath) continue;
|
|
220
221
|
try {
|
|
221
222
|
await scope.operation(async () => {
|
|
222
|
-
staging = await fs.createStagedFile(path, "archive.zip", { type: "file", data: prepared.bytes ?? new Uint8Array() }, {
|
|
223
|
+
staging = await fs.createStagedFile(path, "archive.zip", { type: "file", data: buffered ?? prepared.bytes ?? new Uint8Array() }, {
|
|
223
224
|
signal,
|
|
224
225
|
parent: prepared.parentStat,
|
|
225
226
|
...capabilities.retainedStagingCleanup ? { retainCleanup: true } : {},
|
|
@@ -234,7 +235,7 @@ async function stageZip(scope, prepared, consume) {
|
|
|
234
235
|
}
|
|
235
236
|
}
|
|
236
237
|
if (!staging) fail("ZIP temporary directory attempt limit exceeded");
|
|
237
|
-
if (prepared.source) {
|
|
238
|
+
if (prepared.source && buffered === void 0) {
|
|
238
239
|
for await (const chunk of readBytes(prepared.source, signal)) {
|
|
239
240
|
try {
|
|
240
241
|
await writeFileOutput(scope.context, chunk, (bytes) => scope.operation(async () => {
|