@opencode/codemode 0.0.0-dev-19530 → 2.0.0
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/data.d.ts +5 -6
- package/dist/data.js +44 -47
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/interpreter/errors.d.ts +3 -5
- package/dist/interpreter/errors.js +22 -51
- package/dist/interpreter/execute.js +3 -5
- package/dist/interpreter/globals.js +47 -69
- package/dist/interpreter/host.d.ts +41 -0
- package/dist/interpreter/host.js +44 -0
- package/dist/interpreter/methods.d.ts +4 -0
- package/dist/interpreter/methods.js +837 -0
- package/dist/interpreter/model.d.ts +36 -13
- package/dist/interpreter/model.js +45 -15
- package/dist/interpreter/objects.d.ts +13 -106
- package/dist/interpreter/objects.js +65 -192
- package/dist/interpreter/promises.d.ts +13 -12
- package/dist/interpreter/promises.js +54 -59
- package/dist/interpreter/references.d.ts +0 -1
- package/dist/interpreter/references.js +33 -20
- package/dist/interpreter/runner.d.ts +11 -15
- package/dist/interpreter/runner.js +21 -21
- package/dist/interpreter/runtime.d.ts +3 -3
- package/dist/interpreter/runtime.js +327 -165
- package/dist/interpreter/scope.js +6 -6
- package/dist/stdlib/array.d.ts +2 -4
- package/dist/stdlib/array.js +32 -424
- package/dist/stdlib/collections.d.ts +7 -3
- package/dist/stdlib/collections.js +119 -291
- package/dist/stdlib/console.d.ts +2 -3
- package/dist/stdlib/console.js +30 -35
- package/dist/stdlib/date.d.ts +7 -1
- package/dist/stdlib/date.js +188 -93
- package/dist/stdlib/json.d.ts +2 -2
- package/dist/stdlib/json.js +27 -27
- package/dist/stdlib/math.d.ts +2 -2
- package/dist/stdlib/math.js +76 -96
- package/dist/stdlib/number.d.ts +4 -3
- package/dist/stdlib/number.js +60 -95
- package/dist/stdlib/object.d.ts +4 -4
- package/dist/stdlib/object.js +54 -128
- package/dist/stdlib/regexp.d.ts +8 -6
- package/dist/stdlib/regexp.js +68 -76
- package/dist/stdlib/string.d.ts +2 -2
- package/dist/stdlib/string.js +50 -213
- package/dist/stdlib/url.d.ts +13 -5
- package/dist/stdlib/url.js +102 -202
- package/dist/stdlib/value.d.ts +9 -5
- package/dist/stdlib/value.js +38 -16
- package/dist/stdlib/web.d.ts +4 -4
- package/dist/stdlib/web.js +10 -12
- package/dist/tool-runtime.d.ts +1 -2
- package/dist/tool-runtime.js +2 -2
- package/dist/values.d.ts +37 -0
- package/dist/values.js +56 -0
- package/package.json +1 -1
- package/dist/interpreter/generators.d.ts +0 -4
- package/dist/interpreter/generators.js +0 -25
- package/dist/interpreter/intrinsics.d.ts +0 -13
- package/dist/interpreter/intrinsics.js +0 -82
- package/dist/interpreter/native.d.ts +0 -19
- package/dist/interpreter/native.js +0 -40
package/dist/stdlib/string.js
CHANGED
|
@@ -1,214 +1,51 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
1
|
+
import { sync } from "../interpreter/host.js";
|
|
2
|
+
import { InterpreterRuntimeError } from "../interpreter/model.js";
|
|
3
|
+
import { coercion } from "./value.js";
|
|
4
|
+
export const stringMethods = new Set([
|
|
5
|
+
"toLowerCase",
|
|
6
|
+
"toUpperCase",
|
|
7
|
+
"trim",
|
|
8
|
+
"trimStart",
|
|
9
|
+
"trimEnd",
|
|
10
|
+
"trimLeft",
|
|
11
|
+
"trimRight",
|
|
12
|
+
"split",
|
|
13
|
+
"slice",
|
|
14
|
+
"substring",
|
|
15
|
+
"substr",
|
|
16
|
+
"includes",
|
|
17
|
+
"startsWith",
|
|
18
|
+
"endsWith",
|
|
19
|
+
"indexOf",
|
|
20
|
+
"lastIndexOf",
|
|
21
|
+
"replace",
|
|
22
|
+
"replaceAll",
|
|
23
|
+
"repeat",
|
|
24
|
+
"padStart",
|
|
25
|
+
"padEnd",
|
|
26
|
+
"charAt",
|
|
27
|
+
"charCodeAt",
|
|
28
|
+
"codePointAt",
|
|
29
|
+
"at",
|
|
30
|
+
"concat",
|
|
31
|
+
"toString",
|
|
32
|
+
"match",
|
|
33
|
+
"matchAll",
|
|
34
|
+
"search",
|
|
35
|
+
"localeCompare",
|
|
36
|
+
"normalize",
|
|
37
|
+
"isWellFormed",
|
|
38
|
+
"toWellFormed",
|
|
39
|
+
]);
|
|
40
|
+
const codeUnits = (name, op) => sync(`String.${name}`, (args, node) => op(...args.map((arg) => {
|
|
41
|
+
if (typeof arg !== "number")
|
|
42
|
+
throw new InterpreterRuntimeError(`String.${name} expects number arguments.`, node);
|
|
15
43
|
return arg;
|
|
16
|
-
};
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
const apply = applyCollectionCallback(runner, args[1], `String.${name}`, node);
|
|
25
|
-
const matches = [];
|
|
26
|
-
const collect = (...callbackArgs) => {
|
|
27
|
-
const match = callbackArgs[0];
|
|
28
|
-
const groups = callbackArgs[callbackArgs.length - 1];
|
|
29
|
-
const hasGroups = groups !== null && typeof groups === "object";
|
|
30
|
-
const offset = callbackArgs[callbackArgs.length - (hasGroups ? 3 : 2)];
|
|
31
|
-
if (typeof match !== "string" || typeof offset !== "number") {
|
|
32
|
-
throw new InterpreterRuntimeError(`String.${name} produced an invalid replacement match.`, node);
|
|
33
|
-
}
|
|
34
|
-
if (hasGroups)
|
|
35
|
-
callbackArgs[callbackArgs.length - 1] = record(protos.Object, groups);
|
|
36
|
-
matches.push({ match, offset, args: callbackArgs });
|
|
37
|
-
return match;
|
|
38
|
-
};
|
|
39
|
-
const pattern = args[0];
|
|
40
|
-
if (pattern instanceof ProgramRegExp) {
|
|
41
|
-
if (name === "replaceAll")
|
|
42
|
-
replaceAllNeedsGlobal(pattern.regex, node);
|
|
43
|
-
if (name === "replace")
|
|
44
|
-
value.replace(pattern.regex, collect);
|
|
45
|
-
else
|
|
46
|
-
value.replaceAll(pattern.regex, collect);
|
|
47
|
-
}
|
|
48
|
-
else {
|
|
49
|
-
const search = coerceToString(requireDataArgument(name, 0, pattern, node));
|
|
50
|
-
if (name === "replace")
|
|
51
|
-
value.replace(search, collect);
|
|
52
|
-
else
|
|
53
|
-
value.replaceAll(search, collect);
|
|
54
|
-
}
|
|
55
|
-
return Effect.gen(function* () {
|
|
56
|
-
const output = [];
|
|
57
|
-
let end = 0;
|
|
58
|
-
for (const match of matches) {
|
|
59
|
-
const replacement = yield* apply(match.args);
|
|
60
|
-
output.push(value.slice(end, match.offset), replacement instanceof ProgramPromise
|
|
61
|
-
? "[object Promise]"
|
|
62
|
-
: coerceToString(toProgram(protos, replacement, `String.${name} replacer result`)));
|
|
63
|
-
end = match.offset + match.match.length;
|
|
64
|
-
}
|
|
65
|
-
output.push(value.slice(end));
|
|
66
|
-
return output.join("");
|
|
67
|
-
});
|
|
68
|
-
};
|
|
69
|
-
export const stringGlobal = (runner) => {
|
|
70
|
-
const protos = runner.prototypes;
|
|
71
|
-
const string = constructor(protos, protos.String, {
|
|
72
|
-
name: "String",
|
|
73
|
-
length: 1,
|
|
74
|
-
call: coercion(runner, "String").call,
|
|
75
|
-
});
|
|
76
|
-
const codeUnits = (name, op) => [
|
|
77
|
-
name,
|
|
78
|
-
1,
|
|
79
|
-
(_, args, node) => op(...args.map((arg) => {
|
|
80
|
-
if (typeof arg !== "number") {
|
|
81
|
-
throw new InterpreterRuntimeError(`String.${name} expects number arguments.`, node);
|
|
82
|
-
}
|
|
83
|
-
return arg;
|
|
84
|
-
})),
|
|
85
|
-
];
|
|
86
|
-
methods(protos, string, [
|
|
87
|
-
codeUnits("fromCharCode", String.fromCharCode),
|
|
88
|
-
codeUnits("fromCodePoint", String.fromCodePoint),
|
|
89
|
-
]);
|
|
90
|
-
const self = (thisValue, name, node) => {
|
|
91
|
-
if (typeof thisValue === "string")
|
|
92
|
-
return thisValue;
|
|
93
|
-
if (thisValue === null || thisValue === undefined) {
|
|
94
|
-
throw new InterpreterRuntimeError(`String.prototype.${name} called on null or undefined.`, node);
|
|
95
|
-
}
|
|
96
|
-
return coerceToString(thisValue);
|
|
97
|
-
};
|
|
98
|
-
// Coerce arguments like native JS; opaque runtime references still reject.
|
|
99
|
-
const str = (name, args, index, node) => coerceToString(requireDataArgument(name, index, args[index], node));
|
|
100
|
-
const num = (name, args, index, node) => coerceToNumber(requireDataArgument(name, index, args[index], node));
|
|
101
|
-
const optNum = (name, args, index, node) => args[index] === undefined ? undefined : num(name, args, index, node);
|
|
102
|
-
const optStr = (name, args, index, node) => args[index] === undefined ? undefined : str(name, args, index, node);
|
|
103
|
-
const rejectRegex = (name, args, node) => {
|
|
104
|
-
if (args[0] instanceof ProgramRegExp) {
|
|
105
|
-
throw new InterpreterRuntimeError(`String.${name} cannot take a regular expression; use regex.test(string) or String.search instead.`, node);
|
|
106
|
-
}
|
|
107
|
-
};
|
|
108
|
-
const simple = (name, length, op) => [name, length, (thisValue, args, node) => op(self(thisValue, name, node), args, node)];
|
|
109
|
-
const replace = (name) => simple(name, 2, (value, args, node) => {
|
|
110
|
-
if (isSupportedCallback(args[1]))
|
|
111
|
-
return replaceWithCallback(runner, value, name, args, node);
|
|
112
|
-
if (typeofValue(args[1]) === "function") {
|
|
113
|
-
throw new InterpreterRuntimeError(`String.${name} cannot use this callable as a replacer; wrap it in an arrow function, e.g. (match) => tools.ns.tool(match).`, node);
|
|
114
|
-
}
|
|
115
|
-
if (args[0] instanceof ProgramRegExp) {
|
|
116
|
-
const pattern = args[0].regex;
|
|
117
|
-
const replacement = str(name, args, 1, node);
|
|
118
|
-
if (name === "replaceAll")
|
|
119
|
-
replaceAllNeedsGlobal(pattern, node);
|
|
120
|
-
return name === "replace" ? value.replace(pattern, replacement) : value.replaceAll(pattern, replacement);
|
|
121
|
-
}
|
|
122
|
-
if (name === "replace")
|
|
123
|
-
return value.replace(str(name, args, 0, node), str(name, args, 1, node));
|
|
124
|
-
return value.replaceAll(str(name, args, 0, node), str(name, args, 1, node));
|
|
125
|
-
});
|
|
126
|
-
methods(protos, protos.String, [
|
|
127
|
-
simple("toString", 0, (value) => value),
|
|
128
|
-
simple("valueOf", 0, (value) => value),
|
|
129
|
-
simple("toLowerCase", 0, (value) => value.toLowerCase()),
|
|
130
|
-
simple("toUpperCase", 0, (value) => value.toUpperCase()),
|
|
131
|
-
simple("trim", 0, (value) => value.trim()),
|
|
132
|
-
simple("trimStart", 0, (value) => value.trimStart()),
|
|
133
|
-
simple("trimLeft", 0, (value) => value.trimStart()),
|
|
134
|
-
simple("trimEnd", 0, (value) => value.trimEnd()),
|
|
135
|
-
simple("trimRight", 0, (value) => value.trimEnd()),
|
|
136
|
-
// Locale/options are deliberately unsupported; comparison uses the host default locale.
|
|
137
|
-
simple("localeCompare", 1, (value, args, node) => value.localeCompare(str("localeCompare", args, 0, node))),
|
|
138
|
-
simple("normalize", 0, (value, args, node) => {
|
|
139
|
-
const form = optStr("normalize", args, 0, node);
|
|
140
|
-
try {
|
|
141
|
-
return value.normalize(form);
|
|
142
|
-
}
|
|
143
|
-
catch {
|
|
144
|
-
throw rangeError(`String.normalize expects the form "NFC", "NFD", "NFKC", or "NFKD" (got ${JSON.stringify(form)}).`, node);
|
|
145
|
-
}
|
|
146
|
-
}),
|
|
147
|
-
simple("split", 2, (value, args, node) => {
|
|
148
|
-
const wrap = (parts) => new ProgramArray(protos.Array, parts);
|
|
149
|
-
// Native: an undefined separator returns the whole string, not a split on "undefined",
|
|
150
|
-
// unless the limit truncates to zero.
|
|
151
|
-
const requestedLimit = optNum("split", args, 1, node);
|
|
152
|
-
if (args[0] === undefined) {
|
|
153
|
-
return wrap(requestedLimit !== undefined && requestedLimit >>> 0 === 0 ? [] : [value]);
|
|
154
|
-
}
|
|
155
|
-
if (args[0] instanceof ProgramRegExp)
|
|
156
|
-
return wrap(value.split(args[0].regex, requestedLimit));
|
|
157
|
-
return wrap(value.split(str("split", args, 0, node), requestedLimit === undefined ? undefined : requestedLimit >>> 0));
|
|
158
|
-
}),
|
|
159
|
-
simple("slice", 2, (value, args, node) => value.slice(optNum("slice", args, 0, node), optNum("slice", args, 1, node))),
|
|
160
|
-
simple("includes", 1, (value, args, node) => {
|
|
161
|
-
rejectRegex("includes", args, node);
|
|
162
|
-
return value.includes(str("includes", args, 0, node), optNum("includes", args, 1, node));
|
|
163
|
-
}),
|
|
164
|
-
simple("startsWith", 1, (value, args, node) => {
|
|
165
|
-
rejectRegex("startsWith", args, node);
|
|
166
|
-
return value.startsWith(str("startsWith", args, 0, node), optNum("startsWith", args, 1, node));
|
|
167
|
-
}),
|
|
168
|
-
simple("endsWith", 1, (value, args, node) => {
|
|
169
|
-
rejectRegex("endsWith", args, node);
|
|
170
|
-
return value.endsWith(str("endsWith", args, 0, node), optNum("endsWith", args, 1, node));
|
|
171
|
-
}),
|
|
172
|
-
simple("indexOf", 1, (value, args, node) => value.indexOf(str("indexOf", args, 0, node), optNum("indexOf", args, 1, node))),
|
|
173
|
-
simple("lastIndexOf", 1, (value, args, node) => value.lastIndexOf(str("lastIndexOf", args, 0, node), optNum("lastIndexOf", args, 1, node))),
|
|
174
|
-
replace("replace"),
|
|
175
|
-
replace("replaceAll"),
|
|
176
|
-
simple("match", 1, (value, args, node) => {
|
|
177
|
-
const pattern = toHostRegex(args[0], "match", node);
|
|
178
|
-
const matched = value.match(pattern);
|
|
179
|
-
if (matched === null)
|
|
180
|
-
return null;
|
|
181
|
-
// Preserve the own `index` and `groups` properties on non-global matches.
|
|
182
|
-
if (pattern.global)
|
|
183
|
-
return toProgram(protos, matched, "String.match result");
|
|
184
|
-
return matchToValue(protos, matched);
|
|
185
|
-
}),
|
|
186
|
-
simple("matchAll", 1, (value, args, node) => {
|
|
187
|
-
const pattern = toHostRegex(args[0], "matchAll", node, "g");
|
|
188
|
-
if (!pattern.global) {
|
|
189
|
-
throw new InterpreterRuntimeError(`String.matchAll requires a regular expression with the global (g) flag: write /${pattern.source}/${pattern.flags}g, or use String.match for a single match.`, node);
|
|
190
|
-
}
|
|
191
|
-
return new ProgramArray(protos.Array, Array.from(value.matchAll(pattern), (match) => matchToValue(protos, match)));
|
|
192
|
-
}),
|
|
193
|
-
simple("search", 1, (value, args, node) => value.search(toHostRegex(args[0], "search", node))),
|
|
194
|
-
simple("repeat", 1, (value, args, node) => {
|
|
195
|
-
const count = num("repeat", args, 0, node);
|
|
196
|
-
if (!Number.isFinite(count) || count < 0) {
|
|
197
|
-
throw rangeError("String.repeat expects a finite non-negative count.", node);
|
|
198
|
-
}
|
|
199
|
-
return value.repeat(count);
|
|
200
|
-
}),
|
|
201
|
-
simple("padStart", 1, (value, args, node) => value.padStart(num("padStart", args, 0, node), optStr("padStart", args, 1, node))),
|
|
202
|
-
simple("padEnd", 1, (value, args, node) => value.padEnd(num("padEnd", args, 0, node), optStr("padEnd", args, 1, node))),
|
|
203
|
-
simple("charAt", 1, (value, args, node) => value.charAt(optNum("charAt", args, 0, node) ?? 0)),
|
|
204
|
-
simple("at", 1, (value, args, node) => value.at(optNum("at", args, 0, node) ?? 0)),
|
|
205
|
-
simple("substring", 2, (value, args, node) => value.substring(optNum("substring", args, 0, node) ?? 0, optNum("substring", args, 1, node))),
|
|
206
|
-
simple("substr", 2, (value, args, node) => value.substr(optNum("substr", args, 0, node) ?? 0, optNum("substr", args, 1, node))),
|
|
207
|
-
simple("isWellFormed", 0, (value) => value.isWellFormed()),
|
|
208
|
-
simple("toWellFormed", 0, (value) => value.toWellFormed()),
|
|
209
|
-
simple("charCodeAt", 1, (value, args, node) => value.charCodeAt(optNum("charCodeAt", args, 0, node) ?? 0)),
|
|
210
|
-
simple("codePointAt", 1, (value, args, node) => value.codePointAt(optNum("codePointAt", args, 0, node) ?? 0)),
|
|
211
|
-
simple("concat", 1, (value, args, node) => value.concat(...args.map((_, index) => str("concat", args, index, node)))),
|
|
212
|
-
]);
|
|
213
|
-
return string;
|
|
214
|
-
};
|
|
44
|
+
})));
|
|
45
|
+
export const stringGlobal = coercion("String", {
|
|
46
|
+
instanceOf: () => false,
|
|
47
|
+
members: {
|
|
48
|
+
fromCharCode: codeUnits("fromCharCode", String.fromCharCode),
|
|
49
|
+
fromCodePoint: codeUnits("fromCodePoint", String.fromCodePoint),
|
|
50
|
+
},
|
|
51
|
+
});
|
package/dist/stdlib/url.d.ts
CHANGED
|
@@ -1,8 +1,16 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { HostFunction } from "../interpreter/host.js";
|
|
2
|
+
import { type AstNode } from "../interpreter/model.js";
|
|
2
3
|
import { type Runner } from "../interpreter/runner.js";
|
|
3
|
-
|
|
4
|
+
import { Values } from "../values.js";
|
|
5
|
+
export declare const urlProperties: Set<string>;
|
|
6
|
+
export declare const urlWritableProperties: Set<string>;
|
|
7
|
+
export declare const urlMethods: Set<string>;
|
|
8
|
+
export declare const urlSearchParamsMethods: Set<string>;
|
|
9
|
+
export declare const uriArgument: (value: unknown, label: string) => string;
|
|
4
10
|
type UriFunction = "encodeURI" | "encodeURIComponent" | "decodeURI" | "decodeURIComponent";
|
|
5
|
-
export declare const uriGlobal:
|
|
6
|
-
export declare const
|
|
7
|
-
export declare const
|
|
11
|
+
export declare const uriGlobal: (name: UriFunction) => HostFunction<never>;
|
|
12
|
+
export declare const urlArgument: (value: unknown, label: string) => string;
|
|
13
|
+
export declare const urlGlobal: HostFunction<never>;
|
|
14
|
+
export declare const urlSearchParamsGlobal: <R>(runner: Runner<R>) => HostFunction<R>;
|
|
15
|
+
export declare const invokeURLMethod: (value: Values.URL, name: string, node: AstNode) => string;
|
|
8
16
|
export {};
|
package/dist/stdlib/url.js
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { Effect } from "effect";
|
|
2
|
-
import { toProgram
|
|
3
|
-
import {
|
|
4
|
-
import { InterpreterRuntimeError
|
|
5
|
-
import {
|
|
2
|
+
import { toProgram } from "../data.js";
|
|
3
|
+
import { HostFunction, requiresNew, sync, syncCall } from "../interpreter/host.js";
|
|
4
|
+
import { InterpreterRuntimeError } from "../interpreter/model.js";
|
|
5
|
+
import { ownEntries, ProgramObject } from "../interpreter/objects.js";
|
|
6
6
|
import { isRuntimeReference } from "../interpreter/references.js";
|
|
7
|
-
import {
|
|
7
|
+
import { preserveConsumerError } from "../interpreter/runner.js";
|
|
8
|
+
import { Values } from "../values.js";
|
|
8
9
|
import { coerceToString } from "./value.js";
|
|
9
|
-
const urlProperties = [
|
|
10
|
+
export const urlProperties = new Set([
|
|
10
11
|
"href",
|
|
11
12
|
"origin",
|
|
12
13
|
"protocol",
|
|
@@ -18,244 +19,143 @@ const urlProperties = [
|
|
|
18
19
|
"pathname",
|
|
19
20
|
"search",
|
|
20
21
|
"hash",
|
|
21
|
-
];
|
|
22
|
-
export const
|
|
22
|
+
]);
|
|
23
|
+
export const urlWritableProperties = new Set([
|
|
24
|
+
"href",
|
|
25
|
+
"protocol",
|
|
26
|
+
"username",
|
|
27
|
+
"password",
|
|
28
|
+
"host",
|
|
29
|
+
"hostname",
|
|
30
|
+
"port",
|
|
31
|
+
"pathname",
|
|
32
|
+
"search",
|
|
33
|
+
"hash",
|
|
34
|
+
]);
|
|
35
|
+
export const urlMethods = new Set(["toString", "toJSON"]);
|
|
36
|
+
export const urlSearchParamsMethods = new Set([
|
|
37
|
+
"append",
|
|
38
|
+
"delete",
|
|
39
|
+
"get",
|
|
40
|
+
"getAll",
|
|
41
|
+
"has",
|
|
42
|
+
"set",
|
|
43
|
+
"sort",
|
|
44
|
+
"forEach",
|
|
45
|
+
"keys",
|
|
46
|
+
"values",
|
|
47
|
+
"entries",
|
|
48
|
+
"toString",
|
|
49
|
+
]);
|
|
50
|
+
export const uriArgument = (value, label) => coerceToString(toProgram(value, label));
|
|
23
51
|
const uriFunctions = {
|
|
24
52
|
encodeURI,
|
|
25
53
|
encodeURIComponent,
|
|
26
54
|
decodeURI,
|
|
27
55
|
decodeURIComponent,
|
|
28
56
|
};
|
|
29
|
-
export const uriGlobal = (
|
|
30
|
-
const value = uriArgument(
|
|
57
|
+
export const uriGlobal = (name) => sync(name, (args, node) => {
|
|
58
|
+
const value = uriArgument(args[0], `${name} input`);
|
|
31
59
|
try {
|
|
32
60
|
return uriFunctions[name](value);
|
|
33
61
|
}
|
|
34
62
|
catch (error) {
|
|
35
|
-
throw
|
|
63
|
+
throw new InterpreterRuntimeError(`${name} received malformed URI data: ${error instanceof Error ? error.message : String(error)}`, node).as("URIError");
|
|
36
64
|
}
|
|
37
65
|
});
|
|
38
|
-
const urlArgument = (
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
const
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
(_, args, node) => {
|
|
65
|
-
if (args.length === 0)
|
|
66
|
-
throw new InterpreterRuntimeError(`URL.${name} requires a URL argument.`, node);
|
|
67
|
-
const input = urlArgument(protos, args[0], `URL.${name} input`);
|
|
68
|
-
const base = args[1] === undefined ? undefined : urlArgument(protos, args[1], `URL.${name} base`);
|
|
69
|
-
try {
|
|
70
|
-
const parsed = new URL(input, base);
|
|
71
|
-
return name === "canParse" ? true : new ProgramURL(proto, protos.URLSearchParams, parsed);
|
|
72
|
-
}
|
|
73
|
-
catch {
|
|
74
|
-
return name === "canParse" ? false : null;
|
|
75
|
-
}
|
|
76
|
-
},
|
|
77
|
-
];
|
|
78
|
-
methods(protos, url, [parse("canParse"), parse("parse")]);
|
|
79
|
-
const self = (thisValue, name, node) => receiver(ProgramURL, thisValue, `URL.prototype.${name}`, node);
|
|
80
|
-
for (const name of urlProperties) {
|
|
81
|
-
defineAccessor(proto, name, (thisValue) => self(thisValue, name).url[name], name === "origin"
|
|
82
|
-
? undefined
|
|
83
|
-
: (thisValue, value) => {
|
|
84
|
-
const target = self(thisValue, name);
|
|
85
|
-
try {
|
|
86
|
-
;
|
|
87
|
-
target.url[name] = uriArgument(protos, value, `URL.${name} value`);
|
|
88
|
-
}
|
|
89
|
-
catch (error) {
|
|
90
|
-
if (error instanceof InterpreterRuntimeError || error instanceof ToolRuntimeError)
|
|
91
|
-
throw error;
|
|
92
|
-
throw new InterpreterRuntimeError(`URL.${name} received an invalid value.`);
|
|
93
|
-
}
|
|
94
|
-
});
|
|
66
|
+
export const urlArgument = (value, label) => value instanceof Values.URL ? value.url.href : uriArgument(value, label);
|
|
67
|
+
const urlStatic = (name) => sync(`URL.${name}`, (args, node) => {
|
|
68
|
+
if (args.length === 0) {
|
|
69
|
+
throw new InterpreterRuntimeError(`URL.${name} requires a URL argument.`, node).as("TypeError");
|
|
70
|
+
}
|
|
71
|
+
const input = urlArgument(args[0], `URL.${name} input`);
|
|
72
|
+
const base = args[1] === undefined ? undefined : urlArgument(args[1], `URL.${name} base`);
|
|
73
|
+
try {
|
|
74
|
+
const url = new URL(input, base);
|
|
75
|
+
return name === "canParse" ? true : new Values.URL(url);
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
return name === "canParse" ? false : null;
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
const constructURL = (args, node) => {
|
|
82
|
+
if (args.length === 0) {
|
|
83
|
+
throw new InterpreterRuntimeError("new URL(...) requires a URL string and an optional base URL.", node).as("TypeError");
|
|
84
|
+
}
|
|
85
|
+
const input = urlArgument(args[0], "new URL input");
|
|
86
|
+
const base = args[1] === undefined ? undefined : urlArgument(args[1], "new URL base");
|
|
87
|
+
try {
|
|
88
|
+
return new Values.URL(new URL(input, base));
|
|
89
|
+
}
|
|
90
|
+
catch {
|
|
91
|
+
throw new InterpreterRuntimeError(`new URL(...) received an invalid URL${base === undefined ? "" : " or base URL"}.`, node).as("TypeError");
|
|
95
92
|
}
|
|
96
|
-
defineAccessor(proto, "searchParams", (thisValue) => self(thisValue, "searchParams").searchParams);
|
|
97
|
-
methods(protos, proto, [
|
|
98
|
-
["toString", 0, (thisValue, _, node) => self(thisValue, "toString", node).url.href],
|
|
99
|
-
["toJSON", 0, (thisValue, _, node) => self(thisValue, "toJSON", node).url.href],
|
|
100
|
-
]);
|
|
101
|
-
return url;
|
|
102
93
|
};
|
|
103
|
-
const
|
|
94
|
+
export const urlGlobal = new HostFunction({
|
|
95
|
+
name: "URL",
|
|
96
|
+
call: requiresNew("URL"),
|
|
97
|
+
construct: syncCall(constructURL),
|
|
98
|
+
instanceOf: (value) => value instanceof Values.URL,
|
|
99
|
+
members: { canParse: urlStatic("canParse"), parse: urlStatic("parse") },
|
|
100
|
+
});
|
|
101
|
+
const readURLSearchParamsPair = (runner, value, node) => Effect.gen(function* () {
|
|
104
102
|
const cursor = yield* runner.syncIterator(value, node);
|
|
105
103
|
if (cursor === undefined) {
|
|
106
|
-
throw new InterpreterRuntimeError("new URLSearchParams(...) expects iterable [name, value] pairs.", node);
|
|
104
|
+
throw new InterpreterRuntimeError("new URLSearchParams(...) expects iterable [name, value] pairs.", node).as("TypeError");
|
|
107
105
|
}
|
|
108
106
|
const items = [];
|
|
109
107
|
while (true) {
|
|
110
108
|
const step = yield* cursor.next;
|
|
111
109
|
if (step.done)
|
|
112
110
|
return items;
|
|
113
|
-
items.push(yield* preserveConsumerError(cursor, Effect.sync(() => uriArgument(
|
|
111
|
+
items.push(yield* preserveConsumerError(cursor, Effect.sync(() => uriArgument(step.value, "URLSearchParams pair value"))));
|
|
114
112
|
}
|
|
115
113
|
});
|
|
116
|
-
const constructURLSearchParams = (runner, init,
|
|
117
|
-
const wrap = (params) => new ProgramURLSearchParams(proto, params);
|
|
114
|
+
const constructURLSearchParams = (runner, init, node) => {
|
|
118
115
|
if (init === undefined)
|
|
119
|
-
return Effect.succeed(
|
|
120
|
-
if (init instanceof
|
|
121
|
-
return Effect.succeed(
|
|
116
|
+
return Effect.succeed(new Values.URLSearchParams(new URLSearchParams()));
|
|
117
|
+
if (init instanceof Values.URLSearchParams) {
|
|
118
|
+
return Effect.succeed(new Values.URLSearchParams(new URLSearchParams(init.params)));
|
|
119
|
+
}
|
|
122
120
|
if (typeof init === "string")
|
|
123
|
-
return Effect.succeed(
|
|
121
|
+
return Effect.succeed(new Values.URLSearchParams(new URLSearchParams(init)));
|
|
124
122
|
if (init === null || typeof init === "number" || typeof init === "boolean") {
|
|
125
|
-
return Effect.succeed(
|
|
123
|
+
return Effect.succeed(new Values.URLSearchParams(new URLSearchParams(coerceToString(init))));
|
|
126
124
|
}
|
|
127
125
|
return Effect.gen(function* () {
|
|
128
126
|
const cursor = yield* runner.syncIterator(init, node);
|
|
129
127
|
if (cursor !== undefined) {
|
|
130
|
-
const
|
|
128
|
+
const entries = [];
|
|
131
129
|
while (true) {
|
|
132
130
|
const step = yield* cursor.next;
|
|
133
131
|
if (step.done) {
|
|
134
|
-
if (
|
|
135
|
-
throw new InterpreterRuntimeError("new URLSearchParams(...) expects iterable [name, value] pairs.", node);
|
|
132
|
+
if (entries.some((entry) => entry.length !== 2)) {
|
|
133
|
+
throw new InterpreterRuntimeError("new URLSearchParams(...) expects iterable [name, value] pairs.", node).as("TypeError");
|
|
136
134
|
}
|
|
137
|
-
return
|
|
135
|
+
return new Values.URLSearchParams(new URLSearchParams(entries.map((entry) => [entry[0] ?? "", entry[1] ?? ""])));
|
|
138
136
|
}
|
|
139
|
-
|
|
137
|
+
entries.push(yield* preserveConsumerError(cursor, readURLSearchParamsPair(runner, step.value, node)));
|
|
140
138
|
}
|
|
141
139
|
}
|
|
142
140
|
if (isRuntimeReference(init)) {
|
|
143
|
-
throw new InterpreterRuntimeError("new URLSearchParams(...) expects a query string, data object, or synchronous iterable pairs.", node);
|
|
141
|
+
throw new InterpreterRuntimeError("new URLSearchParams(...) expects a query string, data object, or synchronous iterable pairs.", node).as("TypeError");
|
|
144
142
|
}
|
|
145
|
-
if (
|
|
146
|
-
return
|
|
143
|
+
if (Values.isValue(init))
|
|
144
|
+
return new Values.URLSearchParams(new URLSearchParams());
|
|
147
145
|
if (!(init instanceof ProgramObject)) {
|
|
148
|
-
throw new InterpreterRuntimeError("new URLSearchParams(...) expects a query string, data object, iterable pairs, or URLSearchParams.", node);
|
|
146
|
+
throw new InterpreterRuntimeError("new URLSearchParams(...) expects a query string, data object, iterable pairs, or URLSearchParams.", node).as("TypeError");
|
|
149
147
|
}
|
|
150
|
-
return
|
|
148
|
+
return new Values.URLSearchParams(new URLSearchParams(Object.fromEntries(ownEntries(init).map(([key, value]) => [key, coerceToString(value)]))));
|
|
151
149
|
});
|
|
152
150
|
};
|
|
153
|
-
export const urlSearchParamsGlobal = (runner) => {
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
const arg = (name, args, index) => uriArgument(protos, args[index], `URLSearchParams.${name} argument ${index + 1}`);
|
|
164
|
-
const requireArgs = (name, args, count, node) => {
|
|
165
|
-
if (args.length < count) {
|
|
166
|
-
throw new InterpreterRuntimeError(`URLSearchParams.${name} requires ${count} argument${count === 1 ? "" : "s"}.`, node);
|
|
167
|
-
}
|
|
168
|
-
};
|
|
169
|
-
defineAccessor(proto, "size", (thisValue) => self(thisValue, "size").params.size);
|
|
170
|
-
methods(protos, proto, [
|
|
171
|
-
[
|
|
172
|
-
"append",
|
|
173
|
-
2,
|
|
174
|
-
(thisValue, args, node) => {
|
|
175
|
-
requireArgs("append", args, 2, node);
|
|
176
|
-
self(thisValue, "append", node).params.append(arg("append", args, 0), arg("append", args, 1));
|
|
177
|
-
return undefined;
|
|
178
|
-
},
|
|
179
|
-
],
|
|
180
|
-
[
|
|
181
|
-
"delete",
|
|
182
|
-
1,
|
|
183
|
-
(thisValue, args, node) => {
|
|
184
|
-
requireArgs("delete", args, 1, node);
|
|
185
|
-
const params = self(thisValue, "delete", node).params;
|
|
186
|
-
if (args[1] !== undefined)
|
|
187
|
-
params.delete(arg("delete", args, 0), arg("delete", args, 1));
|
|
188
|
-
else
|
|
189
|
-
params.delete(arg("delete", args, 0));
|
|
190
|
-
return undefined;
|
|
191
|
-
},
|
|
192
|
-
],
|
|
193
|
-
[
|
|
194
|
-
"get",
|
|
195
|
-
1,
|
|
196
|
-
(thisValue, args, node) => {
|
|
197
|
-
requireArgs("get", args, 1, node);
|
|
198
|
-
return self(thisValue, "get", node).params.get(arg("get", args, 0));
|
|
199
|
-
},
|
|
200
|
-
],
|
|
201
|
-
[
|
|
202
|
-
"getAll",
|
|
203
|
-
1,
|
|
204
|
-
(thisValue, args, node) => {
|
|
205
|
-
requireArgs("getAll", args, 1, node);
|
|
206
|
-
return wrap(self(thisValue, "getAll", node).params.getAll(arg("getAll", args, 0)));
|
|
207
|
-
},
|
|
208
|
-
],
|
|
209
|
-
[
|
|
210
|
-
"has",
|
|
211
|
-
1,
|
|
212
|
-
(thisValue, args, node) => {
|
|
213
|
-
requireArgs("has", args, 1, node);
|
|
214
|
-
const params = self(thisValue, "has", node).params;
|
|
215
|
-
return args[1] !== undefined
|
|
216
|
-
? params.has(arg("has", args, 0), arg("has", args, 1))
|
|
217
|
-
: params.has(arg("has", args, 0));
|
|
218
|
-
},
|
|
219
|
-
],
|
|
220
|
-
[
|
|
221
|
-
"set",
|
|
222
|
-
2,
|
|
223
|
-
(thisValue, args, node) => {
|
|
224
|
-
requireArgs("set", args, 2, node);
|
|
225
|
-
self(thisValue, "set", node).params.set(arg("set", args, 0), arg("set", args, 1));
|
|
226
|
-
return undefined;
|
|
227
|
-
},
|
|
228
|
-
],
|
|
229
|
-
[
|
|
230
|
-
"sort",
|
|
231
|
-
0,
|
|
232
|
-
(thisValue, _, node) => {
|
|
233
|
-
self(thisValue, "sort", node).params.sort();
|
|
234
|
-
return undefined;
|
|
235
|
-
},
|
|
236
|
-
],
|
|
237
|
-
["keys", 0, (thisValue, _, node) => wrap(Array.from(self(thisValue, "keys", node).params.keys()))],
|
|
238
|
-
["values", 0, (thisValue, _, node) => wrap(Array.from(self(thisValue, "values", node).params.values()))],
|
|
239
|
-
[
|
|
240
|
-
"entries",
|
|
241
|
-
0,
|
|
242
|
-
(thisValue, _, node) => wrap(Array.from(self(thisValue, "entries", node).params.entries(), ([key, value]) => wrap([key, value]))),
|
|
243
|
-
],
|
|
244
|
-
["toString", 0, (thisValue, _, node) => self(thisValue, "toString", node).params.toString()],
|
|
245
|
-
[
|
|
246
|
-
"forEach",
|
|
247
|
-
1,
|
|
248
|
-
(thisValue, args, node) => {
|
|
249
|
-
requireArgs("forEach", args, 1, node);
|
|
250
|
-
const target = self(thisValue, "forEach", node);
|
|
251
|
-
const apply = applyCollectionCallback(runner, args[0], "URLSearchParams.forEach", node);
|
|
252
|
-
return Effect.gen(function* () {
|
|
253
|
-
for (const [key, value] of Array.from(target.params.entries()))
|
|
254
|
-
yield* apply([value, key, target]);
|
|
255
|
-
return undefined;
|
|
256
|
-
});
|
|
257
|
-
},
|
|
258
|
-
],
|
|
259
|
-
]);
|
|
260
|
-
return searchParams;
|
|
151
|
+
export const urlSearchParamsGlobal = (runner) => new HostFunction({
|
|
152
|
+
name: "URLSearchParams",
|
|
153
|
+
call: requiresNew("URLSearchParams"),
|
|
154
|
+
construct: (args, node) => constructURLSearchParams(runner, args[0], node),
|
|
155
|
+
instanceOf: (value) => value instanceof Values.URLSearchParams,
|
|
156
|
+
});
|
|
157
|
+
export const invokeURLMethod = (value, name, node) => {
|
|
158
|
+
if (name === "toString" || name === "toJSON")
|
|
159
|
+
return value.url.href;
|
|
160
|
+
throw new InterpreterRuntimeError(`URL method '${name}' is not available.`, node);
|
|
261
161
|
};
|