@poe-platform/safe-js 0.1.83 → 0.1.85
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/README.md +1 -1
- package/dist/safe-js/chunks/{chunk-BL5U2VOU.js → chunk-LWIWUCBZ.js} +2 -2
- package/dist/safe-js/chunks/{chunk-CSC4EXIV.js → chunk-TNPFJ4XS.js} +173 -135
- package/dist/safe-js/chunks/{chunk-CSC4EXIV.js.map → chunk-TNPFJ4XS.js.map} +3 -3
- package/dist/safe-js/cli.js +2 -2
- package/dist/safe-js/core.js +1 -1
- package/dist/safe-js/index.js +2 -2
- package/package.json +2 -2
- /package/dist/safe-js/chunks/{chunk-BL5U2VOU.js.map → chunk-LWIWUCBZ.js.map} +0 -0
package/README.md
CHANGED
|
@@ -444,7 +444,7 @@ For embedding, `runCli(argv, options?)` comes from `@poe-platform/safe-js/cli`.
|
|
|
444
444
|
## Meaningful limitations
|
|
445
445
|
|
|
446
446
|
- **Not a full JavaScript engine.** No user-defined classes, async generators, dynamic imports, or automatic multi-file/npm resolution. No browser build, DOM, general Node API, `eval`, or `Function` constructor. Ordinary guest constructor prototypes are supported, but native and exotic prototype chains are not. Built-in coverage is selective; lint success is not a runtime compatibility guarantee.
|
|
447
|
-
- **Some familiar syntax differs.**
|
|
447
|
+
- **Some familiar syntax differs.** Regex supports `g`, `i`, `m`, and `s`, but not lookaround, backreferences, named groups, Unicode property escapes, or other flags. Compilation and matching have fixed limits in addition to configured budgets.
|
|
448
448
|
- **Budgets are not hard resource isolation.** Limits govern interpreter work, not arbitrary host functions or total process memory. Deadlines are checked cooperatively; cancellation cannot forcibly stop a blocking host call or undo its effects. Add host-operation timeouts and external isolation where required.
|
|
449
449
|
- **Recovery is not exactly-once delivery.** Replay can repeat work and consumes budget again. Pending side effects need external reconciliation; opaque host handles and native iterator frames are not portable checkpoint state. Keep compatible source for ordinary restore or explicitly migrate. Checkpoints can contain input data and host results: store them as sensitive data.
|
|
450
450
|
- **Filesystem access is a grant, not an OS sandbox.** The helper is a subset of `node:fs/promises`, with text-oriented results and no file handles, streams, or Buffer API. Root checks do not isolate the process from concurrent filesystem changes. Prefer narrow host operations when a script only needs a few files.
|
|
@@ -27,7 +27,7 @@ import {
|
|
|
27
27
|
validateMigrationSemantics,
|
|
28
28
|
validateSnapshotData,
|
|
29
29
|
validateSnapshotMigration
|
|
30
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-TNPFJ4XS.js";
|
|
31
31
|
|
|
32
32
|
// packages/safe-js/src/migrate.ts
|
|
33
33
|
import { createHash } from "node:crypto";
|
|
@@ -8245,4 +8245,4 @@ export {
|
|
|
8245
8245
|
parseMcpConfig,
|
|
8246
8246
|
makeMcpModule
|
|
8247
8247
|
};
|
|
8248
|
-
//# sourceMappingURL=chunk-
|
|
8248
|
+
//# sourceMappingURL=chunk-LWIWUCBZ.js.map
|
|
@@ -25081,6 +25081,134 @@ function isObjectLike(value) {
|
|
|
25081
25081
|
return typeof value === "object" && value !== null;
|
|
25082
25082
|
}
|
|
25083
25083
|
|
|
25084
|
+
// packages/safe-js/src/interp/globals/object.ts
|
|
25085
|
+
function createObjectGlobal(methods, budget) {
|
|
25086
|
+
const construct = ([value]) => {
|
|
25087
|
+
if (value === null || value === void 0) {
|
|
25088
|
+
budget.chargeDataUsage(1);
|
|
25089
|
+
return /* @__PURE__ */ Object.create(null);
|
|
25090
|
+
}
|
|
25091
|
+
if (typeof value !== "object") throw new TypeError("Object primitive boxing is not supported.");
|
|
25092
|
+
return value;
|
|
25093
|
+
};
|
|
25094
|
+
const constructor = createSandboxClosure({
|
|
25095
|
+
guest: true,
|
|
25096
|
+
sandbox: true,
|
|
25097
|
+
name: "Object",
|
|
25098
|
+
length: 1,
|
|
25099
|
+
call: construct,
|
|
25100
|
+
construct
|
|
25101
|
+
});
|
|
25102
|
+
const properties = materializeFunctionProperties(constructor);
|
|
25103
|
+
const prototype = properties.prototype;
|
|
25104
|
+
Object.defineProperty(properties, "prototype", { writable: false });
|
|
25105
|
+
for (const [name, method] of Object.entries(methods)) {
|
|
25106
|
+
Object.defineProperty(properties, name, { value: method, writable: true, configurable: true });
|
|
25107
|
+
}
|
|
25108
|
+
const prototypeMethods = {
|
|
25109
|
+
toString: createSandboxClosure({
|
|
25110
|
+
sandbox: true,
|
|
25111
|
+
name: "toString",
|
|
25112
|
+
length: 0,
|
|
25113
|
+
call: (_args, context) => budget.allocateString(`[object ${typeTag(context?.thisValue)}]`)
|
|
25114
|
+
}),
|
|
25115
|
+
valueOf: createSandboxClosure({
|
|
25116
|
+
sandbox: true,
|
|
25117
|
+
name: "valueOf",
|
|
25118
|
+
length: 0,
|
|
25119
|
+
call: (_args, context) => {
|
|
25120
|
+
const value = requireReceiver(context?.thisValue);
|
|
25121
|
+
if (typeof value !== "object")
|
|
25122
|
+
throw new TypeError("Object primitive boxing is not supported.");
|
|
25123
|
+
return value;
|
|
25124
|
+
}
|
|
25125
|
+
}),
|
|
25126
|
+
hasOwnProperty: createSandboxClosure({
|
|
25127
|
+
sandbox: true,
|
|
25128
|
+
name: "hasOwnProperty",
|
|
25129
|
+
length: 1,
|
|
25130
|
+
call: async ([key], context) => hasOwnSandboxProperty(
|
|
25131
|
+
requireReceiver(context?.thisValue),
|
|
25132
|
+
await sandboxString(key, budget, context),
|
|
25133
|
+
false
|
|
25134
|
+
)
|
|
25135
|
+
}),
|
|
25136
|
+
propertyIsEnumerable: createSandboxClosure({
|
|
25137
|
+
sandbox: true,
|
|
25138
|
+
name: "propertyIsEnumerable",
|
|
25139
|
+
length: 1,
|
|
25140
|
+
call: async ([key], context) => hasOwnSandboxProperty(
|
|
25141
|
+
requireReceiver(context?.thisValue),
|
|
25142
|
+
await sandboxString(key, budget, context),
|
|
25143
|
+
true
|
|
25144
|
+
)
|
|
25145
|
+
}),
|
|
25146
|
+
isPrototypeOf: createSandboxClosure({
|
|
25147
|
+
sandbox: true,
|
|
25148
|
+
name: "isPrototypeOf",
|
|
25149
|
+
length: 1,
|
|
25150
|
+
call: ([value], context) => {
|
|
25151
|
+
if (typeof value !== "object" || value === null) return false;
|
|
25152
|
+
const receiver = requireReceiver(context?.thisValue);
|
|
25153
|
+
let depth = 0;
|
|
25154
|
+
for (let current = getSandboxPrototype(value, budget); current !== null; current = getSandboxPrototype(current, budget)) {
|
|
25155
|
+
budget.visitNode();
|
|
25156
|
+
assertSandboxDataDepth(depth++);
|
|
25157
|
+
if (current === receiver) return true;
|
|
25158
|
+
}
|
|
25159
|
+
return false;
|
|
25160
|
+
}
|
|
25161
|
+
})
|
|
25162
|
+
};
|
|
25163
|
+
for (const [name, method] of Object.entries(prototypeMethods)) {
|
|
25164
|
+
Object.defineProperty(prototype, name, { value: method, writable: true, configurable: true });
|
|
25165
|
+
}
|
|
25166
|
+
markDescriptorObject(prototype);
|
|
25167
|
+
installObjectPrototype(budget, prototype, constructor);
|
|
25168
|
+
return constructor;
|
|
25169
|
+
}
|
|
25170
|
+
function requireReceiver(value) {
|
|
25171
|
+
if (value === null || value === void 0)
|
|
25172
|
+
throw new TypeError("Object method requires a non-null receiver.");
|
|
25173
|
+
return value;
|
|
25174
|
+
}
|
|
25175
|
+
function hasOwnSandboxProperty(value, key, enumerable) {
|
|
25176
|
+
requireReceiver(value);
|
|
25177
|
+
if (isGuestHostObject(value)) return hasHostObjectMember(value, key, enumerable);
|
|
25178
|
+
let properties;
|
|
25179
|
+
if (isGuestClosure(value)) properties = materializeFunctionProperties(value);
|
|
25180
|
+
else if (isSandboxClosure(value)) {
|
|
25181
|
+
if (key === "length" || key === "name") return !enumerable;
|
|
25182
|
+
properties = value.properties ?? /* @__PURE__ */ Object.create(null);
|
|
25183
|
+
} else if (isSandboxMap(value) || isSandboxSet(value) || isSandboxPromise(value) || isSandboxGenerator(value))
|
|
25184
|
+
return false;
|
|
25185
|
+
else if (isSandboxRegex(value)) return key === "lastIndex" && !enumerable;
|
|
25186
|
+
else properties = Object(value);
|
|
25187
|
+
const descriptor = Object.getOwnPropertyDescriptor(properties, key);
|
|
25188
|
+
return descriptor !== void 0 && (!enumerable || descriptor.enumerable === true);
|
|
25189
|
+
}
|
|
25190
|
+
function typeTag(value) {
|
|
25191
|
+
if (value === void 0) return "Undefined";
|
|
25192
|
+
if (value === null) return "Null";
|
|
25193
|
+
if (typeof value === "string") return "String";
|
|
25194
|
+
if (typeof value === "number") return "Number";
|
|
25195
|
+
if (typeof value === "boolean") return "Boolean";
|
|
25196
|
+
if (isSandboxClosure(value)) {
|
|
25197
|
+
while (value.boundTarget !== void 0) value = value.boundTarget;
|
|
25198
|
+
return value.generator ? "GeneratorFunction" : value.async ? "AsyncFunction" : "Function";
|
|
25199
|
+
}
|
|
25200
|
+
if (Array.isArray(value)) return "Array";
|
|
25201
|
+
if (isSandboxDate(value)) return "Date";
|
|
25202
|
+
if (isSandboxErrorConstructorInstance(value, "Error")) return "Error";
|
|
25203
|
+
if (isSandboxRegex(value)) return "RegExp";
|
|
25204
|
+
if (isSandboxMap(value)) return "Map";
|
|
25205
|
+
if (isSandboxSet(value)) return "Set";
|
|
25206
|
+
if (isSandboxPromise(value)) return "Promise";
|
|
25207
|
+
if (isSandboxGenerator(value)) return "Generator";
|
|
25208
|
+
if (isFloat32Array(value)) return "Float32Array";
|
|
25209
|
+
return "Object";
|
|
25210
|
+
}
|
|
25211
|
+
|
|
25084
25212
|
// packages/safe-js/src/interp/globals/collections.ts
|
|
25085
25213
|
var mapConstructors = /* @__PURE__ */ new WeakSet();
|
|
25086
25214
|
var setConstructors = /* @__PURE__ */ new WeakSet();
|
|
@@ -26083,11 +26211,14 @@ async function evaluateBinaryExpression(node, context) {
|
|
|
26083
26211
|
if (right.kind !== "normal") {
|
|
26084
26212
|
return right;
|
|
26085
26213
|
}
|
|
26086
|
-
|
|
26087
|
-
|
|
26088
|
-
|
|
26089
|
-
|
|
26090
|
-
|
|
26214
|
+
let leftValue = left.value;
|
|
26215
|
+
if (node.operator === "in") {
|
|
26216
|
+
if (typeof right.value !== "object" || right.value === null) {
|
|
26217
|
+
throw new TypeError("Right-hand side of 'in' must be an object.");
|
|
26218
|
+
}
|
|
26219
|
+
leftValue = await toPropertyKey(leftValue, context);
|
|
26220
|
+
}
|
|
26221
|
+
const value = applyBinaryOperator(node, leftValue, right.value, context);
|
|
26091
26222
|
return {
|
|
26092
26223
|
kind: "normal",
|
|
26093
26224
|
hasValue: true,
|
|
@@ -27795,8 +27926,43 @@ function applyBinaryOperator(node, left, right, context) {
|
|
|
27795
27926
|
}
|
|
27796
27927
|
return false;
|
|
27797
27928
|
case "in":
|
|
27798
|
-
|
|
27929
|
+
return hasSandboxProperty(right, left, context);
|
|
27930
|
+
}
|
|
27931
|
+
}
|
|
27932
|
+
async function toPropertyKey(value, context) {
|
|
27933
|
+
if (isPlainSandboxObject(value) && !isSandboxDate(value) && !isFloat32Array(value) && !isSandboxGenerator(value) && !isGuestHostObject(value)) {
|
|
27934
|
+
for (const name of ["toString", "valueOf"]) {
|
|
27935
|
+
const method = getMemberValue(value, name, context);
|
|
27936
|
+
if (!isSandboxClosure(method)) continue;
|
|
27937
|
+
const primitive = await invokeSandboxClosure(method, [], context, context.callStack, void 0, value);
|
|
27938
|
+
if (primitive === null || typeof primitive !== "object") {
|
|
27939
|
+
return context.budget.allocateString(String(primitive));
|
|
27940
|
+
}
|
|
27941
|
+
}
|
|
27942
|
+
throw new TypeError("Cannot convert object to primitive value.");
|
|
27943
|
+
}
|
|
27944
|
+
return sandboxString(value, context.budget, {
|
|
27945
|
+
stack: context.callStack,
|
|
27946
|
+
thisValue: void 0,
|
|
27947
|
+
invokeClosure: (closure, args, thisValue) => invokeSandboxClosure(closure, args, context, context.callStack, void 0, thisValue)
|
|
27948
|
+
});
|
|
27949
|
+
}
|
|
27950
|
+
function hasSandboxProperty(value, key, context) {
|
|
27951
|
+
let current = value;
|
|
27952
|
+
let depth = 0;
|
|
27953
|
+
while (typeof current === "object" && current !== null) {
|
|
27954
|
+
if (isGuestHostObject(current)) return hasHostObjectMember(current, key);
|
|
27955
|
+
if (hasOwnSandboxProperty(current, key, false)) return true;
|
|
27956
|
+
if (Array.isArray(current) || !isPlainSandboxObject(current) || isSandboxDate(current) || isFloat32Array(current) || isSandboxGenerator(current)) {
|
|
27957
|
+
return getPropertyValue(current, key, context) !== void 0;
|
|
27958
|
+
}
|
|
27959
|
+
current = getSandboxPrototype(current, context.budget);
|
|
27960
|
+
if (current !== null) {
|
|
27961
|
+
context.budget.visitNode();
|
|
27962
|
+
assertSandboxDataDepth(++depth);
|
|
27963
|
+
}
|
|
27799
27964
|
}
|
|
27965
|
+
return false;
|
|
27800
27966
|
}
|
|
27801
27967
|
async function applyCompoundAssignmentOperator(operator, left, right, context) {
|
|
27802
27968
|
left = await toNumericPrimitive(left, context);
|
|
@@ -30094,134 +30260,6 @@ function assertStructuredCloneable(value, seen) {
|
|
|
30094
30260
|
}
|
|
30095
30261
|
}
|
|
30096
30262
|
|
|
30097
|
-
// packages/safe-js/src/interp/globals/object.ts
|
|
30098
|
-
function createObjectGlobal(methods, budget) {
|
|
30099
|
-
const construct = ([value]) => {
|
|
30100
|
-
if (value === null || value === void 0) {
|
|
30101
|
-
budget.chargeDataUsage(1);
|
|
30102
|
-
return /* @__PURE__ */ Object.create(null);
|
|
30103
|
-
}
|
|
30104
|
-
if (typeof value !== "object") throw new TypeError("Object primitive boxing is not supported.");
|
|
30105
|
-
return value;
|
|
30106
|
-
};
|
|
30107
|
-
const constructor = createSandboxClosure({
|
|
30108
|
-
guest: true,
|
|
30109
|
-
sandbox: true,
|
|
30110
|
-
name: "Object",
|
|
30111
|
-
length: 1,
|
|
30112
|
-
call: construct,
|
|
30113
|
-
construct
|
|
30114
|
-
});
|
|
30115
|
-
const properties = materializeFunctionProperties(constructor);
|
|
30116
|
-
const prototype = properties.prototype;
|
|
30117
|
-
Object.defineProperty(properties, "prototype", { writable: false });
|
|
30118
|
-
for (const [name, method] of Object.entries(methods)) {
|
|
30119
|
-
Object.defineProperty(properties, name, { value: method, writable: true, configurable: true });
|
|
30120
|
-
}
|
|
30121
|
-
const prototypeMethods = {
|
|
30122
|
-
toString: createSandboxClosure({
|
|
30123
|
-
sandbox: true,
|
|
30124
|
-
name: "toString",
|
|
30125
|
-
length: 0,
|
|
30126
|
-
call: (_args, context) => budget.allocateString(`[object ${typeTag(context?.thisValue)}]`)
|
|
30127
|
-
}),
|
|
30128
|
-
valueOf: createSandboxClosure({
|
|
30129
|
-
sandbox: true,
|
|
30130
|
-
name: "valueOf",
|
|
30131
|
-
length: 0,
|
|
30132
|
-
call: (_args, context) => {
|
|
30133
|
-
const value = requireReceiver(context?.thisValue);
|
|
30134
|
-
if (typeof value !== "object")
|
|
30135
|
-
throw new TypeError("Object primitive boxing is not supported.");
|
|
30136
|
-
return value;
|
|
30137
|
-
}
|
|
30138
|
-
}),
|
|
30139
|
-
hasOwnProperty: createSandboxClosure({
|
|
30140
|
-
sandbox: true,
|
|
30141
|
-
name: "hasOwnProperty",
|
|
30142
|
-
length: 1,
|
|
30143
|
-
call: async ([key], context) => hasOwnSandboxProperty(
|
|
30144
|
-
requireReceiver(context?.thisValue),
|
|
30145
|
-
await sandboxString(key, budget, context),
|
|
30146
|
-
false
|
|
30147
|
-
)
|
|
30148
|
-
}),
|
|
30149
|
-
propertyIsEnumerable: createSandboxClosure({
|
|
30150
|
-
sandbox: true,
|
|
30151
|
-
name: "propertyIsEnumerable",
|
|
30152
|
-
length: 1,
|
|
30153
|
-
call: async ([key], context) => hasOwnSandboxProperty(
|
|
30154
|
-
requireReceiver(context?.thisValue),
|
|
30155
|
-
await sandboxString(key, budget, context),
|
|
30156
|
-
true
|
|
30157
|
-
)
|
|
30158
|
-
}),
|
|
30159
|
-
isPrototypeOf: createSandboxClosure({
|
|
30160
|
-
sandbox: true,
|
|
30161
|
-
name: "isPrototypeOf",
|
|
30162
|
-
length: 1,
|
|
30163
|
-
call: ([value], context) => {
|
|
30164
|
-
if (typeof value !== "object" || value === null) return false;
|
|
30165
|
-
const receiver = requireReceiver(context?.thisValue);
|
|
30166
|
-
let depth = 0;
|
|
30167
|
-
for (let current = getSandboxPrototype(value, budget); current !== null; current = getSandboxPrototype(current, budget)) {
|
|
30168
|
-
budget.visitNode();
|
|
30169
|
-
assertSandboxDataDepth(depth++);
|
|
30170
|
-
if (current === receiver) return true;
|
|
30171
|
-
}
|
|
30172
|
-
return false;
|
|
30173
|
-
}
|
|
30174
|
-
})
|
|
30175
|
-
};
|
|
30176
|
-
for (const [name, method] of Object.entries(prototypeMethods)) {
|
|
30177
|
-
Object.defineProperty(prototype, name, { value: method, writable: true, configurable: true });
|
|
30178
|
-
}
|
|
30179
|
-
markDescriptorObject(prototype);
|
|
30180
|
-
installObjectPrototype(budget, prototype, constructor);
|
|
30181
|
-
return constructor;
|
|
30182
|
-
}
|
|
30183
|
-
function requireReceiver(value) {
|
|
30184
|
-
if (value === null || value === void 0)
|
|
30185
|
-
throw new TypeError("Object method requires a non-null receiver.");
|
|
30186
|
-
return value;
|
|
30187
|
-
}
|
|
30188
|
-
function hasOwnSandboxProperty(value, key, enumerable) {
|
|
30189
|
-
requireReceiver(value);
|
|
30190
|
-
if (isGuestHostObject(value)) return hasHostObjectMember(value, key, enumerable);
|
|
30191
|
-
let properties;
|
|
30192
|
-
if (isGuestClosure(value)) properties = materializeFunctionProperties(value);
|
|
30193
|
-
else if (isSandboxClosure(value)) {
|
|
30194
|
-
if (key === "length" || key === "name") return !enumerable;
|
|
30195
|
-
properties = value.properties ?? /* @__PURE__ */ Object.create(null);
|
|
30196
|
-
} else if (isSandboxMap(value) || isSandboxSet(value) || isSandboxPromise(value) || isSandboxGenerator(value))
|
|
30197
|
-
return false;
|
|
30198
|
-
else if (isSandboxRegex(value)) return key === "lastIndex" && !enumerable;
|
|
30199
|
-
else properties = Object(value);
|
|
30200
|
-
const descriptor = Object.getOwnPropertyDescriptor(properties, key);
|
|
30201
|
-
return descriptor !== void 0 && (!enumerable || descriptor.enumerable === true);
|
|
30202
|
-
}
|
|
30203
|
-
function typeTag(value) {
|
|
30204
|
-
if (value === void 0) return "Undefined";
|
|
30205
|
-
if (value === null) return "Null";
|
|
30206
|
-
if (typeof value === "string") return "String";
|
|
30207
|
-
if (typeof value === "number") return "Number";
|
|
30208
|
-
if (typeof value === "boolean") return "Boolean";
|
|
30209
|
-
if (isSandboxClosure(value)) {
|
|
30210
|
-
while (value.boundTarget !== void 0) value = value.boundTarget;
|
|
30211
|
-
return value.generator ? "GeneratorFunction" : value.async ? "AsyncFunction" : "Function";
|
|
30212
|
-
}
|
|
30213
|
-
if (Array.isArray(value)) return "Array";
|
|
30214
|
-
if (isSandboxDate(value)) return "Date";
|
|
30215
|
-
if (isSandboxErrorConstructorInstance(value, "Error")) return "Error";
|
|
30216
|
-
if (isSandboxRegex(value)) return "RegExp";
|
|
30217
|
-
if (isSandboxMap(value)) return "Map";
|
|
30218
|
-
if (isSandboxSet(value)) return "Set";
|
|
30219
|
-
if (isSandboxPromise(value)) return "Promise";
|
|
30220
|
-
if (isSandboxGenerator(value)) return "Generator";
|
|
30221
|
-
if (isFloat32Array(value)) return "Float32Array";
|
|
30222
|
-
return "Object";
|
|
30223
|
-
}
|
|
30224
|
-
|
|
30225
30263
|
// packages/safe-js/src/interp/globals/object-array.ts
|
|
30226
30264
|
function createObjectArrayGlobals(options) {
|
|
30227
30265
|
return {
|
|
@@ -32772,4 +32810,4 @@ export {
|
|
|
32772
32810
|
FileSnapshotBackend,
|
|
32773
32811
|
run
|
|
32774
32812
|
};
|
|
32775
|
-
//# sourceMappingURL=chunk-
|
|
32813
|
+
//# sourceMappingURL=chunk-TNPFJ4XS.js.map
|