@opencode/codemode 0.0.0-dev-19862 → 0.0.0-dev-19868
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 +14 -6
- package/dist/data.js +3 -1
- package/dist/interpreter/extensions.js +5 -1
- package/dist/interpreter/globals.js +2 -0
- package/dist/interpreter/interpreter.d.ts +6 -0
- package/dist/interpreter/interpreter.js +8 -5
- package/dist/interpreter/intrinsics.d.ts +1 -1
- package/dist/interpreter/intrinsics.js +2 -0
- package/dist/interpreter/objects.d.ts +5 -1
- package/dist/interpreter/objects.js +8 -0
- package/dist/interpreter/references.js +3 -1
- package/dist/stdlib/console.js +3 -1
- package/dist/stdlib/headers.d.ts +2 -0
- package/dist/stdlib/headers.js +117 -0
- package/dist/stdlib/url.d.ts +6 -0
- package/dist/stdlib/url.js +25 -18
- package/dist/stdlib/value.js +3 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -13,8 +13,8 @@ The idea of code mode was originally introduced by Cloudflare. See
|
|
|
13
13
|
|
|
14
14
|
## How it differs from JavaScript
|
|
15
15
|
|
|
16
|
-
- **Only supported APIs are available.** Programs can use the provided tools
|
|
17
|
-
|
|
16
|
+
- **Only supported APIs are available.** Programs can use the provided tools, supported JavaScript built-ins, and the
|
|
17
|
+
globals the host adds through extensions. Timers, `process`, filesystem access, imports, and modules are unavailable.
|
|
18
18
|
- **Unfinished work is interrupted.** Tool calls and async functions start when called. When the program finishes,
|
|
19
19
|
anything still running is interrupted. Unhandled rejections from un-awaited promises are returned as warnings.
|
|
20
20
|
- **REPL-style results.** Without an explicit `return`, the final top-level expression becomes the result. `undefined`
|
|
@@ -94,11 +94,19 @@ receive `{ extension, name, args }`. An `after` hook also receives how the call
|
|
|
94
94
|
`failure` with its error, or `interrupted`). A failing `before` hook denies the call, and the program catches the
|
|
95
95
|
failure as a thrown error.
|
|
96
96
|
|
|
97
|
-
### `
|
|
97
|
+
### `Extension.make`
|
|
98
98
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
99
|
+
Extensions are host functions a program calls directly as globals, such as `fetch`. Unlike tools they are not in the
|
|
100
|
+
catalog, not counted against `maxToolCalls`, and not described to the model; the host decides what they mean.
|
|
101
|
+
|
|
102
|
+
```ts
|
|
103
|
+
const web = Extension.make({ name: "web", globals: { fetch: (url: string) => globalThis.fetch(url) } })
|
|
104
|
+
const runtime = CodeMode.make({ tools, extensions: [web] })
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Every value crossing in either direction is converted, never shared: arguments come in as copies, results go out as
|
|
108
|
+
copies, and a function inside a result is callable the same way. A global that shadows a built-in or another
|
|
109
|
+
extension throws at `CodeMode.make`.
|
|
102
110
|
|
|
103
111
|
### OpenAPI tools
|
|
104
112
|
|
package/dist/data.js
CHANGED
|
@@ -2,7 +2,7 @@ export * as Data from "./data.js";
|
|
|
2
2
|
import { Effect } from "effect";
|
|
3
3
|
import { MAX_VALUE_DEPTH } from "./interpreter/limits.js";
|
|
4
4
|
import { invalidData, rangeError, typeError } from "./interpreter/model.js";
|
|
5
|
-
import { Arr, Bytes, Callable, define, ErrorObj, get, keys, Obj, PromiseObj, record, SetObj, URLSearchParamsObj, } from "./interpreter/objects.js";
|
|
5
|
+
import { Arr, Bytes, Callable, define, ErrorObj, get, keys, Obj, PromiseObj, record, SetObj, URLSearchParamsObj, HeadersObj, } from "./interpreter/objects.js";
|
|
6
6
|
import { typeofValue } from "./interpreter/references.js";
|
|
7
7
|
/**
|
|
8
8
|
* What `JSON.stringify` would serialize for a program value, as host JSON: `toJSON` is honored, functions and
|
|
@@ -42,6 +42,8 @@ const walk = (ctx, value, replacer, boundary) => {
|
|
|
42
42
|
}
|
|
43
43
|
if (boundary && value instanceof URLSearchParamsObj)
|
|
44
44
|
return value.params.toString();
|
|
45
|
+
if (value instanceof HeadersObj)
|
|
46
|
+
return Object.fromEntries(value.headers);
|
|
45
47
|
const target = boundary && value instanceof SetObj ? new Arr(ctx.builtins.Array, [...value.set]) : value;
|
|
46
48
|
if (stack.has(target))
|
|
47
49
|
throw typeError("Converting circular structure to JSON.");
|
|
@@ -5,7 +5,7 @@ import { createErrorValue, isErrorType } from "./intrinsics.js";
|
|
|
5
5
|
import { MAX_VALUE_DEPTH } from "./limits.js";
|
|
6
6
|
import { PendingThrow, Throw, typeError } from "./model.js";
|
|
7
7
|
import { fn } from "./native.js";
|
|
8
|
-
import { Callable, define, entries, get, has, hidden, keys, Arr, Bytes, DateObj, ErrorObj, GeneratorObj, MapObj, Obj, PromiseObj, RegExpObj, SetObj, URLObj, URLSearchParamsObj, } from "./objects.js";
|
|
8
|
+
import { Callable, define, entries, get, has, hidden, keys, Arr, Bytes, DateObj, ErrorObj, GeneratorObj, MapObj, Obj, PromiseObj, RegExpObj, SetObj, URLObj, URLSearchParamsObj, HeadersObj, } from "./objects.js";
|
|
9
9
|
import { describeValue } from "./references.js";
|
|
10
10
|
/**
|
|
11
11
|
* The global bindings of one run's extensions. Everything crossing the boundary is converted: plain data and
|
|
@@ -32,6 +32,8 @@ export const extensionGlobals = (ctx, extensions) => {
|
|
|
32
32
|
return new URL(value.url.href);
|
|
33
33
|
if (value instanceof URLSearchParamsObj)
|
|
34
34
|
return new URLSearchParams(value.params);
|
|
35
|
+
if (value instanceof HeadersObj)
|
|
36
|
+
return new Headers(value.headers);
|
|
35
37
|
const next = (item) => toHost(item, label, depth + 1, seen);
|
|
36
38
|
if (value instanceof MapObj)
|
|
37
39
|
return new Map([...value.map].map(([key, item]) => [next(key), next(item)]));
|
|
@@ -114,6 +116,8 @@ export const extensionGlobals = (ctx, extensions) => {
|
|
|
114
116
|
if (value instanceof URLSearchParams) {
|
|
115
117
|
return new URLSearchParamsObj(builtins.URLSearchParams, new URLSearchParams(value));
|
|
116
118
|
}
|
|
119
|
+
if (value instanceof Headers)
|
|
120
|
+
return new HeadersObj(builtins.Headers, new Headers(value));
|
|
117
121
|
if (value instanceof Map) {
|
|
118
122
|
const wrapped = new MapObj(builtins.Map);
|
|
119
123
|
for (const [key, item] of value)
|
|
@@ -11,6 +11,7 @@ import { objectGlobal } from "../stdlib/object.js";
|
|
|
11
11
|
import { regexpGlobal } from "../stdlib/regexp.js";
|
|
12
12
|
import { stringGlobal } from "../stdlib/string.js";
|
|
13
13
|
import { uriGlobal, urlGlobal, urlSearchParamsGlobal } from "../stdlib/url.js";
|
|
14
|
+
import { headersGlobal } from "../stdlib/headers.js";
|
|
14
15
|
import { coercion } from "../stdlib/value.js";
|
|
15
16
|
import { base64Global, cryptoGlobal } from "../stdlib/web.js";
|
|
16
17
|
import { ToolReference } from "../tool-runtime.js";
|
|
@@ -71,6 +72,7 @@ const table = {
|
|
|
71
72
|
Set: (ctx) => setGlobal(ctx),
|
|
72
73
|
URL: (ctx) => urlGlobal(ctx),
|
|
73
74
|
URLSearchParams: (ctx) => urlSearchParamsGlobal(ctx),
|
|
75
|
+
Headers: (ctx) => headersGlobal(ctx),
|
|
74
76
|
Uint8Array: (ctx) => uint8ArrayGlobal(ctx),
|
|
75
77
|
TextEncoder: (ctx) => textEncoderGlobal(ctx),
|
|
76
78
|
TextDecoder: (ctx) => textDecoderGlobal(ctx),
|
|
@@ -23,6 +23,12 @@ export declare class Interpreter<R> {
|
|
|
23
23
|
call(callable: unknown, thisValue: unknown, args: Array<unknown>): Effect.Effect<unknown, unknown, R>;
|
|
24
24
|
await(promise: PromiseObj): Effect.Effect<unknown, unknown, never>;
|
|
25
25
|
iterate(value: unknown): Effect.Effect<{
|
|
26
|
+
next: Effect.Effect<{
|
|
27
|
+
done: boolean;
|
|
28
|
+
value: any;
|
|
29
|
+
}, never, never>;
|
|
30
|
+
close: Effect.Effect<void, never, never>;
|
|
31
|
+
}, never, never> | Effect.Effect<{
|
|
26
32
|
next: Effect.Effect<{
|
|
27
33
|
done: boolean;
|
|
28
34
|
value: unknown;
|
|
@@ -5,7 +5,7 @@ import { AsyncIteratorSymbol, CallSite, GeneratorReturn, IteratorSymbol, Optiona
|
|
|
5
5
|
import { checkStringLength } from "./limits.js";
|
|
6
6
|
import { locate, materialize } from "./errors.js";
|
|
7
7
|
import { globals } from "./globals.js";
|
|
8
|
-
import { assign, Callable, define, get, has, hasPrototype, keys, Native, parseArrayIndex, Arr, Bytes, DateObj, Fn, GeneratorObj, MapObj, Obj, PromiseObj, SetObj, URLSearchParamsObj, record, remove, set, } from "./objects.js";
|
|
8
|
+
import { assign, Callable, define, get, has, hasPrototype, keys, Native, parseArrayIndex, Arr, Bytes, DateObj, Fn, GeneratorObj, MapObj, Obj, PromiseObj, SetObj, URLSearchParamsObj, HeadersObj, record, remove, set, } from "./objects.js";
|
|
9
9
|
import { preserveConsumerError } from "./callback.js";
|
|
10
10
|
import { Pending, resolvePromise, resolvePromiseValue } from "./promises.js";
|
|
11
11
|
import { containsOpaqueReference, describeValue, rejectCircularInsertion, typeofValue } from "./references.js";
|
|
@@ -480,7 +480,7 @@ class Frame {
|
|
|
480
480
|
const iterator = yield* self.customIterator(right, node, awaiting);
|
|
481
481
|
const cursor = iterator === undefined ? yield* self.iterate(right, node) : undefined;
|
|
482
482
|
if (iterator === undefined && cursor === undefined) {
|
|
483
|
-
throw invalidData(`${awaiting ? "for await...of" : "for...of"} requires an array, string, Map, Set, or
|
|
483
|
+
throw invalidData(`${awaiting ? "for await...of" : "for...of"} requires an array, string, Map, Set, URLSearchParams, or Headers, or custom iterator value.`, node);
|
|
484
484
|
}
|
|
485
485
|
const close = () => iterator
|
|
486
486
|
? self.closeIterator(iterator, node, awaiting)
|
|
@@ -560,9 +560,11 @@ class Frame {
|
|
|
560
560
|
? value.set.values()
|
|
561
561
|
: value instanceof URLSearchParamsObj
|
|
562
562
|
? value.params.entries()
|
|
563
|
-
: value instanceof
|
|
564
|
-
? value.
|
|
565
|
-
:
|
|
563
|
+
: value instanceof HeadersObj
|
|
564
|
+
? value.headers.entries()
|
|
565
|
+
: value instanceof Bytes
|
|
566
|
+
? value.bytes.values()
|
|
567
|
+
: undefined;
|
|
566
568
|
if (iterator !== undefined) {
|
|
567
569
|
const proto = this.ctx.builtins.Array;
|
|
568
570
|
return Effect.succeed({
|
|
@@ -1513,6 +1515,7 @@ class Frame {
|
|
|
1513
1515
|
value instanceof MapObj ||
|
|
1514
1516
|
value instanceof SetObj ||
|
|
1515
1517
|
value instanceof URLSearchParamsObj ||
|
|
1518
|
+
value instanceof HeadersObj ||
|
|
1516
1519
|
value instanceof Bytes) {
|
|
1517
1520
|
const cursor = yield* self.iterate(value, node);
|
|
1518
1521
|
if (!cursor)
|
|
@@ -2,7 +2,7 @@ import { ErrorObj, Obj } from "./objects.js";
|
|
|
2
2
|
export declare const errorTypes: readonly ["Error", "TypeError", "RangeError", "SyntaxError", "ReferenceError", "EvalError", "URIError", "AggregateError"];
|
|
3
3
|
export type ErrorType = (typeof errorTypes)[number];
|
|
4
4
|
export declare const isErrorType: (name: string) => name is ErrorType;
|
|
5
|
-
declare const builtins: readonly ["Object", "Function", "Array", "String", "Number", "Boolean", "Date", "RegExp", "Map", "Set", "URL", "URLSearchParams", "Uint8Array", "TextEncoder", "TextDecoder", "Promise", "Iterator", "AsyncIterator", "Generator", "AsyncGenerator"];
|
|
5
|
+
declare const builtins: readonly ["Object", "Function", "Array", "String", "Number", "Boolean", "Date", "RegExp", "Map", "Set", "URL", "URLSearchParams", "Headers", "Uint8Array", "TextEncoder", "TextDecoder", "Promise", "Iterator", "AsyncIterator", "Generator", "AsyncGenerator"];
|
|
6
6
|
/**
|
|
7
7
|
* The built-in prototype objects of one runtime, allocated empty in dependency order. The globals populate them
|
|
8
8
|
* and attach their constructors when the runtime is built.
|
|
@@ -24,6 +24,7 @@ const builtins = [
|
|
|
24
24
|
"Set",
|
|
25
25
|
"URL",
|
|
26
26
|
"URLSearchParams",
|
|
27
|
+
"Headers",
|
|
27
28
|
"Uint8Array",
|
|
28
29
|
"TextEncoder",
|
|
29
30
|
"TextDecoder",
|
|
@@ -68,6 +69,7 @@ export const createBuiltins = () => {
|
|
|
68
69
|
Set: plain(),
|
|
69
70
|
URL: plain(),
|
|
70
71
|
URLSearchParams: plain(),
|
|
72
|
+
Headers: plain(),
|
|
71
73
|
Uint8Array: plain(),
|
|
72
74
|
TextEncoder: plain(),
|
|
73
75
|
TextDecoder: plain(),
|
|
@@ -99,6 +99,10 @@ export declare class URLSearchParamsObj extends Obj {
|
|
|
99
99
|
readonly params: URLSearchParams;
|
|
100
100
|
constructor(proto: Obj, params: URLSearchParams);
|
|
101
101
|
}
|
|
102
|
+
export declare class HeadersObj extends Obj {
|
|
103
|
+
readonly headers: Headers;
|
|
104
|
+
constructor(proto: Obj, headers: Headers);
|
|
105
|
+
}
|
|
102
106
|
export declare class URLObj extends Obj {
|
|
103
107
|
readonly url: URL;
|
|
104
108
|
readonly searchParams: URLSearchParamsObj;
|
|
@@ -110,7 +114,7 @@ export declare class Bytes extends Obj {
|
|
|
110
114
|
constructor(proto: Obj, bytes: Uint8Array);
|
|
111
115
|
}
|
|
112
116
|
/** Built-in objects that wrap a host value; data-like, but never plain data. */
|
|
113
|
-
export declare const isWrapper: (value: unknown) => value is DateObj | RegExpObj | MapObj | SetObj | URLObj | URLSearchParamsObj | Bytes;
|
|
117
|
+
export declare const isWrapper: (value: unknown) => value is DateObj | RegExpObj | MapObj | SetObj | URLObj | URLSearchParamsObj | HeadersObj | Bytes;
|
|
114
118
|
export declare const parseArrayIndex: (key: string | number) => number | undefined;
|
|
115
119
|
/** The own property under `key`, including an array's live indexes and `length`. */
|
|
116
120
|
export declare const own: (target: Obj, key: PropertyKey) => Slot | undefined;
|
|
@@ -105,6 +105,13 @@ export class URLSearchParamsObj extends Obj {
|
|
|
105
105
|
this.params = params;
|
|
106
106
|
}
|
|
107
107
|
}
|
|
108
|
+
export class HeadersObj extends Obj {
|
|
109
|
+
headers;
|
|
110
|
+
constructor(proto, headers) {
|
|
111
|
+
super(proto);
|
|
112
|
+
this.headers = headers;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
108
115
|
export class URLObj extends Obj {
|
|
109
116
|
url;
|
|
110
117
|
searchParams;
|
|
@@ -129,6 +136,7 @@ export const isWrapper = (value) => value instanceof DateObj ||
|
|
|
129
136
|
value instanceof SetObj ||
|
|
130
137
|
value instanceof URLObj ||
|
|
131
138
|
value instanceof URLSearchParamsObj ||
|
|
139
|
+
value instanceof HeadersObj ||
|
|
132
140
|
value instanceof Bytes;
|
|
133
141
|
const MAX_ARRAY_INDEX = 4_294_967_295;
|
|
134
142
|
export const parseArrayIndex = (key) => {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ToolReference } from "../tool-runtime.js";
|
|
2
2
|
import { invalidData } from "./model.js";
|
|
3
|
-
import { Callable, getOwn, isWrapper, ownKeys, Arr, Bytes, DateObj, GeneratorObj, MapObj, Obj, PromiseObj, RegExpObj, SetObj, URLObj, URLSearchParamsObj, } from "./objects.js";
|
|
3
|
+
import { Callable, getOwn, isWrapper, ownKeys, Arr, Bytes, DateObj, GeneratorObj, MapObj, Obj, PromiseObj, RegExpObj, SetObj, URLObj, URLSearchParamsObj, HeadersObj, } from "./objects.js";
|
|
4
4
|
/** Values that cannot cross the data boundary. */
|
|
5
5
|
export const isRuntimeReference = (value) => value instanceof Callable ||
|
|
6
6
|
value instanceof GeneratorObj ||
|
|
@@ -63,6 +63,8 @@ export const describeValue = (value) => {
|
|
|
63
63
|
return "a URL";
|
|
64
64
|
if (value instanceof URLSearchParamsObj)
|
|
65
65
|
return "a URLSearchParams";
|
|
66
|
+
if (value instanceof HeadersObj)
|
|
67
|
+
return "a Headers";
|
|
66
68
|
if (value instanceof Bytes)
|
|
67
69
|
return "a Uint8Array";
|
|
68
70
|
if (value instanceof GeneratorObj)
|
package/dist/stdlib/console.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { methods } from "../interpreter/native.js";
|
|
2
|
-
import { entries, get, Arr, Bytes, DateObj, MapObj, Obj, PromiseObj, RegExpObj, SetObj, URLObj, URLSearchParamsObj, } from "../interpreter/objects.js";
|
|
2
|
+
import { entries, get, Arr, Bytes, DateObj, MapObj, Obj, PromiseObj, RegExpObj, SetObj, URLObj, URLSearchParamsObj, HeadersObj, } from "../interpreter/objects.js";
|
|
3
3
|
import { containsOpaqueReference, isRuntimeReference } from "../interpreter/references.js";
|
|
4
4
|
import { coerceToString } from "./value.js";
|
|
5
5
|
const consoleMethods = ["log", "info", "debug", "warn", "error", "dir", "table"];
|
|
@@ -53,6 +53,8 @@ const formatConsoleValue = (value, seen, depth) => {
|
|
|
53
53
|
return coerceToString(value);
|
|
54
54
|
if (value instanceof URLSearchParamsObj)
|
|
55
55
|
return coerceToString(value);
|
|
56
|
+
if (value instanceof HeadersObj)
|
|
57
|
+
return `Headers ${JSON.stringify(Object.fromEntries(value.headers))}`;
|
|
56
58
|
if (value instanceof Bytes)
|
|
57
59
|
return `Uint8Array(${value.bytes.length}) [${value.bytes.join(",")}]`;
|
|
58
60
|
if (depth > MAX_CONSOLE_DEPTH)
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { Effect } from "effect";
|
|
2
|
+
import { constructor, methods, prototypeFrom, receiver, requiresNew } from "../interpreter/native.js";
|
|
3
|
+
import { typeError } from "../interpreter/model.js";
|
|
4
|
+
import { entries, Arr, HeadersObj, Obj } from "../interpreter/objects.js";
|
|
5
|
+
import { applyCollectionCallback } from "../interpreter/callback.js";
|
|
6
|
+
import { isRuntimeReference } from "../interpreter/references.js";
|
|
7
|
+
import { coerceToString } from "./value.js";
|
|
8
|
+
import { readPairs } from "./url.js";
|
|
9
|
+
// The host validates header names and values and throws its own TypeError; the program gets one of its own.
|
|
10
|
+
const attempt = (run) => {
|
|
11
|
+
try {
|
|
12
|
+
return run();
|
|
13
|
+
}
|
|
14
|
+
catch (error) {
|
|
15
|
+
throw typeError(error instanceof Error ? error.message : String(error));
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
const constructHeaders = (ctx, init, proto) => {
|
|
19
|
+
const wrap = (headers) => new HeadersObj(proto, headers);
|
|
20
|
+
if (init === undefined)
|
|
21
|
+
return Effect.succeed(wrap(new Headers()));
|
|
22
|
+
return Effect.gen(function* () {
|
|
23
|
+
const pairs = init instanceof Obj ? yield* readPairs(ctx, init, "new Headers(...)") : undefined;
|
|
24
|
+
if (pairs !== undefined)
|
|
25
|
+
return wrap(attempt(() => new Headers(pairs)));
|
|
26
|
+
if (!(init instanceof Obj) || isRuntimeReference(init)) {
|
|
27
|
+
throw typeError("new Headers(...) expects a record of names to values, iterable [name, value] pairs, or Headers.");
|
|
28
|
+
}
|
|
29
|
+
return wrap(attempt(() => new Headers(Object.fromEntries(entries(init).map(([key, value]) => [key, coerceToString(value)])))));
|
|
30
|
+
});
|
|
31
|
+
};
|
|
32
|
+
export const headersGlobal = (ctx) => {
|
|
33
|
+
const builtins = ctx.builtins;
|
|
34
|
+
const proto = builtins.Headers;
|
|
35
|
+
const headers = constructor(builtins, proto, {
|
|
36
|
+
name: "Headers",
|
|
37
|
+
call: requiresNew("Headers"),
|
|
38
|
+
construct: (args, newTarget) => constructHeaders(ctx, args[0], prototypeFrom(newTarget, proto)),
|
|
39
|
+
});
|
|
40
|
+
const self = (thisValue, name) => receiver(HeadersObj, thisValue, `Headers.prototype.${name}`);
|
|
41
|
+
const wrap = (items) => new Arr(builtins.Array, items);
|
|
42
|
+
const arg = (args, index) => coerceToString(args[index]);
|
|
43
|
+
const requireArgs = (name, args, count) => {
|
|
44
|
+
if (args.length < count)
|
|
45
|
+
throw typeError(`Headers.${name} requires ${count} argument${count === 1 ? "" : "s"}.`);
|
|
46
|
+
};
|
|
47
|
+
methods(builtins, proto, [
|
|
48
|
+
[
|
|
49
|
+
"append",
|
|
50
|
+
2,
|
|
51
|
+
(thisValue, args) => {
|
|
52
|
+
requireArgs("append", args, 2);
|
|
53
|
+
const target = self(thisValue, "append").headers;
|
|
54
|
+
return attempt(() => target.append(arg(args, 0), arg(args, 1)));
|
|
55
|
+
},
|
|
56
|
+
],
|
|
57
|
+
[
|
|
58
|
+
"delete",
|
|
59
|
+
1,
|
|
60
|
+
(thisValue, args) => {
|
|
61
|
+
requireArgs("delete", args, 1);
|
|
62
|
+
const target = self(thisValue, "delete").headers;
|
|
63
|
+
return attempt(() => target.delete(arg(args, 0)));
|
|
64
|
+
},
|
|
65
|
+
],
|
|
66
|
+
[
|
|
67
|
+
"get",
|
|
68
|
+
1,
|
|
69
|
+
(thisValue, args) => {
|
|
70
|
+
requireArgs("get", args, 1);
|
|
71
|
+
const target = self(thisValue, "get").headers;
|
|
72
|
+
return attempt(() => target.get(arg(args, 0)));
|
|
73
|
+
},
|
|
74
|
+
],
|
|
75
|
+
["getSetCookie", 0, (thisValue) => wrap(self(thisValue, "getSetCookie").headers.getSetCookie())],
|
|
76
|
+
[
|
|
77
|
+
"has",
|
|
78
|
+
1,
|
|
79
|
+
(thisValue, args) => {
|
|
80
|
+
requireArgs("has", args, 1);
|
|
81
|
+
const target = self(thisValue, "has").headers;
|
|
82
|
+
return attempt(() => target.has(arg(args, 0)));
|
|
83
|
+
},
|
|
84
|
+
],
|
|
85
|
+
[
|
|
86
|
+
"set",
|
|
87
|
+
2,
|
|
88
|
+
(thisValue, args) => {
|
|
89
|
+
requireArgs("set", args, 2);
|
|
90
|
+
const target = self(thisValue, "set").headers;
|
|
91
|
+
return attempt(() => target.set(arg(args, 0), arg(args, 1)));
|
|
92
|
+
},
|
|
93
|
+
],
|
|
94
|
+
["keys", 0, (thisValue) => wrap(Array.from(self(thisValue, "keys").headers.keys()))],
|
|
95
|
+
["values", 0, (thisValue) => wrap(Array.from(self(thisValue, "values").headers.values()))],
|
|
96
|
+
[
|
|
97
|
+
"entries",
|
|
98
|
+
0,
|
|
99
|
+
(thisValue) => wrap(Array.from(self(thisValue, "entries").headers.entries(), ([key, value]) => wrap([key, value]))),
|
|
100
|
+
],
|
|
101
|
+
[
|
|
102
|
+
"forEach",
|
|
103
|
+
1,
|
|
104
|
+
(thisValue, args) => {
|
|
105
|
+
requireArgs("forEach", args, 1);
|
|
106
|
+
const target = self(thisValue, "forEach");
|
|
107
|
+
const apply = applyCollectionCallback(ctx, args[0], "Headers.forEach");
|
|
108
|
+
return Effect.gen(function* () {
|
|
109
|
+
for (const [key, value] of Array.from(target.headers.entries()))
|
|
110
|
+
yield* apply([value, key, target]);
|
|
111
|
+
return undefined;
|
|
112
|
+
});
|
|
113
|
+
},
|
|
114
|
+
],
|
|
115
|
+
]);
|
|
116
|
+
return headers;
|
|
117
|
+
};
|
package/dist/stdlib/url.d.ts
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
|
+
import { Effect } from "effect";
|
|
1
2
|
import type { Interpreter } from "../interpreter/interpreter.js";
|
|
2
3
|
type UriFunction = "encodeURI" | "encodeURIComponent" | "decodeURI" | "decodeURIComponent";
|
|
3
4
|
export declare const uriGlobal: <R>(ctx: Interpreter<R>, name: UriFunction) => import("../interpreter/objects.js").Native<R>;
|
|
4
5
|
export declare const urlGlobal: <R>(ctx: Interpreter<R>) => import("../interpreter/objects.js").Native<R>;
|
|
6
|
+
/**
|
|
7
|
+
* Reads a synchronous iterable of `[name, value]` pairs as strings; `undefined` when `init` is not iterable. As in
|
|
8
|
+
* WebIDL, the whole sequence is converted before any pair's length is checked.
|
|
9
|
+
*/
|
|
10
|
+
export declare const readPairs: <R>(ctx: Interpreter<R>, init: unknown, label: string) => Effect.Effect<Array<[string, string]> | undefined, unknown, R>;
|
|
5
11
|
export declare const urlSearchParamsGlobal: <R>(ctx: Interpreter<R>) => import("../interpreter/objects.js").Native<R>;
|
|
6
12
|
export {};
|
package/dist/stdlib/url.js
CHANGED
|
@@ -98,11 +98,10 @@ export const urlGlobal = (ctx) => {
|
|
|
98
98
|
]);
|
|
99
99
|
return url;
|
|
100
100
|
};
|
|
101
|
-
const readPair = (ctx, value) => Effect.gen(function* () {
|
|
101
|
+
const readPair = (ctx, value, label) => Effect.gen(function* () {
|
|
102
102
|
const cursor = yield* ctx.iterate(value);
|
|
103
|
-
if (cursor === undefined)
|
|
104
|
-
throw typeError(
|
|
105
|
-
}
|
|
103
|
+
if (cursor === undefined)
|
|
104
|
+
throw typeError(`${label} expects iterable [name, value] pairs.`);
|
|
106
105
|
const items = [];
|
|
107
106
|
while (true) {
|
|
108
107
|
const step = yield* cursor.next;
|
|
@@ -111,6 +110,25 @@ const readPair = (ctx, value) => Effect.gen(function* () {
|
|
|
111
110
|
items.push(yield* preserveConsumerError(cursor, Effect.sync(() => coerceToString(step.value))));
|
|
112
111
|
}
|
|
113
112
|
});
|
|
113
|
+
/**
|
|
114
|
+
* Reads a synchronous iterable of `[name, value]` pairs as strings; `undefined` when `init` is not iterable. As in
|
|
115
|
+
* WebIDL, the whole sequence is converted before any pair's length is checked.
|
|
116
|
+
*/
|
|
117
|
+
export const readPairs = (ctx, init, label) => Effect.gen(function* () {
|
|
118
|
+
const cursor = yield* ctx.iterate(init);
|
|
119
|
+
if (cursor === undefined)
|
|
120
|
+
return undefined;
|
|
121
|
+
const pairs = [];
|
|
122
|
+
while (true) {
|
|
123
|
+
const step = yield* cursor.next;
|
|
124
|
+
if (step.done) {
|
|
125
|
+
if (pairs.some((entry) => entry.length !== 2))
|
|
126
|
+
throw typeError(`${label} expects iterable [name, value] pairs.`);
|
|
127
|
+
return pairs;
|
|
128
|
+
}
|
|
129
|
+
pairs.push(yield* preserveConsumerError(cursor, readPair(ctx, step.value, label)));
|
|
130
|
+
}
|
|
131
|
+
});
|
|
114
132
|
const constructURLSearchParams = (ctx, init, proto) => {
|
|
115
133
|
const wrap = (params) => new URLSearchParamsObj(proto, params);
|
|
116
134
|
if (init === undefined)
|
|
@@ -123,20 +141,9 @@ const constructURLSearchParams = (ctx, init, proto) => {
|
|
|
123
141
|
return Effect.succeed(wrap(new URLSearchParams(coerceToString(init))));
|
|
124
142
|
}
|
|
125
143
|
return Effect.gen(function* () {
|
|
126
|
-
const
|
|
127
|
-
if (
|
|
128
|
-
|
|
129
|
-
while (true) {
|
|
130
|
-
const step = yield* cursor.next;
|
|
131
|
-
if (step.done) {
|
|
132
|
-
if (pairs.some((entry) => entry.length !== 2)) {
|
|
133
|
-
throw typeError("new URLSearchParams(...) expects iterable [name, value] pairs.");
|
|
134
|
-
}
|
|
135
|
-
return wrap(new URLSearchParams(pairs.map((entry) => [entry[0] ?? "", entry[1] ?? ""])));
|
|
136
|
-
}
|
|
137
|
-
pairs.push(yield* preserveConsumerError(cursor, readPair(ctx, step.value)));
|
|
138
|
-
}
|
|
139
|
-
}
|
|
144
|
+
const pairs = yield* readPairs(ctx, init, "new URLSearchParams(...)");
|
|
145
|
+
if (pairs !== undefined)
|
|
146
|
+
return wrap(new URLSearchParams(pairs));
|
|
140
147
|
if (isRuntimeReference(init)) {
|
|
141
148
|
throw typeError("new URLSearchParams(...) expects a query string, data object, or synchronous iterable pairs.");
|
|
142
149
|
}
|
package/dist/stdlib/value.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { fn } from "../interpreter/native.js";
|
|
2
2
|
import { typeError } from "../interpreter/model.js";
|
|
3
|
-
import { get, isWrapper, Arr, Bytes, DateObj, ErrorObj, MapObj, RegExpObj, SetObj, URLObj, URLSearchParamsObj, } from "../interpreter/objects.js";
|
|
3
|
+
import { get, isWrapper, Arr, Bytes, DateObj, ErrorObj, MapObj, RegExpObj, SetObj, URLObj, URLSearchParamsObj, HeadersObj, } from "../interpreter/objects.js";
|
|
4
4
|
export const compoundOperators = new Set(["+=", "-=", "*=", "/=", "%=", "**=", "&=", "|=", "^=", "<<=", ">>=", ">>>="]);
|
|
5
5
|
/** The built-in string form of a value, without consulting program-defined `toString` methods. */
|
|
6
6
|
export const coerceToString = (value) => {
|
|
@@ -20,6 +20,8 @@ export const coerceToString = (value) => {
|
|
|
20
20
|
return value.url.href;
|
|
21
21
|
if (value instanceof URLSearchParamsObj)
|
|
22
22
|
return value.params.toString();
|
|
23
|
+
if (value instanceof HeadersObj)
|
|
24
|
+
return "[object Headers]";
|
|
23
25
|
if (value instanceof Bytes)
|
|
24
26
|
return value.bytes.join(",");
|
|
25
27
|
if (value instanceof ErrorObj) {
|
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-19868",
|
|
5
5
|
"description": "Effect-native confined code execution over schema-described tools",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"license": "MIT",
|