mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-03-20 16:43:53 +01:00
Handle Postman URL query and variable fields
This commit is contained in:
@@ -1,4 +1,13 @@
|
||||
import { Environment, Folder, HttpRequest, HttpRequestHeader, Model, Workspace, Context } from '@yaakapp/api';
|
||||
import {
|
||||
Environment,
|
||||
Folder,
|
||||
HttpRequest,
|
||||
HttpRequestHeader,
|
||||
Model,
|
||||
Workspace,
|
||||
Context,
|
||||
HttpUrlParameter,
|
||||
} from '@yaakapp/api';
|
||||
|
||||
const POSTMAN_2_1_0_SCHEMA = 'https://schema.getpostman.com/json/collection/v2.1.0/collection.json';
|
||||
const POSTMAN_2_0_0_SCHEMA = 'https://schema.getpostman.com/json/collection/v2.0.0/collection.json';
|
||||
@@ -84,6 +93,8 @@ export function pluginHookImport(
|
||||
headers.push(bodyPatchHeader);
|
||||
}
|
||||
|
||||
const { url, urlParameters } = convertUrl(r.url);
|
||||
|
||||
const request: ExportResources['httpRequests'][0] = {
|
||||
model: 'http_request',
|
||||
id: generateId('http_request'),
|
||||
@@ -91,7 +102,8 @@ export function pluginHookImport(
|
||||
folderId,
|
||||
name: v.name,
|
||||
method: r.method || 'GET',
|
||||
url: typeof r.url === 'string' ? r.url : convertUrl(toRecord(r.url)),
|
||||
url,
|
||||
urlParameters,
|
||||
body: bodyPatch.body,
|
||||
bodyType: bodyPatch.bodyType,
|
||||
authentication: authPatch.authentication,
|
||||
@@ -111,11 +123,13 @@ export function pluginHookImport(
|
||||
return { resources: convertTemplateSyntax(exportResources) };
|
||||
}
|
||||
|
||||
function convertUrl(url: Record<string, any>) {
|
||||
if ('raw' in url) {
|
||||
return url.raw;
|
||||
function convertUrl(url: string | any): Pick<HttpRequest, 'url' | 'urlParameters'> {
|
||||
if (typeof url === 'string') {
|
||||
return { url, urlParameters: [] };
|
||||
}
|
||||
|
||||
url = toRecord(url);
|
||||
|
||||
let v = '';
|
||||
|
||||
if ('protocol' in url && typeof url.protocol === 'string') {
|
||||
@@ -134,9 +148,25 @@ function convertUrl(url: Record<string, any>) {
|
||||
v += `/${Array.isArray(url.path) ? url.path.join('/') : url.path}`;
|
||||
}
|
||||
|
||||
const params: HttpUrlParameter[] = [];
|
||||
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}`;
|
||||
for (const query of url.query) {
|
||||
params.push({
|
||||
name: query.key ?? '',
|
||||
value: query.value ?? '',
|
||||
enabled: !query.disabled,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if ('variable' in url && Array.isArray(url.variable) && url.variable.length > 0) {
|
||||
for (const v of url.variable) {
|
||||
params.push({
|
||||
name: ':' + (v.key ?? ''),
|
||||
value: v.value ?? '',
|
||||
enabled: !v.disabled,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if ('hash' in url && typeof url.hash === 'string') {
|
||||
@@ -145,7 +175,7 @@ function convertUrl(url: Record<string, any>) {
|
||||
|
||||
// TODO: Implement url.variables (path variables)
|
||||
|
||||
return v;
|
||||
return { url: v, urlParameters: params };
|
||||
}
|
||||
|
||||
function importAuth(
|
||||
|
||||
77
plugins/importer-postman/tests/fixtures/nested.output.json
vendored
Normal file
77
plugins/importer-postman/tests/fixtures/nested.output.json
vendored
Normal file
@@ -0,0 +1,77 @@
|
||||
{
|
||||
"resources": {
|
||||
"workspaces": [
|
||||
{
|
||||
"model": "workspace",
|
||||
"id": "GENERATE_ID::WORKSPACE_0",
|
||||
"name": "New Collection",
|
||||
"description": "",
|
||||
"variables": []
|
||||
}
|
||||
],
|
||||
"environments": [],
|
||||
"httpRequests": [
|
||||
{
|
||||
"model": "http_request",
|
||||
"id": "GENERATE_ID::HTTP_REQUEST_0",
|
||||
"workspaceId": "GENERATE_ID::WORKSPACE_0",
|
||||
"folderId": "GENERATE_ID::FOLDER_1",
|
||||
"name": "Request 1",
|
||||
"method": "GET",
|
||||
"url": "",
|
||||
"urlParameters": [],
|
||||
"body": {},
|
||||
"bodyType": null,
|
||||
"authentication": {},
|
||||
"authenticationType": null,
|
||||
"headers": []
|
||||
},
|
||||
{
|
||||
"model": "http_request",
|
||||
"id": "GENERATE_ID::HTTP_REQUEST_1",
|
||||
"workspaceId": "GENERATE_ID::WORKSPACE_0",
|
||||
"folderId": "GENERATE_ID::FOLDER_0",
|
||||
"name": "Request 2",
|
||||
"method": "GET",
|
||||
"url": "",
|
||||
"urlParameters": [],
|
||||
"body": {},
|
||||
"bodyType": null,
|
||||
"authentication": {},
|
||||
"authenticationType": null,
|
||||
"headers": []
|
||||
},
|
||||
{
|
||||
"model": "http_request",
|
||||
"id": "GENERATE_ID::HTTP_REQUEST_2",
|
||||
"workspaceId": "GENERATE_ID::WORKSPACE_0",
|
||||
"folderId": null,
|
||||
"name": "Request 3",
|
||||
"method": "GET",
|
||||
"url": "",
|
||||
"urlParameters": [],
|
||||
"body": {},
|
||||
"bodyType": null,
|
||||
"authentication": {},
|
||||
"authenticationType": null,
|
||||
"headers": []
|
||||
}
|
||||
],
|
||||
"folders": [
|
||||
{
|
||||
"model": "folder",
|
||||
"workspaceId": "GENERATE_ID::WORKSPACE_0",
|
||||
"id": "GENERATE_ID::FOLDER_0",
|
||||
"name": "Top Folder",
|
||||
"folderId": null
|
||||
},
|
||||
{
|
||||
"model": "folder",
|
||||
"workspaceId": "GENERATE_ID::WORKSPACE_0",
|
||||
"id": "GENERATE_ID::FOLDER_1",
|
||||
"name": "Nested Folder",
|
||||
"folderId": "GENERATE_ID::FOLDER_0"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
136
plugins/importer-postman/tests/fixtures/params.input.json
vendored
Normal file
136
plugins/importer-postman/tests/fixtures/params.input.json
vendored
Normal file
@@ -0,0 +1,136 @@
|
||||
{
|
||||
"info": {
|
||||
"_postman_id": "9e6dfada-256c-49ea-a38f-7d1b05b7ca2d",
|
||||
"name": "New Collection",
|
||||
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json",
|
||||
"_exporter_id": "18798"
|
||||
},
|
||||
"item": [
|
||||
{
|
||||
"name": "Form URL",
|
||||
"request": {
|
||||
"auth": {
|
||||
"type": "bearer",
|
||||
"bearer": [
|
||||
{
|
||||
"key": "token",
|
||||
"value": "baeare",
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
},
|
||||
"method": "POST",
|
||||
"header": [
|
||||
{
|
||||
"key": "X-foo",
|
||||
"value": "bar",
|
||||
"description": "description"
|
||||
},
|
||||
{
|
||||
"key": "Disabled",
|
||||
"value": "tnroant",
|
||||
"description": "ntisorantosra",
|
||||
"disabled": true
|
||||
}
|
||||
],
|
||||
"body": {
|
||||
"mode": "formdata",
|
||||
"formdata": [
|
||||
{
|
||||
"key": "Key",
|
||||
"contentType": "Custom/COntent",
|
||||
"description": "DEscription",
|
||||
"type": "file",
|
||||
"src": "/Users/gschier/Desktop/Screenshot 2024-05-31 at 12.05.11 PM.png"
|
||||
}
|
||||
]
|
||||
},
|
||||
"url": {
|
||||
"raw": "example.com/:foo/:bar?q=qqq&",
|
||||
"host": [
|
||||
"example",
|
||||
"com"
|
||||
],
|
||||
"path": [
|
||||
":foo",
|
||||
":bar"
|
||||
],
|
||||
"query": [
|
||||
{
|
||||
"key": "disabled",
|
||||
"value": "secondvalue",
|
||||
"description": "this is disabled",
|
||||
"disabled": true
|
||||
},
|
||||
{
|
||||
"key": "q",
|
||||
"value": "qqq",
|
||||
"description": "hello"
|
||||
},
|
||||
{
|
||||
"key": "",
|
||||
"value": null
|
||||
}
|
||||
],
|
||||
"variable": [
|
||||
{
|
||||
"key": "foo",
|
||||
"value": "fff",
|
||||
"description": "Description"
|
||||
},
|
||||
{
|
||||
"key": "bar",
|
||||
"value": "bbb",
|
||||
"description": "bbb description"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"response": []
|
||||
}
|
||||
],
|
||||
"auth": {
|
||||
"type": "basic",
|
||||
"basic": [
|
||||
{
|
||||
"key": "password",
|
||||
"value": "globalpass",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"key": "username",
|
||||
"value": "globaluser",
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
},
|
||||
"event": [
|
||||
{
|
||||
"listen": "prerequest",
|
||||
"script": {
|
||||
"type": "text/javascript",
|
||||
"packages": {},
|
||||
"exec": [
|
||||
""
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"listen": "test",
|
||||
"script": {
|
||||
"type": "text/javascript",
|
||||
"packages": {},
|
||||
"exec": [
|
||||
""
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"variable": [
|
||||
{
|
||||
"key": "COLLECTION VARIABLE",
|
||||
"value": "collection variable",
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
}
|
||||
90
plugins/importer-postman/tests/fixtures/params.output.json
vendored
Normal file
90
plugins/importer-postman/tests/fixtures/params.output.json
vendored
Normal file
@@ -0,0 +1,90 @@
|
||||
{
|
||||
"resources": {
|
||||
"workspaces": [
|
||||
{
|
||||
"model": "workspace",
|
||||
"id": "GENERATE_ID::WORKSPACE_1",
|
||||
"name": "New Collection",
|
||||
"description": "",
|
||||
"variables": [
|
||||
{
|
||||
"name": "COLLECTION VARIABLE",
|
||||
"value": "collection variable"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"environments": [],
|
||||
"httpRequests": [
|
||||
{
|
||||
"model": "http_request",
|
||||
"id": "GENERATE_ID::HTTP_REQUEST_3",
|
||||
"workspaceId": "GENERATE_ID::WORKSPACE_1",
|
||||
"folderId": null,
|
||||
"name": "Form URL",
|
||||
"method": "POST",
|
||||
"url": "example.com/:foo/:bar",
|
||||
"urlParameters": [
|
||||
{
|
||||
"name": "disabled",
|
||||
"value": "secondvalue",
|
||||
"enabled": false
|
||||
},
|
||||
{
|
||||
"name": "q",
|
||||
"value": "qqq",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"name": "",
|
||||
"value": "",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"name": ":foo",
|
||||
"value": "fff",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"name": ":bar",
|
||||
"value": "bbb",
|
||||
"enabled": true
|
||||
}
|
||||
],
|
||||
"body": {
|
||||
"form": [
|
||||
{
|
||||
"enabled": true,
|
||||
"contentType": "Custom/COntent",
|
||||
"name": "Key",
|
||||
"file": "/Users/gschier/Desktop/Screenshot 2024-05-31 at 12.05.11 PM.png"
|
||||
}
|
||||
]
|
||||
},
|
||||
"bodyType": "multipart/form-data",
|
||||
"authentication": {
|
||||
"token": ""
|
||||
},
|
||||
"authenticationType": "bearer",
|
||||
"headers": [
|
||||
{
|
||||
"name": "X-foo",
|
||||
"value": "bar",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"name": "Disabled",
|
||||
"value": "tnroant",
|
||||
"enabled": false
|
||||
},
|
||||
{
|
||||
"name": "Content-Type",
|
||||
"value": "multipart/form-data",
|
||||
"enabled": true
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"folders": []
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Context, Model } from '@yaakapp/api';
|
||||
import { Context } from '@yaakapp/api';
|
||||
import * as fs from 'node:fs';
|
||||
import * as path from 'node:path';
|
||||
import { describe, expect, test } from 'vitest';
|
||||
@@ -11,71 +11,16 @@ describe('importer-postman', () => {
|
||||
const fixtures = fs.readdirSync(p);
|
||||
|
||||
for (const fixture of fixtures) {
|
||||
if (fixture.includes('.output')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
test('Imports ' + fixture, () => {
|
||||
const contents = fs.readFileSync(path.join(p, fixture), 'utf-8');
|
||||
const imported = pluginHookImport(ctx, contents);
|
||||
const folder0 = newId('folder');
|
||||
const folder1 = newId('folder');
|
||||
expect(imported).toEqual({
|
||||
resources: expect.objectContaining({
|
||||
workspaces: [
|
||||
expect.objectContaining({
|
||||
id: newId('workspace'),
|
||||
model: 'workspace',
|
||||
name: 'New Collection',
|
||||
}),
|
||||
],
|
||||
folders: expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
id: folder0,
|
||||
model: 'folder',
|
||||
workspaceId: existingId('workspace'),
|
||||
name: 'Top Folder',
|
||||
}),
|
||||
expect.objectContaining({
|
||||
folderId: folder0,
|
||||
id: folder1,
|
||||
model: 'folder',
|
||||
workspaceId: existingId('workspace'),
|
||||
name: 'Nested Folder',
|
||||
}),
|
||||
]),
|
||||
httpRequests: expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
id: newId('http_request'),
|
||||
model: 'http_request',
|
||||
name: 'Request 1',
|
||||
workspaceId: existingId('workspace'),
|
||||
folderId: folder1,
|
||||
}),
|
||||
expect.objectContaining({
|
||||
id: newId('http_request'),
|
||||
model: 'http_request',
|
||||
name: 'Request 2',
|
||||
workspaceId: existingId('workspace'),
|
||||
folderId: folder0,
|
||||
}),
|
||||
expect.objectContaining({
|
||||
id: newId('http_request'),
|
||||
model: 'http_request',
|
||||
name: 'Request 3',
|
||||
workspaceId: existingId('workspace'),
|
||||
folderId: null,
|
||||
}),
|
||||
]),
|
||||
}),
|
||||
});
|
||||
const expected = fs.readFileSync(path.join(p, fixture.replace('.input', '.output')), 'utf-8');
|
||||
const result = pluginHookImport(ctx, contents);
|
||||
// console.log(JSON.stringify(result, null, 2))
|
||||
expect(result).toEqual(JSON.parse(expected));
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
const idCount: Partial<Record<Model['model'], number>> = {};
|
||||
|
||||
function newId(model: Model['model']): string {
|
||||
idCount[model] = (idCount[model] ?? -1) + 1;
|
||||
return `GENERATE_ID::${model.toUpperCase()}_${idCount[model]}`;
|
||||
}
|
||||
|
||||
function existingId(model: Model['model']): string {
|
||||
return `GENERATE_ID::${model.toUpperCase()}_${idCount[model] ?? 0}`;
|
||||
}
|
||||
|
||||
@@ -10,13 +10,13 @@
|
||||
"dependencies": {
|
||||
"@xmldom/xmldom": "^0.8.10",
|
||||
"@yaakapp/api": "^0.1.14",
|
||||
"@yaakapp/cli": "^0.0.42",
|
||||
"jsonpath-plus": "^9.0.0",
|
||||
"xpath": "^0.0.34"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/jsonpath": "^0.2.4",
|
||||
"@types/node": "^20.14.9",
|
||||
"@yaakapp/cli": "^0.0.42",
|
||||
"typescript": "^5.5.2",
|
||||
"vitest": "^1.4.0"
|
||||
}
|
||||
@@ -766,6 +766,7 @@
|
||||
"version": "0.0.42",
|
||||
"resolved": "https://registry.npmjs.org/@yaakapp/cli/-/cli-0.0.42.tgz",
|
||||
"integrity": "sha512-HFkg49sksZNQQpnOgZGfyh8pmHbxtkgSNCeEMlaSFezq42YZPHxOPlqTEGxk3JqX6Asz0YO2xJDfUADQCyKNYA==",
|
||||
"dev": true,
|
||||
"hasInstallScript": true,
|
||||
"bin": {
|
||||
"yaakcli": "bin/cli.js"
|
||||
@@ -781,6 +782,7 @@
|
||||
"version": "0.0.42",
|
||||
"resolved": "https://registry.npmjs.org/@yaakapp/cli-darwin-arm64/-/cli-darwin-arm64-0.0.42.tgz",
|
||||
"integrity": "sha512-l8+N/9jwvAYlMQBPfGzNkVoQsYeBtwM3/7ix5b6mT+3zcwrNIDW9HQTEZ2ZTNdo1H548U1F6ppvhAyOdOtIyLg==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
@@ -790,6 +792,7 @@
|
||||
"version": "0.0.42",
|
||||
"resolved": "https://registry.npmjs.org/@yaakapp/cli-darwin-x64/-/cli-darwin-x64-0.0.42.tgz",
|
||||
"integrity": "sha512-grm9UOVCNIpHO3XsEzvvoic43cYCxmuvrUFP/8MZLQgZeQ5L6EBTAlCTtXD2hUGW60+kNNwcgPrDVVrP7Wn2YQ==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
@@ -799,6 +802,7 @@
|
||||
"version": "0.0.42",
|
||||
"resolved": "https://registry.npmjs.org/@yaakapp/cli-linux-x64/-/cli-linux-x64-0.0.42.tgz",
|
||||
"integrity": "sha512-O4ly25zR0BVIN0KxUcc7hmmcdNiRq4tQACuYNMIQ2ppFJYCguSMmGFdeJuyCfvcC/SwJIK6/Kzkr8EAmaTjDOA==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
@@ -808,6 +812,7 @@
|
||||
"version": "0.0.42",
|
||||
"resolved": "https://registry.npmjs.org/@yaakapp/cli-win32-x64/-/cli-win32-x64-0.0.42.tgz",
|
||||
"integrity": "sha512-40BTVcOBIP8VYwD1wfrr6tXG6NQuGz+XDA/ean4AWQWHi1P7BWHC9/uqHlMTLhFvbjcHjtwAl7bzVrXr37E0YQ==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
|
||||
Reference in New Issue
Block a user