@markii/lua 0.17.0-next.0 → 0.17.0-next.2
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/globals.d.ts +28 -14
- package/dist/globals.js +32 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/require.d.ts +3 -3
- package/dist/require.js +1 -1
- package/dist/sandbox.d.ts +7 -8
- package/dist/sandbox.js +9 -2
- package/package.json +3 -3
package/dist/globals.d.ts
CHANGED
|
@@ -6,23 +6,37 @@ export declare const DENIED_GLOBALS: readonly string[];
|
|
|
6
6
|
export interface CreateEmptyLuaEngineOptions {
|
|
7
7
|
/**
|
|
8
8
|
* Forwarded verbatim as wasmoon's `LuaFactory` first constructor argument
|
|
9
|
-
* (`customWasmUri`
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
* `
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
* avoid it (e.g. the playground, via a Vite `?url` asset import so the
|
|
19
|
-
* wasm ships in its own bundle) passes its own local URL here instead.
|
|
20
|
-
* Passing `undefined` is IDENTICAL to omitting this options object
|
|
21
|
-
* entirely — this parameter only ever narrows behavior, never changes it
|
|
22
|
-
* by default.
|
|
9
|
+
* (`customWasmUri`). In Node, leaving it `undefined` keeps wasmoon's own
|
|
10
|
+
* resolution of the local `node_modules/wasmoon/dist/glue.wasm`. Outside
|
|
11
|
+
* Node it is REQUIRED: wasmoon's browser default is a runtime fetch from
|
|
12
|
+
* `https://unpkg.com/...`, and this package never lets that happen
|
|
13
|
+
* silently. With no `wasmUri` outside Node, engine creation throws a
|
|
14
|
+
* `MissingWasmUriError` before wasmoon is touched (`runScript` turns it
|
|
15
|
+
* into a labeled `runtime` failure). A browser host ships its own copy of
|
|
16
|
+
* `glue.wasm` (for example via a bundler `?url` import) and passes that
|
|
17
|
+
* URL here.
|
|
23
18
|
*/
|
|
24
19
|
wasmUri?: string;
|
|
20
|
+
/**
|
|
21
|
+
* Test seam: overrides the Node detection (`isNodeEnvironment`). Leave
|
|
22
|
+
* unset in production.
|
|
23
|
+
*/
|
|
24
|
+
isNode?: boolean;
|
|
25
|
+
}
|
|
26
|
+
/** Message shared by the thrown error and the `runScript` failure. */
|
|
27
|
+
export declare const MISSING_WASM_URI_MESSAGE = "the Lua engine needs its WebAssembly file but this host did not pass `wasmUri`; the host must pass `wasmUri` (a URL to wasmoon glue.wasm) when running outside Node";
|
|
28
|
+
/** Thrown by `createEmptyLuaEngine` when no `wasmUri` is given outside Node. */
|
|
29
|
+
export declare class MissingWasmUriError extends Error {
|
|
30
|
+
constructor();
|
|
25
31
|
}
|
|
32
|
+
/**
|
|
33
|
+
* True only when running under Node. Guarded so a browser, worker, or any
|
|
34
|
+
* other environment without a real `process.versions.node` counts as "not
|
|
35
|
+
* Node".
|
|
36
|
+
*/
|
|
37
|
+
export declare function isNodeEnvironment(): boolean;
|
|
38
|
+
/** True when a run with these options must be refused for want of `wasmUri`. */
|
|
39
|
+
export declare function needsWasmUri(options?: CreateEmptyLuaEngineOptions): boolean;
|
|
26
40
|
/**
|
|
27
41
|
* Creates a fresh wasmoon engine with the curated, empty environment
|
|
28
42
|
* described above. `traceAllocations: true` is required for the memory cap
|
package/dist/globals.js
CHANGED
|
@@ -280,6 +280,36 @@ export const DENIED_GLOBALS = [
|
|
|
280
280
|
'_G',
|
|
281
281
|
'_VERSION',
|
|
282
282
|
];
|
|
283
|
+
/** Message shared by the thrown error and the `runScript` failure. */
|
|
284
|
+
export const MISSING_WASM_URI_MESSAGE = 'the Lua engine needs its WebAssembly file but this host did not pass `wasmUri`; the host must pass `wasmUri` (a URL to wasmoon glue.wasm) when running outside Node';
|
|
285
|
+
/** Thrown by `createEmptyLuaEngine` when no `wasmUri` is given outside Node. */
|
|
286
|
+
export class MissingWasmUriError extends Error {
|
|
287
|
+
constructor() {
|
|
288
|
+
super(MISSING_WASM_URI_MESSAGE);
|
|
289
|
+
this.name = 'MissingWasmUriError';
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
/**
|
|
293
|
+
* True only when running under Node. Guarded so a browser, worker, or any
|
|
294
|
+
* other environment without a real `process.versions.node` counts as "not
|
|
295
|
+
* Node".
|
|
296
|
+
*/
|
|
297
|
+
export function isNodeEnvironment() {
|
|
298
|
+
try {
|
|
299
|
+
const proc = globalThis
|
|
300
|
+
.process;
|
|
301
|
+
return typeof proc?.versions?.node === 'string';
|
|
302
|
+
}
|
|
303
|
+
catch {
|
|
304
|
+
return false;
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
/** True when a run with these options must be refused for want of `wasmUri`. */
|
|
308
|
+
export function needsWasmUri(options) {
|
|
309
|
+
if (options?.wasmUri !== undefined)
|
|
310
|
+
return false;
|
|
311
|
+
return !(options?.isNode ?? isNodeEnvironment());
|
|
312
|
+
}
|
|
283
313
|
/**
|
|
284
314
|
* Creates a fresh wasmoon engine with the curated, empty environment
|
|
285
315
|
* described above. `traceAllocations: true` is required for the memory cap
|
|
@@ -297,6 +327,8 @@ export const DENIED_GLOBALS = [
|
|
|
297
327
|
* the only supported way to execute a note's script.
|
|
298
328
|
*/
|
|
299
329
|
export async function createEmptyLuaEngine(options) {
|
|
330
|
+
if (needsWasmUri(options))
|
|
331
|
+
throw new MissingWasmUriError();
|
|
300
332
|
const factory = new LuaFactory(options?.wasmUri);
|
|
301
333
|
const engine = await factory.createEngine({
|
|
302
334
|
openStandardLibs: false,
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export type { ScriptFailure, ScriptLimitKind, ScriptMarshalReason, } from './errors.js';
|
|
2
2
|
export { CAPABILITY_ERROR_TAG, FETCH_DECODE_ERROR_TAG, MARSHAL_ERROR_TAG, ScriptLimitError, } from './errors.js';
|
|
3
3
|
export type { CreateEmptyLuaEngineOptions } from './globals.js';
|
|
4
|
-
export { ALLOWED_GLOBALS, DENIED_GLOBALS, createEmptyLuaEngine, } from './globals.js';
|
|
4
|
+
export { ALLOWED_GLOBALS, DENIED_GLOBALS, MISSING_WASM_URI_MESSAGE, MissingWasmUriError, createEmptyLuaEngine, isNodeEnvironment, } from './globals.js';
|
|
5
5
|
export type { LimitHandle, ScriptLimits } from './limits.js';
|
|
6
6
|
export { DEFAULT_LIMITS, installLimits } from './limits.js';
|
|
7
7
|
export type { CacheEntry, CacheProvider, CapabilityConfig, CapabilityDenial, CapabilityDenials, CapabilityTier, NetGrants, NetProvider, NetResponse, } from './capabilities.js';
|
package/dist/index.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
// import rule and the ESLint guard in the root config. May depend on
|
|
5
5
|
// @markii/bundle for the `ScriptView` capability type only.
|
|
6
6
|
export { CAPABILITY_ERROR_TAG, FETCH_DECODE_ERROR_TAG, MARSHAL_ERROR_TAG, ScriptLimitError, } from './errors.js';
|
|
7
|
-
export { ALLOWED_GLOBALS, DENIED_GLOBALS, createEmptyLuaEngine, } from './globals.js';
|
|
7
|
+
export { ALLOWED_GLOBALS, DENIED_GLOBALS, MISSING_WASM_URI_MESSAGE, MissingWasmUriError, createEmptyLuaEngine, isNodeEnvironment, } from './globals.js';
|
|
8
8
|
export { DEFAULT_LIMITS, installLimits } from './limits.js';
|
|
9
9
|
export { DEFAULT_MAX_FETCH_BYTES, bytesToLuaString, buildCapabilities, isNetProviderDenial, luaStringToBytes, netProviderDenial, } from './capabilities.js';
|
|
10
10
|
export { buildDoc } from './doc.js';
|
package/dist/require.d.ts
CHANGED
|
@@ -86,12 +86,12 @@ import type { ScriptView } from '@markii/bundle';
|
|
|
86
86
|
* `./limits`' out-of-band JS flag regardless of what any Lua-level
|
|
87
87
|
* `pcall` around it reports.
|
|
88
88
|
*/
|
|
89
|
-
/** A pack-namespaced `require "packName/modulePath"` resolver, injected by a host that has actually wired up pack installation. Returns pure Lua SOURCE TEXT, or `undefined` if this pack/module isn't available — never throws for a routine "not found". */
|
|
90
|
-
export type PackModuleResolver = (packName: string, modulePath: string) => string | undefined
|
|
89
|
+
/** A pack-namespaced `require "packName/modulePath"` resolver, injected by a host that has actually wired up pack installation. Returns pure Lua SOURCE TEXT, or `undefined` if this pack/module isn't available — never throws for a routine "not found". May be synchronous or return a promise; a rejection fails the require like a sync throw, and a promise that never settles is bounded by the run's wall-clock guard. */
|
|
90
|
+
export type PackModuleResolver = (packName: string, modulePath: string) => string | undefined | Promise<string | undefined>;
|
|
91
91
|
export interface RequireConfig {
|
|
92
92
|
/** The SAME `ScriptView` `./capabilities` wires up for `bundle.read`/`bundle.write` — reused, never re-implemented, so bundle-local `require` is subject to the identical path-jail and read-permission check. */
|
|
93
93
|
bundle?: ScriptView;
|
|
94
|
-
/** Optional pack-module seam — see the module doc comment. Absent (
|
|
94
|
+
/** Optional pack-module seam — see the module doc comment. Absent (a host that has not wired pack modules) means every pack-namespaced `require` fails as a clean capability denial. */
|
|
95
95
|
packModuleResolver?: PackModuleResolver;
|
|
96
96
|
/**
|
|
97
97
|
* Records a genuine denial onto the SAME per-run `CapabilityDenials`
|
package/dist/require.js
CHANGED
|
@@ -96,7 +96,7 @@ export function buildRequire(config) {
|
|
|
96
96
|
const segIdx = name.indexOf('/');
|
|
97
97
|
const packName = segIdx === -1 ? name : name.slice(0, segIdx);
|
|
98
98
|
const modulePath = segIdx === -1 ? '' : name.slice(segIdx + 1);
|
|
99
|
-
const resolved = resolver(packName, modulePath);
|
|
99
|
+
const resolved = await resolver(packName, modulePath);
|
|
100
100
|
if (resolved === undefined) {
|
|
101
101
|
throw new Error(`require: no pack module "${modulePath}" in pack "${packName}"`);
|
|
102
102
|
}
|
package/dist/sandbox.d.ts
CHANGED
|
@@ -28,16 +28,15 @@ export interface RunScriptOptions {
|
|
|
28
28
|
limits?: Partial<ScriptLimits>;
|
|
29
29
|
marshalLimits?: Partial<MarshalLimits>;
|
|
30
30
|
/**
|
|
31
|
-
* Forwarded to `./globals`' `createEmptyLuaEngine` as its
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
* copy of wasmoon's `glue.wasm` (e.g. the playground, to avoid a runtime
|
|
37
|
-
* dependency on the unpkg CDN) passes that local URL here instead — see
|
|
38
|
-
* `createEmptyLuaEngine`'s doc comment for the full rationale.
|
|
31
|
+
* Forwarded to `./globals`' `createEmptyLuaEngine` as its `wasmUri`
|
|
32
|
+
* option (wasmoon's `customWasmUri`). In Node it may be omitted (local
|
|
33
|
+
* `node_modules` resolution). Outside Node it is required: a run without
|
|
34
|
+
* it fails before any engine is created, as a `runtime` failure saying
|
|
35
|
+
* the host must pass `wasmUri`. There is no silent CDN fetch.
|
|
39
36
|
*/
|
|
40
37
|
wasmUri?: string;
|
|
38
|
+
/** Test seam: overrides the Node detection. Leave unset in production. */
|
|
39
|
+
isNode?: boolean;
|
|
41
40
|
}
|
|
42
41
|
export type RunScriptResult = {
|
|
43
42
|
ok: true;
|
package/dist/sandbox.js
CHANGED
|
@@ -2,7 +2,7 @@ import { LuaReturn } from 'wasmoon';
|
|
|
2
2
|
import { buildCapabilities, DEFAULT_MAX_FETCH_BYTES, } from './capabilities.js';
|
|
3
3
|
import { buildDoc } from './doc.js';
|
|
4
4
|
import { MARSHAL_ERROR_TAG, ScriptLimitError } from './errors.js';
|
|
5
|
-
import { createEmptyLuaEngine } from './globals.js';
|
|
5
|
+
import { createEmptyLuaEngine, MISSING_WASM_URI_MESSAGE, needsWasmUri, } from './globals.js';
|
|
6
6
|
import { buildJsonTable } from './json-table.js';
|
|
7
7
|
import { DEFAULT_LIMITS, installLimits } from './limits.js';
|
|
8
8
|
import { buildMarshalPrelude, DEFAULT_MARSHAL_LIMITS, finalizeMarshaledValue, wrapUserCode, } from './marshal.js';
|
|
@@ -224,7 +224,14 @@ export async function runScript(options) {
|
|
|
224
224
|
...DEFAULT_MARSHAL_LIMITS,
|
|
225
225
|
...options.marshalLimits,
|
|
226
226
|
};
|
|
227
|
-
const
|
|
227
|
+
const engineOptions = { wasmUri: options.wasmUri, isNode: options.isNode };
|
|
228
|
+
if (needsWasmUri(engineOptions)) {
|
|
229
|
+
return {
|
|
230
|
+
ok: false,
|
|
231
|
+
error: { kind: 'runtime', message: MISSING_WASM_URI_MESSAGE },
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
const engine = await createEmptyLuaEngine(engineOptions);
|
|
228
235
|
engine.global.setMemoryMax(limits.maxMemoryBytes);
|
|
229
236
|
let thread;
|
|
230
237
|
let threadStackIndex;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@markii/lua",
|
|
3
|
-
"version": "0.17.0-next.
|
|
3
|
+
"version": "0.17.0-next.2",
|
|
4
4
|
"description": "Sandboxed Lua 5.4 (wasmoon) execution runtime for Mark's document scripting: an empty-env global whitelist, two-tier capability-gated net/cache/bundle access, instruction-count/wall-clock/memory limits, and depth/size-capped Lua<->JS marshaling.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"markdown",
|
|
@@ -44,8 +44,8 @@
|
|
|
44
44
|
"lint": "eslint ."
|
|
45
45
|
},
|
|
46
46
|
"dependencies": {
|
|
47
|
-
"@markii/bundle": "^0.17.0-next.
|
|
48
|
-
"@markii/runtime": "^0.17.0-next.
|
|
47
|
+
"@markii/bundle": "^0.17.0-next.2",
|
|
48
|
+
"@markii/runtime": "^0.17.0-next.2",
|
|
49
49
|
"wasmoon": "^1.16.0"
|
|
50
50
|
}
|
|
51
51
|
}
|