@apicircle/core 1.0.8 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/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 +995 -87
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +219 -8
- package/dist/index.d.ts +219 -8
- package/dist/index.js +965 -77
- package/dist/index.js.map +1 -1
- package/dist/{patches-ysO3y8pG.d.cts → patches-B3VGNVgf.d.cts} +74 -1
- package/dist/{patches-ysO3y8pG.d.ts → patches-B3VGNVgf.d.ts} +74 -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.cjs
CHANGED
|
@@ -27,22 +27,30 @@ __export(src_exports, {
|
|
|
27
27
|
HTTP_HEADERS_MAP: () => HTTP_HEADERS_MAP,
|
|
28
28
|
OAuth2TokenError: () => OAuth2TokenError,
|
|
29
29
|
PlanRunDeniedError: () => PlanRunDeniedError,
|
|
30
|
+
REGISTRY_JSON_PATH: () => REGISTRY_JSON_PATH,
|
|
30
31
|
RemoteWorkspaceParseError: () => RemoteWorkspaceParseError,
|
|
31
32
|
TRANSFORM_FORMAT_LABELS: () => TRANSFORM_FORMAT_LABELS,
|
|
33
|
+
WORKSPACE_DIR: () => WORKSPACE_DIR,
|
|
34
|
+
appendReleaseEntry: () => appendReleaseEntry,
|
|
32
35
|
applyAuth: () => applyAuth,
|
|
33
36
|
applyAwsSigV4: () => applyAwsSigV4,
|
|
34
37
|
applyContentTypeForBodyType: () => applyContentTypeForBodyType,
|
|
38
|
+
applyLinkedEnvironmentOverrides: () => applyLinkedEnvironmentOverrides,
|
|
35
39
|
applyLinkedUpdate: () => applyLinkedUpdate,
|
|
36
40
|
applyMerge: () => applyMerge,
|
|
37
41
|
applyMutation: () => applyMutation,
|
|
38
42
|
applyPathParams: () => applyPathParams,
|
|
39
43
|
assertNoPlaintextCredentials: () => assertNoPlaintextCredentials,
|
|
44
|
+
attachmentPath: () => attachmentPath,
|
|
45
|
+
attachmentsDir: () => attachmentsDir,
|
|
40
46
|
buildAuthorizeUrl: () => buildAuthorizeUrl,
|
|
41
47
|
buildAutoHeaders: () => buildAutoHeaders,
|
|
42
48
|
buildDigestAuthHeader: () => buildDigestAuthHeader,
|
|
43
49
|
buildHawkAuthHeader: () => buildHawkAuthHeader,
|
|
50
|
+
buildLinkedSnapshot: () => buildLinkedSnapshot,
|
|
44
51
|
buildNtlmType1Negotiate: () => buildNtlmType1Negotiate,
|
|
45
52
|
buildNtlmType3Authenticate: () => buildNtlmType3Authenticate,
|
|
53
|
+
buildReleaseEntry: () => buildReleaseEntry,
|
|
46
54
|
buildRequest: () => buildRequest,
|
|
47
55
|
buildScope: () => buildScope,
|
|
48
56
|
collectAttachmentSlots: () => collectAttachmentSlots,
|
|
@@ -56,6 +64,7 @@ __export(src_exports, {
|
|
|
56
64
|
composeUrl: () => composeUrl,
|
|
57
65
|
composeUrlWithQuery: () => composeUrlWithQuery,
|
|
58
66
|
computeCodeChallenge: () => computeCodeChallenge,
|
|
67
|
+
computeRequestOverridePatch: () => computeRequestOverridePatch,
|
|
59
68
|
computeThreeWayDiff: () => computeThreeWayDiff,
|
|
60
69
|
computeTransformSavings: () => computeTransformSavings,
|
|
61
70
|
decryptString: () => decryptString,
|
|
@@ -68,6 +77,7 @@ __export(src_exports, {
|
|
|
68
77
|
exportKey: () => exportKey,
|
|
69
78
|
extractContext: () => extractContext,
|
|
70
79
|
fetchOAuth2Token: () => fetchOAuth2Token,
|
|
80
|
+
fetchRemoteWorkspaceJson: () => fetchRemoteWorkspaceJson,
|
|
71
81
|
findPathPlaceholders: () => findPathPlaceholders,
|
|
72
82
|
generateAesKey: () => generateAesKey,
|
|
73
83
|
generateCodeVerifier: () => generateCodeVerifier,
|
|
@@ -85,14 +95,18 @@ __export(src_exports, {
|
|
|
85
95
|
hasUnpushedChanges: () => hasUnpushedChanges,
|
|
86
96
|
importApicircleFolderInto: () => importApicircleFolderInto,
|
|
87
97
|
importKey: () => importKey,
|
|
98
|
+
initSecretCrypto: () => initSecretCrypto,
|
|
88
99
|
isApicircleEnvironment: () => isApicircleEnvironment,
|
|
89
100
|
isApicircleFolderExport: () => isApicircleFolderExport,
|
|
90
101
|
isDesktop: () => isDesktop,
|
|
102
|
+
isEmptyOverridePatch: () => isEmptyOverridePatch,
|
|
91
103
|
isInsomniaExport: () => isInsomniaExport,
|
|
92
104
|
isPostmanEnvironment: () => isPostmanEnvironment,
|
|
93
105
|
isPostmanV2Collection: () => isPostmanV2Collection,
|
|
94
106
|
isValidSemver: () => isValidSemver,
|
|
107
|
+
ledgerFromProbe: () => ledgerFromProbe,
|
|
95
108
|
lookup: () => lookup,
|
|
109
|
+
mergeRequestOverride: () => mergeRequestOverride,
|
|
96
110
|
mergeWithAutoHeaders: () => mergeWithAutoHeaders,
|
|
97
111
|
normalizeContentType: () => normalizeContentType,
|
|
98
112
|
parseApicircleEnvironment: () => parseApicircleEnvironment,
|
|
@@ -103,12 +117,15 @@ __export(src_exports, {
|
|
|
103
117
|
parseDigestChallenge: () => parseDigestChallenge,
|
|
104
118
|
parseGraphqlSchema: () => parseGraphqlSchema,
|
|
105
119
|
parseInsomniaCollection: () => parseInsomniaCollection,
|
|
120
|
+
parseLinkedWorkspaceJson: () => parseLinkedWorkspaceJson,
|
|
106
121
|
parseNtlmType2Challenge: () => parseNtlmType2Challenge,
|
|
107
122
|
parsePostmanCollection: () => parsePostmanCollection,
|
|
108
123
|
parsePostmanEnvironment: () => parsePostmanEnvironment,
|
|
124
|
+
parseRegistryActiveId: () => parseRegistryActiveId,
|
|
109
125
|
parseSemver: () => parseSemver,
|
|
110
126
|
parseUrlQuery: () => parseUrlQuery,
|
|
111
127
|
parseWorkspaceJson: () => parseWorkspaceJson,
|
|
128
|
+
plaintextEnvMap: () => plaintextEnvMap,
|
|
112
129
|
pollDeviceFlow: () => pollDeviceFlow,
|
|
113
130
|
preSendValidation: () => preSendValidation,
|
|
114
131
|
previewLinkedUpdate: () => previewLinkedUpdate,
|
|
@@ -121,6 +138,7 @@ __export(src_exports, {
|
|
|
121
138
|
requestRunToExecutionResult: () => requestRunToExecutionResult,
|
|
122
139
|
resolveInheritedAuth: () => resolveInheritedAuth,
|
|
123
140
|
resolvePlanRef: () => resolvePlanRef,
|
|
141
|
+
resolveRequestForExecution: () => resolveRequestForExecution,
|
|
124
142
|
resolveString: () => resolveString,
|
|
125
143
|
resolveStringMap: () => resolveStringMap,
|
|
126
144
|
runAssertions: () => runAssertions,
|
|
@@ -142,7 +160,9 @@ __export(src_exports, {
|
|
|
142
160
|
toYaml: () => toYaml,
|
|
143
161
|
tokenizeCurl: () => tokenizeCurl,
|
|
144
162
|
tryParsePayload: () => tryParsePayload,
|
|
163
|
+
unlockSecretCrypto: () => unlockSecretCrypto,
|
|
145
164
|
validateBranchName: () => validateBranchName,
|
|
165
|
+
workspaceJsonPath: () => workspaceJsonPath,
|
|
146
166
|
yankRelease: () => yankRelease
|
|
147
167
|
});
|
|
148
168
|
module.exports = __toCommonJS(src_exports);
|
|
@@ -1203,8 +1223,7 @@ async function importPkcs8(pem, algorithm) {
|
|
|
1203
1223
|
"JWT: PKCS#1 RSA PEM (`BEGIN RSA PRIVATE KEY`) is not supported. Convert with `openssl pkcs8 -topk8 -in key.pem -out pkcs8.pem -nocrypt`."
|
|
1204
1224
|
);
|
|
1205
1225
|
}
|
|
1206
|
-
const
|
|
1207
|
-
const body = envelope ? envelope[1] : pem;
|
|
1226
|
+
const body = extractPemBody(pem);
|
|
1208
1227
|
const stripped = body.replace(/\s+/g, "");
|
|
1209
1228
|
if (!stripped) {
|
|
1210
1229
|
throw new Error("JWT: PEM key is empty after stripping headers/whitespace");
|
|
@@ -1225,6 +1244,19 @@ async function importPkcs8(pem, algorithm) {
|
|
|
1225
1244
|
["sign"]
|
|
1226
1245
|
);
|
|
1227
1246
|
}
|
|
1247
|
+
function extractPemBody(pem) {
|
|
1248
|
+
const BEGIN = "-----BEGIN ";
|
|
1249
|
+
const END = "-----END ";
|
|
1250
|
+
const FENCE = "-----";
|
|
1251
|
+
const beginAt = pem.indexOf(BEGIN);
|
|
1252
|
+
if (beginAt === -1) return pem;
|
|
1253
|
+
const beginHeaderEnd = pem.indexOf(FENCE, beginAt + BEGIN.length);
|
|
1254
|
+
if (beginHeaderEnd === -1) return pem;
|
|
1255
|
+
const bodyStart = beginHeaderEnd + FENCE.length;
|
|
1256
|
+
const endAt = pem.indexOf(END, bodyStart);
|
|
1257
|
+
if (endAt === -1) return pem;
|
|
1258
|
+
return pem.slice(bodyStart, endAt);
|
|
1259
|
+
}
|
|
1228
1260
|
function base64UrlEncode(bytes) {
|
|
1229
1261
|
let s = "";
|
|
1230
1262
|
for (let i = 0; i < bytes.length; i++) s += String.fromCharCode(bytes[i]);
|
|
@@ -1679,6 +1711,10 @@ async function fetchOAuth2Token(args) {
|
|
|
1679
1711
|
if (args.extraParams) {
|
|
1680
1712
|
for (const [k, v] of Object.entries(args.extraParams)) body.set(k, v);
|
|
1681
1713
|
}
|
|
1714
|
+
const tokenUrlParsed = new URL(args.tokenUrl);
|
|
1715
|
+
if (tokenUrlParsed.protocol !== "https:" && tokenUrlParsed.protocol !== "http:") {
|
|
1716
|
+
throw new Error(`Token URL must use HTTP or HTTPS, got ${tokenUrlParsed.protocol}`);
|
|
1717
|
+
}
|
|
1682
1718
|
const response = await fetchImpl(args.tokenUrl, {
|
|
1683
1719
|
method: "POST",
|
|
1684
1720
|
headers,
|
|
@@ -2625,6 +2661,30 @@ function getVariableAutocomplete(text, cursorPosition, scope) {
|
|
|
2625
2661
|
);
|
|
2626
2662
|
}
|
|
2627
2663
|
|
|
2664
|
+
// src/request/resolveInheritedAuth.ts
|
|
2665
|
+
var NONE = { type: "none" };
|
|
2666
|
+
function resolveInheritedAuth({
|
|
2667
|
+
requestAuth,
|
|
2668
|
+
folderId,
|
|
2669
|
+
folders
|
|
2670
|
+
}) {
|
|
2671
|
+
if (requestAuth.type !== "inherit") return requestAuth;
|
|
2672
|
+
let cursor = folderId;
|
|
2673
|
+
const visited = /* @__PURE__ */ new Set();
|
|
2674
|
+
while (cursor !== null) {
|
|
2675
|
+
if (visited.has(cursor)) {
|
|
2676
|
+
break;
|
|
2677
|
+
}
|
|
2678
|
+
visited.add(cursor);
|
|
2679
|
+
const folder = folders[cursor];
|
|
2680
|
+
if (!folder) break;
|
|
2681
|
+
const auth = folder.auth;
|
|
2682
|
+
if (auth && auth.type !== "inherit" && auth.type !== "none") return auth;
|
|
2683
|
+
cursor = folder.parentId;
|
|
2684
|
+
}
|
|
2685
|
+
return NONE;
|
|
2686
|
+
}
|
|
2687
|
+
|
|
2628
2688
|
// src/request/preSendValidation.ts
|
|
2629
2689
|
var TYPED_BODY_CT = {
|
|
2630
2690
|
json: ["application/json", "application/ld+json", "application/vnd.api+json"],
|
|
@@ -2637,7 +2697,8 @@ function collectMissing(value, scope) {
|
|
|
2637
2697
|
}
|
|
2638
2698
|
function preSendValidation({
|
|
2639
2699
|
request,
|
|
2640
|
-
scope
|
|
2700
|
+
scope,
|
|
2701
|
+
folders
|
|
2641
2702
|
}) {
|
|
2642
2703
|
const warnings = [];
|
|
2643
2704
|
const blockers = [];
|
|
@@ -2712,29 +2773,43 @@ function preSendValidation({
|
|
|
2712
2773
|
});
|
|
2713
2774
|
}
|
|
2714
2775
|
}
|
|
2715
|
-
|
|
2776
|
+
let effectiveAuth = request.auth;
|
|
2777
|
+
let resolvedFromInherit = false;
|
|
2778
|
+
if (folders && effectiveAuth?.type === "inherit") {
|
|
2779
|
+
effectiveAuth = resolveInheritedAuth({
|
|
2780
|
+
requestAuth: { type: "inherit" },
|
|
2781
|
+
folderId: request.folderId,
|
|
2782
|
+
folders
|
|
2783
|
+
});
|
|
2784
|
+
resolvedFromInherit = true;
|
|
2785
|
+
}
|
|
2786
|
+
const auth = effectiveAuth;
|
|
2787
|
+
const inheritedNote = resolvedFromInherit ? " (resolved from folder-level auth)" : "";
|
|
2716
2788
|
if (auth) {
|
|
2717
2789
|
if (auth.type === "bearer" && !auth.token?.trim()) {
|
|
2718
|
-
blockers.push({
|
|
2790
|
+
blockers.push({
|
|
2791
|
+
kind: "auth-fields-missing",
|
|
2792
|
+
message: `Bearer token is empty.${inheritedNote}`
|
|
2793
|
+
});
|
|
2719
2794
|
} else if (auth.type === "basic") {
|
|
2720
2795
|
if (!auth.username?.trim() || !auth.password?.trim()) {
|
|
2721
2796
|
blockers.push({
|
|
2722
2797
|
kind: "auth-fields-missing",
|
|
2723
|
-
message:
|
|
2798
|
+
message: `Basic auth requires both username and password.${inheritedNote}`
|
|
2724
2799
|
});
|
|
2725
2800
|
}
|
|
2726
2801
|
} else if (auth.type === "api-key") {
|
|
2727
2802
|
if (!auth.key?.trim() || !auth.value?.trim()) {
|
|
2728
2803
|
blockers.push({
|
|
2729
2804
|
kind: "auth-fields-missing",
|
|
2730
|
-
message:
|
|
2805
|
+
message: `API key auth requires both name and value.${inheritedNote}`
|
|
2731
2806
|
});
|
|
2732
2807
|
}
|
|
2733
2808
|
} else if (auth.type === "custom-header") {
|
|
2734
2809
|
if (!auth.key?.trim()) {
|
|
2735
2810
|
blockers.push({
|
|
2736
2811
|
kind: "auth-fields-missing",
|
|
2737
|
-
message:
|
|
2812
|
+
message: `Custom header auth requires a header name.${inheritedNote}`
|
|
2738
2813
|
});
|
|
2739
2814
|
}
|
|
2740
2815
|
}
|
|
@@ -3121,6 +3196,15 @@ async function executeRequest(req, opts = {}) {
|
|
|
3121
3196
|
);
|
|
3122
3197
|
const redirectMode = isBrowserRuntime() ? "follow" : "manual";
|
|
3123
3198
|
let currentUrl = builtRequest.url;
|
|
3199
|
+
try {
|
|
3200
|
+
const parsedUrl = new URL(currentUrl);
|
|
3201
|
+
if (parsedUrl.protocol !== "http:" && parsedUrl.protocol !== "https:") {
|
|
3202
|
+
throw new Error(`Unsupported URL scheme: ${parsedUrl.protocol}`);
|
|
3203
|
+
}
|
|
3204
|
+
} catch (e) {
|
|
3205
|
+
if (e instanceof Error && e.message.startsWith("Unsupported URL scheme")) throw e;
|
|
3206
|
+
throw new Error(`Invalid request URL: ${currentUrl}`);
|
|
3207
|
+
}
|
|
3124
3208
|
let currentHeaders = { ...builtRequest.headers };
|
|
3125
3209
|
let currentMethod = builtRequest.method;
|
|
3126
3210
|
let currentBody = builtRequest.body;
|
|
@@ -3419,30 +3503,6 @@ function base64UrlEncode2(bytes) {
|
|
|
3419
3503
|
return btoa(s).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
3420
3504
|
}
|
|
3421
3505
|
|
|
3422
|
-
// src/request/resolveInheritedAuth.ts
|
|
3423
|
-
var NONE = { type: "none" };
|
|
3424
|
-
function resolveInheritedAuth({
|
|
3425
|
-
requestAuth,
|
|
3426
|
-
folderId,
|
|
3427
|
-
folders
|
|
3428
|
-
}) {
|
|
3429
|
-
if (requestAuth.type !== "inherit") return requestAuth;
|
|
3430
|
-
let cursor = folderId;
|
|
3431
|
-
const visited = /* @__PURE__ */ new Set();
|
|
3432
|
-
while (cursor !== null) {
|
|
3433
|
-
if (visited.has(cursor)) {
|
|
3434
|
-
break;
|
|
3435
|
-
}
|
|
3436
|
-
visited.add(cursor);
|
|
3437
|
-
const folder = folders[cursor];
|
|
3438
|
-
if (!folder) break;
|
|
3439
|
-
const auth = folder.auth;
|
|
3440
|
-
if (auth && auth.type !== "inherit" && auth.type !== "none") return auth;
|
|
3441
|
-
cursor = folder.parentId;
|
|
3442
|
-
}
|
|
3443
|
-
return NONE;
|
|
3444
|
-
}
|
|
3445
|
-
|
|
3446
3506
|
// src/request/parseCurl.ts
|
|
3447
3507
|
var HTTP_METHODS = /* @__PURE__ */ new Set(["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"]);
|
|
3448
3508
|
function tokenizeCurl(input) {
|
|
@@ -3744,10 +3804,12 @@ function parsePostmanCollection(input) {
|
|
|
3744
3804
|
items.forEach((item, idx) => {
|
|
3745
3805
|
const pathIds = parentPathIds ? [...parentPathIds, idx] : [idx];
|
|
3746
3806
|
if (Array.isArray(item.item)) {
|
|
3807
|
+
const folderAuth = item.auth ? parseAuth(item.auth, warnings, item.name) : void 0;
|
|
3747
3808
|
folders.push({
|
|
3748
3809
|
name: (item.name ?? "Untitled folder").trim() || "Untitled folder",
|
|
3749
3810
|
pathIds,
|
|
3750
|
-
parentPathIds
|
|
3811
|
+
parentPathIds,
|
|
3812
|
+
...folderAuth && folderAuth.type !== "none" ? { auth: folderAuth } : {}
|
|
3751
3813
|
});
|
|
3752
3814
|
walk(item.item, pathIds);
|
|
3753
3815
|
return;
|
|
@@ -3988,10 +4050,12 @@ function parseInsomniaCollection(input) {
|
|
|
3988
4050
|
const parentPath = r.parentId ? folderIndexById.get(r.parentId) ?? null : null;
|
|
3989
4051
|
const ourPath = parentPath ? [...parentPath, folderCounter++] : [folderCounter++];
|
|
3990
4052
|
folderIndexById.set(r._id ?? "", ourPath);
|
|
4053
|
+
const folderAuth = r.authentication ? parseAuth2(r.authentication, warnings, r.name) : void 0;
|
|
3991
4054
|
folders.push({
|
|
3992
4055
|
name: (r.name ?? "Untitled folder").trim() || "Untitled folder",
|
|
3993
4056
|
pathIds: ourPath,
|
|
3994
|
-
parentPathIds: parentPath
|
|
4057
|
+
parentPathIds: parentPath,
|
|
4058
|
+
...folderAuth && folderAuth.type !== "none" ? { auth: folderAuth } : {}
|
|
3995
4059
|
});
|
|
3996
4060
|
}
|
|
3997
4061
|
const requests = [];
|
|
@@ -4392,7 +4456,7 @@ function serializeFolderExport(envelope) {
|
|
|
4392
4456
|
return JSON.stringify(envelope, null, 2);
|
|
4393
4457
|
}
|
|
4394
4458
|
function suggestFolderExportFilename(envelope) {
|
|
4395
|
-
const slug = envelope.folder.name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(
|
|
4459
|
+
const slug = envelope.folder.name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-/, "").replace(/-$/, "");
|
|
4396
4460
|
const base = slug || "folder";
|
|
4397
4461
|
return `${base}.apicircle.json`;
|
|
4398
4462
|
}
|
|
@@ -5018,6 +5082,140 @@ function extractContext(result, extractions) {
|
|
|
5018
5082
|
return { extracted, warnings };
|
|
5019
5083
|
}
|
|
5020
5084
|
|
|
5085
|
+
// src/environment/resolveRequest.ts
|
|
5086
|
+
var import_shared2 = require("@apicircle/shared");
|
|
5087
|
+
function resolveRequestForExecution(args) {
|
|
5088
|
+
const refs = args.envPriorityOverride && args.envPriorityOverride.length > 0 ? args.envPriorityOverride : args.synced.environments.priorityOrder;
|
|
5089
|
+
const flatEnvs = {};
|
|
5090
|
+
for (const [name, vars] of Object.entries(args.localEnvs)) {
|
|
5091
|
+
flatEnvs[(0, import_shared2.envPriorityKey)({ kind: "local", name })] = vars;
|
|
5092
|
+
}
|
|
5093
|
+
for (const [linkId, byEnv] of Object.entries(args.linkedEnvs ?? {})) {
|
|
5094
|
+
for (const [envName, vars] of Object.entries(byEnv)) {
|
|
5095
|
+
flatEnvs[(0, import_shared2.envPriorityKey)({ kind: "linked", linkedWorkspaceId: linkId, envName })] = vars;
|
|
5096
|
+
}
|
|
5097
|
+
}
|
|
5098
|
+
const ctxMap = { ...args.globalContext ?? {} };
|
|
5099
|
+
for (const v of args.planVariables ?? []) {
|
|
5100
|
+
if (v.key) ctxMap[v.key] = v.value;
|
|
5101
|
+
}
|
|
5102
|
+
for (const v of args.request.contextVars) {
|
|
5103
|
+
if (v.key) ctxMap[v.key] = v.value;
|
|
5104
|
+
}
|
|
5105
|
+
const contextVars = Object.entries(ctxMap).map(([key, value]) => ({ key, value }));
|
|
5106
|
+
const scope = buildScope({
|
|
5107
|
+
contextVars,
|
|
5108
|
+
environments: flatEnvs,
|
|
5109
|
+
activeEnvName: null,
|
|
5110
|
+
// priorityOrder is the sole list the resolver consults.
|
|
5111
|
+
priorityOrder: refs.map(import_shared2.envPriorityKey),
|
|
5112
|
+
secrets: args.secrets ?? {}
|
|
5113
|
+
});
|
|
5114
|
+
const missing = /* @__PURE__ */ new Set();
|
|
5115
|
+
const interp = (s) => {
|
|
5116
|
+
const r = resolveString(s, scope);
|
|
5117
|
+
for (const m of r.missing) missing.add(m);
|
|
5118
|
+
return r.value;
|
|
5119
|
+
};
|
|
5120
|
+
const url = interp(args.request.url);
|
|
5121
|
+
const headers = args.request.headers.map((h) => ({
|
|
5122
|
+
...h,
|
|
5123
|
+
key: interp(h.key),
|
|
5124
|
+
value: interp(h.value)
|
|
5125
|
+
}));
|
|
5126
|
+
const query = args.request.query.map((q) => ({
|
|
5127
|
+
...q,
|
|
5128
|
+
key: interp(q.key),
|
|
5129
|
+
value: interp(q.value)
|
|
5130
|
+
}));
|
|
5131
|
+
let body = args.request.body;
|
|
5132
|
+
if (body.type === "json" || body.type === "text" || body.type === "xml" || body.type === "graphql" || body.type === "urlencoded") {
|
|
5133
|
+
body = { ...body, content: interp(body.content) };
|
|
5134
|
+
} else if (body.type === "form-data" && body.formRows) {
|
|
5135
|
+
body = {
|
|
5136
|
+
...body,
|
|
5137
|
+
formRows: body.formRows.map(
|
|
5138
|
+
(row) => row.kind === "text" ? { ...row, key: interp(row.key), value: interp(row.value) } : { ...row, key: interp(row.key) }
|
|
5139
|
+
)
|
|
5140
|
+
};
|
|
5141
|
+
}
|
|
5142
|
+
const inheritedAuth = resolveInheritedAuth({
|
|
5143
|
+
requestAuth: args.request.auth ?? { type: "none" },
|
|
5144
|
+
folderId: args.request.folderId,
|
|
5145
|
+
folders: args.synced.collections.folders
|
|
5146
|
+
});
|
|
5147
|
+
const auth = interpolateAuthVariables(inheritedAuth, interp);
|
|
5148
|
+
return {
|
|
5149
|
+
request: { ...args.request, url, headers, query, body, auth },
|
|
5150
|
+
scope,
|
|
5151
|
+
missing: [...missing]
|
|
5152
|
+
};
|
|
5153
|
+
}
|
|
5154
|
+
function interpolateAuthVariables(auth, interp) {
|
|
5155
|
+
const resolved = {};
|
|
5156
|
+
for (const [key, value] of Object.entries(auth)) {
|
|
5157
|
+
resolved[key] = key !== "type" && typeof value === "string" ? interp(value) : value;
|
|
5158
|
+
}
|
|
5159
|
+
return resolved;
|
|
5160
|
+
}
|
|
5161
|
+
function applyLinkedEnvironmentOverrides(source, linkedWorkspaceId, synced) {
|
|
5162
|
+
const overrides = Object.values(synced.linkedOverrides.environmentVars).filter(
|
|
5163
|
+
(o) => o.linkedWorkspaceId === linkedWorkspaceId
|
|
5164
|
+
);
|
|
5165
|
+
if (overrides.length === 0) return source;
|
|
5166
|
+
const items = {};
|
|
5167
|
+
for (const [envName, env] of Object.entries(source.items)) {
|
|
5168
|
+
const envOverrides = overrides.filter((o) => o.envName === envName);
|
|
5169
|
+
if (envOverrides.length === 0) {
|
|
5170
|
+
items[envName] = env;
|
|
5171
|
+
continue;
|
|
5172
|
+
}
|
|
5173
|
+
const removed = new Set(envOverrides.filter((o) => o.removed).map((o) => o.varKey));
|
|
5174
|
+
const replaceMap = new Map(envOverrides.filter((o) => !o.removed).map((o) => [o.varKey, o]));
|
|
5175
|
+
const variables = [];
|
|
5176
|
+
const seenKeys = /* @__PURE__ */ new Set();
|
|
5177
|
+
for (const v of env.variables) {
|
|
5178
|
+
if (removed.has(v.key)) continue;
|
|
5179
|
+
const ov = replaceMap.get(v.key);
|
|
5180
|
+
if (ov) {
|
|
5181
|
+
variables.push({
|
|
5182
|
+
key: v.key,
|
|
5183
|
+
value: ov.value ?? v.value,
|
|
5184
|
+
encrypted: ov.encrypted ?? v.encrypted,
|
|
5185
|
+
...ov.secretKeyId !== void 0 ? { secretKeyId: ov.secretKeyId } : v.secretKeyId !== void 0 ? { secretKeyId: v.secretKeyId } : {}
|
|
5186
|
+
});
|
|
5187
|
+
} else {
|
|
5188
|
+
variables.push(v);
|
|
5189
|
+
}
|
|
5190
|
+
seenKeys.add(v.key);
|
|
5191
|
+
}
|
|
5192
|
+
for (const ov of envOverrides) {
|
|
5193
|
+
if (ov.removed) continue;
|
|
5194
|
+
if (seenKeys.has(ov.varKey)) continue;
|
|
5195
|
+
variables.push({
|
|
5196
|
+
key: ov.varKey,
|
|
5197
|
+
value: ov.value ?? "",
|
|
5198
|
+
encrypted: ov.encrypted ?? false,
|
|
5199
|
+
...ov.secretKeyId !== void 0 ? { secretKeyId: ov.secretKeyId } : {}
|
|
5200
|
+
});
|
|
5201
|
+
}
|
|
5202
|
+
items[envName] = { ...env, variables };
|
|
5203
|
+
}
|
|
5204
|
+
return { ...source, items };
|
|
5205
|
+
}
|
|
5206
|
+
function plaintextEnvMap(source) {
|
|
5207
|
+
const out = {};
|
|
5208
|
+
for (const [name, env] of Object.entries(source.items)) {
|
|
5209
|
+
const vars = {};
|
|
5210
|
+
for (const v of env.variables) {
|
|
5211
|
+
if (v.encrypted) continue;
|
|
5212
|
+
vars[v.key] = v.value;
|
|
5213
|
+
}
|
|
5214
|
+
out[name] = vars;
|
|
5215
|
+
}
|
|
5216
|
+
return out;
|
|
5217
|
+
}
|
|
5218
|
+
|
|
5021
5219
|
// src/secrets/crypto.ts
|
|
5022
5220
|
var IV_BYTES = 12;
|
|
5023
5221
|
var SALT_BYTES = 16;
|
|
@@ -5102,6 +5300,95 @@ function base64ToBytes(b64) {
|
|
|
5102
5300
|
return out;
|
|
5103
5301
|
}
|
|
5104
5302
|
|
|
5303
|
+
// src/secrets/passphraseKey.ts
|
|
5304
|
+
var PBKDF2_HASH = "SHA-256";
|
|
5305
|
+
var PBKDF2_ITERATIONS2 = 12e5;
|
|
5306
|
+
var SALT_BYTES2 = 16;
|
|
5307
|
+
var VERIFIER_SENTINEL = "apicircle/passphrase-verifier/v1";
|
|
5308
|
+
function base64Encode2(bytes) {
|
|
5309
|
+
let binary = "";
|
|
5310
|
+
for (let i = 0; i < bytes.length; i++) binary += String.fromCharCode(bytes[i]);
|
|
5311
|
+
return btoa(binary);
|
|
5312
|
+
}
|
|
5313
|
+
function base64Decode2(b64) {
|
|
5314
|
+
const binary = atob(b64);
|
|
5315
|
+
const bytes = new Uint8Array(binary.length);
|
|
5316
|
+
for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);
|
|
5317
|
+
return bytes;
|
|
5318
|
+
}
|
|
5319
|
+
function utf8Bytes(s) {
|
|
5320
|
+
return new TextEncoder().encode(s);
|
|
5321
|
+
}
|
|
5322
|
+
async function deriveKey(passphrase, salt, iterations) {
|
|
5323
|
+
const baseKey = await crypto.subtle.importKey(
|
|
5324
|
+
"raw",
|
|
5325
|
+
utf8Bytes(passphrase),
|
|
5326
|
+
{ name: "PBKDF2" },
|
|
5327
|
+
false,
|
|
5328
|
+
["deriveKey"]
|
|
5329
|
+
);
|
|
5330
|
+
return crypto.subtle.deriveKey(
|
|
5331
|
+
{
|
|
5332
|
+
name: "PBKDF2",
|
|
5333
|
+
salt,
|
|
5334
|
+
iterations,
|
|
5335
|
+
hash: PBKDF2_HASH
|
|
5336
|
+
},
|
|
5337
|
+
baseKey,
|
|
5338
|
+
{ name: "AES-GCM", length: 256 },
|
|
5339
|
+
/* extractable */
|
|
5340
|
+
false,
|
|
5341
|
+
["encrypt", "decrypt"]
|
|
5342
|
+
);
|
|
5343
|
+
}
|
|
5344
|
+
async function computeVerifier(key) {
|
|
5345
|
+
const iv = new Uint8Array(12);
|
|
5346
|
+
const ct = await crypto.subtle.encrypt(
|
|
5347
|
+
{ name: "AES-GCM", iv },
|
|
5348
|
+
key,
|
|
5349
|
+
utf8Bytes(VERIFIER_SENTINEL)
|
|
5350
|
+
);
|
|
5351
|
+
return base64Encode2(new Uint8Array(ct));
|
|
5352
|
+
}
|
|
5353
|
+
async function initSecretCrypto(passphrase, iterations = PBKDF2_ITERATIONS2) {
|
|
5354
|
+
if (passphrase.length === 0) throw new Error("Passphrase cannot be empty");
|
|
5355
|
+
if (iterations < 1) throw new Error("iterations must be >= 1");
|
|
5356
|
+
const salt = crypto.getRandomValues(new Uint8Array(SALT_BYTES2));
|
|
5357
|
+
const key = await deriveKey(passphrase, salt, iterations);
|
|
5358
|
+
const verifier = await computeVerifier(key);
|
|
5359
|
+
return {
|
|
5360
|
+
crypto: {
|
|
5361
|
+
kdf: "pbkdf2-sha256-v1",
|
|
5362
|
+
salt: base64Encode2(salt),
|
|
5363
|
+
iterations,
|
|
5364
|
+
verifier
|
|
5365
|
+
},
|
|
5366
|
+
key
|
|
5367
|
+
};
|
|
5368
|
+
}
|
|
5369
|
+
async function unlockSecretCrypto(passphrase, blob) {
|
|
5370
|
+
if (blob.kdf !== "pbkdf2-sha256-v1") {
|
|
5371
|
+
return { ok: false, reason: `Unsupported KDF: ${String(blob.kdf)}` };
|
|
5372
|
+
}
|
|
5373
|
+
let salt;
|
|
5374
|
+
try {
|
|
5375
|
+
salt = base64Decode2(blob.salt);
|
|
5376
|
+
} catch {
|
|
5377
|
+
return { ok: false, reason: "Workspace secret salt is corrupt." };
|
|
5378
|
+
}
|
|
5379
|
+
let key;
|
|
5380
|
+
try {
|
|
5381
|
+
key = await deriveKey(passphrase, salt, blob.iterations);
|
|
5382
|
+
} catch (err) {
|
|
5383
|
+
return { ok: false, reason: err instanceof Error ? err.message : "Key derivation failed" };
|
|
5384
|
+
}
|
|
5385
|
+
const verifier = await computeVerifier(key);
|
|
5386
|
+
if (verifier !== blob.verifier) {
|
|
5387
|
+
return { ok: false, reason: "Wrong passphrase." };
|
|
5388
|
+
}
|
|
5389
|
+
return { ok: true, key };
|
|
5390
|
+
}
|
|
5391
|
+
|
|
5105
5392
|
// src/git/branchNames.ts
|
|
5106
5393
|
var SLUG_FALLBACK = "workspace";
|
|
5107
5394
|
var SUFFIX_LEN = 6;
|
|
@@ -5159,6 +5446,36 @@ function sortedReplacer(_key, value) {
|
|
|
5159
5446
|
return out;
|
|
5160
5447
|
}
|
|
5161
5448
|
|
|
5449
|
+
// src/git/repoPaths.ts
|
|
5450
|
+
var WORKSPACE_DIR = ".apicircle";
|
|
5451
|
+
var REGISTRY_JSON_PATH = `${WORKSPACE_DIR}/registry.json`;
|
|
5452
|
+
function workspaceJsonPath(workspaceId) {
|
|
5453
|
+
return `${WORKSPACE_DIR}/workspace-${workspaceId}/workspace.json`;
|
|
5454
|
+
}
|
|
5455
|
+
function attachmentsDir(workspaceId) {
|
|
5456
|
+
return `${WORKSPACE_DIR}/workspace-${workspaceId}/attachments`;
|
|
5457
|
+
}
|
|
5458
|
+
function attachmentPath(workspaceId, slotId) {
|
|
5459
|
+
return `${attachmentsDir(workspaceId)}/${slotId}`;
|
|
5460
|
+
}
|
|
5461
|
+
function parseRegistryActiveId(registryJsonContent) {
|
|
5462
|
+
try {
|
|
5463
|
+
const parsed = JSON.parse(registryJsonContent);
|
|
5464
|
+
return parsed.activeWorkspaceId ?? parsed.workspaces?.[0]?.id ?? null;
|
|
5465
|
+
} catch {
|
|
5466
|
+
return null;
|
|
5467
|
+
}
|
|
5468
|
+
}
|
|
5469
|
+
async function fetchRemoteWorkspaceJson(fetchFile) {
|
|
5470
|
+
const registryContent = await fetchFile(REGISTRY_JSON_PATH);
|
|
5471
|
+
if (registryContent === null) return { error: "No .apicircle/registry.json found in repo" };
|
|
5472
|
+
const wsId = parseRegistryActiveId(registryContent);
|
|
5473
|
+
if (!wsId) return { error: "Registry is empty \u2014 no workspaces found" };
|
|
5474
|
+
const wsContent = await fetchFile(workspaceJsonPath(wsId));
|
|
5475
|
+
if (wsContent === null) return { error: `No workspace.json at .apicircle/workspace-${wsId}/` };
|
|
5476
|
+
return { workspaceId: wsId, content: wsContent };
|
|
5477
|
+
}
|
|
5478
|
+
|
|
5162
5479
|
// src/git/parseWorkspaceJson.ts
|
|
5163
5480
|
var MAX_WORKSPACE_JSON_BYTES = 16 * 1024 * 1024;
|
|
5164
5481
|
var FORBIDDEN_KEYS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
|
|
@@ -5415,18 +5732,14 @@ function sortVersionsDesc(versions) {
|
|
|
5415
5732
|
}
|
|
5416
5733
|
|
|
5417
5734
|
// src/release/publishRelease.ts
|
|
5418
|
-
async function
|
|
5735
|
+
async function buildReleaseEntry(synced, args) {
|
|
5419
5736
|
const version = args.version.trim();
|
|
5420
5737
|
if (!isValidSemver(version)) {
|
|
5421
5738
|
throw new Error(`Invalid semver: ${args.version}`);
|
|
5422
5739
|
}
|
|
5423
|
-
const ledger = synced.releases.self ?? emptyLedger();
|
|
5424
|
-
if (ledger.versions.some((v) => v.version === version)) {
|
|
5425
|
-
throw new Error(`Version ${version} already exists in this workspace's release ledger`);
|
|
5426
|
-
}
|
|
5427
5740
|
const snapshotSource = serializeWorkspaceForGit(synced);
|
|
5428
5741
|
const workspaceSnapshot = await sha256Hex2(snapshotSource);
|
|
5429
|
-
|
|
5742
|
+
return {
|
|
5430
5743
|
version,
|
|
5431
5744
|
publishedAt: args.publishedAt ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
5432
5745
|
notes: args.notes,
|
|
@@ -5436,23 +5749,36 @@ async function publishRelease(synced, args) {
|
|
|
5436
5749
|
...args.sha ? { sha: args.sha } : {},
|
|
5437
5750
|
...args.tagName ? { tagName: args.tagName } : {}
|
|
5438
5751
|
};
|
|
5752
|
+
}
|
|
5753
|
+
function appendReleaseEntry(synced, entry, now = entry.publishedAt) {
|
|
5754
|
+
if (!isValidSemver(entry.version)) {
|
|
5755
|
+
throw new Error(`Invalid semver: ${entry.version}`);
|
|
5756
|
+
}
|
|
5757
|
+
const ledger = synced.releases.self ?? emptyLedger();
|
|
5758
|
+
if (ledger.versions.some((v) => v.version === entry.version)) {
|
|
5759
|
+
throw new Error(`Version ${entry.version} already exists in this workspace's release ledger`);
|
|
5760
|
+
}
|
|
5439
5761
|
const next = {
|
|
5440
5762
|
versions: [...ledger.versions, entry],
|
|
5441
|
-
currentVersion: version
|
|
5763
|
+
currentVersion: entry.version
|
|
5442
5764
|
};
|
|
5443
5765
|
return {
|
|
5444
5766
|
...synced,
|
|
5445
5767
|
releases: { ...synced.releases, self: next },
|
|
5446
|
-
meta: { ...synced.meta, updatedAt:
|
|
5768
|
+
meta: { ...synced.meta, updatedAt: now }
|
|
5447
5769
|
};
|
|
5448
5770
|
}
|
|
5449
|
-
function
|
|
5450
|
-
|
|
5771
|
+
async function publishRelease(synced, args) {
|
|
5772
|
+
const entry = await buildReleaseEntry(synced, args);
|
|
5773
|
+
return appendReleaseEntry(synced, entry);
|
|
5451
5774
|
}
|
|
5452
|
-
function
|
|
5453
|
-
return mapReleaseVersion(synced, version, (v) => ({ ...v,
|
|
5775
|
+
function deprecateRelease(synced, version, now = (/* @__PURE__ */ new Date()).toISOString()) {
|
|
5776
|
+
return mapReleaseVersion(synced, version, (v) => ({ ...v, deprecated: true }), now);
|
|
5454
5777
|
}
|
|
5455
|
-
function
|
|
5778
|
+
function yankRelease(synced, version, now = (/* @__PURE__ */ new Date()).toISOString()) {
|
|
5779
|
+
return mapReleaseVersion(synced, version, (v) => ({ ...v, yanked: true }), now);
|
|
5780
|
+
}
|
|
5781
|
+
function mapReleaseVersion(synced, version, fn, now) {
|
|
5456
5782
|
const ledger = synced.releases.self;
|
|
5457
5783
|
if (!ledger) throw new Error("No releases to modify");
|
|
5458
5784
|
const idx = ledger.versions.findIndex((v) => v.version === version);
|
|
@@ -5462,7 +5788,7 @@ function mapReleaseVersion(synced, version, fn) {
|
|
|
5462
5788
|
return {
|
|
5463
5789
|
...synced,
|
|
5464
5790
|
releases: { ...synced.releases, self: { ...ledger, versions } },
|
|
5465
|
-
meta: { ...synced.meta, updatedAt:
|
|
5791
|
+
meta: { ...synced.meta, updatedAt: now }
|
|
5466
5792
|
};
|
|
5467
5793
|
}
|
|
5468
5794
|
function emptyLedger() {
|
|
@@ -5474,6 +5800,99 @@ async function sha256Hex2(text) {
|
|
|
5474
5800
|
return [...new Uint8Array(digest)].map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
5475
5801
|
}
|
|
5476
5802
|
|
|
5803
|
+
// src/linked/linkedSnapshot.ts
|
|
5804
|
+
var LINKED_FORBIDDEN_KEYS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
|
|
5805
|
+
var MAX_LINKED_JSON_BYTES = 16 * 1024 * 1024;
|
|
5806
|
+
function parseLinkedWorkspaceJson(text) {
|
|
5807
|
+
if (text.length > MAX_LINKED_JSON_BYTES) {
|
|
5808
|
+
throw new Error("Remote workspace.json exceeds 16 MiB");
|
|
5809
|
+
}
|
|
5810
|
+
let raw;
|
|
5811
|
+
try {
|
|
5812
|
+
raw = JSON.parse(
|
|
5813
|
+
text,
|
|
5814
|
+
(key, value) => LINKED_FORBIDDEN_KEYS.has(key) ? void 0 : value
|
|
5815
|
+
);
|
|
5816
|
+
} catch {
|
|
5817
|
+
throw new Error("Remote workspace.json is not valid JSON");
|
|
5818
|
+
}
|
|
5819
|
+
if (typeof raw !== "object" || raw === null || Array.isArray(raw)) {
|
|
5820
|
+
throw new Error("Remote workspace.json is not an object");
|
|
5821
|
+
}
|
|
5822
|
+
const obj = raw;
|
|
5823
|
+
const asObject = (v) => typeof v === "object" && v !== null ? v : void 0;
|
|
5824
|
+
return {
|
|
5825
|
+
workspaceId: typeof obj.workspaceId === "string" ? obj.workspaceId : void 0,
|
|
5826
|
+
releases: asObject(obj.releases),
|
|
5827
|
+
collections: asObject(obj.collections),
|
|
5828
|
+
environments: asObject(obj.environments),
|
|
5829
|
+
secretKeys: asObject(obj.secretKeys),
|
|
5830
|
+
globalAssets: asObject(obj.globalAssets)
|
|
5831
|
+
};
|
|
5832
|
+
}
|
|
5833
|
+
function ledgerFromProbe(parsed) {
|
|
5834
|
+
return parsed.releases?.self ?? { versions: [], currentVersion: null };
|
|
5835
|
+
}
|
|
5836
|
+
function buildLinkedSnapshot(parsed, link) {
|
|
5837
|
+
if (!parsed.collections && !parsed.environments) return null;
|
|
5838
|
+
return {
|
|
5839
|
+
pulledAt: link.linkedAt,
|
|
5840
|
+
ref: link.pinnedVersion ? `v${link.pinnedVersion}` : `HEAD@${link.source.branch}`,
|
|
5841
|
+
collections: parsed.collections ?? {
|
|
5842
|
+
tree: { id: "remote-root", type: "root", children: [] },
|
|
5843
|
+
requests: {},
|
|
5844
|
+
folders: {}
|
|
5845
|
+
},
|
|
5846
|
+
environments: parsed.environments ?? {
|
|
5847
|
+
items: {},
|
|
5848
|
+
activeName: null,
|
|
5849
|
+
priorityOrder: []
|
|
5850
|
+
},
|
|
5851
|
+
...parsed.secretKeys ? { secretKeys: parsed.secretKeys } : {},
|
|
5852
|
+
...parsed.globalAssets ? { globalAssets: parsed.globalAssets } : {}
|
|
5853
|
+
};
|
|
5854
|
+
}
|
|
5855
|
+
|
|
5856
|
+
// src/linked/requestOverride.ts
|
|
5857
|
+
var OVERRIDABLE_FIELDS = [
|
|
5858
|
+
"name",
|
|
5859
|
+
"method",
|
|
5860
|
+
"url",
|
|
5861
|
+
"headers",
|
|
5862
|
+
"query",
|
|
5863
|
+
"pathParams",
|
|
5864
|
+
"cookies",
|
|
5865
|
+
"body",
|
|
5866
|
+
"auth",
|
|
5867
|
+
"contextVars",
|
|
5868
|
+
"extractions",
|
|
5869
|
+
"assertions"
|
|
5870
|
+
];
|
|
5871
|
+
function mergeRequestOverride(base, patch) {
|
|
5872
|
+
const merged = { ...base };
|
|
5873
|
+
const p = patch;
|
|
5874
|
+
const target = merged;
|
|
5875
|
+
for (const field of OVERRIDABLE_FIELDS) {
|
|
5876
|
+
if (p[field] !== void 0) target[field] = p[field];
|
|
5877
|
+
}
|
|
5878
|
+
return merged;
|
|
5879
|
+
}
|
|
5880
|
+
function computeRequestOverridePatch(base, effective) {
|
|
5881
|
+
const baseRec = { ...base };
|
|
5882
|
+
const effRec = { ...effective };
|
|
5883
|
+
const patch = {};
|
|
5884
|
+
const patchRec = patch;
|
|
5885
|
+
for (const field of OVERRIDABLE_FIELDS) {
|
|
5886
|
+
if (JSON.stringify(baseRec[field]) !== JSON.stringify(effRec[field])) {
|
|
5887
|
+
patchRec[field] = effRec[field];
|
|
5888
|
+
}
|
|
5889
|
+
}
|
|
5890
|
+
return patch;
|
|
5891
|
+
}
|
|
5892
|
+
function isEmptyOverridePatch(patch) {
|
|
5893
|
+
return Object.keys(patch).filter((k) => OVERRIDABLE_FIELDS.includes(k)).length === 0;
|
|
5894
|
+
}
|
|
5895
|
+
|
|
5477
5896
|
// src/editors/contentTypeLanguageMap.ts
|
|
5478
5897
|
var CONTENT_TYPE_LANGUAGE_MAP = {
|
|
5479
5898
|
"application/json": "json",
|
|
@@ -6406,7 +6825,8 @@ function previewLinkedUpdate(args) {
|
|
|
6406
6825
|
status,
|
|
6407
6826
|
base,
|
|
6408
6827
|
target,
|
|
6409
|
-
override
|
|
6828
|
+
override,
|
|
6829
|
+
...status === "both-changed" && base && target && override ? { autoMergeable: requestOverrideIsDisjoint(base, target, override) } : {}
|
|
6410
6830
|
});
|
|
6411
6831
|
}
|
|
6412
6832
|
const baseFolders = args.base?.collections.folders ?? {};
|
|
@@ -6486,6 +6906,34 @@ function classifyRequest(base, target, override) {
|
|
|
6486
6906
|
if (sourceChanged && !hasOverride) return "source-only";
|
|
6487
6907
|
return "both-changed";
|
|
6488
6908
|
}
|
|
6909
|
+
var OVERRIDABLE_REQUEST_FIELDS = [
|
|
6910
|
+
"name",
|
|
6911
|
+
"method",
|
|
6912
|
+
"url",
|
|
6913
|
+
"headers",
|
|
6914
|
+
"query",
|
|
6915
|
+
"pathParams",
|
|
6916
|
+
"cookies",
|
|
6917
|
+
"body",
|
|
6918
|
+
"auth",
|
|
6919
|
+
"contextVars",
|
|
6920
|
+
"extractions",
|
|
6921
|
+
"assertions"
|
|
6922
|
+
];
|
|
6923
|
+
function requestOverrideIsDisjoint(base, target, override) {
|
|
6924
|
+
const baseRec = { ...base };
|
|
6925
|
+
const targetRec = { ...target };
|
|
6926
|
+
const overriddenFields = Object.keys(override.patch);
|
|
6927
|
+
for (const f of overriddenFields) {
|
|
6928
|
+
if (!OVERRIDABLE_REQUEST_FIELDS.includes(f)) {
|
|
6929
|
+
continue;
|
|
6930
|
+
}
|
|
6931
|
+
if (!structurallyEqual2(baseRec[f], targetRec[f])) {
|
|
6932
|
+
return false;
|
|
6933
|
+
}
|
|
6934
|
+
}
|
|
6935
|
+
return true;
|
|
6936
|
+
}
|
|
6489
6937
|
function classifyFolder(base, target) {
|
|
6490
6938
|
if (!base && target) return "new-in-source";
|
|
6491
6939
|
if (base && !target) return "removed-in-source";
|
|
@@ -6535,7 +6983,7 @@ function applyLinkedUpdate(args) {
|
|
|
6535
6983
|
continue;
|
|
6536
6984
|
}
|
|
6537
6985
|
if (entry.status === "both-changed") {
|
|
6538
|
-
const choice = args.resolutions[id];
|
|
6986
|
+
const choice = args.resolutions[id] ?? (entry.autoMergeable ? "mine" : void 0);
|
|
6539
6987
|
if (!choice) {
|
|
6540
6988
|
throw new Error(
|
|
6541
6989
|
`applyLinkedUpdate: unresolved both-changed entry "${entry.label}" (${id})`
|
|
@@ -6546,7 +6994,8 @@ function applyLinkedUpdate(args) {
|
|
|
6546
6994
|
else if (entry.bucket === "environment-var") envVarOverridesByKey.delete(entry.key);
|
|
6547
6995
|
log.push({ entryKey: id, bucket: entry.bucket, action: "accept-source" });
|
|
6548
6996
|
} else {
|
|
6549
|
-
|
|
6997
|
+
const auto = entry.autoMergeable === true && !args.resolutions[id];
|
|
6998
|
+
log.push({ entryKey: id, bucket: entry.bucket, action: auto ? "auto-merge" : "keep-mine" });
|
|
6550
6999
|
}
|
|
6551
7000
|
}
|
|
6552
7001
|
}
|
|
@@ -6562,7 +7011,7 @@ function structurallyEqual2(a, b) {
|
|
|
6562
7011
|
}
|
|
6563
7012
|
|
|
6564
7013
|
// src/workspace/applyMutation.ts
|
|
6565
|
-
var
|
|
7014
|
+
var import_shared3 = require("@apicircle/shared");
|
|
6566
7015
|
|
|
6567
7016
|
// src/workspace/apicircleFolderImport.ts
|
|
6568
7017
|
function importApicircleFolderInto(synced, parsed, parentFolderId) {
|
|
@@ -6803,6 +7252,8 @@ function applyMutation(state, patch, options = {}) {
|
|
|
6803
7252
|
return applyFolderDelete(state, patch.id, now);
|
|
6804
7253
|
case "folder.move":
|
|
6805
7254
|
return applyFolderMove(state, patch.id, patch.newParentId, now);
|
|
7255
|
+
case "folder.update":
|
|
7256
|
+
return applyFolderUpdate(state, patch.id, patch.patch, now);
|
|
6806
7257
|
case "folder.import_apicircle":
|
|
6807
7258
|
return applyFolderImportApicircle(state, patch.parsed, patch.parentFolderId, now);
|
|
6808
7259
|
case "environment.upsert":
|
|
@@ -6815,6 +7266,10 @@ function applyMutation(state, patch, options = {}) {
|
|
|
6815
7266
|
return applyEnvSetPriority(state, patch.order, now);
|
|
6816
7267
|
case "secretKey.upsert":
|
|
6817
7268
|
return applySecretKeyUpsert(state, patch.meta, now);
|
|
7269
|
+
case "secret.crypto.set":
|
|
7270
|
+
return applySecretCryptoSet(state, patch.crypto, now);
|
|
7271
|
+
case "secret.crypto.clear":
|
|
7272
|
+
return applySecretCryptoClear(state, now);
|
|
6818
7273
|
case "assertion.upsert":
|
|
6819
7274
|
return applyAssertionUpsert(state, patch.requestId, patch.assertion, now);
|
|
6820
7275
|
case "assertion.delete":
|
|
@@ -6823,6 +7278,46 @@ function applyMutation(state, patch, options = {}) {
|
|
|
6823
7278
|
return applyMockUpsert(state, patch.mock, now);
|
|
6824
7279
|
case "mock.delete":
|
|
6825
7280
|
return applyMockDelete(state, patch.id, now);
|
|
7281
|
+
case "release.publish":
|
|
7282
|
+
return applyReleasePublish(state, patch.entry, now);
|
|
7283
|
+
case "release.deprecate":
|
|
7284
|
+
return applyReleaseDeprecate(state, patch.version, now);
|
|
7285
|
+
case "release.yank":
|
|
7286
|
+
return applyReleaseYank(state, patch.version, now);
|
|
7287
|
+
case "linkedWorkspace.upsert":
|
|
7288
|
+
return applyLinkedWorkspaceUpsert(state, patch.link, patch.ledger, patch.snapshot, now);
|
|
7289
|
+
case "linkedWorkspace.remove":
|
|
7290
|
+
return applyLinkedWorkspaceRemove(state, patch.id, now);
|
|
7291
|
+
case "linkedWorkspace.applyUpdate":
|
|
7292
|
+
return applyLinkedWorkspaceApplyUpdate(state, patch, now);
|
|
7293
|
+
case "linkedOverride.setRequest":
|
|
7294
|
+
return applyLinkedOverrideSetRequest(state, patch.override, now);
|
|
7295
|
+
case "linkedOverride.removeRequest":
|
|
7296
|
+
return applyLinkedOverrideRemoveRequest(state, patch.linkedWorkspaceId, patch.itemId, now);
|
|
7297
|
+
case "linkedOverride.setEnvVar":
|
|
7298
|
+
return applyLinkedOverrideSetEnvVar(state, patch.override, now);
|
|
7299
|
+
case "linkedOverride.removeEnvVar":
|
|
7300
|
+
return applyLinkedOverrideRemoveEnvVar(
|
|
7301
|
+
state,
|
|
7302
|
+
patch.linkedWorkspaceId,
|
|
7303
|
+
patch.envName,
|
|
7304
|
+
patch.varKey,
|
|
7305
|
+
now
|
|
7306
|
+
);
|
|
7307
|
+
case "linkedOverride.clearForLink":
|
|
7308
|
+
return applyLinkedOverrideClearForLink(state, patch.linkedWorkspaceId, now);
|
|
7309
|
+
case "globalAsset.upsertFile":
|
|
7310
|
+
return applyGlobalAssetUpsertFile(state, patch.file, now);
|
|
7311
|
+
case "globalAsset.removeFile":
|
|
7312
|
+
return applyGlobalAssetRemoveFile(state, patch.id, now);
|
|
7313
|
+
case "globalAsset.markPushed":
|
|
7314
|
+
return applyGlobalAssetMarkPushed(state, patch.id, patch.ref, now);
|
|
7315
|
+
case "globalAsset.markMerged":
|
|
7316
|
+
return applyGlobalAssetMarkMerged(state, patch.id, patch.ref, now);
|
|
7317
|
+
case "globalAsset.cleanupWorkingRef":
|
|
7318
|
+
return applyGlobalAssetCleanupWorkingRef(state, patch.id, now);
|
|
7319
|
+
case "globalAsset.invalidateRef":
|
|
7320
|
+
return applyGlobalAssetInvalidateRef(state, patch.id, patch.which, now);
|
|
6826
7321
|
case "plan.upsert":
|
|
6827
7322
|
return applyPlanUpsert(state, patch.plan, now);
|
|
6828
7323
|
case "plan.delete":
|
|
@@ -6847,12 +7342,13 @@ function applyRequestCreate(state, request, now) {
|
|
|
6847
7342
|
if (state.synced.collections.requests[request.id]) {
|
|
6848
7343
|
return { next: state, changedIds: [] };
|
|
6849
7344
|
}
|
|
7345
|
+
const tree = request.folderId ? state.synced.collections.tree : pushTreeChild(state.synced.collections.tree, { kind: "request", id: request.id });
|
|
6850
7346
|
const synced = {
|
|
6851
7347
|
...state.synced,
|
|
6852
7348
|
collections: {
|
|
6853
7349
|
...state.synced.collections,
|
|
6854
7350
|
requests: { ...state.synced.collections.requests, [request.id]: request },
|
|
6855
|
-
tree
|
|
7351
|
+
tree
|
|
6856
7352
|
},
|
|
6857
7353
|
meta: { ...state.synced.meta, updatedAt: now }
|
|
6858
7354
|
};
|
|
@@ -6901,12 +7397,13 @@ function applyFolderCreate(state, folder, now) {
|
|
|
6901
7397
|
if (state.synced.collections.folders[folder.id]) {
|
|
6902
7398
|
return { next: state, changedIds: [] };
|
|
6903
7399
|
}
|
|
7400
|
+
const tree = folder.parentId ? state.synced.collections.tree : pushTreeChild(state.synced.collections.tree, { kind: "folder", id: folder.id });
|
|
6904
7401
|
const synced = {
|
|
6905
7402
|
...state.synced,
|
|
6906
7403
|
collections: {
|
|
6907
7404
|
...state.synced.collections,
|
|
6908
7405
|
folders: { ...state.synced.collections.folders, [folder.id]: folder },
|
|
6909
|
-
tree
|
|
7406
|
+
tree
|
|
6910
7407
|
},
|
|
6911
7408
|
meta: { ...state.synced.meta, updatedAt: now }
|
|
6912
7409
|
};
|
|
@@ -6975,6 +7472,57 @@ function applyFolderMove(state, id, newParentId, now) {
|
|
|
6975
7472
|
};
|
|
6976
7473
|
return { next: { ...state, synced }, changedIds: [id] };
|
|
6977
7474
|
}
|
|
7475
|
+
function applyFolderUpdate(state, id, patch, now) {
|
|
7476
|
+
const folder = state.synced.collections.folders[id];
|
|
7477
|
+
if (!folder) {
|
|
7478
|
+
return { next: state, changedIds: [] };
|
|
7479
|
+
}
|
|
7480
|
+
const nameChanging = "name" in patch && patch.name !== void 0;
|
|
7481
|
+
const authChanging = "auth" in patch;
|
|
7482
|
+
if (!nameChanging && !authChanging) {
|
|
7483
|
+
return { next: state, changedIds: [] };
|
|
7484
|
+
}
|
|
7485
|
+
let nextName = folder.name;
|
|
7486
|
+
if (nameChanging) {
|
|
7487
|
+
const trimmed = patch.name.trim();
|
|
7488
|
+
if (!trimmed) {
|
|
7489
|
+
} else if (trimmed === folder.name) {
|
|
7490
|
+
} else if (!isFolderNameUnique(state, folder.parentId, trimmed, id)) {
|
|
7491
|
+
return { next: state, changedIds: [] };
|
|
7492
|
+
} else {
|
|
7493
|
+
nextName = trimmed;
|
|
7494
|
+
}
|
|
7495
|
+
}
|
|
7496
|
+
const nextFolder = { ...folder, name: nextName };
|
|
7497
|
+
if (authChanging) {
|
|
7498
|
+
if (patch.auth === void 0) {
|
|
7499
|
+
delete nextFolder.auth;
|
|
7500
|
+
} else {
|
|
7501
|
+
nextFolder.auth = patch.auth;
|
|
7502
|
+
}
|
|
7503
|
+
}
|
|
7504
|
+
if (nextFolder.name === folder.name && nextFolder.auth === folder.auth) {
|
|
7505
|
+
return { next: state, changedIds: [] };
|
|
7506
|
+
}
|
|
7507
|
+
const synced = {
|
|
7508
|
+
...state.synced,
|
|
7509
|
+
collections: {
|
|
7510
|
+
...state.synced.collections,
|
|
7511
|
+
folders: { ...state.synced.collections.folders, [id]: nextFolder }
|
|
7512
|
+
},
|
|
7513
|
+
meta: { ...state.synced.meta, updatedAt: now }
|
|
7514
|
+
};
|
|
7515
|
+
return { next: { ...state, synced }, changedIds: [id] };
|
|
7516
|
+
}
|
|
7517
|
+
function isFolderNameUnique(state, parentId, trimmedCandidate, ignoreId) {
|
|
7518
|
+
const target = trimmedCandidate.toLowerCase();
|
|
7519
|
+
for (const f of Object.values(state.synced.collections.folders)) {
|
|
7520
|
+
if (f.id === ignoreId) continue;
|
|
7521
|
+
if (f.parentId !== parentId) continue;
|
|
7522
|
+
if (f.name.trim().toLowerCase() === target) return false;
|
|
7523
|
+
}
|
|
7524
|
+
return true;
|
|
7525
|
+
}
|
|
6978
7526
|
function applyFolderImportApicircle(state, parsed, parentFolderId, now) {
|
|
6979
7527
|
const result = importApicircleFolderInto(
|
|
6980
7528
|
state.synced,
|
|
@@ -7054,7 +7602,7 @@ function applyEnvSetPriority(state, order, now) {
|
|
|
7054
7602
|
const knownLocal = new Set(Object.keys(state.synced.environments.items));
|
|
7055
7603
|
const seen = /* @__PURE__ */ new Set();
|
|
7056
7604
|
const filtered = order.filter((ref) => {
|
|
7057
|
-
const key = (0,
|
|
7605
|
+
const key = (0, import_shared3.envPriorityKey)(ref);
|
|
7058
7606
|
if (seen.has(key)) return false;
|
|
7059
7607
|
if (ref.kind === "local" && !knownLocal.has(ref.name)) return false;
|
|
7060
7608
|
seen.add(key);
|
|
@@ -7065,7 +7613,7 @@ function applyEnvSetPriority(state, order, now) {
|
|
|
7065
7613
|
environments: { ...state.synced.environments, priorityOrder: filtered },
|
|
7066
7614
|
meta: { ...state.synced.meta, updatedAt: now }
|
|
7067
7615
|
};
|
|
7068
|
-
return { next: { ...state, synced }, changedIds: filtered.map(
|
|
7616
|
+
return { next: { ...state, synced }, changedIds: filtered.map(import_shared3.envPriorityKey) };
|
|
7069
7617
|
}
|
|
7070
7618
|
function applySecretKeyUpsert(state, meta, now) {
|
|
7071
7619
|
if (!meta.id || !meta.label.trim() || !meta.salt) {
|
|
@@ -7081,6 +7629,28 @@ function applySecretKeyUpsert(state, meta, now) {
|
|
|
7081
7629
|
};
|
|
7082
7630
|
return { next: { ...state, synced }, changedIds: [meta.id] };
|
|
7083
7631
|
}
|
|
7632
|
+
function applySecretCryptoSet(state, crypto2, now) {
|
|
7633
|
+
if (!crypto2 || crypto2.kdf !== "pbkdf2-sha256-v1" || !crypto2.salt || !crypto2.verifier || !(crypto2.iterations >= 1)) {
|
|
7634
|
+
return { next: state, changedIds: [] };
|
|
7635
|
+
}
|
|
7636
|
+
const synced = {
|
|
7637
|
+
...state.synced,
|
|
7638
|
+
secretCrypto: { ...crypto2 },
|
|
7639
|
+
meta: { ...state.synced.meta, updatedAt: now }
|
|
7640
|
+
};
|
|
7641
|
+
return { next: { ...state, synced }, changedIds: ["secret.crypto"] };
|
|
7642
|
+
}
|
|
7643
|
+
function applySecretCryptoClear(state, now) {
|
|
7644
|
+
if (!state.synced.secretCrypto) {
|
|
7645
|
+
return { next: state, changedIds: [] };
|
|
7646
|
+
}
|
|
7647
|
+
const synced = {
|
|
7648
|
+
...state.synced,
|
|
7649
|
+
secretCrypto: null,
|
|
7650
|
+
meta: { ...state.synced.meta, updatedAt: now }
|
|
7651
|
+
};
|
|
7652
|
+
return { next: { ...state, synced }, changedIds: ["secret.crypto"] };
|
|
7653
|
+
}
|
|
7084
7654
|
function applyAssertionUpsert(state, requestId, assertion, now) {
|
|
7085
7655
|
const request = state.synced.collections.requests[requestId];
|
|
7086
7656
|
if (!request) {
|
|
@@ -7138,6 +7708,340 @@ function applyMockDelete(state, id, now) {
|
|
|
7138
7708
|
} : state.local;
|
|
7139
7709
|
return { next: { synced, local }, changedIds: [id] };
|
|
7140
7710
|
}
|
|
7711
|
+
function applyReleasePublish(state, entry, now) {
|
|
7712
|
+
const synced = appendReleaseEntry(state.synced, entry, now);
|
|
7713
|
+
return { next: { ...state, synced }, changedIds: [entry.version] };
|
|
7714
|
+
}
|
|
7715
|
+
function applyReleaseDeprecate(state, version, now) {
|
|
7716
|
+
const synced = deprecateRelease(state.synced, version, now);
|
|
7717
|
+
return { next: { ...state, synced }, changedIds: [version] };
|
|
7718
|
+
}
|
|
7719
|
+
function applyReleaseYank(state, version, now) {
|
|
7720
|
+
const synced = yankRelease(state.synced, version, now);
|
|
7721
|
+
return { next: { ...state, synced }, changedIds: [version] };
|
|
7722
|
+
}
|
|
7723
|
+
function applyLinkedWorkspaceUpsert(state, link, ledger, snapshot2, now) {
|
|
7724
|
+
const synced = {
|
|
7725
|
+
...state.synced,
|
|
7726
|
+
linkedWorkspaces: { ...state.synced.linkedWorkspaces, [link.id]: link },
|
|
7727
|
+
releases: ledger ? {
|
|
7728
|
+
...state.synced.releases,
|
|
7729
|
+
perLink: { ...state.synced.releases.perLink, [link.id]: ledger }
|
|
7730
|
+
} : state.synced.releases,
|
|
7731
|
+
meta: { ...state.synced.meta, updatedAt: now }
|
|
7732
|
+
};
|
|
7733
|
+
const local = snapshot2 ? {
|
|
7734
|
+
...state.local,
|
|
7735
|
+
linkedCollections: { ...state.local.linkedCollections, [link.id]: snapshot2 }
|
|
7736
|
+
} : state.local;
|
|
7737
|
+
return { next: { synced, local }, changedIds: [link.id] };
|
|
7738
|
+
}
|
|
7739
|
+
function applyLinkedWorkspaceRemove(state, id, now) {
|
|
7740
|
+
if (!state.synced.linkedWorkspaces[id]) {
|
|
7741
|
+
return { next: state, changedIds: [] };
|
|
7742
|
+
}
|
|
7743
|
+
const linkedWorkspaces = { ...state.synced.linkedWorkspaces };
|
|
7744
|
+
delete linkedWorkspaces[id];
|
|
7745
|
+
const perLink = { ...state.synced.releases.perLink };
|
|
7746
|
+
delete perLink[id];
|
|
7747
|
+
const prefix = `${id}:`;
|
|
7748
|
+
const dropPrefixed = (map) => Object.fromEntries(Object.entries(map).filter(([k]) => !k.startsWith(prefix)));
|
|
7749
|
+
const synced = {
|
|
7750
|
+
...state.synced,
|
|
7751
|
+
linkedWorkspaces,
|
|
7752
|
+
releases: { ...state.synced.releases, perLink },
|
|
7753
|
+
linkedOverrides: {
|
|
7754
|
+
requests: dropPrefixed(state.synced.linkedOverrides.requests),
|
|
7755
|
+
environmentVars: dropPrefixed(state.synced.linkedOverrides.environmentVars)
|
|
7756
|
+
},
|
|
7757
|
+
meta: { ...state.synced.meta, updatedAt: now }
|
|
7758
|
+
};
|
|
7759
|
+
const linkedCollections = { ...state.local.linkedCollections };
|
|
7760
|
+
delete linkedCollections[id];
|
|
7761
|
+
const githubLinks = { ...state.local.sessions.github.links };
|
|
7762
|
+
delete githubLinks[id];
|
|
7763
|
+
const local = {
|
|
7764
|
+
...state.local,
|
|
7765
|
+
linkedCollections,
|
|
7766
|
+
sessions: {
|
|
7767
|
+
...state.local.sessions,
|
|
7768
|
+
github: { ...state.local.sessions.github, links: githubLinks }
|
|
7769
|
+
}
|
|
7770
|
+
};
|
|
7771
|
+
return { next: { synced, local }, changedIds: [id] };
|
|
7772
|
+
}
|
|
7773
|
+
function applyLinkedWorkspaceApplyUpdate(state, patch, now) {
|
|
7774
|
+
const link = state.synced.linkedWorkspaces[patch.id];
|
|
7775
|
+
if (!link) {
|
|
7776
|
+
return { next: state, changedIds: [] };
|
|
7777
|
+
}
|
|
7778
|
+
const prefix = `${patch.id}:`;
|
|
7779
|
+
const otherRequests = Object.fromEntries(
|
|
7780
|
+
Object.entries(state.synced.linkedOverrides.requests).filter(([k]) => !k.startsWith(prefix))
|
|
7781
|
+
);
|
|
7782
|
+
for (const o of patch.requestOverrides) {
|
|
7783
|
+
otherRequests[`${o.linkedWorkspaceId}:${o.itemId}`] = o;
|
|
7784
|
+
}
|
|
7785
|
+
const otherEnvVars = Object.fromEntries(
|
|
7786
|
+
Object.entries(state.synced.linkedOverrides.environmentVars).filter(
|
|
7787
|
+
([k]) => !k.startsWith(prefix)
|
|
7788
|
+
)
|
|
7789
|
+
);
|
|
7790
|
+
for (const o of patch.envVarOverrides) {
|
|
7791
|
+
otherEnvVars[`${o.linkedWorkspaceId}:${o.envName}:${o.varKey}`] = o;
|
|
7792
|
+
}
|
|
7793
|
+
const synced = {
|
|
7794
|
+
...state.synced,
|
|
7795
|
+
linkedWorkspaces: {
|
|
7796
|
+
...state.synced.linkedWorkspaces,
|
|
7797
|
+
[patch.id]: { ...link, pinnedVersion: patch.pinnedVersion }
|
|
7798
|
+
},
|
|
7799
|
+
releases: {
|
|
7800
|
+
...state.synced.releases,
|
|
7801
|
+
perLink: { ...state.synced.releases.perLink, [patch.id]: patch.ledger }
|
|
7802
|
+
},
|
|
7803
|
+
linkedOverrides: { requests: otherRequests, environmentVars: otherEnvVars },
|
|
7804
|
+
meta: { ...state.synced.meta, updatedAt: now }
|
|
7805
|
+
};
|
|
7806
|
+
const local = {
|
|
7807
|
+
...state.local,
|
|
7808
|
+
linkedCollections: { ...state.local.linkedCollections, [patch.id]: patch.snapshot }
|
|
7809
|
+
};
|
|
7810
|
+
return { next: { synced, local }, changedIds: [patch.id] };
|
|
7811
|
+
}
|
|
7812
|
+
function applyLinkedOverrideSetRequest(state, override, now) {
|
|
7813
|
+
const key = `${override.linkedWorkspaceId}:${override.itemId}`;
|
|
7814
|
+
const synced = {
|
|
7815
|
+
...state.synced,
|
|
7816
|
+
linkedOverrides: {
|
|
7817
|
+
...state.synced.linkedOverrides,
|
|
7818
|
+
requests: {
|
|
7819
|
+
...state.synced.linkedOverrides.requests,
|
|
7820
|
+
[key]: { ...override, updatedAt: now }
|
|
7821
|
+
}
|
|
7822
|
+
},
|
|
7823
|
+
meta: { ...state.synced.meta, updatedAt: now }
|
|
7824
|
+
};
|
|
7825
|
+
return { next: { ...state, synced }, changedIds: [key] };
|
|
7826
|
+
}
|
|
7827
|
+
function applyLinkedOverrideRemoveRequest(state, linkedWorkspaceId, itemId, now) {
|
|
7828
|
+
const key = `${linkedWorkspaceId}:${itemId}`;
|
|
7829
|
+
if (!state.synced.linkedOverrides.requests[key]) {
|
|
7830
|
+
return { next: state, changedIds: [] };
|
|
7831
|
+
}
|
|
7832
|
+
const requests = { ...state.synced.linkedOverrides.requests };
|
|
7833
|
+
delete requests[key];
|
|
7834
|
+
const synced = {
|
|
7835
|
+
...state.synced,
|
|
7836
|
+
linkedOverrides: { ...state.synced.linkedOverrides, requests },
|
|
7837
|
+
meta: { ...state.synced.meta, updatedAt: now }
|
|
7838
|
+
};
|
|
7839
|
+
return { next: { ...state, synced }, changedIds: [key] };
|
|
7840
|
+
}
|
|
7841
|
+
function applyLinkedOverrideSetEnvVar(state, override, now) {
|
|
7842
|
+
const key = `${override.linkedWorkspaceId}:${override.envName}:${override.varKey}`;
|
|
7843
|
+
const synced = {
|
|
7844
|
+
...state.synced,
|
|
7845
|
+
linkedOverrides: {
|
|
7846
|
+
...state.synced.linkedOverrides,
|
|
7847
|
+
environmentVars: {
|
|
7848
|
+
...state.synced.linkedOverrides.environmentVars,
|
|
7849
|
+
[key]: { ...override, updatedAt: now }
|
|
7850
|
+
}
|
|
7851
|
+
},
|
|
7852
|
+
meta: { ...state.synced.meta, updatedAt: now }
|
|
7853
|
+
};
|
|
7854
|
+
return { next: { ...state, synced }, changedIds: [key] };
|
|
7855
|
+
}
|
|
7856
|
+
function applyLinkedOverrideRemoveEnvVar(state, linkedWorkspaceId, envName, varKey, now) {
|
|
7857
|
+
const key = `${linkedWorkspaceId}:${envName}:${varKey}`;
|
|
7858
|
+
if (!state.synced.linkedOverrides.environmentVars[key]) {
|
|
7859
|
+
return { next: state, changedIds: [] };
|
|
7860
|
+
}
|
|
7861
|
+
const environmentVars = { ...state.synced.linkedOverrides.environmentVars };
|
|
7862
|
+
delete environmentVars[key];
|
|
7863
|
+
const synced = {
|
|
7864
|
+
...state.synced,
|
|
7865
|
+
linkedOverrides: { ...state.synced.linkedOverrides, environmentVars },
|
|
7866
|
+
meta: { ...state.synced.meta, updatedAt: now }
|
|
7867
|
+
};
|
|
7868
|
+
return { next: { ...state, synced }, changedIds: [key] };
|
|
7869
|
+
}
|
|
7870
|
+
function applyLinkedOverrideClearForLink(state, linkedWorkspaceId, now) {
|
|
7871
|
+
const prefix = `${linkedWorkspaceId}:`;
|
|
7872
|
+
const requestKeys = Object.keys(state.synced.linkedOverrides.requests).filter(
|
|
7873
|
+
(k) => k.startsWith(prefix)
|
|
7874
|
+
);
|
|
7875
|
+
const envKeys = Object.keys(state.synced.linkedOverrides.environmentVars).filter(
|
|
7876
|
+
(k) => k.startsWith(prefix)
|
|
7877
|
+
);
|
|
7878
|
+
if (requestKeys.length === 0 && envKeys.length === 0) {
|
|
7879
|
+
return { next: state, changedIds: [] };
|
|
7880
|
+
}
|
|
7881
|
+
const requests = Object.fromEntries(
|
|
7882
|
+
Object.entries(state.synced.linkedOverrides.requests).filter(([k]) => !k.startsWith(prefix))
|
|
7883
|
+
);
|
|
7884
|
+
const environmentVars = Object.fromEntries(
|
|
7885
|
+
Object.entries(state.synced.linkedOverrides.environmentVars).filter(
|
|
7886
|
+
([k]) => !k.startsWith(prefix)
|
|
7887
|
+
)
|
|
7888
|
+
);
|
|
7889
|
+
const synced = {
|
|
7890
|
+
...state.synced,
|
|
7891
|
+
linkedOverrides: { requests, environmentVars },
|
|
7892
|
+
meta: { ...state.synced.meta, updatedAt: now }
|
|
7893
|
+
};
|
|
7894
|
+
return { next: { ...state, synced }, changedIds: [...requestKeys, ...envKeys] };
|
|
7895
|
+
}
|
|
7896
|
+
function applyGlobalAssetUpsertFile(state, file, now) {
|
|
7897
|
+
const files = state.synced.globalAssets.files ?? {};
|
|
7898
|
+
const existing = files[file.id];
|
|
7899
|
+
const next = {
|
|
7900
|
+
...file,
|
|
7901
|
+
workingBranchRef: file.workingBranchRef !== void 0 ? file.workingBranchRef : existing?.workingBranchRef,
|
|
7902
|
+
baseBranchRef: file.baseBranchRef !== void 0 ? file.baseBranchRef : existing?.baseBranchRef,
|
|
7903
|
+
updatedAt: now
|
|
7904
|
+
};
|
|
7905
|
+
const synced = {
|
|
7906
|
+
...state.synced,
|
|
7907
|
+
globalAssets: {
|
|
7908
|
+
...state.synced.globalAssets,
|
|
7909
|
+
files: { ...files, [file.id]: next }
|
|
7910
|
+
},
|
|
7911
|
+
meta: { ...state.synced.meta, updatedAt: now }
|
|
7912
|
+
};
|
|
7913
|
+
return { next: { ...state, synced }, changedIds: [file.id] };
|
|
7914
|
+
}
|
|
7915
|
+
function applyGlobalAssetRemoveFile(state, id, now) {
|
|
7916
|
+
const files = state.synced.globalAssets.files ?? {};
|
|
7917
|
+
if (!files[id]) {
|
|
7918
|
+
return { next: state, changedIds: [] };
|
|
7919
|
+
}
|
|
7920
|
+
const { [id]: _drop, ...rest } = files;
|
|
7921
|
+
void _drop;
|
|
7922
|
+
const requests = { ...state.synced.collections.requests };
|
|
7923
|
+
for (const [reqId, req] of Object.entries(requests)) {
|
|
7924
|
+
const body = clearAssetFromRequestBody(req.body, id);
|
|
7925
|
+
if (body !== req.body) requests[reqId] = { ...req, body, updatedAt: now };
|
|
7926
|
+
}
|
|
7927
|
+
const mockServers = { ...state.synced.mockServers };
|
|
7928
|
+
for (const [serverId, server] of Object.entries(mockServers)) {
|
|
7929
|
+
let touchedServer = false;
|
|
7930
|
+
const endpoints = server.endpoints.map((endpoint) => {
|
|
7931
|
+
let touched = false;
|
|
7932
|
+
const defaultResponse = clearAssetFromMockResponse(endpoint.defaultResponse, id);
|
|
7933
|
+
if (defaultResponse !== endpoint.defaultResponse) touched = true;
|
|
7934
|
+
const requestValidation = endpoint.requestValidation.map((rule) => {
|
|
7935
|
+
const failResponse = clearAssetFromMockResponse(rule.failResponse, id);
|
|
7936
|
+
if (failResponse === rule.failResponse) return rule;
|
|
7937
|
+
touched = true;
|
|
7938
|
+
return { ...rule, failResponse };
|
|
7939
|
+
});
|
|
7940
|
+
const responseRules = endpoint.responseRules.map((rule) => {
|
|
7941
|
+
const response = clearAssetFromMockResponse(rule.response, id);
|
|
7942
|
+
if (response === rule.response) return rule;
|
|
7943
|
+
touched = true;
|
|
7944
|
+
return { ...rule, response };
|
|
7945
|
+
});
|
|
7946
|
+
if (!touched) return endpoint;
|
|
7947
|
+
touchedServer = true;
|
|
7948
|
+
return { ...endpoint, defaultResponse, requestValidation, responseRules };
|
|
7949
|
+
});
|
|
7950
|
+
if (touchedServer) {
|
|
7951
|
+
const source = server.source.kind === "manual" ? { kind: "manual", endpoints } : server.source;
|
|
7952
|
+
mockServers[serverId] = { ...server, source, endpoints, updatedAt: now };
|
|
7953
|
+
}
|
|
7954
|
+
}
|
|
7955
|
+
let local = state.local;
|
|
7956
|
+
if (local.pendingFileUploads && local.pendingFileUploads[id]) {
|
|
7957
|
+
const nextPending = { ...local.pendingFileUploads };
|
|
7958
|
+
delete nextPending[id];
|
|
7959
|
+
local = { ...local, pendingFileUploads: nextPending };
|
|
7960
|
+
}
|
|
7961
|
+
if (local.assetUsageIndex && local.assetUsageIndex[id]) {
|
|
7962
|
+
const nextUsage = { ...local.assetUsageIndex };
|
|
7963
|
+
delete nextUsage[id];
|
|
7964
|
+
local = { ...local, assetUsageIndex: nextUsage };
|
|
7965
|
+
}
|
|
7966
|
+
const existing = files[id];
|
|
7967
|
+
const hadRemoteRef = Boolean(existing.workingBranchRef || existing.baseBranchRef);
|
|
7968
|
+
if (hadRemoteRef && !(local.pendingAttachmentDeletes ?? []).includes(existing.slotId)) {
|
|
7969
|
+
local = {
|
|
7970
|
+
...local,
|
|
7971
|
+
pendingAttachmentDeletes: [...local.pendingAttachmentDeletes ?? [], existing.slotId]
|
|
7972
|
+
};
|
|
7973
|
+
}
|
|
7974
|
+
const synced = {
|
|
7975
|
+
...state.synced,
|
|
7976
|
+
collections: { ...state.synced.collections, requests },
|
|
7977
|
+
mockServers,
|
|
7978
|
+
globalAssets: { ...state.synced.globalAssets, files: rest },
|
|
7979
|
+
meta: { ...state.synced.meta, updatedAt: now }
|
|
7980
|
+
};
|
|
7981
|
+
return { next: { synced, local }, changedIds: [id] };
|
|
7982
|
+
}
|
|
7983
|
+
function applyGlobalAssetMarkPushed(state, id, ref, now) {
|
|
7984
|
+
return mutateAssetRef(state, id, now, (asset) => ({ ...asset, workingBranchRef: ref }));
|
|
7985
|
+
}
|
|
7986
|
+
function applyGlobalAssetMarkMerged(state, id, ref, now) {
|
|
7987
|
+
return mutateAssetRef(state, id, now, (asset) => ({ ...asset, baseBranchRef: ref }));
|
|
7988
|
+
}
|
|
7989
|
+
function applyGlobalAssetCleanupWorkingRef(state, id, now) {
|
|
7990
|
+
return mutateAssetRef(state, id, now, (asset) => {
|
|
7991
|
+
if (!asset.workingBranchRef) return asset;
|
|
7992
|
+
return { ...asset, workingBranchRef: null };
|
|
7993
|
+
});
|
|
7994
|
+
}
|
|
7995
|
+
function applyGlobalAssetInvalidateRef(state, id, which, now) {
|
|
7996
|
+
return mutateAssetRef(state, id, now, (asset) => {
|
|
7997
|
+
if (which === "working") {
|
|
7998
|
+
if (!asset.workingBranchRef) return asset;
|
|
7999
|
+
return { ...asset, workingBranchRef: null };
|
|
8000
|
+
}
|
|
8001
|
+
if (!asset.baseBranchRef) return asset;
|
|
8002
|
+
return { ...asset, baseBranchRef: null };
|
|
8003
|
+
});
|
|
8004
|
+
}
|
|
8005
|
+
function mutateAssetRef(state, id, now, transform) {
|
|
8006
|
+
const files = state.synced.globalAssets.files ?? {};
|
|
8007
|
+
const existing = files[id];
|
|
8008
|
+
if (!existing) return { next: state, changedIds: [] };
|
|
8009
|
+
const updated = transform(existing);
|
|
8010
|
+
if (updated === existing) return { next: state, changedIds: [] };
|
|
8011
|
+
const next = { ...updated, updatedAt: now };
|
|
8012
|
+
const synced = {
|
|
8013
|
+
...state.synced,
|
|
8014
|
+
globalAssets: {
|
|
8015
|
+
...state.synced.globalAssets,
|
|
8016
|
+
files: { ...files, [id]: next }
|
|
8017
|
+
},
|
|
8018
|
+
meta: { ...state.synced.meta, updatedAt: now }
|
|
8019
|
+
};
|
|
8020
|
+
return { next: { ...state, synced }, changedIds: [id] };
|
|
8021
|
+
}
|
|
8022
|
+
function clearAssetFromRequestBody(body, id) {
|
|
8023
|
+
if (body.type === "binary" && body.attachment?.globalFileAssetId === id) {
|
|
8024
|
+
return { type: "binary", content: "" };
|
|
8025
|
+
}
|
|
8026
|
+
if (body.type !== "form-data" || !body.formRows) return body;
|
|
8027
|
+
let touched = false;
|
|
8028
|
+
const formRows = body.formRows.map((row) => {
|
|
8029
|
+
if (row.kind !== "file" || row.globalFileAssetId !== id) return row;
|
|
8030
|
+
touched = true;
|
|
8031
|
+
return { kind: "file", key: row.key, enabled: row.enabled, slotId: null };
|
|
8032
|
+
});
|
|
8033
|
+
return touched ? { ...body, formRows } : body;
|
|
8034
|
+
}
|
|
8035
|
+
function clearAssetFromMockResponse(response, id) {
|
|
8036
|
+
const body = clearAssetFromMockBody(response.body, id);
|
|
8037
|
+
return body === response.body ? response : { ...response, body };
|
|
8038
|
+
}
|
|
8039
|
+
function clearAssetFromMockBody(body, id) {
|
|
8040
|
+
if (body.type === "binary" && body.attachment?.globalFileAssetId === id) {
|
|
8041
|
+
return { type: "binary", content: "" };
|
|
8042
|
+
}
|
|
8043
|
+
return body;
|
|
8044
|
+
}
|
|
7141
8045
|
function applyPlanUpsert(state, plan, now) {
|
|
7142
8046
|
const existing = state.local.executionPlans[plan.id];
|
|
7143
8047
|
const merged = existing ? { ...existing, ...plan, id: existing.id, createdAt: existing.createdAt, updatedAt: now } : { ...plan, updatedAt: now };
|
|
@@ -7223,7 +8127,7 @@ function evictSnapshotsToCap(entries, maxBytes) {
|
|
|
7223
8127
|
};
|
|
7224
8128
|
}
|
|
7225
8129
|
function applySnapshotCapture(state, args, now) {
|
|
7226
|
-
const id = args.id ?? (0,
|
|
8130
|
+
const id = args.id ?? (0, import_shared3.generateId)();
|
|
7227
8131
|
const snapshot2 = {
|
|
7228
8132
|
id,
|
|
7229
8133
|
createdAt: now,
|
|
@@ -7312,7 +8216,7 @@ function applyHistoryPurge(state, olderThanMs) {
|
|
|
7312
8216
|
}
|
|
7313
8217
|
|
|
7314
8218
|
// src/workspace/runPlan.ts
|
|
7315
|
-
var
|
|
8219
|
+
var import_shared4 = require("@apicircle/shared");
|
|
7316
8220
|
var MAX_REQUEST_RUNS = 500;
|
|
7317
8221
|
var MAX_PLAN_RUNS = 200;
|
|
7318
8222
|
var ANONYMOUS_ACTOR = { kind: "unknown", name: "unknown" };
|
|
@@ -7378,22 +8282,6 @@ function lookupPlanStepRequest(step, synced, local) {
|
|
|
7378
8282
|
linkedGlobalAssets: snapshot2.globalAssets
|
|
7379
8283
|
};
|
|
7380
8284
|
}
|
|
7381
|
-
function mergeRequestOverride(base, patch) {
|
|
7382
|
-
const merged = { ...base };
|
|
7383
|
-
if (patch.name !== void 0) merged.name = patch.name;
|
|
7384
|
-
if (patch.method !== void 0) merged.method = patch.method;
|
|
7385
|
-
if (patch.url !== void 0) merged.url = patch.url;
|
|
7386
|
-
if (patch.headers !== void 0) merged.headers = patch.headers;
|
|
7387
|
-
if (patch.query !== void 0) merged.query = patch.query;
|
|
7388
|
-
if (patch.pathParams !== void 0) merged.pathParams = patch.pathParams;
|
|
7389
|
-
if (patch.cookies !== void 0) merged.cookies = patch.cookies;
|
|
7390
|
-
if (patch.body !== void 0) merged.body = patch.body;
|
|
7391
|
-
if (patch.auth !== void 0) merged.auth = patch.auth;
|
|
7392
|
-
if (patch.contextVars !== void 0) merged.contextVars = patch.contextVars;
|
|
7393
|
-
if (patch.extractions !== void 0) merged.extractions = patch.extractions;
|
|
7394
|
-
if (patch.assertions !== void 0) merged.assertions = patch.assertions;
|
|
7395
|
-
return merged;
|
|
7396
|
-
}
|
|
7397
8285
|
function applyEnvironmentOverrides(source, linkedWorkspaceId, synced) {
|
|
7398
8286
|
const overrides = Object.values(synced.linkedOverrides.environmentVars).filter(
|
|
7399
8287
|
(override) => override.linkedWorkspaceId === linkedWorkspaceId
|
|
@@ -7459,7 +8347,7 @@ async function runPlan(state, planId, opts = {}) {
|
|
|
7459
8347
|
const baseRefs = plan.envPriorityOrder.length > 0 ? plan.envPriorityOrder : state.synced.environments.priorityOrder;
|
|
7460
8348
|
const envRefs = opts.env ? [{ kind: "local", name: opts.env }, ...baseRefs] : baseRefs;
|
|
7461
8349
|
const startedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
7462
|
-
const planRunId = (0,
|
|
8350
|
+
const planRunId = (0, import_shared4.generateId)();
|
|
7463
8351
|
const t0 = Date.now();
|
|
7464
8352
|
const stepRecords = [];
|
|
7465
8353
|
const newRequestRuns = [];
|
|
@@ -7492,7 +8380,7 @@ async function runPlan(state, planId, opts = {}) {
|
|
|
7492
8380
|
const lookup2 = lookupPlanStepRequest(step, state.synced, state.local);
|
|
7493
8381
|
const baseRequest = lookup2.request;
|
|
7494
8382
|
if (!baseRequest) {
|
|
7495
|
-
const runId = (0,
|
|
8383
|
+
const runId = (0, import_shared4.generateId)();
|
|
7496
8384
|
const error = lookup2.error ?? "Request no longer exists in workspace.";
|
|
7497
8385
|
newRequestRuns.push(orphanRun(runId, step.requestId, error));
|
|
7498
8386
|
stepRecords.push({ requestRunId: runId, passed: false });
|
|
@@ -7610,7 +8498,7 @@ function buildEnvMaps(synced, secretsById, local) {
|
|
|
7610
8498
|
vars[v.key] = v.value;
|
|
7611
8499
|
}
|
|
7612
8500
|
}
|
|
7613
|
-
flat[(0,
|
|
8501
|
+
flat[(0, import_shared4.envPriorityKey)({ kind: "local", name })] = vars;
|
|
7614
8502
|
}
|
|
7615
8503
|
if (local) {
|
|
7616
8504
|
for (const [linkId, snapshot2] of Object.entries(local.linkedCollections)) {
|
|
@@ -7627,7 +8515,7 @@ function buildEnvMaps(synced, secretsById, local) {
|
|
|
7627
8515
|
vars[variable.key] = variable.value;
|
|
7628
8516
|
}
|
|
7629
8517
|
}
|
|
7630
|
-
flat[(0,
|
|
8518
|
+
flat[(0, import_shared4.envPriorityKey)({ kind: "linked", linkedWorkspaceId: linkId, envName })] = vars;
|
|
7631
8519
|
}
|
|
7632
8520
|
}
|
|
7633
8521
|
}
|
|
@@ -7654,7 +8542,7 @@ function resolveRequest(request, synced, plan, envRefs, globalContext, flatEnvs,
|
|
|
7654
8542
|
contextVars: Object.entries(ctxMap).map(([key, value]) => ({ key, value })),
|
|
7655
8543
|
environments: flatEnvs,
|
|
7656
8544
|
activeEnvName: null,
|
|
7657
|
-
priorityOrder: envRefs.map(
|
|
8545
|
+
priorityOrder: envRefs.map(import_shared4.envPriorityKey),
|
|
7658
8546
|
secrets: secretsByLabel
|
|
7659
8547
|
});
|
|
7660
8548
|
const missing = /* @__PURE__ */ new Set();
|
|
@@ -7724,7 +8612,7 @@ function orphanRun(id, requestId, error) {
|
|
|
7724
8612
|
function buildRequestRun(resolved, result, assertions) {
|
|
7725
8613
|
const { preview, truncated } = clampPreview(result.body ?? "");
|
|
7726
8614
|
return {
|
|
7727
|
-
id: (0,
|
|
8615
|
+
id: (0, import_shared4.generateId)(),
|
|
7728
8616
|
requestId: resolved.id,
|
|
7729
8617
|
startedAt: result.startedAt,
|
|
7730
8618
|
durationMs: result.durationMs,
|
|
@@ -7744,8 +8632,8 @@ function buildRequestRun(resolved, result, assertions) {
|
|
|
7744
8632
|
};
|
|
7745
8633
|
}
|
|
7746
8634
|
function clampPreview(value) {
|
|
7747
|
-
if (value.length <=
|
|
7748
|
-
return { preview: value.slice(0,
|
|
8635
|
+
if (value.length <= import_shared4.RUN_BODY_PREVIEW_LIMIT) return { preview: value, truncated: false };
|
|
8636
|
+
return { preview: value.slice(0, import_shared4.RUN_BODY_PREVIEW_LIMIT), truncated: true };
|
|
7749
8637
|
}
|
|
7750
8638
|
function redactUrlCredentials(url) {
|
|
7751
8639
|
try {
|
|
@@ -7968,9 +8856,9 @@ function toCsv(value) {
|
|
|
7968
8856
|
}
|
|
7969
8857
|
|
|
7970
8858
|
// src/transform/computeSavings.ts
|
|
7971
|
-
var
|
|
8859
|
+
var import_shared5 = require("@apicircle/shared");
|
|
7972
8860
|
function computeTransformSavings(body, contentType) {
|
|
7973
|
-
const originalBytes = (0,
|
|
8861
|
+
const originalBytes = (0, import_shared5.utf8ByteLength)(body);
|
|
7974
8862
|
if (!isJsonLike(body, contentType)) {
|
|
7975
8863
|
return { originalBytes, minifiedBytes: originalBytes, candidates: [] };
|
|
7976
8864
|
}
|
|
@@ -7981,7 +8869,7 @@ function computeTransformSavings(body, contentType) {
|
|
|
7981
8869
|
return { originalBytes, minifiedBytes: originalBytes, candidates: [] };
|
|
7982
8870
|
}
|
|
7983
8871
|
const minified = JSON.stringify(parsed);
|
|
7984
|
-
const minifiedBytes = (0,
|
|
8872
|
+
const minifiedBytes = (0, import_shared5.utf8ByteLength)(minified);
|
|
7985
8873
|
const candidates = [];
|
|
7986
8874
|
try {
|
|
7987
8875
|
const toon = toToon(parsed);
|
|
@@ -8008,7 +8896,7 @@ function computeTransformSavings(body, contentType) {
|
|
|
8008
8896
|
};
|
|
8009
8897
|
}
|
|
8010
8898
|
function makeCandidate(format, preview, baselineBytes) {
|
|
8011
|
-
const bytes = (0,
|
|
8899
|
+
const bytes = (0, import_shared5.utf8ByteLength)(preview);
|
|
8012
8900
|
const ratio = baselineBytes === 0 ? 0 : 1 - bytes / baselineBytes;
|
|
8013
8901
|
return {
|
|
8014
8902
|
format,
|
|
@@ -8037,22 +8925,30 @@ var TRANSFORM_FORMAT_LABELS = {
|
|
|
8037
8925
|
HTTP_HEADERS_MAP,
|
|
8038
8926
|
OAuth2TokenError,
|
|
8039
8927
|
PlanRunDeniedError,
|
|
8928
|
+
REGISTRY_JSON_PATH,
|
|
8040
8929
|
RemoteWorkspaceParseError,
|
|
8041
8930
|
TRANSFORM_FORMAT_LABELS,
|
|
8931
|
+
WORKSPACE_DIR,
|
|
8932
|
+
appendReleaseEntry,
|
|
8042
8933
|
applyAuth,
|
|
8043
8934
|
applyAwsSigV4,
|
|
8044
8935
|
applyContentTypeForBodyType,
|
|
8936
|
+
applyLinkedEnvironmentOverrides,
|
|
8045
8937
|
applyLinkedUpdate,
|
|
8046
8938
|
applyMerge,
|
|
8047
8939
|
applyMutation,
|
|
8048
8940
|
applyPathParams,
|
|
8049
8941
|
assertNoPlaintextCredentials,
|
|
8942
|
+
attachmentPath,
|
|
8943
|
+
attachmentsDir,
|
|
8050
8944
|
buildAuthorizeUrl,
|
|
8051
8945
|
buildAutoHeaders,
|
|
8052
8946
|
buildDigestAuthHeader,
|
|
8053
8947
|
buildHawkAuthHeader,
|
|
8948
|
+
buildLinkedSnapshot,
|
|
8054
8949
|
buildNtlmType1Negotiate,
|
|
8055
8950
|
buildNtlmType3Authenticate,
|
|
8951
|
+
buildReleaseEntry,
|
|
8056
8952
|
buildRequest,
|
|
8057
8953
|
buildScope,
|
|
8058
8954
|
collectAttachmentSlots,
|
|
@@ -8066,6 +8962,7 @@ var TRANSFORM_FORMAT_LABELS = {
|
|
|
8066
8962
|
composeUrl,
|
|
8067
8963
|
composeUrlWithQuery,
|
|
8068
8964
|
computeCodeChallenge,
|
|
8965
|
+
computeRequestOverridePatch,
|
|
8069
8966
|
computeThreeWayDiff,
|
|
8070
8967
|
computeTransformSavings,
|
|
8071
8968
|
decryptString,
|
|
@@ -8078,6 +8975,7 @@ var TRANSFORM_FORMAT_LABELS = {
|
|
|
8078
8975
|
exportKey,
|
|
8079
8976
|
extractContext,
|
|
8080
8977
|
fetchOAuth2Token,
|
|
8978
|
+
fetchRemoteWorkspaceJson,
|
|
8081
8979
|
findPathPlaceholders,
|
|
8082
8980
|
generateAesKey,
|
|
8083
8981
|
generateCodeVerifier,
|
|
@@ -8095,14 +8993,18 @@ var TRANSFORM_FORMAT_LABELS = {
|
|
|
8095
8993
|
hasUnpushedChanges,
|
|
8096
8994
|
importApicircleFolderInto,
|
|
8097
8995
|
importKey,
|
|
8996
|
+
initSecretCrypto,
|
|
8098
8997
|
isApicircleEnvironment,
|
|
8099
8998
|
isApicircleFolderExport,
|
|
8100
8999
|
isDesktop,
|
|
9000
|
+
isEmptyOverridePatch,
|
|
8101
9001
|
isInsomniaExport,
|
|
8102
9002
|
isPostmanEnvironment,
|
|
8103
9003
|
isPostmanV2Collection,
|
|
8104
9004
|
isValidSemver,
|
|
9005
|
+
ledgerFromProbe,
|
|
8105
9006
|
lookup,
|
|
9007
|
+
mergeRequestOverride,
|
|
8106
9008
|
mergeWithAutoHeaders,
|
|
8107
9009
|
normalizeContentType,
|
|
8108
9010
|
parseApicircleEnvironment,
|
|
@@ -8113,12 +9015,15 @@ var TRANSFORM_FORMAT_LABELS = {
|
|
|
8113
9015
|
parseDigestChallenge,
|
|
8114
9016
|
parseGraphqlSchema,
|
|
8115
9017
|
parseInsomniaCollection,
|
|
9018
|
+
parseLinkedWorkspaceJson,
|
|
8116
9019
|
parseNtlmType2Challenge,
|
|
8117
9020
|
parsePostmanCollection,
|
|
8118
9021
|
parsePostmanEnvironment,
|
|
9022
|
+
parseRegistryActiveId,
|
|
8119
9023
|
parseSemver,
|
|
8120
9024
|
parseUrlQuery,
|
|
8121
9025
|
parseWorkspaceJson,
|
|
9026
|
+
plaintextEnvMap,
|
|
8122
9027
|
pollDeviceFlow,
|
|
8123
9028
|
preSendValidation,
|
|
8124
9029
|
previewLinkedUpdate,
|
|
@@ -8131,6 +9036,7 @@ var TRANSFORM_FORMAT_LABELS = {
|
|
|
8131
9036
|
requestRunToExecutionResult,
|
|
8132
9037
|
resolveInheritedAuth,
|
|
8133
9038
|
resolvePlanRef,
|
|
9039
|
+
resolveRequestForExecution,
|
|
8134
9040
|
resolveString,
|
|
8135
9041
|
resolveStringMap,
|
|
8136
9042
|
runAssertions,
|
|
@@ -8152,7 +9058,9 @@ var TRANSFORM_FORMAT_LABELS = {
|
|
|
8152
9058
|
toYaml,
|
|
8153
9059
|
tokenizeCurl,
|
|
8154
9060
|
tryParsePayload,
|
|
9061
|
+
unlockSecretCrypto,
|
|
8155
9062
|
validateBranchName,
|
|
9063
|
+
workspaceJsonPath,
|
|
8156
9064
|
yankRelease
|
|
8157
9065
|
});
|
|
8158
9066
|
//# sourceMappingURL=index.cjs.map
|