@apicircle/core 1.0.8 → 1.0.9

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/index.cjs CHANGED
@@ -22,6 +22,7 @@ var src_exports = {};
22
22
  __export(src_exports, {
23
23
  ANONYMOUS_ACTOR: () => ANONYMOUS_ACTOR,
24
24
  APICIRCLE_FOLDER_EXPORT_FORMAT: () => APICIRCLE_FOLDER_EXPORT_FORMAT,
25
+ ATTACHMENTS_DIR: () => ATTACHMENTS_DIR,
25
26
  DESKTOP_APP_ORIGIN: () => DESKTOP_APP_ORIGIN,
26
27
  EMPTY_UNPUSHED_SUMMARY: () => EMPTY_UNPUSHED_SUMMARY,
27
28
  HTTP_HEADERS_MAP: () => HTTP_HEADERS_MAP,
@@ -29,6 +30,8 @@ __export(src_exports, {
29
30
  PlanRunDeniedError: () => PlanRunDeniedError,
30
31
  RemoteWorkspaceParseError: () => RemoteWorkspaceParseError,
31
32
  TRANSFORM_FORMAT_LABELS: () => TRANSFORM_FORMAT_LABELS,
33
+ WORKSPACE_DIR: () => WORKSPACE_DIR,
34
+ WORKSPACE_JSON_PATH: () => WORKSPACE_JSON_PATH,
32
35
  applyAuth: () => applyAuth,
33
36
  applyAwsSigV4: () => applyAwsSigV4,
34
37
  applyContentTypeForBodyType: () => applyContentTypeForBodyType,
@@ -37,6 +40,7 @@ __export(src_exports, {
37
40
  applyMutation: () => applyMutation,
38
41
  applyPathParams: () => applyPathParams,
39
42
  assertNoPlaintextCredentials: () => assertNoPlaintextCredentials,
43
+ attachmentPath: () => attachmentPath,
40
44
  buildAuthorizeUrl: () => buildAuthorizeUrl,
41
45
  buildAutoHeaders: () => buildAutoHeaders,
42
46
  buildDigestAuthHeader: () => buildDigestAuthHeader,
@@ -5159,6 +5163,14 @@ function sortedReplacer(_key, value) {
5159
5163
  return out;
5160
5164
  }
5161
5165
 
5166
+ // src/git/repoPaths.ts
5167
+ var WORKSPACE_DIR = ".apicircle";
5168
+ var WORKSPACE_JSON_PATH = `${WORKSPACE_DIR}/workspace.json`;
5169
+ var ATTACHMENTS_DIR = `${WORKSPACE_DIR}/attachments`;
5170
+ function attachmentPath(slotId) {
5171
+ return `${ATTACHMENTS_DIR}/${slotId}`;
5172
+ }
5173
+
5162
5174
  // src/git/parseWorkspaceJson.ts
5163
5175
  var MAX_WORKSPACE_JSON_BYTES = 16 * 1024 * 1024;
5164
5176
  var FORBIDDEN_KEYS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
@@ -6823,6 +6835,18 @@ function applyMutation(state, patch, options = {}) {
6823
6835
  return applyMockUpsert(state, patch.mock, now);
6824
6836
  case "mock.delete":
6825
6837
  return applyMockDelete(state, patch.id, now);
6838
+ case "globalAsset.upsertFile":
6839
+ return applyGlobalAssetUpsertFile(state, patch.file, now);
6840
+ case "globalAsset.removeFile":
6841
+ return applyGlobalAssetRemoveFile(state, patch.id, now);
6842
+ case "globalAsset.markPushed":
6843
+ return applyGlobalAssetMarkPushed(state, patch.id, patch.ref, now);
6844
+ case "globalAsset.markMerged":
6845
+ return applyGlobalAssetMarkMerged(state, patch.id, patch.ref, now);
6846
+ case "globalAsset.cleanupWorkingRef":
6847
+ return applyGlobalAssetCleanupWorkingRef(state, patch.id, now);
6848
+ case "globalAsset.invalidateRef":
6849
+ return applyGlobalAssetInvalidateRef(state, patch.id, patch.which, now);
6826
6850
  case "plan.upsert":
6827
6851
  return applyPlanUpsert(state, patch.plan, now);
6828
6852
  case "plan.delete":
@@ -7138,6 +7162,147 @@ function applyMockDelete(state, id, now) {
7138
7162
  } : state.local;
7139
7163
  return { next: { synced, local }, changedIds: [id] };
7140
7164
  }
7165
+ function applyGlobalAssetUpsertFile(state, file, now) {
7166
+ const files = state.synced.globalAssets.files ?? {};
7167
+ const existing = files[file.id];
7168
+ const next = {
7169
+ ...file,
7170
+ workingBranchRef: file.workingBranchRef !== void 0 ? file.workingBranchRef : existing?.workingBranchRef,
7171
+ baseBranchRef: file.baseBranchRef !== void 0 ? file.baseBranchRef : existing?.baseBranchRef,
7172
+ updatedAt: now
7173
+ };
7174
+ const synced = {
7175
+ ...state.synced,
7176
+ globalAssets: {
7177
+ ...state.synced.globalAssets,
7178
+ files: { ...files, [file.id]: next }
7179
+ },
7180
+ meta: { ...state.synced.meta, updatedAt: now }
7181
+ };
7182
+ return { next: { ...state, synced }, changedIds: [file.id] };
7183
+ }
7184
+ function applyGlobalAssetRemoveFile(state, id, now) {
7185
+ const files = state.synced.globalAssets.files ?? {};
7186
+ if (!files[id]) {
7187
+ return { next: state, changedIds: [] };
7188
+ }
7189
+ const { [id]: _drop, ...rest } = files;
7190
+ void _drop;
7191
+ const requests = { ...state.synced.collections.requests };
7192
+ for (const [reqId, req] of Object.entries(requests)) {
7193
+ const body = clearAssetFromRequestBody(req.body, id);
7194
+ if (body !== req.body) requests[reqId] = { ...req, body, updatedAt: now };
7195
+ }
7196
+ const mockServers = { ...state.synced.mockServers };
7197
+ for (const [serverId, server] of Object.entries(mockServers)) {
7198
+ let touchedServer = false;
7199
+ const endpoints = server.endpoints.map((endpoint) => {
7200
+ let touched = false;
7201
+ const defaultResponse = clearAssetFromMockResponse(endpoint.defaultResponse, id);
7202
+ if (defaultResponse !== endpoint.defaultResponse) touched = true;
7203
+ const requestValidation = endpoint.requestValidation.map((rule) => {
7204
+ const failResponse = clearAssetFromMockResponse(rule.failResponse, id);
7205
+ if (failResponse === rule.failResponse) return rule;
7206
+ touched = true;
7207
+ return { ...rule, failResponse };
7208
+ });
7209
+ const responseRules = endpoint.responseRules.map((rule) => {
7210
+ const response = clearAssetFromMockResponse(rule.response, id);
7211
+ if (response === rule.response) return rule;
7212
+ touched = true;
7213
+ return { ...rule, response };
7214
+ });
7215
+ if (!touched) return endpoint;
7216
+ touchedServer = true;
7217
+ return { ...endpoint, defaultResponse, requestValidation, responseRules };
7218
+ });
7219
+ if (touchedServer) {
7220
+ const source = server.source.kind === "manual" ? { kind: "manual", endpoints } : server.source;
7221
+ mockServers[serverId] = { ...server, source, endpoints, updatedAt: now };
7222
+ }
7223
+ }
7224
+ let local = state.local;
7225
+ if (local.pendingFileUploads && local.pendingFileUploads[id]) {
7226
+ const nextPending = { ...local.pendingFileUploads };
7227
+ delete nextPending[id];
7228
+ local = { ...local, pendingFileUploads: nextPending };
7229
+ }
7230
+ if (local.assetUsageIndex && local.assetUsageIndex[id]) {
7231
+ const nextUsage = { ...local.assetUsageIndex };
7232
+ delete nextUsage[id];
7233
+ local = { ...local, assetUsageIndex: nextUsage };
7234
+ }
7235
+ const synced = {
7236
+ ...state.synced,
7237
+ collections: { ...state.synced.collections, requests },
7238
+ mockServers,
7239
+ globalAssets: { ...state.synced.globalAssets, files: rest },
7240
+ meta: { ...state.synced.meta, updatedAt: now }
7241
+ };
7242
+ return { next: { synced, local }, changedIds: [id] };
7243
+ }
7244
+ function applyGlobalAssetMarkPushed(state, id, ref, now) {
7245
+ return mutateAssetRef(state, id, now, (asset) => ({ ...asset, workingBranchRef: ref }));
7246
+ }
7247
+ function applyGlobalAssetMarkMerged(state, id, ref, now) {
7248
+ return mutateAssetRef(state, id, now, (asset) => ({ ...asset, baseBranchRef: ref }));
7249
+ }
7250
+ function applyGlobalAssetCleanupWorkingRef(state, id, now) {
7251
+ return mutateAssetRef(state, id, now, (asset) => {
7252
+ if (!asset.workingBranchRef) return asset;
7253
+ return { ...asset, workingBranchRef: null };
7254
+ });
7255
+ }
7256
+ function applyGlobalAssetInvalidateRef(state, id, which, now) {
7257
+ return mutateAssetRef(state, id, now, (asset) => {
7258
+ if (which === "working") {
7259
+ if (!asset.workingBranchRef) return asset;
7260
+ return { ...asset, workingBranchRef: null };
7261
+ }
7262
+ if (!asset.baseBranchRef) return asset;
7263
+ return { ...asset, baseBranchRef: null };
7264
+ });
7265
+ }
7266
+ function mutateAssetRef(state, id, now, transform) {
7267
+ const files = state.synced.globalAssets.files ?? {};
7268
+ const existing = files[id];
7269
+ if (!existing) return { next: state, changedIds: [] };
7270
+ const updated = transform(existing);
7271
+ if (updated === existing) return { next: state, changedIds: [] };
7272
+ const next = { ...updated, updatedAt: now };
7273
+ const synced = {
7274
+ ...state.synced,
7275
+ globalAssets: {
7276
+ ...state.synced.globalAssets,
7277
+ files: { ...files, [id]: next }
7278
+ },
7279
+ meta: { ...state.synced.meta, updatedAt: now }
7280
+ };
7281
+ return { next: { ...state, synced }, changedIds: [id] };
7282
+ }
7283
+ function clearAssetFromRequestBody(body, id) {
7284
+ if (body.type === "binary" && body.attachment?.globalFileAssetId === id) {
7285
+ return { type: "binary", content: "" };
7286
+ }
7287
+ if (body.type !== "form-data" || !body.formRows) return body;
7288
+ let touched = false;
7289
+ const formRows = body.formRows.map((row) => {
7290
+ if (row.kind !== "file" || row.globalFileAssetId !== id) return row;
7291
+ touched = true;
7292
+ return { kind: "file", key: row.key, enabled: row.enabled, slotId: null };
7293
+ });
7294
+ return touched ? { ...body, formRows } : body;
7295
+ }
7296
+ function clearAssetFromMockResponse(response, id) {
7297
+ const body = clearAssetFromMockBody(response.body, id);
7298
+ return body === response.body ? response : { ...response, body };
7299
+ }
7300
+ function clearAssetFromMockBody(body, id) {
7301
+ if (body.type === "binary" && body.attachment?.globalFileAssetId === id) {
7302
+ return { type: "binary", content: "" };
7303
+ }
7304
+ return body;
7305
+ }
7141
7306
  function applyPlanUpsert(state, plan, now) {
7142
7307
  const existing = state.local.executionPlans[plan.id];
7143
7308
  const merged = existing ? { ...existing, ...plan, id: existing.id, createdAt: existing.createdAt, updatedAt: now } : { ...plan, updatedAt: now };
@@ -8032,6 +8197,7 @@ var TRANSFORM_FORMAT_LABELS = {
8032
8197
  0 && (module.exports = {
8033
8198
  ANONYMOUS_ACTOR,
8034
8199
  APICIRCLE_FOLDER_EXPORT_FORMAT,
8200
+ ATTACHMENTS_DIR,
8035
8201
  DESKTOP_APP_ORIGIN,
8036
8202
  EMPTY_UNPUSHED_SUMMARY,
8037
8203
  HTTP_HEADERS_MAP,
@@ -8039,6 +8205,8 @@ var TRANSFORM_FORMAT_LABELS = {
8039
8205
  PlanRunDeniedError,
8040
8206
  RemoteWorkspaceParseError,
8041
8207
  TRANSFORM_FORMAT_LABELS,
8208
+ WORKSPACE_DIR,
8209
+ WORKSPACE_JSON_PATH,
8042
8210
  applyAuth,
8043
8211
  applyAwsSigV4,
8044
8212
  applyContentTypeForBodyType,
@@ -8047,6 +8215,7 @@ var TRANSFORM_FORMAT_LABELS = {
8047
8215
  applyMutation,
8048
8216
  applyPathParams,
8049
8217
  assertNoPlaintextCredentials,
8218
+ attachmentPath,
8050
8219
  buildAuthorizeUrl,
8051
8220
  buildAutoHeaders,
8052
8221
  buildDigestAuthHeader,