Use baseUrl variable for OpenAPI imports

This commit is contained in:
Gregory Schier
2026-06-29 14:42:29 -07:00
parent 3b9c311dc5
commit 580302cbd2
3 changed files with 295 additions and 199 deletions
+25 -4
View File
@@ -1,5 +1,6 @@
import type { import type {
Context, Context,
Environment,
Folder, Folder,
HttpRequest, HttpRequest,
HttpRequestHeader, HttpRequestHeader,
@@ -15,6 +16,7 @@ type AtLeast<T, K extends keyof T> = Partial<T> & Pick<T, K>;
type UnknownRecord = Record<string, unknown>; type UnknownRecord = Record<string, unknown>;
type ImportResources = { type ImportResources = {
workspaces: AtLeast<Workspace, "name" | "id" | "model">[]; workspaces: AtLeast<Workspace, "name" | "id" | "model">[];
environments: AtLeast<Environment, "name" | "id" | "model" | "workspaceId" | "variables">[];
folders: AtLeast<Folder, "name" | "id" | "model" | "workspaceId">[]; folders: AtLeast<Folder, "name" | "id" | "model" | "workspaceId">[];
httpRequests: AtLeast<HttpRequest, "name" | "id" | "model" | "workspaceId">[]; httpRequests: AtLeast<HttpRequest, "name" | "id" | "model" | "workspaceId">[];
}; };
@@ -55,9 +57,25 @@ export async function convertOpenApi(contents: string): Promise<ImportPluginResp
const resources: ImportResources = { const resources: ImportResources = {
workspaces: [workspace], workspaces: [workspace],
environments: [],
folders: [], folders: [],
httpRequests: [], httpRequests: [],
}; };
const baseUrl = importBaseUrl(spec);
const requestBaseUrl = baseUrl.length > 0 ? "${[baseUrl]}" : "";
if (baseUrl.length > 0) {
resources.environments.push({
model: "environment",
id: importState.generateId("environment"),
workspaceId: workspace.id,
name: "Global Variables",
variables: [{ name: "baseUrl", value: baseUrl }],
parentModel: "workspace",
parentId: null,
sortPriority: importState.nextSortPriority(),
});
}
const folderIdsByTag = new Map<string, string>(); const folderIdsByTag = new Map<string, string>();
for (const tag of toArray(spec.tags)) { for (const tag of toArray(spec.tags)) {
@@ -102,6 +120,7 @@ export async function convertOpenApi(contents: string): Promise<ImportPluginResp
operation, operation,
path: rawPath, path: rawPath,
pathParameters, pathParameters,
requestBaseUrl,
spec, spec,
workspaceId: workspace.id, workspaceId: workspace.id,
folderId, folderId,
@@ -115,7 +134,7 @@ export async function convertOpenApi(contents: string): Promise<ImportPluginResp
return { return {
resources: deleteUndefinedAttrs( resources: deleteUndefinedAttrs(
convertTemplateSyntax({ convertTemplateSyntax({
environments: [], environments: resources.environments,
folders: resources.folders, folders: resources.folders,
grpcRequests: [], grpcRequests: [],
httpRequests: resources.httpRequests, httpRequests: resources.httpRequests,
@@ -132,6 +151,7 @@ function importOperation({
operation, operation,
path, path,
pathParameters, pathParameters,
requestBaseUrl,
spec, spec,
workspaceId, workspaceId,
folderId, folderId,
@@ -141,6 +161,7 @@ function importOperation({
operation: UnknownRecord; operation: UnknownRecord;
path: string; path: string;
pathParameters: unknown[]; pathParameters: unknown[];
requestBaseUrl: string;
spec: UnknownRecord; spec: UnknownRecord;
workspaceId: string; workspaceId: string;
folderId: string | null; folderId: string | null;
@@ -165,7 +186,7 @@ function importOperation({
bodyContentType: body.bodyType, bodyContentType: body.bodyType,
}), }),
method: method.toUpperCase(), method: method.toUpperCase(),
url: buildOperationUrl(spec, path), url: buildOperationUrl(requestBaseUrl, path),
urlParameters, urlParameters,
headers, headers,
body: body.body, body: body.body,
@@ -340,8 +361,8 @@ function findOrCreateFolderId({
return folder.id; return folder.id;
} }
function buildOperationUrl(spec: UnknownRecord, path: string): string { function buildOperationUrl(baseUrl: string, path: string): string {
return joinUrlParts(importBaseUrl(spec), path.replaceAll(/{([^}/]+)}/g, ":$1")); return joinUrlParts(baseUrl, path.replaceAll(/{([^}/]+)}/g, ":$1"));
} }
function importBaseUrl(spec: UnknownRecord): string { function importBaseUrl(spec: UnknownRecord): string {
File diff suppressed because it is too large Load Diff
+13 -2
View File
@@ -117,11 +117,17 @@ describe("importer-openapi", () => {
expect(imported?.resources.folders).toEqual([ expect(imported?.resources.folders).toEqual([
expect.objectContaining({ name: "accounts", description: "Account operations" }), expect.objectContaining({ name: "accounts", description: "Account operations" }),
]); ]);
expect(imported?.resources.environments).toEqual([
expect.objectContaining({
name: "Global Variables",
variables: [{ name: "baseUrl", value: "https://api.example.com/v1" }],
}),
]);
expect(imported?.resources.httpRequests).toEqual([ expect(imported?.resources.httpRequests).toEqual([
expect.objectContaining({ expect.objectContaining({
name: "Create member", name: "Create member",
method: "POST", method: "POST",
url: "https://api.example.com/v1/accounts/:accountId/members", url: "${[baseUrl]}/accounts/:accountId/members",
authenticationType: "bearer", authenticationType: "bearer",
authentication: { token: "", prefix: "Bearer" }, authentication: { token: "", prefix: "Bearer" },
bodyType: "application/json", bodyType: "application/json",
@@ -208,9 +214,14 @@ describe("importer-openapi", () => {
expect(imported?.resources.httpRequests[499]).toEqual( expect(imported?.resources.httpRequests[499]).toEqual(
expect.objectContaining({ expect.objectContaining({
name: "Read resource 499", name: "Read resource 499",
url: "https://api.example.com/client/v4/zones/:zoneId/resources/499", url: "${[baseUrl]}/zones/:zoneId/resources/499",
}), }),
); );
expect(imported?.resources.environments).toEqual([
expect.objectContaining({
variables: [{ name: "baseUrl", value: "https://api.example.com/client/v4" }],
}),
]);
}); });
test("Skips invalid file", async () => { test("Skips invalid file", async () => {