mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-09-09 19:31:57 +02:00
feat(import): add stable per-resource source keys to the importer contract (#614)
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
e63a87718c
commit
81a2a5d955
@@ -15,6 +15,21 @@ export function convertId(id: string): string {
|
||||
return `GENERATE_ID::${id}`;
|
||||
}
|
||||
|
||||
export function createSourceKeys() {
|
||||
const keys: Record<string, string> = {};
|
||||
return {
|
||||
/** Convert a resource's own document ID, keeping it as that resource's source key. */
|
||||
own(id: string): string {
|
||||
const converted = convertId(id);
|
||||
keys[converted] = id;
|
||||
return converted;
|
||||
},
|
||||
all: (): Record<string, string> => keys,
|
||||
};
|
||||
}
|
||||
|
||||
export type SourceKeys = ReturnType<typeof createSourceKeys>;
|
||||
|
||||
export function importHttpBodyAndHeaders(obj: any) {
|
||||
const { headers } = importHeaders(obj);
|
||||
const { body, bodyType } = importHttpBody(obj.body);
|
||||
|
||||
@@ -1,10 +1,18 @@
|
||||
/* oxlint-disable no-explicit-any */
|
||||
import type { PartialImportResources } from "@yaakapp/api";
|
||||
import { convertId, convertTemplateSyntax, importHttpBodyAndHeaders, isJSObject } from "./common";
|
||||
import {
|
||||
convertId,
|
||||
convertTemplateSyntax,
|
||||
createSourceKeys,
|
||||
importHttpBodyAndHeaders,
|
||||
isJSObject,
|
||||
type SourceKeys,
|
||||
} from "./common";
|
||||
|
||||
export function convertInsomniaV4(parsed: any) {
|
||||
if (!Array.isArray(parsed.resources)) return null;
|
||||
|
||||
const keys = createSourceKeys();
|
||||
const resources: PartialImportResources = {
|
||||
environments: [],
|
||||
folders: [],
|
||||
@@ -20,7 +28,7 @@ export function convertInsomniaV4(parsed: any) {
|
||||
);
|
||||
for (const w of workspacesToImport) {
|
||||
resources.workspaces.push({
|
||||
id: convertId(w._id),
|
||||
id: keys.own(w._id),
|
||||
createdAt: w.created ? new Date(w.created).toISOString().replace("Z", "") : undefined,
|
||||
updatedAt: w.updated ? new Date(w.updated).toISOString().replace("Z", "") : undefined,
|
||||
model: "workspace",
|
||||
@@ -31,7 +39,7 @@ export function convertInsomniaV4(parsed: any) {
|
||||
(r: any) => isJSObject(r) && r._type === "environment",
|
||||
);
|
||||
resources.environments.push(
|
||||
...environmentsToImport.map((r: any) => importEnvironment(r, w._id)),
|
||||
...environmentsToImport.map((r: any) => importEnvironment(r, w._id, keys)),
|
||||
);
|
||||
|
||||
const nextFolder = (parentId: string) => {
|
||||
@@ -40,12 +48,12 @@ export function convertInsomniaV4(parsed: any) {
|
||||
if (!isJSObject(child)) continue;
|
||||
|
||||
if (child._type === "request_group") {
|
||||
resources.folders.push(importFolder(child, w._id));
|
||||
resources.folders.push(importFolder(child, w._id, keys));
|
||||
nextFolder(child._id);
|
||||
} else if (child._type === "request") {
|
||||
resources.httpRequests.push(importHttpRequest(child, w._id));
|
||||
resources.httpRequests.push(importHttpRequest(child, w._id, keys));
|
||||
} else if (child._type === "grpc_request") {
|
||||
resources.grpcRequests.push(importGrpcRequest(child, w._id));
|
||||
resources.grpcRequests.push(importGrpcRequest(child, w._id, keys));
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -60,10 +68,14 @@ export function convertInsomniaV4(parsed: any) {
|
||||
resources.environments = resources.environments.filter(Boolean);
|
||||
resources.workspaces = resources.workspaces.filter(Boolean);
|
||||
|
||||
return { resources: convertTemplateSyntax(resources) };
|
||||
return { resources: convertTemplateSyntax(resources), sourceKeys: keys.all() };
|
||||
}
|
||||
|
||||
function importHttpRequest(r: any, workspaceId: string): PartialImportResources["httpRequests"][0] {
|
||||
function importHttpRequest(
|
||||
r: any,
|
||||
workspaceId: string,
|
||||
keys: SourceKeys,
|
||||
): PartialImportResources["httpRequests"][0] {
|
||||
let authenticationType: string | null = null;
|
||||
let authentication = {};
|
||||
if (r.authentication.type === "bearer") {
|
||||
@@ -80,7 +92,7 @@ function importHttpRequest(r: any, workspaceId: string): PartialImportResources[
|
||||
}
|
||||
|
||||
return {
|
||||
id: convertId(r.meta?.id ?? r._id),
|
||||
id: keys.own(r.meta?.id ?? r._id),
|
||||
createdAt: r.created ? new Date(r.created).toISOString().replace("Z", "") : undefined,
|
||||
updatedAt: r.modified ? new Date(r.modified).toISOString().replace("Z", "") : undefined,
|
||||
workspaceId: convertId(workspaceId),
|
||||
@@ -102,13 +114,17 @@ function importHttpRequest(r: any, workspaceId: string): PartialImportResources[
|
||||
};
|
||||
}
|
||||
|
||||
function importGrpcRequest(r: any, workspaceId: string): PartialImportResources["grpcRequests"][0] {
|
||||
function importGrpcRequest(
|
||||
r: any,
|
||||
workspaceId: string,
|
||||
keys: SourceKeys,
|
||||
): PartialImportResources["grpcRequests"][0] {
|
||||
const parts = r.protoMethodName.split("/").filter((p: any) => p !== "");
|
||||
const service = parts[0] ?? null;
|
||||
const method = parts[1] ?? null;
|
||||
|
||||
return {
|
||||
id: convertId(r.meta?.id ?? r._id),
|
||||
id: keys.own(r.meta?.id ?? r._id),
|
||||
createdAt: r.created ? new Date(r.created).toISOString().replace("Z", "") : undefined,
|
||||
updatedAt: r.modified ? new Date(r.modified).toISOString().replace("Z", "") : undefined,
|
||||
workspaceId: convertId(workspaceId),
|
||||
@@ -131,9 +147,13 @@ function importGrpcRequest(r: any, workspaceId: string): PartialImportResources[
|
||||
};
|
||||
}
|
||||
|
||||
function importFolder(f: any, workspaceId: string): PartialImportResources["folders"][0] {
|
||||
function importFolder(
|
||||
f: any,
|
||||
workspaceId: string,
|
||||
keys: SourceKeys,
|
||||
): PartialImportResources["folders"][0] {
|
||||
return {
|
||||
id: convertId(f._id),
|
||||
id: keys.own(f._id),
|
||||
createdAt: f.created ? new Date(f.created).toISOString().replace("Z", "") : undefined,
|
||||
updatedAt: f.modified ? new Date(f.modified).toISOString().replace("Z", "") : undefined,
|
||||
folderId: f.parentId === workspaceId ? null : convertId(f.parentId),
|
||||
@@ -147,11 +167,12 @@ function importFolder(f: any, workspaceId: string): PartialImportResources["fold
|
||||
function importEnvironment(
|
||||
e: any,
|
||||
workspaceId: string,
|
||||
keys: SourceKeys,
|
||||
isParentOg?: boolean,
|
||||
): PartialImportResources["environments"][0] {
|
||||
const isParent = isParentOg ?? e.parentId === workspaceId;
|
||||
return {
|
||||
id: convertId(e._id),
|
||||
id: keys.own(e._id),
|
||||
createdAt: e.created ? new Date(e.created).toISOString().replace("Z", "") : undefined,
|
||||
updatedAt: e.modified ? new Date(e.modified).toISOString().replace("Z", "") : undefined,
|
||||
workspaceId: convertId(workspaceId),
|
||||
|
||||
@@ -3,9 +3,11 @@ import type { PartialImportResources } from "@yaakapp/api";
|
||||
import {
|
||||
convertId,
|
||||
convertTemplateSyntax,
|
||||
createSourceKeys,
|
||||
importHeaders,
|
||||
importHttpBodyAndHeaders,
|
||||
isJSObject,
|
||||
type SourceKeys,
|
||||
} from "./common";
|
||||
|
||||
export function convertInsomniaV5(parsed: any) {
|
||||
@@ -18,6 +20,7 @@ export function convertInsomniaV5(parsed: any) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const keys = createSourceKeys();
|
||||
const resources: PartialImportResources = {
|
||||
environments: [],
|
||||
folders: [],
|
||||
@@ -30,7 +33,7 @@ export function convertInsomniaV5(parsed: any) {
|
||||
// Import workspaces
|
||||
const meta = ("meta" in parsed ? parsed.meta : {}) as Record<string, any>;
|
||||
resources.workspaces.push({
|
||||
id: convertId(meta.id ?? "collection"),
|
||||
id: keys.own(meta.id ?? "collection"),
|
||||
createdAt: meta.created ? new Date(meta.created).toISOString().replace("Z", "") : undefined,
|
||||
updatedAt: meta.modified ? new Date(meta.modified).toISOString().replace("Z", "") : undefined,
|
||||
model: "workspace",
|
||||
@@ -42,8 +45,10 @@ export function convertInsomniaV5(parsed: any) {
|
||||
|
||||
// Import environments
|
||||
resources.environments.push(
|
||||
importEnvironment(parsed.environments, meta.id, true),
|
||||
...(parsed.environments.subEnvironments ?? []).map((r: any) => importEnvironment(r, meta.id)),
|
||||
importEnvironment(parsed.environments, meta.id, keys, true),
|
||||
...(parsed.environments.subEnvironments ?? []).map((r: any) =>
|
||||
importEnvironment(r, meta.id, keys),
|
||||
),
|
||||
);
|
||||
|
||||
// Import folders
|
||||
@@ -52,16 +57,16 @@ export function convertInsomniaV5(parsed: any) {
|
||||
if (!isJSObject(child)) continue;
|
||||
|
||||
if (Array.isArray(child.children)) {
|
||||
const { folder, environment } = importFolder(child, meta.id, parentId);
|
||||
const { folder, environment } = importFolder(child, meta.id, parentId, keys);
|
||||
resources.folders.push(folder);
|
||||
if (environment) resources.environments.push(environment);
|
||||
nextFolder(child.children, child.meta.id);
|
||||
} else if (child.method) {
|
||||
resources.httpRequests.push(importHttpRequest(child, meta.id, parentId));
|
||||
resources.httpRequests.push(importHttpRequest(child, meta.id, parentId, keys));
|
||||
} else if (child.protoFileId) {
|
||||
resources.grpcRequests.push(importGrpcRequest(child, meta.id, parentId));
|
||||
resources.grpcRequests.push(importGrpcRequest(child, meta.id, parentId, keys));
|
||||
} else if (child.url) {
|
||||
resources.websocketRequests.push(importWebsocketRequest(child, meta.id, parentId));
|
||||
resources.websocketRequests.push(importWebsocketRequest(child, meta.id, parentId, keys));
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -75,13 +80,14 @@ export function convertInsomniaV5(parsed: any) {
|
||||
resources.environments = resources.environments.filter(Boolean);
|
||||
resources.workspaces = resources.workspaces.filter(Boolean);
|
||||
|
||||
return { resources: convertTemplateSyntax(resources) };
|
||||
return { resources: convertTemplateSyntax(resources), sourceKeys: keys.all() };
|
||||
}
|
||||
|
||||
function importHttpRequest(
|
||||
r: any,
|
||||
workspaceId: string,
|
||||
parentId: string,
|
||||
keys: SourceKeys,
|
||||
): PartialImportResources["httpRequests"][0] {
|
||||
const id = r.meta?.id ?? r._id;
|
||||
const created = r.meta?.created ?? r.created;
|
||||
@@ -89,7 +95,7 @@ function importHttpRequest(
|
||||
const sortKey = r.meta?.sortKey ?? r.sortKey;
|
||||
|
||||
return {
|
||||
id: convertId(id),
|
||||
id: keys.own(id),
|
||||
workspaceId: convertId(workspaceId),
|
||||
createdAt: created ? new Date(created).toISOString().replace("Z", "") : undefined,
|
||||
updatedAt: updated ? new Date(updated).toISOString().replace("Z", "") : undefined,
|
||||
@@ -114,6 +120,7 @@ function importGrpcRequest(
|
||||
r: any,
|
||||
workspaceId: string,
|
||||
parentId: string,
|
||||
keys: SourceKeys,
|
||||
): PartialImportResources["grpcRequests"][0] {
|
||||
const id = r.meta?.id ?? r._id;
|
||||
const created = r.meta?.created ?? r.created;
|
||||
@@ -126,7 +133,7 @@ function importGrpcRequest(
|
||||
|
||||
return {
|
||||
model: "grpc_request",
|
||||
id: convertId(id),
|
||||
id: keys.own(id),
|
||||
workspaceId: convertId(workspaceId),
|
||||
createdAt: created ? new Date(created).toISOString().replace("Z", "") : undefined,
|
||||
updatedAt: updated ? new Date(updated).toISOString().replace("Z", "") : undefined,
|
||||
@@ -152,6 +159,7 @@ function importWebsocketRequest(
|
||||
r: any,
|
||||
workspaceId: string,
|
||||
parentId: string,
|
||||
keys: SourceKeys,
|
||||
): PartialImportResources["websocketRequests"][0] {
|
||||
const id = r.meta?.id ?? r._id;
|
||||
const created = r.meta?.created ?? r.created;
|
||||
@@ -160,7 +168,7 @@ function importWebsocketRequest(
|
||||
|
||||
return {
|
||||
model: "websocket_request",
|
||||
id: convertId(id),
|
||||
id: keys.own(id),
|
||||
workspaceId: convertId(workspaceId),
|
||||
createdAt: created ? new Date(created).toISOString().replace("Z", "") : undefined,
|
||||
updatedAt: updated ? new Date(updated).toISOString().replace("Z", "") : undefined,
|
||||
@@ -198,6 +206,7 @@ function importFolder(
|
||||
f: any,
|
||||
workspaceId: string,
|
||||
parentId: string,
|
||||
keys: SourceKeys,
|
||||
): {
|
||||
folder: PartialImportResources["folders"][0];
|
||||
environment: PartialImportResources["environments"][0] | null;
|
||||
@@ -210,7 +219,7 @@ function importFolder(
|
||||
let environment: PartialImportResources["environments"][0] | null = null;
|
||||
if (Object.keys(f.environment ?? {}).length > 0) {
|
||||
environment = {
|
||||
id: convertId(`${id}folder`),
|
||||
id: keys.own(`${id}folder`),
|
||||
createdAt: created ? new Date(created).toISOString().replace("Z", "") : undefined,
|
||||
updatedAt: updated ? new Date(updated).toISOString().replace("Z", "") : undefined,
|
||||
workspaceId: convertId(workspaceId),
|
||||
@@ -230,7 +239,7 @@ function importFolder(
|
||||
return {
|
||||
folder: {
|
||||
model: "folder",
|
||||
id: convertId(id),
|
||||
id: keys.own(id),
|
||||
createdAt: created ? new Date(created).toISOString().replace("Z", "") : undefined,
|
||||
updatedAt: updated ? new Date(updated).toISOString().replace("Z", "") : undefined,
|
||||
folderId: parentId === workspaceId ? null : convertId(parentId),
|
||||
@@ -248,6 +257,7 @@ function importFolder(
|
||||
function importEnvironment(
|
||||
e: any,
|
||||
workspaceId: string,
|
||||
keys: SourceKeys,
|
||||
isParent?: boolean,
|
||||
): PartialImportResources["environments"][0] {
|
||||
const id = e.meta?.id ?? e._id;
|
||||
@@ -256,7 +266,7 @@ function importEnvironment(
|
||||
const sortKey = e.meta?.sortKey ?? e.sortKey;
|
||||
|
||||
return {
|
||||
id: convertId(id),
|
||||
id: keys.own(id),
|
||||
createdAt: created ? new Date(created).toISOString().replace("Z", "") : undefined,
|
||||
updatedAt: updated ? new Date(updated).toISOString().replace("Z", "") : undefined,
|
||||
workspaceId: convertId(workspaceId),
|
||||
|
||||
Reference in New Issue
Block a user