@opencode/codemode 0.0.0-dev-19631 → 0.0.0-dev-19633
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/codemode.js +1 -1
- package/dist/data.d.ts +3 -3
- package/dist/data.js +37 -31
- package/dist/interpreter/callback.d.ts +20 -0
- package/dist/interpreter/{runner.js → callback.js} +10 -10
- package/dist/interpreter/errors.d.ts +5 -5
- package/dist/interpreter/errors.js +21 -22
- package/dist/interpreter/execute.d.ts +2 -2
- package/dist/interpreter/execute.js +11 -11
- package/dist/interpreter/extensions.d.ts +2 -2
- package/dist/interpreter/extensions.js +42 -36
- package/dist/interpreter/generators.d.ts +2 -3
- package/dist/interpreter/generators.js +8 -8
- package/dist/interpreter/globals.d.ts +2 -12
- package/dist/interpreter/globals.js +41 -37
- package/dist/interpreter/interpreter.d.ts +31 -0
- package/dist/interpreter/{runtime.js → interpreter.js} +118 -117
- package/dist/interpreter/intrinsics.d.ts +5 -5
- package/dist/interpreter/intrinsics.js +16 -10
- package/dist/interpreter/model.d.ts +3 -3
- package/dist/interpreter/model.js +1 -1
- package/dist/interpreter/native.d.ts +9 -9
- package/dist/interpreter/native.js +9 -9
- package/dist/interpreter/objects.d.ts +51 -46
- package/dist/interpreter/objects.js +57 -40
- package/dist/interpreter/promises.d.ts +13 -13
- package/dist/interpreter/promises.js +70 -70
- package/dist/interpreter/references.js +17 -15
- package/dist/openapi/types.d.ts +1 -1
- package/dist/stdlib/array.d.ts +3 -3
- package/dist/stdlib/array.js +31 -31
- package/dist/stdlib/bytes.d.ts +10 -0
- package/dist/stdlib/bytes.js +228 -0
- package/dist/stdlib/collections.d.ts +4 -4
- package/dist/stdlib/collections.js +55 -55
- package/dist/stdlib/console.d.ts +3 -3
- package/dist/stdlib/console.js +24 -22
- package/dist/stdlib/date.d.ts +2 -2
- package/dist/stdlib/date.js +19 -19
- package/dist/stdlib/json.d.ts +3 -3
- package/dist/stdlib/json.js +24 -24
- package/dist/stdlib/math.d.ts +3 -3
- package/dist/stdlib/math.js +7 -7
- package/dist/stdlib/number.d.ts +3 -3
- package/dist/stdlib/number.js +11 -11
- package/dist/stdlib/object.d.ts +5 -5
- package/dist/stdlib/object.js +41 -39
- package/dist/stdlib/regexp.d.ts +6 -6
- package/dist/stdlib/regexp.js +24 -24
- package/dist/stdlib/string.d.ts +2 -2
- package/dist/stdlib/string.js +24 -24
- package/dist/stdlib/url.d.ts +6 -6
- package/dist/stdlib/url.js +39 -39
- package/dist/stdlib/value.d.ts +3 -3
- package/dist/stdlib/value.js +18 -14
- package/dist/stdlib/web.d.ts +4 -4
- package/dist/stdlib/web.js +19 -5
- package/dist/tool-runtime.d.ts +2 -2
- package/dist/tool-runtime.js +2 -2
- package/package.json +1 -1
- package/dist/interpreter/runner.d.ts +0 -27
- package/dist/interpreter/runtime.d.ts +0 -19
package/dist/stdlib/regexp.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Effect } from "effect";
|
|
2
2
|
import { constructor, methods, prototypeFrom, receiver } from "../interpreter/native.js";
|
|
3
3
|
import { syntaxError, typeError } from "../interpreter/model.js";
|
|
4
|
-
import { define, defineAccessor, getOwn,
|
|
4
|
+
import { define, defineAccessor, getOwn, Arr, Obj, RegExpObj, record, set } from "../interpreter/objects.js";
|
|
5
5
|
import { coerceToNumber, coerceToString } from "./value.js";
|
|
6
6
|
const flagProperties = [
|
|
7
7
|
"hasIndices",
|
|
@@ -19,7 +19,7 @@ export const toHostRegex = (arg, method, extraFlags = "") => {
|
|
|
19
19
|
// Native parity: an undefined pattern behaves as an empty pattern.
|
|
20
20
|
if (arg === undefined)
|
|
21
21
|
return new RegExp("", extraFlags);
|
|
22
|
-
if (arg instanceof
|
|
22
|
+
if (arg instanceof RegExpObj)
|
|
23
23
|
return arg.regex;
|
|
24
24
|
if (typeof arg === "string") {
|
|
25
25
|
try {
|
|
@@ -31,28 +31,28 @@ export const toHostRegex = (arg, method, extraFlags = "") => {
|
|
|
31
31
|
}
|
|
32
32
|
throw typeError(`String.${method} expects a regular expression (a /pattern/flags literal or new RegExp(...)) or a string pattern, not ${arg === null ? "null" : typeof arg}.`);
|
|
33
33
|
};
|
|
34
|
-
export const matchToValue = (
|
|
35
|
-
const result = new
|
|
34
|
+
export const matchToValue = (builtins, match) => {
|
|
35
|
+
const result = new Arr(builtins.Array, Array.from(match, (group) => group));
|
|
36
36
|
if (match.index !== undefined)
|
|
37
37
|
define(result, "index", match.index);
|
|
38
38
|
if (match.input !== undefined)
|
|
39
39
|
define(result, "input", match.input);
|
|
40
40
|
if (match.groups)
|
|
41
|
-
define(result, "groups", record(
|
|
41
|
+
define(result, "groups", record(builtins.Object, match.groups));
|
|
42
42
|
if (match.indices)
|
|
43
|
-
define(result, "indices", indicesToValue(
|
|
43
|
+
define(result, "indices", indicesToValue(builtins, match.indices));
|
|
44
44
|
return result;
|
|
45
45
|
};
|
|
46
|
-
export const constructRegExp = (
|
|
46
|
+
export const constructRegExp = (builtins, args, proto = builtins.RegExp) => {
|
|
47
47
|
const first = args[0];
|
|
48
|
-
const pattern = first instanceof
|
|
48
|
+
const pattern = first instanceof RegExpObj ? first.regex.source : first === undefined ? "" : coerceToString(first);
|
|
49
49
|
const flagsArg = args[1];
|
|
50
50
|
if (flagsArg !== undefined && typeof flagsArg !== "string") {
|
|
51
51
|
throw syntaxError(`RegExp flags must be a string of flag characters (e.g. "g", "gi"), not ${flagsArg === null ? "null" : typeof flagsArg}.`);
|
|
52
52
|
}
|
|
53
|
-
const flags = flagsArg ?? (first instanceof
|
|
53
|
+
const flags = flagsArg ?? (first instanceof RegExpObj ? first.regex.flags : "");
|
|
54
54
|
try {
|
|
55
|
-
return new
|
|
55
|
+
return new RegExpObj(proto, pattern, flags);
|
|
56
56
|
}
|
|
57
57
|
catch (error) {
|
|
58
58
|
const reason = regexFailureReason(error);
|
|
@@ -68,16 +68,16 @@ const toLength = (value) => {
|
|
|
68
68
|
return Math.min(Math.floor(number), Number.MAX_SAFE_INTEGER);
|
|
69
69
|
};
|
|
70
70
|
// RegExp constructs identically with or without new, like JS.
|
|
71
|
-
export const regexpGlobal = (
|
|
72
|
-
const
|
|
73
|
-
const proto =
|
|
74
|
-
const regexp = constructor(
|
|
71
|
+
export const regexpGlobal = (ctx) => {
|
|
72
|
+
const builtins = ctx.builtins;
|
|
73
|
+
const proto = builtins.RegExp;
|
|
74
|
+
const regexp = constructor(builtins, proto, {
|
|
75
75
|
name: "RegExp",
|
|
76
76
|
length: 2,
|
|
77
|
-
call: (_, args) => Effect.sync(() => constructRegExp(
|
|
78
|
-
construct: (args, newTarget) => Effect.sync(() => constructRegExp(
|
|
77
|
+
call: (_, args) => Effect.sync(() => constructRegExp(builtins, args)),
|
|
78
|
+
construct: (args, newTarget) => Effect.sync(() => constructRegExp(builtins, args, prototypeFrom(newTarget, proto))),
|
|
79
79
|
});
|
|
80
|
-
methods(
|
|
80
|
+
methods(builtins, regexp, [
|
|
81
81
|
[
|
|
82
82
|
"escape",
|
|
83
83
|
1,
|
|
@@ -88,7 +88,7 @@ export const regexpGlobal = (runner) => {
|
|
|
88
88
|
},
|
|
89
89
|
],
|
|
90
90
|
]);
|
|
91
|
-
const self = (thisValue, name) => receiver(
|
|
91
|
+
const self = (thisValue, name) => receiver(RegExpObj, thisValue, `RegExp.prototype.${name}`);
|
|
92
92
|
defineAccessor(proto, "source", (thisValue) => self(thisValue, "source").regex.source);
|
|
93
93
|
defineAccessor(proto, "flags", (thisValue) => self(thisValue, "flags").regex.flags);
|
|
94
94
|
for (const name of flagProperties)
|
|
@@ -107,22 +107,22 @@ export const regexpGlobal = (runner) => {
|
|
|
107
107
|
set(value, "lastIndex", value.regex.lastIndex);
|
|
108
108
|
if (name === "test")
|
|
109
109
|
return matched !== null;
|
|
110
|
-
return matched === null ? null : matchToValue(
|
|
110
|
+
return matched === null ? null : matchToValue(builtins, matched);
|
|
111
111
|
},
|
|
112
112
|
];
|
|
113
|
-
methods(
|
|
113
|
+
methods(builtins, proto, [
|
|
114
114
|
run("exec"),
|
|
115
115
|
run("test"),
|
|
116
116
|
["toString", 0, (thisValue) => coerceToString(self(thisValue, "toString"))],
|
|
117
117
|
]);
|
|
118
118
|
return regexp;
|
|
119
119
|
};
|
|
120
|
-
const indicesToValue = (
|
|
121
|
-
const range = (pair) => pair === undefined ? undefined : new
|
|
122
|
-
const result = new
|
|
120
|
+
const indicesToValue = (builtins, indices) => {
|
|
121
|
+
const range = (pair) => pair === undefined ? undefined : new Arr(builtins.Array, [...pair]);
|
|
122
|
+
const result = new Arr(builtins.Array, Array.from(indices, range));
|
|
123
123
|
const groups = indices.groups;
|
|
124
124
|
define(result, "groups", groups === undefined
|
|
125
125
|
? undefined
|
|
126
|
-
: record(
|
|
126
|
+
: record(builtins.Object, Object.fromEntries(Object.entries(groups).map(([key, pair]) => [key, range(pair)]))));
|
|
127
127
|
return result;
|
|
128
128
|
};
|
package/dist/stdlib/string.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export declare const stringGlobal: <R>(
|
|
1
|
+
import type { Interpreter } from "../interpreter/interpreter.js";
|
|
2
|
+
export declare const stringGlobal: <R>(ctx: Interpreter<R>) => import("../interpreter/objects.js").Native<R>;
|
package/dist/stdlib/string.js
CHANGED
|
@@ -3,9 +3,9 @@ import { toProgram } from "../data.js";
|
|
|
3
3
|
import { constructor, methods } from "../interpreter/native.js";
|
|
4
4
|
import { checkArrayLength, checkStringLength } from "../interpreter/limits.js";
|
|
5
5
|
import { invalidData, rangeError, typeError } from "../interpreter/model.js";
|
|
6
|
-
import {
|
|
6
|
+
import { Arr, PromiseObj, RegExpObj, record } from "../interpreter/objects.js";
|
|
7
7
|
import { containsOpaqueReference, typeofValue } from "../interpreter/references.js";
|
|
8
|
-
import { applyCollectionCallback, isSupportedCallback } from "../interpreter/
|
|
8
|
+
import { applyCollectionCallback, isSupportedCallback } from "../interpreter/callback.js";
|
|
9
9
|
import { matchToValue, toHostRegex } from "./regexp.js";
|
|
10
10
|
import { coerceToNumber, coerceToString, coercion } from "./value.js";
|
|
11
11
|
// console is intercepted by the interpreter before reaching here.
|
|
@@ -20,9 +20,9 @@ const replaceAllNeedsGlobal = (pattern) => {
|
|
|
20
20
|
throw typeError(`String.replaceAll requires a regular expression with the global (g) flag: write /${pattern.source}/${pattern.flags}g, or use String.replace to replace only the first match.`);
|
|
21
21
|
}
|
|
22
22
|
};
|
|
23
|
-
const replaceWithCallback = (
|
|
24
|
-
const
|
|
25
|
-
const apply = applyCollectionCallback(
|
|
23
|
+
const replaceWithCallback = (ctx, value, name, args) => {
|
|
24
|
+
const builtins = ctx.builtins;
|
|
25
|
+
const apply = applyCollectionCallback(ctx, args[1], `String.${name}`);
|
|
26
26
|
const matches = [];
|
|
27
27
|
const collect = (...callbackArgs) => {
|
|
28
28
|
const match = callbackArgs[0];
|
|
@@ -33,12 +33,12 @@ const replaceWithCallback = (runner, value, name, args) => {
|
|
|
33
33
|
throw typeError(`String.${name} produced an invalid replacement match.`);
|
|
34
34
|
}
|
|
35
35
|
if (hasGroups)
|
|
36
|
-
callbackArgs[callbackArgs.length - 1] = record(
|
|
36
|
+
callbackArgs[callbackArgs.length - 1] = record(builtins.Object, groups);
|
|
37
37
|
matches.push({ match, offset, args: callbackArgs });
|
|
38
38
|
return match;
|
|
39
39
|
};
|
|
40
40
|
const pattern = args[0];
|
|
41
|
-
if (pattern instanceof
|
|
41
|
+
if (pattern instanceof RegExpObj) {
|
|
42
42
|
if (name === "replaceAll")
|
|
43
43
|
replaceAllNeedsGlobal(pattern.regex);
|
|
44
44
|
if (name === "replace")
|
|
@@ -58,21 +58,21 @@ const replaceWithCallback = (runner, value, name, args) => {
|
|
|
58
58
|
let end = 0;
|
|
59
59
|
for (const match of matches) {
|
|
60
60
|
const replacement = yield* apply(match.args);
|
|
61
|
-
output.push(value.slice(end, match.offset), replacement instanceof
|
|
61
|
+
output.push(value.slice(end, match.offset), replacement instanceof PromiseObj
|
|
62
62
|
? "[object Promise]"
|
|
63
|
-
: coerceToString(toProgram(
|
|
63
|
+
: coerceToString(toProgram(builtins, replacement, `String.${name} replacer result`)));
|
|
64
64
|
end = match.offset + match.match.length;
|
|
65
65
|
}
|
|
66
66
|
output.push(value.slice(end));
|
|
67
67
|
return output.join("");
|
|
68
68
|
});
|
|
69
69
|
};
|
|
70
|
-
export const stringGlobal = (
|
|
71
|
-
const
|
|
72
|
-
const string = constructor(
|
|
70
|
+
export const stringGlobal = (ctx) => {
|
|
71
|
+
const builtins = ctx.builtins;
|
|
72
|
+
const string = constructor(builtins, builtins.String, {
|
|
73
73
|
name: "String",
|
|
74
74
|
length: 1,
|
|
75
|
-
call: coercion(
|
|
75
|
+
call: coercion(ctx, "String").call,
|
|
76
76
|
});
|
|
77
77
|
const codeUnits = (name, op) => [
|
|
78
78
|
name,
|
|
@@ -84,7 +84,7 @@ export const stringGlobal = (runner) => {
|
|
|
84
84
|
return arg;
|
|
85
85
|
})),
|
|
86
86
|
];
|
|
87
|
-
methods(
|
|
87
|
+
methods(builtins, string, [
|
|
88
88
|
codeUnits("fromCharCode", String.fromCharCode),
|
|
89
89
|
codeUnits("fromCodePoint", String.fromCodePoint),
|
|
90
90
|
]);
|
|
@@ -102,7 +102,7 @@ export const stringGlobal = (runner) => {
|
|
|
102
102
|
const optNum = (name, args, index) => args[index] === undefined ? undefined : num(name, args, index);
|
|
103
103
|
const optStr = (name, args, index) => args[index] === undefined ? undefined : str(name, args, index);
|
|
104
104
|
const rejectRegex = (name, args) => {
|
|
105
|
-
if (args[0] instanceof
|
|
105
|
+
if (args[0] instanceof RegExpObj) {
|
|
106
106
|
throw typeError(`String.${name} cannot take a regular expression; use regex.test(string) or String.search instead.`);
|
|
107
107
|
}
|
|
108
108
|
};
|
|
@@ -113,11 +113,11 @@ export const stringGlobal = (runner) => {
|
|
|
113
113
|
];
|
|
114
114
|
const replace = (name) => simple(name, 2, (value, args) => {
|
|
115
115
|
if (isSupportedCallback(args[1]))
|
|
116
|
-
return replaceWithCallback(
|
|
116
|
+
return replaceWithCallback(ctx, value, name, args);
|
|
117
117
|
if (typeofValue(args[1]) === "function") {
|
|
118
118
|
throw typeError(`String.${name} cannot use this callable as a replacer; wrap it in an arrow function, e.g. (match) => tools.ns.tool(match).`);
|
|
119
119
|
}
|
|
120
|
-
if (args[0] instanceof
|
|
120
|
+
if (args[0] instanceof RegExpObj) {
|
|
121
121
|
const pattern = args[0].regex;
|
|
122
122
|
const replacement = str(name, args, 1);
|
|
123
123
|
if (name === "replaceAll")
|
|
@@ -128,7 +128,7 @@ export const stringGlobal = (runner) => {
|
|
|
128
128
|
return value.replace(str(name, args, 0), str(name, args, 1));
|
|
129
129
|
return value.replaceAll(str(name, args, 0), str(name, args, 1));
|
|
130
130
|
});
|
|
131
|
-
methods(
|
|
131
|
+
methods(builtins, builtins.String, [
|
|
132
132
|
simple("toString", 0, (value) => value),
|
|
133
133
|
simple("valueOf", 0, (value) => value),
|
|
134
134
|
simple("toLowerCase", 0, (value) => value.toLowerCase()),
|
|
@@ -150,14 +150,14 @@ export const stringGlobal = (runner) => {
|
|
|
150
150
|
}
|
|
151
151
|
}),
|
|
152
152
|
simple("split", 2, (value, args) => {
|
|
153
|
-
const wrap = (parts) => new
|
|
153
|
+
const wrap = (parts) => new Arr(builtins.Array, parts);
|
|
154
154
|
// Native: an undefined separator returns the whole string, not a split on "undefined",
|
|
155
155
|
// unless the limit truncates to zero.
|
|
156
156
|
const requestedLimit = optNum("split", args, 1);
|
|
157
157
|
if (args[0] === undefined) {
|
|
158
158
|
return wrap(requestedLimit !== undefined && requestedLimit >>> 0 === 0 ? [] : [value]);
|
|
159
159
|
}
|
|
160
|
-
const parts = args[0] instanceof
|
|
160
|
+
const parts = args[0] instanceof RegExpObj
|
|
161
161
|
? value.split(args[0].regex, requestedLimit)
|
|
162
162
|
: value.split(str("split", args, 0), requestedLimit === undefined ? undefined : requestedLimit >>> 0);
|
|
163
163
|
checkArrayLength(parts.length);
|
|
@@ -187,8 +187,8 @@ export const stringGlobal = (runner) => {
|
|
|
187
187
|
return null;
|
|
188
188
|
// Preserve the own `index` and `groups` properties on non-global matches.
|
|
189
189
|
if (pattern.global)
|
|
190
|
-
return toProgram(
|
|
191
|
-
return matchToValue(
|
|
190
|
+
return toProgram(builtins, matched, "String.match result");
|
|
191
|
+
return matchToValue(builtins, matched);
|
|
192
192
|
}),
|
|
193
193
|
simple("matchAll", 1, (value, args) => {
|
|
194
194
|
const pattern = toHostRegex(args[0], "matchAll", "g");
|
|
@@ -198,9 +198,9 @@ export const stringGlobal = (runner) => {
|
|
|
198
198
|
const matches = [];
|
|
199
199
|
for (const match of value.matchAll(pattern)) {
|
|
200
200
|
checkArrayLength(matches.length + 1);
|
|
201
|
-
matches.push(matchToValue(
|
|
201
|
+
matches.push(matchToValue(builtins, match));
|
|
202
202
|
}
|
|
203
|
-
return new
|
|
203
|
+
return new Arr(builtins.Array, matches);
|
|
204
204
|
}),
|
|
205
205
|
simple("search", 1, (value, args) => value.search(toHostRegex(args[0], "search"))),
|
|
206
206
|
simple("repeat", 1, (value, args) => {
|
package/dist/stdlib/url.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import {
|
|
3
|
-
export declare const uriArgument: (
|
|
1
|
+
import type { Builtins } from "../interpreter/intrinsics.js";
|
|
2
|
+
import type { Interpreter } from "../interpreter/interpreter.js";
|
|
3
|
+
export declare const uriArgument: (builtins: Builtins, value: unknown, label: string) => string;
|
|
4
4
|
type UriFunction = "encodeURI" | "encodeURIComponent" | "decodeURI" | "decodeURIComponent";
|
|
5
|
-
export declare const uriGlobal: <R>(
|
|
6
|
-
export declare const urlGlobal: <R>(
|
|
7
|
-
export declare const urlSearchParamsGlobal: <R>(
|
|
5
|
+
export declare const uriGlobal: <R>(ctx: Interpreter<R>, name: UriFunction) => import("../interpreter/objects.js").Native<R>;
|
|
6
|
+
export declare const urlGlobal: <R>(ctx: Interpreter<R>) => import("../interpreter/objects.js").Native<R>;
|
|
7
|
+
export declare const urlSearchParamsGlobal: <R>(ctx: Interpreter<R>) => import("../interpreter/objects.js").Native<R>;
|
|
8
8
|
export {};
|
package/dist/stdlib/url.js
CHANGED
|
@@ -2,9 +2,9 @@ import { Effect } from "effect";
|
|
|
2
2
|
import { toProgram, ToolRuntimeError } from "../data.js";
|
|
3
3
|
import { constructor, fn, methods, prototypeFrom, receiver, requiresNew } from "../interpreter/native.js";
|
|
4
4
|
import { PendingThrow, typeError, uriError } from "../interpreter/model.js";
|
|
5
|
-
import { defineAccessor, entries, isWrapper,
|
|
5
|
+
import { defineAccessor, entries, isWrapper, Arr, Obj, URLObj, URLSearchParamsObj } from "../interpreter/objects.js";
|
|
6
6
|
import { isRuntimeReference } from "../interpreter/references.js";
|
|
7
|
-
import { applyCollectionCallback, preserveConsumerError } from "../interpreter/
|
|
7
|
+
import { applyCollectionCallback, preserveConsumerError } from "../interpreter/callback.js";
|
|
8
8
|
import { coerceToString } from "./value.js";
|
|
9
9
|
const urlProperties = [
|
|
10
10
|
"href",
|
|
@@ -19,15 +19,15 @@ const urlProperties = [
|
|
|
19
19
|
"search",
|
|
20
20
|
"hash",
|
|
21
21
|
];
|
|
22
|
-
export const uriArgument = (
|
|
22
|
+
export const uriArgument = (builtins, value, label) => coerceToString(toProgram(builtins, value, label));
|
|
23
23
|
const uriFunctions = {
|
|
24
24
|
encodeURI,
|
|
25
25
|
encodeURIComponent,
|
|
26
26
|
decodeURI,
|
|
27
27
|
decodeURIComponent,
|
|
28
28
|
};
|
|
29
|
-
export const uriGlobal = (
|
|
30
|
-
const value = uriArgument(
|
|
29
|
+
export const uriGlobal = (ctx, name) => fn(ctx.builtins, name, 1, (_, args) => {
|
|
30
|
+
const value = uriArgument(ctx.builtins, args[0], `${name} input`);
|
|
31
31
|
try {
|
|
32
32
|
return uriFunctions[name](value);
|
|
33
33
|
}
|
|
@@ -35,24 +35,24 @@ export const uriGlobal = (runner, name) => fn(runner.prototypes, name, 1, (_, ar
|
|
|
35
35
|
throw uriError(`${name} received malformed URI data: ${error instanceof Error ? error.message : String(error)}`);
|
|
36
36
|
}
|
|
37
37
|
});
|
|
38
|
-
const urlArgument = (
|
|
39
|
-
export const urlGlobal = (
|
|
40
|
-
const
|
|
41
|
-
const proto =
|
|
38
|
+
const urlArgument = (builtins, value, label) => value instanceof URLObj ? value.url.href : uriArgument(builtins, value, label);
|
|
39
|
+
export const urlGlobal = (ctx) => {
|
|
40
|
+
const builtins = ctx.builtins;
|
|
41
|
+
const proto = builtins.URL;
|
|
42
42
|
const construct = (args, into) => {
|
|
43
43
|
if (args.length === 0) {
|
|
44
44
|
throw typeError("new URL(...) requires a URL string and an optional base URL.");
|
|
45
45
|
}
|
|
46
|
-
const input = urlArgument(
|
|
47
|
-
const base = args[1] === undefined ? undefined : urlArgument(
|
|
46
|
+
const input = urlArgument(builtins, args[0], "new URL input");
|
|
47
|
+
const base = args[1] === undefined ? undefined : urlArgument(builtins, args[1], "new URL base");
|
|
48
48
|
try {
|
|
49
|
-
return new
|
|
49
|
+
return new URLObj(into, builtins.URLSearchParams, new URL(input, base));
|
|
50
50
|
}
|
|
51
51
|
catch {
|
|
52
52
|
throw typeError(`new URL(...) received an invalid URL${base === undefined ? "" : " or base URL"}.`);
|
|
53
53
|
}
|
|
54
54
|
};
|
|
55
|
-
const url = constructor(
|
|
55
|
+
const url = constructor(builtins, proto, {
|
|
56
56
|
name: "URL",
|
|
57
57
|
length: 1,
|
|
58
58
|
call: requiresNew("URL"),
|
|
@@ -64,19 +64,19 @@ export const urlGlobal = (runner) => {
|
|
|
64
64
|
(_, args) => {
|
|
65
65
|
if (args.length === 0)
|
|
66
66
|
throw typeError(`URL.${name} requires a URL argument.`);
|
|
67
|
-
const input = urlArgument(
|
|
68
|
-
const base = args[1] === undefined ? undefined : urlArgument(
|
|
67
|
+
const input = urlArgument(builtins, args[0], `URL.${name} input`);
|
|
68
|
+
const base = args[1] === undefined ? undefined : urlArgument(builtins, args[1], `URL.${name} base`);
|
|
69
69
|
try {
|
|
70
70
|
const parsed = new URL(input, base);
|
|
71
|
-
return name === "canParse" ? true : new
|
|
71
|
+
return name === "canParse" ? true : new URLObj(proto, builtins.URLSearchParams, parsed);
|
|
72
72
|
}
|
|
73
73
|
catch {
|
|
74
74
|
return name === "canParse" ? false : null;
|
|
75
75
|
}
|
|
76
76
|
},
|
|
77
77
|
];
|
|
78
|
-
methods(
|
|
79
|
-
const self = (thisValue, name) => receiver(
|
|
78
|
+
methods(builtins, url, [parse("canParse"), parse("parse")]);
|
|
79
|
+
const self = (thisValue, name) => receiver(URLObj, thisValue, `URL.prototype.${name}`);
|
|
80
80
|
for (const name of urlProperties) {
|
|
81
81
|
defineAccessor(proto, name, (thisValue) => self(thisValue, name).url[name], name === "origin"
|
|
82
82
|
? undefined
|
|
@@ -84,7 +84,7 @@ export const urlGlobal = (runner) => {
|
|
|
84
84
|
const target = self(thisValue, name);
|
|
85
85
|
try {
|
|
86
86
|
;
|
|
87
|
-
target.url[name] = uriArgument(
|
|
87
|
+
target.url[name] = uriArgument(builtins, value, `URL.${name} value`);
|
|
88
88
|
}
|
|
89
89
|
catch (error) {
|
|
90
90
|
if (error instanceof PendingThrow || error instanceof ToolRuntimeError)
|
|
@@ -94,14 +94,14 @@ export const urlGlobal = (runner) => {
|
|
|
94
94
|
});
|
|
95
95
|
}
|
|
96
96
|
defineAccessor(proto, "searchParams", (thisValue) => self(thisValue, "searchParams").searchParams);
|
|
97
|
-
methods(
|
|
97
|
+
methods(builtins, proto, [
|
|
98
98
|
["toString", 0, (thisValue) => self(thisValue, "toString").url.href],
|
|
99
99
|
["toJSON", 0, (thisValue) => self(thisValue, "toJSON").url.href],
|
|
100
100
|
]);
|
|
101
101
|
return url;
|
|
102
102
|
};
|
|
103
|
-
const readPair = (
|
|
104
|
-
const cursor = yield*
|
|
103
|
+
const readPair = (ctx, value) => Effect.gen(function* () {
|
|
104
|
+
const cursor = yield* ctx.iterate(value);
|
|
105
105
|
if (cursor === undefined) {
|
|
106
106
|
throw typeError("new URLSearchParams(...) expects iterable [name, value] pairs.");
|
|
107
107
|
}
|
|
@@ -110,14 +110,14 @@ const readPair = (runner, value) => Effect.gen(function* () {
|
|
|
110
110
|
const step = yield* cursor.next;
|
|
111
111
|
if (step.done)
|
|
112
112
|
return items;
|
|
113
|
-
items.push(yield* preserveConsumerError(cursor, Effect.sync(() => uriArgument(
|
|
113
|
+
items.push(yield* preserveConsumerError(cursor, Effect.sync(() => uriArgument(ctx.builtins, step.value, "URLSearchParams pair value"))));
|
|
114
114
|
}
|
|
115
115
|
});
|
|
116
|
-
const constructURLSearchParams = (
|
|
117
|
-
const wrap = (params) => new
|
|
116
|
+
const constructURLSearchParams = (ctx, init, proto) => {
|
|
117
|
+
const wrap = (params) => new URLSearchParamsObj(proto, params);
|
|
118
118
|
if (init === undefined)
|
|
119
119
|
return Effect.succeed(wrap(new URLSearchParams()));
|
|
120
|
-
if (init instanceof
|
|
120
|
+
if (init instanceof URLSearchParamsObj)
|
|
121
121
|
return Effect.succeed(wrap(new URLSearchParams(init.params)));
|
|
122
122
|
if (typeof init === "string")
|
|
123
123
|
return Effect.succeed(wrap(new URLSearchParams(init)));
|
|
@@ -125,7 +125,7 @@ const constructURLSearchParams = (runner, init, proto) => {
|
|
|
125
125
|
return Effect.succeed(wrap(new URLSearchParams(coerceToString(init))));
|
|
126
126
|
}
|
|
127
127
|
return Effect.gen(function* () {
|
|
128
|
-
const cursor = yield*
|
|
128
|
+
const cursor = yield* ctx.iterate(init);
|
|
129
129
|
if (cursor !== undefined) {
|
|
130
130
|
const pairs = [];
|
|
131
131
|
while (true) {
|
|
@@ -136,7 +136,7 @@ const constructURLSearchParams = (runner, init, proto) => {
|
|
|
136
136
|
}
|
|
137
137
|
return wrap(new URLSearchParams(pairs.map((entry) => [entry[0] ?? "", entry[1] ?? ""])));
|
|
138
138
|
}
|
|
139
|
-
pairs.push(yield* preserveConsumerError(cursor, readPair(
|
|
139
|
+
pairs.push(yield* preserveConsumerError(cursor, readPair(ctx, step.value)));
|
|
140
140
|
}
|
|
141
141
|
}
|
|
142
142
|
if (isRuntimeReference(init)) {
|
|
@@ -144,30 +144,30 @@ const constructURLSearchParams = (runner, init, proto) => {
|
|
|
144
144
|
}
|
|
145
145
|
if (isWrapper(init))
|
|
146
146
|
return wrap(new URLSearchParams());
|
|
147
|
-
if (!(init instanceof
|
|
147
|
+
if (!(init instanceof Obj)) {
|
|
148
148
|
throw typeError("new URLSearchParams(...) expects a query string, data object, iterable pairs, or URLSearchParams.");
|
|
149
149
|
}
|
|
150
150
|
return wrap(new URLSearchParams(Object.fromEntries(entries(init).map(([key, value]) => [key, coerceToString(value)]))));
|
|
151
151
|
});
|
|
152
152
|
};
|
|
153
|
-
export const urlSearchParamsGlobal = (
|
|
154
|
-
const
|
|
155
|
-
const proto =
|
|
156
|
-
const searchParams = constructor(
|
|
153
|
+
export const urlSearchParamsGlobal = (ctx) => {
|
|
154
|
+
const builtins = ctx.builtins;
|
|
155
|
+
const proto = builtins.URLSearchParams;
|
|
156
|
+
const searchParams = constructor(builtins, proto, {
|
|
157
157
|
name: "URLSearchParams",
|
|
158
158
|
call: requiresNew("URLSearchParams"),
|
|
159
|
-
construct: (args, newTarget) => constructURLSearchParams(
|
|
159
|
+
construct: (args, newTarget) => constructURLSearchParams(ctx, args[0], prototypeFrom(newTarget, proto)),
|
|
160
160
|
});
|
|
161
|
-
const self = (thisValue, name) => receiver(
|
|
162
|
-
const wrap = (items) => new
|
|
163
|
-
const arg = (name, args, index) => uriArgument(
|
|
161
|
+
const self = (thisValue, name) => receiver(URLSearchParamsObj, thisValue, `URLSearchParams.prototype.${name}`);
|
|
162
|
+
const wrap = (items) => new Arr(builtins.Array, items);
|
|
163
|
+
const arg = (name, args, index) => uriArgument(builtins, args[index], `URLSearchParams.${name} argument ${index + 1}`);
|
|
164
164
|
const requireArgs = (name, args, count) => {
|
|
165
165
|
if (args.length < count) {
|
|
166
166
|
throw typeError(`URLSearchParams.${name} requires ${count} argument${count === 1 ? "" : "s"}.`);
|
|
167
167
|
}
|
|
168
168
|
};
|
|
169
169
|
defineAccessor(proto, "size", (thisValue) => self(thisValue, "size").params.size);
|
|
170
|
-
methods(
|
|
170
|
+
methods(builtins, proto, [
|
|
171
171
|
[
|
|
172
172
|
"append",
|
|
173
173
|
2,
|
|
@@ -248,7 +248,7 @@ export const urlSearchParamsGlobal = (runner) => {
|
|
|
248
248
|
(thisValue, args) => {
|
|
249
249
|
requireArgs("forEach", args, 1);
|
|
250
250
|
const target = self(thisValue, "forEach");
|
|
251
|
-
const apply = applyCollectionCallback(
|
|
251
|
+
const apply = applyCollectionCallback(ctx, args[0], "URLSearchParams.forEach");
|
|
252
252
|
return Effect.gen(function* () {
|
|
253
253
|
for (const [key, value] of Array.from(target.params.entries()))
|
|
254
254
|
yield* apply([value, key, target]);
|
package/dist/stdlib/value.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { type
|
|
2
|
-
import type {
|
|
1
|
+
import { type Native } from "../interpreter/objects.js";
|
|
2
|
+
import type { Interpreter } from "../interpreter/interpreter.js";
|
|
3
3
|
export declare const compoundOperators: Set<string>;
|
|
4
4
|
/** The built-in string form of a value, without consulting program-defined `toString` methods. */
|
|
5
5
|
export declare const coerceToString: (value: unknown) => string;
|
|
6
6
|
export declare const coerceToNumber: (value: unknown) => number;
|
|
7
7
|
export type Coercion = "Number" | "String" | "Boolean" | "parseInt" | "parseFloat" | "isFinite" | "isNaN";
|
|
8
8
|
/** A global coercion function such as `Number` or `parseInt`. */
|
|
9
|
-
export declare const coercion: <R>(
|
|
9
|
+
export declare const coercion: <R>(ctx: Interpreter<R>, name: Coercion, length?: number) => Native<R>;
|
package/dist/stdlib/value.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { toProgram } from "../data.js";
|
|
2
2
|
import { fn } from "../interpreter/native.js";
|
|
3
3
|
import { typeError } from "../interpreter/model.js";
|
|
4
|
-
import { get, isWrapper,
|
|
4
|
+
import { get, isWrapper, Arr, Bytes, DateObj, ErrorObj, MapObj, RegExpObj, SetObj, URLObj, URLSearchParamsObj, } from "../interpreter/objects.js";
|
|
5
5
|
export const compoundOperators = new Set(["+=", "-=", "*=", "/=", "%=", "**=", "&=", "|=", "^=", "<<=", ">>=", ">>>="]);
|
|
6
6
|
/** The built-in string form of a value, without consulting program-defined `toString` methods. */
|
|
7
7
|
export const coerceToString = (value) => {
|
|
@@ -9,19 +9,21 @@ export const coerceToString = (value) => {
|
|
|
9
9
|
return "null";
|
|
10
10
|
if (value === undefined)
|
|
11
11
|
return "undefined";
|
|
12
|
-
if (value instanceof
|
|
12
|
+
if (value instanceof DateObj)
|
|
13
13
|
return Number.isFinite(value.time) ? new Date(value.time).toISOString() : "Invalid Date";
|
|
14
|
-
if (value instanceof
|
|
14
|
+
if (value instanceof RegExpObj)
|
|
15
15
|
return `/${value.regex.source}/${value.regex.flags}`;
|
|
16
|
-
if (value instanceof
|
|
16
|
+
if (value instanceof MapObj)
|
|
17
17
|
return "[object Map]";
|
|
18
|
-
if (value instanceof
|
|
18
|
+
if (value instanceof SetObj)
|
|
19
19
|
return "[object Set]";
|
|
20
|
-
if (value instanceof
|
|
20
|
+
if (value instanceof URLObj)
|
|
21
21
|
return value.url.href;
|
|
22
|
-
if (value instanceof
|
|
22
|
+
if (value instanceof URLSearchParamsObj)
|
|
23
23
|
return value.params.toString();
|
|
24
|
-
if (value instanceof
|
|
24
|
+
if (value instanceof Bytes)
|
|
25
|
+
return value.bytes.join(",");
|
|
26
|
+
if (value instanceof ErrorObj) {
|
|
25
27
|
// Match Error.prototype.toString: "name: message", or just one when the other is empty.
|
|
26
28
|
const name = get(value, "name");
|
|
27
29
|
const message = get(value, "message");
|
|
@@ -33,7 +35,7 @@ export const coerceToString = (value) => {
|
|
|
33
35
|
return shownMessage;
|
|
34
36
|
return `${shownName}: ${shownMessage}`;
|
|
35
37
|
}
|
|
36
|
-
if (value instanceof
|
|
38
|
+
if (value instanceof Arr) {
|
|
37
39
|
return value.items.map((item) => (item === null || item === undefined ? "" : coerceToString(item))).join(",");
|
|
38
40
|
}
|
|
39
41
|
if (typeof value === "object")
|
|
@@ -41,15 +43,17 @@ export const coerceToString = (value) => {
|
|
|
41
43
|
return String(value);
|
|
42
44
|
};
|
|
43
45
|
export const coerceToNumber = (value) => {
|
|
44
|
-
if (value instanceof
|
|
46
|
+
if (value instanceof DateObj)
|
|
45
47
|
return value.time;
|
|
48
|
+
if (value instanceof Bytes)
|
|
49
|
+
return Number(coerceToString(value));
|
|
46
50
|
if (isWrapper(value))
|
|
47
51
|
return Number.NaN;
|
|
48
|
-
if (value instanceof
|
|
52
|
+
if (value instanceof Arr)
|
|
49
53
|
return Number(coerceToString(value));
|
|
50
54
|
return value !== null && typeof value === "object" ? Number.NaN : Number(value);
|
|
51
55
|
};
|
|
52
|
-
const coerce = (
|
|
56
|
+
const coerce = (ctx, name, args) => {
|
|
53
57
|
// Native: Number() is 0 and String() is "", unlike their undefined-argument forms; the
|
|
54
58
|
// other coercers match native through the undefined-argument path below.
|
|
55
59
|
if (args.length === 0) {
|
|
@@ -74,7 +78,7 @@ const coerce = (runner, name, args) => {
|
|
|
74
78
|
return parseInt(coerceToString(raw));
|
|
75
79
|
return parseFloat(coerceToString(raw));
|
|
76
80
|
}
|
|
77
|
-
const value = toProgram(
|
|
81
|
+
const value = toProgram(ctx.builtins, raw, `${name} input`);
|
|
78
82
|
if (name === "Number")
|
|
79
83
|
return coerceToNumber(value);
|
|
80
84
|
if (name === "Boolean")
|
|
@@ -95,4 +99,4 @@ const coerce = (runner, name, args) => {
|
|
|
95
99
|
return coerceToString(value);
|
|
96
100
|
};
|
|
97
101
|
/** A global coercion function such as `Number` or `parseInt`. */
|
|
98
|
-
export const coercion = (
|
|
102
|
+
export const coercion = (ctx, name, length = 1) => fn(ctx.builtins, name, length, (_, args) => toProgram(ctx.builtins, coerce(ctx, name, args), `${name} result`));
|
package/dist/stdlib/web.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import type {
|
|
3
|
-
export declare const base64Global: <R>(
|
|
4
|
-
export declare const cryptoGlobal: <R>(
|
|
1
|
+
import { Obj } from "../interpreter/objects.js";
|
|
2
|
+
import type { Interpreter } from "../interpreter/interpreter.js";
|
|
3
|
+
export declare const base64Global: <R>(ctx: Interpreter<R>, name: "atob" | "btoa") => import("../interpreter/objects.js").Native<R>;
|
|
4
|
+
export declare const cryptoGlobal: <R>(ctx: Interpreter<R>) => Obj;
|
package/dist/stdlib/web.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { fn, methods } from "../interpreter/native.js";
|
|
2
2
|
import { typeError } from "../interpreter/model.js";
|
|
3
|
-
import {
|
|
3
|
+
import { Bytes, Obj } from "../interpreter/objects.js";
|
|
4
|
+
import { describeValue } from "../interpreter/references.js";
|
|
4
5
|
import { coerceToString } from "./value.js";
|
|
5
6
|
// WebIDL DOMString conversion: a missing argument is a TypeError, anything else stringifies. Invalid input is a
|
|
6
7
|
// TypeError as well; browsers throw a DOMException named InvalidCharacterError, which CodeMode does not have.
|
|
7
|
-
export const base64Global = (
|
|
8
|
+
export const base64Global = (ctx, name) => fn(ctx.builtins, name, 1, (_, args) => {
|
|
8
9
|
if (args.length === 0)
|
|
9
10
|
throw typeError(`${name} requires 1 argument (a string)`);
|
|
10
11
|
const input = coerceToString(args[0]);
|
|
@@ -15,8 +16,21 @@ export const base64Global = (runner, name) => fn(runner.prototypes, name, 1, (_,
|
|
|
15
16
|
throw typeError("The string contains invalid characters.");
|
|
16
17
|
}
|
|
17
18
|
});
|
|
18
|
-
export const cryptoGlobal = (
|
|
19
|
-
const object = new
|
|
20
|
-
methods(
|
|
19
|
+
export const cryptoGlobal = (ctx) => {
|
|
20
|
+
const object = new Obj(ctx.builtins.Object);
|
|
21
|
+
methods(ctx.builtins, object, [
|
|
22
|
+
["randomUUID", 0, () => crypto.randomUUID()],
|
|
23
|
+
[
|
|
24
|
+
"getRandomValues",
|
|
25
|
+
1,
|
|
26
|
+
(_, args) => {
|
|
27
|
+
if (!(args[0] instanceof Bytes)) {
|
|
28
|
+
throw typeError(`crypto.getRandomValues expects a Uint8Array, received ${describeValue(args[0])}.`);
|
|
29
|
+
}
|
|
30
|
+
crypto.getRandomValues(args[0].bytes);
|
|
31
|
+
return args[0];
|
|
32
|
+
},
|
|
33
|
+
],
|
|
34
|
+
]);
|
|
21
35
|
return object;
|
|
22
36
|
};
|