@poe-platform/safe-bash 0.1.756 → 0.1.757
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/image-ast/index.browser.js +4 -4
- package/dist/image-ast/index.js +4 -4
- package/dist/safe-bash/chunks/{chunk-LESPJ3OG.js → chunk-WNWIBBJZ.js} +15 -2
- package/dist/safe-bash/command-chunks/{chunk-S4J6MSLY.js → chunk-444OTXM7.js} +3 -3
- package/dist/safe-bash/command-chunks/{chunk-6AIOGLZO.js → chunk-CE6Z2ULX.js} +2 -2
- package/dist/safe-bash/command-chunks/{chunk-5VSGEE6J.js → chunk-F4IQCXZG.js} +5 -5
- package/dist/safe-bash/command-chunks/{chunk-F5MORDSU.js → chunk-FDNCPZQS.js} +32 -1
- package/dist/safe-bash/command-chunks/{chunk-SG3ZDZCX.js → chunk-FLMLM7Y4.js} +2 -2
- package/dist/safe-bash/command-chunks/{chunk-CT3FB722.js → chunk-J7UMKBRK.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-QQOAK7JQ.js → chunk-KKJCKPTA.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-7KS6PX4U.js → chunk-KSIGF4AG.js} +3 -3
- package/dist/safe-bash/command-chunks/{chunk-4HQ7WYSI.js → chunk-MED2BOOW.js} +30 -5
- package/dist/safe-bash/command-chunks/{chunk-JRNLDPLI.js → chunk-OZSWW23M.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-DKQ5REXF.js → chunk-QDPRSPHQ.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-WOPU2VWF.js → chunk-RID3B5RE.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-DVZCHNB5.js → chunk-S4MLIYSN.js} +7 -7
- package/dist/safe-bash/command-chunks/{chunk-REYTQLLB.js → chunk-TT2DMDBY.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-UGX6MXDD.js → chunk-UIIT4ULR.js} +3 -3
- package/dist/safe-bash/command-chunks/{chunk-A6NFLWZI.js → chunk-WKPOGTZY.js} +22 -6
- package/dist/safe-bash/command-chunks/{chunk-3DOHQQJR.js → chunk-Y64PA6IA.js} +8 -8
- package/dist/safe-bash/command-chunks/{chunk-6Z7OS3TZ.js → chunk-ZP5KDHB4.js} +7 -7
- package/dist/safe-bash/commands/pandoc/index.d.ts +1 -1
- package/dist/safe-bash/commands/pandoc/index.js +5 -3
- package/dist/safe-bash/commands/python/index.browser.js +1 -1
- package/dist/safe-bash/commands/python/index.js +6 -0
- package/dist/safe-bash/commands/python/jspi.js +11 -2
- package/dist/safe-bash/core.browser.js +6 -4
- package/dist/safe-bash-command-csvkit/index.js +8 -8
- package/dist/safe-bash-command-soffice/index.js +16 -16
- package/dist/safe-bash-command-ssconvert/core.js +8 -8
- package/dist/safe-bash-command-ssconvert/formats/csv.js +9 -9
- package/dist/safe-bash-command-ssconvert/formats/ods.js +8 -8
- package/dist/safe-bash-command-ssconvert/formats/spreadsheetml.js +1 -1
- package/dist/safe-bash-command-ssconvert/formats/xls.js +9 -8
- package/dist/safe-bash-command-ssconvert/formats/xlsx.js +8 -8
- package/dist/safe-bash-command-ssconvert/index.js +107 -27
- package/dist/safe-bash-contracts/filesystem-descriptor.js +1 -1
- package/dist/safe-bash-contracts/filesystem-output.js +1 -1
- package/dist/safe-bash-mcp/index.js +4 -4
- package/dist/spreadsheet-engine/formulas/ast.d.ts +13 -0
- package/dist/spreadsheet-engine/formulas/conventions.js +1 -1
- package/dist/spreadsheet-engine/formulas/dependencies.js +2 -2
- package/dist/spreadsheet-engine/formulas/evaluator.js +2 -2
- package/dist/spreadsheet-engine/formulas/named-expressions.d.ts +2 -2
- package/dist/spreadsheet-engine/formulas/named-expressions.js +31 -5
- package/dist/spreadsheet-engine/formulas/parser.js +34 -0
- package/dist/spreadsheet-engine/formulas/rewriting.js +19 -1
- package/dist/spreadsheet-engine/formulas/serialization.js +6 -0
- package/dist/spreadsheet-format-xls/biff-write-formulas.js +2 -0
- package/dist/xlsx-ast/formula-semantics.js +2 -0
- package/package.json +2 -2
- package/dist/safe-bash/chunks/browser-ECQX6GMK.js +0 -6766
- package/dist/safe-bash/chunks/bz2-4OP3OWW3.js +0 -8
- package/dist/safe-bash/chunks/chunk-22XPAAOI.js +0 -173
- package/dist/safe-bash/chunks/chunk-44WUNUPV.js +0 -649
- package/dist/safe-bash/chunks/chunk-4E3SGG37.js +0 -876
- package/dist/safe-bash/chunks/chunk-4QTSSQKP.js +0 -898
- package/dist/safe-bash/chunks/chunk-5UVGPVXP.js +0 -410
- package/dist/safe-bash/chunks/chunk-64OE6Q6X.js +0 -3487
- package/dist/safe-bash/chunks/chunk-6IIFUPN2.js +0 -1526
- package/dist/safe-bash/chunks/chunk-BENDLTQD.js +0 -7065
- package/dist/safe-bash/chunks/chunk-BMO5LWEX.js +0 -534
- package/dist/safe-bash/chunks/chunk-BPMCPTNP.js +0 -1920
- package/dist/safe-bash/chunks/chunk-BRJTAWP5.js +0 -2955
- package/dist/safe-bash/chunks/chunk-C3GEIN7Q.js +0 -20054
- package/dist/safe-bash/chunks/chunk-CBVANNKK.js +0 -174814
- package/dist/safe-bash/chunks/chunk-CEWCRI6H.js +0 -2813
- package/dist/safe-bash/chunks/chunk-CGL53DQQ.js +0 -37
- package/dist/safe-bash/chunks/chunk-CTYJJD4O.js +0 -869
- package/dist/safe-bash/chunks/chunk-CWSS4MQA.js +0 -7
- package/dist/safe-bash/chunks/chunk-DLIGMTCP.js +0 -3266
- package/dist/safe-bash/chunks/chunk-EMAJ7WUW.js +0 -1031
- package/dist/safe-bash/chunks/chunk-FDKIZ2IJ.js +0 -1950
- package/dist/safe-bash/chunks/chunk-FZWJ2A7V.js +0 -3093
- package/dist/safe-bash/chunks/chunk-G2VCIF2J.js +0 -22
- package/dist/safe-bash/chunks/chunk-GVKBUQDX.js +0 -2649
- package/dist/safe-bash/chunks/chunk-IO2OGW3E.js +0 -28051
- package/dist/safe-bash/chunks/chunk-ISCZG7WA.js +0 -2648
- package/dist/safe-bash/chunks/chunk-JCN3FXLP.js +0 -38983
- package/dist/safe-bash/chunks/chunk-KJHDD4A2.js +0 -759
- package/dist/safe-bash/chunks/chunk-LB6HVRXS.js +0 -857
- package/dist/safe-bash/chunks/chunk-LLWAJOZH.js +0 -15
- package/dist/safe-bash/chunks/chunk-LMUKYZIJ.js +0 -708
- package/dist/safe-bash/chunks/chunk-M5SCNKIK.js +0 -2012
- package/dist/safe-bash/chunks/chunk-MJPFHANT.js +0 -3350
- package/dist/safe-bash/chunks/chunk-MZQW2DOL.js +0 -82
- package/dist/safe-bash/chunks/chunk-NB2V7EOY.js +0 -1348
- package/dist/safe-bash/chunks/chunk-NJVGOIYN.js +0 -17
- package/dist/safe-bash/chunks/chunk-OLNZHDIQ.js +0 -5141
- package/dist/safe-bash/chunks/chunk-OSUXMC43.js +0 -2317
- package/dist/safe-bash/chunks/chunk-OUUVROTM.js +0 -38
- package/dist/safe-bash/chunks/chunk-PA6GYKBQ.js +0 -151
- package/dist/safe-bash/chunks/chunk-PEFHZ226.js +0 -6957
- package/dist/safe-bash/chunks/chunk-QBB5P5KW.js +0 -4839
- package/dist/safe-bash/chunks/chunk-RSAWYAEH.js +0 -973
- package/dist/safe-bash/chunks/chunk-UWLYRWT4.js +0 -739
- package/dist/safe-bash/chunks/chunk-V463NBQH.js +0 -13
- package/dist/safe-bash/chunks/chunk-WPUALYUS.js +0 -843
- package/dist/safe-bash/chunks/chunk-XHKFSRGU.js +0 -5747
- package/dist/safe-bash/chunks/chunk-XHRCLZ3N.js +0 -13391
- package/dist/safe-bash/chunks/chunk-XPF5XHLY.js +0 -15
- package/dist/safe-bash/chunks/chunk-ZBFOWARG.js +0 -305
- package/dist/safe-bash/chunks/chunk-ZG7GWQ5P.js +0 -1859
- package/dist/safe-bash/chunks/model-store-EIY3ZQLZ.js +0 -10
- package/dist/safe-bash/chunks/pdf-renderer-CMF3CSVU.js +0 -22
- package/dist/safe-bash/chunks/pptx-ZL6L7KP2-O425BFIU.js +0 -30658
- package/dist/safe-bash/chunks/src-HHEPGR7U.js +0 -18969
- package/dist/safe-bash/chunks/src-MXIKQCIC.js +0 -187
- package/dist/safe-bash/chunks/usage-6TGVA2OM.js +0 -35
- package/dist/safe-bash/chunks/xz-EGQGQUEI.js +0 -8
- package/dist/safe-bash/chunks/xz-K2E2WLM6.js +0 -9
- package/dist/safe-bash/chunks/zstd-6JBLP5EF.js +0 -8
- package/dist/safe-bash/git_rust-C3QYOAZL.wasm +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
openCommandFile
|
|
3
|
-
} from "../safe-bash/command-chunks/chunk-
|
|
3
|
+
} from "../safe-bash/command-chunks/chunk-KSIGF4AG.js";
|
|
4
4
|
import "../safe-bash/command-chunks/chunk-PTLDMI4O.js";
|
|
5
5
|
import "../safe-bash/command-chunks/chunk-U6CJOXRY.js";
|
|
6
6
|
import "../safe-bash/command-chunks/chunk-WYJTWJZ5.js";
|
|
@@ -14397,7 +14397,7 @@ function forwardFileDescriptor(descriptor, operation, capabilities, snapshot = (
|
|
|
14397
14397
|
write: (retained, buffer, position, options) => operation("write", options, () => retained.write(buffer, position, options)),
|
|
14398
14398
|
truncate: (retained, length, options) => operation("ftruncate", options, () => retained.truncate(length, options)),
|
|
14399
14399
|
sync: (retained, dataOnly, options) => operation(dataOnly ? "fdatasync" : "fsync", options, () => retained.sync(dataOnly, options)),
|
|
14400
|
-
close: (retained) => operation("close", {}, () => retained.close())
|
|
14400
|
+
close: (retained, options) => operation("close", {}, () => retained.close(options))
|
|
14401
14401
|
};
|
|
14402
14402
|
}
|
|
14403
14403
|
function integer(value, syscall, path6) {
|
|
@@ -14565,10 +14565,10 @@ var ManagedFileDescriptor = class {
|
|
|
14565
14565
|
await backend.sync(backend.resource, dataOnly, forwarded);
|
|
14566
14566
|
});
|
|
14567
14567
|
}
|
|
14568
|
-
close() {
|
|
14568
|
+
close(options = {}) {
|
|
14569
14569
|
this.#closing ??= this.#pending.then(async () => {
|
|
14570
14570
|
try {
|
|
14571
|
-
await this.#backend.close(this.#backend.resource);
|
|
14571
|
+
await this.#backend.close(this.#backend.resource, options);
|
|
14572
14572
|
} finally {
|
|
14573
14573
|
this.#backend = void 0;
|
|
14574
14574
|
this.#getPosition = void 0;
|
|
@@ -14626,7 +14626,7 @@ async function openFileDescriptor(path6, options, capabilities, acquire) {
|
|
|
14626
14626
|
signal?.throwIfAborted();
|
|
14627
14627
|
return descriptor;
|
|
14628
14628
|
} catch (error) {
|
|
14629
|
-
await finishCleanup(() => backend.close(backend.resource), true);
|
|
14629
|
+
await finishCleanup(() => backend.close(backend.resource, {}), true);
|
|
14630
14630
|
signal?.throwIfAborted();
|
|
14631
14631
|
throw error;
|
|
14632
14632
|
}
|
|
@@ -13,6 +13,17 @@ export interface Axis {
|
|
|
13
13
|
readonly value: number;
|
|
14
14
|
readonly relative: boolean;
|
|
15
15
|
}
|
|
16
|
+
/** A binary-format name use retains identity while copies displace its definition.
|
|
17
|
+
* Offsets apply to references resolved at the current definition's declaration
|
|
18
|
+
* anchor. Copy adds row/column deltas only in relative mode and always adds tab
|
|
19
|
+
* displacement unless sheetRelative is false; moving leaves offsets intact. */
|
|
20
|
+
export interface NameRelocation {
|
|
21
|
+
readonly relative: boolean;
|
|
22
|
+
readonly row: number;
|
|
23
|
+
readonly column: number;
|
|
24
|
+
readonly sheet: number;
|
|
25
|
+
readonly sheetRelative?: boolean;
|
|
26
|
+
}
|
|
16
27
|
export interface ReferenceEndpoint {
|
|
17
28
|
readonly row?: Axis;
|
|
18
29
|
readonly column?: Axis;
|
|
@@ -62,6 +73,7 @@ export type FormulaNode = Span & ({
|
|
|
62
73
|
readonly kind: "name";
|
|
63
74
|
readonly name: string;
|
|
64
75
|
readonly sheet?: string;
|
|
76
|
+
readonly relocation?: NameRelocation;
|
|
65
77
|
/** Empty means the current workbook; without a sheet it selects only global names. */
|
|
66
78
|
readonly workbook?: string;
|
|
67
79
|
} | {
|
|
@@ -117,6 +129,7 @@ export interface FormulaGrammar {
|
|
|
117
129
|
readonly quotedLabels?: "openformula" | "calc";
|
|
118
130
|
/** Permit ssconvert's live label anchors in internal workbook expressions. */
|
|
119
131
|
readonly internalLabels?: boolean;
|
|
132
|
+
readonly internalNames?: boolean;
|
|
120
133
|
readonly quotedErrors?: boolean;
|
|
121
134
|
readonly rangeSeparator?: string;
|
|
122
135
|
readonly sheetSpans?: boolean;
|
|
@@ -25,7 +25,7 @@ export const odfGrammar = Object.freeze({ ...gnumericGrammar,
|
|
|
25
25
|
prefixes: Object.freeze(["of:=", "oooc:=", "="]), functionPrefixes: Object.freeze(["ORG.GNUMERIC.", "COM.MICROSOFT."])
|
|
26
26
|
});
|
|
27
27
|
/** Internal OpenFormula preserves relative sheets alongside live label anchors. */
|
|
28
|
-
export const internalOdfGrammar = Object.freeze({ ...odfGrammar, internalLabels: true });
|
|
28
|
+
export const internalOdfGrammar = Object.freeze({ ...odfGrammar, internalLabels: true, internalNames: true });
|
|
29
29
|
export const sylkGrammar = Object.freeze({ ...gnumericGrammar, id: "sylk", address: "r1c1" });
|
|
30
30
|
/** Native SYLK output quotes strings without escaping; its reader does not invert that operation. */
|
|
31
31
|
export const sylkWriterGrammar = Object.freeze({ ...sylkGrammar, id: "sylk-writer", stringEscape: "raw" });
|
|
@@ -80,7 +80,7 @@ export function buildDependencyGraph(book, roots, resolve, parse, tick, onRange,
|
|
|
80
80
|
const name = named(node, position);
|
|
81
81
|
if (!name || names.has(name))
|
|
82
82
|
return [];
|
|
83
|
-
return staticRanges(parseNamedExpression(name, book, parse, tick, maximumDepth), position, new Set([...names, name]), depth + 1);
|
|
83
|
+
return staticRanges(parseNamedExpression(name, book, parse, tick, maximumDepth, node.relocation), position, new Set([...names, name]), depth + 1);
|
|
84
84
|
}
|
|
85
85
|
if (node.kind === "call" && (node.name === "IF" || node.name === "CHOOSE")) {
|
|
86
86
|
const ranges = [];
|
|
@@ -188,7 +188,7 @@ export function buildDependencyGraph(book, roots, resolve, parse, tick, onRange,
|
|
|
188
188
|
if (node.kind === "name" && (node.workbook === undefined || node.workbook === "")) {
|
|
189
189
|
const name = named(node, position);
|
|
190
190
|
if (name && !names.has(name)) {
|
|
191
|
-
pending.push({ node: parseNamedExpression(name, book, parse, tick, maximumDepth), position, names: new Set([...names, name]), depth: depth + 1 });
|
|
191
|
+
pending.push({ node: parseNamedExpression(name, book, parse, tick, maximumDepth, node.relocation), position, names: new Set([...names, name]), depth: depth + 1 });
|
|
192
192
|
}
|
|
193
193
|
}
|
|
194
194
|
const children = node.kind === "unary" || node.kind === "parentheses" ? [node.child] : node.kind === "binary" ? [node.left, node.right] : node.kind === "call" ? node.args : node.kind === "array" ? node.rows.flat() : [];
|
|
@@ -175,7 +175,7 @@ export function* recalculateWorkbookSteps(input, context, options = false, onDia
|
|
|
175
175
|
const name = book.names?.find(entry => entry.sheet === sheet && matches(entry)) ?? book.names?.find(entry => entry.sheet === undefined && matches(entry));
|
|
176
176
|
if (!name || names.has(name))
|
|
177
177
|
return error("#REF!");
|
|
178
|
-
return indirectRange(parseNamedExpression(name, book, parse, tick, context.limits.formulaDependencyDepth ?? Infinity), position, new Set([...names, name]), depth + 1);
|
|
178
|
+
return indirectRange(parseNamedExpression(name, book, parse, tick, context.limits.formulaDependencyDepth ?? Infinity, node.relocation), position, new Set([...names, name]), depth + 1);
|
|
179
179
|
}
|
|
180
180
|
function scalar(value, position) {
|
|
181
181
|
// OpenFormula §5.10.4 selects at the formula position when the consumer
|
|
@@ -264,7 +264,7 @@ export function* recalculateWorkbookSteps(input, context, options = false, onDia
|
|
|
264
264
|
const name = book.names?.find(entry => entry.sheet === sheet && matches(entry)) ?? book.names?.find(entry => entry.sheet === undefined && matches(entry));
|
|
265
265
|
if (!name || names.has(name))
|
|
266
266
|
return error("#NAME?");
|
|
267
|
-
return evaluate(parseNamedExpression(name, book, parse, tick, context.limits.formulaDependencyDepth ?? Infinity), position, array, new Set([...names, name]), wantReference);
|
|
267
|
+
return evaluate(parseNamedExpression(name, book, parse, tick, context.limits.formulaDependencyDepth ?? Infinity, node.relocation), position, array, new Set([...names, name]), wantReference);
|
|
268
268
|
}
|
|
269
269
|
if (node.kind === "unary") {
|
|
270
270
|
const apply = (value) => {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type NamedExpression, type Workbook } from "../../spreadsheet-ast/index.js";
|
|
2
|
-
import type { FormulaNode, ParsePosition } from "./ast.js";
|
|
2
|
+
import type { FormulaNode, NameRelocation, ParsePosition } from "./ast.js";
|
|
3
3
|
/** Parse relative offsets at the declaration anchor and bind nested names there.
|
|
4
4
|
* References and functions in the resulting expression still use the caller's
|
|
5
5
|
* evaluation position, as in native expr_name_eval. */
|
|
6
|
-
export declare function parseNamedExpression(name: NamedExpression, book: Workbook, parse: (source: string, position: ParsePosition, arrayStringLiterals?: boolean) => FormulaNode, tick: () => void, maximumDepth?: number): FormulaNode;
|
|
6
|
+
export declare function parseNamedExpression(name: NamedExpression, book: Workbook, parse: (source: string, position: ParsePosition, arrayStringLiterals?: boolean) => FormulaNode, tick: () => void, maximumDepth?: number, relocation?: NameRelocation): FormulaNode;
|
|
@@ -4,23 +4,49 @@ import { foldSheetName } from "../../spreadsheet-ast/case-fold.js";
|
|
|
4
4
|
/** Parse relative offsets at the declaration anchor and bind nested names there.
|
|
5
5
|
* References and functions in the resulting expression still use the caller's
|
|
6
6
|
* evaluation position, as in native expr_name_eval. */
|
|
7
|
-
export function parseNamedExpression(name, book, parse, tick, maximumDepth = Infinity) {
|
|
7
|
+
export function parseNamedExpression(name, book, parse, tick, maximumDepth = Infinity, relocation) {
|
|
8
8
|
if (name.expression === "" || name.expression === "=") {
|
|
9
9
|
tick();
|
|
10
10
|
return { kind: "literal", value: { kind: "blank" }, start: 0, end: 0 };
|
|
11
11
|
}
|
|
12
12
|
const position = name.position ?? { sheet: name.sheet ?? book.sheets[0]?.id ?? "", row: 0, column: 0 };
|
|
13
|
+
function displace(ref, fallback) {
|
|
14
|
+
if (!relocation || ref.workbook !== undefined)
|
|
15
|
+
return ref;
|
|
16
|
+
const origin = book.sheets.findIndex(sheet => sheet.id === position.sheet);
|
|
17
|
+
const index = ref.sheetRelative ? origin + (ref.sheetOffset ?? 0) : ref.sheet !== undefined || fallback !== undefined
|
|
18
|
+
? book.sheets.findIndex(sheet => foldSheetName(sheet.name) === foldSheetName(ref.sheet ?? fallback)) : origin;
|
|
19
|
+
const target = index >= 0 ? book.sheets[index + relocation.sheet] : undefined;
|
|
20
|
+
if (!target)
|
|
21
|
+
return undefined;
|
|
22
|
+
const axis = (value, key) => ({ value: value.value + (value.relative ? position[key] : 0) + relocation[key], relative: false });
|
|
23
|
+
return { ...ref, sheet: target.name, sheetRelative: false, ...(ref.row ? { row: axis(ref.row, "row") } : {}), ...(ref.column ? { column: axis(ref.column, "column") } : {}) };
|
|
24
|
+
}
|
|
13
25
|
function bind(node, depth = 0) {
|
|
14
26
|
tick();
|
|
15
27
|
if (depth > maximumDepth)
|
|
16
28
|
throw new SsconvertError("resource-limit", "ssconvert formula dependency depth limit exceeded");
|
|
17
|
-
if (node.kind === "
|
|
29
|
+
if (node.kind === "reference" && relocation) {
|
|
30
|
+
const first = displace(node.first), last = node.last ? displace(node.last, node.first.sheet) : undefined;
|
|
31
|
+
if (!first || node.last && !last)
|
|
32
|
+
return { kind: "literal", value: { kind: "error", value: "#REF!" }, start: node.start, end: node.end };
|
|
33
|
+
return { ...node, first, ...(last ? { last } : {}) };
|
|
34
|
+
}
|
|
35
|
+
if (node.kind === "name" && (node.workbook === undefined || node.workbook === "")) {
|
|
36
|
+
const inherited = relocation ? { ...relocation,
|
|
37
|
+
row: relocation.row + (node.relocation?.row ?? 0), column: relocation.column + (node.relocation?.column ?? 0),
|
|
38
|
+
sheet: relocation.sheet + (node.relocation?.sheet ?? 0) } : node.relocation;
|
|
39
|
+
const bound = inherited ? { ...node, relocation: inherited } : node;
|
|
40
|
+
if (node.workbook === "" && node.sheet === undefined)
|
|
41
|
+
return bound;
|
|
18
42
|
const scope = node.sheet === undefined ? name.sheet : book.sheets.find(sheet => foldSheetName(sheet.name) === foldSheetName(node.sheet))?.id;
|
|
19
43
|
const target = resolveName(book, node.name, scope);
|
|
20
|
-
if (target?.sheet === undefined)
|
|
21
|
-
|
|
44
|
+
if (target?.sheet === undefined) {
|
|
45
|
+
const { sheet: ignoredSheet, ...global } = bound;
|
|
46
|
+
return { ...global, workbook: "" };
|
|
47
|
+
}
|
|
22
48
|
const sheet = book.sheets.find(sheet => sheet.id === target.sheet);
|
|
23
|
-
return sheet ? { ...
|
|
49
|
+
return sheet ? { ...bound, sheet: sheet.name } : bound;
|
|
24
50
|
}
|
|
25
51
|
if (node.kind === "parentheses" || node.kind === "unary")
|
|
26
52
|
return { ...node, child: bind(node.child, depth + 1) };
|
|
@@ -335,6 +335,40 @@ export function parseExpression(source, options) {
|
|
|
335
335
|
throw new SsconvertError("resource-limit", "ssconvert formula node limit exceeded");
|
|
336
336
|
try {
|
|
337
337
|
const c = source[offset];
|
|
338
|
+
if (source.startsWith("@name.", offset)) {
|
|
339
|
+
if (grammar.id !== "gnumeric" && !grammar.internalNames)
|
|
340
|
+
fail("Internal live name in native formula");
|
|
341
|
+
offset += 6;
|
|
342
|
+
const relative = source.startsWith("relative", offset);
|
|
343
|
+
if (!relative && !source.startsWith("absolute", offset))
|
|
344
|
+
fail("Invalid live name mode");
|
|
345
|
+
offset += 8;
|
|
346
|
+
const fixedSheet = source.startsWith(".fixed-sheet", offset);
|
|
347
|
+
if (fixedSheet)
|
|
348
|
+
offset += 12;
|
|
349
|
+
if (source[offset++] !== "[")
|
|
350
|
+
fail("Invalid live name mode");
|
|
351
|
+
const displacement = (separator) => {
|
|
352
|
+
const start = offset;
|
|
353
|
+
if (source[offset] === "-")
|
|
354
|
+
offset++;
|
|
355
|
+
const begin = offset;
|
|
356
|
+
while (digit(source[offset]))
|
|
357
|
+
offset++;
|
|
358
|
+
const value = Number(source.slice(start, offset));
|
|
359
|
+
if (offset === begin || !Number.isSafeInteger(value) || source[offset++] !== separator)
|
|
360
|
+
fail("Invalid live name displacement");
|
|
361
|
+
return value;
|
|
362
|
+
};
|
|
363
|
+
const row = displacement(","), column = displacement(","), sheet = displacement("]");
|
|
364
|
+
if (!relative && (row !== 0 || column !== 0) || source[offset++] !== ":" || source[offset] !== '"')
|
|
365
|
+
fail("Invalid live name");
|
|
366
|
+
const name = quoted('"', grammar.stringEscape);
|
|
367
|
+
if (!name)
|
|
368
|
+
fail("Empty live name");
|
|
369
|
+
options.onName?.(name);
|
|
370
|
+
return node({ kind: "name", name, workbook: "", relocation: { relative, row, column, sheet, ...(fixedSheet ? { sheetRelative: false } : {}) }, start, end: offset });
|
|
371
|
+
}
|
|
338
372
|
if (c === "@" && !internalLabels)
|
|
339
373
|
fail("Internal label reference in native formula");
|
|
340
374
|
if (c === "@" && internalLabels) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { SsconvertError } from "../contracts.js";
|
|
2
2
|
import { foldSheetName } from "../../spreadsheet-ast/case-fold.js";
|
|
3
|
-
import { serializeReference, serializeLabelReference, quoteFormulaString } from "./serialization.js";
|
|
3
|
+
import { serializeExpression, serializeReference, serializeLabelReference, quoteFormulaString } from "./serialization.js";
|
|
4
4
|
export function visitFormula(node, visitor) {
|
|
5
5
|
visitor(node);
|
|
6
6
|
if (node.kind === "unary" || node.kind === "parentheses")
|
|
@@ -106,6 +106,24 @@ export function rewriteReferences(document, edit) {
|
|
|
106
106
|
: serializeReference(first, last, document.grammar, position) });
|
|
107
107
|
}
|
|
108
108
|
}
|
|
109
|
+
else if (node.kind === "name" && node.relocation && edit.translation === "copy") {
|
|
110
|
+
const relocation = { ...node.relocation };
|
|
111
|
+
if (relocation.relative) {
|
|
112
|
+
relocation.row += target.row - document.position.row;
|
|
113
|
+
relocation.column += target.column - document.position.column;
|
|
114
|
+
}
|
|
115
|
+
if (relocation.sheetRelative !== false && target.sheet !== document.position.sheet) {
|
|
116
|
+
const origin = document.sheetOrder?.indexOf(document.position.sheet) ?? -1;
|
|
117
|
+
const destination = document.sheetOrder?.indexOf(target.sheet) ?? -1;
|
|
118
|
+
if (origin < 0 || destination < 0)
|
|
119
|
+
throw new SsconvertError("invalid-request", "Cross-sheet formula copy requires workbook tab order");
|
|
120
|
+
relocation.sheet += destination - origin;
|
|
121
|
+
}
|
|
122
|
+
if (![relocation.row, relocation.column, relocation.sheet].every(Number.isSafeInteger))
|
|
123
|
+
throw new SsconvertError("invalid-request", "Invalid live name displacement");
|
|
124
|
+
const text = serializeExpression({ ...document, root: { ...node, relocation } }, document.grammar, false).slice(document.grammar.prefixes[0]?.length ?? 0);
|
|
125
|
+
changes.push({ start: node.start, end: node.end, text });
|
|
126
|
+
}
|
|
109
127
|
else if (node.kind === "name" && (node.workbook === undefined || node.workbook === "") && node.sheet && renamedSheet(node.sheet) !== undefined) {
|
|
110
128
|
const text = quoteFormulaString(renamedSheet(node.sheet), "'", document.grammar) + document.grammar.sheetSeparator + node.name;
|
|
111
129
|
changes.push({ start: node.start, end: node.end, text: document.grammar.bracketReferences ? "[" + text + "]" : text });
|
|
@@ -161,6 +161,12 @@ export function serializeExpression(document, grammar = document.grammar, preser
|
|
|
161
161
|
case "reference": return value.label ? grammar.quotedLabels === "openformula" && options.quotedLabel
|
|
162
162
|
? quoteFormulaString(options.quotedLabel(value), "'", grammar) : serializeLabelReference(value, grammar, position) : serializeReference(options.relativeSheets === "fixed" ? { ...value.first, sheetRelative: false } : value.first, options.relativeSheets === "fixed" && value.last ? { ...value.last, sheetRelative: false } : value.last, grammar, position);
|
|
163
163
|
case "name": {
|
|
164
|
+
if (value.relocation) {
|
|
165
|
+
if (grammar.id !== "gnumeric" && !grammar.internalNames)
|
|
166
|
+
throw new SsconvertError("unsupported-feature", "Unsupported ssconvert feature: live name relocation in target grammar");
|
|
167
|
+
const { relative, row, column, sheet } = value.relocation;
|
|
168
|
+
return `@name.${relative ? "relative" : "absolute"}${value.relocation.sheetRelative === false ? ".fixed-sheet" : ""}[${row},${column},${sheet}]:` + quoteFormulaString(value.name, '"', grammar);
|
|
169
|
+
}
|
|
164
170
|
if (grammar.qualifiedNames === false && (value.sheet !== undefined || value.workbook !== undefined))
|
|
165
171
|
throw new SsconvertError("unsupported-feature", "Unsupported ssconvert feature: qualified formula name in target grammar");
|
|
166
172
|
if (value.workbook === "" && grammar.bracketReferences && value.sheet === undefined)
|
|
@@ -366,6 +366,8 @@ export class BiffFormulaWriter {
|
|
|
366
366
|
push(first);
|
|
367
367
|
}
|
|
368
368
|
else if (node.kind === "name") {
|
|
369
|
+
if (node.relocation)
|
|
370
|
+
throw new SsconvertError("unsupported-feature", "Unsupported ssconvert feature: live name relocation in BIFF output");
|
|
369
371
|
if (node.workbook) {
|
|
370
372
|
const bookIndex = this.externalBook(node.workbook), book = this.externalBooks[bookIndex];
|
|
371
373
|
const scope = node.sheet === undefined ? undefined : this.externalScope(bookIndex, node.sheet);
|
|
@@ -19,6 +19,8 @@ export function nativeOpenFormula(source, position, context, arrayStringLiterals
|
|
|
19
19
|
throw new SsconvertError("unsupported-feature", "Unsupported ssconvert feature: automatic label intersection in Gnumeric output");
|
|
20
20
|
if (node.kind === "reference" && node.label)
|
|
21
21
|
throw new SsconvertError("unsupported-feature", "Unsupported ssconvert feature: live label reference in Gnumeric output");
|
|
22
|
+
if (node.kind === "name" && node.relocation)
|
|
23
|
+
throw new SsconvertError("unsupported-feature", "Unsupported ssconvert feature: live name relocation in Gnumeric output");
|
|
22
24
|
});
|
|
23
25
|
if (!source.startsWith("of:="))
|
|
24
26
|
return source;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@poe-platform/safe-bash",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.757",
|
|
4
4
|
"description": "Extensible virtual shell with pluggable filesystems and streaming commands",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -837,7 +837,7 @@
|
|
|
837
837
|
"access": "public"
|
|
838
838
|
},
|
|
839
839
|
"dependencies": {
|
|
840
|
-
"@poe-platform/safe-fs": "0.1.
|
|
840
|
+
"@poe-platform/safe-fs": "0.1.757",
|
|
841
841
|
"pdf-lib": "1.17.1",
|
|
842
842
|
"@noble/hashes": "2.4.0",
|
|
843
843
|
"pako": "3.0.1",
|