@sheetxl/runner 0.8.0-beta.2 → 0.8.0-beta.21
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/LICENSE.md +17 -7
- package/README.md +1 -1
- package/node/esm/index.mjs +172 -111
- package/package.json +14 -9
- package/types/src/RunDiagnosis.d.ts +33 -0
- package/types/src/Snippet.d.ts +6 -0
- package/types/src/index.d.ts +1 -0
package/LICENSE.md
CHANGED
|
@@ -1,11 +1,21 @@
|
|
|
1
|
-
|
|
1
|
+
MIT License
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Copyright (c) 2026-present SheetXL Inc. & Michael T. Ford
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
6
11
|
|
|
7
|
-
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
8
14
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -58,7 +58,7 @@ import Runner, { type RunContext } from '@sheetxl/runner';
|
|
|
58
58
|
|
|
59
59
|
export default async function main(ctx: RunContext) {
|
|
60
60
|
const { wb, log, args } = ctx;
|
|
61
|
-
wb.
|
|
61
|
+
wb.getWorksheet().getRange('A1').setValue(args.region);
|
|
62
62
|
log('updated value');
|
|
63
63
|
}
|
|
64
64
|
```
|
package/node/esm/index.mjs
CHANGED
|
@@ -1,31 +1,31 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @license @sheetxl/runner - SheetXL - Programmatic execution for SheetXL scripts - v0.8.0-beta.
|
|
2
|
+
* @license @sheetxl/runner - SheetXL - Programmatic execution for SheetXL scripts - v0.8.0-beta.21
|
|
3
3
|
*
|
|
4
4
|
* (C) 2026-present SheetXL Inc. & Michael T. Ford
|
|
5
|
-
* License:
|
|
5
|
+
* License: MIT
|
|
6
6
|
*/
|
|
7
7
|
import t from "node:path";
|
|
8
8
|
import e from "node:fs";
|
|
9
9
|
import { pathToFileURL as n } from "node:url";
|
|
10
10
|
import { createLogChannels as r, resolveLogTimeout as s } from "@sheetxl/utils";
|
|
11
|
-
var
|
|
12
|
-
function
|
|
11
|
+
var i = Object.defineProperty;
|
|
12
|
+
function o(e, n = "SHEETXL_IN") {
|
|
13
13
|
if (t.isAbsolute(e)) return e;
|
|
14
14
|
const r = n ? process.env[n] : void 0;
|
|
15
15
|
return t.resolve(r ?? process.cwd(), e);
|
|
16
16
|
}
|
|
17
17
|
var a = ((t, e) => {
|
|
18
18
|
let n = {};
|
|
19
|
-
for (var r in t)
|
|
19
|
+
for (var r in t) i(n, r, {
|
|
20
20
|
get: t[r],
|
|
21
21
|
enumerable: !0
|
|
22
22
|
});
|
|
23
|
-
return e ||
|
|
23
|
+
return e || i(n, Symbol.toStringTag, { value: "Module" }), n;
|
|
24
24
|
})({
|
|
25
|
-
DEFAULT_DESCRIPTION: () =>
|
|
26
|
-
classify: () =>
|
|
27
|
-
prepare: () =>
|
|
28
|
-
toSnippetOffset: () =>
|
|
25
|
+
DEFAULT_DESCRIPTION: () => v,
|
|
26
|
+
classify: () => w,
|
|
27
|
+
prepare: () => T,
|
|
28
|
+
toSnippetOffset: () => b
|
|
29
29
|
}), c = null;
|
|
30
30
|
function l() {
|
|
31
31
|
return c || (c = (async () => {
|
|
@@ -51,17 +51,17 @@ function p(t) {
|
|
|
51
51
|
for (let n = 0; n < t.length; n++) "\n" === t[n] && e++;
|
|
52
52
|
return e;
|
|
53
53
|
}
|
|
54
|
-
function
|
|
54
|
+
function d(t, e, n) {
|
|
55
55
|
let r = n.getStart(e);
|
|
56
56
|
for (const s of n.declarationList.declarations) {
|
|
57
57
|
const n = s.initializer;
|
|
58
58
|
if (!n) continue;
|
|
59
|
-
const
|
|
60
|
-
t.copy(r,
|
|
59
|
+
const i = n.getStart(e);
|
|
60
|
+
t.copy(r, i), t.add("await ("), t.copy(i, n.end), t.add(")"), r = n.end;
|
|
61
61
|
}
|
|
62
62
|
t.copy(r, n.end), t.terminate();
|
|
63
63
|
}
|
|
64
|
-
var
|
|
64
|
+
var f = class {
|
|
65
65
|
constructor(t) {
|
|
66
66
|
this._code = t, this.spans = [], this._parts = [], this._length = 0;
|
|
67
67
|
}
|
|
@@ -81,8 +81,12 @@ var d = class {
|
|
|
81
81
|
toString() {
|
|
82
82
|
return this._parts.join("");
|
|
83
83
|
}
|
|
84
|
-
}, m =
|
|
85
|
-
|
|
84
|
+
}, m = /* @__PURE__ */ new Set([
|
|
85
|
+
"log",
|
|
86
|
+
"warn",
|
|
87
|
+
"error"
|
|
88
|
+
]), h = "await wb?.whenCalculationReady?.(); ";
|
|
89
|
+
function g(t, e) {
|
|
86
90
|
const n = e.statements;
|
|
87
91
|
let r = n.length - 1;
|
|
88
92
|
for (; r >= 0 && n[r].kind === t.SyntaxKind.EmptyStatement;) r--;
|
|
@@ -97,8 +101,8 @@ function h(t, e) {
|
|
|
97
101
|
to: s.expression.end
|
|
98
102
|
};
|
|
99
103
|
if (t.isFunctionDeclaration(s) && s.body) {
|
|
100
|
-
const n = t.getModifiers(s) ?? [],
|
|
101
|
-
if (n.some((e) => e.kind === t.SyntaxKind.DefaultKeyword) && !s.name || !
|
|
104
|
+
const n = t.getModifiers(s) ?? [], i = n.some((e) => e.kind === t.SyntaxKind.ExportKeyword);
|
|
105
|
+
if (n.some((e) => e.kind === t.SyntaxKind.DefaultKeyword) && !s.name || !i && function(t, e) {
|
|
102
106
|
let n = -1;
|
|
103
107
|
for (let r = 0; r < e.statements.length; r++) {
|
|
104
108
|
const s = e.statements[r];
|
|
@@ -109,20 +113,20 @@ function h(t, e) {
|
|
|
109
113
|
}
|
|
110
114
|
return n;
|
|
111
115
|
}(t, e) === r) {
|
|
112
|
-
let
|
|
113
|
-
for (const e of n) e.kind !== t.SyntaxKind.ExportKeyword && e.kind !== t.SyntaxKind.DefaultKeyword || (
|
|
114
|
-
for (;
|
|
116
|
+
let i = s.getStart(e);
|
|
117
|
+
for (const e of n) e.kind !== t.SyntaxKind.ExportKeyword && e.kind !== t.SyntaxKind.DefaultKeyword || (i = e.end);
|
|
118
|
+
for (; i < s.end && /\s/.test(e.text[i]);) i++;
|
|
115
119
|
return {
|
|
116
120
|
index: r,
|
|
117
|
-
from:
|
|
121
|
+
from: i,
|
|
118
122
|
to: s.end
|
|
119
123
|
};
|
|
120
124
|
}
|
|
121
125
|
}
|
|
122
126
|
return null;
|
|
123
127
|
}
|
|
124
|
-
var y = "const __entry: (ctx: SheetXL.IScript.ScriptContext) => unknown = (",
|
|
125
|
-
async function
|
|
128
|
+
var y = "const __entry: (ctx: SheetXL.IScript.ScriptContext) => unknown = (", x = (t) => `); ${t} = await __entry(ctx);`;
|
|
129
|
+
async function w(t) {
|
|
126
130
|
const e = await u(t);
|
|
127
131
|
if (!e) return function(t) {
|
|
128
132
|
return /^\s*export\s+default\b/m.test(t) || /^\s*export\s*\{[^}]*\bas\s+default\b/m.test(t);
|
|
@@ -136,11 +140,11 @@ async function x(t) {
|
|
|
136
140
|
}
|
|
137
141
|
return !1;
|
|
138
142
|
}(n, r) && !function(t, e) {
|
|
139
|
-
const n =
|
|
143
|
+
const n = g(t, e);
|
|
140
144
|
return !!n && e.statements.every((e, r) => r === n.index || !t.isExportAssignment(e) && !t.isExportDeclaration(e) && !(t.canHaveModifiers(e) && t.getModifiers(e)?.some((e) => e.kind === t.SyntaxKind.ExportKeyword)));
|
|
141
145
|
}(n, r) ? "script" : "snippet";
|
|
142
146
|
}
|
|
143
|
-
var
|
|
147
|
+
var S = 3, v = "Run Snippet", E = (t, e, n = [], r) => {
|
|
144
148
|
const s = [
|
|
145
149
|
...n,
|
|
146
150
|
...r ? [r] : [],
|
|
@@ -158,93 +162,103 @@ var w = 3, S = "Run Snippet", v = (t, e, n = [], r) => {
|
|
|
158
162
|
bodyStart: s.length
|
|
159
163
|
};
|
|
160
164
|
};
|
|
161
|
-
async function
|
|
165
|
+
async function T(t, e) {
|
|
162
166
|
const n = e?.epilogue ?? " return __result;", r = await u(t);
|
|
163
167
|
if (!r) {
|
|
164
|
-
const e = await l() ? void 0 : "TypeScript is unavailable, so this snippet ran without implicit await or a result value. Install the `typescript` peer dependency to restore them.", { source: r, bodyStart: s } =
|
|
168
|
+
const e = await l() ? void 0 : "TypeScript is unavailable, so this snippet ran without implicit await or a result value. Install the `typescript` peer dependency to restore them.", { source: r, bodyStart: s } = E(t, n);
|
|
165
169
|
return {
|
|
166
170
|
source: r,
|
|
167
171
|
kind: "verbatim",
|
|
168
|
-
lineOffset:
|
|
172
|
+
lineOffset: S,
|
|
169
173
|
spans: [{
|
|
170
174
|
at: s,
|
|
171
175
|
from: 0,
|
|
172
176
|
length: t.length
|
|
173
177
|
}],
|
|
178
|
+
expectsValue: !1,
|
|
174
179
|
warning: e
|
|
175
180
|
};
|
|
176
181
|
}
|
|
177
|
-
const { ts: s, sf:
|
|
182
|
+
const { ts: s, sf: i } = r, o = i.statements, a = function(t, e) {
|
|
178
183
|
if (!e.statements[0]) return;
|
|
179
184
|
const n = t.getLeadingCommentRanges(e.text, 0);
|
|
180
185
|
if (n?.length) for (let r = n.length - 1; r >= 0; r--) {
|
|
181
186
|
const s = n[r];
|
|
182
187
|
if (s.kind !== t.SyntaxKind.MultiLineCommentTrivia) continue;
|
|
183
|
-
const
|
|
184
|
-
if (
|
|
188
|
+
const i = e.text.slice(s.pos, s.end);
|
|
189
|
+
if (i.startsWith("/**")) return i;
|
|
185
190
|
}
|
|
186
|
-
}(s,
|
|
187
|
-
if (1 ===
|
|
188
|
-
const { source: r, bodyStart: s } =
|
|
191
|
+
}(s, i), c = a ? p(a) + 1 : 0;
|
|
192
|
+
if (1 === o.length && s.isBlock(o[0])) {
|
|
193
|
+
const { source: r, bodyStart: s } = E(` __result = await (
|
|
189
194
|
${t}\n );`, n, [], a);
|
|
190
195
|
return {
|
|
191
196
|
source: r,
|
|
192
197
|
kind: "expression",
|
|
193
|
-
lineOffset:
|
|
198
|
+
lineOffset: S + c + 1,
|
|
194
199
|
spans: [{
|
|
195
200
|
at: s + 21,
|
|
196
201
|
from: 0,
|
|
197
202
|
length: t.length
|
|
198
|
-
}]
|
|
203
|
+
}],
|
|
204
|
+
expectsValue: !0
|
|
199
205
|
};
|
|
200
206
|
}
|
|
201
|
-
const { body:
|
|
207
|
+
const { body: w, spans: v, hoisted: T, expectsValue: b } = function(t, e, n) {
|
|
202
208
|
const r = e.text, s = e.statements;
|
|
203
|
-
let
|
|
209
|
+
let i = -1;
|
|
204
210
|
for (let e = s.length - 1; e >= 0; e--) if (s[e].kind !== t.SyntaxKind.EmptyStatement) {
|
|
205
|
-
t.isExpressionStatement(s[e]) && (
|
|
211
|
+
t.isExpressionStatement(s[e]) && (i = e);
|
|
206
212
|
break;
|
|
207
213
|
}
|
|
208
|
-
const
|
|
209
|
-
let
|
|
210
|
-
|
|
211
|
-
const
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
214
|
+
const o = g(t, e);
|
|
215
|
+
let a = !1;
|
|
216
|
+
if (!o && -1 !== i) {
|
|
217
|
+
const e = s[i].expression;
|
|
218
|
+
a = !(t.isCallExpression(e) && t.isIdentifier(e.expression) && m.has(e.expression.text));
|
|
219
|
+
}
|
|
220
|
+
const c = [], l = new f(r);
|
|
221
|
+
let u = 0, w = !1;
|
|
222
|
+
for (let a = 0; a < s.length; a++) {
|
|
223
|
+
const f = s[a], m = f.getStart(e);
|
|
224
|
+
if (l.copy(u, m), u = f.end, t.isImportDeclaration(f) || t.isImportEqualsDeclaration(f)) {
|
|
225
|
+
const t = r.slice(m, f.end);
|
|
226
|
+
c.push({
|
|
215
227
|
text: t,
|
|
216
|
-
from:
|
|
217
|
-
}),
|
|
228
|
+
from: m
|
|
229
|
+
}), l.add("\n".repeat(p(t)));
|
|
218
230
|
continue;
|
|
219
231
|
}
|
|
220
|
-
|
|
232
|
+
w && l.add(h), w = !0, o?.index !== a ? t.isVariableStatement(f) ? d(l, e, f) : t.isExpressionStatement(f) ? (l.add(a === i ? `${n} = await (` : "await ("), l.copy(f.expression.getStart(e), f.expression.end), l.add(");")) : (l.copy(m, f.end), l.terminate()) : (l.add(y), l.copy(o.from, o.to), l.add(x(n)));
|
|
221
233
|
}
|
|
222
|
-
return
|
|
223
|
-
body:
|
|
224
|
-
spans:
|
|
225
|
-
hoisted:
|
|
234
|
+
return l.copy(u, r.length), {
|
|
235
|
+
body: l.toString(),
|
|
236
|
+
spans: l.spans,
|
|
237
|
+
hoisted: c,
|
|
238
|
+
expectsValue: a
|
|
226
239
|
};
|
|
227
|
-
}(s,
|
|
228
|
-
let
|
|
229
|
-
const
|
|
240
|
+
}(s, i, "__result"), _ = T.map((t) => t.text), k = T.length > 0 ? p(_.join("\n")) + T.length : 0, { source: D, bodyStart: K } = E(w, n, _, a);
|
|
241
|
+
let R = 0;
|
|
242
|
+
const I = T.map((t) => {
|
|
230
243
|
const e = {
|
|
231
|
-
at:
|
|
244
|
+
at: R,
|
|
232
245
|
from: t.from,
|
|
233
246
|
length: t.text.length
|
|
234
247
|
};
|
|
235
|
-
return
|
|
248
|
+
return R += t.text.length + 1, e;
|
|
236
249
|
});
|
|
237
250
|
return {
|
|
238
|
-
source:
|
|
251
|
+
source: D,
|
|
239
252
|
kind: "statements",
|
|
240
|
-
lineOffset:
|
|
241
|
-
spans: [...
|
|
253
|
+
lineOffset: S + k + c,
|
|
254
|
+
spans: [...I, ...v.map((t) => ({
|
|
242
255
|
...t,
|
|
243
256
|
at: t.at + K
|
|
244
|
-
}))]
|
|
257
|
+
}))],
|
|
258
|
+
expectsValue: b
|
|
245
259
|
};
|
|
246
260
|
}
|
|
247
|
-
function
|
|
261
|
+
function b(t, e) {
|
|
248
262
|
let n = null;
|
|
249
263
|
for (const r of t.spans) {
|
|
250
264
|
if (r.at > e) return null !== n && e < n.at + n.length ? n.from + (e - n.at) : r.from;
|
|
@@ -252,7 +266,51 @@ function _(t, e) {
|
|
|
252
266
|
}
|
|
253
267
|
return n ? n.from + Math.min(e - n.at, n.length) : 0;
|
|
254
268
|
}
|
|
255
|
-
|
|
269
|
+
var _ = /* @__PURE__ */ new Set(["TS2339", "TS2551"]), k = /* @__PURE__ */ new Set([
|
|
270
|
+
..._,
|
|
271
|
+
"TS2304",
|
|
272
|
+
"TS2552",
|
|
273
|
+
"TS2448",
|
|
274
|
+
"TS2588",
|
|
275
|
+
"TS2531",
|
|
276
|
+
"TS2532",
|
|
277
|
+
"TS2533",
|
|
278
|
+
"TS18047",
|
|
279
|
+
"TS18048",
|
|
280
|
+
"TS18049",
|
|
281
|
+
"TS2349",
|
|
282
|
+
"TS2351",
|
|
283
|
+
"TS2721",
|
|
284
|
+
"TS2722",
|
|
285
|
+
"TS2723"
|
|
286
|
+
]), D = /on type '(never|\{\})'/;
|
|
287
|
+
function K(t) {
|
|
288
|
+
return void 0 === t || "TypeError" === t || "ReferenceError" === t;
|
|
289
|
+
}
|
|
290
|
+
async function R(t, e) {
|
|
291
|
+
try {
|
|
292
|
+
const n = "snippet" === await w(t) ? await T(t) : null;
|
|
293
|
+
if ("undefined" === e && !n?.expectsValue) return [];
|
|
294
|
+
const [{ ScriptCompiler: r }, { getScriptingDeclarations: s }] = await Promise.all([import("@sheetxl/scripting"), import("@sheetxl/sdk")]), { diagnostics: i } = await r.compile({
|
|
295
|
+
source: n?.source ?? t,
|
|
296
|
+
ambientTypes: await s(),
|
|
297
|
+
lenient: !0,
|
|
298
|
+
disableBundle: !0,
|
|
299
|
+
disableSourceMap: !0
|
|
300
|
+
}), o = "threw" === e ? k : _;
|
|
301
|
+
return i.filter((t) => "error" === t.severity && o.has(t.code) && !(_.has(t.code) && D.test(t.message))).map((t) => ({
|
|
302
|
+
...t,
|
|
303
|
+
start: n ? b(n, t.start) : t.start,
|
|
304
|
+
..."undefined" === e ? {
|
|
305
|
+
severity: "warning",
|
|
306
|
+
message: `${t.message} It reads as undefined.`
|
|
307
|
+
} : {}
|
|
308
|
+
}));
|
|
309
|
+
} catch {
|
|
310
|
+
return [];
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
async function I(t, e, n = "Runner timed out") {
|
|
256
314
|
if (!e || e <= 0) return t;
|
|
257
315
|
let r;
|
|
258
316
|
const s = new Promise((t, s) => r = setTimeout(() => s(new Error(n)), e));
|
|
@@ -262,31 +320,31 @@ async function b(t, e, n = "Runner timed out") {
|
|
|
262
320
|
clearTimeout(r);
|
|
263
321
|
}
|
|
264
322
|
}
|
|
265
|
-
var
|
|
266
|
-
function
|
|
267
|
-
return
|
|
323
|
+
var C = null;
|
|
324
|
+
function $() {
|
|
325
|
+
return C || (C = (async () => {
|
|
268
326
|
const { register: t } = await import("tsx/esm/api");
|
|
269
327
|
t({ tsconfig: !1 });
|
|
270
|
-
})()),
|
|
328
|
+
})()), C;
|
|
271
329
|
}
|
|
272
|
-
var
|
|
273
|
-
function
|
|
274
|
-
return
|
|
330
|
+
var L = "data:text/typescript,", M = "data:text/javascript,", W = null;
|
|
331
|
+
function P() {
|
|
332
|
+
return W || (W = (async () => {
|
|
275
333
|
const { registerHooks: e, stripTypeScriptTypes: r } = await import("node:module"), s = r;
|
|
276
334
|
e({
|
|
277
335
|
resolve(e, r, s) {
|
|
278
|
-
const
|
|
279
|
-
if (
|
|
280
|
-
const
|
|
336
|
+
const i = r.parentURL;
|
|
337
|
+
if (i && (i.startsWith(L) || i.startsWith(M))) {
|
|
338
|
+
const i = n(t.join(process.cwd(), "_inline_.ts")).href;
|
|
281
339
|
return s(e, {
|
|
282
340
|
...r,
|
|
283
|
-
parentURL:
|
|
341
|
+
parentURL: i
|
|
284
342
|
});
|
|
285
343
|
}
|
|
286
344
|
return s(e, r);
|
|
287
345
|
},
|
|
288
346
|
load(t, e, n) {
|
|
289
|
-
if (t.startsWith(
|
|
347
|
+
if (t.startsWith(L)) {
|
|
290
348
|
const e = decodeURIComponent(t.slice(21)), n = process.emitWarning;
|
|
291
349
|
let r;
|
|
292
350
|
process.emitWarning = () => {};
|
|
@@ -304,16 +362,16 @@ function $() {
|
|
|
304
362
|
return n(t, e);
|
|
305
363
|
}
|
|
306
364
|
});
|
|
307
|
-
})()),
|
|
365
|
+
})()), W;
|
|
308
366
|
}
|
|
309
|
-
async function
|
|
367
|
+
async function A(e) {
|
|
310
368
|
const r = "string" == typeof (s = e) ? s.startsWith("file:") ? s : n(t.resolve(process.cwd(), s)).href : s.href;
|
|
311
369
|
var s;
|
|
312
|
-
const
|
|
313
|
-
return ".ts" !==
|
|
370
|
+
const i = t.extname(new URL(r).pathname).toLowerCase();
|
|
371
|
+
return ".ts" !== i && ".tsx" !== i || await $(), import(r);
|
|
314
372
|
}
|
|
315
|
-
async function
|
|
316
|
-
const s = n.notifier ?? (await import("@sheetxl/sdk")).Notifier,
|
|
373
|
+
async function U(t, e, n) {
|
|
374
|
+
const s = n.notifier ?? (await import("@sheetxl/sdk")).Notifier, i = r({
|
|
317
375
|
debug: (t) => s.debug(t),
|
|
318
376
|
log: (t) => s.log(t),
|
|
319
377
|
info: (t) => s.log(t),
|
|
@@ -328,65 +386,68 @@ async function L(t, e, n) {
|
|
|
328
386
|
_: []
|
|
329
387
|
},
|
|
330
388
|
wb: t,
|
|
331
|
-
log:
|
|
332
|
-
warn:
|
|
333
|
-
error:
|
|
389
|
+
log: i.log,
|
|
390
|
+
warn: i.warn,
|
|
391
|
+
error: i.error
|
|
334
392
|
},
|
|
335
|
-
channels:
|
|
393
|
+
channels: i,
|
|
336
394
|
notifier: s
|
|
337
395
|
};
|
|
338
396
|
}
|
|
339
|
-
var
|
|
340
|
-
const
|
|
397
|
+
var j = async (n, r, i) => {
|
|
398
|
+
const o = i.target, a = Array.isArray(o) ? o : [o], c = await Promise.all(a.map((n) => (async (n, r = {}) => {
|
|
341
399
|
let s = null;
|
|
342
|
-
const
|
|
400
|
+
const i = (t, e) => {
|
|
343
401
|
let n = t?.default;
|
|
344
402
|
if (n && "function" != typeof n && "function" == typeof n.default && (n = n.default), "function" != typeof n) throw new Error(`Script '${e}' has no runnable entry: export a default function, e.g. \`export default function main(ctx) { … }\`.`);
|
|
345
403
|
return n;
|
|
346
404
|
};
|
|
347
405
|
if ("function" == typeof n) s = n;
|
|
348
406
|
else if ("string" == typeof n || n instanceof URL) {
|
|
349
|
-
let
|
|
350
|
-
if ("string" != typeof n || /^[a-z]+:\/\//i.test(n))
|
|
407
|
+
let o = null;
|
|
408
|
+
if ("string" != typeof n || /^[a-z]+:\/\//i.test(n)) o = await A(n);
|
|
351
409
|
else {
|
|
352
410
|
const s = t.resolve(r.cwd ?? process.cwd(), n);
|
|
353
411
|
if (!e.existsSync(s)) throw new Error(`Script not found: ${s}`);
|
|
354
|
-
e.accessSync(s, e.constants.R_OK),
|
|
412
|
+
e.accessSync(s, e.constants.R_OK), o = await A(s);
|
|
355
413
|
}
|
|
356
|
-
s = o
|
|
414
|
+
s = i(o, String(n));
|
|
357
415
|
} else if ("code" in n) {
|
|
358
416
|
const t = n.filename ?? "inline.ts";
|
|
359
417
|
let e, r = null;
|
|
360
|
-
t.endsWith(".ts") || t.endsWith(".tsx") ? (await
|
|
418
|
+
t.endsWith(".ts") || t.endsWith(".tsx") ? (await $(), await P(), e = `${L}${encodeURIComponent(n.code)}`, r = await import(e)) : (await P(), e = `${M}${encodeURIComponent(n.code)}`, r = await import(e)), s = i(r, t);
|
|
361
419
|
} else {
|
|
362
420
|
if (!("runner" in n)) throw new Error("Invalid run target specified.");
|
|
363
421
|
s = n.runner;
|
|
364
422
|
}
|
|
365
423
|
return s;
|
|
366
|
-
})(n,
|
|
367
|
-
let u, p = n,
|
|
368
|
-
const
|
|
369
|
-
for (let t = 0; t <
|
|
370
|
-
const e = c[t], { ctx: n, channels:
|
|
371
|
-
|
|
424
|
+
})(n, i))), l = Date.now();
|
|
425
|
+
let u, p = n, d = null;
|
|
426
|
+
const f = c.length;
|
|
427
|
+
for (let t = 0; t < f; t++) {
|
|
428
|
+
const e = c[t], { ctx: n, channels: o, notifier: a } = await U(p, r, i);
|
|
429
|
+
d = a;
|
|
372
430
|
const l = Date.now();
|
|
373
431
|
let m;
|
|
374
|
-
const h = p,
|
|
432
|
+
const h = p, g = (t) => Promise.resolve().then(() => e(t));
|
|
375
433
|
try {
|
|
376
|
-
m = await
|
|
434
|
+
m = await I(null !== h ? Promise.resolve(h.doBatch((t, e) => g({
|
|
435
|
+
...n,
|
|
436
|
+
wb: e
|
|
437
|
+
}), "Run Script")) : g(n), i.timeoutMs, "Runner timed out");
|
|
377
438
|
} finally {
|
|
378
|
-
await
|
|
439
|
+
await o.flush({ timeoutMs: s(i.logTimeoutMs) });
|
|
379
440
|
}
|
|
380
|
-
const
|
|
381
|
-
u = m, null != m && m.isIWorkbook && (p = m), a.debug(`Run ${1 ===
|
|
441
|
+
const y = Date.now();
|
|
442
|
+
u = m, null != m && m.isIWorkbook && (p = m), a.debug(`Run ${1 === f ? "" : `${t + 1}/${f} `}completed in ${y - l} ms.`);
|
|
382
443
|
}
|
|
383
|
-
if (
|
|
444
|
+
if (f > 1 && d) {
|
|
384
445
|
const t = Date.now();
|
|
385
|
-
|
|
446
|
+
d.debug(`All runs completed in ${t - l} ms.`);
|
|
386
447
|
}
|
|
387
448
|
return u;
|
|
388
|
-
},
|
|
449
|
+
}, O = { run: async (t, e, n) => {
|
|
389
450
|
const { withScriptRuntime: r } = await import("@sheetxl/sdk");
|
|
390
|
-
return r(() =>
|
|
451
|
+
return r(() => j(t, e, n));
|
|
391
452
|
} };
|
|
392
|
-
export { a as Snippet,
|
|
453
|
+
export { a as Snippet, O as default, R as diagnoseRun, K as isExplainable, o as resolvePath };
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sheetxl/runner",
|
|
3
3
|
"description": "SheetXL - Programmatic execution for SheetXL scripts",
|
|
4
|
-
"version": "0.8.0-beta.
|
|
5
|
-
"license": "
|
|
4
|
+
"version": "0.8.0-beta.21",
|
|
5
|
+
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"exports": {
|
|
8
8
|
".": {
|
|
@@ -36,18 +36,23 @@
|
|
|
36
36
|
"runner"
|
|
37
37
|
],
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@sheetxl/io": "^0.8.0-beta.
|
|
40
|
-
"@sheetxl/primitives": "^0.8.0-beta.
|
|
41
|
-
"@sheetxl/scripting": "^0.8.0-beta.
|
|
42
|
-
"@sheetxl/sdk": "^0.8.0-beta.
|
|
43
|
-
"@sheetxl/utils": "^0.8.0-beta.
|
|
39
|
+
"@sheetxl/io": "^0.8.0-beta.21",
|
|
40
|
+
"@sheetxl/primitives": "^0.8.0-beta.21",
|
|
41
|
+
"@sheetxl/scripting": "^0.8.0-beta.21",
|
|
42
|
+
"@sheetxl/sdk": "^0.8.0-beta.21",
|
|
43
|
+
"@sheetxl/utils": "^0.8.0-beta.21",
|
|
44
|
+
"tsx": "^4.23.15"
|
|
44
45
|
},
|
|
45
46
|
"peerDependencies": {
|
|
46
47
|
"typescript": "^5.9.0 || ^6.0.0"
|
|
47
48
|
},
|
|
49
|
+
"peerDependenciesMeta": {
|
|
50
|
+
"typescript": {
|
|
51
|
+
"optional": true
|
|
52
|
+
}
|
|
53
|
+
},
|
|
48
54
|
"devDependencies": {
|
|
49
|
-
"@types/node": "^26.
|
|
50
|
-
"tsx": "^4.23.1",
|
|
55
|
+
"@types/node": "^26.6.4",
|
|
51
56
|
"typescript": "^5.9.0 || ^6.0.0"
|
|
52
57
|
}
|
|
53
58
|
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { Diagnostic } from '@sheetxl/scripting';
|
|
2
|
+
/**
|
|
3
|
+
* What a run did that a type check may explain: it threw, or a snippet's final expression came
|
|
4
|
+
* back `undefined`.
|
|
5
|
+
*
|
|
6
|
+
* @remarks
|
|
7
|
+
* `undefined` is a symptom because the SheetXL API never returns it - `null` is the empty answer.
|
|
8
|
+
* A read that produced `undefined` read something that is not there.
|
|
9
|
+
*/
|
|
10
|
+
export type RunSymptom = 'threw' | 'undefined';
|
|
11
|
+
/**
|
|
12
|
+
* Whether a failure is one a type check can explain, by the error's `name`. A failure with no
|
|
13
|
+
* name (a thrown string, an error that crossed a wire as its message) is checked too.
|
|
14
|
+
*/
|
|
15
|
+
export declare function isExplainable(errorName: string | undefined): boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Type-checks the source of a run that has already gone wrong, and returns the findings that can
|
|
18
|
+
* explain it.
|
|
19
|
+
*
|
|
20
|
+
* @remarks
|
|
21
|
+
* A run is never type-checked before it executes: the types are for discovery, not enforcement,
|
|
22
|
+
* and most of what a strict check reports about code written to run once (an unannotated `[]`,
|
|
23
|
+
* `catch (e)`, a field added to `{}`) runs correctly. A failed run leaves nothing behind, so
|
|
24
|
+
* running first costs nothing, and the check is paid only by a run with a symptom.
|
|
25
|
+
*
|
|
26
|
+
* The one implementation behind `sheetxl -e` and the MCP `run` tool, so both answer alike.
|
|
27
|
+
*
|
|
28
|
+
* Positions are in `source` as given - a snippet is checked in its wrapper and mapped back.
|
|
29
|
+
* A `threw` finding is an error; an `undefined` one is a warning, as the run completed.
|
|
30
|
+
* Never throws: a diagnosis that fails must not replace the failure it was diagnosing.
|
|
31
|
+
*/
|
|
32
|
+
export declare function diagnoseRun(source: string, symptom: RunSymptom): Promise<Diagnostic[]>;
|
|
33
|
+
//# sourceMappingURL=RunDiagnosis.d.ts.map
|
package/types/src/Snippet.d.ts
CHANGED
|
@@ -83,6 +83,12 @@ export interface Prepared {
|
|
|
83
83
|
lineOffset: number;
|
|
84
84
|
/** Where the author's text sits within {@link source}, in source order. */
|
|
85
85
|
spans: Span[];
|
|
86
|
+
/**
|
|
87
|
+
* Whether the snippet ends in an expression whose value is its answer — not a statement, not a
|
|
88
|
+
* call to `log`/`warn`/`error`, and not an entry function, which may return nothing as a script
|
|
89
|
+
* may. Such a snippet answering `undefined` read something that is not there.
|
|
90
|
+
*/
|
|
91
|
+
expectsValue: boolean;
|
|
86
92
|
/**
|
|
87
93
|
* Set only when the contract could not be honored — no implicit await, no result. Callers should
|
|
88
94
|
* surface it; a snippet quietly returning `undefined` is worse than one that failed.
|