@caplets/core 0.24.1 → 0.25.1
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/attach/options.d.ts +1 -0
- package/dist/attach/server.d.ts +3 -0
- package/dist/caplet-source.js +14 -11
- package/dist/cli/commands.d.ts +10 -2
- package/dist/cli/doctor.d.ts +4 -1
- package/dist/cli.d.ts +3 -2
- package/dist/code-mode/platform-runtime.generated.d.ts +1 -1
- package/dist/code-mode.js +6 -6
- package/dist/{completion-BeVXdm9q.js → completion-De4t5MtT.js} +32 -10
- package/dist/config-runtime.js +2 -2
- package/dist/daemon/config.d.ts +8 -0
- package/dist/daemon/env.d.ts +2 -0
- package/dist/daemon/index.d.ts +18 -0
- package/dist/daemon/logs.d.ts +15 -0
- package/dist/daemon/manager.d.ts +2 -0
- package/dist/daemon/paths.d.ts +2 -0
- package/dist/daemon/platform-darwin.d.ts +3 -0
- package/dist/daemon/platform-linux.d.ts +3 -0
- package/dist/daemon/platform-windows.d.ts +3 -0
- package/dist/daemon/process.d.ts +11 -0
- package/dist/daemon/shell.d.ts +20 -0
- package/dist/daemon/types.d.ts +178 -0
- package/dist/daemon/validation.d.ts +14 -0
- package/dist/daemon/xml.d.ts +1 -0
- package/dist/generated-tool-input-schema.js +1 -1
- package/dist/index.js +5854 -3559
- package/dist/native/options.d.ts +5 -2
- package/dist/native/remote.d.ts +6 -1
- package/dist/native.js +1 -1
- package/dist/observed-output-shapes/pure.js +1 -1
- package/dist/{observed-output-shapes-D2k2-q8K.js → observed-output-shapes-DuP7mJQf.js} +1 -1
- package/dist/observed-output-shapes.js +1 -1
- package/dist/project-binding/attach.d.ts +1 -3
- package/dist/project-binding/session.d.ts +1 -0
- package/dist/remote/credential-store.d.ts +12 -0
- package/dist/remote/options.d.ts +2 -7
- package/dist/remote/pairing.d.ts +13 -0
- package/dist/remote/profile-store.d.ts +94 -0
- package/dist/remote/profiles.d.ts +47 -0
- package/dist/remote/selection.d.ts +4 -4
- package/dist/remote/server-credential-store.d.ts +84 -0
- package/dist/remote/server-credentials.d.ts +21 -0
- package/dist/remote-control/client.d.ts +4 -1
- package/dist/{schemas-C0PNPwjS.js → schemas-BoqMu4MG.js} +11 -8
- package/dist/serve/http.d.ts +5 -0
- package/dist/serve/index.d.ts +1 -3
- package/dist/serve/options.d.ts +7 -12
- package/dist/server/options.d.ts +2 -9
- package/dist/{service-Cvnuu9wr.js → service-Ut6dN9M8.js} +1119 -289
- package/dist/{validation-DgxCzt-A.js → validation-C4tYXw6G.js} +1 -1
- package/package.json +1 -1
- package/dist/serve/daemon/config.d.ts +0 -8
- package/dist/serve/daemon/index.d.ts +0 -16
- package/dist/serve/daemon/paths.d.ts +0 -3
- package/dist/serve/daemon/platform-darwin.d.ts +0 -2
- package/dist/serve/daemon/platform-linux.d.ts +0 -2
- package/dist/serve/daemon/platform-windows.d.ts +0 -2
- package/dist/serve/daemon/platform.d.ts +0 -9
- package/dist/serve/daemon/process.d.ts +0 -5
- package/dist/serve/daemon/types.d.ts +0 -86
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { A as safeParseAsync$1, C as toJSONSchema, D as parse$3, E as $ZodType, F as NEVER, M as defineLazy, N as normalizeParams, O as parseAsync, P as $constructor, S as datetime, T as $ZodObject, _ as record, a as any, b as unknown, c as custom, d as literal, f as looseObject, g as preprocess, h as optional, i as _null, j as clone, k as safeParse$1, l as discriminatedUnion, m as object$1, o as array, p as number$1, r as _enum, s as boolean, t as ZodNumber$1, u as intersection, v as string, w as _coercedNumber, x as url, y as union } from "./schemas-
|
|
2
|
-
import { a as isAllowedHttpBaseUrl, c as validateHttpActionHeaders, d as errorResult, f as redactSecrets, i as SERVER_ID_PATTERN, n as HEADER_NAME_PATTERN, o as isAllowedRemoteUrl, p as toSafeError, r as HTTP_BASE_URL_PATTERN, s as isUrl, t as FORBIDDEN_HEADERS, u as CapletsError } from "./validation-
|
|
1
|
+
import { A as safeParseAsync$1, C as toJSONSchema, D as parse$3, E as $ZodType, F as NEVER, M as defineLazy, N as normalizeParams, O as parseAsync, P as $constructor, S as datetime, T as $ZodObject, _ as record, a as any, b as unknown, c as custom, d as literal, f as looseObject, g as preprocess, h as optional, i as _null, j as clone, k as safeParse$1, l as discriminatedUnion, m as object$1, o as array, p as number$1, r as _enum, s as boolean, t as ZodNumber$1, u as intersection, v as string, w as _coercedNumber, x as url, y as union } from "./schemas-BoqMu4MG.js";
|
|
2
|
+
import { a as isAllowedHttpBaseUrl, c as validateHttpActionHeaders, d as errorResult, f as redactSecrets, i as SERVER_ID_PATTERN, n as HEADER_NAME_PATTERN, o as isAllowedRemoteUrl, p as toSafeError, r as HTTP_BASE_URL_PATTERN, s as isUrl, t as FORBIDDEN_HEADERS, u as CapletsError } from "./validation-C4tYXw6G.js";
|
|
3
3
|
import { generatedToolInputJsonSchema, generatedToolInputJsonSchemaForCaplet, generatedToolInputSchemaForCaplet, mcpOperations, operations } from "./generated-tool-input-schema.js";
|
|
4
|
-
import { f as observedOutputShapeKey, i as observeOutputShape, r as normalizedObservableValue, t as usefulOutputSchema, u as FileObservedOutputShapeStore } from "./observed-output-shapes-
|
|
4
|
+
import { f as observedOutputShapeKey, i as observeOutputShape, r as normalizedObservableValue, t as usefulOutputSchema, u as FileObservedOutputShapeStore } from "./observed-output-shapes-DuP7mJQf.js";
|
|
5
5
|
import { createRequire } from "node:module";
|
|
6
6
|
import { accessSync, chmodSync, constants, existsSync, lstatSync, mkdirSync, readFileSync, readdirSync, renameSync, rmSync, statSync, watch, writeFileSync } from "node:fs";
|
|
7
7
|
import { basename, delimiter, dirname, extname, isAbsolute, join, parse, posix, relative, resolve, sep, win32 } from "node:path";
|
|
@@ -14,7 +14,6 @@ import { homedir } from "node:os";
|
|
|
14
14
|
import { readFile } from "node:fs/promises";
|
|
15
15
|
import ts from "typescript";
|
|
16
16
|
import { getQuickJS, shouldInterruptAfterDeadline } from "quickjs-emscripten";
|
|
17
|
-
import { Buffer as Buffer$1 } from "node:buffer";
|
|
18
17
|
//#region \0rolldown/runtime.js
|
|
19
18
|
var __create = Object.create;
|
|
20
19
|
var __defProp = Object.defineProperty;
|
|
@@ -46,7 +45,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
46
45
|
value: mod,
|
|
47
46
|
enumerable: true
|
|
48
47
|
}) : target, mod));
|
|
49
|
-
var __require = /*
|
|
48
|
+
var __require = /* #__PURE__ */ (() => createRequire(import.meta.url))();
|
|
50
49
|
//#endregion
|
|
51
50
|
//#region ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v3/helpers/util.js
|
|
52
51
|
var util$1;
|
|
@@ -8911,7 +8910,7 @@ var require_boolSchema = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
8911
8910
|
var require_rules = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
8912
8911
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8913
8912
|
exports.getRules = exports.isJSONType = void 0;
|
|
8914
|
-
const jsonTypes = new Set([
|
|
8913
|
+
const jsonTypes = /* @__PURE__ */ new Set([
|
|
8915
8914
|
"string",
|
|
8916
8915
|
"number",
|
|
8917
8916
|
"integer",
|
|
@@ -9030,7 +9029,7 @@ var require_dataType = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
9030
9029
|
return checkTypes;
|
|
9031
9030
|
}
|
|
9032
9031
|
exports.coerceAndCheckDataType = coerceAndCheckDataType;
|
|
9033
|
-
const COERCIBLE = new Set([
|
|
9032
|
+
const COERCIBLE = /* @__PURE__ */ new Set([
|
|
9034
9033
|
"string",
|
|
9035
9034
|
"number",
|
|
9036
9035
|
"integer",
|
|
@@ -9584,7 +9583,7 @@ var require_resolve = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
9584
9583
|
const util_1 = require_util$1();
|
|
9585
9584
|
const equal = require_fast_deep_equal();
|
|
9586
9585
|
const traverse = require_json_schema_traverse();
|
|
9587
|
-
const SIMPLE_INLINED = new Set([
|
|
9586
|
+
const SIMPLE_INLINED = /* @__PURE__ */ new Set([
|
|
9588
9587
|
"type",
|
|
9589
9588
|
"format",
|
|
9590
9589
|
"pattern",
|
|
@@ -9609,7 +9608,7 @@ var require_resolve = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
9609
9608
|
return countKeys(schema) <= limit;
|
|
9610
9609
|
}
|
|
9611
9610
|
exports.inlineRef = inlineRef;
|
|
9612
|
-
const REF_KEYWORDS = new Set([
|
|
9611
|
+
const REF_KEYWORDS = /* @__PURE__ */ new Set([
|
|
9613
9612
|
"$ref",
|
|
9614
9613
|
"$recursiveRef",
|
|
9615
9614
|
"$recursiveAnchor",
|
|
@@ -10330,7 +10329,7 @@ var require_compile = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
10330
10329
|
return getJsonPointer.call(this, p, schOrRef);
|
|
10331
10330
|
}
|
|
10332
10331
|
exports.resolveSchema = resolveSchema;
|
|
10333
|
-
const PREVENT_SCOPE_CHANGE = new Set([
|
|
10332
|
+
const PREVENT_SCOPE_CHANGE = /* @__PURE__ */ new Set([
|
|
10334
10333
|
"properties",
|
|
10335
10334
|
"patternProperties",
|
|
10336
10335
|
"enum",
|
|
@@ -11282,7 +11281,7 @@ var require_core$4 = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
11282
11281
|
"useDefaults",
|
|
11283
11282
|
"coerceTypes"
|
|
11284
11283
|
];
|
|
11285
|
-
const EXT_SCOPE_NAMES = new Set([
|
|
11284
|
+
const EXT_SCOPE_NAMES = /* @__PURE__ */ new Set([
|
|
11286
11285
|
"validate",
|
|
11287
11286
|
"serialize",
|
|
11288
11287
|
"parse",
|
|
@@ -18096,7 +18095,7 @@ function searchToolList(tools, query, limit, compact) {
|
|
|
18096
18095
|
return utility === 0 ? left.tool.name.localeCompare(right.tool.name) : utility;
|
|
18097
18096
|
}).slice(0, limit).map((candidate) => compact(candidate.tool));
|
|
18098
18097
|
}
|
|
18099
|
-
const MUTATING_QUERY_TOKENS = new Set([
|
|
18098
|
+
const MUTATING_QUERY_TOKENS = /* @__PURE__ */ new Set([
|
|
18100
18099
|
"add",
|
|
18101
18100
|
"create",
|
|
18102
18101
|
"delete",
|
|
@@ -18627,8 +18626,8 @@ function compactToolSafetyHints(tool) {
|
|
|
18627
18626
|
};
|
|
18628
18627
|
}
|
|
18629
18628
|
function compactToolSchemaHints(tool) {
|
|
18630
|
-
const schema = isRecord$
|
|
18631
|
-
const properties = isRecord$
|
|
18629
|
+
const schema = isRecord$7(tool.inputSchema) ? tool.inputSchema : void 0;
|
|
18630
|
+
const properties = isRecord$7(schema?.properties) ? schema.properties : {};
|
|
18632
18631
|
const acceptedArgs = Object.keys(properties).sort();
|
|
18633
18632
|
const requiredArgs = Array.isArray(schema?.required) ? schema.required.filter((value) => typeof value === "string").sort() : [];
|
|
18634
18633
|
const argsTemplate = compactArgsTemplate(properties, requiredArgs, acceptedArgs);
|
|
@@ -18652,7 +18651,7 @@ function compactArgsTemplate(properties, requiredArgs, acceptedArgs) {
|
|
|
18652
18651
|
if (templateArgs.length === 0 || templateArgs.length > 4) return void 0;
|
|
18653
18652
|
if (requiredArgs.length === 0 && acceptedArgs.length > 3) return void 0;
|
|
18654
18653
|
const entries = templateArgs.flatMap((name) => {
|
|
18655
|
-
const value = placeholderForSchema(isRecord$
|
|
18654
|
+
const value = placeholderForSchema(isRecord$7(properties[name]) ? properties[name] : void 0);
|
|
18656
18655
|
return value === void 0 ? [] : [[name, value]];
|
|
18657
18656
|
});
|
|
18658
18657
|
return entries.length === templateArgs.length ? Object.fromEntries(entries) : void 0;
|
|
@@ -18672,13 +18671,13 @@ function placeholderForSchema(schema) {
|
|
|
18672
18671
|
}
|
|
18673
18672
|
}
|
|
18674
18673
|
function compactToolSelectionHints(tool) {
|
|
18675
|
-
if (!isRecord$
|
|
18674
|
+
if (!isRecord$7(tool)) return {};
|
|
18676
18675
|
return {
|
|
18677
18676
|
...typeof tool.useWhen === "string" && tool.useWhen.trim() ? { useWhen: tool.useWhen.trim() } : {},
|
|
18678
18677
|
...typeof tool.avoidWhen === "string" && tool.avoidWhen.trim() ? { avoidWhen: tool.avoidWhen.trim() } : {}
|
|
18679
18678
|
};
|
|
18680
18679
|
}
|
|
18681
|
-
function isRecord$
|
|
18680
|
+
function isRecord$7(value) {
|
|
18682
18681
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
18683
18682
|
}
|
|
18684
18683
|
function sameServerConfig(left, right) {
|
|
@@ -18753,7 +18752,7 @@ function markdownCallToolResultContent(result, context = {}) {
|
|
|
18753
18752
|
return textContent(renderStructuredMarkdown(result, context));
|
|
18754
18753
|
}
|
|
18755
18754
|
function hasRenderableStructuredContent(value) {
|
|
18756
|
-
if (!isRecord$
|
|
18755
|
+
if (!isRecord$6(value)) return false;
|
|
18757
18756
|
return Object.keys(value).some((key) => key !== "caplets" && key !== "elapsedMs");
|
|
18758
18757
|
}
|
|
18759
18758
|
function renderStructuredMarkdown(value, context) {
|
|
@@ -18887,13 +18886,13 @@ function renderErrorMarkdown(value, title) {
|
|
|
18887
18886
|
].join("\n");
|
|
18888
18887
|
}
|
|
18889
18888
|
function isDiscoveryWrapper(value) {
|
|
18890
|
-
return isRecord$
|
|
18889
|
+
return isRecord$6(value) && "result" in value;
|
|
18891
18890
|
}
|
|
18892
18891
|
function isErrorStructuredContent(value) {
|
|
18893
|
-
return isRecord$
|
|
18892
|
+
return isRecord$6(value) && "error" in value;
|
|
18894
18893
|
}
|
|
18895
18894
|
function isHttpLikeResult(value) {
|
|
18896
|
-
return isRecord$
|
|
18895
|
+
return isRecord$6(value) && ("status" in value || "statusText" in value || "body" in value);
|
|
18897
18896
|
}
|
|
18898
18897
|
function isGraphQlHttpResult(value) {
|
|
18899
18898
|
if (!isHttpLikeResult(value)) return false;
|
|
@@ -18901,7 +18900,7 @@ function isGraphQlHttpResult(value) {
|
|
|
18901
18900
|
return Boolean(body && ("data" in body || "errors" in body));
|
|
18902
18901
|
}
|
|
18903
18902
|
function isCliResult(value) {
|
|
18904
|
-
return isRecord$
|
|
18903
|
+
return isRecord$6(value) && ("exitCode" in value || "stdout" in value || "stderr" in value);
|
|
18905
18904
|
}
|
|
18906
18905
|
function renderBodyValue(value) {
|
|
18907
18906
|
if (value === void 0) return "_No response body._";
|
|
@@ -18969,8 +18968,8 @@ function compactListHints(record) {
|
|
|
18969
18968
|
const acceptedArgs = stringArrayValue(record.acceptedArgs);
|
|
18970
18969
|
if (requiredArgs.length > 0) hints.push(`required args: ${requiredArgs.join(", ")}`);
|
|
18971
18970
|
else if (acceptedArgs.length > 0) hints.push(`args: ${acceptedArgs.join(", ")}`);
|
|
18972
|
-
if (isRecord$
|
|
18973
|
-
if (isRecord$
|
|
18971
|
+
if (isRecord$6(record.argsTemplate)) hints.push(`args template: ${compactJsonText(record.argsTemplate, 160)}`);
|
|
18972
|
+
if (isRecord$6(record.callTemplate)) hints.push(`call: ${compactJsonText(record.callTemplate, 220)}`);
|
|
18974
18973
|
if (record.supportsFields === true) hints.push("supports fields");
|
|
18975
18974
|
if (record.readOnlyHint === true) hints.push("read-only");
|
|
18976
18975
|
if (record.destructiveHint === true) hints.push("destructive");
|
|
@@ -19040,9 +19039,9 @@ function humanizeKey(key) {
|
|
|
19040
19039
|
return key.replace(/([A-Z])/gu, " $1").replace(/^./u, (char) => char.toUpperCase());
|
|
19041
19040
|
}
|
|
19042
19041
|
function asRecord$3(value) {
|
|
19043
|
-
return isRecord$
|
|
19042
|
+
return isRecord$6(value) ? value : void 0;
|
|
19044
19043
|
}
|
|
19045
|
-
function isRecord$
|
|
19044
|
+
function isRecord$6(value) {
|
|
19046
19045
|
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
19047
19046
|
}
|
|
19048
19047
|
//#endregion
|
|
@@ -20098,7 +20097,7 @@ var require_Collection = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
20098
20097
|
const a = [];
|
|
20099
20098
|
a[k] = v;
|
|
20100
20099
|
v = a;
|
|
20101
|
-
} else v = new Map([[k, v]]);
|
|
20100
|
+
} else v = /* @__PURE__ */ new Map([[k, v]]);
|
|
20102
20101
|
}
|
|
20103
20102
|
return createNode.createNode(v, void 0, {
|
|
20104
20103
|
aliasDuplicateObjects: false,
|
|
@@ -20657,7 +20656,7 @@ var require_stringify = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
20657
20656
|
if (ctx.resolvedAliases?.has(item)) throw new TypeError(`Cannot stringify circular structure without alias nodes`);
|
|
20658
20657
|
else {
|
|
20659
20658
|
if (ctx.resolvedAliases) ctx.resolvedAliases.add(item);
|
|
20660
|
-
else ctx.resolvedAliases = new Set([item]);
|
|
20659
|
+
else ctx.resolvedAliases = /* @__PURE__ */ new Set([item]);
|
|
20661
20660
|
item = item.resolve(ctx.doc);
|
|
20662
20661
|
}
|
|
20663
20662
|
}
|
|
@@ -22051,7 +22050,7 @@ var require_tags = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
22051
22050
|
var schema$2 = require_schema$7();
|
|
22052
22051
|
var set = require_set$1();
|
|
22053
22052
|
var timestamp = require_timestamp$1();
|
|
22054
|
-
const schemas = new Map([
|
|
22053
|
+
const schemas = /* @__PURE__ */ new Map([
|
|
22055
22054
|
["core", schema.schema],
|
|
22056
22055
|
["failsafe", [
|
|
22057
22056
|
map.map,
|
|
@@ -26763,7 +26762,7 @@ function hasEnvReference$1(value) {
|
|
|
26763
26762
|
}
|
|
26764
26763
|
//#endregion
|
|
26765
26764
|
//#region src/config.ts
|
|
26766
|
-
const NON_INTERPOLATED_SERVER_FIELDS = new Set([
|
|
26765
|
+
const NON_INTERPOLATED_SERVER_FIELDS = /* @__PURE__ */ new Set([
|
|
26767
26766
|
"name",
|
|
26768
26767
|
"description",
|
|
26769
26768
|
"tags",
|
|
@@ -27962,7 +27961,7 @@ function googleDiscoverySchemaToJsonSchema(value, schemas = {}, seen = /* @__PUR
|
|
|
27962
27961
|
type: "object",
|
|
27963
27962
|
additionalProperties: true
|
|
27964
27963
|
};
|
|
27965
|
-
return googleDiscoverySchemaToJsonSchema(target, schemas, new Set([...seen, value.$ref]));
|
|
27964
|
+
return googleDiscoverySchemaToJsonSchema(target, schemas, /* @__PURE__ */ new Set([...seen, value.$ref]));
|
|
27966
27965
|
}
|
|
27967
27966
|
const type = discoveryTypeToJsonSchemaType(value.type);
|
|
27968
27967
|
const converted = {};
|
|
@@ -28017,17 +28016,17 @@ function googleDiscoveryScopesForOperations(operations) {
|
|
|
28017
28016
|
return [...new Set(operations.flatMap((operation) => operation.scopes))].sort();
|
|
28018
28017
|
}
|
|
28019
28018
|
function validateGoogleDiscoveryDocument(value) {
|
|
28020
|
-
if (!isRecord$
|
|
28019
|
+
if (!isRecord$5(value)) throw new Error("Invalid Google Discovery document: expected an object");
|
|
28021
28020
|
if (value.kind !== void 0 && value.kind !== "discovery#restDescription") throw new Error("Invalid Google Discovery document: expected kind discovery#restDescription");
|
|
28022
|
-
if (value.resources !== void 0 && !isRecord$
|
|
28023
|
-
if (value.methods !== void 0 && !isRecord$
|
|
28024
|
-
if (!isRecord$
|
|
28025
|
-
if (value.schemas !== void 0 && !isRecord$
|
|
28026
|
-
if (value.parameters !== void 0 && !isRecord$
|
|
28021
|
+
if (value.resources !== void 0 && !isRecord$5(value.resources)) throw new Error("Invalid Google Discovery document: expected resources object");
|
|
28022
|
+
if (value.methods !== void 0 && !isRecord$5(value.methods)) throw new Error("Invalid Google Discovery document: expected methods object");
|
|
28023
|
+
if (!isRecord$5(value.resources) && !isRecord$5(value.methods)) throw new Error("Invalid Google Discovery document: expected resources or methods object");
|
|
28024
|
+
if (value.schemas !== void 0 && !isRecord$5(value.schemas)) throw new Error("Invalid Google Discovery document: expected schemas object");
|
|
28025
|
+
if (value.parameters !== void 0 && !isRecord$5(value.parameters)) throw new Error("Invalid Google Discovery document: expected parameters object");
|
|
28027
28026
|
return value;
|
|
28028
28027
|
}
|
|
28029
28028
|
function collectDocumentMethods(document) {
|
|
28030
|
-
return [...Object.entries(document.methods ?? {}).filter((entry) => isRecord$
|
|
28029
|
+
return [...Object.entries(document.methods ?? {}).filter((entry) => isRecord$5(entry[1])).map(([methodKey, method]) => ({
|
|
28031
28030
|
resourcePath: [],
|
|
28032
28031
|
methodKey,
|
|
28033
28032
|
method
|
|
@@ -28036,9 +28035,9 @@ function collectDocumentMethods(document) {
|
|
|
28036
28035
|
function collectMethods(resources, resourcePath = []) {
|
|
28037
28036
|
const entries = [];
|
|
28038
28037
|
for (const [resourceName, resource] of Object.entries(resources)) {
|
|
28039
|
-
if (!isRecord$
|
|
28038
|
+
if (!isRecord$5(resource)) continue;
|
|
28040
28039
|
const nextPath = [...resourcePath, resourceName];
|
|
28041
|
-
for (const [methodKey, method] of Object.entries(resource.methods ?? {})) if (isRecord$
|
|
28040
|
+
for (const [methodKey, method] of Object.entries(resource.methods ?? {})) if (isRecord$5(method)) entries.push({
|
|
28042
28041
|
resourcePath: nextPath,
|
|
28043
28042
|
methodKey,
|
|
28044
28043
|
method
|
|
@@ -28211,7 +28210,7 @@ function globMatches(pattern, name) {
|
|
|
28211
28210
|
function isJsonSchemaObject(value) {
|
|
28212
28211
|
return value.type === "object" || "properties" in value || "additionalProperties" in value;
|
|
28213
28212
|
}
|
|
28214
|
-
function isRecord$
|
|
28213
|
+
function isRecord$5(value) {
|
|
28215
28214
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
28216
28215
|
}
|
|
28217
28216
|
function collapseWhitespace(value) {
|
|
@@ -41373,7 +41372,7 @@ var require_OverlappingFieldsCanBeMergedRule = /* @__PURE__ */ __commonJSMin(((e
|
|
|
41373
41372
|
}
|
|
41374
41373
|
add(a, b, weaklyPresent) {
|
|
41375
41374
|
const map = this._data.get(a);
|
|
41376
|
-
if (map === void 0) this._data.set(a, new Map([[b, weaklyPresent]]));
|
|
41375
|
+
if (map === void 0) this._data.set(a, /* @__PURE__ */ new Map([[b, weaklyPresent]]));
|
|
41377
41376
|
else map.set(b, weaklyPresent);
|
|
41378
41377
|
}
|
|
41379
41378
|
};
|
|
@@ -61333,7 +61332,7 @@ const HTTP_METHODS = [
|
|
|
61333
61332
|
];
|
|
61334
61333
|
const DEFAULT_OPENAPI_RESPONSE_MAX_BYTES = 100 * 1024 * 1024;
|
|
61335
61334
|
const JSON_CONTENT_TYPES = ["application/json"];
|
|
61336
|
-
const FORBIDDEN_ARGUMENT_HEADERS = new Set([
|
|
61335
|
+
const FORBIDDEN_ARGUMENT_HEADERS = /* @__PURE__ */ new Set([
|
|
61337
61336
|
"accept",
|
|
61338
61337
|
"authorization",
|
|
61339
61338
|
"connection",
|
|
@@ -62995,7 +62994,7 @@ var CapletSetManager = class CapletSetManager {
|
|
|
62995
62994
|
...this.options.artifactDir ? { artifactDir: this.options.artifactDir } : {},
|
|
62996
62995
|
...this.options.exposeLocalArtifactPaths === false ? { exposeLocalArtifactPaths: false } : {}
|
|
62997
62996
|
};
|
|
62998
|
-
const childAncestry = new Set([...ancestry, cacheKey]);
|
|
62997
|
+
const childAncestry = /* @__PURE__ */ new Set([...ancestry, cacheKey]);
|
|
62999
62998
|
child = {
|
|
63000
62999
|
registry,
|
|
63001
63000
|
downstream: new DownstreamManager(registry, sharedOptions),
|
|
@@ -63435,7 +63434,7 @@ var CapletsEngine = class {
|
|
|
63435
63434
|
}
|
|
63436
63435
|
}
|
|
63437
63436
|
async completeCliWords(words) {
|
|
63438
|
-
const { completeCliWords } = await import("./completion-
|
|
63437
|
+
const { completeCliWords } = await import("./completion-De4t5MtT.js").then((n) => n.r);
|
|
63439
63438
|
return await completeCliWords(words, {
|
|
63440
63439
|
config: this.registry.config,
|
|
63441
63440
|
managers: {
|
|
@@ -63568,7 +63567,7 @@ var CapletsEngine = class {
|
|
|
63568
63567
|
async invalidateChangedBackends(previous, next) {
|
|
63569
63568
|
const previousCaplets = new Map(allCaplets(previous).map((server) => [server.server, server]));
|
|
63570
63569
|
const nextCaplets = new Map(allCaplets(next).map((server) => [server.server, server]));
|
|
63571
|
-
const changedIds = new Set([...previousCaplets.keys(), ...nextCaplets.keys()]);
|
|
63570
|
+
const changedIds = /* @__PURE__ */ new Set([...previousCaplets.keys(), ...nextCaplets.keys()]);
|
|
63572
63571
|
for (const serverId of changedIds) {
|
|
63573
63572
|
const before = previousCaplets.get(serverId);
|
|
63574
63573
|
const after = nextCaplets.get(serverId);
|
|
@@ -63725,7 +63724,7 @@ function annotateDirectResult(result, caplet, operation) {
|
|
|
63725
63724
|
return {
|
|
63726
63725
|
...result,
|
|
63727
63726
|
_meta: {
|
|
63728
|
-
...isRecord$
|
|
63727
|
+
...isRecord$4(existingMeta) ? existingMeta : {},
|
|
63729
63728
|
caplets: {
|
|
63730
63729
|
capletId: caplet.server,
|
|
63731
63730
|
backend: caplet.backend,
|
|
@@ -63738,7 +63737,7 @@ function annotateDirectResult(result, caplet, operation) {
|
|
|
63738
63737
|
function isUnsupportedCapability(error) {
|
|
63739
63738
|
return error instanceof CapletsError && error.code === "UNSUPPORTED_CAPABILITY";
|
|
63740
63739
|
}
|
|
63741
|
-
function isRecord$
|
|
63740
|
+
function isRecord$4(value) {
|
|
63742
63741
|
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
63743
63742
|
}
|
|
63744
63743
|
//#endregion
|
|
@@ -63971,7 +63970,7 @@ var CodeModeJournalStore = class {
|
|
|
63971
63970
|
version: JOURNAL_VERSION,
|
|
63972
63971
|
journalKey,
|
|
63973
63972
|
sessionIdHash: this.sessionIdHash(input.sessionId),
|
|
63974
|
-
recoveryRefHashes: [
|
|
63973
|
+
recoveryRefHashes: [.../* @__PURE__ */ new Set([...existing?.recoveryRefHashes ?? [], recoveryRefHash])],
|
|
63975
63974
|
createdAt: existing?.createdAt ?? now.toISOString(),
|
|
63976
63975
|
updatedAt: now.toISOString(),
|
|
63977
63976
|
expiresAt,
|
|
@@ -65030,7 +65029,7 @@ var import_lib = (/* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
65030
65029
|
ParseExpressionEmptyInput: "Unexpected parseExpression() input: The input is empty or contains only comments.",
|
|
65031
65030
|
ParseExpressionExpectsEOF: ({ unexpected }) => `Unexpected parseExpression() input: The input should contain exactly one expression, but the first expression is followed by the unexpected character \`${String.fromCodePoint(unexpected)}\`.`
|
|
65032
65031
|
};
|
|
65033
|
-
const UnparenthesizedPipeBodyDescriptions = new Set([
|
|
65032
|
+
const UnparenthesizedPipeBodyDescriptions = /* @__PURE__ */ new Set([
|
|
65034
65033
|
"ArrowFunctionExpression",
|
|
65035
65034
|
"AssignmentExpression",
|
|
65036
65035
|
"ConditionalExpression",
|
|
@@ -66931,7 +66930,7 @@ var import_lib = (/* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
66931
66930
|
function isIteratorStart(current, next, next2) {
|
|
66932
66931
|
return current === 64 && next === 64 && isIdentifierStart(next2);
|
|
66933
66932
|
}
|
|
66934
|
-
const reservedWordLikeSet = new Set([
|
|
66933
|
+
const reservedWordLikeSet = /* @__PURE__ */ new Set([
|
|
66935
66934
|
"break",
|
|
66936
66935
|
"case",
|
|
66937
66936
|
"catch",
|
|
@@ -67137,7 +67136,7 @@ var import_lib = (/* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
67137
67136
|
if (!this.scopeStack[0].declareFunctions.has(id.name)) super.checkLocalExport(id);
|
|
67138
67137
|
}
|
|
67139
67138
|
};
|
|
67140
|
-
const reservedTypes = new Set([
|
|
67139
|
+
const reservedTypes = /* @__PURE__ */ new Set([
|
|
67141
67140
|
"_",
|
|
67142
67141
|
"any",
|
|
67143
67142
|
"bool",
|
|
@@ -70116,7 +70115,7 @@ var import_lib = (/* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
70116
70115
|
return code >= 48 && code <= 57;
|
|
70117
70116
|
};
|
|
70118
70117
|
const forbiddenNumericSeparatorSiblings = {
|
|
70119
|
-
decBinOct: new Set([
|
|
70118
|
+
decBinOct: /* @__PURE__ */ new Set([
|
|
70120
70119
|
46,
|
|
70121
70120
|
66,
|
|
70122
70121
|
69,
|
|
@@ -70126,7 +70125,7 @@ var import_lib = (/* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
70126
70125
|
101,
|
|
70127
70126
|
111
|
|
70128
70127
|
]),
|
|
70129
|
-
hex: new Set([
|
|
70128
|
+
hex: /* @__PURE__ */ new Set([
|
|
70130
70129
|
46,
|
|
70131
70130
|
88,
|
|
70132
70131
|
95,
|
|
@@ -70334,7 +70333,7 @@ var import_lib = (/* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
70334
70333
|
function buildPosition(pos, lineStart, curLine) {
|
|
70335
70334
|
return new Position(curLine, pos - lineStart, pos);
|
|
70336
70335
|
}
|
|
70337
|
-
const VALID_REGEX_FLAGS = new Set([
|
|
70336
|
+
const VALID_REGEX_FLAGS = /* @__PURE__ */ new Set([
|
|
70338
70337
|
103,
|
|
70339
70338
|
109,
|
|
70340
70339
|
115,
|
|
@@ -77792,10 +77791,10 @@ function resolveTimer(context, deferred, fired) {
|
|
|
77792
77791
|
}
|
|
77793
77792
|
//#endregion
|
|
77794
77793
|
//#region src/code-mode/platform-runtime.generated.ts
|
|
77795
|
-
const CODE_MODE_PLATFORM_RUNTIME_SOURCE = "(function() {\n //#region node_modules/.pnpm/@ungap+structured-clone@1.3.1/node_modules/@ungap/structured-clone/esm/deserialize.js\n const env = typeof self === \"object\" ? self : globalThis;\n const guard = (name, init) => {\n switch (name) {\n case \"Function\":\n case \"SharedWorker\":\n case \"Worker\":\n case \"eval\":\n case \"setInterval\":\n case \"setTimeout\": throw new TypeError(\"unable to deserialize \" + name);\n }\n return new env[name](init);\n };\n const deserializer = ($, _) => {\n const as = (out, index) => {\n $.set(index, out);\n return out;\n };\n const unpair = (index) => {\n if ($.has(index)) return $.get(index);\n const [type, value] = _[index];\n switch (type) {\n case 0:\n case -1: return as(value, index);\n case 1: {\n const arr = as([], index);\n for (const index of value) arr.push(unpair(index));\n return arr;\n }\n case 2: {\n const object = as({}, index);\n for (const [key, index] of value) object[unpair(key)] = unpair(index);\n return object;\n }\n case 3: return as(new Date(value), index);\n case 4: {\n const { source, flags } = value;\n return as(new RegExp(source, flags), index);\n }\n case 5: {\n const map = as(/* @__PURE__ */ new Map(), index);\n for (const [key, index] of value) map.set(unpair(key), unpair(index));\n return map;\n }\n case 6: {\n const set = as(/* @__PURE__ */ new Set(), index);\n for (const index of value) set.add(unpair(index));\n return set;\n }\n case 7: {\n const { name, message } = value;\n return as(guard(name, message), index);\n }\n case 8: return as(BigInt(value), index);\n case \"BigInt\": return as(Object(BigInt(value)), index);\n case \"ArrayBuffer\": return as(new Uint8Array(value).buffer, value);\n case \"DataView\": {\n const { buffer } = new Uint8Array(value);\n return as(new DataView(buffer), value);\n }\n }\n return as(guard(type, value), index);\n };\n return unpair;\n };\n /**\n * @typedef {Array<string,any>} Record a type representation\n */\n /**\n * Returns a deserialized value from a serialized array of Records.\n * @param {Record[]} serialized a previously serialized value.\n * @returns {any}\n */\n const deserialize = (serialized) => deserializer(/* @__PURE__ */ new Map(), serialized)(0);\n //#endregion\n //#region node_modules/.pnpm/@ungap+structured-clone@1.3.1/node_modules/@ungap/structured-clone/esm/serialize.js\n const EMPTY = \"\";\n const { toString } = {};\n const { keys } = Object;\n const typeOf = (value) => {\n const type = typeof value;\n if (type !== \"object\" || !value) return [0, type];\n const asString = toString.call(value).slice(8, -1);\n switch (asString) {\n case \"Array\": return [1, EMPTY];\n case \"Object\": return [2, EMPTY];\n case \"Date\": return [3, EMPTY];\n case \"RegExp\": return [4, EMPTY];\n case \"Map\": return [5, EMPTY];\n case \"Set\": return [6, EMPTY];\n case \"DataView\": return [1, asString];\n }\n if (asString.includes(\"Array\")) return [1, asString];\n if (asString.includes(\"Error\")) return [7, asString];\n return [2, asString];\n };\n const shouldSkip = ([TYPE, type]) => TYPE === 0 && (type === \"function\" || type === \"symbol\");\n const serializer = (strict, json, $, _) => {\n const as = (out, value) => {\n const index = _.push(out) - 1;\n $.set(value, index);\n return index;\n };\n const pair = (value) => {\n if ($.has(value)) return $.get(value);\n let [TYPE, type] = typeOf(value);\n switch (TYPE) {\n case 0: {\n let entry = value;\n switch (type) {\n case \"bigint\":\n TYPE = 8;\n entry = value.toString();\n break;\n case \"function\":\n case \"symbol\":\n if (strict) throw new TypeError(\"unable to serialize \" + type);\n entry = null;\n break;\n case \"undefined\": return as([-1], value);\n }\n return as([TYPE, entry], value);\n }\n case 1: {\n if (type) {\n let spread = value;\n if (type === \"DataView\") spread = new Uint8Array(value.buffer);\n else if (type === \"ArrayBuffer\") spread = new Uint8Array(value);\n return as([type, [...spread]], value);\n }\n const arr = [];\n const index = as([TYPE, arr], value);\n for (const entry of value) arr.push(pair(entry));\n return index;\n }\n case 2: {\n if (type) switch (type) {\n case \"BigInt\": return as([type, value.toString()], value);\n case \"Boolean\":\n case \"Number\":\n case \"String\": return as([type, value.valueOf()], value);\n }\n if (json && \"toJSON\" in value) return pair(value.toJSON());\n const entries = [];\n const index = as([TYPE, entries], value);\n for (const key of keys(value)) if (strict || !shouldSkip(typeOf(value[key]))) entries.push([pair(key), pair(value[key])]);\n return index;\n }\n case 3: return as([TYPE, value.toISOString()], value);\n case 4: {\n const { source, flags } = value;\n return as([TYPE, {\n source,\n flags\n }], value);\n }\n case 5: {\n const entries = [];\n const index = as([TYPE, entries], value);\n for (const [key, entry] of value) if (strict || !(shouldSkip(typeOf(key)) || shouldSkip(typeOf(entry)))) entries.push([pair(key), pair(entry)]);\n return index;\n }\n case 6: {\n const entries = [];\n const index = as([TYPE, entries], value);\n for (const entry of value) if (strict || !shouldSkip(typeOf(entry))) entries.push(pair(entry));\n return index;\n }\n }\n const { message } = value;\n return as([TYPE, {\n name: type,\n message\n }], value);\n };\n return pair;\n };\n /**\n * @typedef {Array<string,any>} Record a type representation\n */\n /**\n * Returns an array of serialized Records.\n * @param {any} value a serializable value.\n * @param {{json?: boolean, lossy?: boolean}?} options an object with a `lossy` or `json` property that,\n * if `true`, will not throw errors on incompatible types, and behave more\n * like JSON stringify would behave. Symbol and Function will be discarded.\n * @returns {Record[]}\n */\n const serialize = (value, { json, lossy } = {}) => {\n const _ = [];\n return serializer(!(json || lossy), !!json, /* @__PURE__ */ new Map(), _)(value), _;\n };\n //#endregion\n //#region node_modules/.pnpm/@ungap+structured-clone@1.3.1/node_modules/@ungap/structured-clone/esm/index.js\n /**\n * @typedef {Array<string,any>} Record a type representation\n */\n /**\n * Returns an array of serialized Records.\n * @param {any} any a serializable value.\n * @param {{transfer?: any[], json?: boolean, lossy?: boolean}?} options an object with\n * a transfer option (ignored when polyfilled) and/or non standard fields that\n * fallback to the polyfill if present.\n * @returns {Record[]}\n */\n var esm_default = typeof structuredClone === \"function\" ? (any, options) => options && (\"json\" in options || \"lossy\" in options) ? deserialize(serialize(any, options)) : structuredClone(any) : (any, options) => deserialize(serialize(any, options));\n //#endregion\n //#region node_modules/.pnpm/formdata-node@6.0.3/node_modules/formdata-node/lib/form-data.js\n var __accessCheck = (obj, member, msg) => {\n if (!member.has(obj)) throw TypeError(\"Cannot \" + msg);\n };\n var __privateGet = (obj, member, getter) => {\n __accessCheck(obj, member, \"read from private field\");\n return getter ? getter.call(obj) : member.get(obj);\n };\n var __privateAdd = (obj, member, value) => {\n if (member.has(obj)) throw TypeError(\"Cannot add the same private member more than once\");\n member instanceof WeakSet ? member.add(obj) : member.set(obj, value);\n };\n var __privateSet = (obj, member, value, setter) => {\n __accessCheck(obj, member, \"write to private field\");\n setter ? setter.call(obj, value) : member.set(obj, value);\n return value;\n };\n var __privateMethod = (obj, member, method) => {\n __accessCheck(obj, member, \"access private method\");\n return method;\n };\n var isFunction = (value) => typeof value === \"function\";\n var isObject = (value) => typeof value === \"object\" && value != null && !Array.isArray(value);\n var isAsyncIterable = (value) => isObject(value) && isFunction(value[Symbol.asyncIterator]);\n var MAX_CHUNK_SIZE = 65536;\n async function* clonePart(value) {\n if (value.byteLength <= MAX_CHUNK_SIZE) {\n yield value;\n return;\n }\n let offset = 0;\n while (offset < value.byteLength) {\n const size = Math.min(value.byteLength - offset, MAX_CHUNK_SIZE);\n const buffer = value.buffer.slice(offset, offset + size);\n offset += buffer.byteLength;\n yield new Uint8Array(buffer);\n }\n }\n async function* readStream(readable) {\n const reader = readable.getReader();\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n yield value;\n }\n }\n async function* chunkStream(stream) {\n for await (const value of stream) yield* clonePart(value);\n }\n var getStreamIterator = (source) => {\n if (isAsyncIterable(source)) return chunkStream(source);\n if (isFunction(source.getReader)) return chunkStream(readStream(source));\n throw new TypeError(\"Unsupported data source: Expected either ReadableStream or async iterable.\");\n };\n async function* consumeNodeBlob(blob) {\n let position = 0;\n while (position !== blob.size) {\n const buffer = await blob.slice(position, Math.min(blob.size, position + MAX_CHUNK_SIZE)).arrayBuffer();\n position += buffer.byteLength;\n yield new Uint8Array(buffer);\n }\n }\n async function* consumeBlobParts(parts, clone = false) {\n for (const part of parts) if (ArrayBuffer.isView(part)) if (clone) yield* clonePart(part);\n else yield part;\n else if (isFunction(part.stream)) yield* getStreamIterator(part.stream());\n else yield* consumeNodeBlob(part);\n }\n function* sliceBlob(blobParts, blobSize, start = 0, end) {\n end ??= blobSize;\n let relativeStart = start < 0 ? Math.max(blobSize + start, 0) : Math.min(start, blobSize);\n let relativeEnd = end < 0 ? Math.max(blobSize + end, 0) : Math.min(end, blobSize);\n const span = Math.max(relativeEnd - relativeStart, 0);\n let added = 0;\n for (const part of blobParts) {\n if (added >= span) break;\n const partSize = ArrayBuffer.isView(part) ? part.byteLength : part.size;\n if (relativeStart && partSize <= relativeStart) {\n relativeStart -= partSize;\n relativeEnd -= partSize;\n } else {\n let chunk;\n if (ArrayBuffer.isView(part)) {\n chunk = part.subarray(relativeStart, Math.min(partSize, relativeEnd));\n added += chunk.byteLength;\n } else {\n chunk = part.slice(relativeStart, Math.min(partSize, relativeEnd));\n added += chunk.size;\n }\n relativeEnd -= partSize;\n relativeStart = 0;\n yield chunk;\n }\n }\n }\n var _parts, _type, _size;\n var _Blob = class _Blob {\n /**\n * Returns a new [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) object.\n * The content of the blob consists of the concatenation of the values given in the parameter array.\n *\n * @param blobParts An `Array` strings, or [`ArrayBuffer`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer), [`ArrayBufferView`](https://developer.mozilla.org/en-US/docs/Web/API/ArrayBufferView), [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) objects, or a mix of any of such objects, that will be put inside the [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob).\n * @param options An optional object of type `BlobPropertyBag`.\n */\n constructor(blobParts = [], options = {}) {\n /**\n * An `Array` of [`ArrayBufferView`](https://developer.mozilla.org/en-US/docs/Web/API/ArrayBufferView) or [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) objects, or a mix of any of such objects, that will be put inside the [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob).\n */\n __privateAdd(this, _parts, []);\n /**\n * Returns the [`MIME type`](https://developer.mozilla.org/en-US/docs/Glossary/MIME_type) of the [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) or [`File`](https://developer.mozilla.org/en-US/docs/Web/API/File).\n */\n __privateAdd(this, _type, \"\");\n /**\n * Returns the size of the [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) or [`File`](https://developer.mozilla.org/en-US/docs/Web/API/File) in bytes.\n */\n __privateAdd(this, _size, 0);\n options ??= {};\n if (typeof blobParts !== \"object\" || blobParts === null) throw new TypeError(\"Failed to construct 'Blob': The provided value cannot be converted to a sequence.\");\n if (!isFunction(blobParts[Symbol.iterator])) throw new TypeError(\"Failed to construct 'Blob': The object must have a callable @@iterator property.\");\n if (typeof options !== \"object\" && !isFunction(options)) throw new TypeError(\"Failed to construct 'Blob': parameter 2 cannot convert to dictionary.\");\n const encoder = new TextEncoder();\n for (const raw of blobParts) {\n let part;\n if (ArrayBuffer.isView(raw)) part = new Uint8Array(raw.buffer.slice(raw.byteOffset, raw.byteOffset + raw.byteLength));\n else if (raw instanceof ArrayBuffer) part = new Uint8Array(raw.slice(0));\n else if (raw instanceof _Blob) part = raw;\n else part = encoder.encode(String(raw));\n __privateSet(this, _size, __privateGet(this, _size) + (ArrayBuffer.isView(part) ? part.byteLength : part.size));\n __privateGet(this, _parts).push(part);\n }\n const type = options.type === void 0 ? \"\" : String(options.type);\n __privateSet(this, _type, /^[\\x20-\\x7E]*$/.test(type) ? type : \"\");\n }\n static [Symbol.hasInstance](value) {\n return Boolean(value && typeof value === \"object\" && isFunction(value.constructor) && (isFunction(value.stream) || isFunction(value.arrayBuffer)) && /^(Blob|File)$/.test(value[Symbol.toStringTag]));\n }\n /**\n * Returns the [`MIME type`](https://developer.mozilla.org/en-US/docs/Glossary/MIME_type) of the [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) or [`File`](https://developer.mozilla.org/en-US/docs/Web/API/File).\n */\n get type() {\n return __privateGet(this, _type);\n }\n /**\n * Returns the size of the [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) or [`File`](https://developer.mozilla.org/en-US/docs/Web/API/File) in bytes.\n */\n get size() {\n return __privateGet(this, _size);\n }\n /**\n * Creates and returns a new [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) object which contains data from a subset of the blob on which it's called.\n *\n * @param start An index into the Blob indicating the first byte to include in the new Blob. If you specify a negative value, it's treated as an offset from the end of the Blob toward the beginning. For example, -10 would be the 10th from last byte in the Blob. The default value is 0. If you specify a value for start that is larger than the size of the source Blob, the returned Blob has size 0 and contains no data.\n * @param end An index into the Blob indicating the first byte that will *not* be included in the new Blob (i.e. the byte exactly at this index is not included). If you specify a negative value, it's treated as an offset from the end of the Blob toward the beginning. For example, -10 would be the 10th from last byte in the Blob. The default value is size.\n * @param contentType The content type to assign to the new Blob; this will be the value of its type property. The default value is an empty string.\n */\n slice(start, end, contentType) {\n return new _Blob(sliceBlob(__privateGet(this, _parts), this.size, start, end), { type: contentType });\n }\n /**\n * Returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that resolves with a string containing the contents of the blob, interpreted as UTF-8.\n */\n async text() {\n const decoder = new TextDecoder();\n let result = \"\";\n for await (const chunk of consumeBlobParts(__privateGet(this, _parts))) result += decoder.decode(chunk, { stream: true });\n result += decoder.decode();\n return result;\n }\n /**\n * Returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that resolves with the contents of the blob as binary data contained in an [`ArrayBuffer`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer).\n */\n async arrayBuffer() {\n const view = new Uint8Array(this.size);\n let offset = 0;\n for await (const chunk of consumeBlobParts(__privateGet(this, _parts))) {\n view.set(chunk, offset);\n offset += chunk.length;\n }\n return view.buffer;\n }\n /**\n * Returns a [`ReadableStream`](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream) which upon reading returns the data contained within the [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob).\n */\n stream() {\n const iterator = consumeBlobParts(__privateGet(this, _parts), true);\n return new ReadableStream({\n async pull(controller) {\n const { value, done } = await iterator.next();\n if (done) return queueMicrotask(() => controller.close());\n controller.enqueue(value);\n },\n async cancel() {\n await iterator.return();\n }\n });\n }\n get [Symbol.toStringTag]() {\n return \"Blob\";\n }\n };\n _parts = /* @__PURE__ */ new WeakMap();\n _type = /* @__PURE__ */ new WeakMap();\n _size = /* @__PURE__ */ new WeakMap();\n var Blob = _Blob;\n Object.defineProperties(Blob.prototype, {\n type: { enumerable: true },\n size: { enumerable: true },\n slice: { enumerable: true },\n stream: { enumerable: true },\n text: { enumerable: true },\n arrayBuffer: { enumerable: true }\n });\n var isBlob = (value) => value instanceof Blob;\n var _name, _lastModified;\n var File = class extends Blob {\n /**\n * Creates a new File instance.\n *\n * @param fileBits An `Array` strings, or [`ArrayBuffer`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer), [`ArrayBufferView`](https://developer.mozilla.org/en-US/docs/Web/API/ArrayBufferView), [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) objects, or a mix of any of such objects, that will be put inside the [`File`](https://developer.mozilla.org/en-US/docs/Web/API/File).\n * @param name The name of the file.\n * @param options An options object containing optional attributes for the file.\n */\n constructor(fileBits, name, options = {}) {\n super(fileBits, options);\n /**\n * Returns the name of the file referenced by the File object.\n */\n __privateAdd(this, _name, void 0);\n /**\n * The last modified date of the file as the number of milliseconds since the Unix epoch (January 1, 1970 at midnight). Files without a known last modified date return the current date.\n */\n __privateAdd(this, _lastModified, 0);\n if (arguments.length < 2) throw new TypeError(`Failed to construct 'File': 2 arguments required, but only ${arguments.length} present.`);\n __privateSet(this, _name, String(name));\n const lastModified = options.lastModified === void 0 ? Date.now() : Number(options.lastModified);\n if (!Number.isNaN(lastModified)) __privateSet(this, _lastModified, lastModified);\n }\n static [Symbol.hasInstance](value) {\n return value instanceof Blob && value[Symbol.toStringTag] === \"File\" && typeof value.name === \"string\";\n }\n /**\n * Name of the file referenced by the File object.\n */\n get name() {\n return __privateGet(this, _name);\n }\n /* c8 ignore next 3 */\n get webkitRelativePath() {\n return \"\";\n }\n /**\n * The last modified date of the file as the number of milliseconds since the Unix epoch (January 1, 1970 at midnight). Files without a known last modified date return the current date.\n */\n get lastModified() {\n return __privateGet(this, _lastModified);\n }\n get [Symbol.toStringTag]() {\n return \"File\";\n }\n };\n _name = /* @__PURE__ */ new WeakMap();\n _lastModified = /* @__PURE__ */ new WeakMap();\n var isFile = (value) => value instanceof File;\n var _entries, _setEntry, setEntry_fn;\n var FormData = class {\n constructor() {\n __privateAdd(this, _setEntry);\n /**\n * Stores internal data for every entry\n */\n __privateAdd(this, _entries, /* @__PURE__ */ new Map());\n }\n static [Symbol.hasInstance](value) {\n if (!value) return false;\n const val = value;\n return Boolean(isFunction(val.constructor) && val[Symbol.toStringTag] === \"FormData\" && isFunction(val.append) && isFunction(val.set) && isFunction(val.get) && isFunction(val.getAll) && isFunction(val.has) && isFunction(val.delete) && isFunction(val.entries) && isFunction(val.values) && isFunction(val.keys) && isFunction(val[Symbol.iterator]) && isFunction(val.forEach));\n }\n /**\n * Appends a new value onto an existing key inside a FormData object,\n * or adds the key if it does not already exist.\n *\n * The difference between `set()` and `append()` is that if the specified key already exists, `set()` will overwrite all existing values with the new one, whereas `append()` will append the new value onto the end of the existing set of values.\n *\n * @param name The name of the field whose data is contained in `value`.\n * @param value The field's value. This can be [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob)\n or [`File`](https://developer.mozilla.org/en-US/docs/Web/API/File). If none of these are specified the value is converted to a string.\n * @param fileName The filename reported to the server, when a Blob or File is passed as the second parameter. The default filename for Blob objects is \"blob\". The default filename for File objects is the file's filename.\n */\n append(name, value, fileName) {\n __privateMethod(this, _setEntry, setEntry_fn).call(this, {\n name,\n fileName,\n append: true,\n rawValue: value,\n argsLength: arguments.length\n });\n }\n /**\n * Set a new value for an existing key inside FormData,\n * or add the new field if it does not already exist.\n *\n * @param name The name of the field whose data is contained in `value`.\n * @param value The field's value. This can be [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob)\n or [`File`](https://developer.mozilla.org/en-US/docs/Web/API/File). If none of these are specified the value is converted to a string.\n * @param fileName The filename reported to the server, when a Blob or File is passed as the second parameter. The default filename for Blob objects is \"blob\". The default filename for File objects is the file's filename.\n *\n */\n set(name, value, fileName) {\n __privateMethod(this, _setEntry, setEntry_fn).call(this, {\n name,\n fileName,\n append: false,\n rawValue: value,\n argsLength: arguments.length\n });\n }\n /**\n * Returns the first value associated with a given key from within a `FormData` object.\n * If you expect multiple values and want all of them, use the `getAll()` method instead.\n *\n * @param {string} name A name of the value you want to retrieve.\n *\n * @returns A `FormDataEntryValue` containing the value. If the key doesn't exist, the method returns null.\n */\n get(name) {\n const field = __privateGet(this, _entries).get(String(name));\n if (!field) return null;\n return field[0];\n }\n /**\n * Returns all the values associated with a given key from within a `FormData` object.\n *\n * @param {string} name A name of the value you want to retrieve.\n *\n * @returns An array of `FormDataEntryValue` whose key matches the value passed in the `name` parameter. If the key doesn't exist, the method returns an empty list.\n */\n getAll(name) {\n const field = __privateGet(this, _entries).get(String(name));\n if (!field) return [];\n return field.slice();\n }\n /**\n * Returns a boolean stating whether a `FormData` object contains a certain key.\n *\n * @param name A string representing the name of the key you want to test for.\n *\n * @return A boolean value.\n */\n has(name) {\n return __privateGet(this, _entries).has(String(name));\n }\n /**\n * Deletes a key and its value(s) from a `FormData` object.\n *\n * @param name The name of the key you want to delete.\n */\n delete(name) {\n __privateGet(this, _entries).delete(String(name));\n }\n /**\n * Returns an [`iterator`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols) allowing to go through all keys contained in this `FormData` object.\n * Each key is a `string`.\n */\n *keys() {\n for (const key of __privateGet(this, _entries).keys()) yield key;\n }\n /**\n * Returns an [`iterator`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols) allowing to go through the `FormData` key/value pairs.\n * The key of each pair is a string; the value is a [`FormDataValue`](https://developer.mozilla.org/en-US/docs/Web/API/FormDataEntryValue).\n */\n *entries() {\n for (const name of this.keys()) {\n const values = this.getAll(name);\n for (const value of values) yield [name, value];\n }\n }\n /**\n * Returns an [`iterator`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols) allowing to go through all values contained in this object `FormData` object.\n * Each value is a [`FormDataValue`](https://developer.mozilla.org/en-US/docs/Web/API/FormDataEntryValue).\n */\n *values() {\n for (const [, value] of this) yield value;\n }\n /**\n * An alias for FormData#entries()\n */\n [Symbol.iterator]() {\n return this.entries();\n }\n /**\n * Executes given callback function for each field of the FormData instance\n */\n forEach(callback, thisArg) {\n for (const [name, value] of this) callback.call(thisArg, value, name, this);\n }\n get [Symbol.toStringTag]() {\n return \"FormData\";\n }\n };\n _entries = /* @__PURE__ */ new WeakMap();\n _setEntry = /* @__PURE__ */ new WeakSet();\n setEntry_fn = function({ name, rawValue, append, fileName, argsLength }) {\n const methodName = append ? \"append\" : \"set\";\n if (argsLength < 2) throw new TypeError(`Failed to execute '${methodName}' on 'FormData': 2 arguments required, but only ${argsLength} present.`);\n name = String(name);\n let value;\n if (isFile(rawValue)) value = fileName === void 0 ? rawValue : new File([rawValue], fileName, {\n type: rawValue.type,\n lastModified: rawValue.lastModified\n });\n else if (isBlob(rawValue)) value = new File([rawValue], fileName === void 0 ? \"blob\" : fileName, { type: rawValue.type });\n else if (fileName) throw new TypeError(`Failed to execute '${methodName}' on 'FormData': parameter 2 is not of type 'Blob'.`);\n else value = String(rawValue);\n const values = __privateGet(this, _entries).get(name);\n if (!values) {\n __privateGet(this, _entries).set(name, [value]);\n return;\n }\n if (!append) {\n __privateGet(this, _entries).set(name, [value]);\n return;\n }\n values.push(value);\n };\n /*! Based on fetch-blob. MIT License. Jimmy Wärting <https://jimmy.warting.se/opensource> & David Frank */\n //#endregion\n //#region node_modules/.pnpm/set-cookie-parser@3.1.0/node_modules/set-cookie-parser/lib/set-cookie.js\n var defaultParseOptions = {\n decodeValues: true,\n map: false,\n silent: false,\n split: \"auto\"\n };\n function isForbiddenKey(key) {\n return typeof key !== \"string\" || key in {};\n }\n function createNullObj() {\n return Object.create(null);\n }\n function isNonEmptyString(str) {\n return typeof str === \"string\" && !!str.trim();\n }\n function parseString(setCookieValue, options) {\n var parts = setCookieValue.split(\";\").filter(isNonEmptyString);\n var parsed = parseNameValuePair(parts.shift());\n var name = parsed.name;\n var value = parsed.value;\n options = options ? Object.assign({}, defaultParseOptions, options) : defaultParseOptions;\n if (isForbiddenKey(name)) return null;\n try {\n value = options.decodeValues ? decodeURIComponent(value) : value;\n } catch (e) {\n console.error(\"set-cookie-parser: failed to decode cookie value. Set options.decodeValues=false to disable decoding.\", e);\n }\n var cookie = createNullObj();\n cookie.name = name;\n cookie.value = value;\n parts.forEach(function(part) {\n var sides = part.split(\"=\");\n var key = sides.shift().trimLeft().toLowerCase();\n if (isForbiddenKey(key)) return;\n var value = sides.join(\"=\");\n if (key === \"expires\") cookie.expires = new Date(value);\n else if (key === \"max-age\") {\n var n = parseInt(value, 10);\n if (!Number.isNaN(n)) cookie.maxAge = n;\n } else if (key === \"secure\") cookie.secure = true;\n else if (key === \"httponly\") cookie.httpOnly = true;\n else if (key === \"samesite\") cookie.sameSite = value;\n else if (key === \"partitioned\") cookie.partitioned = true;\n else if (key) cookie[key] = value;\n });\n return cookie;\n }\n function parseNameValuePair(nameValuePairStr) {\n var name = \"\";\n var value = \"\";\n var nameValueArr = nameValuePairStr.split(\"=\");\n if (nameValueArr.length > 1) {\n name = nameValueArr.shift();\n value = nameValueArr.join(\"=\");\n } else value = nameValuePairStr;\n return {\n name,\n value\n };\n }\n function parseSetCookie(input, options) {\n options = options ? Object.assign({}, defaultParseOptions, options) : defaultParseOptions;\n if (!input) if (!options.map) return [];\n else return createNullObj();\n if (input.headers) if (typeof input.headers.getSetCookie === \"function\") input = input.headers.getSetCookie();\n else if (input.headers[\"set-cookie\"]) input = input.headers[\"set-cookie\"];\n else {\n var sch = input.headers[Object.keys(input.headers).find(function(key) {\n return key.toLowerCase() === \"set-cookie\";\n })];\n if (!sch && input.headers.cookie && !options.silent) console.warn(\"Warning: set-cookie-parser appears to have been called on a request object. It is designed to parse Set-Cookie headers from responses, not Cookie headers from requests. Set the option {silent: true} to suppress this warning.\");\n input = sch;\n }\n var split = options.split;\n var isArray = Array.isArray(input);\n if (split === \"auto\") split = !isArray;\n if (!isArray) input = [input];\n input = input.filter(isNonEmptyString);\n if (split) input = input.map(splitCookiesString).flat();\n if (!options.map) return input.map(function(str) {\n return parseString(str, options);\n }).filter(Boolean);\n else {\n var cookies = createNullObj();\n return input.reduce(function(cookies, str) {\n var cookie = parseString(str, options);\n if (cookie && !isForbiddenKey(cookie.name)) cookies[cookie.name] = cookie;\n return cookies;\n }, cookies);\n }\n }\n function splitCookiesString(cookiesString) {\n if (Array.isArray(cookiesString)) return cookiesString;\n if (typeof cookiesString !== \"string\") return [];\n var cookiesStrings = [];\n var pos = 0;\n var start;\n var ch;\n var lastComma;\n var nextStart;\n var cookiesSeparatorFound;\n function skipWhitespace() {\n while (pos < cookiesString.length && /\\s/.test(cookiesString.charAt(pos))) pos += 1;\n return pos < cookiesString.length;\n }\n function notSpecialChar() {\n ch = cookiesString.charAt(pos);\n return ch !== \"=\" && ch !== \";\" && ch !== \",\";\n }\n while (pos < cookiesString.length) {\n start = pos;\n cookiesSeparatorFound = false;\n while (skipWhitespace()) {\n ch = cookiesString.charAt(pos);\n if (ch === \",\") {\n lastComma = pos;\n pos += 1;\n skipWhitespace();\n nextStart = pos;\n while (pos < cookiesString.length && notSpecialChar()) pos += 1;\n if (pos < cookiesString.length && cookiesString.charAt(pos) === \"=\") {\n cookiesSeparatorFound = true;\n pos = nextStart;\n cookiesStrings.push(cookiesString.substring(start, lastComma));\n start = pos;\n } else pos = lastComma + 1;\n } else pos += 1;\n }\n if (!cookiesSeparatorFound || pos >= cookiesString.length) cookiesStrings.push(cookiesString.substring(start, cookiesString.length));\n }\n return cookiesStrings;\n }\n parseSetCookie.parseSetCookie = parseSetCookie;\n parseSetCookie.parse = parseSetCookie;\n parseSetCookie.parseString = parseString;\n parseSetCookie.splitCookiesString = splitCookiesString;\n //#endregion\n //#region node_modules/.pnpm/headers-polyfill@5.0.1/node_modules/headers-polyfill/lib/index.mjs\n const HEADERS_INVALID_CHARACTERS = /[^a-z0-9\\-#$%&'*+.^_`|~]/i;\n function normalizeHeaderName(name) {\n if (HEADERS_INVALID_CHARACTERS.test(name) || name.trim() === \"\") throw new TypeError(\"Invalid character in header field name\");\n return name.trim().toLowerCase();\n }\n const charCodesToRemove = [\n String.fromCharCode(10),\n String.fromCharCode(13),\n String.fromCharCode(9),\n String.fromCharCode(32)\n ];\n const HEADER_VALUE_REMOVE_REGEXP = new RegExp(`(^[${charCodesToRemove.join(\"\")}]|$[${charCodesToRemove.join(\"\")}])`, \"g\");\n /**\n * Normalize the given header value.\n * @see https://fetch.spec.whatwg.org/#concept-header-value-normalize\n */\n function normalizeHeaderValue(value) {\n return value.replace(HEADER_VALUE_REMOVE_REGEXP, \"\");\n }\n /**\n * Validate the given header name.\n * @see https://fetch.spec.whatwg.org/#header-name\n */\n function isValidHeaderName(value) {\n if (typeof value !== \"string\") return false;\n if (value.length === 0) return false;\n for (let i = 0; i < value.length; i++) {\n const character = value.charCodeAt(i);\n if (character > 127 || !isToken(character)) return false;\n }\n return true;\n }\n function isToken(value) {\n return ![\n 127,\n 32,\n \"(\",\n \")\",\n \"<\",\n \">\",\n \"@\",\n \",\",\n \";\",\n \":\",\n \"\\\\\",\n \"\\\"\",\n \"/\",\n \"[\",\n \"]\",\n \"?\",\n \"=\",\n \"{\",\n \"}\"\n ].includes(value);\n }\n /**\n * Validate the given header value.\n * @see https://fetch.spec.whatwg.org/#header-value\n */\n function isValidHeaderValue(value) {\n if (typeof value !== \"string\") return false;\n if (value.trim() !== value) return false;\n for (let i = 0; i < value.length; i++) {\n const character = value.charCodeAt(i);\n if (character === 0 || character === 10 || character === 13) return false;\n }\n return true;\n }\n let _Symbol$toStringTag;\n const NORMALIZED_HEADERS = Symbol(\"normalizedHeaders\");\n const RAW_HEADER_NAMES = Symbol(\"rawHeaderNames\");\n const HEADER_VALUE_DELIMITER = \", \";\n var Headers = class Headers {\n constructor(init) {\n this[NORMALIZED_HEADERS] = {};\n this[RAW_HEADER_NAMES] = /* @__PURE__ */ new Map();\n this[_Symbol$toStringTag] = \"Headers\";\n /**\n * @note Cannot necessarily check if the `init` is an instance of the\n * `Headers` because that class may not be defined in Node or jsdom.\n */\n if ([\"Headers\", \"HeadersPolyfill\"].includes(init?.constructor?.name) || init instanceof Headers || typeof globalThis.Headers !== \"undefined\" && init instanceof globalThis.Headers) init.forEach((value, name) => {\n this.append(name, value);\n }, this);\n else if (Array.isArray(init)) init.forEach(([name, value]) => {\n this.append(name, Array.isArray(value) ? value.join(HEADER_VALUE_DELIMITER) : value);\n });\n else if (init) Object.getOwnPropertyNames(init).forEach((name) => {\n const value = init[name];\n this.append(name, Array.isArray(value) ? value.join(HEADER_VALUE_DELIMITER) : value);\n });\n }\n [(_Symbol$toStringTag = Symbol.toStringTag, Symbol.iterator)]() {\n return this.entries();\n }\n *keys() {\n for (const [name] of this.entries()) yield name;\n }\n *values() {\n for (const [, value] of this.entries()) yield value;\n }\n *entries() {\n let sortedKeys = Object.keys(this[NORMALIZED_HEADERS]).sort((a, b) => a.localeCompare(b));\n for (const name of sortedKeys) if (name === \"set-cookie\") for (const value of this.getSetCookie()) yield [name, value];\n else yield [name, this.get(name)];\n }\n /**\n * Returns a boolean stating whether a `Headers` object contains a certain header.\n */\n has(name) {\n if (!isValidHeaderName(name)) throw new TypeError(`Invalid header name \"${name}\"`);\n return this[NORMALIZED_HEADERS].hasOwnProperty(normalizeHeaderName(name));\n }\n /**\n * Returns a `ByteString` sequence of all the values of a header with a given name.\n */\n get(name) {\n if (!isValidHeaderName(name)) throw TypeError(`Invalid header name \"${name}\"`);\n return this[NORMALIZED_HEADERS][normalizeHeaderName(name)] ?? null;\n }\n /**\n * Sets a new value for an existing header inside a `Headers` object, or adds the header if it does not already exist.\n */\n set(name, value) {\n if (!isValidHeaderName(name) || !isValidHeaderValue(value)) return;\n const normalizedName = normalizeHeaderName(name);\n const normalizedValue = normalizeHeaderValue(value);\n this[NORMALIZED_HEADERS][normalizedName] = normalizeHeaderValue(normalizedValue);\n this[RAW_HEADER_NAMES].set(normalizedName, name);\n }\n /**\n * Appends a new value onto an existing header inside a `Headers` object, or adds the header if it does not already exist.\n */\n append(name, value) {\n if (!isValidHeaderName(name) || !isValidHeaderValue(value)) return;\n const normalizedName = normalizeHeaderName(name);\n const normalizedValue = normalizeHeaderValue(value);\n let resolvedValue = this.has(normalizedName) ? `${this.get(normalizedName)}, ${normalizedValue}` : normalizedValue;\n this.set(name, resolvedValue);\n }\n /**\n * Deletes a header from the `Headers` object.\n */\n delete(name) {\n if (!isValidHeaderName(name)) return;\n if (!this.has(name)) return;\n const normalizedName = normalizeHeaderName(name);\n delete this[NORMALIZED_HEADERS][normalizedName];\n this[RAW_HEADER_NAMES].delete(normalizedName);\n }\n /**\n * Traverses the `Headers` object,\n * calling the given callback for each header.\n */\n forEach(callback, thisArg) {\n for (const [name, value] of this.entries()) callback.call(thisArg, value, name, this);\n }\n /**\n * Returns an array containing the values\n * of all Set-Cookie headers associated\n * with a response\n */\n getSetCookie() {\n const setCookieHeader = this.get(\"set-cookie\");\n if (setCookieHeader === null) return [];\n if (setCookieHeader === \"\") return [\"\"];\n return splitCookiesString(setCookieHeader);\n }\n };\n //#endregion\n //#region packages/core/src/code-mode/platform-entry.ts\n const platformBridgeGlobalThis = globalThis;\n const capletsPlatformHost = {\n randomUUID: platformBridgeGlobalThis.__caplets_platform_random_uuid,\n randomValues: platformBridgeGlobalThis.__caplets_platform_random_values,\n sleep: platformBridgeGlobalThis.__caplets_platform_sleep,\n clearTimer: platformBridgeGlobalThis.__caplets_platform_clear_timer\n };\n delete platformBridgeGlobalThis.__caplets_platform_random_uuid;\n delete platformBridgeGlobalThis.__caplets_platform_random_values;\n delete platformBridgeGlobalThis.__caplets_platform_sleep;\n delete platformBridgeGlobalThis.__caplets_platform_clear_timer;\n const DISABLED_FETCH_MESSAGE = \"Direct fetch is not available in Code Mode; use a Caplet instead.\";\n const BASE64_ALPHABET = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\n const base64Lookup = new Map(BASE64_ALPHABET.split(\"\").map((char, index) => [char, index]));\n function utf8Encode(input) {\n const encoded = encodeURIComponent(input);\n const bytes = [];\n for (let index = 0; index < encoded.length; index += 1) {\n if (encoded[index] === \"%\") {\n bytes.push(Number.parseInt(encoded.slice(index + 1, index + 3), 16));\n index += 2;\n continue;\n }\n bytes.push(encoded.charCodeAt(index));\n }\n return Uint8Array.from(bytes);\n }\n function utf8Decode(input) {\n let output = \"\";\n for (let index = 0; index < input.length; index += 1) {\n const first = input[index] ?? 0;\n if (first < 128) {\n output += String.fromCharCode(first);\n continue;\n }\n if (first >= 194 && first <= 223) {\n const second = input[index + 1];\n if (isUtf8Continuation(second)) {\n output += String.fromCodePoint((first & 31) << 6 | second & 63);\n index += 1;\n continue;\n }\n output += \"�\";\n continue;\n }\n if (first >= 224 && first <= 239) {\n const second = input[index + 1];\n const third = input[index + 2];\n if (isValidUtf8SecondForThreeByte(first, second) && isUtf8Continuation(third)) {\n output += String.fromCodePoint((first & 15) << 12 | (second & 63) << 6 | third & 63);\n index += 2;\n continue;\n }\n output += \"�\";\n if (isValidUtf8SecondForThreeByte(first, second)) index += 1;\n continue;\n }\n if (first >= 240 && first <= 244) {\n const second = input[index + 1];\n const third = input[index + 2];\n const fourth = input[index + 3];\n if (isValidUtf8SecondForFourByte(first, second) && isUtf8Continuation(third) && isUtf8Continuation(fourth)) {\n output += String.fromCodePoint((first & 7) << 18 | (second & 63) << 12 | (third & 63) << 6 | fourth & 63);\n index += 3;\n continue;\n }\n output += \"�\";\n if (isValidUtf8SecondForFourByte(first, second)) index += isUtf8Continuation(third) ? 2 : 1;\n continue;\n }\n output += \"�\";\n }\n return output;\n }\n function isUtf8Continuation(value) {\n return value !== void 0 && value >= 128 && value <= 191;\n }\n function isValidUtf8SecondForThreeByte(first, second) {\n if (second === void 0) return false;\n if (first === 224) return second >= 160 && second <= 191;\n if (first === 237) return second >= 128 && second <= 159;\n return second >= 128 && second <= 191;\n }\n function isValidUtf8SecondForFourByte(first, second) {\n if (second === void 0) return false;\n if (first === 240) return second >= 144 && second <= 191;\n if (first === 244) return second >= 128 && second <= 143;\n return second >= 128 && second <= 191;\n }\n var TextEncoderShim = class {\n encoding = \"utf-8\";\n encode(input = \"\") {\n return utf8Encode(String(input));\n }\n };\n var TextDecoderShim = class {\n encoding;\n constructor(label = \"utf-8\") {\n const normalized = label.toLowerCase();\n if (![\n \"utf-8\",\n \"utf8\",\n \"unicode-1-1-utf-8\"\n ].includes(normalized)) throw new TypeError(`Unsupported encoding: ${label}`);\n this.encoding = \"utf-8\";\n }\n decode(input) {\n if (input === void 0) return \"\";\n return utf8Decode(copyBytes(input));\n }\n };\n const textEncoder = new TextEncoderShim();\n const textDecoder = new TextDecoderShim();\n var URLSearchParamsShim = class URLSearchParamsShim {\n #entries = [];\n #onChange;\n constructor(init = \"\", onChange) {\n this.#onChange = onChange;\n if (typeof init === \"string\") {\n const source = init.startsWith(\"?\") ? init.slice(1) : init;\n if (!source) return;\n for (const pair of source.split(\"&\")) {\n if (!pair) continue;\n const separatorIndex = pair.indexOf(\"=\");\n const key = separatorIndex >= 0 ? pair.slice(0, separatorIndex) : pair;\n const value = separatorIndex >= 0 ? pair.slice(separatorIndex + 1) : \"\";\n this.#entries.push([decodeUrlParam(key), decodeUrlParam(value)]);\n }\n return;\n }\n if (init instanceof URLSearchParamsShim) {\n this.#entries = [...init.#entries];\n return;\n }\n if (Array.isArray(init)) {\n this.#entries = init.map(([key, value]) => [String(key), String(value)]);\n return;\n }\n this.#entries = Object.entries(init).map(([key, value]) => [key, String(value)]);\n }\n append(name, value) {\n this.#entries.push([String(name), String(value)]);\n this.#onChange?.();\n }\n delete(name) {\n const normalized = String(name);\n this.#entries = this.#entries.filter(([key]) => key !== normalized);\n this.#onChange?.();\n }\n entries() {\n return this.#entries[Symbol.iterator]();\n }\n forEach(callback) {\n for (const [key, value] of this.#entries) callback(value, key, this);\n }\n get(name) {\n return this.#entries.find(([key]) => key === String(name))?.[1] ?? null;\n }\n getAll(name) {\n return this.#entries.filter(([key]) => key === String(name)).map(([, value]) => value);\n }\n has(name) {\n return this.#entries.some(([key]) => key === String(name));\n }\n keys() {\n return this.#entries.map(([key]) => key)[Symbol.iterator]();\n }\n set(name, value) {\n const normalizedName = String(name);\n const normalizedValue = String(value);\n const next = [];\n let replaced = false;\n for (const entry of this.#entries) {\n if (entry[0] !== normalizedName) {\n next.push(entry);\n continue;\n }\n if (!replaced) {\n next.push([normalizedName, normalizedValue]);\n replaced = true;\n }\n }\n if (!replaced) next.push([normalizedName, normalizedValue]);\n this.#entries = next;\n this.#onChange?.();\n }\n toString() {\n return this.#entries.map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`).join(\"&\");\n }\n values() {\n return this.#entries.map(([, value]) => value)[Symbol.iterator]();\n }\n [Symbol.iterator]() {\n return this.entries();\n }\n };\n function decodeUrlParam(value) {\n return decodeURIComponent(value.replace(/\\+/gu, \" \"));\n }\n function parseAbsoluteUrl(input) {\n const match = /^(?<protocol>[a-zA-Z][a-zA-Z\\d+.-]*:)\\/\\/(?<host>[^/?#]*)(?<pathname>[^?#]*)?(?<search>\\?[^#]*)?(?<hash>#.*)?$/u.exec(input);\n if (!match?.groups?.protocol || !match.groups.host) return;\n return {\n protocol: match.groups.protocol,\n host: match.groups.host,\n pathname: match.groups.pathname || \"/\",\n search: match.groups.search || \"\",\n hash: match.groups.hash || \"\"\n };\n }\n function normalizePathname(pathname) {\n const segments = [];\n for (const part of pathname.split(\"/\")) {\n if (!part || part === \".\") continue;\n if (part === \"..\") {\n segments.pop();\n continue;\n }\n segments.push(part);\n }\n return `/${segments.join(\"/\")}`;\n }\n function resolveUrl(input, base) {\n const absolute = parseAbsoluteUrl(input);\n if (absolute) return absolute;\n if (base === void 0) throw new TypeError(`Invalid URL: ${input}`);\n const baseUrl = base instanceof URLShim ? base : new URLShim(String(base));\n const basePath = baseUrl.pathname.endsWith(\"/\") ? baseUrl.pathname : baseUrl.pathname.slice(0, baseUrl.pathname.lastIndexOf(\"/\") + 1);\n const [beforeHash, rawHash = \"\"] = input.split(\"#\");\n const hasExplicitSearch = beforeHash?.includes(\"?\") ?? false;\n const [rawPath, rawSearch = \"\"] = (beforeHash ?? \"\").split(\"?\");\n const pathname = rawPath === \"\" && (input === \"\" || input.startsWith(\"?\") || input.startsWith(\"#\")) ? baseUrl.pathname : rawPath?.startsWith(\"/\") ? rawPath : `${basePath}${rawPath || \"\"}`;\n return {\n protocol: baseUrl.protocol,\n host: baseUrl.host,\n pathname: normalizePathname(pathname),\n search: hasExplicitSearch ? `?${rawSearch}` : rawPath === \"\" && (input === \"\" || input.startsWith(\"#\")) ? baseUrl.search : \"\",\n hash: rawHash ? `#${rawHash}` : \"\"\n };\n }\n var URLShim = class {\n host;\n hostname;\n origin;\n password = \"\";\n port;\n protocol;\n searchParams;\n username = \"\";\n hash;\n pathname;\n #search;\n constructor(input, base) {\n const parsed = resolveUrl(String(input), base);\n this.protocol = parsed.protocol;\n this.host = parsed.host;\n const portIndex = this.host.lastIndexOf(\":\");\n this.hostname = portIndex >= 0 ? this.host.slice(0, portIndex) : this.host;\n this.port = portIndex >= 0 ? this.host.slice(portIndex + 1) : \"\";\n this.pathname = parsed.pathname;\n this.#search = parsed.search;\n this.hash = parsed.hash;\n this.origin = `${this.protocol}//${this.host}`;\n this.searchParams = new URLSearchParamsShim(this.#search, () => {\n const next = this.searchParams.toString();\n this.#search = next ? `?${next}` : \"\";\n });\n }\n get href() {\n return `${this.origin}${this.pathname}${this.#search}${this.hash}`;\n }\n get search() {\n return this.#search;\n }\n toString() {\n return this.href;\n }\n toJSON() {\n return this.href;\n }\n };\n var ReadableStreamShim = class {\n #queue = [];\n #closed = false;\n #pulling = false;\n #source;\n #controller;\n #pending;\n constructor(source = {}) {\n this.#source = source;\n this.#controller = {\n enqueue: (value) => {\n if (this.#pending) {\n this.#pending.resolve({\n done: false,\n value\n });\n this.#pending = void 0;\n return;\n }\n this.#queue.push(value);\n },\n close: () => {\n this.#closed = true;\n if (this.#pending) {\n this.#pending.resolve({ done: true });\n this.#pending = void 0;\n }\n }\n };\n source.start?.(this.#controller);\n }\n async #pull() {\n if (this.#pulling || this.#closed || !this.#source.pull) return;\n this.#pulling = true;\n try {\n await this.#source.pull(this.#controller);\n } finally {\n this.#pulling = false;\n }\n }\n getReader() {\n return { read: async () => {\n if (this.#queue.length > 0) return {\n done: false,\n value: this.#queue.shift()\n };\n await this.#pull();\n if (this.#queue.length > 0) return {\n done: false,\n value: this.#queue.shift()\n };\n if (this.#closed) return {\n done: true,\n value: void 0\n };\n return await new Promise((resolve) => {\n this.#pending = { resolve };\n this.#pull();\n });\n } };\n }\n };\n var WritableStreamShim = class {\n #sink;\n constructor(sink = {}) {\n this.#sink = sink;\n }\n getWriter() {\n return {\n write: async (chunk) => {\n await this.#sink.write?.(chunk);\n },\n close: async () => {\n await this.#sink.close?.();\n }\n };\n }\n };\n var TransformStreamShim = class {\n readable;\n writable;\n constructor(transformer = {}) {\n const queue = [];\n let closed = false;\n let pending;\n const controller = {\n enqueue: (value) => {\n if (pending) {\n pending.resolve({\n done: false,\n value\n });\n pending = void 0;\n return;\n }\n queue.push(value);\n },\n close: () => {\n closed = true;\n if (pending) {\n pending.resolve({ done: true });\n pending = void 0;\n }\n }\n };\n this.readable = { getReader() {\n return { read: async () => {\n if (queue.length > 0) return {\n done: false,\n value: queue.shift()\n };\n if (closed) return {\n done: true,\n value: void 0\n };\n return await new Promise((resolve) => {\n pending = { resolve };\n });\n } };\n } };\n this.writable = new WritableStreamShim({\n write: async (chunk) => {\n transformer.transform?.(chunk, controller);\n },\n close: async () => {\n transformer.flush?.(controller);\n controller.close();\n }\n });\n }\n };\n function definePlatformGlobal(name, value, options = {}) {\n if (!options.overwrite && name in globalThis) return;\n Object.defineProperty(globalThis, name, {\n value,\n writable: true,\n configurable: true\n });\n }\n function formatLogArg(value) {\n if (typeof value === \"string\") return value;\n try {\n return JSON.stringify(value);\n } catch {\n return String(value);\n }\n }\n function formatLogLine(args) {\n return args.map(formatLogArg).join(\" \");\n }\n const platformConsole = {\n log: (...args) => __caplets_log(\"log\", formatLogLine(args)),\n info: (...args) => __caplets_log(\"info\", formatLogLine(args)),\n warn: (...args) => __caplets_log(\"warn\", formatLogLine(args)),\n error: (...args) => __caplets_log(\"error\", formatLogLine(args)),\n debug: (...args) => __caplets_log(\"debug\", formatLogLine(args))\n };\n function normalizeEncoding(encoding) {\n const normalized = (encoding ?? \"utf8\").toLowerCase();\n switch (normalized) {\n case \"utf8\":\n case \"utf-8\":\n case \"base64\":\n case \"base64url\":\n case \"hex\": return normalized;\n default: throw new TypeError(`Unsupported Buffer encoding: ${encoding}`);\n }\n }\n function hexToBytes(value) {\n if (value.length % 2 !== 0) throw new TypeError(\"Invalid hex string length\");\n const bytes = new Uint8Array(value.length / 2);\n for (let index = 0; index < value.length; index += 2) {\n const parsed = Number.parseInt(value.slice(index, index + 2), 16);\n if (Number.isNaN(parsed)) throw new TypeError(\"Invalid hex string\");\n bytes[index / 2] = parsed;\n }\n return bytes;\n }\n function bytesToHex(bytes) {\n return Array.from(bytes, (value) => value.toString(16).padStart(2, \"0\")).join(\"\");\n }\n function base64ToBytes(value, encoding) {\n let normalized = value.replace(/\\s+/gu, \"\");\n if (encoding === \"base64url\") normalized = normalized.replace(/-/gu, \"+\").replace(/_/gu, \"/\");\n const padding = normalized.length % 4;\n if (padding === 1) throw new TypeError(\"Invalid base64 string\");\n if (padding > 0) normalized = normalized.padEnd(normalized.length + (4 - padding), \"=\");\n const output = [];\n for (let index = 0; index < normalized.length; index += 4) {\n const values = normalized.slice(index, index + 4).split(\"\").map((char) => char === \"=\" ? 64 : base64Lookup.get(char) ?? NaN);\n if (values.some((entry) => Number.isNaN(entry))) throw new TypeError(\"Invalid base64 string\");\n const [a = 0, b = 0, c = 64, d = 64] = values;\n const triple = a << 18 | b << 12 | (c & 63) << 6 | d & 63;\n output.push(triple >> 16 & 255);\n if (c !== 64) output.push(triple >> 8 & 255);\n if (d !== 64) output.push(triple & 255);\n }\n return Uint8Array.from(output);\n }\n function bytesToBase64(bytes, encoding) {\n let output = \"\";\n for (let index = 0; index < bytes.length; index += 3) {\n const a = bytes[index] ?? 0;\n const b = bytes[index + 1] ?? 0;\n const c = bytes[index + 2] ?? 0;\n const triple = a << 16 | b << 8 | c;\n output += BASE64_ALPHABET[triple >> 18 & 63];\n output += BASE64_ALPHABET[triple >> 12 & 63];\n output += index + 1 < bytes.length ? BASE64_ALPHABET[triple >> 6 & 63] : \"=\";\n output += index + 2 < bytes.length ? BASE64_ALPHABET[triple & 63] : \"=\";\n }\n if (encoding === \"base64url\") return output.replace(/\\+/gu, \"-\").replace(/\\//gu, \"_\").replace(/=+$/gu, \"\");\n return output;\n }\n function copyBytes(input) {\n if (input instanceof ArrayBuffer) return new Uint8Array(input.slice(0));\n return new Uint8Array(input.buffer.slice(input.byteOffset, input.byteOffset + input.byteLength));\n }\n function toBytes(input, encoding) {\n if (input instanceof BufferShim) return input.toUint8Array();\n if (typeof input === \"string\") switch (normalizeEncoding(encoding)) {\n case \"utf8\":\n case \"utf-8\": return textEncoder.encode(input);\n case \"base64\":\n case \"base64url\": return base64ToBytes(input, normalizeEncoding(encoding));\n case \"hex\": return hexToBytes(input);\n }\n if (input instanceof ArrayBuffer || ArrayBuffer.isView(input)) return copyBytes(input);\n if (Array.isArray(input)) return Uint8Array.from(input);\n throw new TypeError(\"Buffer.from only supports strings, arrays, ArrayBuffers, and typed arrays\");\n }\n var BufferShim = class BufferShim {\n #bytes;\n byteLength;\n length;\n constructor(bytes) {\n this.#bytes = bytes;\n this.byteLength = bytes.byteLength;\n this.length = bytes.length;\n }\n static from(input, encoding) {\n return new BufferShim(toBytes(input, encoding));\n }\n static isBuffer(value) {\n return value instanceof BufferShim;\n }\n static byteLength(input, encoding) {\n return toBytes(input, encoding).byteLength;\n }\n toUint8Array() {\n return new Uint8Array(this.#bytes);\n }\n toString(encoding) {\n switch (normalizeEncoding(encoding)) {\n case \"utf8\":\n case \"utf-8\": return textDecoder.decode(this.#bytes);\n case \"base64\":\n case \"base64url\": return bytesToBase64(this.#bytes, normalizeEncoding(encoding));\n case \"hex\": return bytesToHex(this.#bytes);\n }\n }\n };\n function atobShim(input) {\n return Array.from(base64ToBytes(String(input), \"base64\"), (value) => String.fromCharCode(value)).join(\"\");\n }\n function btoaShim(input) {\n const bytes = new Uint8Array(input.length);\n for (let index = 0; index < input.length; index += 1) {\n const codePoint = input.charCodeAt(index);\n if (codePoint > 255) throw new TypeError(\"The string to be encoded contains characters outside of Latin1\");\n bytes[index] = codePoint;\n }\n return bytesToBase64(bytes, \"base64\");\n }\n function queueMicrotaskShim(callback) {\n Promise.resolve().then(callback);\n }\n var AbortSignalShim = class AbortSignalShim {\n aborted = false;\n reason;\n onabort = null;\n #listeners = /* @__PURE__ */ new Set();\n addEventListener(type, listener) {\n if (type === \"abort\" && listener) this.#listeners.add(listener);\n }\n removeEventListener(type, listener) {\n if (type === \"abort\" && listener) this.#listeners.delete(listener);\n }\n dispatchEvent(event) {\n if (event.type !== \"abort\") return true;\n this.onabort?.(event);\n for (const listener of this.#listeners) listener(event);\n return true;\n }\n throwIfAborted() {\n if (this.aborted) throw this.reason ?? /* @__PURE__ */ new Error(\"Operation was aborted\");\n }\n static abort(reason) {\n const signal = new AbortSignalShim();\n signal.abort(reason);\n return signal;\n }\n abort(reason) {\n if (this.aborted) return;\n this.aborted = true;\n this.reason = reason;\n this.dispatchEvent({\n type: \"abort\",\n target: this\n });\n }\n };\n var AbortControllerShim = class {\n signal = new AbortSignalShim();\n abort(reason) {\n this.signal.abort(reason);\n }\n };\n function cloneFormData(input) {\n const clone = new FormData();\n for (const [name, value] of input.entries()) {\n if (value instanceof File) {\n clone.append(name, new File([value], value.name, { type: value.type }), value.name);\n continue;\n }\n clone.append(name, value);\n }\n return clone;\n }\n function cloneBodyValue(input) {\n if (input === null || input === void 0 || typeof input === \"string\") return input;\n if (input instanceof FormData) return cloneFormData(input);\n if (input instanceof Blob) return input.slice(0, input.size, input.type);\n if (input instanceof ArrayBuffer || ArrayBuffer.isView(input)) return copyBytes(input);\n return input;\n }\n function blobFromBody(input) {\n if (input instanceof Blob) return input;\n if (typeof input === \"string\") return new Blob([input], { type: \"text/plain;charset=utf-8\" });\n if (input instanceof FormData) throw new TypeError(\"FormData body reading is not supported in Code Mode\");\n if (input instanceof ArrayBuffer || ArrayBuffer.isView(input)) return new Blob([copyBytes(input)]);\n return new Blob([]);\n }\n var BodyMixin = class {\n _bodyInit;\n bodyUsed = false;\n body = null;\n constructor(body) {\n this._bodyInit = cloneBodyValue(body);\n }\n async arrayBuffer() {\n this.bodyUsed = true;\n return await blobFromBody(this._bodyInit).arrayBuffer();\n }\n async blob() {\n this.bodyUsed = true;\n return blobFromBody(this._bodyInit);\n }\n async formData() {\n this.bodyUsed = true;\n if (this._bodyInit instanceof FormData) return cloneFormData(this._bodyInit);\n throw new TypeError(\"Body does not contain FormData\");\n }\n async json() {\n return JSON.parse(await this.text());\n }\n async text() {\n this.bodyUsed = true;\n return await blobFromBody(this._bodyInit).text();\n }\n };\n function toHeaders(init) {\n return init instanceof Headers ? new Headers(init) : new Headers(init ?? {});\n }\n function normalizeMethod(method) {\n return String(method ?? \"GET\").toUpperCase();\n }\n var RequestShim = class RequestShim extends BodyMixin {\n headers;\n method;\n signal;\n url;\n constructor(input, init = {}) {\n const sourceBody = input instanceof RequestShim ? input._bodyInit : void 0;\n super(init.body ?? sourceBody);\n if (input instanceof RequestShim) this.url = input.url;\n else this.url = input instanceof URLShim ? input.href : new URLShim(String(input)).href;\n this.method = normalizeMethod(init.method ?? (input instanceof RequestShim ? input.method : \"GET\"));\n this.headers = toHeaders(init.headers ?? (input instanceof RequestShim ? input.headers : void 0));\n this.signal = init.signal ?? (input instanceof RequestShim ? input.signal : new AbortControllerShim().signal);\n }\n clone() {\n return new RequestShim(this, {\n method: this.method,\n headers: this.headers,\n body: this._bodyInit,\n signal: this.signal\n });\n }\n };\n var ResponseShim = class ResponseShim extends BodyMixin {\n headers;\n ok;\n redirected = false;\n status;\n statusText;\n type = \"default\";\n url = \"\";\n constructor(body, init = {}) {\n super(body);\n this.status = init.status ?? 200;\n this.statusText = init.statusText ?? \"\";\n this.headers = toHeaders(init.headers);\n this.ok = this.status >= 200 && this.status <= 299;\n }\n clone() {\n return new ResponseShim(this._bodyInit, {\n headers: this.headers,\n status: this.status,\n statusText: this.statusText\n });\n }\n static json(data, init) {\n const headers = toHeaders(init?.headers);\n if (!headers.has(\"content-type\")) headers.set(\"content-type\", \"application/json\");\n const responseInit = { headers };\n if (init?.status !== void 0) responseInit.status = init.status;\n if (init?.statusText !== void 0) responseInit.statusText = init.statusText;\n return new ResponseShim(JSON.stringify(data), responseInit);\n }\n };\n function disabledFetch() {\n throw new Error(DISABLED_FETCH_MESSAGE);\n }\n const integerTypedArrayConstructors = new Set([\n Int8Array,\n Uint8Array,\n Uint8ClampedArray,\n Int16Array,\n Uint16Array,\n Int32Array,\n Uint32Array,\n typeof BigInt64Array === \"undefined\" ? void 0 : BigInt64Array,\n typeof BigUint64Array === \"undefined\" ? void 0 : BigUint64Array\n ]);\n var QuotaExceededErrorShim = class extends Error {\n constructor(message) {\n super(message);\n this.name = \"QuotaExceededError\";\n }\n };\n const platformCrypto = {\n randomUUID() {\n const randomUUID = capletsPlatformHost.randomUUID;\n if (!randomUUID) throw new Error(\"Code Mode platform random UUID bridge is not installed\");\n return randomUUID();\n },\n getRandomValues(typedArray) {\n if (!ArrayBuffer.isView(typedArray) || typedArray instanceof DataView) throw new TypeError(\"crypto.getRandomValues requires an integer typed array\");\n if (!integerTypedArrayConstructors.has(typedArray.constructor)) throw new TypeError(\"crypto.getRandomValues requires an integer typed array\");\n if (typedArray.byteLength > 65536) throw new QuotaExceededErrorShim(\"crypto.getRandomValues cannot generate more than 65,536 bytes\");\n const randomValues = capletsPlatformHost.randomValues;\n if (!randomValues) throw new Error(\"Code Mode platform random values bridge is not installed\");\n const bytes = randomValues(typedArray.byteLength);\n new Uint8Array(typedArray.buffer, typedArray.byteOffset, typedArray.byteLength).set(bytes);\n return typedArray;\n }\n };\n let nextTimerId = 1;\n const activeTimers = /* @__PURE__ */ new Set();\n function normalizeTimerDelay(delay) {\n const value = Number(delay ?? 0);\n if (!Number.isFinite(value) || value <= 0) return 0;\n return Math.trunc(value);\n }\n function setTimeoutShim(callback, delay, ...args) {\n if (typeof callback !== \"function\") throw new TypeError(\"setTimeout callback must be a function\");\n const timerId = nextTimerId++;\n activeTimers.add(timerId);\n const sleep = capletsPlatformHost.sleep;\n if (!sleep) throw new Error(\"Code Mode platform sleep bridge is not installed\");\n sleep(timerId, normalizeTimerDelay(delay)).then((fired) => {\n activeTimers.delete(timerId);\n if (fired) callback(...args);\n });\n return timerId;\n }\n function clearTimeoutShim(timerId) {\n const id = Number(timerId);\n activeTimers.delete(id);\n capletsPlatformHost.clearTimer?.(id);\n }\n function setIntervalShim(callback, delay, ...args) {\n if (typeof callback !== \"function\") throw new TypeError(\"setInterval callback must be a function\");\n const timerId = nextTimerId++;\n const intervalDelay = normalizeTimerDelay(delay);\n activeTimers.add(timerId);\n const tick = () => {\n const sleep = capletsPlatformHost.sleep;\n if (!sleep) throw new Error(\"Code Mode platform sleep bridge is not installed\");\n sleep(timerId, intervalDelay).then((fired) => {\n if (!fired || !activeTimers.has(timerId)) {\n activeTimers.delete(timerId);\n return;\n }\n callback(...args);\n if (activeTimers.has(timerId)) tick();\n });\n };\n tick();\n return timerId;\n }\n function clearIntervalShim(timerId) {\n clearTimeoutShim(timerId);\n }\n definePlatformGlobal(\"atob\", atobShim);\n definePlatformGlobal(\"btoa\", btoaShim);\n definePlatformGlobal(\"Buffer\", BufferShim);\n definePlatformGlobal(\"TextEncoder\", TextEncoderShim);\n definePlatformGlobal(\"TextDecoder\", TextDecoderShim);\n definePlatformGlobal(\"URL\", URLShim);\n definePlatformGlobal(\"URLSearchParams\", URLSearchParamsShim);\n definePlatformGlobal(\"structuredClone\", esm_default);\n definePlatformGlobal(\"Headers\", Headers);\n definePlatformGlobal(\"Blob\", Blob);\n definePlatformGlobal(\"File\", File);\n definePlatformGlobal(\"FormData\", FormData);\n definePlatformGlobal(\"ReadableStream\", ReadableStreamShim);\n definePlatformGlobal(\"WritableStream\", WritableStreamShim);\n definePlatformGlobal(\"TransformStream\", TransformStreamShim);\n definePlatformGlobal(\"AbortController\", AbortControllerShim);\n definePlatformGlobal(\"AbortSignal\", AbortSignalShim);\n definePlatformGlobal(\"Request\", RequestShim);\n definePlatformGlobal(\"Response\", ResponseShim);\n definePlatformGlobal(\"crypto\", platformCrypto);\n definePlatformGlobal(\"setTimeout\", setTimeoutShim);\n definePlatformGlobal(\"clearTimeout\", clearTimeoutShim);\n definePlatformGlobal(\"setInterval\", setIntervalShim);\n definePlatformGlobal(\"clearInterval\", clearIntervalShim);\n definePlatformGlobal(\"queueMicrotask\", queueMicrotaskShim);\n definePlatformGlobal(\"console\", platformConsole);\n definePlatformGlobal(\"fetch\", disabledFetch, { overwrite: true });\n //#endregion\n})();";
|
|
77794
|
+
const CODE_MODE_PLATFORM_RUNTIME_SOURCE = "(function() {\n //#region node_modules/.pnpm/@ungap+structured-clone@1.3.1/node_modules/@ungap/structured-clone/esm/deserialize.js\n const env = typeof self === \"object\" ? self : globalThis;\n const guard = (name, init) => {\n switch (name) {\n case \"Function\":\n case \"SharedWorker\":\n case \"Worker\":\n case \"eval\":\n case \"setInterval\":\n case \"setTimeout\": throw new TypeError(\"unable to deserialize \" + name);\n }\n return new env[name](init);\n };\n const deserializer = ($, _) => {\n const as = (out, index) => {\n $.set(index, out);\n return out;\n };\n const unpair = (index) => {\n if ($.has(index)) return $.get(index);\n const [type, value] = _[index];\n switch (type) {\n case 0:\n case -1: return as(value, index);\n case 1: {\n const arr = as([], index);\n for (const index of value) arr.push(unpair(index));\n return arr;\n }\n case 2: {\n const object = as({}, index);\n for (const [key, index] of value) object[unpair(key)] = unpair(index);\n return object;\n }\n case 3: return as(new Date(value), index);\n case 4: {\n const { source, flags } = value;\n return as(new RegExp(source, flags), index);\n }\n case 5: {\n const map = as(/* @__PURE__ */ new Map(), index);\n for (const [key, index] of value) map.set(unpair(key), unpair(index));\n return map;\n }\n case 6: {\n const set = as(/* @__PURE__ */ new Set(), index);\n for (const index of value) set.add(unpair(index));\n return set;\n }\n case 7: {\n const { name, message } = value;\n return as(guard(name, message), index);\n }\n case 8: return as(BigInt(value), index);\n case \"BigInt\": return as(Object(BigInt(value)), index);\n case \"ArrayBuffer\": return as(new Uint8Array(value).buffer, value);\n case \"DataView\": {\n const { buffer } = new Uint8Array(value);\n return as(new DataView(buffer), value);\n }\n }\n return as(guard(type, value), index);\n };\n return unpair;\n };\n /**\n * @typedef {Array<string,any>} Record a type representation\n */\n /**\n * Returns a deserialized value from a serialized array of Records.\n * @param {Record[]} serialized a previously serialized value.\n * @returns {any}\n */\n const deserialize = (serialized) => deserializer(/* @__PURE__ */ new Map(), serialized)(0);\n //#endregion\n //#region node_modules/.pnpm/@ungap+structured-clone@1.3.1/node_modules/@ungap/structured-clone/esm/serialize.js\n const EMPTY = \"\";\n const { toString } = {};\n const { keys } = Object;\n const typeOf = (value) => {\n const type = typeof value;\n if (type !== \"object\" || !value) return [0, type];\n const asString = toString.call(value).slice(8, -1);\n switch (asString) {\n case \"Array\": return [1, EMPTY];\n case \"Object\": return [2, EMPTY];\n case \"Date\": return [3, EMPTY];\n case \"RegExp\": return [4, EMPTY];\n case \"Map\": return [5, EMPTY];\n case \"Set\": return [6, EMPTY];\n case \"DataView\": return [1, asString];\n }\n if (asString.includes(\"Array\")) return [1, asString];\n if (asString.includes(\"Error\")) return [7, asString];\n return [2, asString];\n };\n const shouldSkip = ([TYPE, type]) => TYPE === 0 && (type === \"function\" || type === \"symbol\");\n const serializer = (strict, json, $, _) => {\n const as = (out, value) => {\n const index = _.push(out) - 1;\n $.set(value, index);\n return index;\n };\n const pair = (value) => {\n if ($.has(value)) return $.get(value);\n let [TYPE, type] = typeOf(value);\n switch (TYPE) {\n case 0: {\n let entry = value;\n switch (type) {\n case \"bigint\":\n TYPE = 8;\n entry = value.toString();\n break;\n case \"function\":\n case \"symbol\":\n if (strict) throw new TypeError(\"unable to serialize \" + type);\n entry = null;\n break;\n case \"undefined\": return as([-1], value);\n }\n return as([TYPE, entry], value);\n }\n case 1: {\n if (type) {\n let spread = value;\n if (type === \"DataView\") spread = new Uint8Array(value.buffer);\n else if (type === \"ArrayBuffer\") spread = new Uint8Array(value);\n return as([type, [...spread]], value);\n }\n const arr = [];\n const index = as([TYPE, arr], value);\n for (const entry of value) arr.push(pair(entry));\n return index;\n }\n case 2: {\n if (type) switch (type) {\n case \"BigInt\": return as([type, value.toString()], value);\n case \"Boolean\":\n case \"Number\":\n case \"String\": return as([type, value.valueOf()], value);\n }\n if (json && \"toJSON\" in value) return pair(value.toJSON());\n const entries = [];\n const index = as([TYPE, entries], value);\n for (const key of keys(value)) if (strict || !shouldSkip(typeOf(value[key]))) entries.push([pair(key), pair(value[key])]);\n return index;\n }\n case 3: return as([TYPE, value.toISOString()], value);\n case 4: {\n const { source, flags } = value;\n return as([TYPE, {\n source,\n flags\n }], value);\n }\n case 5: {\n const entries = [];\n const index = as([TYPE, entries], value);\n for (const [key, entry] of value) if (strict || !(shouldSkip(typeOf(key)) || shouldSkip(typeOf(entry)))) entries.push([pair(key), pair(entry)]);\n return index;\n }\n case 6: {\n const entries = [];\n const index = as([TYPE, entries], value);\n for (const entry of value) if (strict || !shouldSkip(typeOf(entry))) entries.push(pair(entry));\n return index;\n }\n }\n const { message } = value;\n return as([TYPE, {\n name: type,\n message\n }], value);\n };\n return pair;\n };\n /**\n * @typedef {Array<string,any>} Record a type representation\n */\n /**\n * Returns an array of serialized Records.\n * @param {any} value a serializable value.\n * @param {{json?: boolean, lossy?: boolean}?} options an object with a `lossy` or `json` property that,\n * if `true`, will not throw errors on incompatible types, and behave more\n * like JSON stringify would behave. Symbol and Function will be discarded.\n * @returns {Record[]}\n */\n const serialize = (value, { json, lossy } = {}) => {\n const _ = [];\n return serializer(!(json || lossy), !!json, /* @__PURE__ */ new Map(), _)(value), _;\n };\n //#endregion\n //#region node_modules/.pnpm/@ungap+structured-clone@1.3.1/node_modules/@ungap/structured-clone/esm/index.js\n /**\n * @typedef {Array<string,any>} Record a type representation\n */\n /**\n * Returns an array of serialized Records.\n * @param {any} any a serializable value.\n * @param {{transfer?: any[], json?: boolean, lossy?: boolean}?} options an object with\n * a transfer option (ignored when polyfilled) and/or non standard fields that\n * fallback to the polyfill if present.\n * @returns {Record[]}\n */\n var esm_default = typeof structuredClone === \"function\" ? (any, options) => options && (\"json\" in options || \"lossy\" in options) ? deserialize(serialize(any, options)) : structuredClone(any) : (any, options) => deserialize(serialize(any, options));\n //#endregion\n //#region node_modules/.pnpm/formdata-node@6.0.3/node_modules/formdata-node/lib/form-data.js\n var __accessCheck = (obj, member, msg) => {\n if (!member.has(obj)) throw TypeError(\"Cannot \" + msg);\n };\n var __privateGet = (obj, member, getter) => {\n __accessCheck(obj, member, \"read from private field\");\n return getter ? getter.call(obj) : member.get(obj);\n };\n var __privateAdd = (obj, member, value) => {\n if (member.has(obj)) throw TypeError(\"Cannot add the same private member more than once\");\n member instanceof WeakSet ? member.add(obj) : member.set(obj, value);\n };\n var __privateSet = (obj, member, value, setter) => {\n __accessCheck(obj, member, \"write to private field\");\n setter ? setter.call(obj, value) : member.set(obj, value);\n return value;\n };\n var __privateMethod = (obj, member, method) => {\n __accessCheck(obj, member, \"access private method\");\n return method;\n };\n var isFunction = (value) => typeof value === \"function\";\n var isObject = (value) => typeof value === \"object\" && value != null && !Array.isArray(value);\n var isAsyncIterable = (value) => isObject(value) && isFunction(value[Symbol.asyncIterator]);\n var MAX_CHUNK_SIZE = 65536;\n async function* clonePart(value) {\n if (value.byteLength <= MAX_CHUNK_SIZE) {\n yield value;\n return;\n }\n let offset = 0;\n while (offset < value.byteLength) {\n const size = Math.min(value.byteLength - offset, MAX_CHUNK_SIZE);\n const buffer = value.buffer.slice(offset, offset + size);\n offset += buffer.byteLength;\n yield new Uint8Array(buffer);\n }\n }\n async function* readStream(readable) {\n const reader = readable.getReader();\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n yield value;\n }\n }\n async function* chunkStream(stream) {\n for await (const value of stream) yield* clonePart(value);\n }\n var getStreamIterator = (source) => {\n if (isAsyncIterable(source)) return chunkStream(source);\n if (isFunction(source.getReader)) return chunkStream(readStream(source));\n throw new TypeError(\"Unsupported data source: Expected either ReadableStream or async iterable.\");\n };\n async function* consumeNodeBlob(blob) {\n let position = 0;\n while (position !== blob.size) {\n const buffer = await blob.slice(position, Math.min(blob.size, position + MAX_CHUNK_SIZE)).arrayBuffer();\n position += buffer.byteLength;\n yield new Uint8Array(buffer);\n }\n }\n async function* consumeBlobParts(parts, clone = false) {\n for (const part of parts) if (ArrayBuffer.isView(part)) if (clone) yield* clonePart(part);\n else yield part;\n else if (isFunction(part.stream)) yield* getStreamIterator(part.stream());\n else yield* consumeNodeBlob(part);\n }\n function* sliceBlob(blobParts, blobSize, start = 0, end) {\n end ??= blobSize;\n let relativeStart = start < 0 ? Math.max(blobSize + start, 0) : Math.min(start, blobSize);\n let relativeEnd = end < 0 ? Math.max(blobSize + end, 0) : Math.min(end, blobSize);\n const span = Math.max(relativeEnd - relativeStart, 0);\n let added = 0;\n for (const part of blobParts) {\n if (added >= span) break;\n const partSize = ArrayBuffer.isView(part) ? part.byteLength : part.size;\n if (relativeStart && partSize <= relativeStart) {\n relativeStart -= partSize;\n relativeEnd -= partSize;\n } else {\n let chunk;\n if (ArrayBuffer.isView(part)) {\n chunk = part.subarray(relativeStart, Math.min(partSize, relativeEnd));\n added += chunk.byteLength;\n } else {\n chunk = part.slice(relativeStart, Math.min(partSize, relativeEnd));\n added += chunk.size;\n }\n relativeEnd -= partSize;\n relativeStart = 0;\n yield chunk;\n }\n }\n }\n var _parts, _type, _size;\n var _Blob = class _Blob {\n /**\n * Returns a new [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) object.\n * The content of the blob consists of the concatenation of the values given in the parameter array.\n *\n * @param blobParts An `Array` strings, or [`ArrayBuffer`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer), [`ArrayBufferView`](https://developer.mozilla.org/en-US/docs/Web/API/ArrayBufferView), [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) objects, or a mix of any of such objects, that will be put inside the [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob).\n * @param options An optional object of type `BlobPropertyBag`.\n */\n constructor(blobParts = [], options = {}) {\n /**\n * An `Array` of [`ArrayBufferView`](https://developer.mozilla.org/en-US/docs/Web/API/ArrayBufferView) or [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) objects, or a mix of any of such objects, that will be put inside the [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob).\n */\n __privateAdd(this, _parts, []);\n /**\n * Returns the [`MIME type`](https://developer.mozilla.org/en-US/docs/Glossary/MIME_type) of the [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) or [`File`](https://developer.mozilla.org/en-US/docs/Web/API/File).\n */\n __privateAdd(this, _type, \"\");\n /**\n * Returns the size of the [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) or [`File`](https://developer.mozilla.org/en-US/docs/Web/API/File) in bytes.\n */\n __privateAdd(this, _size, 0);\n options ??= {};\n if (typeof blobParts !== \"object\" || blobParts === null) throw new TypeError(\"Failed to construct 'Blob': The provided value cannot be converted to a sequence.\");\n if (!isFunction(blobParts[Symbol.iterator])) throw new TypeError(\"Failed to construct 'Blob': The object must have a callable @@iterator property.\");\n if (typeof options !== \"object\" && !isFunction(options)) throw new TypeError(\"Failed to construct 'Blob': parameter 2 cannot convert to dictionary.\");\n const encoder = new TextEncoder();\n for (const raw of blobParts) {\n let part;\n if (ArrayBuffer.isView(raw)) part = new Uint8Array(raw.buffer.slice(raw.byteOffset, raw.byteOffset + raw.byteLength));\n else if (raw instanceof ArrayBuffer) part = new Uint8Array(raw.slice(0));\n else if (raw instanceof _Blob) part = raw;\n else part = encoder.encode(String(raw));\n __privateSet(this, _size, __privateGet(this, _size) + (ArrayBuffer.isView(part) ? part.byteLength : part.size));\n __privateGet(this, _parts).push(part);\n }\n const type = options.type === void 0 ? \"\" : String(options.type);\n __privateSet(this, _type, /^[\\x20-\\x7E]*$/.test(type) ? type : \"\");\n }\n static [Symbol.hasInstance](value) {\n return Boolean(value && typeof value === \"object\" && isFunction(value.constructor) && (isFunction(value.stream) || isFunction(value.arrayBuffer)) && /^(Blob|File)$/.test(value[Symbol.toStringTag]));\n }\n /**\n * Returns the [`MIME type`](https://developer.mozilla.org/en-US/docs/Glossary/MIME_type) of the [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) or [`File`](https://developer.mozilla.org/en-US/docs/Web/API/File).\n */\n get type() {\n return __privateGet(this, _type);\n }\n /**\n * Returns the size of the [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) or [`File`](https://developer.mozilla.org/en-US/docs/Web/API/File) in bytes.\n */\n get size() {\n return __privateGet(this, _size);\n }\n /**\n * Creates and returns a new [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) object which contains data from a subset of the blob on which it's called.\n *\n * @param start An index into the Blob indicating the first byte to include in the new Blob. If you specify a negative value, it's treated as an offset from the end of the Blob toward the beginning. For example, -10 would be the 10th from last byte in the Blob. The default value is 0. If you specify a value for start that is larger than the size of the source Blob, the returned Blob has size 0 and contains no data.\n * @param end An index into the Blob indicating the first byte that will *not* be included in the new Blob (i.e. the byte exactly at this index is not included). If you specify a negative value, it's treated as an offset from the end of the Blob toward the beginning. For example, -10 would be the 10th from last byte in the Blob. The default value is size.\n * @param contentType The content type to assign to the new Blob; this will be the value of its type property. The default value is an empty string.\n */\n slice(start, end, contentType) {\n return new _Blob(sliceBlob(__privateGet(this, _parts), this.size, start, end), { type: contentType });\n }\n /**\n * Returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that resolves with a string containing the contents of the blob, interpreted as UTF-8.\n */\n async text() {\n const decoder = new TextDecoder();\n let result = \"\";\n for await (const chunk of consumeBlobParts(__privateGet(this, _parts))) result += decoder.decode(chunk, { stream: true });\n result += decoder.decode();\n return result;\n }\n /**\n * Returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that resolves with the contents of the blob as binary data contained in an [`ArrayBuffer`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer).\n */\n async arrayBuffer() {\n const view = new Uint8Array(this.size);\n let offset = 0;\n for await (const chunk of consumeBlobParts(__privateGet(this, _parts))) {\n view.set(chunk, offset);\n offset += chunk.length;\n }\n return view.buffer;\n }\n /**\n * Returns a [`ReadableStream`](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream) which upon reading returns the data contained within the [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob).\n */\n stream() {\n const iterator = consumeBlobParts(__privateGet(this, _parts), true);\n return new ReadableStream({\n async pull(controller) {\n const { value, done } = await iterator.next();\n if (done) return queueMicrotask(() => controller.close());\n controller.enqueue(value);\n },\n async cancel() {\n await iterator.return();\n }\n });\n }\n get [Symbol.toStringTag]() {\n return \"Blob\";\n }\n };\n _parts = /* @__PURE__ */ new WeakMap();\n _type = /* @__PURE__ */ new WeakMap();\n _size = /* @__PURE__ */ new WeakMap();\n var Blob = _Blob;\n Object.defineProperties(Blob.prototype, {\n type: { enumerable: true },\n size: { enumerable: true },\n slice: { enumerable: true },\n stream: { enumerable: true },\n text: { enumerable: true },\n arrayBuffer: { enumerable: true }\n });\n var isBlob = (value) => value instanceof Blob;\n var _name, _lastModified;\n var File = class extends Blob {\n /**\n * Creates a new File instance.\n *\n * @param fileBits An `Array` strings, or [`ArrayBuffer`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer), [`ArrayBufferView`](https://developer.mozilla.org/en-US/docs/Web/API/ArrayBufferView), [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) objects, or a mix of any of such objects, that will be put inside the [`File`](https://developer.mozilla.org/en-US/docs/Web/API/File).\n * @param name The name of the file.\n * @param options An options object containing optional attributes for the file.\n */\n constructor(fileBits, name, options = {}) {\n super(fileBits, options);\n /**\n * Returns the name of the file referenced by the File object.\n */\n __privateAdd(this, _name, void 0);\n /**\n * The last modified date of the file as the number of milliseconds since the Unix epoch (January 1, 1970 at midnight). Files without a known last modified date return the current date.\n */\n __privateAdd(this, _lastModified, 0);\n if (arguments.length < 2) throw new TypeError(`Failed to construct 'File': 2 arguments required, but only ${arguments.length} present.`);\n __privateSet(this, _name, String(name));\n const lastModified = options.lastModified === void 0 ? Date.now() : Number(options.lastModified);\n if (!Number.isNaN(lastModified)) __privateSet(this, _lastModified, lastModified);\n }\n static [Symbol.hasInstance](value) {\n return value instanceof Blob && value[Symbol.toStringTag] === \"File\" && typeof value.name === \"string\";\n }\n /**\n * Name of the file referenced by the File object.\n */\n get name() {\n return __privateGet(this, _name);\n }\n /* c8 ignore next 3 */\n get webkitRelativePath() {\n return \"\";\n }\n /**\n * The last modified date of the file as the number of milliseconds since the Unix epoch (January 1, 1970 at midnight). Files without a known last modified date return the current date.\n */\n get lastModified() {\n return __privateGet(this, _lastModified);\n }\n get [Symbol.toStringTag]() {\n return \"File\";\n }\n };\n _name = /* @__PURE__ */ new WeakMap();\n _lastModified = /* @__PURE__ */ new WeakMap();\n var isFile = (value) => value instanceof File;\n var _entries, _setEntry, setEntry_fn;\n var FormData = class {\n constructor() {\n __privateAdd(this, _setEntry);\n /**\n * Stores internal data for every entry\n */\n __privateAdd(this, _entries, /* @__PURE__ */ new Map());\n }\n static [Symbol.hasInstance](value) {\n if (!value) return false;\n const val = value;\n return Boolean(isFunction(val.constructor) && val[Symbol.toStringTag] === \"FormData\" && isFunction(val.append) && isFunction(val.set) && isFunction(val.get) && isFunction(val.getAll) && isFunction(val.has) && isFunction(val.delete) && isFunction(val.entries) && isFunction(val.values) && isFunction(val.keys) && isFunction(val[Symbol.iterator]) && isFunction(val.forEach));\n }\n /**\n * Appends a new value onto an existing key inside a FormData object,\n * or adds the key if it does not already exist.\n *\n * The difference between `set()` and `append()` is that if the specified key already exists, `set()` will overwrite all existing values with the new one, whereas `append()` will append the new value onto the end of the existing set of values.\n *\n * @param name The name of the field whose data is contained in `value`.\n * @param value The field's value. This can be [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob)\n or [`File`](https://developer.mozilla.org/en-US/docs/Web/API/File). If none of these are specified the value is converted to a string.\n * @param fileName The filename reported to the server, when a Blob or File is passed as the second parameter. The default filename for Blob objects is \"blob\". The default filename for File objects is the file's filename.\n */\n append(name, value, fileName) {\n __privateMethod(this, _setEntry, setEntry_fn).call(this, {\n name,\n fileName,\n append: true,\n rawValue: value,\n argsLength: arguments.length\n });\n }\n /**\n * Set a new value for an existing key inside FormData,\n * or add the new field if it does not already exist.\n *\n * @param name The name of the field whose data is contained in `value`.\n * @param value The field's value. This can be [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob)\n or [`File`](https://developer.mozilla.org/en-US/docs/Web/API/File). If none of these are specified the value is converted to a string.\n * @param fileName The filename reported to the server, when a Blob or File is passed as the second parameter. The default filename for Blob objects is \"blob\". The default filename for File objects is the file's filename.\n *\n */\n set(name, value, fileName) {\n __privateMethod(this, _setEntry, setEntry_fn).call(this, {\n name,\n fileName,\n append: false,\n rawValue: value,\n argsLength: arguments.length\n });\n }\n /**\n * Returns the first value associated with a given key from within a `FormData` object.\n * If you expect multiple values and want all of them, use the `getAll()` method instead.\n *\n * @param {string} name A name of the value you want to retrieve.\n *\n * @returns A `FormDataEntryValue` containing the value. If the key doesn't exist, the method returns null.\n */\n get(name) {\n const field = __privateGet(this, _entries).get(String(name));\n if (!field) return null;\n return field[0];\n }\n /**\n * Returns all the values associated with a given key from within a `FormData` object.\n *\n * @param {string} name A name of the value you want to retrieve.\n *\n * @returns An array of `FormDataEntryValue` whose key matches the value passed in the `name` parameter. If the key doesn't exist, the method returns an empty list.\n */\n getAll(name) {\n const field = __privateGet(this, _entries).get(String(name));\n if (!field) return [];\n return field.slice();\n }\n /**\n * Returns a boolean stating whether a `FormData` object contains a certain key.\n *\n * @param name A string representing the name of the key you want to test for.\n *\n * @return A boolean value.\n */\n has(name) {\n return __privateGet(this, _entries).has(String(name));\n }\n /**\n * Deletes a key and its value(s) from a `FormData` object.\n *\n * @param name The name of the key you want to delete.\n */\n delete(name) {\n __privateGet(this, _entries).delete(String(name));\n }\n /**\n * Returns an [`iterator`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols) allowing to go through all keys contained in this `FormData` object.\n * Each key is a `string`.\n */\n *keys() {\n for (const key of __privateGet(this, _entries).keys()) yield key;\n }\n /**\n * Returns an [`iterator`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols) allowing to go through the `FormData` key/value pairs.\n * The key of each pair is a string; the value is a [`FormDataValue`](https://developer.mozilla.org/en-US/docs/Web/API/FormDataEntryValue).\n */\n *entries() {\n for (const name of this.keys()) {\n const values = this.getAll(name);\n for (const value of values) yield [name, value];\n }\n }\n /**\n * Returns an [`iterator`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols) allowing to go through all values contained in this object `FormData` object.\n * Each value is a [`FormDataValue`](https://developer.mozilla.org/en-US/docs/Web/API/FormDataEntryValue).\n */\n *values() {\n for (const [, value] of this) yield value;\n }\n /**\n * An alias for FormData#entries()\n */\n [Symbol.iterator]() {\n return this.entries();\n }\n /**\n * Executes given callback function for each field of the FormData instance\n */\n forEach(callback, thisArg) {\n for (const [name, value] of this) callback.call(thisArg, value, name, this);\n }\n get [Symbol.toStringTag]() {\n return \"FormData\";\n }\n };\n _entries = /* @__PURE__ */ new WeakMap();\n _setEntry = /* @__PURE__ */ new WeakSet();\n setEntry_fn = function({ name, rawValue, append, fileName, argsLength }) {\n const methodName = append ? \"append\" : \"set\";\n if (argsLength < 2) throw new TypeError(`Failed to execute '${methodName}' on 'FormData': 2 arguments required, but only ${argsLength} present.`);\n name = String(name);\n let value;\n if (isFile(rawValue)) value = fileName === void 0 ? rawValue : new File([rawValue], fileName, {\n type: rawValue.type,\n lastModified: rawValue.lastModified\n });\n else if (isBlob(rawValue)) value = new File([rawValue], fileName === void 0 ? \"blob\" : fileName, { type: rawValue.type });\n else if (fileName) throw new TypeError(`Failed to execute '${methodName}' on 'FormData': parameter 2 is not of type 'Blob'.`);\n else value = String(rawValue);\n const values = __privateGet(this, _entries).get(name);\n if (!values) {\n __privateGet(this, _entries).set(name, [value]);\n return;\n }\n if (!append) {\n __privateGet(this, _entries).set(name, [value]);\n return;\n }\n values.push(value);\n };\n /*! Based on fetch-blob. MIT License. Jimmy Wärting <https://jimmy.warting.se/opensource> & David Frank */\n //#endregion\n //#region node_modules/.pnpm/set-cookie-parser@3.1.0/node_modules/set-cookie-parser/lib/set-cookie.js\n var defaultParseOptions = {\n decodeValues: true,\n map: false,\n silent: false,\n split: \"auto\"\n };\n function isForbiddenKey(key) {\n return typeof key !== \"string\" || key in {};\n }\n function createNullObj() {\n return Object.create(null);\n }\n function isNonEmptyString(str) {\n return typeof str === \"string\" && !!str.trim();\n }\n function parseString(setCookieValue, options) {\n var parts = setCookieValue.split(\";\").filter(isNonEmptyString);\n var parsed = parseNameValuePair(parts.shift());\n var name = parsed.name;\n var value = parsed.value;\n options = options ? Object.assign({}, defaultParseOptions, options) : defaultParseOptions;\n if (isForbiddenKey(name)) return null;\n try {\n value = options.decodeValues ? decodeURIComponent(value) : value;\n } catch (e) {\n console.error(\"set-cookie-parser: failed to decode cookie value. Set options.decodeValues=false to disable decoding.\", e);\n }\n var cookie = createNullObj();\n cookie.name = name;\n cookie.value = value;\n parts.forEach(function(part) {\n var sides = part.split(\"=\");\n var key = sides.shift().trimLeft().toLowerCase();\n if (isForbiddenKey(key)) return;\n var value = sides.join(\"=\");\n if (key === \"expires\") cookie.expires = new Date(value);\n else if (key === \"max-age\") {\n var n = parseInt(value, 10);\n if (!Number.isNaN(n)) cookie.maxAge = n;\n } else if (key === \"secure\") cookie.secure = true;\n else if (key === \"httponly\") cookie.httpOnly = true;\n else if (key === \"samesite\") cookie.sameSite = value;\n else if (key === \"partitioned\") cookie.partitioned = true;\n else if (key) cookie[key] = value;\n });\n return cookie;\n }\n function parseNameValuePair(nameValuePairStr) {\n var name = \"\";\n var value = \"\";\n var nameValueArr = nameValuePairStr.split(\"=\");\n if (nameValueArr.length > 1) {\n name = nameValueArr.shift();\n value = nameValueArr.join(\"=\");\n } else value = nameValuePairStr;\n return {\n name,\n value\n };\n }\n function parseSetCookie(input, options) {\n options = options ? Object.assign({}, defaultParseOptions, options) : defaultParseOptions;\n if (!input) if (!options.map) return [];\n else return createNullObj();\n if (input.headers) if (typeof input.headers.getSetCookie === \"function\") input = input.headers.getSetCookie();\n else if (input.headers[\"set-cookie\"]) input = input.headers[\"set-cookie\"];\n else {\n var sch = input.headers[Object.keys(input.headers).find(function(key) {\n return key.toLowerCase() === \"set-cookie\";\n })];\n if (!sch && input.headers.cookie && !options.silent) console.warn(\"Warning: set-cookie-parser appears to have been called on a request object. It is designed to parse Set-Cookie headers from responses, not Cookie headers from requests. Set the option {silent: true} to suppress this warning.\");\n input = sch;\n }\n var split = options.split;\n var isArray = Array.isArray(input);\n if (split === \"auto\") split = !isArray;\n if (!isArray) input = [input];\n input = input.filter(isNonEmptyString);\n if (split) input = input.map(splitCookiesString).flat();\n if (!options.map) return input.map(function(str) {\n return parseString(str, options);\n }).filter(Boolean);\n else {\n var cookies = createNullObj();\n return input.reduce(function(cookies, str) {\n var cookie = parseString(str, options);\n if (cookie && !isForbiddenKey(cookie.name)) cookies[cookie.name] = cookie;\n return cookies;\n }, cookies);\n }\n }\n function splitCookiesString(cookiesString) {\n if (Array.isArray(cookiesString)) return cookiesString;\n if (typeof cookiesString !== \"string\") return [];\n var cookiesStrings = [];\n var pos = 0;\n var start;\n var ch;\n var lastComma;\n var nextStart;\n var cookiesSeparatorFound;\n function skipWhitespace() {\n while (pos < cookiesString.length && /\\s/.test(cookiesString.charAt(pos))) pos += 1;\n return pos < cookiesString.length;\n }\n function notSpecialChar() {\n ch = cookiesString.charAt(pos);\n return ch !== \"=\" && ch !== \";\" && ch !== \",\";\n }\n while (pos < cookiesString.length) {\n start = pos;\n cookiesSeparatorFound = false;\n while (skipWhitespace()) {\n ch = cookiesString.charAt(pos);\n if (ch === \",\") {\n lastComma = pos;\n pos += 1;\n skipWhitespace();\n nextStart = pos;\n while (pos < cookiesString.length && notSpecialChar()) pos += 1;\n if (pos < cookiesString.length && cookiesString.charAt(pos) === \"=\") {\n cookiesSeparatorFound = true;\n pos = nextStart;\n cookiesStrings.push(cookiesString.substring(start, lastComma));\n start = pos;\n } else pos = lastComma + 1;\n } else pos += 1;\n }\n if (!cookiesSeparatorFound || pos >= cookiesString.length) cookiesStrings.push(cookiesString.substring(start, cookiesString.length));\n }\n return cookiesStrings;\n }\n parseSetCookie.parseSetCookie = parseSetCookie;\n parseSetCookie.parse = parseSetCookie;\n parseSetCookie.parseString = parseString;\n parseSetCookie.splitCookiesString = splitCookiesString;\n //#endregion\n //#region node_modules/.pnpm/headers-polyfill@5.0.1/node_modules/headers-polyfill/lib/index.mjs\n const HEADERS_INVALID_CHARACTERS = /[^a-z0-9\\-#$%&'*+.^_`|~]/i;\n function normalizeHeaderName(name) {\n if (HEADERS_INVALID_CHARACTERS.test(name) || name.trim() === \"\") throw new TypeError(\"Invalid character in header field name\");\n return name.trim().toLowerCase();\n }\n const charCodesToRemove = [\n String.fromCharCode(10),\n String.fromCharCode(13),\n String.fromCharCode(9),\n String.fromCharCode(32)\n ];\n const HEADER_VALUE_REMOVE_REGEXP = new RegExp(`(^[${charCodesToRemove.join(\"\")}]|$[${charCodesToRemove.join(\"\")}])`, \"g\");\n /**\n * Normalize the given header value.\n * @see https://fetch.spec.whatwg.org/#concept-header-value-normalize\n */\n function normalizeHeaderValue(value) {\n return value.replace(HEADER_VALUE_REMOVE_REGEXP, \"\");\n }\n /**\n * Validate the given header name.\n * @see https://fetch.spec.whatwg.org/#header-name\n */\n function isValidHeaderName(value) {\n if (typeof value !== \"string\") return false;\n if (value.length === 0) return false;\n for (let i = 0; i < value.length; i++) {\n const character = value.charCodeAt(i);\n if (character > 127 || !isToken(character)) return false;\n }\n return true;\n }\n function isToken(value) {\n return ![\n 127,\n 32,\n \"(\",\n \")\",\n \"<\",\n \">\",\n \"@\",\n \",\",\n \";\",\n \":\",\n \"\\\\\",\n \"\\\"\",\n \"/\",\n \"[\",\n \"]\",\n \"?\",\n \"=\",\n \"{\",\n \"}\"\n ].includes(value);\n }\n /**\n * Validate the given header value.\n * @see https://fetch.spec.whatwg.org/#header-value\n */\n function isValidHeaderValue(value) {\n if (typeof value !== \"string\") return false;\n if (value.trim() !== value) return false;\n for (let i = 0; i < value.length; i++) {\n const character = value.charCodeAt(i);\n if (character === 0 || character === 10 || character === 13) return false;\n }\n return true;\n }\n let _Symbol$toStringTag;\n const NORMALIZED_HEADERS = Symbol(\"normalizedHeaders\");\n const RAW_HEADER_NAMES = Symbol(\"rawHeaderNames\");\n const HEADER_VALUE_DELIMITER = \", \";\n var Headers = class Headers {\n constructor(init) {\n this[NORMALIZED_HEADERS] = {};\n this[RAW_HEADER_NAMES] = /* @__PURE__ */ new Map();\n this[_Symbol$toStringTag] = \"Headers\";\n /**\n * @note Cannot necessarily check if the `init` is an instance of the\n * `Headers` because that class may not be defined in Node or jsdom.\n */\n if ([\"Headers\", \"HeadersPolyfill\"].includes(init?.constructor?.name) || init instanceof Headers || typeof globalThis.Headers !== \"undefined\" && init instanceof globalThis.Headers) init.forEach((value, name) => {\n this.append(name, value);\n }, this);\n else if (Array.isArray(init)) init.forEach(([name, value]) => {\n this.append(name, Array.isArray(value) ? value.join(HEADER_VALUE_DELIMITER) : value);\n });\n else if (init) Object.getOwnPropertyNames(init).forEach((name) => {\n const value = init[name];\n this.append(name, Array.isArray(value) ? value.join(HEADER_VALUE_DELIMITER) : value);\n });\n }\n [(_Symbol$toStringTag = Symbol.toStringTag, Symbol.iterator)]() {\n return this.entries();\n }\n *keys() {\n for (const [name] of this.entries()) yield name;\n }\n *values() {\n for (const [, value] of this.entries()) yield value;\n }\n *entries() {\n let sortedKeys = Object.keys(this[NORMALIZED_HEADERS]).sort((a, b) => a.localeCompare(b));\n for (const name of sortedKeys) if (name === \"set-cookie\") for (const value of this.getSetCookie()) yield [name, value];\n else yield [name, this.get(name)];\n }\n /**\n * Returns a boolean stating whether a `Headers` object contains a certain header.\n */\n has(name) {\n if (!isValidHeaderName(name)) throw new TypeError(`Invalid header name \"${name}\"`);\n return this[NORMALIZED_HEADERS].hasOwnProperty(normalizeHeaderName(name));\n }\n /**\n * Returns a `ByteString` sequence of all the values of a header with a given name.\n */\n get(name) {\n if (!isValidHeaderName(name)) throw TypeError(`Invalid header name \"${name}\"`);\n return this[NORMALIZED_HEADERS][normalizeHeaderName(name)] ?? null;\n }\n /**\n * Sets a new value for an existing header inside a `Headers` object, or adds the header if it does not already exist.\n */\n set(name, value) {\n if (!isValidHeaderName(name) || !isValidHeaderValue(value)) return;\n const normalizedName = normalizeHeaderName(name);\n const normalizedValue = normalizeHeaderValue(value);\n this[NORMALIZED_HEADERS][normalizedName] = normalizeHeaderValue(normalizedValue);\n this[RAW_HEADER_NAMES].set(normalizedName, name);\n }\n /**\n * Appends a new value onto an existing header inside a `Headers` object, or adds the header if it does not already exist.\n */\n append(name, value) {\n if (!isValidHeaderName(name) || !isValidHeaderValue(value)) return;\n const normalizedName = normalizeHeaderName(name);\n const normalizedValue = normalizeHeaderValue(value);\n let resolvedValue = this.has(normalizedName) ? `${this.get(normalizedName)}, ${normalizedValue}` : normalizedValue;\n this.set(name, resolvedValue);\n }\n /**\n * Deletes a header from the `Headers` object.\n */\n delete(name) {\n if (!isValidHeaderName(name)) return;\n if (!this.has(name)) return;\n const normalizedName = normalizeHeaderName(name);\n delete this[NORMALIZED_HEADERS][normalizedName];\n this[RAW_HEADER_NAMES].delete(normalizedName);\n }\n /**\n * Traverses the `Headers` object,\n * calling the given callback for each header.\n */\n forEach(callback, thisArg) {\n for (const [name, value] of this.entries()) callback.call(thisArg, value, name, this);\n }\n /**\n * Returns an array containing the values\n * of all Set-Cookie headers associated\n * with a response\n */\n getSetCookie() {\n const setCookieHeader = this.get(\"set-cookie\");\n if (setCookieHeader === null) return [];\n if (setCookieHeader === \"\") return [\"\"];\n return splitCookiesString(setCookieHeader);\n }\n };\n //#endregion\n //#region packages/core/src/code-mode/platform-entry.ts\n const platformBridgeGlobalThis = globalThis;\n const capletsPlatformHost = {\n randomUUID: platformBridgeGlobalThis.__caplets_platform_random_uuid,\n randomValues: platformBridgeGlobalThis.__caplets_platform_random_values,\n sleep: platformBridgeGlobalThis.__caplets_platform_sleep,\n clearTimer: platformBridgeGlobalThis.__caplets_platform_clear_timer\n };\n delete platformBridgeGlobalThis.__caplets_platform_random_uuid;\n delete platformBridgeGlobalThis.__caplets_platform_random_values;\n delete platformBridgeGlobalThis.__caplets_platform_sleep;\n delete platformBridgeGlobalThis.__caplets_platform_clear_timer;\n const DISABLED_FETCH_MESSAGE = \"Direct fetch is not available in Code Mode; use a Caplet instead.\";\n const BASE64_ALPHABET = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\n const base64Lookup = new Map(BASE64_ALPHABET.split(\"\").map((char, index) => [char, index]));\n function utf8Encode(input) {\n const encoded = encodeURIComponent(input);\n const bytes = [];\n for (let index = 0; index < encoded.length; index += 1) {\n if (encoded[index] === \"%\") {\n bytes.push(Number.parseInt(encoded.slice(index + 1, index + 3), 16));\n index += 2;\n continue;\n }\n bytes.push(encoded.charCodeAt(index));\n }\n return Uint8Array.from(bytes);\n }\n function utf8Decode(input) {\n let output = \"\";\n for (let index = 0; index < input.length; index += 1) {\n const first = input[index] ?? 0;\n if (first < 128) {\n output += String.fromCharCode(first);\n continue;\n }\n if (first >= 194 && first <= 223) {\n const second = input[index + 1];\n if (isUtf8Continuation(second)) {\n output += String.fromCodePoint((first & 31) << 6 | second & 63);\n index += 1;\n continue;\n }\n output += \"�\";\n continue;\n }\n if (first >= 224 && first <= 239) {\n const second = input[index + 1];\n const third = input[index + 2];\n if (isValidUtf8SecondForThreeByte(first, second) && isUtf8Continuation(third)) {\n output += String.fromCodePoint((first & 15) << 12 | (second & 63) << 6 | third & 63);\n index += 2;\n continue;\n }\n output += \"�\";\n if (isValidUtf8SecondForThreeByte(first, second)) index += 1;\n continue;\n }\n if (first >= 240 && first <= 244) {\n const second = input[index + 1];\n const third = input[index + 2];\n const fourth = input[index + 3];\n if (isValidUtf8SecondForFourByte(first, second) && isUtf8Continuation(third) && isUtf8Continuation(fourth)) {\n output += String.fromCodePoint((first & 7) << 18 | (second & 63) << 12 | (third & 63) << 6 | fourth & 63);\n index += 3;\n continue;\n }\n output += \"�\";\n if (isValidUtf8SecondForFourByte(first, second)) index += isUtf8Continuation(third) ? 2 : 1;\n continue;\n }\n output += \"�\";\n }\n return output;\n }\n function isUtf8Continuation(value) {\n return value !== void 0 && value >= 128 && value <= 191;\n }\n function isValidUtf8SecondForThreeByte(first, second) {\n if (second === void 0) return false;\n if (first === 224) return second >= 160 && second <= 191;\n if (first === 237) return second >= 128 && second <= 159;\n return second >= 128 && second <= 191;\n }\n function isValidUtf8SecondForFourByte(first, second) {\n if (second === void 0) return false;\n if (first === 240) return second >= 144 && second <= 191;\n if (first === 244) return second >= 128 && second <= 143;\n return second >= 128 && second <= 191;\n }\n var TextEncoderShim = class {\n encoding = \"utf-8\";\n encode(input = \"\") {\n return utf8Encode(String(input));\n }\n };\n var TextDecoderShim = class {\n encoding;\n constructor(label = \"utf-8\") {\n const normalized = label.toLowerCase();\n if (![\n \"utf-8\",\n \"utf8\",\n \"unicode-1-1-utf-8\"\n ].includes(normalized)) throw new TypeError(`Unsupported encoding: ${label}`);\n this.encoding = \"utf-8\";\n }\n decode(input) {\n if (input === void 0) return \"\";\n return utf8Decode(copyBytes(input));\n }\n };\n const textEncoder = new TextEncoderShim();\n const textDecoder = new TextDecoderShim();\n var URLSearchParamsShim = class URLSearchParamsShim {\n #entries = [];\n #onChange;\n constructor(init = \"\", onChange) {\n this.#onChange = onChange;\n if (typeof init === \"string\") {\n const source = init.startsWith(\"?\") ? init.slice(1) : init;\n if (!source) return;\n for (const pair of source.split(\"&\")) {\n if (!pair) continue;\n const separatorIndex = pair.indexOf(\"=\");\n const key = separatorIndex >= 0 ? pair.slice(0, separatorIndex) : pair;\n const value = separatorIndex >= 0 ? pair.slice(separatorIndex + 1) : \"\";\n this.#entries.push([decodeUrlParam(key), decodeUrlParam(value)]);\n }\n return;\n }\n if (init instanceof URLSearchParamsShim) {\n this.#entries = [...init.#entries];\n return;\n }\n if (Array.isArray(init)) {\n this.#entries = init.map(([key, value]) => [String(key), String(value)]);\n return;\n }\n this.#entries = Object.entries(init).map(([key, value]) => [key, String(value)]);\n }\n append(name, value) {\n this.#entries.push([String(name), String(value)]);\n this.#onChange?.();\n }\n delete(name) {\n const normalized = String(name);\n this.#entries = this.#entries.filter(([key]) => key !== normalized);\n this.#onChange?.();\n }\n entries() {\n return this.#entries[Symbol.iterator]();\n }\n forEach(callback) {\n for (const [key, value] of this.#entries) callback(value, key, this);\n }\n get(name) {\n return this.#entries.find(([key]) => key === String(name))?.[1] ?? null;\n }\n getAll(name) {\n return this.#entries.filter(([key]) => key === String(name)).map(([, value]) => value);\n }\n has(name) {\n return this.#entries.some(([key]) => key === String(name));\n }\n keys() {\n return this.#entries.map(([key]) => key)[Symbol.iterator]();\n }\n set(name, value) {\n const normalizedName = String(name);\n const normalizedValue = String(value);\n const next = [];\n let replaced = false;\n for (const entry of this.#entries) {\n if (entry[0] !== normalizedName) {\n next.push(entry);\n continue;\n }\n if (!replaced) {\n next.push([normalizedName, normalizedValue]);\n replaced = true;\n }\n }\n if (!replaced) next.push([normalizedName, normalizedValue]);\n this.#entries = next;\n this.#onChange?.();\n }\n toString() {\n return this.#entries.map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`).join(\"&\");\n }\n values() {\n return this.#entries.map(([, value]) => value)[Symbol.iterator]();\n }\n [Symbol.iterator]() {\n return this.entries();\n }\n };\n function decodeUrlParam(value) {\n return decodeURIComponent(value.replace(/\\+/gu, \" \"));\n }\n function parseAbsoluteUrl(input) {\n const match = /^(?<protocol>[a-zA-Z][a-zA-Z\\d+.-]*:)\\/\\/(?<host>[^/?#]*)(?<pathname>[^?#]*)?(?<search>\\?[^#]*)?(?<hash>#.*)?$/u.exec(input);\n if (!match?.groups?.protocol || !match.groups.host) return;\n return {\n protocol: match.groups.protocol,\n host: match.groups.host,\n pathname: match.groups.pathname || \"/\",\n search: match.groups.search || \"\",\n hash: match.groups.hash || \"\"\n };\n }\n function normalizePathname(pathname) {\n const segments = [];\n for (const part of pathname.split(\"/\")) {\n if (!part || part === \".\") continue;\n if (part === \"..\") {\n segments.pop();\n continue;\n }\n segments.push(part);\n }\n return `/${segments.join(\"/\")}`;\n }\n function resolveUrl(input, base) {\n const absolute = parseAbsoluteUrl(input);\n if (absolute) return absolute;\n if (base === void 0) throw new TypeError(`Invalid URL: ${input}`);\n const baseUrl = base instanceof URLShim ? base : new URLShim(String(base));\n const basePath = baseUrl.pathname.endsWith(\"/\") ? baseUrl.pathname : baseUrl.pathname.slice(0, baseUrl.pathname.lastIndexOf(\"/\") + 1);\n const [beforeHash, rawHash = \"\"] = input.split(\"#\");\n const hasExplicitSearch = beforeHash?.includes(\"?\") ?? false;\n const [rawPath, rawSearch = \"\"] = (beforeHash ?? \"\").split(\"?\");\n const pathname = rawPath === \"\" && (input === \"\" || input.startsWith(\"?\") || input.startsWith(\"#\")) ? baseUrl.pathname : rawPath?.startsWith(\"/\") ? rawPath : `${basePath}${rawPath || \"\"}`;\n return {\n protocol: baseUrl.protocol,\n host: baseUrl.host,\n pathname: normalizePathname(pathname),\n search: hasExplicitSearch ? `?${rawSearch}` : rawPath === \"\" && (input === \"\" || input.startsWith(\"#\")) ? baseUrl.search : \"\",\n hash: rawHash ? `#${rawHash}` : \"\"\n };\n }\n var URLShim = class {\n host;\n hostname;\n origin;\n password = \"\";\n port;\n protocol;\n searchParams;\n username = \"\";\n hash;\n pathname;\n #search;\n constructor(input, base) {\n const parsed = resolveUrl(String(input), base);\n this.protocol = parsed.protocol;\n this.host = parsed.host;\n const portIndex = this.host.lastIndexOf(\":\");\n this.hostname = portIndex >= 0 ? this.host.slice(0, portIndex) : this.host;\n this.port = portIndex >= 0 ? this.host.slice(portIndex + 1) : \"\";\n this.pathname = parsed.pathname;\n this.#search = parsed.search;\n this.hash = parsed.hash;\n this.origin = `${this.protocol}//${this.host}`;\n this.searchParams = new URLSearchParamsShim(this.#search, () => {\n const next = this.searchParams.toString();\n this.#search = next ? `?${next}` : \"\";\n });\n }\n get href() {\n return `${this.origin}${this.pathname}${this.#search}${this.hash}`;\n }\n get search() {\n return this.#search;\n }\n toString() {\n return this.href;\n }\n toJSON() {\n return this.href;\n }\n };\n var ReadableStreamShim = class {\n #queue = [];\n #closed = false;\n #pulling = false;\n #source;\n #controller;\n #pending;\n constructor(source = {}) {\n this.#source = source;\n this.#controller = {\n enqueue: (value) => {\n if (this.#pending) {\n this.#pending.resolve({\n done: false,\n value\n });\n this.#pending = void 0;\n return;\n }\n this.#queue.push(value);\n },\n close: () => {\n this.#closed = true;\n if (this.#pending) {\n this.#pending.resolve({ done: true });\n this.#pending = void 0;\n }\n }\n };\n source.start?.(this.#controller);\n }\n async #pull() {\n if (this.#pulling || this.#closed || !this.#source.pull) return;\n this.#pulling = true;\n try {\n await this.#source.pull(this.#controller);\n } finally {\n this.#pulling = false;\n }\n }\n getReader() {\n return { read: async () => {\n if (this.#queue.length > 0) return {\n done: false,\n value: this.#queue.shift()\n };\n await this.#pull();\n if (this.#queue.length > 0) return {\n done: false,\n value: this.#queue.shift()\n };\n if (this.#closed) return {\n done: true,\n value: void 0\n };\n return await new Promise((resolve) => {\n this.#pending = { resolve };\n this.#pull();\n });\n } };\n }\n };\n var WritableStreamShim = class {\n #sink;\n constructor(sink = {}) {\n this.#sink = sink;\n }\n getWriter() {\n return {\n write: async (chunk) => {\n await this.#sink.write?.(chunk);\n },\n close: async () => {\n await this.#sink.close?.();\n }\n };\n }\n };\n var TransformStreamShim = class {\n readable;\n writable;\n constructor(transformer = {}) {\n const queue = [];\n let closed = false;\n let pending;\n const controller = {\n enqueue: (value) => {\n if (pending) {\n pending.resolve({\n done: false,\n value\n });\n pending = void 0;\n return;\n }\n queue.push(value);\n },\n close: () => {\n closed = true;\n if (pending) {\n pending.resolve({ done: true });\n pending = void 0;\n }\n }\n };\n this.readable = { getReader() {\n return { read: async () => {\n if (queue.length > 0) return {\n done: false,\n value: queue.shift()\n };\n if (closed) return {\n done: true,\n value: void 0\n };\n return await new Promise((resolve) => {\n pending = { resolve };\n });\n } };\n } };\n this.writable = new WritableStreamShim({\n write: async (chunk) => {\n transformer.transform?.(chunk, controller);\n },\n close: async () => {\n transformer.flush?.(controller);\n controller.close();\n }\n });\n }\n };\n function definePlatformGlobal(name, value, options = {}) {\n if (!options.overwrite && name in globalThis) return;\n Object.defineProperty(globalThis, name, {\n value,\n writable: true,\n configurable: true\n });\n }\n function formatLogArg(value) {\n if (typeof value === \"string\") return value;\n try {\n return JSON.stringify(value);\n } catch {\n return String(value);\n }\n }\n function formatLogLine(args) {\n return args.map(formatLogArg).join(\" \");\n }\n const platformConsole = {\n log: (...args) => __caplets_log(\"log\", formatLogLine(args)),\n info: (...args) => __caplets_log(\"info\", formatLogLine(args)),\n warn: (...args) => __caplets_log(\"warn\", formatLogLine(args)),\n error: (...args) => __caplets_log(\"error\", formatLogLine(args)),\n debug: (...args) => __caplets_log(\"debug\", formatLogLine(args))\n };\n function normalizeEncoding(encoding) {\n const normalized = (encoding ?? \"utf8\").toLowerCase();\n switch (normalized) {\n case \"utf8\":\n case \"utf-8\":\n case \"base64\":\n case \"base64url\":\n case \"hex\": return normalized;\n default: throw new TypeError(`Unsupported Buffer encoding: ${encoding}`);\n }\n }\n function hexToBytes(value) {\n if (value.length % 2 !== 0) throw new TypeError(\"Invalid hex string length\");\n const bytes = new Uint8Array(value.length / 2);\n for (let index = 0; index < value.length; index += 2) {\n const parsed = Number.parseInt(value.slice(index, index + 2), 16);\n if (Number.isNaN(parsed)) throw new TypeError(\"Invalid hex string\");\n bytes[index / 2] = parsed;\n }\n return bytes;\n }\n function bytesToHex(bytes) {\n return Array.from(bytes, (value) => value.toString(16).padStart(2, \"0\")).join(\"\");\n }\n function base64ToBytes(value, encoding) {\n let normalized = value.replace(/\\s+/gu, \"\");\n if (encoding === \"base64url\") normalized = normalized.replace(/-/gu, \"+\").replace(/_/gu, \"/\");\n const padding = normalized.length % 4;\n if (padding === 1) throw new TypeError(\"Invalid base64 string\");\n if (padding > 0) normalized = normalized.padEnd(normalized.length + (4 - padding), \"=\");\n const output = [];\n for (let index = 0; index < normalized.length; index += 4) {\n const values = normalized.slice(index, index + 4).split(\"\").map((char) => char === \"=\" ? 64 : base64Lookup.get(char) ?? NaN);\n if (values.some((entry) => Number.isNaN(entry))) throw new TypeError(\"Invalid base64 string\");\n const [a = 0, b = 0, c = 64, d = 64] = values;\n const triple = a << 18 | b << 12 | (c & 63) << 6 | d & 63;\n output.push(triple >> 16 & 255);\n if (c !== 64) output.push(triple >> 8 & 255);\n if (d !== 64) output.push(triple & 255);\n }\n return Uint8Array.from(output);\n }\n function bytesToBase64(bytes, encoding) {\n let output = \"\";\n for (let index = 0; index < bytes.length; index += 3) {\n const a = bytes[index] ?? 0;\n const b = bytes[index + 1] ?? 0;\n const c = bytes[index + 2] ?? 0;\n const triple = a << 16 | b << 8 | c;\n output += BASE64_ALPHABET[triple >> 18 & 63];\n output += BASE64_ALPHABET[triple >> 12 & 63];\n output += index + 1 < bytes.length ? BASE64_ALPHABET[triple >> 6 & 63] : \"=\";\n output += index + 2 < bytes.length ? BASE64_ALPHABET[triple & 63] : \"=\";\n }\n if (encoding === \"base64url\") return output.replace(/\\+/gu, \"-\").replace(/\\//gu, \"_\").replace(/=+$/gu, \"\");\n return output;\n }\n function copyBytes(input) {\n if (input instanceof ArrayBuffer) return new Uint8Array(input.slice(0));\n return new Uint8Array(input.buffer.slice(input.byteOffset, input.byteOffset + input.byteLength));\n }\n function toBytes(input, encoding) {\n if (input instanceof BufferShim) return input.toUint8Array();\n if (typeof input === \"string\") switch (normalizeEncoding(encoding)) {\n case \"utf8\":\n case \"utf-8\": return textEncoder.encode(input);\n case \"base64\":\n case \"base64url\": return base64ToBytes(input, normalizeEncoding(encoding));\n case \"hex\": return hexToBytes(input);\n }\n if (input instanceof ArrayBuffer || ArrayBuffer.isView(input)) return copyBytes(input);\n if (Array.isArray(input)) return Uint8Array.from(input);\n throw new TypeError(\"Buffer.from only supports strings, arrays, ArrayBuffers, and typed arrays\");\n }\n var BufferShim = class BufferShim {\n #bytes;\n byteLength;\n length;\n constructor(bytes) {\n this.#bytes = bytes;\n this.byteLength = bytes.byteLength;\n this.length = bytes.length;\n }\n static from(input, encoding) {\n return new BufferShim(toBytes(input, encoding));\n }\n static isBuffer(value) {\n return value instanceof BufferShim;\n }\n static byteLength(input, encoding) {\n return toBytes(input, encoding).byteLength;\n }\n toUint8Array() {\n return new Uint8Array(this.#bytes);\n }\n toString(encoding) {\n switch (normalizeEncoding(encoding)) {\n case \"utf8\":\n case \"utf-8\": return textDecoder.decode(this.#bytes);\n case \"base64\":\n case \"base64url\": return bytesToBase64(this.#bytes, normalizeEncoding(encoding));\n case \"hex\": return bytesToHex(this.#bytes);\n }\n }\n };\n function atobShim(input) {\n return Array.from(base64ToBytes(String(input), \"base64\"), (value) => String.fromCharCode(value)).join(\"\");\n }\n function btoaShim(input) {\n const bytes = new Uint8Array(input.length);\n for (let index = 0; index < input.length; index += 1) {\n const codePoint = input.charCodeAt(index);\n if (codePoint > 255) throw new TypeError(\"The string to be encoded contains characters outside of Latin1\");\n bytes[index] = codePoint;\n }\n return bytesToBase64(bytes, \"base64\");\n }\n function queueMicrotaskShim(callback) {\n Promise.resolve().then(callback);\n }\n var AbortSignalShim = class AbortSignalShim {\n aborted = false;\n reason;\n onabort = null;\n #listeners = /* @__PURE__ */ new Set();\n addEventListener(type, listener) {\n if (type === \"abort\" && listener) this.#listeners.add(listener);\n }\n removeEventListener(type, listener) {\n if (type === \"abort\" && listener) this.#listeners.delete(listener);\n }\n dispatchEvent(event) {\n if (event.type !== \"abort\") return true;\n this.onabort?.(event);\n for (const listener of this.#listeners) listener(event);\n return true;\n }\n throwIfAborted() {\n if (this.aborted) throw this.reason ?? /* @__PURE__ */ new Error(\"Operation was aborted\");\n }\n static abort(reason) {\n const signal = new AbortSignalShim();\n signal.abort(reason);\n return signal;\n }\n abort(reason) {\n if (this.aborted) return;\n this.aborted = true;\n this.reason = reason;\n this.dispatchEvent({\n type: \"abort\",\n target: this\n });\n }\n };\n var AbortControllerShim = class {\n signal = new AbortSignalShim();\n abort(reason) {\n this.signal.abort(reason);\n }\n };\n function cloneFormData(input) {\n const clone = new FormData();\n for (const [name, value] of input.entries()) {\n if (value instanceof File) {\n clone.append(name, new File([value], value.name, { type: value.type }), value.name);\n continue;\n }\n clone.append(name, value);\n }\n return clone;\n }\n function cloneBodyValue(input) {\n if (input === null || input === void 0 || typeof input === \"string\") return input;\n if (input instanceof FormData) return cloneFormData(input);\n if (input instanceof Blob) return input.slice(0, input.size, input.type);\n if (input instanceof ArrayBuffer || ArrayBuffer.isView(input)) return copyBytes(input);\n return input;\n }\n function blobFromBody(input) {\n if (input instanceof Blob) return input;\n if (typeof input === \"string\") return new Blob([input], { type: \"text/plain;charset=utf-8\" });\n if (input instanceof FormData) throw new TypeError(\"FormData body reading is not supported in Code Mode\");\n if (input instanceof ArrayBuffer || ArrayBuffer.isView(input)) return new Blob([copyBytes(input)]);\n return new Blob([]);\n }\n var BodyMixin = class {\n _bodyInit;\n bodyUsed = false;\n body = null;\n constructor(body) {\n this._bodyInit = cloneBodyValue(body);\n }\n async arrayBuffer() {\n this.bodyUsed = true;\n return await blobFromBody(this._bodyInit).arrayBuffer();\n }\n async blob() {\n this.bodyUsed = true;\n return blobFromBody(this._bodyInit);\n }\n async formData() {\n this.bodyUsed = true;\n if (this._bodyInit instanceof FormData) return cloneFormData(this._bodyInit);\n throw new TypeError(\"Body does not contain FormData\");\n }\n async json() {\n return JSON.parse(await this.text());\n }\n async text() {\n this.bodyUsed = true;\n return await blobFromBody(this._bodyInit).text();\n }\n };\n function toHeaders(init) {\n return init instanceof Headers ? new Headers(init) : new Headers(init ?? {});\n }\n function normalizeMethod(method) {\n return String(method ?? \"GET\").toUpperCase();\n }\n var RequestShim = class RequestShim extends BodyMixin {\n headers;\n method;\n signal;\n url;\n constructor(input, init = {}) {\n const sourceBody = input instanceof RequestShim ? input._bodyInit : void 0;\n super(init.body ?? sourceBody);\n if (input instanceof RequestShim) this.url = input.url;\n else this.url = input instanceof URLShim ? input.href : new URLShim(String(input)).href;\n this.method = normalizeMethod(init.method ?? (input instanceof RequestShim ? input.method : \"GET\"));\n this.headers = toHeaders(init.headers ?? (input instanceof RequestShim ? input.headers : void 0));\n this.signal = init.signal ?? (input instanceof RequestShim ? input.signal : new AbortControllerShim().signal);\n }\n clone() {\n return new RequestShim(this, {\n method: this.method,\n headers: this.headers,\n body: this._bodyInit,\n signal: this.signal\n });\n }\n };\n var ResponseShim = class ResponseShim extends BodyMixin {\n headers;\n ok;\n redirected = false;\n status;\n statusText;\n type = \"default\";\n url = \"\";\n constructor(body, init = {}) {\n super(body);\n this.status = init.status ?? 200;\n this.statusText = init.statusText ?? \"\";\n this.headers = toHeaders(init.headers);\n this.ok = this.status >= 200 && this.status <= 299;\n }\n clone() {\n return new ResponseShim(this._bodyInit, {\n headers: this.headers,\n status: this.status,\n statusText: this.statusText\n });\n }\n static json(data, init) {\n const headers = toHeaders(init?.headers);\n if (!headers.has(\"content-type\")) headers.set(\"content-type\", \"application/json\");\n const responseInit = { headers };\n if (init?.status !== void 0) responseInit.status = init.status;\n if (init?.statusText !== void 0) responseInit.statusText = init.statusText;\n return new ResponseShim(JSON.stringify(data), responseInit);\n }\n };\n function disabledFetch() {\n throw new Error(DISABLED_FETCH_MESSAGE);\n }\n const integerTypedArrayConstructors = /* @__PURE__ */ new Set([\n Int8Array,\n Uint8Array,\n Uint8ClampedArray,\n Int16Array,\n Uint16Array,\n Int32Array,\n Uint32Array,\n typeof BigInt64Array === \"undefined\" ? void 0 : BigInt64Array,\n typeof BigUint64Array === \"undefined\" ? void 0 : BigUint64Array\n ]);\n var QuotaExceededErrorShim = class extends Error {\n constructor(message) {\n super(message);\n this.name = \"QuotaExceededError\";\n }\n };\n const platformCrypto = {\n randomUUID() {\n const randomUUID = capletsPlatformHost.randomUUID;\n if (!randomUUID) throw new Error(\"Code Mode platform random UUID bridge is not installed\");\n return randomUUID();\n },\n getRandomValues(typedArray) {\n if (!ArrayBuffer.isView(typedArray) || typedArray instanceof DataView) throw new TypeError(\"crypto.getRandomValues requires an integer typed array\");\n if (!integerTypedArrayConstructors.has(typedArray.constructor)) throw new TypeError(\"crypto.getRandomValues requires an integer typed array\");\n if (typedArray.byteLength > 65536) throw new QuotaExceededErrorShim(\"crypto.getRandomValues cannot generate more than 65,536 bytes\");\n const randomValues = capletsPlatformHost.randomValues;\n if (!randomValues) throw new Error(\"Code Mode platform random values bridge is not installed\");\n const bytes = randomValues(typedArray.byteLength);\n new Uint8Array(typedArray.buffer, typedArray.byteOffset, typedArray.byteLength).set(bytes);\n return typedArray;\n }\n };\n let nextTimerId = 1;\n const activeTimers = /* @__PURE__ */ new Set();\n function normalizeTimerDelay(delay) {\n const value = Number(delay ?? 0);\n if (!Number.isFinite(value) || value <= 0) return 0;\n return Math.trunc(value);\n }\n function setTimeoutShim(callback, delay, ...args) {\n if (typeof callback !== \"function\") throw new TypeError(\"setTimeout callback must be a function\");\n const timerId = nextTimerId++;\n activeTimers.add(timerId);\n const sleep = capletsPlatformHost.sleep;\n if (!sleep) throw new Error(\"Code Mode platform sleep bridge is not installed\");\n sleep(timerId, normalizeTimerDelay(delay)).then((fired) => {\n activeTimers.delete(timerId);\n if (fired) callback(...args);\n });\n return timerId;\n }\n function clearTimeoutShim(timerId) {\n const id = Number(timerId);\n activeTimers.delete(id);\n capletsPlatformHost.clearTimer?.(id);\n }\n function setIntervalShim(callback, delay, ...args) {\n if (typeof callback !== \"function\") throw new TypeError(\"setInterval callback must be a function\");\n const timerId = nextTimerId++;\n const intervalDelay = normalizeTimerDelay(delay);\n activeTimers.add(timerId);\n const tick = () => {\n const sleep = capletsPlatformHost.sleep;\n if (!sleep) throw new Error(\"Code Mode platform sleep bridge is not installed\");\n sleep(timerId, intervalDelay).then((fired) => {\n if (!fired || !activeTimers.has(timerId)) {\n activeTimers.delete(timerId);\n return;\n }\n callback(...args);\n if (activeTimers.has(timerId)) tick();\n });\n };\n tick();\n return timerId;\n }\n function clearIntervalShim(timerId) {\n clearTimeoutShim(timerId);\n }\n definePlatformGlobal(\"atob\", atobShim);\n definePlatformGlobal(\"btoa\", btoaShim);\n definePlatformGlobal(\"Buffer\", BufferShim);\n definePlatformGlobal(\"TextEncoder\", TextEncoderShim);\n definePlatformGlobal(\"TextDecoder\", TextDecoderShim);\n definePlatformGlobal(\"URL\", URLShim);\n definePlatformGlobal(\"URLSearchParams\", URLSearchParamsShim);\n definePlatformGlobal(\"structuredClone\", esm_default);\n definePlatformGlobal(\"Headers\", Headers);\n definePlatformGlobal(\"Blob\", Blob);\n definePlatformGlobal(\"File\", File);\n definePlatformGlobal(\"FormData\", FormData);\n definePlatformGlobal(\"ReadableStream\", ReadableStreamShim);\n definePlatformGlobal(\"WritableStream\", WritableStreamShim);\n definePlatformGlobal(\"TransformStream\", TransformStreamShim);\n definePlatformGlobal(\"AbortController\", AbortControllerShim);\n definePlatformGlobal(\"AbortSignal\", AbortSignalShim);\n definePlatformGlobal(\"Request\", RequestShim);\n definePlatformGlobal(\"Response\", ResponseShim);\n definePlatformGlobal(\"crypto\", platformCrypto);\n definePlatformGlobal(\"setTimeout\", setTimeoutShim);\n definePlatformGlobal(\"clearTimeout\", clearTimeoutShim);\n definePlatformGlobal(\"setInterval\", setIntervalShim);\n definePlatformGlobal(\"clearInterval\", clearIntervalShim);\n definePlatformGlobal(\"queueMicrotask\", queueMicrotaskShim);\n definePlatformGlobal(\"console\", platformConsole);\n definePlatformGlobal(\"fetch\", disabledFetch, { overwrite: true });\n //#endregion\n})();";
|
|
77796
77795
|
//#endregion
|
|
77797
77796
|
//#region src/code-mode/sandbox.ts
|
|
77798
|
-
const CODE_MODE_SANDBOX_METHODS = new Set([
|
|
77797
|
+
const CODE_MODE_SANDBOX_METHODS = /* @__PURE__ */ new Set([
|
|
77799
77798
|
"inspect",
|
|
77800
77799
|
"check",
|
|
77801
77800
|
"tools",
|
|
@@ -77813,7 +77812,7 @@ const CODE_MODE_SANDBOX_METHODS = new Set([
|
|
|
77813
77812
|
"readLogs",
|
|
77814
77813
|
"readRecovery"
|
|
77815
77814
|
]);
|
|
77816
|
-
const CODE_MODE_DEBUG_METHODS = new Set(["readLogs", "readRecovery"]);
|
|
77815
|
+
const CODE_MODE_DEBUG_METHODS = /* @__PURE__ */ new Set(["readLogs", "readRecovery"]);
|
|
77817
77816
|
var QuickJsCodeModeSandbox = class {
|
|
77818
77817
|
async run(input) {
|
|
77819
77818
|
return await evaluateInQuickJs(input);
|
|
@@ -78823,7 +78822,7 @@ function splitPersistentPrelude(javascript, existingNames = [], checkpointToken
|
|
|
78823
78822
|
const ranges = [];
|
|
78824
78823
|
const names = collectPersistentBindingNames(source);
|
|
78825
78824
|
const lexicalNames = collectTopLevelLexicalBindingNames(source);
|
|
78826
|
-
const allNames = [
|
|
78825
|
+
const allNames = [.../* @__PURE__ */ new Set([...existingNames, ...names])];
|
|
78827
78826
|
const snapshotNames = allNames.filter((name) => !lexicalNames.has(name));
|
|
78828
78827
|
const returnTempName = uniqueInternalName("__caplets_return", allNames);
|
|
78829
78828
|
const postlude = snapshotNames.map((name) => persistentBindingPostlude(name, checkpointToken)).join("\n");
|
|
@@ -78856,7 +78855,7 @@ function collectPersistentReturnRanges(node, source, snapshotNames, ranges, retu
|
|
|
78856
78855
|
if (snapshotNames.length === 0) return;
|
|
78857
78856
|
if (ts.isFunctionLike(node) || ts.isClassLike(node)) return;
|
|
78858
78857
|
const declared = lexicalNamesDeclaredByNode(node);
|
|
78859
|
-
const activeShadowedNames = declared.size === 0 ? shadowedNames : new Set([...shadowedNames, ...declared]);
|
|
78858
|
+
const activeShadowedNames = declared.size === 0 ? shadowedNames : /* @__PURE__ */ new Set([...shadowedNames, ...declared]);
|
|
78860
78859
|
if (ts.isReturnStatement(node)) {
|
|
78861
78860
|
const expression = node.expression?.getText(source);
|
|
78862
78861
|
const postludeExpression = snapshotNames.filter((name) => !activeShadowedNames.has(name)).map((name) => persistentBindingExpression(name, checkpointToken)).join(", ");
|
|
@@ -78921,10 +78920,10 @@ function collectPersistentFinallyRanges(node, snapshotNames, ranges, checkpointT
|
|
|
78921
78920
|
if (snapshotNames.length === 0) return;
|
|
78922
78921
|
if (ts.isFunctionLike(node) || ts.isClassLike(node)) return;
|
|
78923
78922
|
const declared = lexicalNamesDeclaredByNode(node);
|
|
78924
|
-
const activeShadowedNames = declared.size === 0 ? shadowedNames : new Set([...shadowedNames, ...declared]);
|
|
78923
|
+
const activeShadowedNames = declared.size === 0 ? shadowedNames : /* @__PURE__ */ new Set([...shadowedNames, ...declared]);
|
|
78925
78924
|
if (ts.isTryStatement(node) && node.finallyBlock) {
|
|
78926
78925
|
const finallyDeclared = lexicalNamesDeclaredByNode(node.finallyBlock);
|
|
78927
|
-
const finallyShadowedNames = finallyDeclared.size === 0 ? activeShadowedNames : new Set([...activeShadowedNames, ...finallyDeclared]);
|
|
78926
|
+
const finallyShadowedNames = finallyDeclared.size === 0 ? activeShadowedNames : /* @__PURE__ */ new Set([...activeShadowedNames, ...finallyDeclared]);
|
|
78928
78927
|
const postlude = snapshotNames.filter((name) => !finallyShadowedNames.has(name)).map((name) => persistentBindingPostlude(name, checkpointToken)).join("\n");
|
|
78929
78928
|
if (postlude) ranges.push({
|
|
78930
78929
|
start: node.finallyBlock.end - 1,
|
|
@@ -79735,32 +79734,18 @@ function nativeCapletToolDescription(toolName, caplet) {
|
|
|
79735
79734
|
}
|
|
79736
79735
|
//#endregion
|
|
79737
79736
|
//#region src/server/options.ts
|
|
79738
|
-
const DEFAULT_SERVER_USER = "caplets";
|
|
79739
79737
|
function resolveCapletsServer(input = {}, env = process.env) {
|
|
79740
79738
|
const rawUrl = nonEmpty$1(input.url, "url") ?? nonEmpty$1(env.CAPLETS_SERVER_URL, "CAPLETS_SERVER_URL");
|
|
79741
79739
|
if (rawUrl === void 0) throw new CapletsError("REQUEST_INVALID", "CAPLETS_SERVER_URL or url is required.");
|
|
79742
79740
|
const baseUrl = parseServerBaseUrl(rawUrl);
|
|
79743
|
-
const userWasExplicit = input.user !== void 0 || hasEnv$1(env.CAPLETS_SERVER_USER);
|
|
79744
|
-
const user = nonEmpty$1(input.user, "user") ?? nonEmpty$1(env.CAPLETS_SERVER_USER, "CAPLETS_SERVER_USER") ?? DEFAULT_SERVER_USER;
|
|
79745
|
-
const password = nonEmpty$1(input.password, "password") ?? nonEmpty$1(env.CAPLETS_SERVER_PASSWORD, "CAPLETS_SERVER_PASSWORD");
|
|
79746
|
-
if (userWasExplicit && password === void 0) throw new CapletsError("REQUEST_INVALID", "Caplets server Basic Auth requires a password; set CAPLETS_SERVER_PASSWORD or password.");
|
|
79747
|
-
const auth = password === void 0 ? {
|
|
79748
|
-
enabled: false,
|
|
79749
|
-
user
|
|
79750
|
-
} : {
|
|
79751
|
-
enabled: true,
|
|
79752
|
-
user,
|
|
79753
|
-
password
|
|
79754
|
-
};
|
|
79755
|
-
const requestInit = auth.enabled ? { headers: { Authorization: basicAuthHeader$1(auth.user, auth.password) } } : {};
|
|
79756
79741
|
return {
|
|
79757
79742
|
baseUrl,
|
|
79758
79743
|
mcpUrl: mcpUrlForBase(baseUrl),
|
|
79759
79744
|
attachUrl: attachUrlForBase(baseUrl),
|
|
79760
79745
|
controlUrl: controlUrlForBase(baseUrl),
|
|
79761
79746
|
healthUrl: healthUrlForBase(baseUrl),
|
|
79762
|
-
auth,
|
|
79763
|
-
requestInit,
|
|
79747
|
+
auth: { type: "none" },
|
|
79748
|
+
requestInit: {},
|
|
79764
79749
|
...input.fetch ? { fetch: input.fetch } : {}
|
|
79765
79750
|
};
|
|
79766
79751
|
}
|
|
@@ -79797,18 +79782,12 @@ function isLoopbackHost(host) {
|
|
|
79797
79782
|
const normalized = host.toLocaleLowerCase();
|
|
79798
79783
|
return normalized === "localhost" || normalized === "127.0.0.1" || normalized === "::1" || normalized === "[::1]";
|
|
79799
79784
|
}
|
|
79800
|
-
function basicAuthHeader$1(user, password) {
|
|
79801
|
-
return `Basic ${Buffer$1.from(`${user}:${password}`).toString("base64")}`;
|
|
79802
|
-
}
|
|
79803
79785
|
function nonEmpty$1(value, label) {
|
|
79804
79786
|
if (value === void 0) return;
|
|
79805
79787
|
const trimmed = value.trim();
|
|
79806
79788
|
if (!trimmed) throw new CapletsError("REQUEST_INVALID", `${label} must not be empty`);
|
|
79807
79789
|
return trimmed;
|
|
79808
79790
|
}
|
|
79809
|
-
function hasEnv$1(value) {
|
|
79810
|
-
return value !== void 0 && value.trim() !== "";
|
|
79811
|
-
}
|
|
79812
79791
|
//#endregion
|
|
79813
79792
|
//#region src/remote/options.ts
|
|
79814
79793
|
const DEFAULT_REMOTE_USER = "caplets";
|
|
@@ -79832,25 +79811,16 @@ function resolveCapletsRemote(input = {}, env = process.env) {
|
|
|
79832
79811
|
const rawUrl = nonEmpty(input.url, "url") ?? nonEmpty(env.CAPLETS_REMOTE_URL, "CAPLETS_REMOTE_URL");
|
|
79833
79812
|
if (rawUrl === void 0) throw new CapletsError("REQUEST_INVALID", "CAPLETS_REMOTE_URL or url is required.");
|
|
79834
79813
|
const baseUrl = parseServerBaseUrl(rawUrl);
|
|
79835
|
-
const token = nonEmpty(input.token, "token")
|
|
79836
|
-
const userWasExplicit = input.user !== void 0 || hasEnv(env.CAPLETS_REMOTE_USER);
|
|
79837
|
-
const user = nonEmpty(input.user, "user") ?? nonEmpty(env.CAPLETS_REMOTE_USER, "CAPLETS_REMOTE_USER") ?? DEFAULT_REMOTE_USER;
|
|
79838
|
-
const password = nonEmpty(input.password, "password") ?? nonEmpty(env.CAPLETS_REMOTE_PASSWORD, "CAPLETS_REMOTE_PASSWORD");
|
|
79814
|
+
const token = nonEmpty(input.token, "token");
|
|
79839
79815
|
const workspace = nonEmpty(input.workspace, "workspace") ?? nonEmpty(env.CAPLETS_REMOTE_WORKSPACE, "CAPLETS_REMOTE_WORKSPACE");
|
|
79840
|
-
if (token && password) throw new CapletsError("REQUEST_INVALID", "Use either CAPLETS_REMOTE_TOKEN or CAPLETS_REMOTE_PASSWORD, not both.");
|
|
79841
|
-
if (!token && userWasExplicit && password === void 0) throw new CapletsError("REQUEST_INVALID", "Remote Caplets Basic Auth requires a password; set CAPLETS_REMOTE_PASSWORD or password.");
|
|
79842
79816
|
const auth = token ? {
|
|
79843
79817
|
type: "bearer",
|
|
79844
79818
|
token
|
|
79845
|
-
} : password === void 0 ? {
|
|
79846
|
-
type: "none",
|
|
79847
|
-
user
|
|
79848
79819
|
} : {
|
|
79849
|
-
type: "
|
|
79850
|
-
user
|
|
79851
|
-
password
|
|
79820
|
+
type: "none",
|
|
79821
|
+
user: DEFAULT_REMOTE_USER
|
|
79852
79822
|
};
|
|
79853
|
-
const requestInit = auth.type === "bearer" ? { headers: { Authorization: `Bearer ${auth.token}` } } :
|
|
79823
|
+
const requestInit = auth.type === "bearer" ? { headers: { Authorization: `Bearer ${auth.token}` } } : {};
|
|
79854
79824
|
return {
|
|
79855
79825
|
baseUrl,
|
|
79856
79826
|
mcpUrl: appendBasePath(baseUrl, "v1/mcp"),
|
|
@@ -79870,7 +79840,7 @@ function resolveHostedCloudRemote(input = {}, env = process.env) {
|
|
|
79870
79840
|
const cloud = parseHostedCloudRemoteUrl(rawUrl);
|
|
79871
79841
|
const workspace = cloud.workspace ?? nonEmpty(input.workspace, "workspace") ?? nonEmpty(env.CAPLETS_REMOTE_WORKSPACE, "CAPLETS_REMOTE_WORKSPACE");
|
|
79872
79842
|
if (!workspace) throw new CapletsError("REQUEST_INVALID", "Caplets Cloud remote URL requires a selected workspace.");
|
|
79873
|
-
const token = nonEmpty(input.token, "token")
|
|
79843
|
+
const token = nonEmpty(input.token, "token");
|
|
79874
79844
|
const auth = token ? {
|
|
79875
79845
|
type: "bearer",
|
|
79876
79846
|
token
|
|
@@ -79900,6 +79870,11 @@ function hostedCloudWorkspaceFromRemoteUrl(value) {
|
|
|
79900
79870
|
return;
|
|
79901
79871
|
}
|
|
79902
79872
|
}
|
|
79873
|
+
function normalizeRemoteProfileHostUrl(value) {
|
|
79874
|
+
const url = parseServerBaseUrl(value);
|
|
79875
|
+
if (isCapletsCloudUrl(url.toString())) return `${url.origin}/`;
|
|
79876
|
+
return url.toString();
|
|
79877
|
+
}
|
|
79903
79878
|
function projectBindingWebSocketUrlForBase(baseUrl) {
|
|
79904
79879
|
return webSocketUrl(appendBasePath(baseUrl, "v1/attach/project-bindings/connect"));
|
|
79905
79880
|
}
|
|
@@ -79937,18 +79912,12 @@ function parseCapletsMode(value) {
|
|
|
79937
79912
|
if (value === "auto" || value === "local" || value === "remote" || value === "cloud") return value;
|
|
79938
79913
|
throw new CapletsError("REQUEST_INVALID", `Expected CAPLETS_MODE to be auto, local, remote, or cloud, got ${value}`);
|
|
79939
79914
|
}
|
|
79940
|
-
function basicAuthHeader(user, password) {
|
|
79941
|
-
return `Basic ${Buffer$1.from(`${user}:${password}`).toString("base64")}`;
|
|
79942
|
-
}
|
|
79943
79915
|
function nonEmpty(value, label) {
|
|
79944
79916
|
if (value === void 0) return void 0;
|
|
79945
79917
|
const trimmed = value.trim();
|
|
79946
79918
|
if (!trimmed) throw new CapletsError("REQUEST_INVALID", `${label} must not be empty`);
|
|
79947
79919
|
return trimmed;
|
|
79948
79920
|
}
|
|
79949
|
-
function hasEnv(value) {
|
|
79950
|
-
return value !== void 0 && value.trim() !== "";
|
|
79951
|
-
}
|
|
79952
79921
|
//#endregion
|
|
79953
79922
|
//#region src/native/options.ts
|
|
79954
79923
|
const DEFAULT_POLL_INTERVAL_MS = 3e4;
|
|
@@ -79960,7 +79929,11 @@ function resolveNativeCapletsServiceOptions(input = {}, env = process.env) {
|
|
|
79960
79929
|
}, env);
|
|
79961
79930
|
if (mode.mode === "local") return { mode: "local" };
|
|
79962
79931
|
const remoteFetch = input.remote?.fetch;
|
|
79963
|
-
const server = mode.mode === "cloud" ?
|
|
79932
|
+
const server = mode.mode === "cloud" ? resolveNativeHostedCloudRemoteOrPlaceholder(input.remote?.url ?? env.CAPLETS_REMOTE_URL ?? "", optionalWorkspace(input, env).workspace, remoteFetch) : resolveCapletsRemote({
|
|
79933
|
+
...input.remote?.url ? { url: input.remote.url } : {},
|
|
79934
|
+
...input.remote?.workspace ? { workspace: input.remote.workspace } : {},
|
|
79935
|
+
...remoteFetch ? { fetch: remoteFetch } : {}
|
|
79936
|
+
}, env);
|
|
79964
79937
|
const cloud = resolveNativeCloudPresence(input.remote?.cloud, env);
|
|
79965
79938
|
return {
|
|
79966
79939
|
mode: mode.mode,
|
|
@@ -79981,16 +79954,19 @@ function resolveNativeHostedCloudRemote(url, workspace, fetch) {
|
|
|
79981
79954
|
...fetch ? { fetch } : {}
|
|
79982
79955
|
});
|
|
79983
79956
|
}
|
|
79957
|
+
function resolveNativeHostedCloudRemoteOrPlaceholder(url, workspace, fetch) {
|
|
79958
|
+
if (!isCapletsCloudUrl(url)) throw new CapletsError("REQUEST_INVALID", "CAPLETS_MODE=cloud requires Caplets Cloud.");
|
|
79959
|
+
if (workspace) return resolveNativeHostedCloudRemote(url, workspace, fetch);
|
|
79960
|
+
return resolveCapletsRemote({
|
|
79961
|
+
url,
|
|
79962
|
+
...fetch ? { fetch } : {}
|
|
79963
|
+
}, {});
|
|
79964
|
+
}
|
|
79984
79965
|
function optionalWorkspace(input, env) {
|
|
79985
79966
|
const workspace = input.remote?.cloud?.workspaceId ?? input.remote?.workspace ?? env.CAPLETS_REMOTE_WORKSPACE ?? env.CAPLETS_CLOUD_WORKSPACE_ID;
|
|
79986
79967
|
return workspace ? { workspace } : {};
|
|
79987
79968
|
}
|
|
79988
79969
|
function nativeAuthFromRemoteAuth$1(auth) {
|
|
79989
|
-
if (auth.type === "basic") return {
|
|
79990
|
-
enabled: true,
|
|
79991
|
-
user: auth.user,
|
|
79992
|
-
password: auth.password
|
|
79993
|
-
};
|
|
79994
79970
|
if (auth.type === "none") return {
|
|
79995
79971
|
enabled: false,
|
|
79996
79972
|
user: auth.user
|
|
@@ -80314,45 +80290,79 @@ function projectSyncFiles(projectRoot) {
|
|
|
80314
80290
|
//#endregion
|
|
80315
80291
|
//#region src/native/remote.ts
|
|
80316
80292
|
function createSdkRemoteCapletsClient(options) {
|
|
80317
|
-
const fetchImpl = options.fetch ?? fetch;
|
|
80318
80293
|
const listeners = /* @__PURE__ */ new Set();
|
|
80319
80294
|
let manifest;
|
|
80320
80295
|
let exportByName = /* @__PURE__ */ new Map();
|
|
80321
80296
|
let eventsAbort;
|
|
80297
|
+
let eventsStartInFlight;
|
|
80322
80298
|
let eventsReconnectTimer;
|
|
80299
|
+
let closed = false;
|
|
80300
|
+
const resolveRuntimeOptions = async () => {
|
|
80301
|
+
return options.resolveRuntimeOptions ? await options.resolveRuntimeOptions() : options;
|
|
80302
|
+
};
|
|
80303
|
+
const fetchFor = (runtimeOptions) => runtimeOptions.fetch ?? fetch;
|
|
80304
|
+
const fetchCurrentManifest = async () => {
|
|
80305
|
+
const runtimeOptions = await resolveRuntimeOptions();
|
|
80306
|
+
return await fetchAttachManifest(runtimeOptions.url, runtimeOptions.requestInit, fetchFor(runtimeOptions));
|
|
80307
|
+
};
|
|
80308
|
+
const invokeCurrentExport = async (body) => {
|
|
80309
|
+
const runtimeOptions = await resolveRuntimeOptions();
|
|
80310
|
+
return await invokeAttachExport(runtimeOptions.url, runtimeOptions.requestInit, fetchFor(runtimeOptions), body);
|
|
80311
|
+
};
|
|
80323
80312
|
const clearEventsReconnectTimer = () => {
|
|
80324
80313
|
if (eventsReconnectTimer) {
|
|
80325
80314
|
clearTimeout(eventsReconnectTimer);
|
|
80326
80315
|
eventsReconnectTimer = void 0;
|
|
80327
80316
|
}
|
|
80328
80317
|
};
|
|
80318
|
+
const scheduleEventsReconnect = () => {
|
|
80319
|
+
if (closed || listeners.size === 0) return;
|
|
80320
|
+
clearEventsReconnectTimer();
|
|
80321
|
+
eventsReconnectTimer = setTimeout(() => {
|
|
80322
|
+
eventsReconnectTimer = void 0;
|
|
80323
|
+
startEvents();
|
|
80324
|
+
}, 1e3);
|
|
80325
|
+
};
|
|
80326
|
+
const startEventsNow = async () => {
|
|
80327
|
+
try {
|
|
80328
|
+
const runtimeOptions = await resolveRuntimeOptions();
|
|
80329
|
+
if (closed || eventsAbort || listeners.size === 0) return;
|
|
80330
|
+
eventsAbort = startAttachEvents(runtimeOptions.url, runtimeOptions.requestInit, fetchFor(runtimeOptions), listeners, (closedAbort, retry) => {
|
|
80331
|
+
if (eventsAbort !== closedAbort) return;
|
|
80332
|
+
eventsAbort = void 0;
|
|
80333
|
+
if (!retry || closedAbort.signal.aborted || listeners.size === 0) return;
|
|
80334
|
+
scheduleEventsReconnect();
|
|
80335
|
+
});
|
|
80336
|
+
} catch (error) {
|
|
80337
|
+
if (isPermanentRemoteCredentialsError(error)) {
|
|
80338
|
+
options.writeErr?.(`${remoteAuthError(options.authKind ?? "self_hosted_remote").message}\n`);
|
|
80339
|
+
return;
|
|
80340
|
+
}
|
|
80341
|
+
scheduleEventsReconnect();
|
|
80342
|
+
}
|
|
80343
|
+
};
|
|
80329
80344
|
const startEvents = () => {
|
|
80330
|
-
if (eventsAbort || listeners.size === 0) return;
|
|
80331
|
-
|
|
80332
|
-
|
|
80333
|
-
|
|
80334
|
-
if (
|
|
80335
|
-
clearEventsReconnectTimer();
|
|
80336
|
-
eventsReconnectTimer = setTimeout(() => {
|
|
80337
|
-
eventsReconnectTimer = void 0;
|
|
80338
|
-
startEvents();
|
|
80339
|
-
}, 1e3);
|
|
80345
|
+
if (closed || eventsAbort || eventsStartInFlight || listeners.size === 0) return;
|
|
80346
|
+
const start = startEventsNow();
|
|
80347
|
+
eventsStartInFlight = start;
|
|
80348
|
+
start.finally(() => {
|
|
80349
|
+
if (eventsStartInFlight === start) eventsStartInFlight = void 0;
|
|
80340
80350
|
});
|
|
80341
80351
|
};
|
|
80342
80352
|
return {
|
|
80343
80353
|
async listTools() {
|
|
80344
|
-
manifest = await
|
|
80354
|
+
manifest = await fetchCurrentManifest();
|
|
80345
80355
|
exportByName = exportMapFor(manifest);
|
|
80346
80356
|
return toolsFromManifest(manifest);
|
|
80347
80357
|
},
|
|
80348
80358
|
async callTool(name, args) {
|
|
80349
80359
|
if (!manifest) {
|
|
80350
|
-
manifest = await
|
|
80360
|
+
manifest = await fetchCurrentManifest();
|
|
80351
80361
|
exportByName = exportMapFor(manifest);
|
|
80352
80362
|
}
|
|
80353
80363
|
const invokeWithStaleRetry = async (entry, input) => {
|
|
80354
80364
|
try {
|
|
80355
|
-
return await
|
|
80365
|
+
return await invokeCurrentExport({
|
|
80356
80366
|
revision: manifest.revision,
|
|
80357
80367
|
kind: entry.kind,
|
|
80358
80368
|
exportId: entry.exportId,
|
|
@@ -80360,12 +80370,12 @@ function createSdkRemoteCapletsClient(options) {
|
|
|
80360
80370
|
});
|
|
80361
80371
|
} catch (error) {
|
|
80362
80372
|
if (!isAttachManifestStale(error)) throw error;
|
|
80363
|
-
const nextManifest = await
|
|
80373
|
+
const nextManifest = await fetchCurrentManifest();
|
|
80364
80374
|
const nextEntry = compatibleExport(nextManifest, entry);
|
|
80365
80375
|
manifest = nextManifest;
|
|
80366
80376
|
exportByName = exportMapFor(nextManifest);
|
|
80367
80377
|
if (!nextEntry) throw new CapletsError("ATTACH_EXPORT_NOT_FOUND", "Attach export changed after manifest refresh; refetch the manifest before retrying.");
|
|
80368
|
-
return await
|
|
80378
|
+
return await invokeCurrentExport({
|
|
80369
80379
|
revision: nextManifest.revision,
|
|
80370
80380
|
kind: nextEntry.kind,
|
|
80371
80381
|
exportId: nextEntry.exportId,
|
|
@@ -80394,6 +80404,7 @@ function createSdkRemoteCapletsClient(options) {
|
|
|
80394
80404
|
};
|
|
80395
80405
|
},
|
|
80396
80406
|
async close() {
|
|
80407
|
+
closed = true;
|
|
80397
80408
|
clearEventsReconnectTimer();
|
|
80398
80409
|
eventsAbort?.abort();
|
|
80399
80410
|
eventsAbort = void 0;
|
|
@@ -80990,7 +81001,7 @@ function errorMessage$1(error) {
|
|
|
80990
81001
|
return error instanceof Error ? error.message : String(error);
|
|
80991
81002
|
}
|
|
80992
81003
|
function remoteAuthError(kind) {
|
|
80993
|
-
return new CapletsError("AUTH_FAILED", kind === "hosted_cloud" ? "Caplets Cloud authentication failed; run caplets
|
|
81004
|
+
return new CapletsError("AUTH_FAILED", kind === "hosted_cloud" ? "Caplets Cloud authentication failed; run caplets remote login <cloud-url>." : "Remote Caplets authentication failed; run caplets remote login <url>.");
|
|
80994
81005
|
}
|
|
80995
81006
|
function isSessionFailure(error) {
|
|
80996
81007
|
const candidate = error;
|
|
@@ -81007,6 +81018,15 @@ function isAuthFailure(error) {
|
|
|
81007
81018
|
if (status === 401 || status === 403 || statusCode === 401 || statusCode === 403 || code === 401 || code === 403) return true;
|
|
81008
81019
|
return /\b(401|403|unauthorized|forbidden)\b/iu.test(errorMessage$1(error));
|
|
81009
81020
|
}
|
|
81021
|
+
function isPermanentRemoteCredentialsError(error) {
|
|
81022
|
+
const candidate = error;
|
|
81023
|
+
if (candidate?.projectBindingCode === "remote_credentials_required" || candidate?.projectBindingCode === "remote_auth_failed") return true;
|
|
81024
|
+
if (isPlainObject(candidate?.details)) {
|
|
81025
|
+
const code = candidate.details.code;
|
|
81026
|
+
if (code === "remote_credentials_required" || code === "remote_auth_failed") return true;
|
|
81027
|
+
}
|
|
81028
|
+
return isAuthFailure(error);
|
|
81029
|
+
}
|
|
81010
81030
|
//#endregion
|
|
81011
81031
|
//#region src/cloud-auth/errors.ts
|
|
81012
81032
|
const SECRET_PATTERN = /(cap_access_[a-z0-9._~+/=-]+|cap_refresh_[a-z0-9._~+/=-]+|one_time_code_[a-z0-9._~+/=-]+|Bearer\s+)[^\s"]*/giu;
|
|
@@ -81107,7 +81127,7 @@ var CloudAuthClient = class {
|
|
|
81107
81127
|
throw new CapletsError("AUTH_FAILED", message, redactCloudAuthSecrets({
|
|
81108
81128
|
code,
|
|
81109
81129
|
message,
|
|
81110
|
-
recoveryCommand: code === "workspace_switch_required" ? "caplets cloud
|
|
81130
|
+
recoveryCommand: code === "workspace_switch_required" ? "caplets remote login <cloud-url> --workspace <workspace>" : "caplets remote login <cloud-url>",
|
|
81111
81131
|
requestId
|
|
81112
81132
|
}));
|
|
81113
81133
|
}
|
|
@@ -81147,6 +81167,78 @@ function normalizeCredentials(response, fallbackCloudUrl) {
|
|
|
81147
81167
|
};
|
|
81148
81168
|
}
|
|
81149
81169
|
//#endregion
|
|
81170
|
+
//#region src/project-binding/errors.ts
|
|
81171
|
+
const PROJECT_BINDING_ERROR_CODES = [
|
|
81172
|
+
"cloud_auth_required",
|
|
81173
|
+
"cloud_auth_expired",
|
|
81174
|
+
"cloud_auth_revoked",
|
|
81175
|
+
"workspace_selection_required",
|
|
81176
|
+
"workspace_switch_required",
|
|
81177
|
+
"workspace_forbidden",
|
|
81178
|
+
"project_binding_forbidden",
|
|
81179
|
+
"endpoint_unavailable",
|
|
81180
|
+
"websocket_upgrade_required",
|
|
81181
|
+
"sync_required",
|
|
81182
|
+
"sync_failed",
|
|
81183
|
+
"sync_size_limit_exceeded",
|
|
81184
|
+
"lease_conflict",
|
|
81185
|
+
"lease_expired",
|
|
81186
|
+
"policy_denied",
|
|
81187
|
+
"usage_limit_reached",
|
|
81188
|
+
"billing_required",
|
|
81189
|
+
"subscription_past_due",
|
|
81190
|
+
"email_verification_required",
|
|
81191
|
+
"remote_credentials_required",
|
|
81192
|
+
"remote_auth_failed"
|
|
81193
|
+
];
|
|
81194
|
+
var ProjectBindingError = class extends CapletsError {
|
|
81195
|
+
projectBindingCode;
|
|
81196
|
+
recoveryCommand;
|
|
81197
|
+
requestId;
|
|
81198
|
+
constructor(input) {
|
|
81199
|
+
super("SERVER_UNAVAILABLE", input.message, input);
|
|
81200
|
+
this.name = "ProjectBindingError";
|
|
81201
|
+
this.projectBindingCode = input.code;
|
|
81202
|
+
this.recoveryCommand = input.recoveryCommand;
|
|
81203
|
+
this.requestId = input.requestId;
|
|
81204
|
+
}
|
|
81205
|
+
};
|
|
81206
|
+
function projectBindingRecovery(code, message = defaultProjectBindingMessage(code)) {
|
|
81207
|
+
return {
|
|
81208
|
+
code,
|
|
81209
|
+
message,
|
|
81210
|
+
recoveryCommand: recoveryCommandFor(code)
|
|
81211
|
+
};
|
|
81212
|
+
}
|
|
81213
|
+
function projectBindingError(code, message) {
|
|
81214
|
+
return new ProjectBindingError(projectBindingRecovery(code, message));
|
|
81215
|
+
}
|
|
81216
|
+
function recoveryCommandFor(code) {
|
|
81217
|
+
switch (code) {
|
|
81218
|
+
case "cloud_auth_required":
|
|
81219
|
+
case "cloud_auth_expired":
|
|
81220
|
+
case "cloud_auth_revoked":
|
|
81221
|
+
case "workspace_selection_required": return "caplets remote login <cloud-url>";
|
|
81222
|
+
case "workspace_switch_required": return "caplets remote login <cloud-url> --workspace <workspace>";
|
|
81223
|
+
case "sync_size_limit_exceeded": return "Add exclusions to .capletsignore or upgrade the workspace plan.";
|
|
81224
|
+
case "remote_credentials_required":
|
|
81225
|
+
case "remote_auth_failed": return "caplets remote login <url>";
|
|
81226
|
+
case "endpoint_unavailable":
|
|
81227
|
+
case "websocket_upgrade_required": return "caplets doctor";
|
|
81228
|
+
default: return;
|
|
81229
|
+
}
|
|
81230
|
+
}
|
|
81231
|
+
function defaultProjectBindingMessage(code) {
|
|
81232
|
+
switch (code) {
|
|
81233
|
+
case "sync_size_limit_exceeded": return "Project sync size exceeds the selected workspace policy.";
|
|
81234
|
+
case "workspace_switch_required": return "The requested workspace differs from the saved Selected Workspace.";
|
|
81235
|
+
case "cloud_auth_required": return "Hosted Project Binding requires Remote Login.";
|
|
81236
|
+
case "endpoint_unavailable":
|
|
81237
|
+
case "websocket_upgrade_required": return "Project Binding endpoint is unavailable.";
|
|
81238
|
+
default: return code.replace(/_/gu, " ");
|
|
81239
|
+
}
|
|
81240
|
+
}
|
|
81241
|
+
//#endregion
|
|
81150
81242
|
//#region src/cloud-auth/store.ts
|
|
81151
81243
|
var CloudAuthStore = class {
|
|
81152
81244
|
path;
|
|
@@ -81166,7 +81258,7 @@ var CloudAuthStore = class {
|
|
|
81166
81258
|
}
|
|
81167
81259
|
};
|
|
81168
81260
|
function migrateCredentials(value) {
|
|
81169
|
-
const record = isRecord$
|
|
81261
|
+
const record = isRecord$3(value) ? value : {};
|
|
81170
81262
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
81171
81263
|
return {
|
|
81172
81264
|
version: 2,
|
|
@@ -81216,7 +81308,7 @@ function cloudAuthPath(options = {}) {
|
|
|
81216
81308
|
if (platform === "win32") return win32.join(defaultConfigBaseDir(env, home, platform), "Caplets", "cloud-auth.json");
|
|
81217
81309
|
return posix.join(defaultConfigBaseDir(env, home, platform), "caplets", "cloud-auth.json");
|
|
81218
81310
|
}
|
|
81219
|
-
function isRecord$
|
|
81311
|
+
function isRecord$3(value) {
|
|
81220
81312
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
81221
81313
|
}
|
|
81222
81314
|
function stringValue(value) {
|
|
@@ -81227,79 +81319,567 @@ function arrayValue(value) {
|
|
|
81227
81319
|
if (typeof value === "string") return value.split(/\s+/u).filter(Boolean);
|
|
81228
81320
|
}
|
|
81229
81321
|
//#endregion
|
|
81230
|
-
//#region src/
|
|
81231
|
-
|
|
81232
|
-
|
|
81233
|
-
|
|
81234
|
-
|
|
81235
|
-
|
|
81236
|
-
|
|
81237
|
-
|
|
81238
|
-
|
|
81239
|
-
|
|
81240
|
-
|
|
81241
|
-
|
|
81242
|
-
|
|
81243
|
-
|
|
81244
|
-
|
|
81245
|
-
|
|
81246
|
-
|
|
81247
|
-
|
|
81248
|
-
|
|
81249
|
-
|
|
81250
|
-
|
|
81251
|
-
|
|
81252
|
-
|
|
81253
|
-
|
|
81254
|
-
|
|
81255
|
-
|
|
81256
|
-
|
|
81257
|
-
|
|
81258
|
-
|
|
81259
|
-
|
|
81260
|
-
|
|
81261
|
-
|
|
81262
|
-
|
|
81263
|
-
|
|
81322
|
+
//#region src/remote/credential-store.ts
|
|
81323
|
+
var FileRemoteCredentialStore = class {
|
|
81324
|
+
root;
|
|
81325
|
+
constructor(options = {}) {
|
|
81326
|
+
this.root = options.root ?? join(DEFAULT_AUTH_DIR, "remote-credentials");
|
|
81327
|
+
}
|
|
81328
|
+
pathForKey(key) {
|
|
81329
|
+
return join(this.root, `${encodeURIComponent(key)}.json`);
|
|
81330
|
+
}
|
|
81331
|
+
async load(key) {
|
|
81332
|
+
const path = this.pathForKey(key);
|
|
81333
|
+
if (!existsSync(path)) return void 0;
|
|
81334
|
+
return parseRemoteProfileCredential(JSON.parse(readFileSync(path, "utf8")));
|
|
81335
|
+
}
|
|
81336
|
+
async save(key, credential) {
|
|
81337
|
+
mkdirSync(this.root, {
|
|
81338
|
+
recursive: true,
|
|
81339
|
+
mode: 448
|
|
81340
|
+
});
|
|
81341
|
+
try {
|
|
81342
|
+
chmodSync(this.root, 448);
|
|
81343
|
+
} catch {}
|
|
81344
|
+
const path = this.pathForKey(key);
|
|
81345
|
+
const tempPath = `${path}.${process.pid}.${Date.now()}.tmp`;
|
|
81346
|
+
writeFileSync(tempPath, `${JSON.stringify(credential, null, 2)}\n`, { mode: 384 });
|
|
81347
|
+
try {
|
|
81348
|
+
chmodSync(tempPath, 384);
|
|
81349
|
+
} catch {}
|
|
81350
|
+
renameSync(tempPath, path);
|
|
81351
|
+
}
|
|
81352
|
+
async delete(key) {
|
|
81353
|
+
const path = this.pathForKey(key);
|
|
81354
|
+
if (!existsSync(path)) return false;
|
|
81355
|
+
rmSync(path, { force: true });
|
|
81356
|
+
return true;
|
|
81264
81357
|
}
|
|
81265
81358
|
};
|
|
81266
|
-
function
|
|
81359
|
+
function parseRemoteProfileCredential(value) {
|
|
81360
|
+
if (!isRecord$2(value)) return void 0;
|
|
81267
81361
|
return {
|
|
81268
|
-
|
|
81269
|
-
|
|
81270
|
-
|
|
81362
|
+
...typeof value.accessToken === "string" ? { accessToken: value.accessToken } : {},
|
|
81363
|
+
...typeof value.refreshToken === "string" ? { refreshToken: value.refreshToken } : {},
|
|
81364
|
+
...typeof value.tokenType === "string" ? { tokenType: value.tokenType } : {},
|
|
81365
|
+
...typeof value.expiresAt === "string" ? { expiresAt: value.expiresAt } : {},
|
|
81366
|
+
...Array.isArray(value.scope) ? { scope: value.scope.filter((entry) => typeof entry === "string") } : {},
|
|
81367
|
+
...typeof value.clientSecret === "string" ? { clientSecret: value.clientSecret } : {},
|
|
81368
|
+
...typeof value.pairingCode === "string" ? { pairingCode: value.pairingCode } : {}
|
|
81271
81369
|
};
|
|
81272
81370
|
}
|
|
81273
|
-
function
|
|
81274
|
-
return
|
|
81371
|
+
function isRecord$2(value) {
|
|
81372
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
81275
81373
|
}
|
|
81276
|
-
|
|
81277
|
-
|
|
81278
|
-
|
|
81279
|
-
|
|
81280
|
-
|
|
81281
|
-
|
|
81282
|
-
|
|
81283
|
-
|
|
81284
|
-
|
|
81285
|
-
|
|
81286
|
-
|
|
81287
|
-
|
|
81288
|
-
|
|
81289
|
-
|
|
81374
|
+
//#endregion
|
|
81375
|
+
//#region src/remote/profiles.ts
|
|
81376
|
+
function remoteProfileKey(input) {
|
|
81377
|
+
const hostUrl = normalizeRemoteProfileHostUrl(input.hostUrl);
|
|
81378
|
+
if (input.kind === "cloud") {
|
|
81379
|
+
const workspace = input.workspace ?? hostedCloudWorkspaceFromRemoteUrl(input.hostUrl);
|
|
81380
|
+
if (!workspace) throw new CapletsError("REQUEST_INVALID", "Cloud Remote Profile requires a workspace.");
|
|
81381
|
+
return `cloud:${hostUrl}:${workspace}`;
|
|
81382
|
+
}
|
|
81383
|
+
return `self-hosted:${hostUrl}`;
|
|
81384
|
+
}
|
|
81385
|
+
function selectedWorkspaceKey(hostUrl) {
|
|
81386
|
+
return `cloud:${normalizeRemoteProfileHostUrl(hostUrl)}:selected-workspace`;
|
|
81387
|
+
}
|
|
81388
|
+
function remoteProfileStatus(input) {
|
|
81389
|
+
const hostUrl = normalizeRemoteProfileHostUrl(input.hostUrl);
|
|
81390
|
+
const key = input.key ?? remoteProfileKey({
|
|
81391
|
+
kind: input.kind,
|
|
81392
|
+
hostUrl,
|
|
81393
|
+
workspace: input.workspaceSlug ?? input.workspaceId
|
|
81394
|
+
});
|
|
81395
|
+
const expiresAt = input.credential?.expiresAt;
|
|
81396
|
+
const expired = Number.isFinite(Date.parse(expiresAt ?? "")) ? Date.parse(expiresAt ?? "") <= Date.now() : false;
|
|
81397
|
+
return {
|
|
81398
|
+
authenticated: Boolean(input.credential?.accessToken) && !expired,
|
|
81399
|
+
kind: input.kind,
|
|
81400
|
+
key,
|
|
81401
|
+
hostUrl,
|
|
81402
|
+
...input.workspaceId ? { workspaceId: input.workspaceId } : {},
|
|
81403
|
+
...input.workspaceSlug ? { workspaceSlug: input.workspaceSlug } : {},
|
|
81404
|
+
...input.clientId ? { clientId: input.clientId } : {},
|
|
81405
|
+
selected: Boolean(input.selected),
|
|
81406
|
+
...input.clientLabel ? { clientLabel: input.clientLabel } : {},
|
|
81407
|
+
...input.createdAt ? { createdAt: input.createdAt } : {},
|
|
81408
|
+
...input.updatedAt ? { updatedAt: input.updatedAt } : {},
|
|
81409
|
+
...expiresAt ? { expiresAt } : {},
|
|
81410
|
+
...input.credential?.scope ? { scope: input.credential.scope } : {},
|
|
81411
|
+
...input.credential?.tokenType ? { tokenType: input.credential.tokenType } : {}
|
|
81412
|
+
};
|
|
81290
81413
|
}
|
|
81291
|
-
|
|
81292
|
-
|
|
81293
|
-
|
|
81294
|
-
|
|
81295
|
-
|
|
81296
|
-
|
|
81297
|
-
|
|
81298
|
-
|
|
81414
|
+
//#endregion
|
|
81415
|
+
//#region src/remote/profile-store.ts
|
|
81416
|
+
const PROFILE_LOCK_DIR = "remote-profiles.lock";
|
|
81417
|
+
const PROFILE_REFRESH_LOCK_DIR = "remote-profile-refresh-locks";
|
|
81418
|
+
const PROFILE_LOCK_TIMEOUT_MS = 2e4;
|
|
81419
|
+
function createRemoteProfileStore(options = {}) {
|
|
81420
|
+
const env = options.env ?? process.env;
|
|
81421
|
+
return new FileRemoteProfileStore({
|
|
81422
|
+
root: join(options.authDir ?? (env.CAPLETS_CLOUD_AUTH_PATH ? dirname(env.CAPLETS_CLOUD_AUTH_PATH) : void 0) ?? DEFAULT_AUTH_DIR, "remote-profiles"),
|
|
81423
|
+
legacyCloudAuthStore: options.legacyCloudAuthStore ?? new CloudAuthStore(options.authDir ? { path: join(options.authDir, "cloud-auth.json") } : { env })
|
|
81424
|
+
});
|
|
81425
|
+
}
|
|
81426
|
+
function cloudCredentialsFromRemoteProfile(status, credential) {
|
|
81427
|
+
return {
|
|
81428
|
+
version: 2,
|
|
81429
|
+
cloudUrl: status.hostUrl,
|
|
81430
|
+
workspaceId: status.workspaceId ?? "",
|
|
81431
|
+
...status.workspaceSlug ? { workspaceSlug: status.workspaceSlug } : {},
|
|
81432
|
+
accessToken: credential.accessToken ?? "",
|
|
81433
|
+
refreshToken: credential.refreshToken ?? "",
|
|
81434
|
+
expiresAt: credential.expiresAt ?? (/* @__PURE__ */ new Date(0)).toISOString(),
|
|
81435
|
+
scope: credential.scope,
|
|
81436
|
+
tokenType: credential.tokenType,
|
|
81437
|
+
deviceName: status.clientLabel,
|
|
81438
|
+
createdAt: status.createdAt,
|
|
81439
|
+
lastRefreshAt: status.updatedAt
|
|
81440
|
+
};
|
|
81441
|
+
}
|
|
81442
|
+
var FileRemoteProfileStore = class {
|
|
81443
|
+
root;
|
|
81444
|
+
credentials;
|
|
81445
|
+
legacyCloudAuthStore;
|
|
81446
|
+
constructor(options = {}) {
|
|
81447
|
+
this.root = options.root ?? join(DEFAULT_AUTH_DIR, "remote-profiles");
|
|
81448
|
+
this.credentials = options.credentials ?? new FileRemoteCredentialStore({ root: join(this.root, "credentials") });
|
|
81449
|
+
this.legacyCloudAuthStore = options.legacyCloudAuthStore;
|
|
81450
|
+
}
|
|
81451
|
+
async saveSelfHostedProfile(input) {
|
|
81452
|
+
return await this.withMutationLock(async () => await this.writeSelfHostedProfile(input));
|
|
81453
|
+
}
|
|
81454
|
+
async getSelfHostedProfileStatus(input) {
|
|
81455
|
+
const key = remoteProfileKey({
|
|
81456
|
+
kind: "self-hosted",
|
|
81457
|
+
hostUrl: normalizeRemoteProfileHostUrl(input.hostUrl)
|
|
81458
|
+
});
|
|
81459
|
+
return this.statusByKey(key, false);
|
|
81460
|
+
}
|
|
81461
|
+
async logoutSelfHostedProfile(input) {
|
|
81462
|
+
return await this.withMutationLock(async () => {
|
|
81463
|
+
const key = remoteProfileKey({
|
|
81464
|
+
kind: "self-hosted",
|
|
81465
|
+
hostUrl: normalizeRemoteProfileHostUrl(input.hostUrl)
|
|
81466
|
+
});
|
|
81467
|
+
if (!this.readProfile(key)) return false;
|
|
81468
|
+
await this.credentials.delete(key);
|
|
81469
|
+
rmSync(this.profilePath(key), { force: true });
|
|
81470
|
+
return true;
|
|
81471
|
+
});
|
|
81472
|
+
}
|
|
81473
|
+
async refreshSelfHostedProfileIfNeeded(input) {
|
|
81474
|
+
const key = remoteProfileKey({
|
|
81475
|
+
kind: "self-hosted",
|
|
81476
|
+
hostUrl: normalizeRemoteProfileHostUrl(input.hostUrl)
|
|
81477
|
+
});
|
|
81478
|
+
return await this.withRefreshLock(key, async () => {
|
|
81479
|
+
const snapshot = await this.withMutationLock(async () => this.selfHostedRefreshSnapshot(key, input));
|
|
81480
|
+
if (!snapshot || !snapshot.needsRefresh) return snapshot?.result;
|
|
81481
|
+
const refreshed = await input.refresh(snapshot.result.status, snapshot.result.credential);
|
|
81482
|
+
return await this.withMutationLock(async () => {
|
|
81483
|
+
const current = await this.selfHostedRefreshSnapshot(key, input);
|
|
81484
|
+
if (!current || !current.needsRefresh) return current?.result;
|
|
81485
|
+
const refreshedStatus = await this.writeSelfHostedProfile(refreshed);
|
|
81486
|
+
const refreshedCredential = await this.credentials.load(refreshedStatus.key);
|
|
81487
|
+
if (!refreshedCredential?.accessToken) return void 0;
|
|
81488
|
+
return {
|
|
81489
|
+
status: refreshedStatus,
|
|
81490
|
+
credential: refreshedCredential
|
|
81491
|
+
};
|
|
81492
|
+
});
|
|
81493
|
+
});
|
|
81494
|
+
}
|
|
81495
|
+
async refreshCloudProfileIfNeeded(input) {
|
|
81496
|
+
const snapshot = await this.withMutationLock(async () => this.cloudRefreshSnapshot(input));
|
|
81497
|
+
if (!snapshot || !snapshot.needsRefresh) return snapshot?.result;
|
|
81498
|
+
return await this.withRefreshLock(snapshot.result.status.key, async () => {
|
|
81499
|
+
const lockedSnapshot = await this.withMutationLock(async () => this.cloudRefreshSnapshot(input));
|
|
81500
|
+
if (!lockedSnapshot || !lockedSnapshot.needsRefresh) return lockedSnapshot?.result;
|
|
81501
|
+
const refreshed = await input.refresh(lockedSnapshot.result.status, lockedSnapshot.result.credential);
|
|
81502
|
+
return await this.withMutationLock(async () => {
|
|
81503
|
+
const current = await this.cloudRefreshSnapshot(input);
|
|
81504
|
+
if (!current || !current.needsRefresh) return current?.result;
|
|
81505
|
+
const refreshedStatus = await this.writeCloudProfile(refreshed, { select: current.result.status.selected });
|
|
81506
|
+
const refreshedCredential = await this.credentials.load(refreshedStatus.key);
|
|
81507
|
+
if (!refreshedCredential?.accessToken) return void 0;
|
|
81508
|
+
return {
|
|
81509
|
+
status: refreshedStatus,
|
|
81510
|
+
credential: refreshedCredential
|
|
81511
|
+
};
|
|
81512
|
+
});
|
|
81513
|
+
});
|
|
81514
|
+
}
|
|
81515
|
+
async saveCloudProfile(input) {
|
|
81516
|
+
return await this.withMutationLock(async () => await this.writeCloudProfile(input));
|
|
81517
|
+
}
|
|
81518
|
+
async getCloudProfileStatus(input) {
|
|
81519
|
+
const hostUrl = normalizeRemoteProfileHostUrl(input.hostUrl);
|
|
81520
|
+
const workspace = input.workspace ?? hostedCloudWorkspaceFromRemoteUrl(input.hostUrl);
|
|
81521
|
+
if (workspace) {
|
|
81522
|
+
const found = await this.findCloudStatus(hostUrl, workspace);
|
|
81523
|
+
if (found) return found;
|
|
81524
|
+
return this.migrateLegacyCloudProfile(hostUrl, workspace);
|
|
81525
|
+
}
|
|
81526
|
+
const selected = this.readSelectedWorkspace(hostUrl);
|
|
81527
|
+
if (selected) return this.statusByKey(selected.profileKey, true);
|
|
81528
|
+
if (this.listProfilesForHost(hostUrl).length > 0) throw new CapletsError("REQUEST_INVALID", "Cloud Remote Profile requires a selected or explicit workspace.");
|
|
81529
|
+
return this.migrateLegacyCloudProfile(hostUrl);
|
|
81530
|
+
}
|
|
81531
|
+
async listCloudProfileStatuses(hostUrlInput) {
|
|
81532
|
+
const hostUrl = normalizeRemoteProfileHostUrl(hostUrlInput);
|
|
81533
|
+
const selected = this.readSelectedWorkspace(hostUrl)?.profileKey;
|
|
81534
|
+
return (await Promise.all(this.listProfilesForHost(hostUrl).map(async (profile) => this.statusFor(profile, void 0, profile.key === selected)))).sort((left, right) => (left.workspaceSlug ?? left.workspaceId ?? "").localeCompare(right.workspaceSlug ?? right.workspaceId ?? ""));
|
|
81535
|
+
}
|
|
81536
|
+
async listProfileStatuses() {
|
|
81537
|
+
const dir = this.profilesDir();
|
|
81538
|
+
if (!existsSync(dir)) return [];
|
|
81539
|
+
return (await Promise.all(readdirSync(dir, { withFileTypes: true }).filter((entry) => entry.isFile() && entry.name.endsWith(".json")).map((entry) => this.readProfileFile(join(dir, entry.name))).filter((profile) => Boolean(profile)).map(async (profile) => {
|
|
81540
|
+
const selected = profile.kind === "cloud" ? this.readSelectedWorkspace(profile.hostUrl)?.profileKey === profile.key : false;
|
|
81541
|
+
return await this.statusFor(profile, void 0, selected);
|
|
81542
|
+
}))).sort((left, right) => {
|
|
81543
|
+
const host = left.hostUrl.localeCompare(right.hostUrl);
|
|
81544
|
+
if (host !== 0) return host;
|
|
81545
|
+
return (left.workspaceSlug ?? left.workspaceId ?? "").localeCompare(right.workspaceSlug ?? right.workspaceId ?? "");
|
|
81546
|
+
});
|
|
81547
|
+
}
|
|
81548
|
+
async logoutCloudProfile(input) {
|
|
81549
|
+
return await this.withMutationLock(async () => {
|
|
81550
|
+
const hostUrl = normalizeRemoteProfileHostUrl(input.hostUrl);
|
|
81551
|
+
const workspace = input.workspace ?? hostedCloudWorkspaceFromRemoteUrl(input.hostUrl);
|
|
81552
|
+
const selected = this.readSelectedWorkspace(hostUrl);
|
|
81553
|
+
let key;
|
|
81554
|
+
if (workspace) key = this.listProfilesForHost(hostUrl).find((profile) => profileMatchesWorkspace(profile, workspace))?.key;
|
|
81555
|
+
else if (selected) key = selected.profileKey;
|
|
81556
|
+
else if (this.listProfilesForHost(hostUrl).length > 0) throw new CapletsError("REQUEST_INVALID", "Cloud Remote Profile requires a selected or explicit workspace.");
|
|
81557
|
+
if (!key) return false;
|
|
81558
|
+
const profile = this.readProfile(key);
|
|
81559
|
+
await this.credentials.delete(key);
|
|
81560
|
+
rmSync(this.profilePath(key), { force: true });
|
|
81561
|
+
if (selected?.profileKey === key) rmSync(this.selectedWorkspacePath(hostUrl), { force: true });
|
|
81562
|
+
await this.clearMatchingLegacyCloudAuth(hostUrl, profile);
|
|
81563
|
+
return true;
|
|
81564
|
+
});
|
|
81565
|
+
}
|
|
81566
|
+
async clearSelectedCloudWorkspace(hostUrlInput) {
|
|
81567
|
+
return await this.withMutationLock(async () => {
|
|
81568
|
+
const path = this.selectedWorkspacePath(normalizeRemoteProfileHostUrl(hostUrlInput));
|
|
81569
|
+
if (!existsSync(path)) return false;
|
|
81570
|
+
rmSync(path, { force: true });
|
|
81571
|
+
return true;
|
|
81572
|
+
});
|
|
81573
|
+
}
|
|
81574
|
+
async selfHostedRefreshSnapshot(key, input) {
|
|
81575
|
+
const profile = this.readProfile(key);
|
|
81576
|
+
if (!profile) return void 0;
|
|
81577
|
+
const credential = await this.credentials.load(key);
|
|
81578
|
+
if (!credential?.accessToken) return void 0;
|
|
81579
|
+
const status = await this.statusFor(profile, credential, false);
|
|
81580
|
+
return {
|
|
81581
|
+
needsRefresh: input.needsRefresh(credential),
|
|
81582
|
+
result: {
|
|
81583
|
+
status,
|
|
81584
|
+
credential
|
|
81585
|
+
}
|
|
81586
|
+
};
|
|
81587
|
+
}
|
|
81588
|
+
async cloudRefreshSnapshot(input) {
|
|
81589
|
+
const hostUrl = normalizeRemoteProfileHostUrl(input.hostUrl);
|
|
81590
|
+
const workspace = input.workspace ?? hostedCloudWorkspaceFromRemoteUrl(input.hostUrl);
|
|
81591
|
+
let status;
|
|
81592
|
+
if (workspace) status = await this.findCloudStatus(hostUrl, workspace);
|
|
81593
|
+
else {
|
|
81594
|
+
const selected = this.readSelectedWorkspace(hostUrl);
|
|
81595
|
+
if (selected) status = await this.statusByKey(selected.profileKey, true);
|
|
81596
|
+
else if (this.listProfilesForHost(hostUrl).length > 0) throw new CapletsError("REQUEST_INVALID", "Cloud Remote Profile requires a selected or explicit workspace.");
|
|
81597
|
+
}
|
|
81598
|
+
if (!status) return void 0;
|
|
81599
|
+
const credential = await this.credentials.load(status.key);
|
|
81600
|
+
if (!credential?.accessToken) return void 0;
|
|
81601
|
+
return {
|
|
81602
|
+
needsRefresh: input.needsRefresh(credential),
|
|
81603
|
+
result: {
|
|
81604
|
+
status,
|
|
81605
|
+
credential
|
|
81606
|
+
}
|
|
81607
|
+
};
|
|
81608
|
+
}
|
|
81609
|
+
async findCloudStatus(hostUrl, workspace) {
|
|
81610
|
+
const selected = this.readSelectedWorkspace(hostUrl)?.profileKey;
|
|
81611
|
+
const profile = this.listProfilesForHost(hostUrl).find((candidate) => profileMatchesWorkspace(candidate, workspace));
|
|
81612
|
+
if (!profile) return void 0;
|
|
81613
|
+
return this.statusFor(profile, void 0, profile.key === selected);
|
|
81614
|
+
}
|
|
81615
|
+
async migrateLegacyCloudProfile(hostUrl, workspace) {
|
|
81616
|
+
const legacy = await this.legacyCloudAuthStore?.load();
|
|
81617
|
+
if (!legacy) return void 0;
|
|
81618
|
+
if (normalizeRemoteProfileHostUrl(legacy.cloudUrl) !== hostUrl) return void 0;
|
|
81619
|
+
if (workspace && workspace !== legacy.workspaceSlug && workspace !== legacy.workspaceId) return;
|
|
81620
|
+
return this.saveCloudProfile({
|
|
81621
|
+
hostUrl,
|
|
81622
|
+
workspaceId: legacy.workspaceId,
|
|
81623
|
+
...legacy.workspaceSlug ? { workspaceSlug: legacy.workspaceSlug } : {},
|
|
81624
|
+
clientLabel: legacy.deviceName,
|
|
81625
|
+
credentials: legacyCredential(legacy),
|
|
81626
|
+
now: legacy.createdAt ? new Date(legacy.createdAt) : void 0
|
|
81627
|
+
});
|
|
81628
|
+
}
|
|
81629
|
+
async clearMatchingLegacyCloudAuth(hostUrl, profile) {
|
|
81630
|
+
const legacy = await this.legacyCloudAuthStore?.load();
|
|
81631
|
+
if (!legacy) return;
|
|
81632
|
+
if (normalizeRemoteProfileHostUrl(legacy.cloudUrl) !== hostUrl) return;
|
|
81633
|
+
if (!profile) return;
|
|
81634
|
+
const workspaceIdMatches = legacy.workspaceId === profile.workspaceId;
|
|
81635
|
+
const workspaceSlugMatches = Boolean(legacy.workspaceSlug && profile.workspaceSlug && legacy.workspaceSlug === profile.workspaceSlug);
|
|
81636
|
+
if (!workspaceIdMatches && !workspaceSlugMatches) return;
|
|
81637
|
+
await this.legacyCloudAuthStore?.clear();
|
|
81638
|
+
}
|
|
81639
|
+
async statusByKey(key, selected) {
|
|
81640
|
+
const profile = this.readProfile(key);
|
|
81641
|
+
if (!profile) return void 0;
|
|
81642
|
+
return this.statusFor(profile, void 0, selected);
|
|
81643
|
+
}
|
|
81644
|
+
async statusFor(profile, credential, selected) {
|
|
81645
|
+
const build = (loadedCredential) => remoteProfileStatus({
|
|
81646
|
+
kind: profile.kind,
|
|
81647
|
+
key: profile.key,
|
|
81648
|
+
hostUrl: profile.hostUrl,
|
|
81649
|
+
workspaceId: profile.workspaceId,
|
|
81650
|
+
workspaceSlug: profile.workspaceSlug,
|
|
81651
|
+
clientId: profile.clientId,
|
|
81652
|
+
clientLabel: profile.clientLabel,
|
|
81653
|
+
createdAt: profile.createdAt,
|
|
81654
|
+
updatedAt: profile.updatedAt,
|
|
81655
|
+
selected,
|
|
81656
|
+
credential: loadedCredential
|
|
81657
|
+
});
|
|
81658
|
+
if (credential !== void 0) return build(credential);
|
|
81659
|
+
return build(await this.credentials.load(profile.key));
|
|
81660
|
+
}
|
|
81661
|
+
async writeSelfHostedProfile(input) {
|
|
81662
|
+
const hostUrl = normalizeRemoteProfileHostUrl(input.hostUrl);
|
|
81663
|
+
const key = remoteProfileKey({
|
|
81664
|
+
kind: "self-hosted",
|
|
81665
|
+
hostUrl
|
|
81666
|
+
});
|
|
81667
|
+
const now = (input.now ?? /* @__PURE__ */ new Date()).toISOString();
|
|
81668
|
+
const existing = this.readProfile(key);
|
|
81669
|
+
const profile = {
|
|
81670
|
+
version: 1,
|
|
81671
|
+
kind: "self-hosted",
|
|
81672
|
+
key,
|
|
81673
|
+
hostUrl,
|
|
81674
|
+
clientId: input.clientId,
|
|
81675
|
+
...input.clientLabel ? { clientLabel: input.clientLabel } : {},
|
|
81676
|
+
createdAt: existing?.createdAt ?? now,
|
|
81677
|
+
updatedAt: now
|
|
81678
|
+
};
|
|
81679
|
+
await this.credentials.save(key, input.credentials);
|
|
81680
|
+
this.writeJson(this.profilePath(key), profile);
|
|
81681
|
+
return await this.statusFor(profile, input.credentials, false);
|
|
81682
|
+
}
|
|
81683
|
+
async writeCloudProfile(input, options = {}) {
|
|
81684
|
+
const hostUrl = normalizeRemoteProfileHostUrl(input.hostUrl);
|
|
81685
|
+
const workspace = cloudWorkspace(input);
|
|
81686
|
+
const key = remoteProfileKey({
|
|
81687
|
+
kind: "cloud",
|
|
81688
|
+
hostUrl,
|
|
81689
|
+
workspace
|
|
81690
|
+
});
|
|
81691
|
+
const now = (input.now ?? /* @__PURE__ */ new Date()).toISOString();
|
|
81692
|
+
const existing = this.readProfile(key);
|
|
81693
|
+
const select = options.select ?? true;
|
|
81694
|
+
const profile = {
|
|
81695
|
+
version: 1,
|
|
81696
|
+
kind: "cloud",
|
|
81697
|
+
key,
|
|
81698
|
+
hostUrl,
|
|
81699
|
+
workspaceId: input.workspaceId,
|
|
81700
|
+
...input.workspaceSlug ? { workspaceSlug: input.workspaceSlug } : {},
|
|
81701
|
+
...input.clientLabel ? { clientLabel: input.clientLabel } : {},
|
|
81702
|
+
createdAt: existing?.createdAt ?? now,
|
|
81703
|
+
updatedAt: now
|
|
81704
|
+
};
|
|
81705
|
+
await this.credentials.save(key, input.credentials);
|
|
81706
|
+
this.writeJson(this.profilePath(key), profile);
|
|
81707
|
+
if (select) this.writeJson(this.selectedWorkspacePath(hostUrl), {
|
|
81708
|
+
version: 1,
|
|
81709
|
+
hostUrl,
|
|
81710
|
+
workspace,
|
|
81711
|
+
profileKey: key,
|
|
81712
|
+
selectedAt: now
|
|
81713
|
+
});
|
|
81714
|
+
return await this.statusFor(profile, input.credentials, select);
|
|
81715
|
+
}
|
|
81716
|
+
listProfilesForHost(hostUrl) {
|
|
81717
|
+
const dir = this.profilesDir();
|
|
81718
|
+
if (!existsSync(dir)) return [];
|
|
81719
|
+
return readdirSync(dir, { withFileTypes: true }).filter((entry) => entry.isFile() && entry.name.endsWith(".json")).map((entry) => this.readProfileFile(join(dir, entry.name))).filter((profile) => Boolean(profile)).filter((profile) => profile.kind === "cloud" && profile.hostUrl === hostUrl);
|
|
81720
|
+
}
|
|
81721
|
+
readProfile(key) {
|
|
81722
|
+
return this.readProfileFile(this.profilePath(key));
|
|
81723
|
+
}
|
|
81724
|
+
readProfileFile(path) {
|
|
81725
|
+
if (!existsSync(path)) return void 0;
|
|
81726
|
+
return parseStoredRemoteProfile(JSON.parse(readFileSync(path, "utf8")));
|
|
81727
|
+
}
|
|
81728
|
+
readSelectedWorkspace(hostUrl) {
|
|
81729
|
+
const path = this.selectedWorkspacePath(hostUrl);
|
|
81730
|
+
if (!existsSync(path)) return void 0;
|
|
81731
|
+
return parseSelectedCloudWorkspace(JSON.parse(readFileSync(path, "utf8")), hostUrl);
|
|
81732
|
+
}
|
|
81733
|
+
profilePath(key) {
|
|
81734
|
+
return join(this.profilesDir(), `${encodeURIComponent(key)}.json`);
|
|
81299
81735
|
}
|
|
81736
|
+
selectedWorkspacePath(hostUrl) {
|
|
81737
|
+
return join(this.selectionsDir(), `${encodeURIComponent(selectedWorkspaceKey(hostUrl))}.json`);
|
|
81738
|
+
}
|
|
81739
|
+
profilesDir() {
|
|
81740
|
+
return join(this.root, "profiles");
|
|
81741
|
+
}
|
|
81742
|
+
selectionsDir() {
|
|
81743
|
+
return join(this.root, "selections");
|
|
81744
|
+
}
|
|
81745
|
+
writeJson(path, value) {
|
|
81746
|
+
const directory = dirname(path);
|
|
81747
|
+
mkdirSync(directory, {
|
|
81748
|
+
recursive: true,
|
|
81749
|
+
mode: 448
|
|
81750
|
+
});
|
|
81751
|
+
try {
|
|
81752
|
+
chmodSync(directory, 448);
|
|
81753
|
+
} catch {}
|
|
81754
|
+
const tempPath = `${path}.${process.pid}.${Date.now()}.tmp`;
|
|
81755
|
+
writeFileSync(tempPath, `${JSON.stringify(value, null, 2)}\n`, { mode: 384 });
|
|
81756
|
+
try {
|
|
81757
|
+
chmodSync(tempPath, 384);
|
|
81758
|
+
} catch {}
|
|
81759
|
+
renameSync(tempPath, path);
|
|
81760
|
+
}
|
|
81761
|
+
async withMutationLock(operation) {
|
|
81762
|
+
await this.acquireLock(this.lockPath(), "Remote Profile store is locked.");
|
|
81763
|
+
try {
|
|
81764
|
+
return await operation();
|
|
81765
|
+
} finally {
|
|
81766
|
+
this.releaseLock(this.lockPath());
|
|
81767
|
+
}
|
|
81768
|
+
}
|
|
81769
|
+
async withRefreshLock(key, operation) {
|
|
81770
|
+
const lockPath = this.refreshLockPath(key);
|
|
81771
|
+
await this.acquireLock(lockPath, "Remote Profile refresh is locked.");
|
|
81772
|
+
try {
|
|
81773
|
+
return await operation();
|
|
81774
|
+
} finally {
|
|
81775
|
+
this.releaseLock(lockPath);
|
|
81776
|
+
}
|
|
81777
|
+
}
|
|
81778
|
+
async acquireLock(lockPath, message) {
|
|
81779
|
+
mkdirSync(this.root, {
|
|
81780
|
+
recursive: true,
|
|
81781
|
+
mode: 448
|
|
81782
|
+
});
|
|
81783
|
+
mkdirSync(dirname(lockPath), {
|
|
81784
|
+
recursive: true,
|
|
81785
|
+
mode: 448
|
|
81786
|
+
});
|
|
81787
|
+
const started = Date.now();
|
|
81788
|
+
while (true) try {
|
|
81789
|
+
mkdirSync(lockPath, {
|
|
81790
|
+
recursive: false,
|
|
81791
|
+
mode: 448
|
|
81792
|
+
});
|
|
81793
|
+
return;
|
|
81794
|
+
} catch (error) {
|
|
81795
|
+
if (isFileExistsError(error) && this.clearStaleLock(lockPath)) continue;
|
|
81796
|
+
if (!isFileExistsError(error) || Date.now() - started >= PROFILE_LOCK_TIMEOUT_MS) throw new CapletsError("SERVER_UNAVAILABLE", message);
|
|
81797
|
+
await sleep(10);
|
|
81798
|
+
}
|
|
81799
|
+
}
|
|
81800
|
+
releaseLock(lockPath) {
|
|
81801
|
+
rmSync(lockPath, {
|
|
81802
|
+
recursive: true,
|
|
81803
|
+
force: true
|
|
81804
|
+
});
|
|
81805
|
+
}
|
|
81806
|
+
clearStaleLock(lockPath) {
|
|
81807
|
+
try {
|
|
81808
|
+
if (Date.now() - statSync(lockPath).mtimeMs < PROFILE_LOCK_TIMEOUT_MS) return false;
|
|
81809
|
+
rmSync(lockPath, {
|
|
81810
|
+
recursive: true,
|
|
81811
|
+
force: true
|
|
81812
|
+
});
|
|
81813
|
+
return true;
|
|
81814
|
+
} catch {
|
|
81815
|
+
return false;
|
|
81816
|
+
}
|
|
81817
|
+
}
|
|
81818
|
+
lockPath() {
|
|
81819
|
+
return join(this.root, PROFILE_LOCK_DIR);
|
|
81820
|
+
}
|
|
81821
|
+
refreshLockPath(key) {
|
|
81822
|
+
return join(this.root, PROFILE_REFRESH_LOCK_DIR, `${encodeURIComponent(key)}.lock`);
|
|
81823
|
+
}
|
|
81824
|
+
};
|
|
81825
|
+
async function sleep(ms) {
|
|
81826
|
+
await new Promise((resolve) => setTimeout(resolve, ms));
|
|
81827
|
+
}
|
|
81828
|
+
function isFileExistsError(error) {
|
|
81829
|
+
return typeof error === "object" && error !== null && "code" in error && error.code === "EEXIST";
|
|
81830
|
+
}
|
|
81831
|
+
function cloudWorkspace(input) {
|
|
81832
|
+
return input.workspaceSlug ?? input.workspaceId ?? hostedCloudWorkspaceFromRemoteUrl(input.hostUrl) ?? "";
|
|
81833
|
+
}
|
|
81834
|
+
function profileMatchesWorkspace(profile, workspace) {
|
|
81835
|
+
return profile.workspaceSlug === workspace || profile.workspaceId === workspace;
|
|
81836
|
+
}
|
|
81837
|
+
function legacyCredential(credentials) {
|
|
81838
|
+
return {
|
|
81839
|
+
accessToken: credentials.accessToken,
|
|
81840
|
+
refreshToken: credentials.refreshToken,
|
|
81841
|
+
expiresAt: credentials.expiresAt,
|
|
81842
|
+
...credentials.scope ? { scope: credentials.scope } : {},
|
|
81843
|
+
...credentials.tokenType ? { tokenType: credentials.tokenType } : {}
|
|
81844
|
+
};
|
|
81845
|
+
}
|
|
81846
|
+
function parseStoredRemoteProfile(value) {
|
|
81847
|
+
if (!isRecord$1(value)) return void 0;
|
|
81848
|
+
if (value.version !== 1) return void 0;
|
|
81849
|
+
if (value.kind !== "cloud" && value.kind !== "self-hosted") return void 0;
|
|
81850
|
+
if (typeof value.key !== "string" || typeof value.hostUrl !== "string" || typeof value.createdAt !== "string" || typeof value.updatedAt !== "string") return;
|
|
81851
|
+
if (value.kind === "cloud" && typeof value.workspaceId !== "string") return void 0;
|
|
81852
|
+
if (value.kind === "self-hosted" && typeof value.clientId !== "string") return void 0;
|
|
81853
|
+
return {
|
|
81854
|
+
version: 1,
|
|
81855
|
+
kind: value.kind,
|
|
81856
|
+
key: value.key,
|
|
81857
|
+
hostUrl: value.hostUrl,
|
|
81858
|
+
...typeof value.workspaceId === "string" ? { workspaceId: value.workspaceId } : {},
|
|
81859
|
+
...typeof value.workspaceSlug === "string" ? { workspaceSlug: value.workspaceSlug } : {},
|
|
81860
|
+
...typeof value.clientId === "string" ? { clientId: value.clientId } : {},
|
|
81861
|
+
...typeof value.clientLabel === "string" ? { clientLabel: value.clientLabel } : {},
|
|
81862
|
+
createdAt: value.createdAt,
|
|
81863
|
+
updatedAt: value.updatedAt
|
|
81864
|
+
};
|
|
81865
|
+
}
|
|
81866
|
+
function parseSelectedCloudWorkspace(value, expectedHostUrl) {
|
|
81867
|
+
if (!isRecord$1(value)) return void 0;
|
|
81868
|
+
if (value.version !== 1 || value.hostUrl !== expectedHostUrl || typeof value.workspace !== "string" || typeof value.profileKey !== "string" || typeof value.selectedAt !== "string") return;
|
|
81869
|
+
return {
|
|
81870
|
+
version: 1,
|
|
81871
|
+
hostUrl: value.hostUrl,
|
|
81872
|
+
workspace: value.workspace,
|
|
81873
|
+
profileKey: value.profileKey,
|
|
81874
|
+
selectedAt: value.selectedAt
|
|
81875
|
+
};
|
|
81876
|
+
}
|
|
81877
|
+
function isRecord$1(value) {
|
|
81878
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
81300
81879
|
}
|
|
81301
81880
|
//#endregion
|
|
81302
81881
|
//#region src/remote/selection.ts
|
|
81882
|
+
const SELF_HOSTED_REFRESH_TIMEOUT_MS = 15e3;
|
|
81303
81883
|
async function resolveRemoteSelection(input = {}, env = process.env) {
|
|
81304
81884
|
const modeValue = input.mode ?? env.CAPLETS_MODE;
|
|
81305
81885
|
const mode = resolveRemoteMode({
|
|
@@ -81307,43 +81887,112 @@ async function resolveRemoteSelection(input = {}, env = process.env) {
|
|
|
81307
81887
|
...input.remoteUrl !== void 0 ? { remoteUrl: input.remoteUrl } : {}
|
|
81308
81888
|
}, env);
|
|
81309
81889
|
if (mode.mode === "local") throw new CapletsError("REQUEST_INVALID", "caplets attach requires a remote upstream; set CAPLETS_REMOTE_URL or use caplets serve for local-only MCP.");
|
|
81310
|
-
if (mode.mode === "remote")
|
|
81311
|
-
|
|
81312
|
-
|
|
81313
|
-
|
|
81314
|
-
|
|
81315
|
-
|
|
81316
|
-
|
|
81317
|
-
|
|
81318
|
-
|
|
81319
|
-
|
|
81320
|
-
|
|
81321
|
-
|
|
81322
|
-
|
|
81323
|
-
|
|
81324
|
-
|
|
81325
|
-
|
|
81326
|
-
|
|
81327
|
-
|
|
81328
|
-
|
|
81329
|
-
|
|
81330
|
-
|
|
81331
|
-
|
|
81332
|
-
|
|
81333
|
-
|
|
81334
|
-
|
|
81335
|
-
|
|
81890
|
+
if (mode.mode === "remote") {
|
|
81891
|
+
const remoteUrl = input.remoteUrl ?? env.CAPLETS_REMOTE_URL;
|
|
81892
|
+
if (!remoteUrl) throw new CapletsError("REQUEST_INVALID", "CAPLETS_REMOTE_URL or remoteUrl is required.");
|
|
81893
|
+
const credential = (await createRemoteProfileStore({
|
|
81894
|
+
authDir: input.authDir,
|
|
81895
|
+
env
|
|
81896
|
+
}).refreshSelfHostedProfileIfNeeded({
|
|
81897
|
+
hostUrl: remoteUrl,
|
|
81898
|
+
needsRefresh: (credential) => credentialsNeedRefresh({ expiresAt: credential.expiresAt ?? "" }),
|
|
81899
|
+
refresh: async (status, credential) => {
|
|
81900
|
+
if (!credential.refreshToken || !status.clientId) throw remoteLoginRequired(remoteUrl);
|
|
81901
|
+
const refreshed = await refreshSelfHostedCredentials(remoteUrl, credential.refreshToken, input.fetch ? { fetch: input.fetch } : {});
|
|
81902
|
+
return {
|
|
81903
|
+
hostUrl: refreshed.hostUrl ?? remoteUrl,
|
|
81904
|
+
clientId: refreshed.clientId,
|
|
81905
|
+
clientLabel: refreshed.clientLabel ?? status.clientLabel,
|
|
81906
|
+
credentials: {
|
|
81907
|
+
accessToken: refreshed.accessToken,
|
|
81908
|
+
refreshToken: refreshed.refreshToken,
|
|
81909
|
+
expiresAt: refreshed.expiresAt,
|
|
81910
|
+
tokenType: refreshed.tokenType
|
|
81911
|
+
}
|
|
81912
|
+
};
|
|
81913
|
+
}
|
|
81914
|
+
}))?.credential;
|
|
81915
|
+
if (!credential?.accessToken) {
|
|
81916
|
+
const normalizedUrl = normalizeRemoteProfileHostUrl(remoteUrl);
|
|
81917
|
+
throw new ProjectBindingError({
|
|
81918
|
+
code: "remote_credentials_required",
|
|
81919
|
+
message: `Remote Login required for ${normalizedUrl}.`,
|
|
81920
|
+
recoveryCommand: `caplets remote login ${normalizedUrl}`
|
|
81921
|
+
});
|
|
81922
|
+
}
|
|
81923
|
+
return {
|
|
81924
|
+
kind: "self_hosted_remote",
|
|
81925
|
+
remote: resolveCapletsRemote({
|
|
81926
|
+
url: remoteUrl,
|
|
81927
|
+
token: credential.accessToken,
|
|
81928
|
+
...input.workspace !== void 0 ? { workspace: input.workspace } : {},
|
|
81929
|
+
...input.fetch !== void 0 ? { fetch: input.fetch } : {}
|
|
81930
|
+
}, env),
|
|
81931
|
+
...credential.expiresAt ? { credentialExpiresAt: credential.expiresAt } : {}
|
|
81336
81932
|
};
|
|
81337
|
-
await store.save(credentials);
|
|
81338
81933
|
}
|
|
81339
|
-
const
|
|
81340
|
-
|
|
81934
|
+
const store = createRemoteProfileStore({
|
|
81935
|
+
authDir: input.authDir,
|
|
81936
|
+
env
|
|
81937
|
+
});
|
|
81341
81938
|
const remoteUrl = input.remoteUrl ?? env.CAPLETS_REMOTE_URL;
|
|
81342
81939
|
if (!remoteUrl) throw new CapletsError("REQUEST_INVALID", "CAPLETS_MODE=cloud requires CAPLETS_REMOTE_URL or remoteUrl.");
|
|
81343
81940
|
const workspaceFromRemoteUrl = hostedCloudWorkspaceFromRemoteUrl(remoteUrl);
|
|
81941
|
+
const explicitWorkspace = input.workspace ?? (workspaceFromRemoteUrl ? void 0 : env.CAPLETS_REMOTE_WORKSPACE);
|
|
81942
|
+
const profileWorkspace = workspaceFromRemoteUrl ?? explicitWorkspace;
|
|
81943
|
+
const normalizedRemoteUrl = normalizeRemoteProfileHostUrl(remoteUrl);
|
|
81944
|
+
let status = await store.getCloudProfileStatus({
|
|
81945
|
+
hostUrl: normalizedRemoteUrl,
|
|
81946
|
+
workspace: profileWorkspace
|
|
81947
|
+
});
|
|
81948
|
+
if (!status && profileWorkspace) status = await store.getCloudProfileStatus({ hostUrl: normalizedRemoteUrl });
|
|
81949
|
+
let credential = status ? await store.credentials.load(status.key) : void 0;
|
|
81950
|
+
if (!status || !credential?.accessToken) throw projectBindingError("cloud_auth_required");
|
|
81951
|
+
let credentials = cloudCredentialsFromRemoteProfile(status, credential);
|
|
81952
|
+
if (credentialsNeedRefresh(credentials)) {
|
|
81953
|
+
const refreshed = await store.refreshCloudProfileIfNeeded({
|
|
81954
|
+
hostUrl: normalizedRemoteUrl,
|
|
81955
|
+
workspace: profileWorkspace,
|
|
81956
|
+
needsRefresh: (candidate) => credentialsNeedRefresh({ expiresAt: candidate.expiresAt ?? "" }),
|
|
81957
|
+
refresh: async (candidateStatus, candidateCredential) => {
|
|
81958
|
+
const candidateCredentials = cloudCredentialsFromRemoteProfile(candidateStatus, candidateCredential);
|
|
81959
|
+
if (!candidateCredentials.refreshToken) throw projectBindingError("cloud_auth_required");
|
|
81960
|
+
const refreshedCredentials = await new CloudAuthClient({
|
|
81961
|
+
cloudUrl: candidateCredentials.cloudUrl,
|
|
81962
|
+
...input.fetch !== void 0 ? { fetch: input.fetch } : {}
|
|
81963
|
+
}).refresh({ refreshToken: candidateCredentials.refreshToken });
|
|
81964
|
+
const nextCredentials = {
|
|
81965
|
+
...candidateCredentials,
|
|
81966
|
+
...refreshedCredentials,
|
|
81967
|
+
refreshToken: refreshedCredentials.refreshToken ?? candidateCredentials.refreshToken,
|
|
81968
|
+
createdAt: candidateCredentials.createdAt,
|
|
81969
|
+
lastRefreshAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
81970
|
+
};
|
|
81971
|
+
return {
|
|
81972
|
+
hostUrl: nextCredentials.cloudUrl,
|
|
81973
|
+
workspaceId: nextCredentials.workspaceId,
|
|
81974
|
+
...nextCredentials.workspaceSlug ? { workspaceSlug: nextCredentials.workspaceSlug } : {},
|
|
81975
|
+
clientLabel: nextCredentials.deviceName,
|
|
81976
|
+
credentials: {
|
|
81977
|
+
accessToken: nextCredentials.accessToken,
|
|
81978
|
+
refreshToken: nextCredentials.refreshToken,
|
|
81979
|
+
expiresAt: nextCredentials.expiresAt,
|
|
81980
|
+
scope: nextCredentials.scope,
|
|
81981
|
+
tokenType: nextCredentials.tokenType
|
|
81982
|
+
}
|
|
81983
|
+
};
|
|
81984
|
+
}
|
|
81985
|
+
});
|
|
81986
|
+
if (!refreshed?.credential?.accessToken) throw projectBindingError("cloud_auth_required");
|
|
81987
|
+
status = refreshed.status;
|
|
81988
|
+
credential = refreshed.credential;
|
|
81989
|
+
credentials = cloudCredentialsFromRemoteProfile(status, credential);
|
|
81990
|
+
}
|
|
81991
|
+
const selectedWorkspace = credentials.workspaceSlug ?? credentials.workspaceId;
|
|
81992
|
+
if (explicitWorkspace && explicitWorkspace !== credentials.workspaceId && explicitWorkspace !== credentials.workspaceSlug) throw projectBindingError("workspace_switch_required", `Requested workspace ${explicitWorkspace} differs from saved Selected Workspace ${selectedWorkspace}.`);
|
|
81344
81993
|
if (workspaceFromRemoteUrl && workspaceFromRemoteUrl !== credentials.workspaceSlug && workspaceFromRemoteUrl !== credentials.workspaceId) throw projectBindingError("workspace_switch_required", `Requested workspace ${workspaceFromRemoteUrl} differs from saved Selected Workspace ${selectedWorkspace}.`);
|
|
81345
81994
|
const missingScope = requiredHostedCloudAttachScopes().find((scope) => !credentials.scope?.includes(scope));
|
|
81346
|
-
if (missingScope) throw projectBindingError("cloud_auth_required", `Hosted Cloud attach requires Cloud Auth scope ${missingScope}. Run caplets
|
|
81995
|
+
if (missingScope) throw projectBindingError("cloud_auth_required", `Hosted Cloud attach requires Cloud Auth scope ${missingScope}. Run caplets remote login ${credentials.cloudUrl} again.`);
|
|
81347
81996
|
const remote = resolveHostedCloudRemote({
|
|
81348
81997
|
url: remoteUrl,
|
|
81349
81998
|
token: credentials.accessToken,
|
|
@@ -81355,6 +82004,7 @@ async function resolveRemoteSelection(input = {}, env = process.env) {
|
|
|
81355
82004
|
remote,
|
|
81356
82005
|
selectedWorkspace,
|
|
81357
82006
|
credentials,
|
|
82007
|
+
credentialExpiresAt: credentials.expiresAt,
|
|
81358
82008
|
cloudPresence: {
|
|
81359
82009
|
url: remote.baseUrl,
|
|
81360
82010
|
accessToken: credentials.accessToken,
|
|
@@ -81366,6 +82016,74 @@ function credentialsNeedRefresh(credentials) {
|
|
|
81366
82016
|
const expiresAt = Date.parse(credentials.expiresAt);
|
|
81367
82017
|
return Number.isFinite(expiresAt) && expiresAt <= Date.now() + 6e4;
|
|
81368
82018
|
}
|
|
82019
|
+
async function refreshSelfHostedCredentials(remoteUrl, refreshToken, options) {
|
|
82020
|
+
const response = await fetchSelfHostedRefresh(appendBasePath(new URL(normalizeRemoteProfileHostUrl(remoteUrl)), "v1/remote/refresh"), refreshToken, options);
|
|
82021
|
+
if (!response.ok) throw await selfHostedRefreshError(remoteUrl, response);
|
|
82022
|
+
return parseSelfHostedRefreshCredentials(response);
|
|
82023
|
+
}
|
|
82024
|
+
async function selfHostedRefreshError(remoteUrl, response) {
|
|
82025
|
+
const summary = await parseSelfHostedRefreshError(response);
|
|
82026
|
+
if (response.status === 401 || summary?.code === "AUTH_FAILED") return remoteLoginRequired(remoteUrl);
|
|
82027
|
+
if (response.status === 503 || summary?.code === "SERVER_UNAVAILABLE") return new CapletsError("SERVER_UNAVAILABLE", summary?.message ?? "Remote credential refresh is temporarily unavailable.");
|
|
82028
|
+
return new CapletsError("AUTH_REFRESH_FAILED", summary?.message ?? `Remote credential refresh failed with HTTP ${response.status}.`);
|
|
82029
|
+
}
|
|
82030
|
+
async function parseSelfHostedRefreshError(response) {
|
|
82031
|
+
const parsed = await response.clone().json().catch(() => void 0);
|
|
82032
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return void 0;
|
|
82033
|
+
const error = parsed.error;
|
|
82034
|
+
if (!error || typeof error !== "object" || Array.isArray(error)) return void 0;
|
|
82035
|
+
const record = error;
|
|
82036
|
+
return {
|
|
82037
|
+
...typeof record.code === "string" ? { code: record.code } : {},
|
|
82038
|
+
...typeof record.message === "string" ? { message: record.message } : {}
|
|
82039
|
+
};
|
|
82040
|
+
}
|
|
82041
|
+
async function fetchSelfHostedRefresh(refreshUrl, refreshToken, options) {
|
|
82042
|
+
const controller = new AbortController();
|
|
82043
|
+
let timeout;
|
|
82044
|
+
try {
|
|
82045
|
+
const refresh = (options.fetch ?? fetch)(refreshUrl, {
|
|
82046
|
+
method: "POST",
|
|
82047
|
+
headers: { "content-type": "application/json" },
|
|
82048
|
+
body: JSON.stringify({ refreshToken }),
|
|
82049
|
+
signal: controller.signal
|
|
82050
|
+
});
|
|
82051
|
+
const timedOut = new Promise((_resolve, reject) => {
|
|
82052
|
+
timeout = setTimeout(() => {
|
|
82053
|
+
controller.abort();
|
|
82054
|
+
reject(new CapletsError("SERVER_UNAVAILABLE", "Remote credential refresh timed out."));
|
|
82055
|
+
}, SELF_HOSTED_REFRESH_TIMEOUT_MS);
|
|
82056
|
+
});
|
|
82057
|
+
return await Promise.race([refresh, timedOut]);
|
|
82058
|
+
} catch (error) {
|
|
82059
|
+
if (error instanceof CapletsError) throw error;
|
|
82060
|
+
throw new CapletsError("SERVER_UNAVAILABLE", "Remote credential refresh failed.");
|
|
82061
|
+
} finally {
|
|
82062
|
+
if (timeout) clearTimeout(timeout);
|
|
82063
|
+
}
|
|
82064
|
+
}
|
|
82065
|
+
function remoteLoginRequired(remoteUrl) {
|
|
82066
|
+
return new ProjectBindingError({
|
|
82067
|
+
code: "remote_credentials_required",
|
|
82068
|
+
message: `Remote Login required for ${normalizeRemoteProfileHostUrl(remoteUrl)}.`,
|
|
82069
|
+
recoveryCommand: `caplets remote login ${normalizeRemoteProfileHostUrl(remoteUrl)}`
|
|
82070
|
+
});
|
|
82071
|
+
}
|
|
82072
|
+
async function parseSelfHostedRefreshCredentials(response) {
|
|
82073
|
+
const parsed = await response.json();
|
|
82074
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) throw new CapletsError("DOWNSTREAM_PROTOCOL_ERROR", "Remote refresh response must be an object.");
|
|
82075
|
+
const record = parsed;
|
|
82076
|
+
if (typeof record.clientId !== "string" || typeof record.accessToken !== "string" || typeof record.refreshToken !== "string") throw new CapletsError("DOWNSTREAM_PROTOCOL_ERROR", "Remote refresh response is missing credentials.");
|
|
82077
|
+
return {
|
|
82078
|
+
...typeof record.hostUrl === "string" ? { hostUrl: record.hostUrl } : {},
|
|
82079
|
+
clientId: record.clientId,
|
|
82080
|
+
...typeof record.clientLabel === "string" ? { clientLabel: record.clientLabel } : {},
|
|
82081
|
+
accessToken: record.accessToken,
|
|
82082
|
+
refreshToken: record.refreshToken,
|
|
82083
|
+
...typeof record.tokenType === "string" ? { tokenType: record.tokenType } : {},
|
|
82084
|
+
...typeof record.expiresAt === "string" ? { expiresAt: record.expiresAt } : {}
|
|
82085
|
+
};
|
|
82086
|
+
}
|
|
81369
82087
|
function requiredHostedCloudAttachScopes() {
|
|
81370
82088
|
return HOSTED_CLOUD_AUTH_SCOPES.filter((scope) => scope !== "mcp:tools");
|
|
81371
82089
|
}
|
|
@@ -81376,21 +82094,24 @@ let hasWarnedRemoteProjectBindingFallback = false;
|
|
|
81376
82094
|
function createNativeCapletsService(options = {}) {
|
|
81377
82095
|
const resolved = resolveNativeCapletsServiceOptions(options);
|
|
81378
82096
|
if (resolved.mode === "remote") {
|
|
81379
|
-
|
|
81380
|
-
|
|
81381
|
-
|
|
81382
|
-
|
|
81383
|
-
|
|
81384
|
-
|
|
81385
|
-
|
|
82097
|
+
if (options.remoteClientFactory) {
|
|
82098
|
+
const local = createLocalOverlayService(options);
|
|
82099
|
+
try {
|
|
82100
|
+
return createCompositeRemoteService(resolved.remote, local, options, "self_hosted_remote");
|
|
82101
|
+
} catch (error) {
|
|
82102
|
+
if (options.mode !== "remote") {
|
|
82103
|
+
warnRemoteProjectBindingFallback(options);
|
|
82104
|
+
return local;
|
|
82105
|
+
}
|
|
82106
|
+
local.close().catch((closeError) => {
|
|
82107
|
+
writeErr(options, `Could not close local overlay Caplets service: ${errorMessage(closeError)}\n`);
|
|
82108
|
+
});
|
|
82109
|
+
throw error;
|
|
81386
82110
|
}
|
|
81387
|
-
local.close().catch((closeError) => {
|
|
81388
|
-
writeErr(options, `Could not close local overlay Caplets service: ${errorMessage(closeError)}\n`);
|
|
81389
|
-
});
|
|
81390
|
-
throw error;
|
|
81391
82111
|
}
|
|
82112
|
+
return new ProfileBackedNativeCapletsService(options, resolved.remote, "self_hosted_remote");
|
|
81392
82113
|
}
|
|
81393
|
-
if (resolved.mode === "cloud") return new
|
|
82114
|
+
if (resolved.mode === "cloud") return new ProfileBackedNativeCapletsService(options, resolved.remote, "hosted_cloud");
|
|
81394
82115
|
return new DefaultNativeCapletsService(options);
|
|
81395
82116
|
}
|
|
81396
82117
|
var DefaultNativeCapletsService = class {
|
|
@@ -81751,31 +82472,55 @@ function createLocalOverlayService(options) {
|
|
|
81751
82472
|
return (options.localServiceFactory ?? createDefaultNativeCapletsService)(localOptions);
|
|
81752
82473
|
}
|
|
81753
82474
|
function createCompositeRemoteService(remoteOptions, local, options, authKind) {
|
|
81754
|
-
|
|
81755
|
-
|
|
81756
|
-
|
|
82475
|
+
const { remote, presence } = createCompositeRemoteParts(remoteOptions, local, options, authKind);
|
|
82476
|
+
return new CompositeNativeCapletsService(remote, local, options, presence);
|
|
82477
|
+
}
|
|
82478
|
+
function createCompositeRemoteParts(remoteOptions, local, options, authKind, resolveRuntimeRemoteOptions) {
|
|
82479
|
+
const remote = new RemoteNativeCapletsService({
|
|
82480
|
+
client: createRemoteClient(remoteOptions, options, authKind, resolveRuntimeRemoteOptions),
|
|
82481
|
+
clientFactory: () => createRemoteClient(remoteOptions, options, authKind, resolveRuntimeRemoteOptions),
|
|
81757
82482
|
pollIntervalMs: remoteOptions.pollIntervalMs,
|
|
81758
82483
|
authKind,
|
|
81759
82484
|
...options.writeErr ? { writeErr: options.writeErr } : {}
|
|
81760
|
-
})
|
|
82485
|
+
});
|
|
82486
|
+
const presence = createProjectBindingSessionManager(remoteOptions.cloud, local, options);
|
|
82487
|
+
return {
|
|
82488
|
+
remote,
|
|
82489
|
+
...presence ? { presence } : {}
|
|
82490
|
+
};
|
|
82491
|
+
}
|
|
82492
|
+
function createRemoteClient(remoteOptions, options, authKind, resolveRuntimeRemoteOptions) {
|
|
82493
|
+
if (options.remoteClientFactory) return options.remoteClientFactory(remoteOptions);
|
|
82494
|
+
return createSdkRemoteCapletsClient({
|
|
82495
|
+
...remoteOptions,
|
|
82496
|
+
authKind,
|
|
82497
|
+
...options.writeErr ? { writeErr: options.writeErr } : {},
|
|
82498
|
+
...resolveRuntimeRemoteOptions ? { resolveRuntimeOptions: resolveRuntimeRemoteOptions } : {}
|
|
82499
|
+
});
|
|
81761
82500
|
}
|
|
81762
|
-
var
|
|
82501
|
+
var ProfileBackedNativeCapletsService = class {
|
|
81763
82502
|
options;
|
|
81764
82503
|
baseRemote;
|
|
82504
|
+
authKind;
|
|
81765
82505
|
local;
|
|
81766
82506
|
listeners = /* @__PURE__ */ new Set();
|
|
81767
82507
|
delegate;
|
|
81768
82508
|
unsubscribeDelegate;
|
|
82509
|
+
remoteSignature;
|
|
82510
|
+
credentialExpiresAt;
|
|
82511
|
+
ensureDelegateCurrentInFlight;
|
|
81769
82512
|
closed = false;
|
|
81770
|
-
constructor(options, baseRemote) {
|
|
82513
|
+
constructor(options, baseRemote, authKind) {
|
|
81771
82514
|
this.options = options;
|
|
81772
82515
|
this.baseRemote = baseRemote;
|
|
82516
|
+
this.authKind = authKind;
|
|
81773
82517
|
this.local = createLocalOverlayService(options);
|
|
81774
82518
|
}
|
|
81775
82519
|
listTools() {
|
|
81776
82520
|
return this.delegate?.listTools() ?? this.local.listTools();
|
|
81777
82521
|
}
|
|
81778
82522
|
async execute(capletId, request) {
|
|
82523
|
+
if (!this.delegate || nativeCredentialsNeedRefresh(this.credentialExpiresAt)) await this.ensureDelegateCurrent();
|
|
81779
82524
|
return await (this.delegate ?? this.local).execute(capletId, request);
|
|
81780
82525
|
}
|
|
81781
82526
|
codeModeService() {
|
|
@@ -81783,42 +82528,8 @@ var CloudNativeCapletsService = class {
|
|
|
81783
82528
|
}
|
|
81784
82529
|
async reload() {
|
|
81785
82530
|
if (this.closed) return false;
|
|
81786
|
-
|
|
81787
|
-
|
|
81788
|
-
const remoteUrl = this.options.remote?.url ?? this.baseRemote.url.toString().replace(/\/mcp$/u, "");
|
|
81789
|
-
const selection = await resolveRemoteSelection({
|
|
81790
|
-
mode: "cloud",
|
|
81791
|
-
remoteUrl,
|
|
81792
|
-
...cloudFetch ? { fetch: cloudFetch } : {}
|
|
81793
|
-
}, {
|
|
81794
|
-
...process.env,
|
|
81795
|
-
CAPLETS_MODE: "cloud",
|
|
81796
|
-
CAPLETS_REMOTE_URL: remoteUrl
|
|
81797
|
-
});
|
|
81798
|
-
if (selection.kind !== "hosted_cloud") throw new CapletsError("REQUEST_INVALID", "CAPLETS_MODE=cloud requires Caplets Cloud.");
|
|
81799
|
-
const cloudPresence = {
|
|
81800
|
-
url: selection.cloudPresence.url,
|
|
81801
|
-
accessToken: selection.cloudPresence.accessToken,
|
|
81802
|
-
workspaceId: selection.cloudPresence.workspaceId,
|
|
81803
|
-
...this.options.remote?.cloud?.projectRoot ? { projectRoot: this.options.remote.cloud.projectRoot } : {},
|
|
81804
|
-
heartbeatIntervalMs: this.options.remote?.cloud?.heartbeatIntervalMs ?? this.baseRemote.cloud?.heartbeatIntervalMs ?? 3e4
|
|
81805
|
-
};
|
|
81806
|
-
const remoteOptions = {
|
|
81807
|
-
...this.baseRemote,
|
|
81808
|
-
url: selection.remote.attachUrl,
|
|
81809
|
-
auth: nativeAuthFromRemoteAuth(selection.remote.auth),
|
|
81810
|
-
requestInit: selection.remote.requestInit,
|
|
81811
|
-
...selection.remote.fetch ? { fetch: selection.remote.fetch } : {},
|
|
81812
|
-
cloud: cloudPresence
|
|
81813
|
-
};
|
|
81814
|
-
this.delegate = createCompositeRemoteService(remoteOptions, this.local, this.options, "hosted_cloud");
|
|
81815
|
-
this.unsubscribeDelegate = this.delegate.onToolsChanged((tools) => this.emit(tools));
|
|
81816
|
-
} catch (error) {
|
|
81817
|
-
if (this.options.mode === "cloud") throw error;
|
|
81818
|
-
warnRemoteProjectBindingFallback(this.options);
|
|
81819
|
-
return await this.local.reload();
|
|
81820
|
-
}
|
|
81821
|
-
return await this.delegate.reload();
|
|
82531
|
+
await this.ensureDelegateCurrent();
|
|
82532
|
+
return await (this.delegate ?? this.local).reload();
|
|
81822
82533
|
}
|
|
81823
82534
|
onToolsChanged(listener) {
|
|
81824
82535
|
this.listeners.add(listener);
|
|
@@ -81834,13 +82545,110 @@ var CloudNativeCapletsService = class {
|
|
|
81834
82545
|
emit(tools) {
|
|
81835
82546
|
for (const listener of this.listeners) listener(tools);
|
|
81836
82547
|
}
|
|
82548
|
+
async ensureDelegateCurrent() {
|
|
82549
|
+
if (this.ensureDelegateCurrentInFlight) {
|
|
82550
|
+
await this.ensureDelegateCurrentInFlight;
|
|
82551
|
+
return;
|
|
82552
|
+
}
|
|
82553
|
+
const refresh = this.ensureDelegateCurrentNow();
|
|
82554
|
+
this.ensureDelegateCurrentInFlight = refresh;
|
|
82555
|
+
try {
|
|
82556
|
+
await refresh;
|
|
82557
|
+
} finally {
|
|
82558
|
+
if (this.ensureDelegateCurrentInFlight === refresh) this.ensureDelegateCurrentInFlight = void 0;
|
|
82559
|
+
}
|
|
82560
|
+
}
|
|
82561
|
+
async ensureDelegateCurrentNow() {
|
|
82562
|
+
try {
|
|
82563
|
+
const remoteOptions = await this.resolveProfileRemoteOptions();
|
|
82564
|
+
if (this.closed) return;
|
|
82565
|
+
const signature = remoteOptionsSignature(remoteOptions);
|
|
82566
|
+
if (!this.delegate) {
|
|
82567
|
+
const { remote, presence } = createCompositeRemoteParts(remoteOptions, this.local, this.options, this.authKind, () => this.resolveProfileRemoteOptions());
|
|
82568
|
+
this.delegate = new CompositeNativeCapletsService(remote, this.local, this.options, presence);
|
|
82569
|
+
this.unsubscribeDelegate = this.delegate.onToolsChanged((tools) => this.emit(tools));
|
|
82570
|
+
this.remoteSignature = signature;
|
|
82571
|
+
this.credentialExpiresAt = remoteOptions.credentialExpiresAt;
|
|
82572
|
+
return;
|
|
82573
|
+
}
|
|
82574
|
+
if (signature === this.remoteSignature) return;
|
|
82575
|
+
const { remote, presence } = createCompositeRemoteParts(remoteOptions, this.local, this.options, this.authKind, () => this.resolveProfileRemoteOptions());
|
|
82576
|
+
if (!await remote.reload()) {
|
|
82577
|
+
await Promise.all([remote.close(), presence?.close()]);
|
|
82578
|
+
return;
|
|
82579
|
+
}
|
|
82580
|
+
await this.delegate.replaceRemote(remote, presence);
|
|
82581
|
+
this.remoteSignature = signature;
|
|
82582
|
+
this.credentialExpiresAt = remoteOptions.credentialExpiresAt;
|
|
82583
|
+
} catch (error) {
|
|
82584
|
+
if (this.options.mode === "cloud" || this.options.mode === "remote") {
|
|
82585
|
+
if (this.delegate) throw error;
|
|
82586
|
+
await this.close().catch((closeError) => {
|
|
82587
|
+
writeErr(this.options, `Could not close local overlay Caplets service: ${errorMessage(closeError)}\n`);
|
|
82588
|
+
});
|
|
82589
|
+
throw error;
|
|
82590
|
+
}
|
|
82591
|
+
warnRemoteProjectBindingFallback(this.options);
|
|
82592
|
+
if (!this.delegate) await this.local.reload();
|
|
82593
|
+
}
|
|
82594
|
+
}
|
|
82595
|
+
async resolveProfileRemoteOptions() {
|
|
82596
|
+
const cloudFetch = this.options.remote?.fetch;
|
|
82597
|
+
const remoteUrl = this.options.remote?.url ?? process.env.CAPLETS_REMOTE_URL ?? this.baseRemote.url.toString().replace(/\/v1(?:\/ws\/[^/]+)?\/attach$/u, "");
|
|
82598
|
+
const selection = await resolveRemoteSelection({
|
|
82599
|
+
mode: this.authKind === "hosted_cloud" ? "cloud" : "remote",
|
|
82600
|
+
remoteUrl,
|
|
82601
|
+
...this.options.remote?.workspace ? { workspace: this.options.remote.workspace } : {},
|
|
82602
|
+
...this.options.authDir ? { authDir: this.options.authDir } : {},
|
|
82603
|
+
...cloudFetch ? { fetch: cloudFetch } : {}
|
|
82604
|
+
}, {
|
|
82605
|
+
...process.env,
|
|
82606
|
+
CAPLETS_MODE: this.authKind === "hosted_cloud" ? "cloud" : "remote",
|
|
82607
|
+
CAPLETS_REMOTE_URL: remoteUrl
|
|
82608
|
+
});
|
|
82609
|
+
if (this.authKind === "hosted_cloud" && selection.kind !== "hosted_cloud") throw new CapletsError("REQUEST_INVALID", "CAPLETS_MODE=cloud requires Caplets Cloud.");
|
|
82610
|
+
if (this.authKind === "self_hosted_remote" && selection.kind !== "self_hosted_remote") throw new CapletsError("REQUEST_INVALID", "CAPLETS_MODE=remote requires self-hosted Caplets.");
|
|
82611
|
+
const cloudPresence = selection.kind === "hosted_cloud" ? {
|
|
82612
|
+
url: selection.cloudPresence.url,
|
|
82613
|
+
accessToken: selection.cloudPresence.accessToken,
|
|
82614
|
+
workspaceId: selection.cloudPresence.workspaceId,
|
|
82615
|
+
...this.options.remote?.cloud?.projectRoot ? { projectRoot: this.options.remote.cloud.projectRoot } : {},
|
|
82616
|
+
heartbeatIntervalMs: this.options.remote?.cloud?.heartbeatIntervalMs ?? this.baseRemote.cloud?.heartbeatIntervalMs ?? 3e4
|
|
82617
|
+
} : void 0;
|
|
82618
|
+
return remoteOptionsFromSelection(selection, this.baseRemote, cloudPresence);
|
|
82619
|
+
}
|
|
81837
82620
|
};
|
|
81838
|
-
function
|
|
81839
|
-
|
|
81840
|
-
|
|
81841
|
-
|
|
81842
|
-
|
|
82621
|
+
function remoteOptionsFromSelection(selection, baseRemote, cloudPresence) {
|
|
82622
|
+
return {
|
|
82623
|
+
...baseRemote,
|
|
82624
|
+
url: selection.remote.attachUrl,
|
|
82625
|
+
auth: nativeAuthFromRemoteAuth(selection.remote.auth),
|
|
82626
|
+
requestInit: selection.remote.requestInit,
|
|
82627
|
+
...selection.remote.fetch ? { fetch: selection.remote.fetch } : {},
|
|
82628
|
+
...cloudPresence ? { cloud: cloudPresence } : {},
|
|
82629
|
+
...selection.credentialExpiresAt ? { credentialExpiresAt: selection.credentialExpiresAt } : {}
|
|
81843
82630
|
};
|
|
82631
|
+
}
|
|
82632
|
+
function remoteOptionsSignature(remoteOptions) {
|
|
82633
|
+
return JSON.stringify({
|
|
82634
|
+
url: remoteOptions.url.toString(),
|
|
82635
|
+
requestInit: remoteOptions.requestInit,
|
|
82636
|
+
credentialExpiresAt: remoteOptions.credentialExpiresAt,
|
|
82637
|
+
cloud: remoteOptions.cloud ? {
|
|
82638
|
+
url: remoteOptions.cloud.url.toString(),
|
|
82639
|
+
accessToken: remoteOptions.cloud.accessToken,
|
|
82640
|
+
workspaceId: remoteOptions.cloud.workspaceId,
|
|
82641
|
+
projectRoot: remoteOptions.cloud.projectRoot,
|
|
82642
|
+
heartbeatIntervalMs: remoteOptions.cloud.heartbeatIntervalMs
|
|
82643
|
+
} : void 0
|
|
82644
|
+
});
|
|
82645
|
+
}
|
|
82646
|
+
function nativeCredentialsNeedRefresh(expiresAt) {
|
|
82647
|
+
if (!expiresAt) return false;
|
|
82648
|
+
const parsed = Date.parse(expiresAt);
|
|
82649
|
+
return Number.isFinite(parsed) && parsed <= Date.now() + 6e4;
|
|
82650
|
+
}
|
|
82651
|
+
function nativeAuthFromRemoteAuth(auth) {
|
|
81844
82652
|
if (auth.type === "none") return {
|
|
81845
82653
|
enabled: false,
|
|
81846
82654
|
user: auth.user
|
|
@@ -81856,7 +82664,8 @@ var CompositeNativeCapletsService = class {
|
|
|
81856
82664
|
options;
|
|
81857
82665
|
presence;
|
|
81858
82666
|
listeners = /* @__PURE__ */ new Set();
|
|
81859
|
-
|
|
82667
|
+
unsubscribeRemote;
|
|
82668
|
+
unsubscribeLocal;
|
|
81860
82669
|
warnedShadowedLocalCaplets = /* @__PURE__ */ new Set();
|
|
81861
82670
|
tools = [];
|
|
81862
82671
|
closed = false;
|
|
@@ -81867,11 +82676,10 @@ var CompositeNativeCapletsService = class {
|
|
|
81867
82676
|
this.local = local;
|
|
81868
82677
|
this.options = options;
|
|
81869
82678
|
this.presence = presence;
|
|
81870
|
-
this.
|
|
82679
|
+
this.unsubscribeRemote = this.remote.onToolsChanged(() => this.updateMergedTools());
|
|
82680
|
+
this.unsubscribeLocal = this.local.onToolsChanged(() => this.updateMergedTools());
|
|
81871
82681
|
this.tools = this.mergeTools();
|
|
81872
|
-
this.
|
|
81873
|
-
writeErr(options, `Could not register Caplets Cloud Project Binding: ${errorMessage(error)}\n`);
|
|
81874
|
-
});
|
|
82682
|
+
this.startPresence();
|
|
81875
82683
|
}
|
|
81876
82684
|
listTools() {
|
|
81877
82685
|
return [...this.tools];
|
|
@@ -81909,7 +82717,8 @@ var CompositeNativeCapletsService = class {
|
|
|
81909
82717
|
async close() {
|
|
81910
82718
|
if (this.closed) return;
|
|
81911
82719
|
this.closed = true;
|
|
81912
|
-
|
|
82720
|
+
this.unsubscribeRemote();
|
|
82721
|
+
this.unsubscribeLocal();
|
|
81913
82722
|
this.listeners.clear();
|
|
81914
82723
|
this.codeModeSessions.close();
|
|
81915
82724
|
await Promise.all([
|
|
@@ -81918,6 +82727,22 @@ var CompositeNativeCapletsService = class {
|
|
|
81918
82727
|
this.presence?.close()
|
|
81919
82728
|
]);
|
|
81920
82729
|
}
|
|
82730
|
+
async replaceRemote(remote, presence) {
|
|
82731
|
+
if (this.closed) {
|
|
82732
|
+
await Promise.all([remote.close(), presence?.close()]);
|
|
82733
|
+
return;
|
|
82734
|
+
}
|
|
82735
|
+
const previousRemote = this.remote;
|
|
82736
|
+
const previousPresence = this.presence;
|
|
82737
|
+
this.unsubscribeRemote();
|
|
82738
|
+
this.remote = remote;
|
|
82739
|
+
this.presence = presence;
|
|
82740
|
+
this.unsubscribeRemote = this.remote.onToolsChanged(() => this.updateMergedTools());
|
|
82741
|
+
await Promise.all([previousRemote.close(), previousPresence?.close()]);
|
|
82742
|
+
if (this.closed) return;
|
|
82743
|
+
this.startPresence();
|
|
82744
|
+
this.updateMergedTools();
|
|
82745
|
+
}
|
|
81921
82746
|
updateMergedTools() {
|
|
81922
82747
|
if (this.closed || this.batchingReload) return;
|
|
81923
82748
|
const tools = this.mergeTools();
|
|
@@ -81946,7 +82771,7 @@ var CompositeNativeCapletsService = class {
|
|
|
81946
82771
|
return localExecutionKeys(this.local.listTools(), capletId).some((key) => !remoteIds.has(key));
|
|
81947
82772
|
}
|
|
81948
82773
|
warnShadowedLocalCaplets(localTools, remoteIds) {
|
|
81949
|
-
const localIds = new Set([...localTools.filter((tool) => tool.codeModeRun !== true).map((tool) => tool.sourceCaplet ?? tool.caplet), ...codeModeCallableNativeTools(localTools, { fallbackToVisible: false }).map((tool) => tool.caplet)]);
|
|
82774
|
+
const localIds = /* @__PURE__ */ new Set([...localTools.filter((tool) => tool.codeModeRun !== true).map((tool) => tool.sourceCaplet ?? tool.caplet), ...codeModeCallableNativeTools(localTools, { fallbackToVisible: false }).map((tool) => tool.caplet)]);
|
|
81950
82775
|
for (const capletId of localIds) {
|
|
81951
82776
|
if (!remoteIds.has(capletId)) continue;
|
|
81952
82777
|
if (this.warnedShadowedLocalCaplets.has(capletId)) continue;
|
|
@@ -81962,6 +82787,11 @@ var CompositeNativeCapletsService = class {
|
|
|
81962
82787
|
return;
|
|
81963
82788
|
}
|
|
81964
82789
|
}
|
|
82790
|
+
startPresence() {
|
|
82791
|
+
this.presence?.start().catch((error) => {
|
|
82792
|
+
writeErr(this.options, `Could not register Caplets Cloud Project Binding: ${errorMessage(error)}\n`);
|
|
82793
|
+
});
|
|
82794
|
+
}
|
|
81965
82795
|
};
|
|
81966
82796
|
function remoteCodeModeCallableNativeTools(tools) {
|
|
81967
82797
|
return codeModeCallableNativeTools(tools, { fallbackToVisible: true });
|
|
@@ -82037,4 +82867,4 @@ function errorMessage(error) {
|
|
|
82037
82867
|
return error instanceof Error ? error.message : String(error);
|
|
82038
82868
|
}
|
|
82039
82869
|
//#endregion
|
|
82040
|
-
export {
|
|
82870
|
+
export { decodeDirectResourceUri as $, ElicitResultSchema as $t, nativeCapletToolDescription as A, objectFromShape as An, defaultCacheBaseDir as At, QuickJsCodeModeSandbox as B, assertClientRequestTaskCapability as Bt, resolveRemoteMode as C, getLiteralValue as Cn, startOAuthFlow as Ct, parseServerBaseUrl as D, isSchemaOptional as Dn, DEFAULT_AUTH_DIR as Dt, isLoopbackHost as E, getSchemaDescription as En, readTokenBundle as Et, codeModeRunInputSchema as F, resolveConfigPath as Ft, CodeModeLogStore as G, toJsonSchemaCompat as Gt, createCodeModeCapletsApi as H, AjvJsonSchemaValidator as Ht, codeModeRunParamsSchema as I, resolveProjectCapletsRoot as It, generateCodeModeDeclarations as J, CompleteRequestSchema as Jt, redactCodeModeLogText as K, CallToolRequestSchema as Kt, emptyCodeModeRunMeta as L, resolveProjectConfigPath as Lt, nativeCapletsSystemGuidance as M, safeParseAsync as Mn, defaultConfigPath as Mt, nativeCodeModeToolId as N, __exportAll as Nn, defaultStateBaseDir as Nt, resolveCapletsServer as O, isZ4Schema as On, DEFAULT_COMPLETION_CACHE_DIR as Ot, nativeCodeModeToolName as P, resolveCapletsRoot as Pt, resolveExposure as Q, DEFAULT_NEGOTIATED_PROTOCOL_VERSION as Qt, runCodeMode as R, ReadBuffer as Rt, resolveHostedCloudRemote as S, isJSONRPCResultResponse as Sn, startGenericOAuthFlow as St, controlUrlForBase as T, getParseErrorMessage as Tn, isTokenBundleExpired as Tt, listCodeModeCallableCaplets as U, Protocol as Ut, diagnoseCodeModeTypeScript as V, assertToolsCallTaskCapability as Vt, CodeModeJournalStore as W, mergeCapabilities as Wt, minifyCodeModeDeclarationText as X, CreateMessageResultWithToolsSchema as Xt, generateCodeModeRunToolDescription as Y, CreateMessageResultSchema as Yt, CapletsEngine as Z, CreateTaskResultSchema as Zt, resolveNativeCapletsServiceOptions as _, assertCompleteRequestPrompt as _n, markdownCallToolResultContent as _t, CloudAuthStore as a, JSONRPCMessageSchema as an, capabilityDescription as at, normalizeRemoteProfileHostUrl as b, isJSONRPCErrorResponse as bn, runGenericOAuthFlow as bt, redactedCloudAuthStatus as c, ListResourceTemplatesRequestSchema as cn, loadConfigWithSources as ct, projectBindingError as d, ListToolsRequestSchema as dn, loadProjectConfig as dt, EmptyResultSchema as en, directResourceUriMatchesTemplate as et, projectBindingRecovery as f, LoggingLevelSchema as fn, parseConfig as ft, buildProjectSyncManifest as g, SetLevelRequestSchema as gn, hasRenderableStructuredContent as gt, createSdkRemoteCapletsClient as h, SUPPORTED_PROTOCOL_VERSIONS as hn, loadCapletFilesFromMap as ht, createRemoteProfileStore as i, InitializedNotificationSchema as in, ServerRegistry as it, nativeCapletToolName as j, safeParse as jn, defaultConfigBaseDir as jt, nativeCapletPromptGuidance as k, normalizeObjectSchema as kn, DEFAULT_OBSERVED_OUTPUT_SHAPE_CACHE_DIR as kt, PROJECT_BINDING_ERROR_CODES as l, ListResourcesRequestSchema as ln, loadGlobalConfig as lt, RemoteNativeCapletsService as m, ReadResourceRequestSchema as mn, validateCapletFile as mt, resolveRemoteSelection as n, GetPromptRequestSchema as nn, fingerprintProjectRoot as nt, cloudAuthPath as o, LATEST_PROTOCOL_VERSION as on, GoogleDiscoveryManager as ot, CloudAuthClient as p, McpError as pn, discoverCapletFiles as pt, codeModeDeclarationHash as q, CallToolResultSchema as qt, cloudCredentialsFromRemoteProfile as r, InitializeRequestSchema as rn, handleServerTool as rt, migrateCredentials as s, ListPromptsRequestSchema as sn, loadConfig as st, createNativeCapletsService as t, ErrorCode as tn, findProjectRoot as tt, ProjectBindingError as u, ListRootsResultSchema as un, loadLocalOverlayConfigWithSources as ut, hostedCloudWorkspaceFromRemoteUrl as v, assertCompleteRequestResourceTemplate as vn, markdownStructuredContent as vt, appendBasePath as w, getObjectShape as wn, deleteTokenBundle as wt, resolveCapletsRemote as x, isJSONRPCRequest as xn, runOAuthFlow as xt, isCapletsCloudUrl as y, isInitializeRequest as yn, refreshOAuthTokenBundle as yt, CodeModeSessionManager as z, serializeMessage as zt };
|