@opencode/codemode 0.0.0-dev-19427 → 0.0.0-dev-19432
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.
|
@@ -5,3 +5,4 @@ export declare const containsOpaqueReference: (value: unknown) => boolean;
|
|
|
5
5
|
export declare const rejectCircularInsertion: (container: object, value: unknown, label: string, node: AstNode, seen?: Set<object>) => void;
|
|
6
6
|
export declare const describeValue: (value: unknown) => string;
|
|
7
7
|
export declare const typeofValue: (value: unknown) => string;
|
|
8
|
+
export declare const parseArrayIndex: (key: string | number) => number | undefined;
|
|
@@ -93,3 +93,11 @@ export const typeofValue = (value) => {
|
|
|
93
93
|
return value.path.length > 0 ? "function" : "object";
|
|
94
94
|
return typeof value;
|
|
95
95
|
};
|
|
96
|
+
const MAX_ARRAY_LENGTH = 4_294_967_295;
|
|
97
|
+
export const parseArrayIndex = (key) => {
|
|
98
|
+
const property = String(key);
|
|
99
|
+
if (!/^(0|[1-9]\d*)$/.test(property))
|
|
100
|
+
return undefined;
|
|
101
|
+
const index = Number(property);
|
|
102
|
+
return index < MAX_ARRAY_LENGTH ? index : undefined;
|
|
103
|
+
};
|
|
@@ -8,7 +8,7 @@ import { HostFunction, HostNamespace } from "./host.js";
|
|
|
8
8
|
import { invokeIntrinsic } from "./methods.js";
|
|
9
9
|
import { preserveConsumerError } from "./runner.js";
|
|
10
10
|
import { invokePromiseInstanceMethod, PromiseRuntime, resolvePromise, resolvePromiseValue } from "./promises.js";
|
|
11
|
-
import { containsOpaqueReference, describeValue, isRuntimeReference, rejectCircularInsertion, typeofValue, } from "./references.js";
|
|
11
|
+
import { containsOpaqueReference, describeValue, isRuntimeReference, parseArrayIndex, rejectCircularInsertion, typeofValue, } from "./references.js";
|
|
12
12
|
import { ScopeStack } from "./scope.js";
|
|
13
13
|
import { arrayMethods, mapMethods, setMethods } from "../stdlib/collections.js";
|
|
14
14
|
import { dateMethods } from "../stdlib/date.js";
|
|
@@ -16,16 +16,9 @@ import { numberMethods } from "../stdlib/number.js";
|
|
|
16
16
|
import { constructRegExp, regexpMethods, regexpProperties } from "../stdlib/regexp.js";
|
|
17
17
|
import { stringMethods } from "../stdlib/string.js";
|
|
18
18
|
import { uriArgument, urlMethods, urlProperties, urlSearchParamsMethods, urlWritableProperties } from "../stdlib/url.js";
|
|
19
|
+
import { enumerableSource } from "../stdlib/object.js";
|
|
19
20
|
import { coerceToNumber, coerceToString, compoundOperators, errorBrandName } from "../stdlib/value.js";
|
|
20
21
|
import { Values } from "../values.js";
|
|
21
|
-
const MAX_ARRAY_LENGTH = 4_294_967_295;
|
|
22
|
-
const parseArrayIndex = (key) => {
|
|
23
|
-
const property = String(key);
|
|
24
|
-
if (!/^(0|[1-9]\d*)$/.test(property))
|
|
25
|
-
return undefined;
|
|
26
|
-
const index = Number(property);
|
|
27
|
-
return index < MAX_ARRAY_LENGTH ? index : undefined;
|
|
28
|
-
};
|
|
29
22
|
const calleeDescription = (callee) => {
|
|
30
23
|
if (callee?.type === "Identifier")
|
|
31
24
|
return callee.name;
|
|
@@ -673,17 +666,13 @@ class Frame {
|
|
|
673
666
|
return value;
|
|
674
667
|
throw new InterpreterRuntimeError(`${context} must be a function.`, node).as("TypeError");
|
|
675
668
|
}
|
|
676
|
-
|
|
677
|
-
|
|
669
|
+
// for...in over null/undefined iterates nothing, like JS.
|
|
670
|
+
enumerableKeys(value, node) {
|
|
671
|
+
if (value instanceof ToolReference)
|
|
678
672
|
return [...this.runtime.toolKeys(value.path)];
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
}
|
|
683
|
-
if (value !== null && typeof value === "object" && !isRuntimeReference(value)) {
|
|
684
|
-
return Object.keys(value);
|
|
685
|
-
}
|
|
686
|
-
return undefined;
|
|
673
|
+
if (value === null || value === undefined)
|
|
674
|
+
return [];
|
|
675
|
+
return Object.keys(enumerableSource("for...in", value, node));
|
|
687
676
|
}
|
|
688
677
|
evaluateForInStatement(node, labels) {
|
|
689
678
|
const left = node.left;
|
|
@@ -695,10 +684,7 @@ class Frame {
|
|
|
695
684
|
if (declared?.lexical)
|
|
696
685
|
self.predeclarePattern(declared.pattern, declared.mutable, left);
|
|
697
686
|
const right = yield* self.evaluateExpression(node.right);
|
|
698
|
-
const keys = self.enumerableKeys(right);
|
|
699
|
-
if (keys === undefined) {
|
|
700
|
-
throw new InterpreterRuntimeError("for...in requires a plain object, array, or tools reference. Use for...of for arrays/strings/Maps/Sets, or Object.keys(value) for a key list.", node);
|
|
701
|
-
}
|
|
687
|
+
const keys = self.enumerableKeys(right, node.right);
|
|
702
688
|
if (left.type !== "Identifier" && left.type !== "VariableDeclaration") {
|
|
703
689
|
throw new InterpreterRuntimeError("Unsupported for...in binding.", left);
|
|
704
690
|
}
|
|
@@ -1597,14 +1583,13 @@ class Frame {
|
|
|
1597
1583
|
for (const property of node.properties) {
|
|
1598
1584
|
if (property.type === "SpreadElement") {
|
|
1599
1585
|
const spread = yield* self.evaluateExpression(property.argument);
|
|
1600
|
-
if (spread === null || spread === undefined
|
|
1586
|
+
if (spread === null || spread === undefined)
|
|
1601
1587
|
continue;
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
}
|
|
1605
|
-
for (const [key, value] of Object.entries(spread))
|
|
1588
|
+
const from = enumerableSource("Object spread", spread, property);
|
|
1589
|
+
for (const [key, value] of Object.entries(from))
|
|
1606
1590
|
objectValue[key] = value;
|
|
1607
|
-
|
|
1591
|
+
if (typeof from === "object")
|
|
1592
|
+
copyIteratorSymbols(from, objectValue);
|
|
1608
1593
|
continue;
|
|
1609
1594
|
}
|
|
1610
1595
|
if (property.kind !== "init") {
|
package/dist/stdlib/object.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { HostFunction } from "../interpreter/host.js";
|
|
2
2
|
import { type AstNode } from "../interpreter/model.js";
|
|
3
3
|
import { type Runner } from "../interpreter/runner.js";
|
|
4
|
+
export declare const enumerableSource: (label: string, value: unknown, node: AstNode) => Record<string, unknown>;
|
|
4
5
|
export declare const objectAssign: (args: Array<unknown>, node: AstNode) => unknown;
|
|
5
6
|
export declare const objectGlobal: <R>(runner: Runner<R>, toolKeys: (path: ReadonlyArray<string>) => ReadonlyArray<string>) => HostFunction<R>;
|
package/dist/stdlib/object.js
CHANGED
|
@@ -2,52 +2,62 @@ import { Effect } from "effect";
|
|
|
2
2
|
import { toProgram } from "../data.js";
|
|
3
3
|
import { HostFunction, sync, syncCall } from "../interpreter/host.js";
|
|
4
4
|
import { AsyncIteratorSymbol, InterpreterRuntimeError, IteratorSymbol } from "../interpreter/model.js";
|
|
5
|
-
import { containsOpaqueReference, describeValue, rejectCircularInsertion, typeofValue, } from "../interpreter/references.js";
|
|
5
|
+
import { containsOpaqueReference, describeValue, isRuntimeReference, parseArrayIndex, rejectCircularInsertion, typeofValue, } from "../interpreter/references.js";
|
|
6
6
|
import { preserveConsumerError } from "../interpreter/runner.js";
|
|
7
7
|
import { ToolReference } from "../tool-runtime.js";
|
|
8
8
|
import { Values } from "../values.js";
|
|
9
9
|
import { groupBy } from "./collections.js";
|
|
10
10
|
import { coerceToString } from "./value.js";
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
if (
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
if (
|
|
18
|
-
throw new InterpreterRuntimeError(
|
|
11
|
+
// ToObject for enumeration. Strings return themselves: the host's Object.keys/entries/hasOwn index a
|
|
12
|
+
// primitive string directly. Numbers, booleans, wrappers, and functions have no own enumerable keys.
|
|
13
|
+
export const enumerableSource = (label, value, node) => {
|
|
14
|
+
if (value === null || value === undefined) {
|
|
15
|
+
throw new InterpreterRuntimeError(`${label} cannot convert ${describeValue(value)} to an object.`, node).as("TypeError");
|
|
16
|
+
}
|
|
17
|
+
if (value instanceof Values.Promise) {
|
|
18
|
+
throw new InterpreterRuntimeError(`${label} received an un-awaited Promise; await it before inspecting the result.`, node, "InvalidDataValue");
|
|
19
|
+
}
|
|
20
|
+
if (value instanceof ToolReference) {
|
|
21
|
+
throw new InterpreterRuntimeError(`${label} cannot read tool references: they are not plain data. Use Object.keys(tools) for names, or search({ query }) for signatures.`, node, "InvalidDataValue");
|
|
19
22
|
}
|
|
20
|
-
|
|
23
|
+
if (typeof value === "string")
|
|
24
|
+
return value;
|
|
25
|
+
if (typeof value !== "object" || Values.isValue(value) || isRuntimeReference(value))
|
|
26
|
+
return {};
|
|
27
|
+
return value;
|
|
21
28
|
};
|
|
22
29
|
export const objectAssign = (args, node) => {
|
|
23
30
|
const target = args[0];
|
|
24
|
-
|
|
25
|
-
|
|
31
|
+
// JS would box a primitive target; wrappers and primitives cannot hold fields here.
|
|
32
|
+
if (target === null || typeof target !== "object" || Values.isValue(target) || isRuntimeReference(target)) {
|
|
33
|
+
throw new InterpreterRuntimeError(`Object.assign expects a data object or array target, received ${describeValue(target)}.`, node).as("TypeError");
|
|
26
34
|
}
|
|
27
35
|
const out = target;
|
|
28
36
|
const seen = new Set();
|
|
29
37
|
const guardedSet = (key, item) => {
|
|
38
|
+
// Arrays hold only indexed elements, as with direct assignment; Reflect.set would otherwise
|
|
39
|
+
// reach Array's length and Object.prototype's __proto__ setter.
|
|
40
|
+
if (Array.isArray(out) && (typeof key === "symbol" || parseArrayIndex(key) === undefined)) {
|
|
41
|
+
throw new InterpreterRuntimeError(`Object.assign cannot assign '${String(key)}' to an array: only array indexes may be assigned.`, node).as("TypeError");
|
|
42
|
+
}
|
|
30
43
|
rejectCircularInsertion(out, item, "Object.assign result", node, seen);
|
|
31
44
|
if (!Reflect.set(out, key, item))
|
|
32
45
|
throw new InterpreterRuntimeError(`Object.assign could not assign property '${String(key)}'.`, node).as("TypeError");
|
|
33
46
|
};
|
|
34
47
|
for (const source of args.slice(1)) {
|
|
35
|
-
if (source === null || source === undefined
|
|
48
|
+
if (source === null || source === undefined)
|
|
49
|
+
continue;
|
|
50
|
+
const from = enumerableSource("Object.assign(...)", source, node);
|
|
51
|
+
if (typeof from !== "object") {
|
|
52
|
+
for (const [key, item] of Object.entries(from))
|
|
53
|
+
guardedSet(key, item);
|
|
36
54
|
continue;
|
|
37
|
-
if (typeof source !== "object" || Array.isArray(source)) {
|
|
38
|
-
throw new InterpreterRuntimeError("Object.assign expects data objects.", node);
|
|
39
55
|
}
|
|
40
|
-
for (const key of Reflect.ownKeys(
|
|
41
|
-
if (typeof key === "
|
|
42
|
-
if (Object.prototype.propertyIsEnumerable.call(source, key))
|
|
43
|
-
guardedSet(key, Reflect.get(source, key));
|
|
44
|
-
continue;
|
|
45
|
-
}
|
|
46
|
-
if (key !== AsyncIteratorSymbol && key !== IteratorSymbol)
|
|
56
|
+
for (const key of Reflect.ownKeys(from)) {
|
|
57
|
+
if (typeof key === "symbol" && key !== AsyncIteratorSymbol && key !== IteratorSymbol)
|
|
47
58
|
continue;
|
|
48
|
-
if (
|
|
49
|
-
|
|
50
|
-
guardedSet(key, Reflect.get(source, key));
|
|
59
|
+
if (Object.prototype.propertyIsEnumerable.call(from, key))
|
|
60
|
+
guardedSet(key, Reflect.get(from, key));
|
|
51
61
|
}
|
|
52
62
|
}
|
|
53
63
|
return out;
|
|
@@ -93,10 +103,7 @@ const rejectTools = (name, args, node) => {
|
|
|
93
103
|
return;
|
|
94
104
|
throw new InterpreterRuntimeError(`Object.${name}(...) cannot read tool references: they are not plain data. Use Object.keys(tools) for names, or search({ query }) for signatures.`, node, "InvalidDataValue");
|
|
95
105
|
};
|
|
96
|
-
const objectStatic = (name, impl) => sync(`Object.${name}`,
|
|
97
|
-
rejectTools(name, args, node);
|
|
98
|
-
return impl(args, node);
|
|
99
|
-
});
|
|
106
|
+
const objectStatic = (name, impl) => sync(`Object.${name}`, impl);
|
|
100
107
|
// Object constructs identically with or without new, like JS. Only `keys` copies its result into the
|
|
101
108
|
// program; `values`, `entries`, `assign`, and `fromEntries` hand back the program's own values.
|
|
102
109
|
export const objectGlobal = (runner, toolKeys) => new HostFunction({
|
|
@@ -107,10 +114,10 @@ export const objectGlobal = (runner, toolKeys) => new HostFunction({
|
|
|
107
114
|
members: {
|
|
108
115
|
keys: sync("Object.keys", (args, node) => toProgram(args[0] instanceof ToolReference
|
|
109
116
|
? [...toolKeys(args[0].path)]
|
|
110
|
-
: Object.keys(
|
|
111
|
-
values: objectStatic("values", (args, node) => Object.values(
|
|
112
|
-
entries: objectStatic("entries", (args, node) => Object.entries(
|
|
113
|
-
hasOwn: objectStatic("hasOwn", (args, node) => Object.hasOwn(
|
|
117
|
+
: Object.keys(enumerableSource("Object.keys(...)", args[0], node)), "Object.keys result")),
|
|
118
|
+
values: objectStatic("values", (args, node) => Object.values(enumerableSource("Object.values(...)", args[0], node))),
|
|
119
|
+
entries: objectStatic("entries", (args, node) => Object.entries(enumerableSource("Object.entries(...)", args[0], node)).map(([key, item]) => [key, item])),
|
|
120
|
+
hasOwn: objectStatic("hasOwn", (args, node) => Object.hasOwn(enumerableSource("Object.hasOwn(...)", args[0], node), args[1] === AsyncIteratorSymbol || args[1] === IteratorSymbol ? args[1] : String(args[1]))),
|
|
114
121
|
is: objectStatic("is", (args, node) => {
|
|
115
122
|
if (containsOpaqueReference(args[0]) || containsOpaqueReference(args[1])) {
|
|
116
123
|
throw new InterpreterRuntimeError("Object.is requires data values.", node, "InvalidDataValue");
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json.schemastore.org/package.json",
|
|
3
3
|
"name": "@opencode/codemode",
|
|
4
|
-
"version": "0.0.0-dev-
|
|
4
|
+
"version": "0.0.0-dev-19432",
|
|
5
5
|
"description": "Effect-native confined code execution over schema-described tools",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"license": "MIT",
|