@apicircle/core 1.0.5 → 1.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-PUXJFN2Z.js → chunk-L5DQT7V6.js} +3 -3
- package/dist/{chunk-PUXJFN2Z.js.map → chunk-L5DQT7V6.js.map} +1 -1
- package/dist/index.cjs +1002 -19
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +123 -3
- package/dist/index.d.ts +123 -3
- package/dist/index.js +978 -8
- package/dist/index.js.map +1 -1
- package/dist/patches-ysO3y8pG.d.cts +312 -0
- package/dist/patches-ysO3y8pG.d.ts +312 -0
- package/dist/workspace/file-backed.cjs +2 -2
- package/dist/workspace/file-backed.cjs.map +1 -1
- package/dist/workspace/file-backed.d.cts +1 -1
- package/dist/workspace/file-backed.d.ts +1 -1
- package/dist/workspace/file-backed.js +1 -1
- package/dist/workspace/registry.cjs +2 -2
- package/dist/workspace/registry.cjs.map +1 -1
- package/dist/workspace/registry.d.cts +1 -1
- package/dist/workspace/registry.d.ts +1 -1
- package/dist/workspace/registry.js +1 -1
- package/package.json +28 -2
- package/dist/patches-N7mvDpXn.d.cts +0 -85
- package/dist/patches-N7mvDpXn.d.ts +0 -85
package/dist/index.cjs
CHANGED
|
@@ -21,6 +21,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
21
21
|
var src_exports = {};
|
|
22
22
|
__export(src_exports, {
|
|
23
23
|
ANONYMOUS_ACTOR: () => ANONYMOUS_ACTOR,
|
|
24
|
+
APICIRCLE_FOLDER_EXPORT_FORMAT: () => APICIRCLE_FOLDER_EXPORT_FORMAT,
|
|
24
25
|
DESKTOP_APP_ORIGIN: () => DESKTOP_APP_ORIGIN,
|
|
25
26
|
EMPTY_UNPUSHED_SUMMARY: () => EMPTY_UNPUSHED_SUMMARY,
|
|
26
27
|
HTTP_HEADERS_MAP: () => HTTP_HEADERS_MAP,
|
|
@@ -45,6 +46,8 @@ __export(src_exports, {
|
|
|
45
46
|
buildRequest: () => buildRequest,
|
|
46
47
|
buildScope: () => buildScope,
|
|
47
48
|
collectAttachmentSlots: () => collectAttachmentSlots,
|
|
49
|
+
collectFolderExport: () => collectFolderExport,
|
|
50
|
+
collectFolderExportCredentials: () => collectFolderExportCredentials,
|
|
48
51
|
collectVariableSuggestions: () => collectVariableSuggestions,
|
|
49
52
|
compareSemver: () => compareSemver,
|
|
50
53
|
composeBody: () => composeBody,
|
|
@@ -80,7 +83,10 @@ __export(src_exports, {
|
|
|
80
83
|
getLanguageFromContentType: () => getLanguageFromContentType,
|
|
81
84
|
getVariableAutocomplete: () => getVariableAutocomplete,
|
|
82
85
|
hasUnpushedChanges: () => hasUnpushedChanges,
|
|
86
|
+
importApicircleFolderInto: () => importApicircleFolderInto,
|
|
83
87
|
importKey: () => importKey,
|
|
88
|
+
isApicircleEnvironment: () => isApicircleEnvironment,
|
|
89
|
+
isApicircleFolderExport: () => isApicircleFolderExport,
|
|
84
90
|
isDesktop: () => isDesktop,
|
|
85
91
|
isInsomniaExport: () => isInsomniaExport,
|
|
86
92
|
isPostmanEnvironment: () => isPostmanEnvironment,
|
|
@@ -89,6 +95,10 @@ __export(src_exports, {
|
|
|
89
95
|
lookup: () => lookup,
|
|
90
96
|
mergeWithAutoHeaders: () => mergeWithAutoHeaders,
|
|
91
97
|
normalizeContentType: () => normalizeContentType,
|
|
98
|
+
parseApicircleEnvironment: () => parseApicircleEnvironment,
|
|
99
|
+
parseApicircleEnvironmentDoc: () => parseApicircleEnvironmentDoc,
|
|
100
|
+
parseApicircleFolderExport: () => parseApicircleFolderExport,
|
|
101
|
+
parseApicircleFolderExportDoc: () => parseApicircleFolderExportDoc,
|
|
92
102
|
parseCurl: () => parseCurl,
|
|
93
103
|
parseDigestChallenge: () => parseDigestChallenge,
|
|
94
104
|
parseGraphqlSchema: () => parseGraphqlSchema,
|
|
@@ -104,6 +114,7 @@ __export(src_exports, {
|
|
|
104
114
|
previewLinkedUpdate: () => previewLinkedUpdate,
|
|
105
115
|
publishRelease: () => publishRelease,
|
|
106
116
|
readJsonPath: () => readJsonPath,
|
|
117
|
+
redactFolderExportCredentials: () => redactFolderExportCredentials,
|
|
107
118
|
redactForGit: () => redactForGit,
|
|
108
119
|
refreshToken: () => refreshToken,
|
|
109
120
|
requestDeviceAuthorization: () => requestDeviceAuthorization,
|
|
@@ -116,11 +127,13 @@ __export(src_exports, {
|
|
|
116
127
|
runClientCredentials: () => runClientCredentials,
|
|
117
128
|
runPlan: () => runPlan,
|
|
118
129
|
runRopc: () => runRopc,
|
|
130
|
+
serializeFolderExport: () => serializeFolderExport,
|
|
119
131
|
serializePayload: () => serializePayload,
|
|
120
132
|
serializeWorkspaceForGit: () => serializeWorkspaceForGit,
|
|
121
133
|
signJwt: () => signJwt,
|
|
122
134
|
slugify: () => slugify,
|
|
123
135
|
sortVersionsDesc: () => sortVersionsDesc,
|
|
136
|
+
suggestFolderExportFilename: () => suggestFolderExportFilename,
|
|
124
137
|
suggestHeaders: () => suggestHeaders,
|
|
125
138
|
summarizeUnpushedChanges: () => summarizeUnpushedChanges,
|
|
126
139
|
supportedContentTypeLanguageMap: () => supportedContentTypeLanguageMap,
|
|
@@ -3079,6 +3092,9 @@ function resolveLocation(from, location) {
|
|
|
3079
3092
|
return null;
|
|
3080
3093
|
}
|
|
3081
3094
|
}
|
|
3095
|
+
function isBrowserRuntime() {
|
|
3096
|
+
return typeof window !== "undefined" && typeof window.document !== "undefined";
|
|
3097
|
+
}
|
|
3082
3098
|
async function executeRequest(req, opts = {}) {
|
|
3083
3099
|
const fetchImpl = opts.fetchImpl ?? globalThis.fetch;
|
|
3084
3100
|
const timeoutMs = opts.timeoutMs === void 0 ? DEFAULT_TIMEOUT_MS : opts.timeoutMs;
|
|
@@ -3103,6 +3119,7 @@ async function executeRequest(req, opts = {}) {
|
|
|
3103
3119
|
() => controller.abort(new Error(`Request timed out after ${timeoutMs}ms`)),
|
|
3104
3120
|
timeoutMs
|
|
3105
3121
|
);
|
|
3122
|
+
const redirectMode = isBrowserRuntime() ? "follow" : "manual";
|
|
3106
3123
|
let currentUrl = builtRequest.url;
|
|
3107
3124
|
let currentHeaders = { ...builtRequest.headers };
|
|
3108
3125
|
let currentMethod = builtRequest.method;
|
|
@@ -3112,7 +3129,7 @@ async function executeRequest(req, opts = {}) {
|
|
|
3112
3129
|
headers: currentHeaders,
|
|
3113
3130
|
body: currentBody,
|
|
3114
3131
|
signal: controller.signal,
|
|
3115
|
-
redirect:
|
|
3132
|
+
redirect: redirectMode
|
|
3116
3133
|
});
|
|
3117
3134
|
let redirectCount = 0;
|
|
3118
3135
|
while (REDIRECT_STATUSES.has(response.status) && redirectCount < MAX_REDIRECTS) {
|
|
@@ -3138,7 +3155,7 @@ async function executeRequest(req, opts = {}) {
|
|
|
3138
3155
|
headers: currentHeaders,
|
|
3139
3156
|
body: currentBody,
|
|
3140
3157
|
signal: controller.signal,
|
|
3141
|
-
redirect:
|
|
3158
|
+
redirect: redirectMode
|
|
3142
3159
|
});
|
|
3143
3160
|
redirectCount++;
|
|
3144
3161
|
}
|
|
@@ -4105,6 +4122,699 @@ function parseAuth2(auth, warnings, name) {
|
|
|
4105
4122
|
}
|
|
4106
4123
|
}
|
|
4107
4124
|
|
|
4125
|
+
// src/import/apicircleFolder.ts
|
|
4126
|
+
var import_shared = require("@apicircle/shared");
|
|
4127
|
+
|
|
4128
|
+
// src/export/folderExportCredentials.ts
|
|
4129
|
+
function collectFolderExportCredentials(envelope) {
|
|
4130
|
+
const out = [];
|
|
4131
|
+
if (envelope.folder.auth) {
|
|
4132
|
+
out.push(
|
|
4133
|
+
...authCredentialFields(envelope.folder.auth).map(
|
|
4134
|
+
(f) => buildCredential(
|
|
4135
|
+
"root-folder",
|
|
4136
|
+
envelope.source.folderId,
|
|
4137
|
+
envelope.folder.name,
|
|
4138
|
+
envelope.folder.auth,
|
|
4139
|
+
f
|
|
4140
|
+
)
|
|
4141
|
+
)
|
|
4142
|
+
);
|
|
4143
|
+
}
|
|
4144
|
+
for (const sub of envelope.folder.subfolders) {
|
|
4145
|
+
if (!sub.auth) continue;
|
|
4146
|
+
out.push(
|
|
4147
|
+
...authCredentialFields(sub.auth).map(
|
|
4148
|
+
(f) => buildCredential("subfolder", sub.id, sub.name, sub.auth, f)
|
|
4149
|
+
)
|
|
4150
|
+
);
|
|
4151
|
+
}
|
|
4152
|
+
for (const req of envelope.folder.requests) {
|
|
4153
|
+
out.push(
|
|
4154
|
+
...authCredentialFields(req.auth).map(
|
|
4155
|
+
(f) => buildCredential("request", req.id, req.name, req.auth, f)
|
|
4156
|
+
)
|
|
4157
|
+
);
|
|
4158
|
+
}
|
|
4159
|
+
return out.sort(credentialCompare);
|
|
4160
|
+
}
|
|
4161
|
+
function redactFolderExportCredentials(envelope, includeIds = /* @__PURE__ */ new Set()) {
|
|
4162
|
+
const next = {
|
|
4163
|
+
...envelope,
|
|
4164
|
+
folder: {
|
|
4165
|
+
...envelope.folder,
|
|
4166
|
+
auth: envelope.folder.auth ? redactAuthForScope(
|
|
4167
|
+
envelope.folder.auth,
|
|
4168
|
+
credentialIdsFor("root-folder", envelope.source.folderId, envelope.folder.auth),
|
|
4169
|
+
includeIds
|
|
4170
|
+
) : envelope.folder.auth,
|
|
4171
|
+
subfolders: envelope.folder.subfolders.map((sub) => {
|
|
4172
|
+
if (!sub.auth) return sub;
|
|
4173
|
+
const ids = credentialIdsFor("subfolder", sub.id, sub.auth);
|
|
4174
|
+
return {
|
|
4175
|
+
...sub,
|
|
4176
|
+
auth: redactAuthForScope(sub.auth, ids, includeIds)
|
|
4177
|
+
};
|
|
4178
|
+
}),
|
|
4179
|
+
requests: envelope.folder.requests.map((req) => ({
|
|
4180
|
+
...req,
|
|
4181
|
+
auth: redactAuthForScope(
|
|
4182
|
+
req.auth,
|
|
4183
|
+
credentialIdsFor("request", req.id, req.auth),
|
|
4184
|
+
includeIds
|
|
4185
|
+
)
|
|
4186
|
+
}))
|
|
4187
|
+
}
|
|
4188
|
+
};
|
|
4189
|
+
return next;
|
|
4190
|
+
}
|
|
4191
|
+
function authCredentialFields(auth) {
|
|
4192
|
+
switch (auth.type) {
|
|
4193
|
+
case "none":
|
|
4194
|
+
case "inherit":
|
|
4195
|
+
case "custom-header":
|
|
4196
|
+
return [];
|
|
4197
|
+
case "basic":
|
|
4198
|
+
return [{ field: "password", label: "Basic \xB7 password" }];
|
|
4199
|
+
case "bearer":
|
|
4200
|
+
return auth.token ? [{ field: "token", label: "Bearer \xB7 token" }] : [];
|
|
4201
|
+
case "api-key":
|
|
4202
|
+
return auth.value ? [{ field: "value", label: "API key \xB7 value" }] : [];
|
|
4203
|
+
case "digest":
|
|
4204
|
+
return [{ field: "password", label: "Digest \xB7 password" }];
|
|
4205
|
+
case "ntlm":
|
|
4206
|
+
return [{ field: "password", label: "NTLM \xB7 password" }];
|
|
4207
|
+
case "hawk":
|
|
4208
|
+
return auth.hawkKey ? [{ field: "hawkKey", label: "Hawk \xB7 hawkKey" }] : [];
|
|
4209
|
+
case "jwt-bearer":
|
|
4210
|
+
return [
|
|
4211
|
+
...auth.secretOrKey ? [{ field: "secretOrKey", label: "JWT \xB7 secretOrKey" }] : [],
|
|
4212
|
+
...auth.token ? [{ field: "token", label: "JWT \xB7 token" }] : []
|
|
4213
|
+
];
|
|
4214
|
+
case "aws-sigv4":
|
|
4215
|
+
return [
|
|
4216
|
+
...auth.secretAccessKey ? [{ field: "secretAccessKey", label: "AWS SigV4 \xB7 secretAccessKey" }] : [],
|
|
4217
|
+
...auth.sessionToken ? [{ field: "sessionToken", label: "AWS SigV4 \xB7 sessionToken" }] : []
|
|
4218
|
+
];
|
|
4219
|
+
case "oauth2-client-credentials":
|
|
4220
|
+
case "oauth2-auth-code":
|
|
4221
|
+
case "oauth2-pkce":
|
|
4222
|
+
return [
|
|
4223
|
+
...auth.clientSecret ? [{ field: "clientSecret", label: `${auth.type} \xB7 clientSecret` }] : [],
|
|
4224
|
+
...auth.accessToken ? [{ field: "accessToken", label: `${auth.type} \xB7 accessToken` }] : [],
|
|
4225
|
+
...auth.refreshToken ? [{ field: "refreshToken", label: `${auth.type} \xB7 refreshToken` }] : []
|
|
4226
|
+
];
|
|
4227
|
+
case "oauth2-password":
|
|
4228
|
+
return [
|
|
4229
|
+
...auth.clientSecret ? [{ field: "clientSecret", label: "oauth2-password \xB7 clientSecret" }] : [],
|
|
4230
|
+
...auth.password ? [{ field: "password", label: "oauth2-password \xB7 password" }] : [],
|
|
4231
|
+
...auth.accessToken ? [{ field: "accessToken", label: "oauth2-password \xB7 accessToken" }] : [],
|
|
4232
|
+
...auth.refreshToken ? [{ field: "refreshToken", label: "oauth2-password \xB7 refreshToken" }] : []
|
|
4233
|
+
];
|
|
4234
|
+
case "oauth2-implicit":
|
|
4235
|
+
return auth.accessToken ? [{ field: "accessToken", label: "oauth2-implicit \xB7 accessToken" }] : [];
|
|
4236
|
+
case "oauth2-device":
|
|
4237
|
+
return [
|
|
4238
|
+
...auth.accessToken ? [{ field: "accessToken", label: "oauth2-device \xB7 accessToken" }] : [],
|
|
4239
|
+
...auth.refreshToken ? [{ field: "refreshToken", label: "oauth2-device \xB7 refreshToken" }] : []
|
|
4240
|
+
];
|
|
4241
|
+
default:
|
|
4242
|
+
return [];
|
|
4243
|
+
}
|
|
4244
|
+
}
|
|
4245
|
+
function buildCredential(scope, ownerId, ownerName, auth, desc) {
|
|
4246
|
+
const prefix = scope === "request" ? "request" : "folder";
|
|
4247
|
+
return {
|
|
4248
|
+
id: `${prefix}:${ownerId}.${auth.type}.${desc.field}`,
|
|
4249
|
+
scope,
|
|
4250
|
+
authType: auth.type,
|
|
4251
|
+
field: desc.field,
|
|
4252
|
+
label: desc.label,
|
|
4253
|
+
ownerName,
|
|
4254
|
+
ownerId
|
|
4255
|
+
};
|
|
4256
|
+
}
|
|
4257
|
+
function credentialIdsFor(scope, ownerId, auth) {
|
|
4258
|
+
const ids = /* @__PURE__ */ new Map();
|
|
4259
|
+
const prefix = scope === "request" ? "request" : "folder";
|
|
4260
|
+
for (const desc of authCredentialFields(auth)) {
|
|
4261
|
+
ids.set(desc.field, `${prefix}:${ownerId}.${auth.type}.${desc.field}`);
|
|
4262
|
+
}
|
|
4263
|
+
return ids;
|
|
4264
|
+
}
|
|
4265
|
+
function redactAuthForScope(auth, ids, includeIds) {
|
|
4266
|
+
const shouldBlank = (field) => {
|
|
4267
|
+
const id = ids.get(field);
|
|
4268
|
+
return !!id && !includeIds.has(id);
|
|
4269
|
+
};
|
|
4270
|
+
switch (auth.type) {
|
|
4271
|
+
case "none":
|
|
4272
|
+
case "inherit":
|
|
4273
|
+
case "custom-header":
|
|
4274
|
+
return auth;
|
|
4275
|
+
case "basic":
|
|
4276
|
+
return shouldBlank("password") ? { ...auth, password: "" } : auth;
|
|
4277
|
+
case "bearer":
|
|
4278
|
+
return shouldBlank("token") ? { ...auth, token: "" } : auth;
|
|
4279
|
+
case "api-key":
|
|
4280
|
+
return shouldBlank("value") ? { ...auth, value: "" } : auth;
|
|
4281
|
+
case "digest":
|
|
4282
|
+
return shouldBlank("password") ? { ...auth, password: "" } : auth;
|
|
4283
|
+
case "ntlm":
|
|
4284
|
+
return shouldBlank("password") ? { ...auth, password: "" } : auth;
|
|
4285
|
+
case "hawk":
|
|
4286
|
+
return shouldBlank("hawkKey") ? { ...auth, hawkKey: "" } : auth;
|
|
4287
|
+
case "jwt-bearer":
|
|
4288
|
+
return {
|
|
4289
|
+
...auth,
|
|
4290
|
+
secretOrKey: shouldBlank("secretOrKey") ? "" : auth.secretOrKey,
|
|
4291
|
+
token: shouldBlank("token") ? "" : auth.token
|
|
4292
|
+
};
|
|
4293
|
+
case "aws-sigv4":
|
|
4294
|
+
return {
|
|
4295
|
+
...auth,
|
|
4296
|
+
secretAccessKey: shouldBlank("secretAccessKey") ? "" : auth.secretAccessKey,
|
|
4297
|
+
sessionToken: shouldBlank("sessionToken") ? "" : auth.sessionToken
|
|
4298
|
+
};
|
|
4299
|
+
case "oauth2-client-credentials":
|
|
4300
|
+
case "oauth2-auth-code":
|
|
4301
|
+
case "oauth2-pkce":
|
|
4302
|
+
return {
|
|
4303
|
+
...auth,
|
|
4304
|
+
clientSecret: shouldBlank("clientSecret") ? "" : auth.clientSecret,
|
|
4305
|
+
accessToken: shouldBlank("accessToken") ? "" : auth.accessToken,
|
|
4306
|
+
refreshToken: shouldBlank("refreshToken") ? "" : auth.refreshToken
|
|
4307
|
+
};
|
|
4308
|
+
case "oauth2-password":
|
|
4309
|
+
return {
|
|
4310
|
+
...auth,
|
|
4311
|
+
clientSecret: shouldBlank("clientSecret") ? "" : auth.clientSecret,
|
|
4312
|
+
password: shouldBlank("password") ? "" : auth.password,
|
|
4313
|
+
accessToken: shouldBlank("accessToken") ? "" : auth.accessToken,
|
|
4314
|
+
refreshToken: shouldBlank("refreshToken") ? "" : auth.refreshToken
|
|
4315
|
+
};
|
|
4316
|
+
case "oauth2-implicit":
|
|
4317
|
+
return {
|
|
4318
|
+
...auth,
|
|
4319
|
+
accessToken: shouldBlank("accessToken") ? "" : auth.accessToken
|
|
4320
|
+
};
|
|
4321
|
+
case "oauth2-device":
|
|
4322
|
+
return {
|
|
4323
|
+
...auth,
|
|
4324
|
+
accessToken: shouldBlank("accessToken") ? "" : auth.accessToken,
|
|
4325
|
+
refreshToken: shouldBlank("refreshToken") ? "" : auth.refreshToken
|
|
4326
|
+
};
|
|
4327
|
+
default:
|
|
4328
|
+
return auth;
|
|
4329
|
+
}
|
|
4330
|
+
}
|
|
4331
|
+
function scopeRank(scope) {
|
|
4332
|
+
if (scope === "root-folder") return 0;
|
|
4333
|
+
if (scope === "subfolder") return 1;
|
|
4334
|
+
return 2;
|
|
4335
|
+
}
|
|
4336
|
+
function credentialCompare(a, b) {
|
|
4337
|
+
const r = scopeRank(a.scope) - scopeRank(b.scope);
|
|
4338
|
+
if (r !== 0) return r;
|
|
4339
|
+
return a.ownerName.localeCompare(b.ownerName, void 0, { sensitivity: "base" });
|
|
4340
|
+
}
|
|
4341
|
+
|
|
4342
|
+
// src/export/folderExport.ts
|
|
4343
|
+
var APICIRCLE_FOLDER_EXPORT_FORMAT = "apicircle.folder/v1";
|
|
4344
|
+
function collectFolderExport(args) {
|
|
4345
|
+
const { synced, folderId } = args;
|
|
4346
|
+
const root = synced.collections.folders[folderId];
|
|
4347
|
+
if (!root) return null;
|
|
4348
|
+
const now = args.now ?? (/* @__PURE__ */ new Date()).toISOString();
|
|
4349
|
+
const appVersion = args.appVersion ?? "apicircle-studio";
|
|
4350
|
+
const folderIds = /* @__PURE__ */ new Set([folderId]);
|
|
4351
|
+
let grew = true;
|
|
4352
|
+
while (grew) {
|
|
4353
|
+
grew = false;
|
|
4354
|
+
for (const f of Object.values(synced.collections.folders)) {
|
|
4355
|
+
if (folderIds.has(f.id)) continue;
|
|
4356
|
+
if (f.parentId && folderIds.has(f.parentId)) {
|
|
4357
|
+
folderIds.add(f.id);
|
|
4358
|
+
grew = true;
|
|
4359
|
+
}
|
|
4360
|
+
}
|
|
4361
|
+
}
|
|
4362
|
+
const subfolders = [];
|
|
4363
|
+
for (const f of Object.values(synced.collections.folders)) {
|
|
4364
|
+
if (f.id !== folderId && folderIds.has(f.id)) subfolders.push(cloneFolder(f));
|
|
4365
|
+
}
|
|
4366
|
+
const requests = [];
|
|
4367
|
+
for (const r of Object.values(synced.collections.requests)) {
|
|
4368
|
+
if (r.folderId && folderIds.has(r.folderId)) requests.push(cloneRequest(r));
|
|
4369
|
+
}
|
|
4370
|
+
const dependencies = collectDependencies(synced, requests);
|
|
4371
|
+
const envelope = {
|
|
4372
|
+
format: APICIRCLE_FOLDER_EXPORT_FORMAT,
|
|
4373
|
+
exportedAt: now,
|
|
4374
|
+
appVersion,
|
|
4375
|
+
source: {
|
|
4376
|
+
workspaceId: synced.workspaceId,
|
|
4377
|
+
folderId,
|
|
4378
|
+
folderName: root.name
|
|
4379
|
+
},
|
|
4380
|
+
folder: {
|
|
4381
|
+
name: root.name,
|
|
4382
|
+
auth: root.auth,
|
|
4383
|
+
subfolders,
|
|
4384
|
+
requests
|
|
4385
|
+
},
|
|
4386
|
+
dependencies
|
|
4387
|
+
};
|
|
4388
|
+
const report = buildReport(envelope);
|
|
4389
|
+
return { envelope, report };
|
|
4390
|
+
}
|
|
4391
|
+
function serializeFolderExport(envelope) {
|
|
4392
|
+
return JSON.stringify(envelope, null, 2);
|
|
4393
|
+
}
|
|
4394
|
+
function suggestFolderExportFilename(envelope) {
|
|
4395
|
+
const slug = envelope.folder.name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
4396
|
+
const base = slug || "folder";
|
|
4397
|
+
return `${base}.apicircle.json`;
|
|
4398
|
+
}
|
|
4399
|
+
function cloneFolder(f) {
|
|
4400
|
+
return {
|
|
4401
|
+
...f,
|
|
4402
|
+
auth: f.auth ? { ...f.auth } : void 0
|
|
4403
|
+
};
|
|
4404
|
+
}
|
|
4405
|
+
function cloneRequest(r) {
|
|
4406
|
+
return {
|
|
4407
|
+
...r,
|
|
4408
|
+
headers: r.headers.map((h) => ({ ...h })),
|
|
4409
|
+
query: r.query.map((q) => ({ ...q })),
|
|
4410
|
+
pathParams: r.pathParams ? { ...r.pathParams } : void 0,
|
|
4411
|
+
cookies: r.cookies ? r.cookies.map((c) => ({ ...c })) : void 0,
|
|
4412
|
+
body: cloneBody(r.body),
|
|
4413
|
+
auth: { ...r.auth },
|
|
4414
|
+
contextVars: r.contextVars.map((v) => ({ ...v })),
|
|
4415
|
+
extractions: r.extractions.map((e) => ({ ...e })),
|
|
4416
|
+
assertions: r.assertions.map((a) => ({ ...a }))
|
|
4417
|
+
};
|
|
4418
|
+
}
|
|
4419
|
+
function cloneBody(body) {
|
|
4420
|
+
if (body.type === "form-data") {
|
|
4421
|
+
return {
|
|
4422
|
+
...body,
|
|
4423
|
+
formRows: body.formRows?.map((row) => ({ ...row })) ?? body.formRows
|
|
4424
|
+
};
|
|
4425
|
+
}
|
|
4426
|
+
if (body.type === "binary") {
|
|
4427
|
+
return {
|
|
4428
|
+
...body,
|
|
4429
|
+
attachment: body.attachment ? { ...body.attachment } : void 0
|
|
4430
|
+
};
|
|
4431
|
+
}
|
|
4432
|
+
return { ...body };
|
|
4433
|
+
}
|
|
4434
|
+
function collectDependencies(synced, requests) {
|
|
4435
|
+
const schemaIds = /* @__PURE__ */ new Set();
|
|
4436
|
+
const graphqlIds = /* @__PURE__ */ new Set();
|
|
4437
|
+
const fileIds = /* @__PURE__ */ new Set();
|
|
4438
|
+
for (const r of requests) {
|
|
4439
|
+
if (r.bodySchemaId) schemaIds.add(r.bodySchemaId);
|
|
4440
|
+
if (r.graphqlSchemaId) graphqlIds.add(r.graphqlSchemaId);
|
|
4441
|
+
if (r.body.type === "binary" && r.body.attachment?.globalFileAssetId) {
|
|
4442
|
+
fileIds.add(r.body.attachment.globalFileAssetId);
|
|
4443
|
+
}
|
|
4444
|
+
if (r.body.type === "form-data" && r.body.formRows) {
|
|
4445
|
+
for (const row of r.body.formRows) {
|
|
4446
|
+
if (row.kind === "file" && row.globalFileAssetId) fileIds.add(row.globalFileAssetId);
|
|
4447
|
+
}
|
|
4448
|
+
}
|
|
4449
|
+
}
|
|
4450
|
+
const assets = synced.globalAssets;
|
|
4451
|
+
const schemas = [];
|
|
4452
|
+
for (const id of schemaIds) {
|
|
4453
|
+
const s = assets.schemas[id];
|
|
4454
|
+
if (s) schemas.push({ ...s });
|
|
4455
|
+
}
|
|
4456
|
+
const graphql = [];
|
|
4457
|
+
for (const id of graphqlIds) {
|
|
4458
|
+
const g = assets.graphql[id];
|
|
4459
|
+
if (g) graphql.push({ ...g });
|
|
4460
|
+
}
|
|
4461
|
+
const files = [];
|
|
4462
|
+
for (const id of fileIds) {
|
|
4463
|
+
const f = assets.files?.[id];
|
|
4464
|
+
if (f) files.push({ ...f });
|
|
4465
|
+
}
|
|
4466
|
+
schemas.sort(byNameThenId);
|
|
4467
|
+
graphql.sort(byNameThenId);
|
|
4468
|
+
files.sort(byNameThenId);
|
|
4469
|
+
return { schemas, graphql, files };
|
|
4470
|
+
}
|
|
4471
|
+
function byNameThenId(a, b) {
|
|
4472
|
+
const c = a.name.localeCompare(b.name, void 0, { sensitivity: "base" });
|
|
4473
|
+
return c !== 0 ? c : a.id.localeCompare(b.id);
|
|
4474
|
+
}
|
|
4475
|
+
function buildReport(envelope) {
|
|
4476
|
+
const subfolderCount = envelope.folder.subfolders.length;
|
|
4477
|
+
const requestCount = envelope.folder.requests.length;
|
|
4478
|
+
const totalFolderCount = subfolderCount + 1;
|
|
4479
|
+
const credentials = collectFolderExportCredentials(envelope);
|
|
4480
|
+
return {
|
|
4481
|
+
folderName: envelope.folder.name,
|
|
4482
|
+
requestCount,
|
|
4483
|
+
subfolderCount,
|
|
4484
|
+
totalFolderCount,
|
|
4485
|
+
dependencies: {
|
|
4486
|
+
schemas: envelope.dependencies.schemas.map((s) => ({ id: s.id, name: s.name })),
|
|
4487
|
+
graphql: envelope.dependencies.graphql.map((g) => ({
|
|
4488
|
+
id: g.id,
|
|
4489
|
+
name: g.name,
|
|
4490
|
+
kind: g.kind
|
|
4491
|
+
})),
|
|
4492
|
+
files: envelope.dependencies.files.map((f) => ({
|
|
4493
|
+
id: f.id,
|
|
4494
|
+
name: f.name,
|
|
4495
|
+
filename: f.filename,
|
|
4496
|
+
size: f.size,
|
|
4497
|
+
mimeType: f.mimeType
|
|
4498
|
+
}))
|
|
4499
|
+
},
|
|
4500
|
+
hasDependencies: envelope.dependencies.schemas.length > 0 || envelope.dependencies.graphql.length > 0 || envelope.dependencies.files.length > 0,
|
|
4501
|
+
credentials,
|
|
4502
|
+
hasCredentials: credentials.length > 0
|
|
4503
|
+
};
|
|
4504
|
+
}
|
|
4505
|
+
|
|
4506
|
+
// src/import/apicircleFolder.ts
|
|
4507
|
+
function isApicircleFolderExport(doc) {
|
|
4508
|
+
if (!doc || typeof doc !== "object") return false;
|
|
4509
|
+
const d = doc;
|
|
4510
|
+
return d.format === APICIRCLE_FOLDER_EXPORT_FORMAT;
|
|
4511
|
+
}
|
|
4512
|
+
function parseApicircleFolderExport(input, options = {}) {
|
|
4513
|
+
let doc;
|
|
4514
|
+
try {
|
|
4515
|
+
doc = JSON.parse(input);
|
|
4516
|
+
} catch (err) {
|
|
4517
|
+
throw new Error(`Couldn't parse JSON: ${err instanceof Error ? err.message : String(err)}`);
|
|
4518
|
+
}
|
|
4519
|
+
return parseApicircleFolderExportDoc(doc, options);
|
|
4520
|
+
}
|
|
4521
|
+
function parseApicircleFolderExportDoc(doc, options = {}) {
|
|
4522
|
+
const id = options.idGenerator ?? import_shared.generateId;
|
|
4523
|
+
if (!isApicircleFolderExport(doc)) {
|
|
4524
|
+
throw new Error(
|
|
4525
|
+
`Unsupported format. Expected an API Circle folder export ("format": "${APICIRCLE_FOLDER_EXPORT_FORMAT}").`
|
|
4526
|
+
);
|
|
4527
|
+
}
|
|
4528
|
+
const envelope = doc;
|
|
4529
|
+
validateEnvelopeShape(envelope);
|
|
4530
|
+
const warnings = [];
|
|
4531
|
+
const folderIdMap = /* @__PURE__ */ new Map();
|
|
4532
|
+
folderIdMap.set(envelope.source.folderId, id());
|
|
4533
|
+
for (const f of envelope.folder.subfolders) folderIdMap.set(f.id, id());
|
|
4534
|
+
const requestIdMap = /* @__PURE__ */ new Map();
|
|
4535
|
+
for (const r of envelope.folder.requests) requestIdMap.set(r.id, id());
|
|
4536
|
+
const schemaIdMap = /* @__PURE__ */ new Map();
|
|
4537
|
+
for (const s of envelope.dependencies.schemas) schemaIdMap.set(s.id, id());
|
|
4538
|
+
const graphqlIdMap = /* @__PURE__ */ new Map();
|
|
4539
|
+
for (const g of envelope.dependencies.graphql) graphqlIdMap.set(g.id, id());
|
|
4540
|
+
const fileIdMap = /* @__PURE__ */ new Map();
|
|
4541
|
+
for (const f of envelope.dependencies.files) fileIdMap.set(f.id, id());
|
|
4542
|
+
const rootFolderId = folderIdMap.get(envelope.source.folderId);
|
|
4543
|
+
const subfolders = envelope.folder.subfolders.map((f) => {
|
|
4544
|
+
const newId = folderIdMap.get(f.id);
|
|
4545
|
+
let newParentId;
|
|
4546
|
+
if (f.parentId === null) {
|
|
4547
|
+
newParentId = rootFolderId;
|
|
4548
|
+
} else {
|
|
4549
|
+
const mapped = folderIdMap.get(f.parentId);
|
|
4550
|
+
if (!mapped) {
|
|
4551
|
+
warnings.push(
|
|
4552
|
+
`Subfolder "${f.name}" referenced parentId "${f.parentId}" that wasn't present in the export \u2014 reattached under "${envelope.folder.name}".`
|
|
4553
|
+
);
|
|
4554
|
+
newParentId = rootFolderId;
|
|
4555
|
+
} else {
|
|
4556
|
+
newParentId = mapped;
|
|
4557
|
+
}
|
|
4558
|
+
}
|
|
4559
|
+
return {
|
|
4560
|
+
...f,
|
|
4561
|
+
id: newId,
|
|
4562
|
+
parentId: newParentId,
|
|
4563
|
+
auth: f.auth ? { ...f.auth } : void 0
|
|
4564
|
+
};
|
|
4565
|
+
});
|
|
4566
|
+
const schemas = envelope.dependencies.schemas.map((s) => ({
|
|
4567
|
+
...s,
|
|
4568
|
+
id: schemaIdMap.get(s.id)
|
|
4569
|
+
}));
|
|
4570
|
+
const graphql = envelope.dependencies.graphql.map((g) => ({
|
|
4571
|
+
...g,
|
|
4572
|
+
id: graphqlIdMap.get(g.id)
|
|
4573
|
+
}));
|
|
4574
|
+
const files = envelope.dependencies.files.map((f) => ({
|
|
4575
|
+
...f,
|
|
4576
|
+
id: fileIdMap.get(f.id)
|
|
4577
|
+
}));
|
|
4578
|
+
const requests = envelope.folder.requests.map((r) => {
|
|
4579
|
+
const newId = requestIdMap.get(r.id);
|
|
4580
|
+
let newFolderId;
|
|
4581
|
+
if (r.folderId === null) {
|
|
4582
|
+
newFolderId = rootFolderId;
|
|
4583
|
+
} else {
|
|
4584
|
+
const mapped = folderIdMap.get(r.folderId);
|
|
4585
|
+
if (!mapped) {
|
|
4586
|
+
warnings.push(
|
|
4587
|
+
`Request "${r.name}" referenced folderId "${r.folderId}" that wasn't present in the export \u2014 reattached under "${envelope.folder.name}".`
|
|
4588
|
+
);
|
|
4589
|
+
newFolderId = rootFolderId;
|
|
4590
|
+
} else {
|
|
4591
|
+
newFolderId = mapped;
|
|
4592
|
+
}
|
|
4593
|
+
}
|
|
4594
|
+
const bodySchemaId = remapDependencyRef(
|
|
4595
|
+
r.bodySchemaId,
|
|
4596
|
+
schemaIdMap,
|
|
4597
|
+
`Request "${r.name}".bodySchemaId`,
|
|
4598
|
+
warnings
|
|
4599
|
+
);
|
|
4600
|
+
const graphqlSchemaId = remapDependencyRef(
|
|
4601
|
+
r.graphqlSchemaId,
|
|
4602
|
+
graphqlIdMap,
|
|
4603
|
+
`Request "${r.name}".graphqlSchemaId`,
|
|
4604
|
+
warnings
|
|
4605
|
+
);
|
|
4606
|
+
return {
|
|
4607
|
+
...r,
|
|
4608
|
+
id: newId,
|
|
4609
|
+
folderId: newFolderId,
|
|
4610
|
+
bodySchemaId,
|
|
4611
|
+
graphqlSchemaId,
|
|
4612
|
+
headers: r.headers.map((h) => ({ ...h })),
|
|
4613
|
+
query: r.query.map((q) => ({ ...q })),
|
|
4614
|
+
pathParams: r.pathParams ? { ...r.pathParams } : void 0,
|
|
4615
|
+
cookies: r.cookies ? r.cookies.map((c) => ({ ...c })) : void 0,
|
|
4616
|
+
body: remapBodyFileRefs(r.body, fileIdMap, r.name, warnings),
|
|
4617
|
+
auth: { ...r.auth },
|
|
4618
|
+
contextVars: r.contextVars.map((v) => ({ ...v })),
|
|
4619
|
+
extractions: r.extractions.map((e) => ({ ...e })),
|
|
4620
|
+
assertions: r.assertions.map((a) => ({ ...a }))
|
|
4621
|
+
};
|
|
4622
|
+
});
|
|
4623
|
+
return {
|
|
4624
|
+
rootFolder: {
|
|
4625
|
+
id: rootFolderId,
|
|
4626
|
+
name: envelope.folder.name,
|
|
4627
|
+
auth: envelope.folder.auth ? { ...envelope.folder.auth } : void 0
|
|
4628
|
+
},
|
|
4629
|
+
subfolders,
|
|
4630
|
+
requests,
|
|
4631
|
+
dependencies: { schemas, graphql, files },
|
|
4632
|
+
sourceFolderName: envelope.source.folderName,
|
|
4633
|
+
warnings
|
|
4634
|
+
};
|
|
4635
|
+
}
|
|
4636
|
+
function validateEnvelopeShape(envelope) {
|
|
4637
|
+
if (!envelope.folder || typeof envelope.folder !== "object") {
|
|
4638
|
+
throw new Error('API Circle folder export is missing the "folder" section.');
|
|
4639
|
+
}
|
|
4640
|
+
if (typeof envelope.folder.name !== "string" || envelope.folder.name.length === 0) {
|
|
4641
|
+
throw new Error('API Circle folder export must have a non-empty "folder.name".');
|
|
4642
|
+
}
|
|
4643
|
+
if (!Array.isArray(envelope.folder.subfolders)) {
|
|
4644
|
+
throw new Error('API Circle folder export must have a "folder.subfolders" array.');
|
|
4645
|
+
}
|
|
4646
|
+
if (!Array.isArray(envelope.folder.requests)) {
|
|
4647
|
+
throw new Error('API Circle folder export must have a "folder.requests" array.');
|
|
4648
|
+
}
|
|
4649
|
+
if (!envelope.dependencies || typeof envelope.dependencies !== "object") {
|
|
4650
|
+
throw new Error('API Circle folder export is missing the "dependencies" section.');
|
|
4651
|
+
}
|
|
4652
|
+
if (!Array.isArray(envelope.dependencies.schemas) || !Array.isArray(envelope.dependencies.graphql) || !Array.isArray(envelope.dependencies.files)) {
|
|
4653
|
+
throw new Error(
|
|
4654
|
+
'API Circle folder export "dependencies" must have schemas / graphql / files arrays.'
|
|
4655
|
+
);
|
|
4656
|
+
}
|
|
4657
|
+
if (!envelope.source || typeof envelope.source !== "object") {
|
|
4658
|
+
throw new Error('API Circle folder export is missing the "source" section.');
|
|
4659
|
+
}
|
|
4660
|
+
if (typeof envelope.source.folderId !== "string" || typeof envelope.source.folderName !== "string") {
|
|
4661
|
+
throw new Error('API Circle folder export "source" must include "folderId" and "folderName".');
|
|
4662
|
+
}
|
|
4663
|
+
}
|
|
4664
|
+
function remapDependencyRef(value, map, label, warnings) {
|
|
4665
|
+
if (value === null || value === void 0) return value;
|
|
4666
|
+
const mapped = map.get(value);
|
|
4667
|
+
if (mapped) return mapped;
|
|
4668
|
+
warnings.push(
|
|
4669
|
+
`${label} referenced a dependency ("${value}") that wasn't embedded in the export \u2014 reference dropped on import.`
|
|
4670
|
+
);
|
|
4671
|
+
return null;
|
|
4672
|
+
}
|
|
4673
|
+
function remapBodyFileRefs(body, fileIdMap, requestName, warnings) {
|
|
4674
|
+
if (body.type === "binary") {
|
|
4675
|
+
if (!body.attachment) return { ...body };
|
|
4676
|
+
const oldId = body.attachment.globalFileAssetId;
|
|
4677
|
+
let nextGlobalFileAssetId = oldId;
|
|
4678
|
+
if (oldId) {
|
|
4679
|
+
const mapped = fileIdMap.get(oldId);
|
|
4680
|
+
if (mapped) {
|
|
4681
|
+
nextGlobalFileAssetId = mapped;
|
|
4682
|
+
} else {
|
|
4683
|
+
warnings.push(
|
|
4684
|
+
`Request "${requestName}".body.attachment referenced file asset "${oldId}" that wasn't embedded in the export \u2014 re-attach the file after import.`
|
|
4685
|
+
);
|
|
4686
|
+
nextGlobalFileAssetId = null;
|
|
4687
|
+
}
|
|
4688
|
+
}
|
|
4689
|
+
return {
|
|
4690
|
+
...body,
|
|
4691
|
+
attachment: {
|
|
4692
|
+
...body.attachment,
|
|
4693
|
+
// Reset slotId — the destination workspace owns its own slots.
|
|
4694
|
+
slotId: null,
|
|
4695
|
+
globalFileAssetId: nextGlobalFileAssetId
|
|
4696
|
+
}
|
|
4697
|
+
};
|
|
4698
|
+
}
|
|
4699
|
+
if (body.type === "form-data") {
|
|
4700
|
+
const formRows = body.formRows?.map((row) => {
|
|
4701
|
+
if (row.kind !== "file") return { ...row };
|
|
4702
|
+
const oldId = row.globalFileAssetId;
|
|
4703
|
+
let nextGlobalFileAssetId = oldId;
|
|
4704
|
+
if (oldId) {
|
|
4705
|
+
const mapped = fileIdMap.get(oldId);
|
|
4706
|
+
if (mapped) {
|
|
4707
|
+
nextGlobalFileAssetId = mapped;
|
|
4708
|
+
} else {
|
|
4709
|
+
warnings.push(
|
|
4710
|
+
`Request "${requestName}" form-data row "${row.key}" referenced file asset "${oldId}" that wasn't embedded in the export \u2014 re-attach the file after import.`
|
|
4711
|
+
);
|
|
4712
|
+
nextGlobalFileAssetId = null;
|
|
4713
|
+
}
|
|
4714
|
+
}
|
|
4715
|
+
return {
|
|
4716
|
+
...row,
|
|
4717
|
+
slotId: null,
|
|
4718
|
+
globalFileAssetId: nextGlobalFileAssetId
|
|
4719
|
+
};
|
|
4720
|
+
});
|
|
4721
|
+
return { ...body, formRows };
|
|
4722
|
+
}
|
|
4723
|
+
return { ...body };
|
|
4724
|
+
}
|
|
4725
|
+
|
|
4726
|
+
// src/import/apicircleEnvironment.ts
|
|
4727
|
+
function isApicircleEnvironment(doc) {
|
|
4728
|
+
if (!doc || typeof doc !== "object") return false;
|
|
4729
|
+
const d = doc;
|
|
4730
|
+
return (d.apicircleEnvironment === 1 || d.apicircleEnvironment === 2) && typeof d.name === "string" && Array.isArray(d.variables);
|
|
4731
|
+
}
|
|
4732
|
+
function parseApicircleEnvironment(input) {
|
|
4733
|
+
let doc;
|
|
4734
|
+
try {
|
|
4735
|
+
doc = JSON.parse(input);
|
|
4736
|
+
} catch (err) {
|
|
4737
|
+
throw new Error(`Couldn't parse JSON: ${err instanceof Error ? err.message : String(err)}`);
|
|
4738
|
+
}
|
|
4739
|
+
return parseApicircleEnvironmentDoc(doc);
|
|
4740
|
+
}
|
|
4741
|
+
function parseApicircleEnvironmentDoc(doc) {
|
|
4742
|
+
if (!isApicircleEnvironment(doc)) {
|
|
4743
|
+
throw new Error(
|
|
4744
|
+
'Unsupported format. Expected an API Circle environment export ("apicircleEnvironment": 1 or 2).'
|
|
4745
|
+
);
|
|
4746
|
+
}
|
|
4747
|
+
const name = doc.name.trim();
|
|
4748
|
+
if (!name) {
|
|
4749
|
+
throw new Error('API Circle environment export must have a non-empty "name".');
|
|
4750
|
+
}
|
|
4751
|
+
const payloadVersion = doc.apicircleEnvironment;
|
|
4752
|
+
const warnings = [];
|
|
4753
|
+
const variables = [];
|
|
4754
|
+
const encryptedBindingHints = [];
|
|
4755
|
+
for (let i = 0; i < doc.variables.length; i += 1) {
|
|
4756
|
+
const raw = doc.variables[i];
|
|
4757
|
+
if (!raw || typeof raw !== "object") {
|
|
4758
|
+
warnings.push(`Row #${i + 1} was not an object \u2014 dropped.`);
|
|
4759
|
+
continue;
|
|
4760
|
+
}
|
|
4761
|
+
const key = typeof raw.key === "string" ? raw.key.trim() : "";
|
|
4762
|
+
if (!key) {
|
|
4763
|
+
warnings.push(`Row #${i + 1} had no key \u2014 dropped.`);
|
|
4764
|
+
continue;
|
|
4765
|
+
}
|
|
4766
|
+
if (raw.encrypted === true) {
|
|
4767
|
+
const secretKeyId = typeof raw.secretKeyId === "string" ? raw.secretKeyId : "";
|
|
4768
|
+
const labelFromSecret = readLabelFromSecretField(raw.secret);
|
|
4769
|
+
const ciphertext = payloadVersion === 2 && typeof raw.value === "string" && raw.value.startsWith("enc:") ? raw.value : null;
|
|
4770
|
+
const salt = payloadVersion === 2 ? readSaltFromSecretField(raw.secret) : null;
|
|
4771
|
+
if (!secretKeyId && !labelFromSecret) {
|
|
4772
|
+
warnings.push(
|
|
4773
|
+
`"${key}" was marked encrypted but carried no secretKeyId and no secret label \u2014 imported as an empty plain variable. Re-bind it under Environments after import.`
|
|
4774
|
+
);
|
|
4775
|
+
variables.push({ key, value: "", encrypted: false });
|
|
4776
|
+
continue;
|
|
4777
|
+
}
|
|
4778
|
+
variables.push({
|
|
4779
|
+
key,
|
|
4780
|
+
value: ciphertext ?? "",
|
|
4781
|
+
encrypted: true,
|
|
4782
|
+
secretKeyId: secretKeyId || void 0
|
|
4783
|
+
});
|
|
4784
|
+
const labelFromFallback = !labelFromSecret;
|
|
4785
|
+
encryptedBindingHints.push({
|
|
4786
|
+
varKey: key,
|
|
4787
|
+
label: labelFromSecret ?? key,
|
|
4788
|
+
originSecretKeyId: secretKeyId || void 0,
|
|
4789
|
+
labelFromFallback,
|
|
4790
|
+
ciphertext,
|
|
4791
|
+
salt
|
|
4792
|
+
});
|
|
4793
|
+
continue;
|
|
4794
|
+
}
|
|
4795
|
+
variables.push({
|
|
4796
|
+
key,
|
|
4797
|
+
value: typeof raw.value === "string" ? raw.value : "",
|
|
4798
|
+
encrypted: false
|
|
4799
|
+
});
|
|
4800
|
+
}
|
|
4801
|
+
return { name, variables, encryptedBindingHints, payloadVersion, warnings };
|
|
4802
|
+
}
|
|
4803
|
+
function readLabelFromSecretField(field) {
|
|
4804
|
+
if (!field || typeof field !== "object") return null;
|
|
4805
|
+
const f = field;
|
|
4806
|
+
if (typeof f.label !== "string") return null;
|
|
4807
|
+
const trimmed = f.label.trim();
|
|
4808
|
+
return trimmed.length > 0 ? trimmed : null;
|
|
4809
|
+
}
|
|
4810
|
+
function readSaltFromSecretField(field) {
|
|
4811
|
+
if (!field || typeof field !== "object") return null;
|
|
4812
|
+
const f = field;
|
|
4813
|
+
if (typeof f.salt !== "string") return null;
|
|
4814
|
+
const trimmed = f.salt.trim();
|
|
4815
|
+
return trimmed.length > 0 ? trimmed : null;
|
|
4816
|
+
}
|
|
4817
|
+
|
|
4108
4818
|
// src/assertions/runAssertions.ts
|
|
4109
4819
|
function runAssertions(assertions, exec) {
|
|
4110
4820
|
return assertions.map((a) => runOne(a, exec));
|
|
@@ -5852,7 +6562,232 @@ function structurallyEqual2(a, b) {
|
|
|
5852
6562
|
}
|
|
5853
6563
|
|
|
5854
6564
|
// src/workspace/applyMutation.ts
|
|
5855
|
-
var
|
|
6565
|
+
var import_shared2 = require("@apicircle/shared");
|
|
6566
|
+
|
|
6567
|
+
// src/workspace/apicircleFolderImport.ts
|
|
6568
|
+
function importApicircleFolderInto(synced, parsed, parentFolderId) {
|
|
6569
|
+
let cur = synced;
|
|
6570
|
+
const schemaRemap = /* @__PURE__ */ new Map();
|
|
6571
|
+
const graphqlRemap = /* @__PURE__ */ new Map();
|
|
6572
|
+
const fileRemap = /* @__PURE__ */ new Map();
|
|
6573
|
+
let schemasAdded = 0;
|
|
6574
|
+
let schemasReused = 0;
|
|
6575
|
+
let graphqlAdded = 0;
|
|
6576
|
+
let graphqlReused = 0;
|
|
6577
|
+
let filesAdded = 0;
|
|
6578
|
+
let filesReused = 0;
|
|
6579
|
+
const filesRequiringReattachment = [];
|
|
6580
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
6581
|
+
for (const incoming of parsed.dependencies.schemas) {
|
|
6582
|
+
const existing = findMatchingSchema(cur, incoming);
|
|
6583
|
+
if (existing) {
|
|
6584
|
+
schemaRemap.set(incoming.id, existing.id);
|
|
6585
|
+
schemasReused += 1;
|
|
6586
|
+
continue;
|
|
6587
|
+
}
|
|
6588
|
+
cur = mergeGlobalSchema(cur, incoming, now);
|
|
6589
|
+
schemaRemap.set(incoming.id, incoming.id);
|
|
6590
|
+
schemasAdded += 1;
|
|
6591
|
+
}
|
|
6592
|
+
for (const incoming of parsed.dependencies.graphql) {
|
|
6593
|
+
const existing = findMatchingGraphQL(cur, incoming);
|
|
6594
|
+
if (existing) {
|
|
6595
|
+
graphqlRemap.set(incoming.id, existing.id);
|
|
6596
|
+
graphqlReused += 1;
|
|
6597
|
+
continue;
|
|
6598
|
+
}
|
|
6599
|
+
cur = mergeGlobalGraphQL(cur, incoming, now);
|
|
6600
|
+
graphqlRemap.set(incoming.id, incoming.id);
|
|
6601
|
+
graphqlAdded += 1;
|
|
6602
|
+
}
|
|
6603
|
+
for (const incoming of parsed.dependencies.files) {
|
|
6604
|
+
const existing = findMatchingFile(cur, incoming);
|
|
6605
|
+
if (existing) {
|
|
6606
|
+
fileRemap.set(incoming.id, existing.id);
|
|
6607
|
+
filesReused += 1;
|
|
6608
|
+
continue;
|
|
6609
|
+
}
|
|
6610
|
+
cur = mergeGlobalFile(cur, incoming, now);
|
|
6611
|
+
fileRemap.set(incoming.id, incoming.id);
|
|
6612
|
+
filesAdded += 1;
|
|
6613
|
+
filesRequiringReattachment.push(incoming.id);
|
|
6614
|
+
}
|
|
6615
|
+
const rootName = uniquifyFolderName(cur, parentFolderId, parsed.rootFolder.name);
|
|
6616
|
+
const root = {
|
|
6617
|
+
id: parsed.rootFolder.id,
|
|
6618
|
+
name: rootName,
|
|
6619
|
+
parentId: parentFolderId,
|
|
6620
|
+
auth: parsed.rootFolder.auth ? { ...parsed.rootFolder.auth } : void 0
|
|
6621
|
+
};
|
|
6622
|
+
cur = insertFolder(
|
|
6623
|
+
cur,
|
|
6624
|
+
root,
|
|
6625
|
+
/* attachToTree */
|
|
6626
|
+
parentFolderId === null
|
|
6627
|
+
);
|
|
6628
|
+
for (const f of parsed.subfolders) {
|
|
6629
|
+
cur = insertFolder(
|
|
6630
|
+
cur,
|
|
6631
|
+
f,
|
|
6632
|
+
/* attachToTree */
|
|
6633
|
+
false
|
|
6634
|
+
);
|
|
6635
|
+
}
|
|
6636
|
+
for (const r of parsed.requests) {
|
|
6637
|
+
const rewritten = {
|
|
6638
|
+
...r,
|
|
6639
|
+
bodySchemaId: rewriteRef(r.bodySchemaId, schemaRemap),
|
|
6640
|
+
graphqlSchemaId: rewriteRef(r.graphqlSchemaId, graphqlRemap),
|
|
6641
|
+
body: rewriteBodyFileRefs(r.body, fileRemap)
|
|
6642
|
+
};
|
|
6643
|
+
cur = insertRequest(cur, rewritten);
|
|
6644
|
+
}
|
|
6645
|
+
return {
|
|
6646
|
+
synced: { ...cur, meta: { ...cur.meta, updatedAt: now } },
|
|
6647
|
+
rootFolderId: root.id,
|
|
6648
|
+
rootFolderName: rootName,
|
|
6649
|
+
counts: {
|
|
6650
|
+
folders: parsed.subfolders.length + 1,
|
|
6651
|
+
requests: parsed.requests.length,
|
|
6652
|
+
schemasAdded,
|
|
6653
|
+
schemasReused,
|
|
6654
|
+
graphqlAdded,
|
|
6655
|
+
graphqlReused,
|
|
6656
|
+
filesAdded,
|
|
6657
|
+
filesReused
|
|
6658
|
+
},
|
|
6659
|
+
filesRequiringReattachment
|
|
6660
|
+
};
|
|
6661
|
+
}
|
|
6662
|
+
function isFolderNameAvailable(synced, parentFolderId, name) {
|
|
6663
|
+
const trimmed = name.trim().toLowerCase();
|
|
6664
|
+
if (!trimmed) return false;
|
|
6665
|
+
for (const node of Object.values(synced.collections.folders)) {
|
|
6666
|
+
if (node.parentId !== parentFolderId) continue;
|
|
6667
|
+
if (node.name.trim().toLowerCase() === trimmed) return false;
|
|
6668
|
+
}
|
|
6669
|
+
return true;
|
|
6670
|
+
}
|
|
6671
|
+
function uniquifyFolderName(synced, parentFolderId, desired) {
|
|
6672
|
+
if (isFolderNameAvailable(synced, parentFolderId, desired)) return desired;
|
|
6673
|
+
let n = 2;
|
|
6674
|
+
while (!isFolderNameAvailable(synced, parentFolderId, `${desired} (${n})`)) {
|
|
6675
|
+
n += 1;
|
|
6676
|
+
if (n > 999) return `${desired} (${n})`;
|
|
6677
|
+
}
|
|
6678
|
+
return `${desired} (${n})`;
|
|
6679
|
+
}
|
|
6680
|
+
function insertFolder(synced, folder, attachToTree) {
|
|
6681
|
+
const folders = { ...synced.collections.folders, [folder.id]: folder };
|
|
6682
|
+
const tree = attachToTree ? {
|
|
6683
|
+
...synced.collections.tree,
|
|
6684
|
+
children: [...synced.collections.tree.children, { kind: "folder", id: folder.id }]
|
|
6685
|
+
} : synced.collections.tree;
|
|
6686
|
+
return {
|
|
6687
|
+
...synced,
|
|
6688
|
+
collections: { ...synced.collections, folders, tree }
|
|
6689
|
+
};
|
|
6690
|
+
}
|
|
6691
|
+
function insertRequest(synced, request) {
|
|
6692
|
+
return {
|
|
6693
|
+
...synced,
|
|
6694
|
+
collections: {
|
|
6695
|
+
...synced.collections,
|
|
6696
|
+
requests: { ...synced.collections.requests, [request.id]: request }
|
|
6697
|
+
}
|
|
6698
|
+
};
|
|
6699
|
+
}
|
|
6700
|
+
function withGlobalAssets(synced) {
|
|
6701
|
+
return synced.globalAssets ?? { schemas: {}, graphql: {}, files: {} };
|
|
6702
|
+
}
|
|
6703
|
+
function findMatchingSchema(synced, candidate) {
|
|
6704
|
+
const ga = withGlobalAssets(synced);
|
|
6705
|
+
for (const existing of Object.values(ga.schemas)) {
|
|
6706
|
+
if (existing.name === candidate.name && existing.schema === candidate.schema) {
|
|
6707
|
+
return existing;
|
|
6708
|
+
}
|
|
6709
|
+
}
|
|
6710
|
+
return null;
|
|
6711
|
+
}
|
|
6712
|
+
function findMatchingGraphQL(synced, candidate) {
|
|
6713
|
+
const ga = withGlobalAssets(synced);
|
|
6714
|
+
for (const existing of Object.values(ga.graphql)) {
|
|
6715
|
+
if (existing.name === candidate.name && existing.kind === candidate.kind && existing.source === candidate.source) {
|
|
6716
|
+
return existing;
|
|
6717
|
+
}
|
|
6718
|
+
}
|
|
6719
|
+
return null;
|
|
6720
|
+
}
|
|
6721
|
+
function findMatchingFile(synced, candidate) {
|
|
6722
|
+
const ga = withGlobalAssets(synced);
|
|
6723
|
+
const files = ga.files ?? {};
|
|
6724
|
+
for (const existing of Object.values(files)) {
|
|
6725
|
+
if (existing.name === candidate.name && existing.filename === candidate.filename && existing.size === candidate.size) {
|
|
6726
|
+
return existing;
|
|
6727
|
+
}
|
|
6728
|
+
}
|
|
6729
|
+
return null;
|
|
6730
|
+
}
|
|
6731
|
+
function mergeGlobalSchema(synced, schema, now) {
|
|
6732
|
+
const ga = withGlobalAssets(synced);
|
|
6733
|
+
return {
|
|
6734
|
+
...synced,
|
|
6735
|
+
globalAssets: {
|
|
6736
|
+
...ga,
|
|
6737
|
+
schemas: { ...ga.schemas, [schema.id]: { ...schema, updatedAt: now } }
|
|
6738
|
+
}
|
|
6739
|
+
};
|
|
6740
|
+
}
|
|
6741
|
+
function mergeGlobalGraphQL(synced, graphql, now) {
|
|
6742
|
+
const ga = withGlobalAssets(synced);
|
|
6743
|
+
return {
|
|
6744
|
+
...synced,
|
|
6745
|
+
globalAssets: {
|
|
6746
|
+
...ga,
|
|
6747
|
+
graphql: { ...ga.graphql, [graphql.id]: { ...graphql, updatedAt: now } }
|
|
6748
|
+
}
|
|
6749
|
+
};
|
|
6750
|
+
}
|
|
6751
|
+
function mergeGlobalFile(synced, file, now) {
|
|
6752
|
+
const ga = withGlobalAssets(synced);
|
|
6753
|
+
const files = ga.files ?? {};
|
|
6754
|
+
return {
|
|
6755
|
+
...synced,
|
|
6756
|
+
globalAssets: {
|
|
6757
|
+
...ga,
|
|
6758
|
+
files: { ...files, [file.id]: { ...file, updatedAt: now } }
|
|
6759
|
+
}
|
|
6760
|
+
};
|
|
6761
|
+
}
|
|
6762
|
+
function rewriteRef(value, remap) {
|
|
6763
|
+
if (value === null || value === void 0) return value;
|
|
6764
|
+
return remap.get(value) ?? value;
|
|
6765
|
+
}
|
|
6766
|
+
function rewriteBodyFileRefs(body, remap) {
|
|
6767
|
+
if (body.type === "binary") {
|
|
6768
|
+
if (!body.attachment) return body;
|
|
6769
|
+
const rewritten = rewriteRef(body.attachment.globalFileAssetId, remap);
|
|
6770
|
+
if (rewritten === body.attachment.globalFileAssetId) return body;
|
|
6771
|
+
return {
|
|
6772
|
+
...body,
|
|
6773
|
+
attachment: { ...body.attachment, globalFileAssetId: rewritten }
|
|
6774
|
+
};
|
|
6775
|
+
}
|
|
6776
|
+
if (body.type === "form-data" && body.formRows) {
|
|
6777
|
+
let mutated = false;
|
|
6778
|
+
const next = body.formRows.map((row) => {
|
|
6779
|
+
if (row.kind !== "file") return row;
|
|
6780
|
+
const rewritten = rewriteRef(row.globalFileAssetId, remap);
|
|
6781
|
+
if (rewritten === row.globalFileAssetId) return row;
|
|
6782
|
+
mutated = true;
|
|
6783
|
+
return { ...row, globalFileAssetId: rewritten };
|
|
6784
|
+
});
|
|
6785
|
+
return mutated ? { ...body, formRows: next } : body;
|
|
6786
|
+
}
|
|
6787
|
+
return body;
|
|
6788
|
+
}
|
|
6789
|
+
|
|
6790
|
+
// src/workspace/applyMutation.ts
|
|
5856
6791
|
function applyMutation(state, patch, options = {}) {
|
|
5857
6792
|
const now = options.now ?? (/* @__PURE__ */ new Date()).toISOString();
|
|
5858
6793
|
switch (patch.kind) {
|
|
@@ -5868,6 +6803,8 @@ function applyMutation(state, patch, options = {}) {
|
|
|
5868
6803
|
return applyFolderDelete(state, patch.id, now);
|
|
5869
6804
|
case "folder.move":
|
|
5870
6805
|
return applyFolderMove(state, patch.id, patch.newParentId, now);
|
|
6806
|
+
case "folder.import_apicircle":
|
|
6807
|
+
return applyFolderImportApicircle(state, patch.parsed, patch.parentFolderId, now);
|
|
5871
6808
|
case "environment.upsert":
|
|
5872
6809
|
return applyEnvUpsert(state, patch.environment, now);
|
|
5873
6810
|
case "environment.delete":
|
|
@@ -5876,6 +6813,8 @@ function applyMutation(state, patch, options = {}) {
|
|
|
5876
6813
|
return applyEnvSetActive(state, patch.name, now);
|
|
5877
6814
|
case "environment.setPriority":
|
|
5878
6815
|
return applyEnvSetPriority(state, patch.order, now);
|
|
6816
|
+
case "secretKey.upsert":
|
|
6817
|
+
return applySecretKeyUpsert(state, patch.meta, now);
|
|
5879
6818
|
case "assertion.upsert":
|
|
5880
6819
|
return applyAssertionUpsert(state, patch.requestId, patch.assertion, now);
|
|
5881
6820
|
case "assertion.delete":
|
|
@@ -6036,6 +6975,23 @@ function applyFolderMove(state, id, newParentId, now) {
|
|
|
6036
6975
|
};
|
|
6037
6976
|
return { next: { ...state, synced }, changedIds: [id] };
|
|
6038
6977
|
}
|
|
6978
|
+
function applyFolderImportApicircle(state, parsed, parentFolderId, now) {
|
|
6979
|
+
const result = importApicircleFolderInto(
|
|
6980
|
+
state.synced,
|
|
6981
|
+
parsed,
|
|
6982
|
+
parentFolderId
|
|
6983
|
+
);
|
|
6984
|
+
const synced = {
|
|
6985
|
+
...result.synced,
|
|
6986
|
+
meta: { ...result.synced.meta, updatedAt: now }
|
|
6987
|
+
};
|
|
6988
|
+
const changedIds = [
|
|
6989
|
+
result.rootFolderId,
|
|
6990
|
+
...parsed.subfolders.map((f) => f.id),
|
|
6991
|
+
...parsed.requests.map((r) => r.id)
|
|
6992
|
+
];
|
|
6993
|
+
return { next: { ...state, synced }, changedIds };
|
|
6994
|
+
}
|
|
6039
6995
|
function applyEnvUpsert(state, environment, now) {
|
|
6040
6996
|
const trimmed = environment.name.trim();
|
|
6041
6997
|
if (!trimmed) {
|
|
@@ -6098,7 +7054,7 @@ function applyEnvSetPriority(state, order, now) {
|
|
|
6098
7054
|
const knownLocal = new Set(Object.keys(state.synced.environments.items));
|
|
6099
7055
|
const seen = /* @__PURE__ */ new Set();
|
|
6100
7056
|
const filtered = order.filter((ref) => {
|
|
6101
|
-
const key = (0,
|
|
7057
|
+
const key = (0, import_shared2.envPriorityKey)(ref);
|
|
6102
7058
|
if (seen.has(key)) return false;
|
|
6103
7059
|
if (ref.kind === "local" && !knownLocal.has(ref.name)) return false;
|
|
6104
7060
|
seen.add(key);
|
|
@@ -6109,7 +7065,21 @@ function applyEnvSetPriority(state, order, now) {
|
|
|
6109
7065
|
environments: { ...state.synced.environments, priorityOrder: filtered },
|
|
6110
7066
|
meta: { ...state.synced.meta, updatedAt: now }
|
|
6111
7067
|
};
|
|
6112
|
-
return { next: { ...state, synced }, changedIds: filtered.map(
|
|
7068
|
+
return { next: { ...state, synced }, changedIds: filtered.map(import_shared2.envPriorityKey) };
|
|
7069
|
+
}
|
|
7070
|
+
function applySecretKeyUpsert(state, meta, now) {
|
|
7071
|
+
if (!meta.id || !meta.label.trim() || !meta.salt) {
|
|
7072
|
+
return { next: state, changedIds: [] };
|
|
7073
|
+
}
|
|
7074
|
+
const synced = {
|
|
7075
|
+
...state.synced,
|
|
7076
|
+
secretKeys: {
|
|
7077
|
+
...state.synced.secretKeys ?? {},
|
|
7078
|
+
[meta.id]: { ...meta, label: meta.label.trim() }
|
|
7079
|
+
},
|
|
7080
|
+
meta: { ...state.synced.meta, updatedAt: now }
|
|
7081
|
+
};
|
|
7082
|
+
return { next: { ...state, synced }, changedIds: [meta.id] };
|
|
6113
7083
|
}
|
|
6114
7084
|
function applyAssertionUpsert(state, requestId, assertion, now) {
|
|
6115
7085
|
const request = state.synced.collections.requests[requestId];
|
|
@@ -6253,7 +7223,7 @@ function evictSnapshotsToCap(entries, maxBytes) {
|
|
|
6253
7223
|
};
|
|
6254
7224
|
}
|
|
6255
7225
|
function applySnapshotCapture(state, args, now) {
|
|
6256
|
-
const id = args.id ?? (0,
|
|
7226
|
+
const id = args.id ?? (0, import_shared2.generateId)();
|
|
6257
7227
|
const snapshot2 = {
|
|
6258
7228
|
id,
|
|
6259
7229
|
createdAt: now,
|
|
@@ -6342,7 +7312,7 @@ function applyHistoryPurge(state, olderThanMs) {
|
|
|
6342
7312
|
}
|
|
6343
7313
|
|
|
6344
7314
|
// src/workspace/runPlan.ts
|
|
6345
|
-
var
|
|
7315
|
+
var import_shared3 = require("@apicircle/shared");
|
|
6346
7316
|
var MAX_REQUEST_RUNS = 500;
|
|
6347
7317
|
var MAX_PLAN_RUNS = 200;
|
|
6348
7318
|
var ANONYMOUS_ACTOR = { kind: "unknown", name: "unknown" };
|
|
@@ -6489,7 +7459,7 @@ async function runPlan(state, planId, opts = {}) {
|
|
|
6489
7459
|
const baseRefs = plan.envPriorityOrder.length > 0 ? plan.envPriorityOrder : state.synced.environments.priorityOrder;
|
|
6490
7460
|
const envRefs = opts.env ? [{ kind: "local", name: opts.env }, ...baseRefs] : baseRefs;
|
|
6491
7461
|
const startedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
6492
|
-
const planRunId = (0,
|
|
7462
|
+
const planRunId = (0, import_shared3.generateId)();
|
|
6493
7463
|
const t0 = Date.now();
|
|
6494
7464
|
const stepRecords = [];
|
|
6495
7465
|
const newRequestRuns = [];
|
|
@@ -6522,7 +7492,7 @@ async function runPlan(state, planId, opts = {}) {
|
|
|
6522
7492
|
const lookup2 = lookupPlanStepRequest(step, state.synced, state.local);
|
|
6523
7493
|
const baseRequest = lookup2.request;
|
|
6524
7494
|
if (!baseRequest) {
|
|
6525
|
-
const runId = (0,
|
|
7495
|
+
const runId = (0, import_shared3.generateId)();
|
|
6526
7496
|
const error = lookup2.error ?? "Request no longer exists in workspace.";
|
|
6527
7497
|
newRequestRuns.push(orphanRun(runId, step.requestId, error));
|
|
6528
7498
|
stepRecords.push({ requestRunId: runId, passed: false });
|
|
@@ -6640,7 +7610,7 @@ function buildEnvMaps(synced, secretsById, local) {
|
|
|
6640
7610
|
vars[v.key] = v.value;
|
|
6641
7611
|
}
|
|
6642
7612
|
}
|
|
6643
|
-
flat[(0,
|
|
7613
|
+
flat[(0, import_shared3.envPriorityKey)({ kind: "local", name })] = vars;
|
|
6644
7614
|
}
|
|
6645
7615
|
if (local) {
|
|
6646
7616
|
for (const [linkId, snapshot2] of Object.entries(local.linkedCollections)) {
|
|
@@ -6657,7 +7627,7 @@ function buildEnvMaps(synced, secretsById, local) {
|
|
|
6657
7627
|
vars[variable.key] = variable.value;
|
|
6658
7628
|
}
|
|
6659
7629
|
}
|
|
6660
|
-
flat[(0,
|
|
7630
|
+
flat[(0, import_shared3.envPriorityKey)({ kind: "linked", linkedWorkspaceId: linkId, envName })] = vars;
|
|
6661
7631
|
}
|
|
6662
7632
|
}
|
|
6663
7633
|
}
|
|
@@ -6684,7 +7654,7 @@ function resolveRequest(request, synced, plan, envRefs, globalContext, flatEnvs,
|
|
|
6684
7654
|
contextVars: Object.entries(ctxMap).map(([key, value]) => ({ key, value })),
|
|
6685
7655
|
environments: flatEnvs,
|
|
6686
7656
|
activeEnvName: null,
|
|
6687
|
-
priorityOrder: envRefs.map(
|
|
7657
|
+
priorityOrder: envRefs.map(import_shared3.envPriorityKey),
|
|
6688
7658
|
secrets: secretsByLabel
|
|
6689
7659
|
});
|
|
6690
7660
|
const missing = /* @__PURE__ */ new Set();
|
|
@@ -6754,7 +7724,7 @@ function orphanRun(id, requestId, error) {
|
|
|
6754
7724
|
function buildRequestRun(resolved, result, assertions) {
|
|
6755
7725
|
const { preview, truncated } = clampPreview(result.body ?? "");
|
|
6756
7726
|
return {
|
|
6757
|
-
id: (0,
|
|
7727
|
+
id: (0, import_shared3.generateId)(),
|
|
6758
7728
|
requestId: resolved.id,
|
|
6759
7729
|
startedAt: result.startedAt,
|
|
6760
7730
|
durationMs: result.durationMs,
|
|
@@ -6774,8 +7744,8 @@ function buildRequestRun(resolved, result, assertions) {
|
|
|
6774
7744
|
};
|
|
6775
7745
|
}
|
|
6776
7746
|
function clampPreview(value) {
|
|
6777
|
-
if (value.length <=
|
|
6778
|
-
return { preview: value.slice(0,
|
|
7747
|
+
if (value.length <= import_shared3.RUN_BODY_PREVIEW_LIMIT) return { preview: value, truncated: false };
|
|
7748
|
+
return { preview: value.slice(0, import_shared3.RUN_BODY_PREVIEW_LIMIT), truncated: true };
|
|
6779
7749
|
}
|
|
6780
7750
|
function redactUrlCredentials(url) {
|
|
6781
7751
|
try {
|
|
@@ -6998,9 +7968,9 @@ function toCsv(value) {
|
|
|
6998
7968
|
}
|
|
6999
7969
|
|
|
7000
7970
|
// src/transform/computeSavings.ts
|
|
7001
|
-
var
|
|
7971
|
+
var import_shared4 = require("@apicircle/shared");
|
|
7002
7972
|
function computeTransformSavings(body, contentType) {
|
|
7003
|
-
const originalBytes = (0,
|
|
7973
|
+
const originalBytes = (0, import_shared4.utf8ByteLength)(body);
|
|
7004
7974
|
if (!isJsonLike(body, contentType)) {
|
|
7005
7975
|
return { originalBytes, minifiedBytes: originalBytes, candidates: [] };
|
|
7006
7976
|
}
|
|
@@ -7011,7 +7981,7 @@ function computeTransformSavings(body, contentType) {
|
|
|
7011
7981
|
return { originalBytes, minifiedBytes: originalBytes, candidates: [] };
|
|
7012
7982
|
}
|
|
7013
7983
|
const minified = JSON.stringify(parsed);
|
|
7014
|
-
const minifiedBytes = (0,
|
|
7984
|
+
const minifiedBytes = (0, import_shared4.utf8ByteLength)(minified);
|
|
7015
7985
|
const candidates = [];
|
|
7016
7986
|
try {
|
|
7017
7987
|
const toon = toToon(parsed);
|
|
@@ -7038,7 +8008,7 @@ function computeTransformSavings(body, contentType) {
|
|
|
7038
8008
|
};
|
|
7039
8009
|
}
|
|
7040
8010
|
function makeCandidate(format, preview, baselineBytes) {
|
|
7041
|
-
const bytes = (0,
|
|
8011
|
+
const bytes = (0, import_shared4.utf8ByteLength)(preview);
|
|
7042
8012
|
const ratio = baselineBytes === 0 ? 0 : 1 - bytes / baselineBytes;
|
|
7043
8013
|
return {
|
|
7044
8014
|
format,
|
|
@@ -7061,6 +8031,7 @@ var TRANSFORM_FORMAT_LABELS = {
|
|
|
7061
8031
|
// Annotate the CommonJS export names for ESM import in node:
|
|
7062
8032
|
0 && (module.exports = {
|
|
7063
8033
|
ANONYMOUS_ACTOR,
|
|
8034
|
+
APICIRCLE_FOLDER_EXPORT_FORMAT,
|
|
7064
8035
|
DESKTOP_APP_ORIGIN,
|
|
7065
8036
|
EMPTY_UNPUSHED_SUMMARY,
|
|
7066
8037
|
HTTP_HEADERS_MAP,
|
|
@@ -7085,6 +8056,8 @@ var TRANSFORM_FORMAT_LABELS = {
|
|
|
7085
8056
|
buildRequest,
|
|
7086
8057
|
buildScope,
|
|
7087
8058
|
collectAttachmentSlots,
|
|
8059
|
+
collectFolderExport,
|
|
8060
|
+
collectFolderExportCredentials,
|
|
7088
8061
|
collectVariableSuggestions,
|
|
7089
8062
|
compareSemver,
|
|
7090
8063
|
composeBody,
|
|
@@ -7120,7 +8093,10 @@ var TRANSFORM_FORMAT_LABELS = {
|
|
|
7120
8093
|
getLanguageFromContentType,
|
|
7121
8094
|
getVariableAutocomplete,
|
|
7122
8095
|
hasUnpushedChanges,
|
|
8096
|
+
importApicircleFolderInto,
|
|
7123
8097
|
importKey,
|
|
8098
|
+
isApicircleEnvironment,
|
|
8099
|
+
isApicircleFolderExport,
|
|
7124
8100
|
isDesktop,
|
|
7125
8101
|
isInsomniaExport,
|
|
7126
8102
|
isPostmanEnvironment,
|
|
@@ -7129,6 +8105,10 @@ var TRANSFORM_FORMAT_LABELS = {
|
|
|
7129
8105
|
lookup,
|
|
7130
8106
|
mergeWithAutoHeaders,
|
|
7131
8107
|
normalizeContentType,
|
|
8108
|
+
parseApicircleEnvironment,
|
|
8109
|
+
parseApicircleEnvironmentDoc,
|
|
8110
|
+
parseApicircleFolderExport,
|
|
8111
|
+
parseApicircleFolderExportDoc,
|
|
7132
8112
|
parseCurl,
|
|
7133
8113
|
parseDigestChallenge,
|
|
7134
8114
|
parseGraphqlSchema,
|
|
@@ -7144,6 +8124,7 @@ var TRANSFORM_FORMAT_LABELS = {
|
|
|
7144
8124
|
previewLinkedUpdate,
|
|
7145
8125
|
publishRelease,
|
|
7146
8126
|
readJsonPath,
|
|
8127
|
+
redactFolderExportCredentials,
|
|
7147
8128
|
redactForGit,
|
|
7148
8129
|
refreshToken,
|
|
7149
8130
|
requestDeviceAuthorization,
|
|
@@ -7156,11 +8137,13 @@ var TRANSFORM_FORMAT_LABELS = {
|
|
|
7156
8137
|
runClientCredentials,
|
|
7157
8138
|
runPlan,
|
|
7158
8139
|
runRopc,
|
|
8140
|
+
serializeFolderExport,
|
|
7159
8141
|
serializePayload,
|
|
7160
8142
|
serializeWorkspaceForGit,
|
|
7161
8143
|
signJwt,
|
|
7162
8144
|
slugify,
|
|
7163
8145
|
sortVersionsDesc,
|
|
8146
|
+
suggestFolderExportFilename,
|
|
7164
8147
|
suggestHeaders,
|
|
7165
8148
|
summarizeUnpushedChanges,
|
|
7166
8149
|
supportedContentTypeLanguageMap,
|