mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-04-25 02:08:28 +02:00
Improved Postman and OpenAPI import
This commit is contained in:
@@ -2,7 +2,7 @@
|
|||||||
"name": "filter-jsonpath",
|
"name": "filter-jsonpath",
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "yaakcli src/index.ts"
|
"build": "BUILD_PLATFORM=browser yaakcli src/index.ts"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"jsonpath": "^1.1.1"
|
"jsonpath": "^1.1.1"
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"name": "importer-postman",
|
"name": "importer-openapi",
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "yaakcli ./src/index.js"
|
"build": "yaakcli ./src/index.js"
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { convert } from 'openapi-to-postmanv2';
|
import { convert } from 'openapi-to-postmanv2';
|
||||||
import { pluginHookImport as pluginHookImportPostman } from '../../importer-postman/build';
|
import { pluginHookImport as pluginHookImportPostman } from '../../importer-postman';
|
||||||
import { Folder, HttpRequest, Workspace, Environment } from '../../../types/models';
|
import { Folder, HttpRequest, Workspace, Environment } from '../../../types/models';
|
||||||
|
|
||||||
type AtLeast<T, K extends keyof T> = Partial<T> & Pick<T, K>;
|
type AtLeast<T, K extends keyof T> = Partial<T> & Pick<T, K>;
|
||||||
@@ -15,15 +15,21 @@ export async function pluginHookImport(
|
|||||||
ctx: any,
|
ctx: any,
|
||||||
contents: string,
|
contents: string,
|
||||||
): Promise<{ resources: ExportResources } | undefined> {
|
): Promise<{ resources: ExportResources } | undefined> {
|
||||||
const result = await new Promise((resolve, reject) => {
|
let postmanCollection;
|
||||||
convert({ type: 'string', data: contents }, {}, (err, result) => {
|
try {
|
||||||
if (err != null) reject(err);
|
postmanCollection = await new Promise((resolve, reject) => {
|
||||||
|
convert({ type: 'string', data: contents }, {}, (err, result) => {
|
||||||
|
if (err != null) reject(err);
|
||||||
|
|
||||||
if (Array.isArray(result.output) && result.output.length > 0) {
|
if (Array.isArray(result.output) && result.output.length > 0) {
|
||||||
resolve(JSON.stringify(result.output[0].data));
|
resolve(result.output[0].data);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
} catch (err) {
|
||||||
|
// Probably not an OpenAPI file, so skip it
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
return pluginHookImportPostman(ctx, result);
|
return pluginHookImportPostman(ctx, JSON.stringify(postmanCollection));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,11 @@ describe('importer-openapi', () => {
|
|||||||
const p = path.join(__dirname, 'fixtures');
|
const p = path.join(__dirname, 'fixtures');
|
||||||
const fixtures = fs.readdirSync(p);
|
const fixtures = fs.readdirSync(p);
|
||||||
|
|
||||||
|
test('Skips invalid file', async () => {
|
||||||
|
const imported = await pluginHookImport({}, '{}');
|
||||||
|
expect(imported).toBeUndefined();
|
||||||
|
})
|
||||||
|
|
||||||
for (const fixture of fixtures) {
|
for (const fixture of fixtures) {
|
||||||
test('Imports ' + fixture, async () => {
|
test('Imports ' + fixture, async () => {
|
||||||
const contents = fs.readFileSync(path.join(p, fixture), 'utf-8');
|
const contents = fs.readFileSync(path.join(p, fixture), 'utf-8');
|
||||||
@@ -14,6 +19,7 @@ describe('importer-openapi', () => {
|
|||||||
expect(imported?.resources.workspaces).toEqual([
|
expect(imported?.resources.workspaces).toEqual([
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
name: 'Swagger Petstore - OpenAPI 3.0',
|
name: 'Swagger Petstore - OpenAPI 3.0',
|
||||||
|
description: expect.stringContaining('This is a sample Pet Store Server'),
|
||||||
}),
|
}),
|
||||||
]);
|
]);
|
||||||
expect(imported?.resources.httpRequests.length).toBe(19);
|
expect(imported?.resources.httpRequests.length).toBe(19);
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ export function pluginHookImport(
|
|||||||
model: 'workspace',
|
model: 'workspace',
|
||||||
id: generateId('workspace'),
|
id: generateId('workspace'),
|
||||||
name: info.name || 'Postman Import',
|
name: info.name || 'Postman Import',
|
||||||
description: info.description || '',
|
description: info.description?.content ?? info.description ?? '',
|
||||||
variables:
|
variables:
|
||||||
root.variable?.map((v: any) => ({
|
root.variable?.map((v: any) => ({
|
||||||
name: v.key,
|
name: v.key,
|
||||||
@@ -73,7 +73,7 @@ export function pluginHookImport(
|
|||||||
folderId,
|
folderId,
|
||||||
name: v.name,
|
name: v.name,
|
||||||
method: r.method || 'GET',
|
method: r.method || 'GET',
|
||||||
url: typeof r.url === 'string' ? r.url : toRecord(r.url).raw,
|
url: typeof r.url === 'string' ? r.url : convertUrl(toRecord(r.url)),
|
||||||
body: bodyPatch.body,
|
body: bodyPatch.body,
|
||||||
bodyType: bodyPatch.bodyType,
|
bodyType: bodyPatch.bodyType,
|
||||||
authentication: authPatch.authentication,
|
authentication: authPatch.authentication,
|
||||||
@@ -103,6 +103,43 @@ export function pluginHookImport(
|
|||||||
return { resources: convertTemplateSyntax(exportResources) };
|
return { resources: convertTemplateSyntax(exportResources) };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function convertUrl(url: Record<string, any>) {
|
||||||
|
if ('raw' in url) {
|
||||||
|
return url.raw;
|
||||||
|
}
|
||||||
|
|
||||||
|
let v = '';
|
||||||
|
|
||||||
|
if ('protocol' in url && typeof url.protocol === 'string') {
|
||||||
|
v += `${url.protocol}://`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ('host' in url) {
|
||||||
|
v += `${Array.isArray(url.host) ? url.host.join('.') : url.host}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ('port' in url && typeof url.port === 'string') {
|
||||||
|
v += `:${url.port}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ('path' in url && Array.isArray(url.path) && url.path.length > 0) {
|
||||||
|
v += `/${Array.isArray(url.path) ? url.path.join('/') : url.path}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ('query' in url && Array.isArray(url.query) && url.query.length > 0) {
|
||||||
|
const qs = url.query.map(q => `${q.key ?? ''}=${q.value ?? ''}`).join('&');
|
||||||
|
v += `?${qs}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ('hash' in url && typeof url.hash === 'string') {
|
||||||
|
v += `#${url.hash}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Implement url.variables (path variables)
|
||||||
|
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
function importAuth(
|
function importAuth(
|
||||||
rawAuth: any,
|
rawAuth: any,
|
||||||
): Pick<HttpRequest, 'authentication' | 'authenticationType' | 'headers'> {
|
): Pick<HttpRequest, 'authentication' | 'authenticationType' | 'headers'> {
|
||||||
@@ -181,16 +218,16 @@ function importBody(rawBody: any): Pick<HttpRequest, 'body' | 'bodyType' | 'head
|
|||||||
form: toArray(body.formdata).map((f) =>
|
form: toArray(body.formdata).map((f) =>
|
||||||
f.src != null
|
f.src != null
|
||||||
? {
|
? {
|
||||||
enabled: !f.disabled,
|
enabled: !f.disabled,
|
||||||
contentType: f.contentType ?? null,
|
contentType: f.contentType ?? null,
|
||||||
name: f.key ?? '',
|
name: f.key ?? '',
|
||||||
file: f.src ?? '',
|
file: f.src ?? '',
|
||||||
}
|
}
|
||||||
: {
|
: {
|
||||||
enabled: !f.disabled,
|
enabled: !f.disabled,
|
||||||
name: f.key ?? '',
|
name: f.key ?? '',
|
||||||
value: f.value ?? '',
|
value: f.value ?? '',
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@@ -216,7 +253,8 @@ function importBody(rawBody: any): Pick<HttpRequest, 'body' | 'bodyType' | 'head
|
|||||||
function parseJSONToRecord(jsonStr: string): Record<string, any> | null {
|
function parseJSONToRecord(jsonStr: string): Record<string, any> | null {
|
||||||
try {
|
try {
|
||||||
return toRecord(JSON.parse(jsonStr));
|
return toRecord(JSON.parse(jsonStr));
|
||||||
} catch (err) {}
|
} catch (err) {
|
||||||
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user