@apicircle/core 1.0.9 → 1.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -4
- package/dist/{chunk-L5DQT7V6.js → chunk-T6A4ICRL.js} +5 -5
- package/dist/chunk-T6A4ICRL.js.map +1 -0
- package/dist/index.cjs +834 -95
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +210 -11
- package/dist/index.d.ts +210 -11
- package/dist/index.js +806 -83
- package/dist/index.js.map +1 -1
- package/dist/{patches-h_K1VcZR.d.cts → patches-B3VGNVgf.d.cts} +53 -1
- package/dist/{patches-h_K1VcZR.d.ts → patches-B3VGNVgf.d.ts} +53 -1
- package/dist/workspace/file-backed.cjs +4 -4
- package/dist/workspace/file-backed.cjs.map +1 -1
- package/dist/workspace/file-backed.d.cts +5 -1
- package/dist/workspace/file-backed.d.ts +5 -1
- package/dist/workspace/file-backed.js +1 -1
- package/dist/workspace/registry.cjs +13 -33
- package/dist/workspace/registry.cjs.map +1 -1
- package/dist/workspace/registry.d.cts +13 -26
- package/dist/workspace/registry.d.ts +13 -26
- package/dist/workspace/registry.js +9 -30
- package/dist/workspace/registry.js.map +1 -1
- package/package.json +3 -2
- package/dist/chunk-L5DQT7V6.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1054,8 +1054,7 @@ async function importPkcs8(pem, algorithm) {
|
|
|
1054
1054
|
"JWT: PKCS#1 RSA PEM (`BEGIN RSA PRIVATE KEY`) is not supported. Convert with `openssl pkcs8 -topk8 -in key.pem -out pkcs8.pem -nocrypt`."
|
|
1055
1055
|
);
|
|
1056
1056
|
}
|
|
1057
|
-
const
|
|
1058
|
-
const body = envelope ? envelope[1] : pem;
|
|
1057
|
+
const body = extractPemBody(pem);
|
|
1059
1058
|
const stripped = body.replace(/\s+/g, "");
|
|
1060
1059
|
if (!stripped) {
|
|
1061
1060
|
throw new Error("JWT: PEM key is empty after stripping headers/whitespace");
|
|
@@ -1076,6 +1075,19 @@ async function importPkcs8(pem, algorithm) {
|
|
|
1076
1075
|
["sign"]
|
|
1077
1076
|
);
|
|
1078
1077
|
}
|
|
1078
|
+
function extractPemBody(pem) {
|
|
1079
|
+
const BEGIN = "-----BEGIN ";
|
|
1080
|
+
const END = "-----END ";
|
|
1081
|
+
const FENCE = "-----";
|
|
1082
|
+
const beginAt = pem.indexOf(BEGIN);
|
|
1083
|
+
if (beginAt === -1) return pem;
|
|
1084
|
+
const beginHeaderEnd = pem.indexOf(FENCE, beginAt + BEGIN.length);
|
|
1085
|
+
if (beginHeaderEnd === -1) return pem;
|
|
1086
|
+
const bodyStart = beginHeaderEnd + FENCE.length;
|
|
1087
|
+
const endAt = pem.indexOf(END, bodyStart);
|
|
1088
|
+
if (endAt === -1) return pem;
|
|
1089
|
+
return pem.slice(bodyStart, endAt);
|
|
1090
|
+
}
|
|
1079
1091
|
function base64UrlEncode(bytes) {
|
|
1080
1092
|
let s = "";
|
|
1081
1093
|
for (let i = 0; i < bytes.length; i++) s += String.fromCharCode(bytes[i]);
|
|
@@ -1530,6 +1542,10 @@ async function fetchOAuth2Token(args) {
|
|
|
1530
1542
|
if (args.extraParams) {
|
|
1531
1543
|
for (const [k, v] of Object.entries(args.extraParams)) body.set(k, v);
|
|
1532
1544
|
}
|
|
1545
|
+
const tokenUrlParsed = new URL(args.tokenUrl);
|
|
1546
|
+
if (tokenUrlParsed.protocol !== "https:" && tokenUrlParsed.protocol !== "http:") {
|
|
1547
|
+
throw new Error(`Token URL must use HTTP or HTTPS, got ${tokenUrlParsed.protocol}`);
|
|
1548
|
+
}
|
|
1533
1549
|
const response = await fetchImpl(args.tokenUrl, {
|
|
1534
1550
|
method: "POST",
|
|
1535
1551
|
headers,
|
|
@@ -2476,6 +2492,30 @@ function getVariableAutocomplete(text, cursorPosition, scope) {
|
|
|
2476
2492
|
);
|
|
2477
2493
|
}
|
|
2478
2494
|
|
|
2495
|
+
// src/request/resolveInheritedAuth.ts
|
|
2496
|
+
var NONE = { type: "none" };
|
|
2497
|
+
function resolveInheritedAuth({
|
|
2498
|
+
requestAuth,
|
|
2499
|
+
folderId,
|
|
2500
|
+
folders
|
|
2501
|
+
}) {
|
|
2502
|
+
if (requestAuth.type !== "inherit") return requestAuth;
|
|
2503
|
+
let cursor = folderId;
|
|
2504
|
+
const visited = /* @__PURE__ */ new Set();
|
|
2505
|
+
while (cursor !== null) {
|
|
2506
|
+
if (visited.has(cursor)) {
|
|
2507
|
+
break;
|
|
2508
|
+
}
|
|
2509
|
+
visited.add(cursor);
|
|
2510
|
+
const folder = folders[cursor];
|
|
2511
|
+
if (!folder) break;
|
|
2512
|
+
const auth = folder.auth;
|
|
2513
|
+
if (auth && auth.type !== "inherit" && auth.type !== "none") return auth;
|
|
2514
|
+
cursor = folder.parentId;
|
|
2515
|
+
}
|
|
2516
|
+
return NONE;
|
|
2517
|
+
}
|
|
2518
|
+
|
|
2479
2519
|
// src/request/preSendValidation.ts
|
|
2480
2520
|
var TYPED_BODY_CT = {
|
|
2481
2521
|
json: ["application/json", "application/ld+json", "application/vnd.api+json"],
|
|
@@ -2488,7 +2528,8 @@ function collectMissing(value, scope) {
|
|
|
2488
2528
|
}
|
|
2489
2529
|
function preSendValidation({
|
|
2490
2530
|
request,
|
|
2491
|
-
scope
|
|
2531
|
+
scope,
|
|
2532
|
+
folders
|
|
2492
2533
|
}) {
|
|
2493
2534
|
const warnings = [];
|
|
2494
2535
|
const blockers = [];
|
|
@@ -2563,29 +2604,43 @@ function preSendValidation({
|
|
|
2563
2604
|
});
|
|
2564
2605
|
}
|
|
2565
2606
|
}
|
|
2566
|
-
|
|
2607
|
+
let effectiveAuth = request.auth;
|
|
2608
|
+
let resolvedFromInherit = false;
|
|
2609
|
+
if (folders && effectiveAuth?.type === "inherit") {
|
|
2610
|
+
effectiveAuth = resolveInheritedAuth({
|
|
2611
|
+
requestAuth: { type: "inherit" },
|
|
2612
|
+
folderId: request.folderId,
|
|
2613
|
+
folders
|
|
2614
|
+
});
|
|
2615
|
+
resolvedFromInherit = true;
|
|
2616
|
+
}
|
|
2617
|
+
const auth = effectiveAuth;
|
|
2618
|
+
const inheritedNote = resolvedFromInherit ? " (resolved from folder-level auth)" : "";
|
|
2567
2619
|
if (auth) {
|
|
2568
2620
|
if (auth.type === "bearer" && !auth.token?.trim()) {
|
|
2569
|
-
blockers.push({
|
|
2621
|
+
blockers.push({
|
|
2622
|
+
kind: "auth-fields-missing",
|
|
2623
|
+
message: `Bearer token is empty.${inheritedNote}`
|
|
2624
|
+
});
|
|
2570
2625
|
} else if (auth.type === "basic") {
|
|
2571
2626
|
if (!auth.username?.trim() || !auth.password?.trim()) {
|
|
2572
2627
|
blockers.push({
|
|
2573
2628
|
kind: "auth-fields-missing",
|
|
2574
|
-
message:
|
|
2629
|
+
message: `Basic auth requires both username and password.${inheritedNote}`
|
|
2575
2630
|
});
|
|
2576
2631
|
}
|
|
2577
2632
|
} else if (auth.type === "api-key") {
|
|
2578
2633
|
if (!auth.key?.trim() || !auth.value?.trim()) {
|
|
2579
2634
|
blockers.push({
|
|
2580
2635
|
kind: "auth-fields-missing",
|
|
2581
|
-
message:
|
|
2636
|
+
message: `API key auth requires both name and value.${inheritedNote}`
|
|
2582
2637
|
});
|
|
2583
2638
|
}
|
|
2584
2639
|
} else if (auth.type === "custom-header") {
|
|
2585
2640
|
if (!auth.key?.trim()) {
|
|
2586
2641
|
blockers.push({
|
|
2587
2642
|
kind: "auth-fields-missing",
|
|
2588
|
-
message:
|
|
2643
|
+
message: `Custom header auth requires a header name.${inheritedNote}`
|
|
2589
2644
|
});
|
|
2590
2645
|
}
|
|
2591
2646
|
}
|
|
@@ -2972,6 +3027,15 @@ async function executeRequest(req, opts = {}) {
|
|
|
2972
3027
|
);
|
|
2973
3028
|
const redirectMode = isBrowserRuntime() ? "follow" : "manual";
|
|
2974
3029
|
let currentUrl = builtRequest.url;
|
|
3030
|
+
try {
|
|
3031
|
+
const parsedUrl = new URL(currentUrl);
|
|
3032
|
+
if (parsedUrl.protocol !== "http:" && parsedUrl.protocol !== "https:") {
|
|
3033
|
+
throw new Error(`Unsupported URL scheme: ${parsedUrl.protocol}`);
|
|
3034
|
+
}
|
|
3035
|
+
} catch (e) {
|
|
3036
|
+
if (e instanceof Error && e.message.startsWith("Unsupported URL scheme")) throw e;
|
|
3037
|
+
throw new Error(`Invalid request URL: ${currentUrl}`);
|
|
3038
|
+
}
|
|
2975
3039
|
let currentHeaders = { ...builtRequest.headers };
|
|
2976
3040
|
let currentMethod = builtRequest.method;
|
|
2977
3041
|
let currentBody = builtRequest.body;
|
|
@@ -3270,30 +3334,6 @@ function base64UrlEncode2(bytes) {
|
|
|
3270
3334
|
return btoa(s).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
3271
3335
|
}
|
|
3272
3336
|
|
|
3273
|
-
// src/request/resolveInheritedAuth.ts
|
|
3274
|
-
var NONE = { type: "none" };
|
|
3275
|
-
function resolveInheritedAuth({
|
|
3276
|
-
requestAuth,
|
|
3277
|
-
folderId,
|
|
3278
|
-
folders
|
|
3279
|
-
}) {
|
|
3280
|
-
if (requestAuth.type !== "inherit") return requestAuth;
|
|
3281
|
-
let cursor = folderId;
|
|
3282
|
-
const visited = /* @__PURE__ */ new Set();
|
|
3283
|
-
while (cursor !== null) {
|
|
3284
|
-
if (visited.has(cursor)) {
|
|
3285
|
-
break;
|
|
3286
|
-
}
|
|
3287
|
-
visited.add(cursor);
|
|
3288
|
-
const folder = folders[cursor];
|
|
3289
|
-
if (!folder) break;
|
|
3290
|
-
const auth = folder.auth;
|
|
3291
|
-
if (auth && auth.type !== "inherit" && auth.type !== "none") return auth;
|
|
3292
|
-
cursor = folder.parentId;
|
|
3293
|
-
}
|
|
3294
|
-
return NONE;
|
|
3295
|
-
}
|
|
3296
|
-
|
|
3297
3337
|
// src/request/parseCurl.ts
|
|
3298
3338
|
var HTTP_METHODS = /* @__PURE__ */ new Set(["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"]);
|
|
3299
3339
|
function tokenizeCurl(input) {
|
|
@@ -3595,10 +3635,12 @@ function parsePostmanCollection(input) {
|
|
|
3595
3635
|
items.forEach((item, idx) => {
|
|
3596
3636
|
const pathIds = parentPathIds ? [...parentPathIds, idx] : [idx];
|
|
3597
3637
|
if (Array.isArray(item.item)) {
|
|
3638
|
+
const folderAuth = item.auth ? parseAuth(item.auth, warnings, item.name) : void 0;
|
|
3598
3639
|
folders.push({
|
|
3599
3640
|
name: (item.name ?? "Untitled folder").trim() || "Untitled folder",
|
|
3600
3641
|
pathIds,
|
|
3601
|
-
parentPathIds
|
|
3642
|
+
parentPathIds,
|
|
3643
|
+
...folderAuth && folderAuth.type !== "none" ? { auth: folderAuth } : {}
|
|
3602
3644
|
});
|
|
3603
3645
|
walk(item.item, pathIds);
|
|
3604
3646
|
return;
|
|
@@ -3839,10 +3881,12 @@ function parseInsomniaCollection(input) {
|
|
|
3839
3881
|
const parentPath = r.parentId ? folderIndexById.get(r.parentId) ?? null : null;
|
|
3840
3882
|
const ourPath = parentPath ? [...parentPath, folderCounter++] : [folderCounter++];
|
|
3841
3883
|
folderIndexById.set(r._id ?? "", ourPath);
|
|
3884
|
+
const folderAuth = r.authentication ? parseAuth2(r.authentication, warnings, r.name) : void 0;
|
|
3842
3885
|
folders.push({
|
|
3843
3886
|
name: (r.name ?? "Untitled folder").trim() || "Untitled folder",
|
|
3844
3887
|
pathIds: ourPath,
|
|
3845
|
-
parentPathIds: parentPath
|
|
3888
|
+
parentPathIds: parentPath,
|
|
3889
|
+
...folderAuth && folderAuth.type !== "none" ? { auth: folderAuth } : {}
|
|
3846
3890
|
});
|
|
3847
3891
|
}
|
|
3848
3892
|
const requests = [];
|
|
@@ -4243,7 +4287,7 @@ function serializeFolderExport(envelope) {
|
|
|
4243
4287
|
return JSON.stringify(envelope, null, 2);
|
|
4244
4288
|
}
|
|
4245
4289
|
function suggestFolderExportFilename(envelope) {
|
|
4246
|
-
const slug = envelope.folder.name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(
|
|
4290
|
+
const slug = envelope.folder.name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-/, "").replace(/-$/, "");
|
|
4247
4291
|
const base = slug || "folder";
|
|
4248
4292
|
return `${base}.apicircle.json`;
|
|
4249
4293
|
}
|
|
@@ -4869,6 +4913,140 @@ function extractContext(result, extractions) {
|
|
|
4869
4913
|
return { extracted, warnings };
|
|
4870
4914
|
}
|
|
4871
4915
|
|
|
4916
|
+
// src/environment/resolveRequest.ts
|
|
4917
|
+
import { envPriorityKey } from "@apicircle/shared";
|
|
4918
|
+
function resolveRequestForExecution(args) {
|
|
4919
|
+
const refs = args.envPriorityOverride && args.envPriorityOverride.length > 0 ? args.envPriorityOverride : args.synced.environments.priorityOrder;
|
|
4920
|
+
const flatEnvs = {};
|
|
4921
|
+
for (const [name, vars] of Object.entries(args.localEnvs)) {
|
|
4922
|
+
flatEnvs[envPriorityKey({ kind: "local", name })] = vars;
|
|
4923
|
+
}
|
|
4924
|
+
for (const [linkId, byEnv] of Object.entries(args.linkedEnvs ?? {})) {
|
|
4925
|
+
for (const [envName, vars] of Object.entries(byEnv)) {
|
|
4926
|
+
flatEnvs[envPriorityKey({ kind: "linked", linkedWorkspaceId: linkId, envName })] = vars;
|
|
4927
|
+
}
|
|
4928
|
+
}
|
|
4929
|
+
const ctxMap = { ...args.globalContext ?? {} };
|
|
4930
|
+
for (const v of args.planVariables ?? []) {
|
|
4931
|
+
if (v.key) ctxMap[v.key] = v.value;
|
|
4932
|
+
}
|
|
4933
|
+
for (const v of args.request.contextVars) {
|
|
4934
|
+
if (v.key) ctxMap[v.key] = v.value;
|
|
4935
|
+
}
|
|
4936
|
+
const contextVars = Object.entries(ctxMap).map(([key, value]) => ({ key, value }));
|
|
4937
|
+
const scope = buildScope({
|
|
4938
|
+
contextVars,
|
|
4939
|
+
environments: flatEnvs,
|
|
4940
|
+
activeEnvName: null,
|
|
4941
|
+
// priorityOrder is the sole list the resolver consults.
|
|
4942
|
+
priorityOrder: refs.map(envPriorityKey),
|
|
4943
|
+
secrets: args.secrets ?? {}
|
|
4944
|
+
});
|
|
4945
|
+
const missing = /* @__PURE__ */ new Set();
|
|
4946
|
+
const interp = (s) => {
|
|
4947
|
+
const r = resolveString(s, scope);
|
|
4948
|
+
for (const m of r.missing) missing.add(m);
|
|
4949
|
+
return r.value;
|
|
4950
|
+
};
|
|
4951
|
+
const url = interp(args.request.url);
|
|
4952
|
+
const headers = args.request.headers.map((h) => ({
|
|
4953
|
+
...h,
|
|
4954
|
+
key: interp(h.key),
|
|
4955
|
+
value: interp(h.value)
|
|
4956
|
+
}));
|
|
4957
|
+
const query = args.request.query.map((q) => ({
|
|
4958
|
+
...q,
|
|
4959
|
+
key: interp(q.key),
|
|
4960
|
+
value: interp(q.value)
|
|
4961
|
+
}));
|
|
4962
|
+
let body = args.request.body;
|
|
4963
|
+
if (body.type === "json" || body.type === "text" || body.type === "xml" || body.type === "graphql" || body.type === "urlencoded") {
|
|
4964
|
+
body = { ...body, content: interp(body.content) };
|
|
4965
|
+
} else if (body.type === "form-data" && body.formRows) {
|
|
4966
|
+
body = {
|
|
4967
|
+
...body,
|
|
4968
|
+
formRows: body.formRows.map(
|
|
4969
|
+
(row) => row.kind === "text" ? { ...row, key: interp(row.key), value: interp(row.value) } : { ...row, key: interp(row.key) }
|
|
4970
|
+
)
|
|
4971
|
+
};
|
|
4972
|
+
}
|
|
4973
|
+
const inheritedAuth = resolveInheritedAuth({
|
|
4974
|
+
requestAuth: args.request.auth ?? { type: "none" },
|
|
4975
|
+
folderId: args.request.folderId,
|
|
4976
|
+
folders: args.synced.collections.folders
|
|
4977
|
+
});
|
|
4978
|
+
const auth = interpolateAuthVariables(inheritedAuth, interp);
|
|
4979
|
+
return {
|
|
4980
|
+
request: { ...args.request, url, headers, query, body, auth },
|
|
4981
|
+
scope,
|
|
4982
|
+
missing: [...missing]
|
|
4983
|
+
};
|
|
4984
|
+
}
|
|
4985
|
+
function interpolateAuthVariables(auth, interp) {
|
|
4986
|
+
const resolved = {};
|
|
4987
|
+
for (const [key, value] of Object.entries(auth)) {
|
|
4988
|
+
resolved[key] = key !== "type" && typeof value === "string" ? interp(value) : value;
|
|
4989
|
+
}
|
|
4990
|
+
return resolved;
|
|
4991
|
+
}
|
|
4992
|
+
function applyLinkedEnvironmentOverrides(source, linkedWorkspaceId, synced) {
|
|
4993
|
+
const overrides = Object.values(synced.linkedOverrides.environmentVars).filter(
|
|
4994
|
+
(o) => o.linkedWorkspaceId === linkedWorkspaceId
|
|
4995
|
+
);
|
|
4996
|
+
if (overrides.length === 0) return source;
|
|
4997
|
+
const items = {};
|
|
4998
|
+
for (const [envName, env] of Object.entries(source.items)) {
|
|
4999
|
+
const envOverrides = overrides.filter((o) => o.envName === envName);
|
|
5000
|
+
if (envOverrides.length === 0) {
|
|
5001
|
+
items[envName] = env;
|
|
5002
|
+
continue;
|
|
5003
|
+
}
|
|
5004
|
+
const removed = new Set(envOverrides.filter((o) => o.removed).map((o) => o.varKey));
|
|
5005
|
+
const replaceMap = new Map(envOverrides.filter((o) => !o.removed).map((o) => [o.varKey, o]));
|
|
5006
|
+
const variables = [];
|
|
5007
|
+
const seenKeys = /* @__PURE__ */ new Set();
|
|
5008
|
+
for (const v of env.variables) {
|
|
5009
|
+
if (removed.has(v.key)) continue;
|
|
5010
|
+
const ov = replaceMap.get(v.key);
|
|
5011
|
+
if (ov) {
|
|
5012
|
+
variables.push({
|
|
5013
|
+
key: v.key,
|
|
5014
|
+
value: ov.value ?? v.value,
|
|
5015
|
+
encrypted: ov.encrypted ?? v.encrypted,
|
|
5016
|
+
...ov.secretKeyId !== void 0 ? { secretKeyId: ov.secretKeyId } : v.secretKeyId !== void 0 ? { secretKeyId: v.secretKeyId } : {}
|
|
5017
|
+
});
|
|
5018
|
+
} else {
|
|
5019
|
+
variables.push(v);
|
|
5020
|
+
}
|
|
5021
|
+
seenKeys.add(v.key);
|
|
5022
|
+
}
|
|
5023
|
+
for (const ov of envOverrides) {
|
|
5024
|
+
if (ov.removed) continue;
|
|
5025
|
+
if (seenKeys.has(ov.varKey)) continue;
|
|
5026
|
+
variables.push({
|
|
5027
|
+
key: ov.varKey,
|
|
5028
|
+
value: ov.value ?? "",
|
|
5029
|
+
encrypted: ov.encrypted ?? false,
|
|
5030
|
+
...ov.secretKeyId !== void 0 ? { secretKeyId: ov.secretKeyId } : {}
|
|
5031
|
+
});
|
|
5032
|
+
}
|
|
5033
|
+
items[envName] = { ...env, variables };
|
|
5034
|
+
}
|
|
5035
|
+
return { ...source, items };
|
|
5036
|
+
}
|
|
5037
|
+
function plaintextEnvMap(source) {
|
|
5038
|
+
const out = {};
|
|
5039
|
+
for (const [name, env] of Object.entries(source.items)) {
|
|
5040
|
+
const vars = {};
|
|
5041
|
+
for (const v of env.variables) {
|
|
5042
|
+
if (v.encrypted) continue;
|
|
5043
|
+
vars[v.key] = v.value;
|
|
5044
|
+
}
|
|
5045
|
+
out[name] = vars;
|
|
5046
|
+
}
|
|
5047
|
+
return out;
|
|
5048
|
+
}
|
|
5049
|
+
|
|
4872
5050
|
// src/secrets/crypto.ts
|
|
4873
5051
|
var IV_BYTES = 12;
|
|
4874
5052
|
var SALT_BYTES = 16;
|
|
@@ -4953,6 +5131,95 @@ function base64ToBytes(b64) {
|
|
|
4953
5131
|
return out;
|
|
4954
5132
|
}
|
|
4955
5133
|
|
|
5134
|
+
// src/secrets/passphraseKey.ts
|
|
5135
|
+
var PBKDF2_HASH = "SHA-256";
|
|
5136
|
+
var PBKDF2_ITERATIONS2 = 12e5;
|
|
5137
|
+
var SALT_BYTES2 = 16;
|
|
5138
|
+
var VERIFIER_SENTINEL = "apicircle/passphrase-verifier/v1";
|
|
5139
|
+
function base64Encode2(bytes) {
|
|
5140
|
+
let binary = "";
|
|
5141
|
+
for (let i = 0; i < bytes.length; i++) binary += String.fromCharCode(bytes[i]);
|
|
5142
|
+
return btoa(binary);
|
|
5143
|
+
}
|
|
5144
|
+
function base64Decode2(b64) {
|
|
5145
|
+
const binary = atob(b64);
|
|
5146
|
+
const bytes = new Uint8Array(binary.length);
|
|
5147
|
+
for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);
|
|
5148
|
+
return bytes;
|
|
5149
|
+
}
|
|
5150
|
+
function utf8Bytes(s) {
|
|
5151
|
+
return new TextEncoder().encode(s);
|
|
5152
|
+
}
|
|
5153
|
+
async function deriveKey(passphrase, salt, iterations) {
|
|
5154
|
+
const baseKey = await crypto.subtle.importKey(
|
|
5155
|
+
"raw",
|
|
5156
|
+
utf8Bytes(passphrase),
|
|
5157
|
+
{ name: "PBKDF2" },
|
|
5158
|
+
false,
|
|
5159
|
+
["deriveKey"]
|
|
5160
|
+
);
|
|
5161
|
+
return crypto.subtle.deriveKey(
|
|
5162
|
+
{
|
|
5163
|
+
name: "PBKDF2",
|
|
5164
|
+
salt,
|
|
5165
|
+
iterations,
|
|
5166
|
+
hash: PBKDF2_HASH
|
|
5167
|
+
},
|
|
5168
|
+
baseKey,
|
|
5169
|
+
{ name: "AES-GCM", length: 256 },
|
|
5170
|
+
/* extractable */
|
|
5171
|
+
false,
|
|
5172
|
+
["encrypt", "decrypt"]
|
|
5173
|
+
);
|
|
5174
|
+
}
|
|
5175
|
+
async function computeVerifier(key) {
|
|
5176
|
+
const iv = new Uint8Array(12);
|
|
5177
|
+
const ct = await crypto.subtle.encrypt(
|
|
5178
|
+
{ name: "AES-GCM", iv },
|
|
5179
|
+
key,
|
|
5180
|
+
utf8Bytes(VERIFIER_SENTINEL)
|
|
5181
|
+
);
|
|
5182
|
+
return base64Encode2(new Uint8Array(ct));
|
|
5183
|
+
}
|
|
5184
|
+
async function initSecretCrypto(passphrase, iterations = PBKDF2_ITERATIONS2) {
|
|
5185
|
+
if (passphrase.length === 0) throw new Error("Passphrase cannot be empty");
|
|
5186
|
+
if (iterations < 1) throw new Error("iterations must be >= 1");
|
|
5187
|
+
const salt = crypto.getRandomValues(new Uint8Array(SALT_BYTES2));
|
|
5188
|
+
const key = await deriveKey(passphrase, salt, iterations);
|
|
5189
|
+
const verifier = await computeVerifier(key);
|
|
5190
|
+
return {
|
|
5191
|
+
crypto: {
|
|
5192
|
+
kdf: "pbkdf2-sha256-v1",
|
|
5193
|
+
salt: base64Encode2(salt),
|
|
5194
|
+
iterations,
|
|
5195
|
+
verifier
|
|
5196
|
+
},
|
|
5197
|
+
key
|
|
5198
|
+
};
|
|
5199
|
+
}
|
|
5200
|
+
async function unlockSecretCrypto(passphrase, blob) {
|
|
5201
|
+
if (blob.kdf !== "pbkdf2-sha256-v1") {
|
|
5202
|
+
return { ok: false, reason: `Unsupported KDF: ${String(blob.kdf)}` };
|
|
5203
|
+
}
|
|
5204
|
+
let salt;
|
|
5205
|
+
try {
|
|
5206
|
+
salt = base64Decode2(blob.salt);
|
|
5207
|
+
} catch {
|
|
5208
|
+
return { ok: false, reason: "Workspace secret salt is corrupt." };
|
|
5209
|
+
}
|
|
5210
|
+
let key;
|
|
5211
|
+
try {
|
|
5212
|
+
key = await deriveKey(passphrase, salt, blob.iterations);
|
|
5213
|
+
} catch (err) {
|
|
5214
|
+
return { ok: false, reason: err instanceof Error ? err.message : "Key derivation failed" };
|
|
5215
|
+
}
|
|
5216
|
+
const verifier = await computeVerifier(key);
|
|
5217
|
+
if (verifier !== blob.verifier) {
|
|
5218
|
+
return { ok: false, reason: "Wrong passphrase." };
|
|
5219
|
+
}
|
|
5220
|
+
return { ok: true, key };
|
|
5221
|
+
}
|
|
5222
|
+
|
|
4956
5223
|
// src/git/branchNames.ts
|
|
4957
5224
|
var SLUG_FALLBACK = "workspace";
|
|
4958
5225
|
var SUFFIX_LEN = 6;
|
|
@@ -5012,10 +5279,32 @@ function sortedReplacer(_key, value) {
|
|
|
5012
5279
|
|
|
5013
5280
|
// src/git/repoPaths.ts
|
|
5014
5281
|
var WORKSPACE_DIR = ".apicircle";
|
|
5015
|
-
var
|
|
5016
|
-
|
|
5017
|
-
|
|
5018
|
-
|
|
5282
|
+
var REGISTRY_JSON_PATH = `${WORKSPACE_DIR}/registry.json`;
|
|
5283
|
+
function workspaceJsonPath(workspaceId) {
|
|
5284
|
+
return `${WORKSPACE_DIR}/workspace-${workspaceId}/workspace.json`;
|
|
5285
|
+
}
|
|
5286
|
+
function attachmentsDir(workspaceId) {
|
|
5287
|
+
return `${WORKSPACE_DIR}/workspace-${workspaceId}/attachments`;
|
|
5288
|
+
}
|
|
5289
|
+
function attachmentPath(workspaceId, slotId) {
|
|
5290
|
+
return `${attachmentsDir(workspaceId)}/${slotId}`;
|
|
5291
|
+
}
|
|
5292
|
+
function parseRegistryActiveId(registryJsonContent) {
|
|
5293
|
+
try {
|
|
5294
|
+
const parsed = JSON.parse(registryJsonContent);
|
|
5295
|
+
return parsed.activeWorkspaceId ?? parsed.workspaces?.[0]?.id ?? null;
|
|
5296
|
+
} catch {
|
|
5297
|
+
return null;
|
|
5298
|
+
}
|
|
5299
|
+
}
|
|
5300
|
+
async function fetchRemoteWorkspaceJson(fetchFile) {
|
|
5301
|
+
const registryContent = await fetchFile(REGISTRY_JSON_PATH);
|
|
5302
|
+
if (registryContent === null) return { error: "No .apicircle/registry.json found in repo" };
|
|
5303
|
+
const wsId = parseRegistryActiveId(registryContent);
|
|
5304
|
+
if (!wsId) return { error: "Registry is empty \u2014 no workspaces found" };
|
|
5305
|
+
const wsContent = await fetchFile(workspaceJsonPath(wsId));
|
|
5306
|
+
if (wsContent === null) return { error: `No workspace.json at .apicircle/workspace-${wsId}/` };
|
|
5307
|
+
return { workspaceId: wsId, content: wsContent };
|
|
5019
5308
|
}
|
|
5020
5309
|
|
|
5021
5310
|
// src/git/parseWorkspaceJson.ts
|
|
@@ -5274,18 +5563,14 @@ function sortVersionsDesc(versions) {
|
|
|
5274
5563
|
}
|
|
5275
5564
|
|
|
5276
5565
|
// src/release/publishRelease.ts
|
|
5277
|
-
async function
|
|
5566
|
+
async function buildReleaseEntry(synced, args) {
|
|
5278
5567
|
const version = args.version.trim();
|
|
5279
5568
|
if (!isValidSemver(version)) {
|
|
5280
5569
|
throw new Error(`Invalid semver: ${args.version}`);
|
|
5281
5570
|
}
|
|
5282
|
-
const ledger = synced.releases.self ?? emptyLedger();
|
|
5283
|
-
if (ledger.versions.some((v) => v.version === version)) {
|
|
5284
|
-
throw new Error(`Version ${version} already exists in this workspace's release ledger`);
|
|
5285
|
-
}
|
|
5286
5571
|
const snapshotSource = serializeWorkspaceForGit(synced);
|
|
5287
5572
|
const workspaceSnapshot = await sha256Hex2(snapshotSource);
|
|
5288
|
-
|
|
5573
|
+
return {
|
|
5289
5574
|
version,
|
|
5290
5575
|
publishedAt: args.publishedAt ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
5291
5576
|
notes: args.notes,
|
|
@@ -5295,23 +5580,36 @@ async function publishRelease(synced, args) {
|
|
|
5295
5580
|
...args.sha ? { sha: args.sha } : {},
|
|
5296
5581
|
...args.tagName ? { tagName: args.tagName } : {}
|
|
5297
5582
|
};
|
|
5583
|
+
}
|
|
5584
|
+
function appendReleaseEntry(synced, entry, now = entry.publishedAt) {
|
|
5585
|
+
if (!isValidSemver(entry.version)) {
|
|
5586
|
+
throw new Error(`Invalid semver: ${entry.version}`);
|
|
5587
|
+
}
|
|
5588
|
+
const ledger = synced.releases.self ?? emptyLedger();
|
|
5589
|
+
if (ledger.versions.some((v) => v.version === entry.version)) {
|
|
5590
|
+
throw new Error(`Version ${entry.version} already exists in this workspace's release ledger`);
|
|
5591
|
+
}
|
|
5298
5592
|
const next = {
|
|
5299
5593
|
versions: [...ledger.versions, entry],
|
|
5300
|
-
currentVersion: version
|
|
5594
|
+
currentVersion: entry.version
|
|
5301
5595
|
};
|
|
5302
5596
|
return {
|
|
5303
5597
|
...synced,
|
|
5304
5598
|
releases: { ...synced.releases, self: next },
|
|
5305
|
-
meta: { ...synced.meta, updatedAt:
|
|
5599
|
+
meta: { ...synced.meta, updatedAt: now }
|
|
5306
5600
|
};
|
|
5307
5601
|
}
|
|
5308
|
-
function
|
|
5309
|
-
|
|
5602
|
+
async function publishRelease(synced, args) {
|
|
5603
|
+
const entry = await buildReleaseEntry(synced, args);
|
|
5604
|
+
return appendReleaseEntry(synced, entry);
|
|
5605
|
+
}
|
|
5606
|
+
function deprecateRelease(synced, version, now = (/* @__PURE__ */ new Date()).toISOString()) {
|
|
5607
|
+
return mapReleaseVersion(synced, version, (v) => ({ ...v, deprecated: true }), now);
|
|
5310
5608
|
}
|
|
5311
|
-
function yankRelease(synced, version) {
|
|
5312
|
-
return mapReleaseVersion(synced, version, (v) => ({ ...v, yanked: true }));
|
|
5609
|
+
function yankRelease(synced, version, now = (/* @__PURE__ */ new Date()).toISOString()) {
|
|
5610
|
+
return mapReleaseVersion(synced, version, (v) => ({ ...v, yanked: true }), now);
|
|
5313
5611
|
}
|
|
5314
|
-
function mapReleaseVersion(synced, version, fn) {
|
|
5612
|
+
function mapReleaseVersion(synced, version, fn, now) {
|
|
5315
5613
|
const ledger = synced.releases.self;
|
|
5316
5614
|
if (!ledger) throw new Error("No releases to modify");
|
|
5317
5615
|
const idx = ledger.versions.findIndex((v) => v.version === version);
|
|
@@ -5321,7 +5619,7 @@ function mapReleaseVersion(synced, version, fn) {
|
|
|
5321
5619
|
return {
|
|
5322
5620
|
...synced,
|
|
5323
5621
|
releases: { ...synced.releases, self: { ...ledger, versions } },
|
|
5324
|
-
meta: { ...synced.meta, updatedAt:
|
|
5622
|
+
meta: { ...synced.meta, updatedAt: now }
|
|
5325
5623
|
};
|
|
5326
5624
|
}
|
|
5327
5625
|
function emptyLedger() {
|
|
@@ -5333,6 +5631,99 @@ async function sha256Hex2(text) {
|
|
|
5333
5631
|
return [...new Uint8Array(digest)].map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
5334
5632
|
}
|
|
5335
5633
|
|
|
5634
|
+
// src/linked/linkedSnapshot.ts
|
|
5635
|
+
var LINKED_FORBIDDEN_KEYS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
|
|
5636
|
+
var MAX_LINKED_JSON_BYTES = 16 * 1024 * 1024;
|
|
5637
|
+
function parseLinkedWorkspaceJson(text) {
|
|
5638
|
+
if (text.length > MAX_LINKED_JSON_BYTES) {
|
|
5639
|
+
throw new Error("Remote workspace.json exceeds 16 MiB");
|
|
5640
|
+
}
|
|
5641
|
+
let raw;
|
|
5642
|
+
try {
|
|
5643
|
+
raw = JSON.parse(
|
|
5644
|
+
text,
|
|
5645
|
+
(key, value) => LINKED_FORBIDDEN_KEYS.has(key) ? void 0 : value
|
|
5646
|
+
);
|
|
5647
|
+
} catch {
|
|
5648
|
+
throw new Error("Remote workspace.json is not valid JSON");
|
|
5649
|
+
}
|
|
5650
|
+
if (typeof raw !== "object" || raw === null || Array.isArray(raw)) {
|
|
5651
|
+
throw new Error("Remote workspace.json is not an object");
|
|
5652
|
+
}
|
|
5653
|
+
const obj = raw;
|
|
5654
|
+
const asObject = (v) => typeof v === "object" && v !== null ? v : void 0;
|
|
5655
|
+
return {
|
|
5656
|
+
workspaceId: typeof obj.workspaceId === "string" ? obj.workspaceId : void 0,
|
|
5657
|
+
releases: asObject(obj.releases),
|
|
5658
|
+
collections: asObject(obj.collections),
|
|
5659
|
+
environments: asObject(obj.environments),
|
|
5660
|
+
secretKeys: asObject(obj.secretKeys),
|
|
5661
|
+
globalAssets: asObject(obj.globalAssets)
|
|
5662
|
+
};
|
|
5663
|
+
}
|
|
5664
|
+
function ledgerFromProbe(parsed) {
|
|
5665
|
+
return parsed.releases?.self ?? { versions: [], currentVersion: null };
|
|
5666
|
+
}
|
|
5667
|
+
function buildLinkedSnapshot(parsed, link) {
|
|
5668
|
+
if (!parsed.collections && !parsed.environments) return null;
|
|
5669
|
+
return {
|
|
5670
|
+
pulledAt: link.linkedAt,
|
|
5671
|
+
ref: link.pinnedVersion ? `v${link.pinnedVersion}` : `HEAD@${link.source.branch}`,
|
|
5672
|
+
collections: parsed.collections ?? {
|
|
5673
|
+
tree: { id: "remote-root", type: "root", children: [] },
|
|
5674
|
+
requests: {},
|
|
5675
|
+
folders: {}
|
|
5676
|
+
},
|
|
5677
|
+
environments: parsed.environments ?? {
|
|
5678
|
+
items: {},
|
|
5679
|
+
activeName: null,
|
|
5680
|
+
priorityOrder: []
|
|
5681
|
+
},
|
|
5682
|
+
...parsed.secretKeys ? { secretKeys: parsed.secretKeys } : {},
|
|
5683
|
+
...parsed.globalAssets ? { globalAssets: parsed.globalAssets } : {}
|
|
5684
|
+
};
|
|
5685
|
+
}
|
|
5686
|
+
|
|
5687
|
+
// src/linked/requestOverride.ts
|
|
5688
|
+
var OVERRIDABLE_FIELDS = [
|
|
5689
|
+
"name",
|
|
5690
|
+
"method",
|
|
5691
|
+
"url",
|
|
5692
|
+
"headers",
|
|
5693
|
+
"query",
|
|
5694
|
+
"pathParams",
|
|
5695
|
+
"cookies",
|
|
5696
|
+
"body",
|
|
5697
|
+
"auth",
|
|
5698
|
+
"contextVars",
|
|
5699
|
+
"extractions",
|
|
5700
|
+
"assertions"
|
|
5701
|
+
];
|
|
5702
|
+
function mergeRequestOverride(base, patch) {
|
|
5703
|
+
const merged = { ...base };
|
|
5704
|
+
const p = patch;
|
|
5705
|
+
const target = merged;
|
|
5706
|
+
for (const field of OVERRIDABLE_FIELDS) {
|
|
5707
|
+
if (p[field] !== void 0) target[field] = p[field];
|
|
5708
|
+
}
|
|
5709
|
+
return merged;
|
|
5710
|
+
}
|
|
5711
|
+
function computeRequestOverridePatch(base, effective) {
|
|
5712
|
+
const baseRec = { ...base };
|
|
5713
|
+
const effRec = { ...effective };
|
|
5714
|
+
const patch = {};
|
|
5715
|
+
const patchRec = patch;
|
|
5716
|
+
for (const field of OVERRIDABLE_FIELDS) {
|
|
5717
|
+
if (JSON.stringify(baseRec[field]) !== JSON.stringify(effRec[field])) {
|
|
5718
|
+
patchRec[field] = effRec[field];
|
|
5719
|
+
}
|
|
5720
|
+
}
|
|
5721
|
+
return patch;
|
|
5722
|
+
}
|
|
5723
|
+
function isEmptyOverridePatch(patch) {
|
|
5724
|
+
return Object.keys(patch).filter((k) => OVERRIDABLE_FIELDS.includes(k)).length === 0;
|
|
5725
|
+
}
|
|
5726
|
+
|
|
5336
5727
|
// src/editors/contentTypeLanguageMap.ts
|
|
5337
5728
|
var CONTENT_TYPE_LANGUAGE_MAP = {
|
|
5338
5729
|
"application/json": "json",
|
|
@@ -6265,7 +6656,8 @@ function previewLinkedUpdate(args) {
|
|
|
6265
6656
|
status,
|
|
6266
6657
|
base,
|
|
6267
6658
|
target,
|
|
6268
|
-
override
|
|
6659
|
+
override,
|
|
6660
|
+
...status === "both-changed" && base && target && override ? { autoMergeable: requestOverrideIsDisjoint(base, target, override) } : {}
|
|
6269
6661
|
});
|
|
6270
6662
|
}
|
|
6271
6663
|
const baseFolders = args.base?.collections.folders ?? {};
|
|
@@ -6345,6 +6737,34 @@ function classifyRequest(base, target, override) {
|
|
|
6345
6737
|
if (sourceChanged && !hasOverride) return "source-only";
|
|
6346
6738
|
return "both-changed";
|
|
6347
6739
|
}
|
|
6740
|
+
var OVERRIDABLE_REQUEST_FIELDS = [
|
|
6741
|
+
"name",
|
|
6742
|
+
"method",
|
|
6743
|
+
"url",
|
|
6744
|
+
"headers",
|
|
6745
|
+
"query",
|
|
6746
|
+
"pathParams",
|
|
6747
|
+
"cookies",
|
|
6748
|
+
"body",
|
|
6749
|
+
"auth",
|
|
6750
|
+
"contextVars",
|
|
6751
|
+
"extractions",
|
|
6752
|
+
"assertions"
|
|
6753
|
+
];
|
|
6754
|
+
function requestOverrideIsDisjoint(base, target, override) {
|
|
6755
|
+
const baseRec = { ...base };
|
|
6756
|
+
const targetRec = { ...target };
|
|
6757
|
+
const overriddenFields = Object.keys(override.patch);
|
|
6758
|
+
for (const f of overriddenFields) {
|
|
6759
|
+
if (!OVERRIDABLE_REQUEST_FIELDS.includes(f)) {
|
|
6760
|
+
continue;
|
|
6761
|
+
}
|
|
6762
|
+
if (!structurallyEqual2(baseRec[f], targetRec[f])) {
|
|
6763
|
+
return false;
|
|
6764
|
+
}
|
|
6765
|
+
}
|
|
6766
|
+
return true;
|
|
6767
|
+
}
|
|
6348
6768
|
function classifyFolder(base, target) {
|
|
6349
6769
|
if (!base && target) return "new-in-source";
|
|
6350
6770
|
if (base && !target) return "removed-in-source";
|
|
@@ -6394,7 +6814,7 @@ function applyLinkedUpdate(args) {
|
|
|
6394
6814
|
continue;
|
|
6395
6815
|
}
|
|
6396
6816
|
if (entry.status === "both-changed") {
|
|
6397
|
-
const choice = args.resolutions[id];
|
|
6817
|
+
const choice = args.resolutions[id] ?? (entry.autoMergeable ? "mine" : void 0);
|
|
6398
6818
|
if (!choice) {
|
|
6399
6819
|
throw new Error(
|
|
6400
6820
|
`applyLinkedUpdate: unresolved both-changed entry "${entry.label}" (${id})`
|
|
@@ -6405,7 +6825,8 @@ function applyLinkedUpdate(args) {
|
|
|
6405
6825
|
else if (entry.bucket === "environment-var") envVarOverridesByKey.delete(entry.key);
|
|
6406
6826
|
log.push({ entryKey: id, bucket: entry.bucket, action: "accept-source" });
|
|
6407
6827
|
} else {
|
|
6408
|
-
|
|
6828
|
+
const auto = entry.autoMergeable === true && !args.resolutions[id];
|
|
6829
|
+
log.push({ entryKey: id, bucket: entry.bucket, action: auto ? "auto-merge" : "keep-mine" });
|
|
6409
6830
|
}
|
|
6410
6831
|
}
|
|
6411
6832
|
}
|
|
@@ -6421,7 +6842,7 @@ function structurallyEqual2(a, b) {
|
|
|
6421
6842
|
}
|
|
6422
6843
|
|
|
6423
6844
|
// src/workspace/applyMutation.ts
|
|
6424
|
-
import { envPriorityKey, generateId as generateId2 } from "@apicircle/shared";
|
|
6845
|
+
import { envPriorityKey as envPriorityKey2, generateId as generateId2 } from "@apicircle/shared";
|
|
6425
6846
|
|
|
6426
6847
|
// src/workspace/apicircleFolderImport.ts
|
|
6427
6848
|
function importApicircleFolderInto(synced, parsed, parentFolderId) {
|
|
@@ -6662,6 +7083,8 @@ function applyMutation(state, patch, options = {}) {
|
|
|
6662
7083
|
return applyFolderDelete(state, patch.id, now);
|
|
6663
7084
|
case "folder.move":
|
|
6664
7085
|
return applyFolderMove(state, patch.id, patch.newParentId, now);
|
|
7086
|
+
case "folder.update":
|
|
7087
|
+
return applyFolderUpdate(state, patch.id, patch.patch, now);
|
|
6665
7088
|
case "folder.import_apicircle":
|
|
6666
7089
|
return applyFolderImportApicircle(state, patch.parsed, patch.parentFolderId, now);
|
|
6667
7090
|
case "environment.upsert":
|
|
@@ -6674,6 +7097,10 @@ function applyMutation(state, patch, options = {}) {
|
|
|
6674
7097
|
return applyEnvSetPriority(state, patch.order, now);
|
|
6675
7098
|
case "secretKey.upsert":
|
|
6676
7099
|
return applySecretKeyUpsert(state, patch.meta, now);
|
|
7100
|
+
case "secret.crypto.set":
|
|
7101
|
+
return applySecretCryptoSet(state, patch.crypto, now);
|
|
7102
|
+
case "secret.crypto.clear":
|
|
7103
|
+
return applySecretCryptoClear(state, now);
|
|
6677
7104
|
case "assertion.upsert":
|
|
6678
7105
|
return applyAssertionUpsert(state, patch.requestId, patch.assertion, now);
|
|
6679
7106
|
case "assertion.delete":
|
|
@@ -6682,6 +7109,34 @@ function applyMutation(state, patch, options = {}) {
|
|
|
6682
7109
|
return applyMockUpsert(state, patch.mock, now);
|
|
6683
7110
|
case "mock.delete":
|
|
6684
7111
|
return applyMockDelete(state, patch.id, now);
|
|
7112
|
+
case "release.publish":
|
|
7113
|
+
return applyReleasePublish(state, patch.entry, now);
|
|
7114
|
+
case "release.deprecate":
|
|
7115
|
+
return applyReleaseDeprecate(state, patch.version, now);
|
|
7116
|
+
case "release.yank":
|
|
7117
|
+
return applyReleaseYank(state, patch.version, now);
|
|
7118
|
+
case "linkedWorkspace.upsert":
|
|
7119
|
+
return applyLinkedWorkspaceUpsert(state, patch.link, patch.ledger, patch.snapshot, now);
|
|
7120
|
+
case "linkedWorkspace.remove":
|
|
7121
|
+
return applyLinkedWorkspaceRemove(state, patch.id, now);
|
|
7122
|
+
case "linkedWorkspace.applyUpdate":
|
|
7123
|
+
return applyLinkedWorkspaceApplyUpdate(state, patch, now);
|
|
7124
|
+
case "linkedOverride.setRequest":
|
|
7125
|
+
return applyLinkedOverrideSetRequest(state, patch.override, now);
|
|
7126
|
+
case "linkedOverride.removeRequest":
|
|
7127
|
+
return applyLinkedOverrideRemoveRequest(state, patch.linkedWorkspaceId, patch.itemId, now);
|
|
7128
|
+
case "linkedOverride.setEnvVar":
|
|
7129
|
+
return applyLinkedOverrideSetEnvVar(state, patch.override, now);
|
|
7130
|
+
case "linkedOverride.removeEnvVar":
|
|
7131
|
+
return applyLinkedOverrideRemoveEnvVar(
|
|
7132
|
+
state,
|
|
7133
|
+
patch.linkedWorkspaceId,
|
|
7134
|
+
patch.envName,
|
|
7135
|
+
patch.varKey,
|
|
7136
|
+
now
|
|
7137
|
+
);
|
|
7138
|
+
case "linkedOverride.clearForLink":
|
|
7139
|
+
return applyLinkedOverrideClearForLink(state, patch.linkedWorkspaceId, now);
|
|
6685
7140
|
case "globalAsset.upsertFile":
|
|
6686
7141
|
return applyGlobalAssetUpsertFile(state, patch.file, now);
|
|
6687
7142
|
case "globalAsset.removeFile":
|
|
@@ -6718,12 +7173,13 @@ function applyRequestCreate(state, request, now) {
|
|
|
6718
7173
|
if (state.synced.collections.requests[request.id]) {
|
|
6719
7174
|
return { next: state, changedIds: [] };
|
|
6720
7175
|
}
|
|
7176
|
+
const tree = request.folderId ? state.synced.collections.tree : pushTreeChild(state.synced.collections.tree, { kind: "request", id: request.id });
|
|
6721
7177
|
const synced = {
|
|
6722
7178
|
...state.synced,
|
|
6723
7179
|
collections: {
|
|
6724
7180
|
...state.synced.collections,
|
|
6725
7181
|
requests: { ...state.synced.collections.requests, [request.id]: request },
|
|
6726
|
-
tree
|
|
7182
|
+
tree
|
|
6727
7183
|
},
|
|
6728
7184
|
meta: { ...state.synced.meta, updatedAt: now }
|
|
6729
7185
|
};
|
|
@@ -6772,12 +7228,13 @@ function applyFolderCreate(state, folder, now) {
|
|
|
6772
7228
|
if (state.synced.collections.folders[folder.id]) {
|
|
6773
7229
|
return { next: state, changedIds: [] };
|
|
6774
7230
|
}
|
|
7231
|
+
const tree = folder.parentId ? state.synced.collections.tree : pushTreeChild(state.synced.collections.tree, { kind: "folder", id: folder.id });
|
|
6775
7232
|
const synced = {
|
|
6776
7233
|
...state.synced,
|
|
6777
7234
|
collections: {
|
|
6778
7235
|
...state.synced.collections,
|
|
6779
7236
|
folders: { ...state.synced.collections.folders, [folder.id]: folder },
|
|
6780
|
-
tree
|
|
7237
|
+
tree
|
|
6781
7238
|
},
|
|
6782
7239
|
meta: { ...state.synced.meta, updatedAt: now }
|
|
6783
7240
|
};
|
|
@@ -6846,6 +7303,57 @@ function applyFolderMove(state, id, newParentId, now) {
|
|
|
6846
7303
|
};
|
|
6847
7304
|
return { next: { ...state, synced }, changedIds: [id] };
|
|
6848
7305
|
}
|
|
7306
|
+
function applyFolderUpdate(state, id, patch, now) {
|
|
7307
|
+
const folder = state.synced.collections.folders[id];
|
|
7308
|
+
if (!folder) {
|
|
7309
|
+
return { next: state, changedIds: [] };
|
|
7310
|
+
}
|
|
7311
|
+
const nameChanging = "name" in patch && patch.name !== void 0;
|
|
7312
|
+
const authChanging = "auth" in patch;
|
|
7313
|
+
if (!nameChanging && !authChanging) {
|
|
7314
|
+
return { next: state, changedIds: [] };
|
|
7315
|
+
}
|
|
7316
|
+
let nextName = folder.name;
|
|
7317
|
+
if (nameChanging) {
|
|
7318
|
+
const trimmed = patch.name.trim();
|
|
7319
|
+
if (!trimmed) {
|
|
7320
|
+
} else if (trimmed === folder.name) {
|
|
7321
|
+
} else if (!isFolderNameUnique(state, folder.parentId, trimmed, id)) {
|
|
7322
|
+
return { next: state, changedIds: [] };
|
|
7323
|
+
} else {
|
|
7324
|
+
nextName = trimmed;
|
|
7325
|
+
}
|
|
7326
|
+
}
|
|
7327
|
+
const nextFolder = { ...folder, name: nextName };
|
|
7328
|
+
if (authChanging) {
|
|
7329
|
+
if (patch.auth === void 0) {
|
|
7330
|
+
delete nextFolder.auth;
|
|
7331
|
+
} else {
|
|
7332
|
+
nextFolder.auth = patch.auth;
|
|
7333
|
+
}
|
|
7334
|
+
}
|
|
7335
|
+
if (nextFolder.name === folder.name && nextFolder.auth === folder.auth) {
|
|
7336
|
+
return { next: state, changedIds: [] };
|
|
7337
|
+
}
|
|
7338
|
+
const synced = {
|
|
7339
|
+
...state.synced,
|
|
7340
|
+
collections: {
|
|
7341
|
+
...state.synced.collections,
|
|
7342
|
+
folders: { ...state.synced.collections.folders, [id]: nextFolder }
|
|
7343
|
+
},
|
|
7344
|
+
meta: { ...state.synced.meta, updatedAt: now }
|
|
7345
|
+
};
|
|
7346
|
+
return { next: { ...state, synced }, changedIds: [id] };
|
|
7347
|
+
}
|
|
7348
|
+
function isFolderNameUnique(state, parentId, trimmedCandidate, ignoreId) {
|
|
7349
|
+
const target = trimmedCandidate.toLowerCase();
|
|
7350
|
+
for (const f of Object.values(state.synced.collections.folders)) {
|
|
7351
|
+
if (f.id === ignoreId) continue;
|
|
7352
|
+
if (f.parentId !== parentId) continue;
|
|
7353
|
+
if (f.name.trim().toLowerCase() === target) return false;
|
|
7354
|
+
}
|
|
7355
|
+
return true;
|
|
7356
|
+
}
|
|
6849
7357
|
function applyFolderImportApicircle(state, parsed, parentFolderId, now) {
|
|
6850
7358
|
const result = importApicircleFolderInto(
|
|
6851
7359
|
state.synced,
|
|
@@ -6925,7 +7433,7 @@ function applyEnvSetPriority(state, order, now) {
|
|
|
6925
7433
|
const knownLocal = new Set(Object.keys(state.synced.environments.items));
|
|
6926
7434
|
const seen = /* @__PURE__ */ new Set();
|
|
6927
7435
|
const filtered = order.filter((ref) => {
|
|
6928
|
-
const key =
|
|
7436
|
+
const key = envPriorityKey2(ref);
|
|
6929
7437
|
if (seen.has(key)) return false;
|
|
6930
7438
|
if (ref.kind === "local" && !knownLocal.has(ref.name)) return false;
|
|
6931
7439
|
seen.add(key);
|
|
@@ -6936,7 +7444,7 @@ function applyEnvSetPriority(state, order, now) {
|
|
|
6936
7444
|
environments: { ...state.synced.environments, priorityOrder: filtered },
|
|
6937
7445
|
meta: { ...state.synced.meta, updatedAt: now }
|
|
6938
7446
|
};
|
|
6939
|
-
return { next: { ...state, synced }, changedIds: filtered.map(
|
|
7447
|
+
return { next: { ...state, synced }, changedIds: filtered.map(envPriorityKey2) };
|
|
6940
7448
|
}
|
|
6941
7449
|
function applySecretKeyUpsert(state, meta, now) {
|
|
6942
7450
|
if (!meta.id || !meta.label.trim() || !meta.salt) {
|
|
@@ -6952,6 +7460,28 @@ function applySecretKeyUpsert(state, meta, now) {
|
|
|
6952
7460
|
};
|
|
6953
7461
|
return { next: { ...state, synced }, changedIds: [meta.id] };
|
|
6954
7462
|
}
|
|
7463
|
+
function applySecretCryptoSet(state, crypto2, now) {
|
|
7464
|
+
if (!crypto2 || crypto2.kdf !== "pbkdf2-sha256-v1" || !crypto2.salt || !crypto2.verifier || !(crypto2.iterations >= 1)) {
|
|
7465
|
+
return { next: state, changedIds: [] };
|
|
7466
|
+
}
|
|
7467
|
+
const synced = {
|
|
7468
|
+
...state.synced,
|
|
7469
|
+
secretCrypto: { ...crypto2 },
|
|
7470
|
+
meta: { ...state.synced.meta, updatedAt: now }
|
|
7471
|
+
};
|
|
7472
|
+
return { next: { ...state, synced }, changedIds: ["secret.crypto"] };
|
|
7473
|
+
}
|
|
7474
|
+
function applySecretCryptoClear(state, now) {
|
|
7475
|
+
if (!state.synced.secretCrypto) {
|
|
7476
|
+
return { next: state, changedIds: [] };
|
|
7477
|
+
}
|
|
7478
|
+
const synced = {
|
|
7479
|
+
...state.synced,
|
|
7480
|
+
secretCrypto: null,
|
|
7481
|
+
meta: { ...state.synced.meta, updatedAt: now }
|
|
7482
|
+
};
|
|
7483
|
+
return { next: { ...state, synced }, changedIds: ["secret.crypto"] };
|
|
7484
|
+
}
|
|
6955
7485
|
function applyAssertionUpsert(state, requestId, assertion, now) {
|
|
6956
7486
|
const request = state.synced.collections.requests[requestId];
|
|
6957
7487
|
if (!request) {
|
|
@@ -7009,6 +7539,191 @@ function applyMockDelete(state, id, now) {
|
|
|
7009
7539
|
} : state.local;
|
|
7010
7540
|
return { next: { synced, local }, changedIds: [id] };
|
|
7011
7541
|
}
|
|
7542
|
+
function applyReleasePublish(state, entry, now) {
|
|
7543
|
+
const synced = appendReleaseEntry(state.synced, entry, now);
|
|
7544
|
+
return { next: { ...state, synced }, changedIds: [entry.version] };
|
|
7545
|
+
}
|
|
7546
|
+
function applyReleaseDeprecate(state, version, now) {
|
|
7547
|
+
const synced = deprecateRelease(state.synced, version, now);
|
|
7548
|
+
return { next: { ...state, synced }, changedIds: [version] };
|
|
7549
|
+
}
|
|
7550
|
+
function applyReleaseYank(state, version, now) {
|
|
7551
|
+
const synced = yankRelease(state.synced, version, now);
|
|
7552
|
+
return { next: { ...state, synced }, changedIds: [version] };
|
|
7553
|
+
}
|
|
7554
|
+
function applyLinkedWorkspaceUpsert(state, link, ledger, snapshot2, now) {
|
|
7555
|
+
const synced = {
|
|
7556
|
+
...state.synced,
|
|
7557
|
+
linkedWorkspaces: { ...state.synced.linkedWorkspaces, [link.id]: link },
|
|
7558
|
+
releases: ledger ? {
|
|
7559
|
+
...state.synced.releases,
|
|
7560
|
+
perLink: { ...state.synced.releases.perLink, [link.id]: ledger }
|
|
7561
|
+
} : state.synced.releases,
|
|
7562
|
+
meta: { ...state.synced.meta, updatedAt: now }
|
|
7563
|
+
};
|
|
7564
|
+
const local = snapshot2 ? {
|
|
7565
|
+
...state.local,
|
|
7566
|
+
linkedCollections: { ...state.local.linkedCollections, [link.id]: snapshot2 }
|
|
7567
|
+
} : state.local;
|
|
7568
|
+
return { next: { synced, local }, changedIds: [link.id] };
|
|
7569
|
+
}
|
|
7570
|
+
function applyLinkedWorkspaceRemove(state, id, now) {
|
|
7571
|
+
if (!state.synced.linkedWorkspaces[id]) {
|
|
7572
|
+
return { next: state, changedIds: [] };
|
|
7573
|
+
}
|
|
7574
|
+
const linkedWorkspaces = { ...state.synced.linkedWorkspaces };
|
|
7575
|
+
delete linkedWorkspaces[id];
|
|
7576
|
+
const perLink = { ...state.synced.releases.perLink };
|
|
7577
|
+
delete perLink[id];
|
|
7578
|
+
const prefix = `${id}:`;
|
|
7579
|
+
const dropPrefixed = (map) => Object.fromEntries(Object.entries(map).filter(([k]) => !k.startsWith(prefix)));
|
|
7580
|
+
const synced = {
|
|
7581
|
+
...state.synced,
|
|
7582
|
+
linkedWorkspaces,
|
|
7583
|
+
releases: { ...state.synced.releases, perLink },
|
|
7584
|
+
linkedOverrides: {
|
|
7585
|
+
requests: dropPrefixed(state.synced.linkedOverrides.requests),
|
|
7586
|
+
environmentVars: dropPrefixed(state.synced.linkedOverrides.environmentVars)
|
|
7587
|
+
},
|
|
7588
|
+
meta: { ...state.synced.meta, updatedAt: now }
|
|
7589
|
+
};
|
|
7590
|
+
const linkedCollections = { ...state.local.linkedCollections };
|
|
7591
|
+
delete linkedCollections[id];
|
|
7592
|
+
const githubLinks = { ...state.local.sessions.github.links };
|
|
7593
|
+
delete githubLinks[id];
|
|
7594
|
+
const local = {
|
|
7595
|
+
...state.local,
|
|
7596
|
+
linkedCollections,
|
|
7597
|
+
sessions: {
|
|
7598
|
+
...state.local.sessions,
|
|
7599
|
+
github: { ...state.local.sessions.github, links: githubLinks }
|
|
7600
|
+
}
|
|
7601
|
+
};
|
|
7602
|
+
return { next: { synced, local }, changedIds: [id] };
|
|
7603
|
+
}
|
|
7604
|
+
function applyLinkedWorkspaceApplyUpdate(state, patch, now) {
|
|
7605
|
+
const link = state.synced.linkedWorkspaces[patch.id];
|
|
7606
|
+
if (!link) {
|
|
7607
|
+
return { next: state, changedIds: [] };
|
|
7608
|
+
}
|
|
7609
|
+
const prefix = `${patch.id}:`;
|
|
7610
|
+
const otherRequests = Object.fromEntries(
|
|
7611
|
+
Object.entries(state.synced.linkedOverrides.requests).filter(([k]) => !k.startsWith(prefix))
|
|
7612
|
+
);
|
|
7613
|
+
for (const o of patch.requestOverrides) {
|
|
7614
|
+
otherRequests[`${o.linkedWorkspaceId}:${o.itemId}`] = o;
|
|
7615
|
+
}
|
|
7616
|
+
const otherEnvVars = Object.fromEntries(
|
|
7617
|
+
Object.entries(state.synced.linkedOverrides.environmentVars).filter(
|
|
7618
|
+
([k]) => !k.startsWith(prefix)
|
|
7619
|
+
)
|
|
7620
|
+
);
|
|
7621
|
+
for (const o of patch.envVarOverrides) {
|
|
7622
|
+
otherEnvVars[`${o.linkedWorkspaceId}:${o.envName}:${o.varKey}`] = o;
|
|
7623
|
+
}
|
|
7624
|
+
const synced = {
|
|
7625
|
+
...state.synced,
|
|
7626
|
+
linkedWorkspaces: {
|
|
7627
|
+
...state.synced.linkedWorkspaces,
|
|
7628
|
+
[patch.id]: { ...link, pinnedVersion: patch.pinnedVersion }
|
|
7629
|
+
},
|
|
7630
|
+
releases: {
|
|
7631
|
+
...state.synced.releases,
|
|
7632
|
+
perLink: { ...state.synced.releases.perLink, [patch.id]: patch.ledger }
|
|
7633
|
+
},
|
|
7634
|
+
linkedOverrides: { requests: otherRequests, environmentVars: otherEnvVars },
|
|
7635
|
+
meta: { ...state.synced.meta, updatedAt: now }
|
|
7636
|
+
};
|
|
7637
|
+
const local = {
|
|
7638
|
+
...state.local,
|
|
7639
|
+
linkedCollections: { ...state.local.linkedCollections, [patch.id]: patch.snapshot }
|
|
7640
|
+
};
|
|
7641
|
+
return { next: { synced, local }, changedIds: [patch.id] };
|
|
7642
|
+
}
|
|
7643
|
+
function applyLinkedOverrideSetRequest(state, override, now) {
|
|
7644
|
+
const key = `${override.linkedWorkspaceId}:${override.itemId}`;
|
|
7645
|
+
const synced = {
|
|
7646
|
+
...state.synced,
|
|
7647
|
+
linkedOverrides: {
|
|
7648
|
+
...state.synced.linkedOverrides,
|
|
7649
|
+
requests: {
|
|
7650
|
+
...state.synced.linkedOverrides.requests,
|
|
7651
|
+
[key]: { ...override, updatedAt: now }
|
|
7652
|
+
}
|
|
7653
|
+
},
|
|
7654
|
+
meta: { ...state.synced.meta, updatedAt: now }
|
|
7655
|
+
};
|
|
7656
|
+
return { next: { ...state, synced }, changedIds: [key] };
|
|
7657
|
+
}
|
|
7658
|
+
function applyLinkedOverrideRemoveRequest(state, linkedWorkspaceId, itemId, now) {
|
|
7659
|
+
const key = `${linkedWorkspaceId}:${itemId}`;
|
|
7660
|
+
if (!state.synced.linkedOverrides.requests[key]) {
|
|
7661
|
+
return { next: state, changedIds: [] };
|
|
7662
|
+
}
|
|
7663
|
+
const requests = { ...state.synced.linkedOverrides.requests };
|
|
7664
|
+
delete requests[key];
|
|
7665
|
+
const synced = {
|
|
7666
|
+
...state.synced,
|
|
7667
|
+
linkedOverrides: { ...state.synced.linkedOverrides, requests },
|
|
7668
|
+
meta: { ...state.synced.meta, updatedAt: now }
|
|
7669
|
+
};
|
|
7670
|
+
return { next: { ...state, synced }, changedIds: [key] };
|
|
7671
|
+
}
|
|
7672
|
+
function applyLinkedOverrideSetEnvVar(state, override, now) {
|
|
7673
|
+
const key = `${override.linkedWorkspaceId}:${override.envName}:${override.varKey}`;
|
|
7674
|
+
const synced = {
|
|
7675
|
+
...state.synced,
|
|
7676
|
+
linkedOverrides: {
|
|
7677
|
+
...state.synced.linkedOverrides,
|
|
7678
|
+
environmentVars: {
|
|
7679
|
+
...state.synced.linkedOverrides.environmentVars,
|
|
7680
|
+
[key]: { ...override, updatedAt: now }
|
|
7681
|
+
}
|
|
7682
|
+
},
|
|
7683
|
+
meta: { ...state.synced.meta, updatedAt: now }
|
|
7684
|
+
};
|
|
7685
|
+
return { next: { ...state, synced }, changedIds: [key] };
|
|
7686
|
+
}
|
|
7687
|
+
function applyLinkedOverrideRemoveEnvVar(state, linkedWorkspaceId, envName, varKey, now) {
|
|
7688
|
+
const key = `${linkedWorkspaceId}:${envName}:${varKey}`;
|
|
7689
|
+
if (!state.synced.linkedOverrides.environmentVars[key]) {
|
|
7690
|
+
return { next: state, changedIds: [] };
|
|
7691
|
+
}
|
|
7692
|
+
const environmentVars = { ...state.synced.linkedOverrides.environmentVars };
|
|
7693
|
+
delete environmentVars[key];
|
|
7694
|
+
const synced = {
|
|
7695
|
+
...state.synced,
|
|
7696
|
+
linkedOverrides: { ...state.synced.linkedOverrides, environmentVars },
|
|
7697
|
+
meta: { ...state.synced.meta, updatedAt: now }
|
|
7698
|
+
};
|
|
7699
|
+
return { next: { ...state, synced }, changedIds: [key] };
|
|
7700
|
+
}
|
|
7701
|
+
function applyLinkedOverrideClearForLink(state, linkedWorkspaceId, now) {
|
|
7702
|
+
const prefix = `${linkedWorkspaceId}:`;
|
|
7703
|
+
const requestKeys = Object.keys(state.synced.linkedOverrides.requests).filter(
|
|
7704
|
+
(k) => k.startsWith(prefix)
|
|
7705
|
+
);
|
|
7706
|
+
const envKeys = Object.keys(state.synced.linkedOverrides.environmentVars).filter(
|
|
7707
|
+
(k) => k.startsWith(prefix)
|
|
7708
|
+
);
|
|
7709
|
+
if (requestKeys.length === 0 && envKeys.length === 0) {
|
|
7710
|
+
return { next: state, changedIds: [] };
|
|
7711
|
+
}
|
|
7712
|
+
const requests = Object.fromEntries(
|
|
7713
|
+
Object.entries(state.synced.linkedOverrides.requests).filter(([k]) => !k.startsWith(prefix))
|
|
7714
|
+
);
|
|
7715
|
+
const environmentVars = Object.fromEntries(
|
|
7716
|
+
Object.entries(state.synced.linkedOverrides.environmentVars).filter(
|
|
7717
|
+
([k]) => !k.startsWith(prefix)
|
|
7718
|
+
)
|
|
7719
|
+
);
|
|
7720
|
+
const synced = {
|
|
7721
|
+
...state.synced,
|
|
7722
|
+
linkedOverrides: { requests, environmentVars },
|
|
7723
|
+
meta: { ...state.synced.meta, updatedAt: now }
|
|
7724
|
+
};
|
|
7725
|
+
return { next: { ...state, synced }, changedIds: [...requestKeys, ...envKeys] };
|
|
7726
|
+
}
|
|
7012
7727
|
function applyGlobalAssetUpsertFile(state, file, now) {
|
|
7013
7728
|
const files = state.synced.globalAssets.files ?? {};
|
|
7014
7729
|
const existing = files[file.id];
|
|
@@ -7079,6 +7794,14 @@ function applyGlobalAssetRemoveFile(state, id, now) {
|
|
|
7079
7794
|
delete nextUsage[id];
|
|
7080
7795
|
local = { ...local, assetUsageIndex: nextUsage };
|
|
7081
7796
|
}
|
|
7797
|
+
const existing = files[id];
|
|
7798
|
+
const hadRemoteRef = Boolean(existing.workingBranchRef || existing.baseBranchRef);
|
|
7799
|
+
if (hadRemoteRef && !(local.pendingAttachmentDeletes ?? []).includes(existing.slotId)) {
|
|
7800
|
+
local = {
|
|
7801
|
+
...local,
|
|
7802
|
+
pendingAttachmentDeletes: [...local.pendingAttachmentDeletes ?? [], existing.slotId]
|
|
7803
|
+
};
|
|
7804
|
+
}
|
|
7082
7805
|
const synced = {
|
|
7083
7806
|
...state.synced,
|
|
7084
7807
|
collections: { ...state.synced.collections, requests },
|
|
@@ -7324,7 +8047,7 @@ function applyHistoryPurge(state, olderThanMs) {
|
|
|
7324
8047
|
}
|
|
7325
8048
|
|
|
7326
8049
|
// src/workspace/runPlan.ts
|
|
7327
|
-
import { envPriorityKey as
|
|
8050
|
+
import { envPriorityKey as envPriorityKey3, generateId as generateId3, RUN_BODY_PREVIEW_LIMIT } from "@apicircle/shared";
|
|
7328
8051
|
var MAX_REQUEST_RUNS = 500;
|
|
7329
8052
|
var MAX_PLAN_RUNS = 200;
|
|
7330
8053
|
var ANONYMOUS_ACTOR = { kind: "unknown", name: "unknown" };
|
|
@@ -7390,22 +8113,6 @@ function lookupPlanStepRequest(step, synced, local) {
|
|
|
7390
8113
|
linkedGlobalAssets: snapshot2.globalAssets
|
|
7391
8114
|
};
|
|
7392
8115
|
}
|
|
7393
|
-
function mergeRequestOverride(base, patch) {
|
|
7394
|
-
const merged = { ...base };
|
|
7395
|
-
if (patch.name !== void 0) merged.name = patch.name;
|
|
7396
|
-
if (patch.method !== void 0) merged.method = patch.method;
|
|
7397
|
-
if (patch.url !== void 0) merged.url = patch.url;
|
|
7398
|
-
if (patch.headers !== void 0) merged.headers = patch.headers;
|
|
7399
|
-
if (patch.query !== void 0) merged.query = patch.query;
|
|
7400
|
-
if (patch.pathParams !== void 0) merged.pathParams = patch.pathParams;
|
|
7401
|
-
if (patch.cookies !== void 0) merged.cookies = patch.cookies;
|
|
7402
|
-
if (patch.body !== void 0) merged.body = patch.body;
|
|
7403
|
-
if (patch.auth !== void 0) merged.auth = patch.auth;
|
|
7404
|
-
if (patch.contextVars !== void 0) merged.contextVars = patch.contextVars;
|
|
7405
|
-
if (patch.extractions !== void 0) merged.extractions = patch.extractions;
|
|
7406
|
-
if (patch.assertions !== void 0) merged.assertions = patch.assertions;
|
|
7407
|
-
return merged;
|
|
7408
|
-
}
|
|
7409
8116
|
function applyEnvironmentOverrides(source, linkedWorkspaceId, synced) {
|
|
7410
8117
|
const overrides = Object.values(synced.linkedOverrides.environmentVars).filter(
|
|
7411
8118
|
(override) => override.linkedWorkspaceId === linkedWorkspaceId
|
|
@@ -7622,7 +8329,7 @@ function buildEnvMaps(synced, secretsById, local) {
|
|
|
7622
8329
|
vars[v.key] = v.value;
|
|
7623
8330
|
}
|
|
7624
8331
|
}
|
|
7625
|
-
flat[
|
|
8332
|
+
flat[envPriorityKey3({ kind: "local", name })] = vars;
|
|
7626
8333
|
}
|
|
7627
8334
|
if (local) {
|
|
7628
8335
|
for (const [linkId, snapshot2] of Object.entries(local.linkedCollections)) {
|
|
@@ -7639,7 +8346,7 @@ function buildEnvMaps(synced, secretsById, local) {
|
|
|
7639
8346
|
vars[variable.key] = variable.value;
|
|
7640
8347
|
}
|
|
7641
8348
|
}
|
|
7642
|
-
flat[
|
|
8349
|
+
flat[envPriorityKey3({ kind: "linked", linkedWorkspaceId: linkId, envName })] = vars;
|
|
7643
8350
|
}
|
|
7644
8351
|
}
|
|
7645
8352
|
}
|
|
@@ -7666,7 +8373,7 @@ function resolveRequest(request, synced, plan, envRefs, globalContext, flatEnvs,
|
|
|
7666
8373
|
contextVars: Object.entries(ctxMap).map(([key, value]) => ({ key, value })),
|
|
7667
8374
|
environments: flatEnvs,
|
|
7668
8375
|
activeEnvName: null,
|
|
7669
|
-
priorityOrder: envRefs.map(
|
|
8376
|
+
priorityOrder: envRefs.map(envPriorityKey3),
|
|
7670
8377
|
secrets: secretsByLabel
|
|
7671
8378
|
});
|
|
7672
8379
|
const missing = /* @__PURE__ */ new Set();
|
|
@@ -8043,31 +8750,35 @@ var TRANSFORM_FORMAT_LABELS = {
|
|
|
8043
8750
|
export {
|
|
8044
8751
|
ANONYMOUS_ACTOR,
|
|
8045
8752
|
APICIRCLE_FOLDER_EXPORT_FORMAT,
|
|
8046
|
-
ATTACHMENTS_DIR,
|
|
8047
8753
|
DESKTOP_APP_ORIGIN,
|
|
8048
8754
|
EMPTY_UNPUSHED_SUMMARY,
|
|
8049
8755
|
HTTP_HEADERS_MAP,
|
|
8050
8756
|
OAuth2TokenError,
|
|
8051
8757
|
PlanRunDeniedError,
|
|
8758
|
+
REGISTRY_JSON_PATH,
|
|
8052
8759
|
RemoteWorkspaceParseError,
|
|
8053
8760
|
TRANSFORM_FORMAT_LABELS,
|
|
8054
8761
|
WORKSPACE_DIR,
|
|
8055
|
-
|
|
8762
|
+
appendReleaseEntry,
|
|
8056
8763
|
applyAuth,
|
|
8057
8764
|
applyAwsSigV4,
|
|
8058
8765
|
applyContentTypeForBodyType,
|
|
8766
|
+
applyLinkedEnvironmentOverrides,
|
|
8059
8767
|
applyLinkedUpdate,
|
|
8060
8768
|
applyMerge,
|
|
8061
8769
|
applyMutation,
|
|
8062
8770
|
applyPathParams,
|
|
8063
8771
|
assertNoPlaintextCredentials,
|
|
8064
8772
|
attachmentPath,
|
|
8773
|
+
attachmentsDir,
|
|
8065
8774
|
buildAuthorizeUrl,
|
|
8066
8775
|
buildAutoHeaders,
|
|
8067
8776
|
buildDigestAuthHeader,
|
|
8068
8777
|
buildHawkAuthHeader,
|
|
8778
|
+
buildLinkedSnapshot,
|
|
8069
8779
|
buildNtlmType1Negotiate,
|
|
8070
8780
|
buildNtlmType3Authenticate,
|
|
8781
|
+
buildReleaseEntry,
|
|
8071
8782
|
buildRequest,
|
|
8072
8783
|
buildScope,
|
|
8073
8784
|
collectAttachmentSlots,
|
|
@@ -8081,6 +8792,7 @@ export {
|
|
|
8081
8792
|
composeUrl,
|
|
8082
8793
|
composeUrlWithQuery,
|
|
8083
8794
|
computeCodeChallenge,
|
|
8795
|
+
computeRequestOverridePatch,
|
|
8084
8796
|
computeThreeWayDiff,
|
|
8085
8797
|
computeTransformSavings,
|
|
8086
8798
|
decryptString,
|
|
@@ -8093,6 +8805,7 @@ export {
|
|
|
8093
8805
|
exportKey,
|
|
8094
8806
|
extractContext,
|
|
8095
8807
|
fetchOAuth2Token,
|
|
8808
|
+
fetchRemoteWorkspaceJson,
|
|
8096
8809
|
findPathPlaceholders,
|
|
8097
8810
|
generateAesKey,
|
|
8098
8811
|
generateCodeVerifier,
|
|
@@ -8110,14 +8823,18 @@ export {
|
|
|
8110
8823
|
hasUnpushedChanges,
|
|
8111
8824
|
importApicircleFolderInto,
|
|
8112
8825
|
importKey,
|
|
8826
|
+
initSecretCrypto,
|
|
8113
8827
|
isApicircleEnvironment,
|
|
8114
8828
|
isApicircleFolderExport,
|
|
8115
8829
|
isDesktop,
|
|
8830
|
+
isEmptyOverridePatch,
|
|
8116
8831
|
isInsomniaExport,
|
|
8117
8832
|
isPostmanEnvironment,
|
|
8118
8833
|
isPostmanV2Collection,
|
|
8119
8834
|
isValidSemver,
|
|
8835
|
+
ledgerFromProbe,
|
|
8120
8836
|
lookup,
|
|
8837
|
+
mergeRequestOverride,
|
|
8121
8838
|
mergeWithAutoHeaders,
|
|
8122
8839
|
normalizeContentType,
|
|
8123
8840
|
parseApicircleEnvironment,
|
|
@@ -8128,12 +8845,15 @@ export {
|
|
|
8128
8845
|
parseDigestChallenge,
|
|
8129
8846
|
parseGraphqlSchema,
|
|
8130
8847
|
parseInsomniaCollection,
|
|
8848
|
+
parseLinkedWorkspaceJson,
|
|
8131
8849
|
parseNtlmType2Challenge,
|
|
8132
8850
|
parsePostmanCollection,
|
|
8133
8851
|
parsePostmanEnvironment,
|
|
8852
|
+
parseRegistryActiveId,
|
|
8134
8853
|
parseSemver,
|
|
8135
8854
|
parseUrlQuery,
|
|
8136
8855
|
parseWorkspaceJson,
|
|
8856
|
+
plaintextEnvMap,
|
|
8137
8857
|
pollDeviceFlow,
|
|
8138
8858
|
preSendValidation,
|
|
8139
8859
|
previewLinkedUpdate,
|
|
@@ -8146,6 +8866,7 @@ export {
|
|
|
8146
8866
|
requestRunToExecutionResult,
|
|
8147
8867
|
resolveInheritedAuth,
|
|
8148
8868
|
resolvePlanRef,
|
|
8869
|
+
resolveRequestForExecution,
|
|
8149
8870
|
resolveString,
|
|
8150
8871
|
resolveStringMap,
|
|
8151
8872
|
runAssertions,
|
|
@@ -8167,7 +8888,9 @@ export {
|
|
|
8167
8888
|
toYaml,
|
|
8168
8889
|
tokenizeCurl,
|
|
8169
8890
|
tryParsePayload,
|
|
8891
|
+
unlockSecretCrypto,
|
|
8170
8892
|
validateBranchName,
|
|
8893
|
+
workspaceJsonPath,
|
|
8171
8894
|
yankRelease
|
|
8172
8895
|
};
|
|
8173
8896
|
//# sourceMappingURL=index.js.map
|