mirror of
https://github.com/usebruno/bruno.git
synced 2026-06-22 04:05:42 +00:00
feat: changes to incorporate oc schema updates
This commit is contained in:
16
package-lock.json
generated
16
package-lock.json
generated
@@ -5669,13 +5669,6 @@
|
||||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/@opencollection/types": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@opencollection/types/-/types-0.1.0.tgz",
|
||||
"integrity": "sha512-/v64ShE+KyDUAfAlO6Qd5wBwPArd603VC44eife/CdmrtPUSIiFBYcZ9gxAD7LlW99J36wb5IkMpKFDvViINiA==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@parcel/watcher": {
|
||||
"version": "2.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.0.tgz",
|
||||
@@ -31912,7 +31905,7 @@
|
||||
"devDependencies": {
|
||||
"@babel/preset-env": "^7.22.0",
|
||||
"@babel/preset-typescript": "^7.22.0",
|
||||
"@opencollection/types": "0.1.0",
|
||||
"@opencollection/types": "0.2.0",
|
||||
"@rollup/plugin-commonjs": "^23.0.2",
|
||||
"@rollup/plugin-json": "^6.1.0",
|
||||
"@rollup/plugin-node-resolve": "^15.0.1",
|
||||
@@ -31932,6 +31925,13 @@
|
||||
"typescript": "^4.8.4"
|
||||
}
|
||||
},
|
||||
"packages/bruno-filestore/node_modules/@opencollection/types": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@opencollection/types/-/types-0.2.0.tgz",
|
||||
"integrity": "sha512-Lucjjoy+ZzfdjL0/9HF6PFlNSDG/m11VZBiR2K5XU6ChJ2XXfJyKocRB2g0tm7e5zQNMoVL3oUoDJ2gexx6xyg==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"packages/bruno-filestore/node_modules/@rollup/plugin-typescript": {
|
||||
"version": "12.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-12.3.0.tgz",
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
"devDependencies": {
|
||||
"@babel/preset-env": "^7.22.0",
|
||||
"@babel/preset-typescript": "^7.22.0",
|
||||
"@opencollection/types": "0.1.0",
|
||||
"@opencollection/types": "0.2.0",
|
||||
"@usebruno/schema-types": "0.0.1",
|
||||
"@rollup/plugin-commonjs": "^23.0.2",
|
||||
"@rollup/plugin-json": "^6.1.0",
|
||||
|
||||
@@ -163,7 +163,7 @@ const buildClientCredentialsFlow = (oauth: BrunoOAuth2): OAuth2ClientCredentials
|
||||
const buildResourceOwnerPasswordFlow = (oauth: BrunoOAuth2): OAuth2ResourceOwnerPasswordFlow => {
|
||||
const flow: OAuth2ResourceOwnerPasswordFlow = {
|
||||
type: 'oauth2',
|
||||
flow: 'resource_owner_password'
|
||||
flow: 'resource_owner_password_credentials'
|
||||
};
|
||||
|
||||
isNonEmptyString(oauth.accessTokenUrl) && (flow.accessTokenUrl = oauth.accessTokenUrl);
|
||||
@@ -394,7 +394,7 @@ export const toBrunoOAuth2 = (oauth: AuthOAuth2 | null | undefined): BrunoOAuth2
|
||||
}
|
||||
break;
|
||||
|
||||
case 'resource_owner_password':
|
||||
case 'resource_owner_password_credentials':
|
||||
brunoOAuth.grantType = 'password';
|
||||
if (oauth.accessTokenUrl) brunoOAuth.accessTokenUrl = oauth.accessTokenUrl;
|
||||
if (oauth.refreshTokenUrl) brunoOAuth.refreshTokenUrl = oauth.refreshTokenUrl;
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
import type { FolderRequest as BrunoFolderRequest } from '@usebruno/schema-types/collection/folder';
|
||||
import type { KeyValue as BrunoKeyValue } from '@usebruno/schema-types/common/key-value';
|
||||
import type { HttpHeader } from '@opencollection/types/requests/http';
|
||||
import type { HttpRequestHeader, HttpResponseHeader } from '@opencollection/types/requests/http';
|
||||
import { uuid } from '../../../utils';
|
||||
|
||||
export const toOpenCollectionHttpHeaders = (headers: BrunoFolderRequest['headers']): HttpHeader[] | undefined => {
|
||||
export const toOpenCollectionHttpHeaders = (headers: BrunoFolderRequest['headers']): HttpRequestHeader[] | undefined => {
|
||||
if (!headers?.length) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const ocHeaders = headers.map((header: BrunoKeyValue): HttpHeader => {
|
||||
const httpHeader: HttpHeader = {
|
||||
const ocHeaders = headers.map((header: BrunoKeyValue): HttpRequestHeader => {
|
||||
const httpHeader: HttpRequestHeader = {
|
||||
name: header.name || '',
|
||||
value: header.value || ''
|
||||
};
|
||||
@@ -25,17 +25,30 @@ export const toOpenCollectionHttpHeaders = (headers: BrunoFolderRequest['headers
|
||||
return ocHeaders.length ? ocHeaders : undefined;
|
||||
};
|
||||
|
||||
export const toBrunoHttpHeaders = (headers: HttpHeader[] | null | undefined): BrunoKeyValue[] | undefined => {
|
||||
export const toOpenCollectionResponseHeaders = (headers: BrunoFolderRequest['headers']): HttpResponseHeader[] | undefined => {
|
||||
if (!headers?.length) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const brunoHeaders = headers.map((header: HttpHeader): BrunoKeyValue => {
|
||||
const ocHeaders = headers.map((header: BrunoKeyValue): HttpResponseHeader => ({
|
||||
name: header.name || '',
|
||||
value: header.value || ''
|
||||
}));
|
||||
|
||||
return ocHeaders.length ? ocHeaders : undefined;
|
||||
};
|
||||
|
||||
export const toBrunoHttpHeaders = (headers: HttpRequestHeader[] | HttpResponseHeader[] | null | undefined): BrunoKeyValue[] | undefined => {
|
||||
if (!headers?.length) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const brunoHeaders = headers.map((header): BrunoKeyValue => {
|
||||
const brunoHeader: BrunoKeyValue = {
|
||||
uid: uuid(),
|
||||
name: header.name || '',
|
||||
value: header.value || '',
|
||||
enabled: header.disabled !== true
|
||||
enabled: ('disabled' in header) ? header.disabled !== true : true
|
||||
};
|
||||
|
||||
return brunoHeader;
|
||||
|
||||
@@ -1,30 +1,39 @@
|
||||
import { Scripts } from '@opencollection/types/common/scripts';
|
||||
import { FolderRequest as BrunoFolderRequest } from '@usebruno/schema-types/collection/folder';
|
||||
import { HttpRequest as BrunoHttpRequest } from '@usebruno/schema-types/requests/http';
|
||||
import { WebSocketRequest as BrunoWebSocketRequest } from '@usebruno/schema-types/requests/websocket';
|
||||
import { GrpcRequest as BrunoGrpcRequest } from '@usebruno/schema-types/requests/grpc';
|
||||
import type { Scripts, Script } from '@opencollection/types/common/scripts';
|
||||
import type { FolderRequest as BrunoFolderRequest } from '@usebruno/schema-types/collection/folder';
|
||||
import type { HttpRequest as BrunoHttpRequest } from '@usebruno/schema-types/requests/http';
|
||||
import type { WebSocketRequest as BrunoWebSocketRequest } from '@usebruno/schema-types/requests/websocket';
|
||||
import type { GrpcRequest as BrunoGrpcRequest } from '@usebruno/schema-types/requests/grpc';
|
||||
|
||||
export const toOpenCollectionScripts = (request: BrunoFolderRequest | BrunoHttpRequest | BrunoWebSocketRequest | BrunoGrpcRequest | null | undefined): Scripts | undefined => {
|
||||
const ocScripts: Scripts = {};
|
||||
const ocScripts: Scripts = [];
|
||||
|
||||
if (request?.script?.req?.trim().length) {
|
||||
ocScripts.preRequest = request.script.req.trim();
|
||||
ocScripts.push({
|
||||
type: 'before-request',
|
||||
code: request.script.req.trim()
|
||||
});
|
||||
}
|
||||
if (request?.script?.res?.trim().length) {
|
||||
ocScripts.postResponse = request.script.res.trim();
|
||||
ocScripts.push({
|
||||
type: 'after-response',
|
||||
code: request.script.res.trim()
|
||||
});
|
||||
}
|
||||
if (request?.tests?.trim().length) {
|
||||
ocScripts.tests = request.tests.trim();
|
||||
ocScripts.push({
|
||||
type: 'tests',
|
||||
code: request.tests.trim()
|
||||
});
|
||||
}
|
||||
|
||||
return Object.keys(ocScripts).length > 0 ? ocScripts : undefined;
|
||||
return ocScripts.length > 0 ? ocScripts : undefined;
|
||||
};
|
||||
|
||||
export const toBrunoScripts = (scripts: Scripts | null | undefined): {
|
||||
script?: { req?: string; res?: string };
|
||||
tests?: string;
|
||||
} | undefined => {
|
||||
if (!scripts) {
|
||||
if (!scripts || !Array.isArray(scripts) || scripts.length === 0) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@@ -33,18 +42,22 @@ export const toBrunoScripts = (scripts: Scripts | null | undefined): {
|
||||
tests?: string;
|
||||
} = {};
|
||||
|
||||
if (scripts.preRequest || scripts.postResponse) {
|
||||
brunoScripts.script = {};
|
||||
if (scripts.preRequest) {
|
||||
brunoScripts.script.req = scripts.preRequest;
|
||||
for (const script of scripts) {
|
||||
if (script.type === 'before-request' && script.code) {
|
||||
if (!brunoScripts.script) {
|
||||
brunoScripts.script = {};
|
||||
}
|
||||
brunoScripts.script.req = script.code;
|
||||
}
|
||||
if (scripts.postResponse) {
|
||||
brunoScripts.script.res = scripts.postResponse;
|
||||
if (script.type === 'after-response' && script.code) {
|
||||
if (!brunoScripts.script) {
|
||||
brunoScripts.script = {};
|
||||
}
|
||||
brunoScripts.script.res = script.code;
|
||||
}
|
||||
if (script.type === 'tests' && script.code) {
|
||||
brunoScripts.tests = script.code;
|
||||
}
|
||||
}
|
||||
|
||||
if (scripts.tests) {
|
||||
brunoScripts.tests = scripts.tests;
|
||||
}
|
||||
|
||||
return Object.keys(brunoScripts).length > 0 ? brunoScripts : undefined;
|
||||
|
||||
@@ -10,12 +10,16 @@ import { toBrunoAssertions } from '../common/assertions';
|
||||
import { uuid } from '../../../utils';
|
||||
|
||||
const parseGraphQLRequest = (ocRequest: GraphQLRequest): BrunoItem => {
|
||||
const info = ocRequest.info;
|
||||
const graphql = ocRequest.graphql;
|
||||
const runtime = ocRequest.runtime;
|
||||
|
||||
const brunoRequest: BrunoHttpRequest = {
|
||||
url: ocRequest.url || '',
|
||||
method: ocRequest.method || 'POST',
|
||||
headers: toBrunoHttpHeaders(ocRequest.headers) || [],
|
||||
params: toBrunoParams(ocRequest.params) || [],
|
||||
auth: toBrunoAuth(ocRequest.auth),
|
||||
url: graphql?.url || '',
|
||||
method: graphql?.method || 'POST',
|
||||
headers: toBrunoHttpHeaders(graphql?.headers) || [],
|
||||
params: toBrunoParams(graphql?.params) || [],
|
||||
auth: toBrunoAuth(runtime?.auth),
|
||||
body: {
|
||||
mode: 'graphql',
|
||||
json: null,
|
||||
@@ -25,8 +29,8 @@ const parseGraphQLRequest = (ocRequest: GraphQLRequest): BrunoItem => {
|
||||
formUrlEncoded: [],
|
||||
multipartForm: [],
|
||||
graphql: {
|
||||
query: (ocRequest.body as GraphQLBody)?.query || null,
|
||||
variables: (ocRequest.body as GraphQLBody)?.variables || null
|
||||
query: (graphql?.body as GraphQLBody)?.query || null,
|
||||
variables: (graphql?.body as GraphQLBody)?.variables || null
|
||||
},
|
||||
file: []
|
||||
},
|
||||
@@ -44,7 +48,7 @@ const parseGraphQLRequest = (ocRequest: GraphQLRequest): BrunoItem => {
|
||||
};
|
||||
|
||||
// scripts
|
||||
const scripts = toBrunoScripts(ocRequest.scripts);
|
||||
const scripts = toBrunoScripts(runtime?.scripts);
|
||||
if (scripts?.script && brunoRequest.script) {
|
||||
if (scripts.script.req) {
|
||||
brunoRequest.script.req = scripts.script.req;
|
||||
@@ -58,11 +62,11 @@ const parseGraphQLRequest = (ocRequest: GraphQLRequest): BrunoItem => {
|
||||
}
|
||||
|
||||
// variables
|
||||
const variables = toBrunoVariables(ocRequest.variables);
|
||||
const variables = toBrunoVariables(runtime?.variables);
|
||||
brunoRequest.vars = variables;
|
||||
|
||||
// assertions
|
||||
const assertions = toBrunoAssertions(ocRequest.assertions);
|
||||
const assertions = toBrunoAssertions(runtime?.assertions);
|
||||
if (assertions) {
|
||||
brunoRequest.assertions = assertions;
|
||||
}
|
||||
@@ -76,9 +80,9 @@ const parseGraphQLRequest = (ocRequest: GraphQLRequest): BrunoItem => {
|
||||
const brunoItem: BrunoItem = {
|
||||
uid: uuid(),
|
||||
type: 'graphql-request',
|
||||
seq: ocRequest.seq || 1,
|
||||
name: ocRequest.name || 'Untitled Request',
|
||||
tags: ocRequest.tags || [],
|
||||
seq: info?.seq || 1,
|
||||
name: info?.name || 'Untitled Request',
|
||||
tags: info?.tags || [],
|
||||
request: brunoRequest,
|
||||
settings: null,
|
||||
fileContent: null,
|
||||
|
||||
@@ -28,13 +28,17 @@ const toBrunoGrpcMetadata = (metadata: GrpcMetadata[] | null | undefined): Bruno
|
||||
};
|
||||
|
||||
const parseGrpcRequest = (ocRequest: GrpcRequest): BrunoItem => {
|
||||
const info = ocRequest.info;
|
||||
const grpc = ocRequest.grpc;
|
||||
const runtime = ocRequest.runtime;
|
||||
|
||||
const brunoRequest: BrunoGrpcRequest = {
|
||||
url: ocRequest.url || '',
|
||||
method: ocRequest.method || '',
|
||||
methodType: ocRequest.methodType || '',
|
||||
protoPath: ocRequest.protoFilePath || null,
|
||||
headers: toBrunoGrpcMetadata(ocRequest.metadata) || [],
|
||||
auth: toBrunoAuth(ocRequest.auth),
|
||||
url: grpc?.url || '',
|
||||
method: grpc?.method || '',
|
||||
methodType: grpc?.methodType || '',
|
||||
protoPath: grpc?.protoFilePath || null,
|
||||
headers: toBrunoGrpcMetadata(grpc?.metadata) || [],
|
||||
auth: toBrunoAuth(runtime?.auth),
|
||||
body: {
|
||||
mode: 'grpc',
|
||||
grpc: []
|
||||
@@ -53,15 +57,15 @@ const parseGrpcRequest = (ocRequest: GrpcRequest): BrunoItem => {
|
||||
};
|
||||
|
||||
// message
|
||||
if (isNonEmptyString(ocRequest.message)) {
|
||||
if (isNonEmptyString(grpc?.message)) {
|
||||
brunoRequest.body.grpc = [{
|
||||
name: '',
|
||||
content: ocRequest.message
|
||||
content: grpc?.message as string
|
||||
}];
|
||||
}
|
||||
|
||||
// scripts
|
||||
const scripts = toBrunoScripts(ocRequest.scripts);
|
||||
const scripts = toBrunoScripts(runtime?.scripts);
|
||||
if (scripts?.script && brunoRequest.script) {
|
||||
if (scripts.script.req) {
|
||||
brunoRequest.script.req = scripts.script.req;
|
||||
@@ -75,11 +79,11 @@ const parseGrpcRequest = (ocRequest: GrpcRequest): BrunoItem => {
|
||||
}
|
||||
|
||||
// variables
|
||||
const variables = toBrunoVariables(ocRequest.variables);
|
||||
const variables = toBrunoVariables(runtime?.variables);
|
||||
brunoRequest.vars = variables;
|
||||
|
||||
// assertions
|
||||
const assertions = toBrunoAssertions(ocRequest.assertions);
|
||||
const assertions = toBrunoAssertions(runtime?.assertions);
|
||||
if (assertions) {
|
||||
brunoRequest.assertions = assertions;
|
||||
}
|
||||
@@ -93,9 +97,9 @@ const parseGrpcRequest = (ocRequest: GrpcRequest): BrunoItem => {
|
||||
const brunoItem: BrunoItem = {
|
||||
uid: uuid(),
|
||||
type: 'grpc-request',
|
||||
seq: ocRequest.seq || 1,
|
||||
name: ocRequest.name || 'Untitled Request',
|
||||
tags: ocRequest.tags || [],
|
||||
seq: info?.seq || 1,
|
||||
name: info?.name || 'Untitled Request',
|
||||
tags: info?.tags || [],
|
||||
request: brunoRequest,
|
||||
settings: {},
|
||||
fileContent: null,
|
||||
|
||||
@@ -11,13 +11,17 @@ import { toBrunoAssertions } from '../common/assertions';
|
||||
import { uuid } from '../../../utils';
|
||||
|
||||
const parseHttpRequest = (ocRequest: HttpRequest): BrunoItem => {
|
||||
const info = ocRequest.info;
|
||||
const http = ocRequest.http;
|
||||
const runtime = ocRequest.runtime;
|
||||
|
||||
const brunoRequest: BrunoHttpRequest = {
|
||||
url: ocRequest.url || '',
|
||||
method: ocRequest.method || 'GET',
|
||||
headers: toBrunoHttpHeaders(ocRequest.headers) || [],
|
||||
params: toBrunoParams(ocRequest.params) || [],
|
||||
auth: toBrunoAuth(ocRequest.auth),
|
||||
body: toBrunoBody(ocRequest.body as HttpRequestBody) || {
|
||||
url: http?.url || '',
|
||||
method: http?.method || 'GET',
|
||||
headers: toBrunoHttpHeaders(http?.headers) || [],
|
||||
params: toBrunoParams(http?.params) || [],
|
||||
auth: toBrunoAuth(runtime?.auth),
|
||||
body: toBrunoBody(http?.body as HttpRequestBody) || {
|
||||
mode: 'none',
|
||||
json: null,
|
||||
text: null,
|
||||
@@ -42,7 +46,7 @@ const parseHttpRequest = (ocRequest: HttpRequest): BrunoItem => {
|
||||
};
|
||||
|
||||
// scripts
|
||||
const scripts = toBrunoScripts(ocRequest.scripts);
|
||||
const scripts = toBrunoScripts(runtime?.scripts);
|
||||
if (scripts?.script && brunoRequest.script) {
|
||||
if (scripts.script.req) {
|
||||
brunoRequest.script.req = scripts.script.req;
|
||||
@@ -56,11 +60,11 @@ const parseHttpRequest = (ocRequest: HttpRequest): BrunoItem => {
|
||||
}
|
||||
|
||||
// variables
|
||||
const variables = toBrunoVariables(ocRequest.variables);
|
||||
const variables = toBrunoVariables(runtime?.variables);
|
||||
brunoRequest.vars = variables;
|
||||
|
||||
// assertions
|
||||
const assertions = toBrunoAssertions(ocRequest.assertions);
|
||||
const assertions = toBrunoAssertions(runtime?.assertions);
|
||||
if (assertions) {
|
||||
brunoRequest.assertions = assertions;
|
||||
}
|
||||
@@ -74,9 +78,9 @@ const parseHttpRequest = (ocRequest: HttpRequest): BrunoItem => {
|
||||
const brunoItem: BrunoItem = {
|
||||
uid: uuid(),
|
||||
type: 'http-request',
|
||||
seq: ocRequest.seq || 1,
|
||||
name: ocRequest.name || 'Untitled Request',
|
||||
tags: ocRequest.tags || [],
|
||||
seq: info?.seq || 1,
|
||||
name: info?.name || 'Untitled Request',
|
||||
tags: info?.tags || [],
|
||||
request: brunoRequest,
|
||||
settings: null,
|
||||
fileContent: null,
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import type { Item as BrunoItem } from '@usebruno/schema-types/collection/item';
|
||||
import type { Script } from '@opencollection/types/collection/item';
|
||||
import type { ScriptFile } from '@opencollection/types/collection/item';
|
||||
import { uuid } from '../../../utils';
|
||||
|
||||
const parseScript = (ocScript: Script): BrunoItem => {
|
||||
const parseScript = (ocScript: ScriptFile): BrunoItem => {
|
||||
const brunoItem: BrunoItem = {
|
||||
uid: uuid(),
|
||||
type: 'js',
|
||||
|
||||
@@ -15,10 +15,14 @@ interface WebSocketRequestWithSettings extends WebSocketRequest {
|
||||
}
|
||||
|
||||
const parseWebsocketRequest = (ocRequest: WebSocketRequestWithSettings): BrunoItem => {
|
||||
const info = ocRequest.info;
|
||||
const websocket = ocRequest.websocket;
|
||||
const runtime = ocRequest.runtime;
|
||||
|
||||
const brunoRequest: BrunoWebSocketRequest = {
|
||||
url: ocRequest.url || '',
|
||||
headers: toBrunoHttpHeaders(ocRequest.headers) || [],
|
||||
auth: toBrunoAuth(ocRequest.auth),
|
||||
url: websocket?.url || '',
|
||||
headers: toBrunoHttpHeaders(websocket?.headers) || [],
|
||||
auth: toBrunoAuth(runtime?.auth),
|
||||
body: {
|
||||
mode: 'ws',
|
||||
ws: []
|
||||
@@ -37,8 +41,8 @@ const parseWebsocketRequest = (ocRequest: WebSocketRequestWithSettings): BrunoIt
|
||||
};
|
||||
|
||||
// message
|
||||
if (ocRequest.message) {
|
||||
const message = ocRequest.message as WebSocketMessage;
|
||||
if (websocket?.message) {
|
||||
const message = websocket.message as WebSocketMessage;
|
||||
if (message.data?.trim().length) {
|
||||
brunoRequest.body.ws = [{
|
||||
name: '',
|
||||
@@ -49,7 +53,7 @@ const parseWebsocketRequest = (ocRequest: WebSocketRequestWithSettings): BrunoIt
|
||||
}
|
||||
|
||||
// scripts
|
||||
const scripts = toBrunoScripts(ocRequest.scripts);
|
||||
const scripts = toBrunoScripts(runtime?.scripts);
|
||||
if (scripts?.script && brunoRequest.script) {
|
||||
if (scripts.script.req) {
|
||||
brunoRequest.script.req = scripts.script.req;
|
||||
@@ -63,7 +67,7 @@ const parseWebsocketRequest = (ocRequest: WebSocketRequestWithSettings): BrunoIt
|
||||
}
|
||||
|
||||
// variables
|
||||
const variables = toBrunoVariables(ocRequest.variables);
|
||||
const variables = toBrunoVariables(runtime?.variables);
|
||||
brunoRequest.vars = variables;
|
||||
|
||||
// docs
|
||||
@@ -90,9 +94,9 @@ const parseWebsocketRequest = (ocRequest: WebSocketRequestWithSettings): BrunoIt
|
||||
const brunoItem: BrunoItem = {
|
||||
uid: uuid(),
|
||||
type: 'ws-request',
|
||||
seq: ocRequest.seq || 1,
|
||||
name: ocRequest.name || 'Untitled Request',
|
||||
tags: ocRequest.tags || [],
|
||||
seq: info?.seq || 1,
|
||||
name: info?.name || 'Untitled Request',
|
||||
tags: info?.tags || [],
|
||||
request: brunoRequest,
|
||||
settings: wsSettings as any,
|
||||
fileContent: null,
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import type { Item as BrunoItem, HttpItemSettings as BrunoHttpItemSettings } from '@usebruno/schema-types/collection/item';
|
||||
import type { HttpRequest as BrunoHttpRequest } from '@usebruno/schema-types/requests/http';
|
||||
import type { GraphQLRequest, GraphQLRequestSettings, GraphQLBody } from '@opencollection/types/requests/graphql';
|
||||
import type { GraphQLRequest, GraphQLRequestSettings, GraphQLBody, GraphQLRequestInfo, GraphQLRequestDetails, GraphQLRequestRuntime } from '@opencollection/types/requests/graphql';
|
||||
import type { Auth } from '@opencollection/types/common/auth';
|
||||
import type { Scripts } from '@opencollection/types/common/scripts';
|
||||
import type { Variable } from '@opencollection/types/common/variables';
|
||||
import type { Assertion } from '@opencollection/types/common/assertions';
|
||||
import type { HttpRequestParam, HttpHeader } from '@opencollection/types/requests/http';
|
||||
import type { HttpRequestParam, HttpRequestHeader } from '@opencollection/types/requests/http';
|
||||
import { stringifyYml } from '../utils';
|
||||
import { isNonEmptyString, isNumber } from '../../../utils';
|
||||
import { toOpenCollectionAuth } from '../common/auth';
|
||||
@@ -17,32 +17,38 @@ import { toOpenCollectionAssertions } from '../common/assertions';
|
||||
|
||||
const stringifyGraphQLRequest = (item: BrunoItem): string => {
|
||||
try {
|
||||
const ocRequest: GraphQLRequest = {
|
||||
const ocRequest: GraphQLRequest = {};
|
||||
const brunoRequest = item.request as BrunoHttpRequest;
|
||||
|
||||
// info block
|
||||
const info: GraphQLRequestInfo = {
|
||||
name: isNonEmptyString(item.name) ? item.name : 'Untitled Request',
|
||||
type: 'graphql'
|
||||
};
|
||||
|
||||
ocRequest.name = isNonEmptyString(item.name) ? item.name : 'Untitled Request';
|
||||
|
||||
// sequence
|
||||
if (item.seq) {
|
||||
ocRequest.seq = item.seq;
|
||||
info.seq = item.seq;
|
||||
}
|
||||
if (item.tags?.length) {
|
||||
info.tags = item.tags;
|
||||
}
|
||||
ocRequest.info = info;
|
||||
|
||||
const brunoRequest = item.request as BrunoHttpRequest;
|
||||
// url and method
|
||||
ocRequest.url = isNonEmptyString(brunoRequest.url) ? brunoRequest.url : '';
|
||||
ocRequest.method = isNonEmptyString(brunoRequest.method) ? brunoRequest.method : 'POST';
|
||||
// graphql block
|
||||
const graphql: GraphQLRequestDetails = {
|
||||
method: isNonEmptyString(brunoRequest.method) ? brunoRequest.method : 'POST',
|
||||
url: isNonEmptyString(brunoRequest.url) ? brunoRequest.url : ''
|
||||
};
|
||||
|
||||
// headers
|
||||
const headers: HttpHeader[] | undefined = toOpenCollectionHttpHeaders(brunoRequest.headers);
|
||||
const headers: HttpRequestHeader[] | undefined = toOpenCollectionHttpHeaders(brunoRequest.headers);
|
||||
if (headers) {
|
||||
ocRequest.headers = headers;
|
||||
graphql.headers = headers;
|
||||
}
|
||||
|
||||
// params
|
||||
const params: HttpRequestParam[] | undefined = toOpenCollectionParams(brunoRequest.params);
|
||||
if (params) {
|
||||
ocRequest.params = params;
|
||||
graphql.params = params;
|
||||
}
|
||||
|
||||
// body
|
||||
@@ -61,83 +67,86 @@ const stringifyGraphQLRequest = (item: BrunoItem): string => {
|
||||
}
|
||||
|
||||
if (hasBody) {
|
||||
ocRequest.body = graphqlBody;
|
||||
graphql.body = graphqlBody;
|
||||
}
|
||||
}
|
||||
|
||||
// auth
|
||||
const auth: Auth | undefined = toOpenCollectionAuth(brunoRequest.auth);
|
||||
if (auth) {
|
||||
ocRequest.auth = auth;
|
||||
ocRequest.graphql = graphql;
|
||||
|
||||
// runtime block
|
||||
const runtime: GraphQLRequestRuntime = {};
|
||||
let hasRuntime = false;
|
||||
|
||||
// variables
|
||||
const variables: Variable[] | undefined = toOpenCollectionVariables(brunoRequest.vars);
|
||||
if (variables) {
|
||||
runtime.variables = variables;
|
||||
hasRuntime = true;
|
||||
}
|
||||
|
||||
// scripts
|
||||
const scripts: Scripts | undefined = toOpenCollectionScripts(brunoRequest);
|
||||
if (scripts) {
|
||||
ocRequest.scripts = scripts;
|
||||
}
|
||||
|
||||
// variables
|
||||
const variables: Variable[] | undefined = toOpenCollectionVariables(brunoRequest.vars);
|
||||
if (variables) {
|
||||
ocRequest.variables = variables;
|
||||
runtime.scripts = scripts;
|
||||
hasRuntime = true;
|
||||
}
|
||||
|
||||
// assertions
|
||||
const assertions: Assertion[] | undefined = toOpenCollectionAssertions(brunoRequest.assertions);
|
||||
if (assertions) {
|
||||
ocRequest.assertions = assertions;
|
||||
runtime.assertions = assertions;
|
||||
hasRuntime = true;
|
||||
}
|
||||
|
||||
// docs
|
||||
if (isNonEmptyString(brunoRequest.docs)) {
|
||||
ocRequest.docs = brunoRequest.docs;
|
||||
// auth
|
||||
const auth: Auth | undefined = toOpenCollectionAuth(brunoRequest.auth);
|
||||
if (auth) {
|
||||
runtime.auth = auth;
|
||||
hasRuntime = true;
|
||||
}
|
||||
|
||||
if (hasRuntime) {
|
||||
ocRequest.runtime = runtime;
|
||||
}
|
||||
|
||||
// settings
|
||||
const httpSettings = item.settings as BrunoHttpItemSettings | undefined;
|
||||
ocRequest.settings = {} as GraphQLRequestSettings;
|
||||
const settings: GraphQLRequestSettings = {};
|
||||
if (httpSettings?.encodeUrl === true) {
|
||||
ocRequest.settings.encodeUrl = true;
|
||||
settings.encodeUrl = true;
|
||||
} else if (httpSettings?.encodeUrl === false) {
|
||||
ocRequest.settings.encodeUrl = false;
|
||||
settings.encodeUrl = false;
|
||||
} else {
|
||||
// todo: we are defaulting to true for now as bruno config does not yet support inherit for encodeUrl
|
||||
// update this when bruno config supports inherit for encodeUrl
|
||||
ocRequest.settings.encodeUrl = true;
|
||||
settings.encodeUrl = true;
|
||||
}
|
||||
|
||||
const timeout = httpSettings?.timeout;
|
||||
if (isNumber(timeout)) {
|
||||
ocRequest.settings.timeout = timeout;
|
||||
settings.timeout = timeout;
|
||||
} else {
|
||||
// todo: we are defaulting to 0 for now as bruno config does not yet support inherit for timeout
|
||||
// update this when bruno config supports inherit for timeout
|
||||
ocRequest.settings.timeout = 0;
|
||||
settings.timeout = 0;
|
||||
}
|
||||
|
||||
if (httpSettings?.followRedirects === true) {
|
||||
ocRequest.settings.followRedirects = true;
|
||||
settings.followRedirects = true;
|
||||
} else if (httpSettings?.followRedirects === false) {
|
||||
ocRequest.settings.followRedirects = false;
|
||||
settings.followRedirects = false;
|
||||
} else {
|
||||
// todo: we are defaulting to true for now as bruno config does not yet support inherit for followRedirects
|
||||
// update this when bruno config supports inherit for followRedirects
|
||||
ocRequest.settings.followRedirects = true;
|
||||
settings.followRedirects = true;
|
||||
}
|
||||
|
||||
const maxRedirects = httpSettings?.maxRedirects;
|
||||
if (isNumber(maxRedirects)) {
|
||||
ocRequest.settings.maxRedirects = maxRedirects;
|
||||
settings.maxRedirects = maxRedirects;
|
||||
} else {
|
||||
// todo: we are defaulting to 5 for now as bruno config does not yet support inherit for maxRedirects
|
||||
// update this when bruno config supports inherit for maxRedirects
|
||||
ocRequest.settings.maxRedirects = 5;
|
||||
settings.maxRedirects = 5;
|
||||
}
|
||||
|
||||
// tags
|
||||
if (item.tags?.length) {
|
||||
ocRequest.tags = item.tags;
|
||||
ocRequest.settings = settings;
|
||||
|
||||
// docs
|
||||
if (isNonEmptyString(brunoRequest.docs)) {
|
||||
ocRequest.docs = brunoRequest.docs;
|
||||
}
|
||||
|
||||
return stringifyYml(ocRequest);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import type { Item as BrunoItem } from '@usebruno/schema-types/collection/item';
|
||||
import type { KeyValue as BrunoKeyValue } from '@usebruno/schema-types/common/key-value';
|
||||
import type { GrpcRequest as BrunoGrpcRequest } from '@usebruno/schema-types/requests/grpc';
|
||||
import type { GrpcRequest, GrpcMetadata, GrpcMessage, GrpcMessageVariant } from '@opencollection/types/requests/grpc';
|
||||
import type { GrpcRequest, GrpcMetadata, GrpcMessage, GrpcRequestInfo, GrpcRequestDetails, GrpcRequestRuntime } from '@opencollection/types/requests/grpc';
|
||||
import type { Auth } from '@opencollection/types/common/auth';
|
||||
import type { Scripts } from '@opencollection/types/common/scripts';
|
||||
import type { Variable } from '@opencollection/types/common/variables';
|
||||
@@ -15,30 +15,36 @@ import { toOpenCollectionAssertions } from '../common/assertions';
|
||||
|
||||
const stringifyGrpcRequest = (item: BrunoItem): string => {
|
||||
try {
|
||||
const ocRequest: GrpcRequest = {
|
||||
const ocRequest: GrpcRequest = {};
|
||||
const brunoRequest = item.request as BrunoGrpcRequest;
|
||||
|
||||
// info block
|
||||
const info: GrpcRequestInfo = {
|
||||
name: isNonEmptyString(item.name) ? item.name : 'Untitled Request',
|
||||
type: 'grpc'
|
||||
};
|
||||
|
||||
ocRequest.name = isNonEmptyString(item.name) ? item.name : 'Untitled Request';
|
||||
|
||||
// sequence
|
||||
if (item.seq) {
|
||||
ocRequest.seq = item.seq;
|
||||
info.seq = item.seq;
|
||||
}
|
||||
if (item.tags?.length) {
|
||||
info.tags = item.tags;
|
||||
}
|
||||
ocRequest.info = info;
|
||||
|
||||
const brunoRequest = item.request as BrunoGrpcRequest;
|
||||
// url and method
|
||||
ocRequest.url = isNonEmptyString(brunoRequest.url) ? brunoRequest.url : '';
|
||||
ocRequest.method = isNonEmptyString(brunoRequest.method) ? brunoRequest.method : '';
|
||||
// grpc block
|
||||
const grpc: GrpcRequestDetails = {
|
||||
url: isNonEmptyString(brunoRequest.url) ? brunoRequest.url : '',
|
||||
method: isNonEmptyString(brunoRequest.method) ? brunoRequest.method : ''
|
||||
};
|
||||
|
||||
// method type
|
||||
if (brunoRequest.methodType) {
|
||||
ocRequest.methodType = brunoRequest.methodType;
|
||||
grpc.methodType = brunoRequest.methodType;
|
||||
}
|
||||
|
||||
// proto file path
|
||||
if (isNonEmptyString(brunoRequest.protoPath)) {
|
||||
ocRequest.protoFilePath = brunoRequest.protoPath;
|
||||
grpc.protoFilePath = brunoRequest.protoPath;
|
||||
}
|
||||
|
||||
// metadata
|
||||
@@ -61,7 +67,7 @@ const stringifyGrpcRequest = (item: BrunoItem): string => {
|
||||
});
|
||||
|
||||
if (metadata.length) {
|
||||
ocRequest.metadata = metadata;
|
||||
grpc.metadata = metadata;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,33 +80,47 @@ const stringifyGrpcRequest = (item: BrunoItem): string => {
|
||||
if (messages.length) {
|
||||
const message: GrpcMessage = messages[0].content || '';
|
||||
if (message.trim().length) {
|
||||
ocRequest.message = message;
|
||||
grpc.message = message;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// auth
|
||||
const auth: Auth | undefined = toOpenCollectionAuth(brunoRequest.auth);
|
||||
if (auth) {
|
||||
ocRequest.auth = auth;
|
||||
ocRequest.grpc = grpc;
|
||||
|
||||
// runtime block
|
||||
const runtime: GrpcRequestRuntime = {};
|
||||
let hasRuntime = false;
|
||||
|
||||
// variables
|
||||
const variables: Variable[] | undefined = toOpenCollectionVariables(brunoRequest.vars);
|
||||
if (variables) {
|
||||
runtime.variables = variables;
|
||||
hasRuntime = true;
|
||||
}
|
||||
|
||||
// scripts
|
||||
const scripts: Scripts | undefined = toOpenCollectionScripts(brunoRequest);
|
||||
if (scripts) {
|
||||
ocRequest.scripts = scripts;
|
||||
}
|
||||
|
||||
// variables
|
||||
const variables: Variable[] | undefined = toOpenCollectionVariables(brunoRequest.vars);
|
||||
if (variables) {
|
||||
ocRequest.variables = variables;
|
||||
runtime.scripts = scripts;
|
||||
hasRuntime = true;
|
||||
}
|
||||
|
||||
// assertions
|
||||
const assertions: Assertion[] | undefined = toOpenCollectionAssertions(brunoRequest.assertions);
|
||||
if (assertions) {
|
||||
ocRequest.assertions = assertions;
|
||||
runtime.assertions = assertions;
|
||||
hasRuntime = true;
|
||||
}
|
||||
|
||||
// auth
|
||||
const auth: Auth | undefined = toOpenCollectionAuth(brunoRequest.auth);
|
||||
if (auth) {
|
||||
runtime.auth = auth;
|
||||
hasRuntime = true;
|
||||
}
|
||||
|
||||
if (hasRuntime) {
|
||||
ocRequest.runtime = runtime;
|
||||
}
|
||||
|
||||
// docs
|
||||
@@ -108,11 +128,6 @@ const stringifyGrpcRequest = (item: BrunoItem): string => {
|
||||
ocRequest.docs = brunoRequest.docs;
|
||||
}
|
||||
|
||||
// tags
|
||||
if (item.tags?.length) {
|
||||
ocRequest.tags = item.tags;
|
||||
}
|
||||
|
||||
return stringifyYml(ocRequest);
|
||||
} catch (error) {
|
||||
console.error('Error stringifying gRPC request:', error);
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import type { Item as BrunoItem, HttpItemSettings as BrunoHttpItemSettings } from '@usebruno/schema-types/collection/item';
|
||||
import type { HttpRequest as BrunoHttpRequest } from '@usebruno/schema-types/requests/http';
|
||||
import type { HttpRequest, HttpRequestSettings, HttpRequestExample } from '@opencollection/types/requests/http';
|
||||
import type { HttpRequest, HttpRequestSettings, HttpRequestExample, HttpRequestInfo, HttpRequestDetails, HttpRequestRuntime, HttpRequestHeader } from '@opencollection/types/requests/http';
|
||||
import type { Auth } from '@opencollection/types/common/auth';
|
||||
import type { Scripts } from '@opencollection/types/common/scripts';
|
||||
import type { Variable } from '@opencollection/types/common/variables';
|
||||
import type { Assertion } from '@opencollection/types/common/assertions';
|
||||
import type { HttpRequestParam, HttpHeader, HttpRequestBody } from '@opencollection/types/requests/http';
|
||||
import type { HttpRequestParam, HttpRequestBody } from '@opencollection/types/requests/http';
|
||||
import { stringifyYml } from '../utils';
|
||||
import { toOpenCollectionAuth } from '../common/auth';
|
||||
import { toOpenCollectionHttpHeaders } from '../common/headers';
|
||||
import { toOpenCollectionHttpHeaders, toOpenCollectionResponseHeaders } from '../common/headers';
|
||||
import { toOpenCollectionParams } from '../common/params';
|
||||
import { toOpenCollectionBody } from '../common/body';
|
||||
import { toOpenCollectionVariables } from '../common/variables';
|
||||
@@ -18,114 +18,118 @@ import { isNumber, isNonEmptyString } from '../../../utils';
|
||||
|
||||
const stringifyHttpRequest = (item: BrunoItem): string => {
|
||||
try {
|
||||
const ocRequest: HttpRequest = {
|
||||
const ocRequest: HttpRequest = {};
|
||||
const brunoRequest = item.request as BrunoHttpRequest;
|
||||
|
||||
// info block
|
||||
const info: HttpRequestInfo = {
|
||||
name: isNonEmptyString(item.name) ? item.name : 'Untitled Request',
|
||||
type: 'http'
|
||||
};
|
||||
|
||||
ocRequest.name = isNonEmptyString(item.name) ? item.name : 'Untitled Request';
|
||||
|
||||
// sequence
|
||||
if (item.seq) {
|
||||
ocRequest.seq = item.seq;
|
||||
info.seq = item.seq;
|
||||
}
|
||||
if (item.tags?.length) {
|
||||
info.tags = item.tags;
|
||||
}
|
||||
ocRequest.info = info;
|
||||
|
||||
const brunoRequest = item.request as BrunoHttpRequest;
|
||||
// url and method
|
||||
ocRequest.url = isNonEmptyString(brunoRequest.url) ? brunoRequest.url : '';
|
||||
ocRequest.method = isNonEmptyString(brunoRequest.method) ? brunoRequest.method : 'GET';
|
||||
// http block
|
||||
const http: HttpRequestDetails = {
|
||||
method: isNonEmptyString(brunoRequest.method) ? brunoRequest.method : 'GET',
|
||||
url: isNonEmptyString(brunoRequest.url) ? brunoRequest.url : ''
|
||||
};
|
||||
|
||||
// headers
|
||||
const headers: HttpHeader[] | undefined = toOpenCollectionHttpHeaders(brunoRequest.headers);
|
||||
const headers: HttpRequestHeader[] | undefined = toOpenCollectionHttpHeaders(brunoRequest.headers);
|
||||
if (headers) {
|
||||
ocRequest.headers = headers;
|
||||
http.headers = headers;
|
||||
}
|
||||
|
||||
// params
|
||||
const params: HttpRequestParam[] | undefined = toOpenCollectionParams(brunoRequest.params);
|
||||
if (params) {
|
||||
ocRequest.params = params;
|
||||
http.params = params;
|
||||
}
|
||||
|
||||
// body
|
||||
const body: HttpRequestBody | undefined = toOpenCollectionBody(brunoRequest.body);
|
||||
if (body) {
|
||||
ocRequest.body = body;
|
||||
http.body = body;
|
||||
}
|
||||
|
||||
// auth
|
||||
const auth: Auth | undefined = toOpenCollectionAuth(brunoRequest.auth);
|
||||
if (auth) {
|
||||
ocRequest.auth = auth;
|
||||
ocRequest.http = http;
|
||||
|
||||
// runtime block
|
||||
const runtime: HttpRequestRuntime = {};
|
||||
let hasRuntime = false;
|
||||
|
||||
// variables
|
||||
const variables: Variable[] | undefined = toOpenCollectionVariables(brunoRequest.vars);
|
||||
if (variables) {
|
||||
runtime.variables = variables;
|
||||
hasRuntime = true;
|
||||
}
|
||||
|
||||
// scripts
|
||||
const scripts: Scripts | undefined = toOpenCollectionScripts(brunoRequest);
|
||||
if (scripts) {
|
||||
ocRequest.scripts = scripts;
|
||||
}
|
||||
|
||||
// variables
|
||||
const variables: Variable[] | undefined = toOpenCollectionVariables(brunoRequest.vars);
|
||||
if (variables) {
|
||||
ocRequest.variables = variables;
|
||||
runtime.scripts = scripts;
|
||||
hasRuntime = true;
|
||||
}
|
||||
|
||||
// assertions
|
||||
const assertions: Assertion[] | undefined = toOpenCollectionAssertions(brunoRequest.assertions);
|
||||
if (assertions) {
|
||||
ocRequest.assertions = assertions;
|
||||
runtime.assertions = assertions;
|
||||
hasRuntime = true;
|
||||
}
|
||||
|
||||
// docs
|
||||
if (isNonEmptyString(brunoRequest.docs)) {
|
||||
ocRequest.docs = brunoRequest.docs;
|
||||
// auth
|
||||
const auth: Auth | undefined = toOpenCollectionAuth(brunoRequest.auth);
|
||||
if (auth) {
|
||||
runtime.auth = auth;
|
||||
hasRuntime = true;
|
||||
}
|
||||
|
||||
if (hasRuntime) {
|
||||
ocRequest.runtime = runtime;
|
||||
}
|
||||
|
||||
// settings
|
||||
const httpSettings = item.settings as BrunoHttpItemSettings | undefined;
|
||||
ocRequest.settings = {} as HttpRequestSettings;
|
||||
const settings: HttpRequestSettings = {};
|
||||
if (httpSettings?.encodeUrl === true) {
|
||||
ocRequest.settings.encodeUrl = true;
|
||||
settings.encodeUrl = true;
|
||||
} else if (httpSettings?.encodeUrl === false) {
|
||||
ocRequest.settings.encodeUrl = false;
|
||||
settings.encodeUrl = false;
|
||||
} else {
|
||||
// todo: we are defaulting to true for now as bruno config does not yet support inherit for encodeUrl
|
||||
// update this when bruno config supports inherit for encodeUrl
|
||||
ocRequest.settings.encodeUrl = true;
|
||||
settings.encodeUrl = true;
|
||||
}
|
||||
|
||||
const timeout = httpSettings?.timeout;
|
||||
if (isNumber(timeout)) {
|
||||
ocRequest.settings.timeout = timeout;
|
||||
settings.timeout = timeout;
|
||||
} else {
|
||||
// todo: we are defaulting to 0 for now as bruno config does not yet support inherit for timeout
|
||||
// update this when bruno config supports inherit for timeout
|
||||
ocRequest.settings.timeout = 0;
|
||||
settings.timeout = 0;
|
||||
}
|
||||
|
||||
if (httpSettings?.followRedirects === true) {
|
||||
ocRequest.settings.followRedirects = true;
|
||||
settings.followRedirects = true;
|
||||
} else if (httpSettings?.followRedirects === false) {
|
||||
ocRequest.settings.followRedirects = false;
|
||||
settings.followRedirects = false;
|
||||
} else {
|
||||
// todo: we are defaulting to true for now as bruno config does not yet support inherit for followRedirects
|
||||
// update this when bruno config supports inherit for followRedirects
|
||||
ocRequest.settings.followRedirects = true;
|
||||
settings.followRedirects = true;
|
||||
}
|
||||
|
||||
const maxRedirects = httpSettings?.maxRedirects;
|
||||
if (isNumber(maxRedirects)) {
|
||||
ocRequest.settings.maxRedirects = maxRedirects;
|
||||
settings.maxRedirects = maxRedirects;
|
||||
} else {
|
||||
// todo: we are defaulting to 5 for now as bruno config does not yet support inherit for maxRedirects
|
||||
// update this when bruno config supports inherit for maxRedirects
|
||||
ocRequest.settings.maxRedirects = 5;
|
||||
settings.maxRedirects = 5;
|
||||
}
|
||||
|
||||
// tags
|
||||
if (item.tags?.length) {
|
||||
ocRequest.tags = item.tags;
|
||||
}
|
||||
ocRequest.settings = settings;
|
||||
|
||||
// examples
|
||||
if (item.examples?.length) {
|
||||
@@ -169,7 +173,7 @@ const stringifyHttpRequest = (item: BrunoItem): string => {
|
||||
ocExample.response.statusText = example.response.statusText;
|
||||
}
|
||||
|
||||
const responseHeaders = toOpenCollectionHttpHeaders(example.response.headers);
|
||||
const responseHeaders = toOpenCollectionResponseHeaders(example.response.headers);
|
||||
if (responseHeaders) {
|
||||
ocExample.response.headers = responseHeaders;
|
||||
}
|
||||
@@ -185,12 +189,16 @@ const stringifyHttpRequest = (item: BrunoItem): string => {
|
||||
return ocExample;
|
||||
});
|
||||
|
||||
// examples
|
||||
if (examples?.length) {
|
||||
ocRequest.examples = examples;
|
||||
}
|
||||
}
|
||||
|
||||
// docs
|
||||
if (isNonEmptyString(brunoRequest.docs)) {
|
||||
ocRequest.docs = brunoRequest.docs;
|
||||
}
|
||||
|
||||
return stringifyYml(ocRequest);
|
||||
} catch (error) {
|
||||
console.error('Error stringifying HTTP request:', error);
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import type { Item as BrunoItem } from '@usebruno/schema-types/collection/item';
|
||||
import type { Script } from '@opencollection/types/collection/item';
|
||||
import type { ScriptFile } from '@opencollection/types/collection/item';
|
||||
import { stringifyYml } from '../utils';
|
||||
|
||||
const stringifyScript = (item: BrunoItem): string => {
|
||||
try {
|
||||
const ocScript: Script = {
|
||||
const ocScript: ScriptFile = {
|
||||
type: 'script'
|
||||
};
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import type { Item as BrunoItem } from '@usebruno/schema-types/collection/item';
|
||||
import type { WebSocketRequest as BrunoWebSocketRequest } from '@usebruno/schema-types/requests/websocket';
|
||||
import type { WebSocketRequest, WebSocketMessage, WebSocketMessageVariant } from '@opencollection/types/requests/websocket';
|
||||
import type { WebSocketRequest, WebSocketMessage, WebSocketRequestInfo, WebSocketRequestDetails, WebSocketRequestRuntime } from '@opencollection/types/requests/websocket';
|
||||
import type { Auth } from '@opencollection/types/common/auth';
|
||||
import type { Scripts } from '@opencollection/types/common/scripts';
|
||||
import type { Variable } from '@opencollection/types/common/variables';
|
||||
import type { HttpHeader } from '@opencollection/types/requests/http';
|
||||
import type { HttpRequestHeader } from '@opencollection/types/requests/http';
|
||||
import { stringifyYml } from '../utils';
|
||||
import { isNonEmptyString } from '../../../utils';
|
||||
import { toOpenCollectionAuth } from '../common/auth';
|
||||
@@ -21,25 +21,31 @@ interface WebSocketRequestWithSettings extends WebSocketRequest {
|
||||
|
||||
const stringifyWebsocketRequest = (item: BrunoItem): string => {
|
||||
try {
|
||||
const ocRequest: WebSocketRequestWithSettings = {
|
||||
const ocRequest: WebSocketRequestWithSettings = {};
|
||||
const brunoRequest = item.request as BrunoWebSocketRequest;
|
||||
|
||||
// info block
|
||||
const info: WebSocketRequestInfo = {
|
||||
name: isNonEmptyString(item.name) ? item.name : 'Untitled Request',
|
||||
type: 'websocket'
|
||||
};
|
||||
|
||||
ocRequest.name = isNonEmptyString(item.name) ? item.name : 'Untitled Request';
|
||||
|
||||
// sequence
|
||||
if (item.seq) {
|
||||
ocRequest.seq = item.seq;
|
||||
info.seq = item.seq;
|
||||
}
|
||||
if (item.tags?.length) {
|
||||
info.tags = item.tags;
|
||||
}
|
||||
ocRequest.info = info;
|
||||
|
||||
const brunoRequest = item.request as BrunoWebSocketRequest;
|
||||
// url
|
||||
ocRequest.url = isNonEmptyString(brunoRequest.url) ? brunoRequest.url : '';
|
||||
// websocket block
|
||||
const websocket: WebSocketRequestDetails = {
|
||||
url: isNonEmptyString(brunoRequest.url) ? brunoRequest.url : ''
|
||||
};
|
||||
|
||||
// headers
|
||||
const headers: HttpHeader[] | undefined = toOpenCollectionHttpHeaders(brunoRequest.headers);
|
||||
const headers: HttpRequestHeader[] | undefined = toOpenCollectionHttpHeaders(brunoRequest.headers);
|
||||
if (headers) {
|
||||
ocRequest.headers = headers;
|
||||
websocket.headers = headers;
|
||||
}
|
||||
|
||||
// message
|
||||
@@ -55,37 +61,40 @@ const stringifyWebsocketRequest = (item: BrunoItem): string => {
|
||||
data: msg.content || ''
|
||||
};
|
||||
if (message.data.trim().length) {
|
||||
ocRequest.message = message;
|
||||
websocket.message = message;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// auth
|
||||
const auth: Auth | undefined = toOpenCollectionAuth(brunoRequest.auth);
|
||||
if (auth) {
|
||||
ocRequest.auth = auth;
|
||||
ocRequest.websocket = websocket;
|
||||
|
||||
// runtime block
|
||||
const runtime: WebSocketRequestRuntime = {};
|
||||
let hasRuntime = false;
|
||||
|
||||
// variables
|
||||
const variables: Variable[] | undefined = toOpenCollectionVariables(brunoRequest.vars);
|
||||
if (variables) {
|
||||
runtime.variables = variables;
|
||||
hasRuntime = true;
|
||||
}
|
||||
|
||||
// scripts
|
||||
const scripts: Scripts | undefined = toOpenCollectionScripts(brunoRequest);
|
||||
if (scripts) {
|
||||
ocRequest.scripts = scripts;
|
||||
runtime.scripts = scripts;
|
||||
hasRuntime = true;
|
||||
}
|
||||
|
||||
// variables
|
||||
const variables: Variable[] | undefined = toOpenCollectionVariables(brunoRequest.vars);
|
||||
if (variables) {
|
||||
ocRequest.variables = variables;
|
||||
// auth
|
||||
const auth: Auth | undefined = toOpenCollectionAuth(brunoRequest.auth);
|
||||
if (auth) {
|
||||
runtime.auth = auth;
|
||||
hasRuntime = true;
|
||||
}
|
||||
|
||||
// docs
|
||||
if (isNonEmptyString(brunoRequest.docs)) {
|
||||
ocRequest.docs = brunoRequest.docs;
|
||||
}
|
||||
|
||||
// tags
|
||||
if (item.tags?.length) {
|
||||
ocRequest.tags = item.tags;
|
||||
if (hasRuntime) {
|
||||
ocRequest.runtime = runtime;
|
||||
}
|
||||
|
||||
// settings
|
||||
@@ -98,6 +107,11 @@ const stringifyWebsocketRequest = (item: BrunoItem): string => {
|
||||
ocRequest.settings.keepAliveInterval = !isNaN(keepAliveInterval) ? keepAliveInterval : 0;
|
||||
}
|
||||
|
||||
// docs
|
||||
if (isNonEmptyString(brunoRequest.docs)) {
|
||||
ocRequest.docs = brunoRequest.docs;
|
||||
}
|
||||
|
||||
return stringifyYml(ocRequest);
|
||||
} catch (error) {
|
||||
console.error('Error stringifying WebSocket request:', error);
|
||||
|
||||
@@ -1,22 +1,36 @@
|
||||
import type { Environment as BrunoEnvironment, EnvironmentVariable as BrunoEnvironmentVariable } from '@usebruno/schema-types/collection/environment';
|
||||
import type { Environment } from '@opencollection/types/config/environments';
|
||||
import type { Variable } from '@opencollection/types/common/variables';
|
||||
import type { Variable, SecretVariable } from '@opencollection/types/common/variables';
|
||||
import { parseYml } from './utils';
|
||||
import { uuid } from '../../utils';
|
||||
|
||||
const toBrunoEnvironmentVariables = (variables: Variable[] | null | undefined): BrunoEnvironmentVariable[] => {
|
||||
const isSecretVariable = (v: Variable | SecretVariable): v is SecretVariable => {
|
||||
return 'secret' in v && v.secret === true;
|
||||
};
|
||||
|
||||
const toBrunoEnvironmentVariables = (variables: (Variable | SecretVariable)[] | null | undefined): BrunoEnvironmentVariable[] => {
|
||||
if (!variables?.length) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return variables.map((v: Variable): BrunoEnvironmentVariable => {
|
||||
return variables.map((v): BrunoEnvironmentVariable => {
|
||||
if (isSecretVariable(v)) {
|
||||
return {
|
||||
uid: uuid(),
|
||||
name: v.name || '',
|
||||
value: '',
|
||||
type: 'text',
|
||||
enabled: v.disabled !== true,
|
||||
secret: true
|
||||
};
|
||||
}
|
||||
const variable: BrunoEnvironmentVariable = {
|
||||
uid: uuid(),
|
||||
name: v.name || '',
|
||||
value: v.value as string || '',
|
||||
value: (typeof v.value === 'string' ? v.value : '') || '',
|
||||
type: 'text',
|
||||
enabled: v.disabled !== true,
|
||||
secret: v.transient === true
|
||||
secret: false
|
||||
};
|
||||
return variable;
|
||||
});
|
||||
|
||||
@@ -11,10 +11,12 @@ const parseFolder = (ymlString: string): FolderRoot => {
|
||||
try {
|
||||
const ocFolder: Folder = parseYml(ymlString);
|
||||
|
||||
const info = ocFolder.info;
|
||||
|
||||
const folderRoot: FolderRoot = {
|
||||
meta: {
|
||||
name: ocFolder.name || 'Untitled Folder',
|
||||
seq: ocFolder.seq || 1
|
||||
name: info?.name || 'Untitled Folder',
|
||||
seq: info?.seq || 1
|
||||
},
|
||||
request: null,
|
||||
docs: null
|
||||
@@ -67,9 +69,13 @@ const parseFolder = (ymlString: string): FolderRoot => {
|
||||
}
|
||||
}
|
||||
|
||||
// docs
|
||||
if (isNonEmptyString(ocFolder.docs)) {
|
||||
folderRoot.docs = ocFolder.docs;
|
||||
// docs (now at root level)
|
||||
if (ocFolder.docs) {
|
||||
if (typeof ocFolder.docs === 'string' && ocFolder.docs.trim().length) {
|
||||
folderRoot.docs = ocFolder.docs;
|
||||
} else if (typeof ocFolder.docs === 'object' && ocFolder.docs.content?.trim().length) {
|
||||
folderRoot.docs = ocFolder.docs.content;
|
||||
}
|
||||
}
|
||||
|
||||
return folderRoot;
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
import type { Item as BrunoItem } from '@usebruno/schema-types/collection/item';
|
||||
import type { Item } from '@opencollection/types/collection/item';
|
||||
import type { Item, ScriptFile } from '@opencollection/types/collection/item';
|
||||
import type { HttpRequest } from '@opencollection/types/requests/http';
|
||||
import type { GraphQLRequest } from '@opencollection/types/requests/graphql';
|
||||
import type { GrpcRequest } from '@opencollection/types/requests/grpc';
|
||||
import type { WebSocketRequest } from '@opencollection/types/requests/websocket';
|
||||
import { parseYml } from './utils';
|
||||
import parseHttpRequest from './items/parseHttpRequest';
|
||||
import parseGraphQLRequest from './items/parseGraphQLRequest';
|
||||
@@ -7,35 +11,48 @@ import parseGrpcRequest from './items/parseGrpcRequest';
|
||||
import parseWebsocketRequest from './items/parseWebsocketRequest';
|
||||
import parseScript from './items/parseScript';
|
||||
|
||||
// Helper to get the type from an item (now in info block)
|
||||
const getItemType = (item: Item): string | undefined => {
|
||||
if ('info' in item && item.info && 'type' in item.info) {
|
||||
return item.info.type;
|
||||
}
|
||||
// For ScriptFile which still has type at root
|
||||
if ('type' in item) {
|
||||
return (item as ScriptFile).type;
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
|
||||
const parseItem = (ymlString: string): BrunoItem => {
|
||||
try {
|
||||
const ocItem: Item = parseYml(ymlString);
|
||||
const itemType = getItemType(ocItem);
|
||||
|
||||
if (!ocItem || !ocItem.type) {
|
||||
if (!ocItem || !itemType) {
|
||||
throw new Error('Invalid item: missing type');
|
||||
}
|
||||
|
||||
switch (ocItem.type) {
|
||||
switch (itemType) {
|
||||
case 'http':
|
||||
return parseHttpRequest(ocItem);
|
||||
return parseHttpRequest(ocItem as HttpRequest);
|
||||
|
||||
case 'graphql':
|
||||
return parseGraphQLRequest(ocItem);
|
||||
return parseGraphQLRequest(ocItem as GraphQLRequest);
|
||||
|
||||
case 'grpc':
|
||||
return parseGrpcRequest(ocItem);
|
||||
return parseGrpcRequest(ocItem as GrpcRequest);
|
||||
|
||||
case 'websocket':
|
||||
return parseWebsocketRequest(ocItem);
|
||||
return parseWebsocketRequest(ocItem as WebSocketRequest);
|
||||
|
||||
case 'script':
|
||||
return parseScript(ocItem);
|
||||
return parseScript(ocItem as ScriptFile);
|
||||
|
||||
case 'folder':
|
||||
throw new Error('Folder items should be handled separately using parseFolder');
|
||||
|
||||
default:
|
||||
throw new Error(`Unsupported item type: ${(ocItem as any).type}`);
|
||||
throw new Error(`Unsupported item type: ${itemType}`);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error parsing item:', error);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { OpenCollection } from '@opencollection/types';
|
||||
import type { ProtoFileItem, ProtoFileImportPath } from '@opencollection/types/config/protobuf';
|
||||
import type { HttpHeader } from '@opencollection/types/requests/http';
|
||||
import type { HttpRequestHeader } from '@opencollection/types/requests/http';
|
||||
import type { ClientCertificate, PemCertificate, Pkcs12Certificate } from '@opencollection/types/config/certificates';
|
||||
import type { Variable } from '@opencollection/types/common/variables';
|
||||
import type { Scripts } from '@opencollection/types/common/scripts';
|
||||
@@ -128,7 +128,7 @@ const stringifyCollection = (collectionRoot: any, brunoConfig: any): string => {
|
||||
|
||||
// headers
|
||||
if (collectionRoot.request?.headers?.length) {
|
||||
const ocHeaders: HttpHeader[] | undefined = toOpenCollectionHttpHeaders(collectionRoot.request?.headers);
|
||||
const ocHeaders: HttpRequestHeader[] | undefined = toOpenCollectionHttpHeaders(collectionRoot.request?.headers);
|
||||
if (ocHeaders) {
|
||||
oc.request.headers = ocHeaders;
|
||||
}
|
||||
|
||||
@@ -1,20 +1,31 @@
|
||||
import type { Environment as BrunoEnvironment, EnvironmentVariable as BrunoEnvironmentVariable } from '@usebruno/schema-types/collection/environment';
|
||||
import type { Environment } from '@opencollection/types/config/environments';
|
||||
import type { Variable } from '@opencollection/types/common/variables';
|
||||
import type { Variable, SecretVariable } from '@opencollection/types/common/variables';
|
||||
import { stringifyYml } from './utils';
|
||||
|
||||
const toOpenCollectionEnvironmentVariables = (variables: BrunoEnvironmentVariable[]): Variable[] | undefined => {
|
||||
const toOpenCollectionEnvironmentVariables = (variables: BrunoEnvironmentVariable[]): (Variable | SecretVariable)[] | undefined => {
|
||||
if (!variables?.length) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const ocVariables: Variable[] = variables
|
||||
const ocVariables: (Variable | SecretVariable)[] = variables
|
||||
.filter((v: BrunoEnvironmentVariable) => {
|
||||
// todo: currently neithwe bru lang nor bruno app supports non-string values
|
||||
// todo: currently neither bru lang nor bruno app supports non-string values
|
||||
// update this when bruno app supports non-string values
|
||||
return typeof v.value === 'string';
|
||||
})
|
||||
.map((v: BrunoEnvironmentVariable): Variable => {
|
||||
.map((v: BrunoEnvironmentVariable): Variable | SecretVariable => {
|
||||
if (v.secret === true) {
|
||||
const secretVar: SecretVariable = {
|
||||
secret: true,
|
||||
name: v.name || ''
|
||||
};
|
||||
if (v.enabled === false) {
|
||||
secretVar.disabled = true;
|
||||
}
|
||||
return secretVar;
|
||||
}
|
||||
|
||||
const variable: Variable = {
|
||||
name: v.name || '',
|
||||
value: v.value as string
|
||||
@@ -24,10 +35,6 @@ const toOpenCollectionEnvironmentVariables = (variables: BrunoEnvironmentVariabl
|
||||
variable.disabled = true;
|
||||
}
|
||||
|
||||
if (v.secret === true) {
|
||||
variable.transient = true;
|
||||
}
|
||||
|
||||
return variable;
|
||||
});
|
||||
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import type { FolderRoot } from '@usebruno/schema-types/collection/folder';
|
||||
import type { Folder } from '@opencollection/types/collection/item';
|
||||
import type { Folder, FolderInfo } from '@opencollection/types/collection/item';
|
||||
import type { Variable } from '@opencollection/types/common/variables';
|
||||
import type { Scripts } from '@opencollection/types/common/scripts';
|
||||
import type { Auth, HttpHeader } from '@opencollection/types/requests/http';
|
||||
import type { Auth } from '@opencollection/types/common/auth';
|
||||
import type { HttpRequestHeader } from '@opencollection/types/requests/http';
|
||||
import type { RequestDefaults } from '@opencollection/types/common/request-defaults';
|
||||
import { toOpenCollectionAuth } from './common/auth';
|
||||
import { toOpenCollectionHttpHeaders } from './common/headers';
|
||||
@@ -31,12 +32,15 @@ const hasRequestScripts = (folderRoot: FolderRoot): boolean => {
|
||||
|
||||
const stringifyFolder = (folderRoot: FolderRoot): string => {
|
||||
try {
|
||||
const ocFolder: Folder = {
|
||||
type: 'folder'
|
||||
};
|
||||
const ocFolder: Folder = {};
|
||||
|
||||
ocFolder.name = folderRoot.meta?.name || 'Untitled Folder';
|
||||
ocFolder.seq = folderRoot.meta?.seq || 1;
|
||||
// info block
|
||||
const info: FolderInfo = {
|
||||
name: folderRoot.meta?.name || 'Untitled Folder',
|
||||
type: 'folder',
|
||||
seq: folderRoot.meta?.seq || 1
|
||||
};
|
||||
ocFolder.info = info;
|
||||
|
||||
// request defaults
|
||||
if (hasRequestDefaults(folderRoot)) {
|
||||
@@ -44,7 +48,7 @@ const stringifyFolder = (folderRoot: FolderRoot): string => {
|
||||
|
||||
// headers
|
||||
if (folderRoot.request?.headers?.length) {
|
||||
const ocHeaders: HttpHeader[] | undefined = toOpenCollectionHttpHeaders(folderRoot.request?.headers);
|
||||
const ocHeaders: HttpRequestHeader[] | undefined = toOpenCollectionHttpHeaders(folderRoot.request?.headers);
|
||||
if (ocHeaders) {
|
||||
ocFolder.request.headers = ocHeaders;
|
||||
}
|
||||
|
||||
@@ -1,12 +1,36 @@
|
||||
import * as YAML from 'yaml';
|
||||
|
||||
// Top-level keys that should have a blank line before them
|
||||
const BLOCK_KEYS = ['info', 'http', 'graphql', 'grpc', 'websocket', 'runtime', 'settings', 'examples', 'docs', 'items', 'request'];
|
||||
|
||||
export const stringifyYml = (obj: any): string => {
|
||||
return YAML.stringify(obj, {
|
||||
const yamlStr = YAML.stringify(obj, {
|
||||
lineWidth: 0,
|
||||
indent: 2,
|
||||
minContentWidth: 0,
|
||||
defaultStringType: 'PLAIN'
|
||||
});
|
||||
|
||||
// Add blank lines before major blocks (only at the top level, not indented)
|
||||
const lines = yamlStr.split('\n');
|
||||
const result: string[] = [];
|
||||
|
||||
for (let i = 0; i < lines.length; i++) {
|
||||
const line = lines[i];
|
||||
// Check if this is a top-level key (no leading whitespace) that should have a blank line
|
||||
if (i > 0 && !line.startsWith(' ') && !line.startsWith('\t')) {
|
||||
const key = line.split(':')[0];
|
||||
if (BLOCK_KEYS.includes(key)) {
|
||||
// Add blank line before this block (if previous line isn't already blank)
|
||||
if (result.length > 0 && result[result.length - 1].trim() !== '') {
|
||||
result.push('');
|
||||
}
|
||||
}
|
||||
}
|
||||
result.push(line);
|
||||
}
|
||||
|
||||
return result.join('\n');
|
||||
};
|
||||
|
||||
export const parseYml = (ymlString: string): any => {
|
||||
|
||||
Reference in New Issue
Block a user