mirror of
https://github.com/usebruno/bruno.git
synced 2026-06-27 06:34:06 +00:00
consistent string handling across parsers (#6866)
* consistent string handling across parsers * fix
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import type { Action, ActionSetVariable, ActionVariableScope } from '@opencollection/types/common/actions';
|
||||
import type { Variable as BrunoVariable, Variables as BrunoVariables } from '@usebruno/schema-types/common/variables';
|
||||
import { uuid } from '../../../utils';
|
||||
import { uuid, ensureString } from '../../../utils';
|
||||
|
||||
/**
|
||||
* Convert Bruno post-response variables to OpenCollection actions.
|
||||
@@ -58,8 +58,8 @@ export const toBrunoPostResponseVariables = (actions: Action[] | null | undefine
|
||||
|
||||
const variable: BrunoVariable = {
|
||||
uid: uuid(),
|
||||
name: setVarAction.variable?.name || '',
|
||||
value: setVarAction.selector?.expression || '',
|
||||
name: ensureString(setVarAction.variable?.name),
|
||||
value: ensureString(setVarAction.selector?.expression),
|
||||
enabled: setVarAction.disabled !== true,
|
||||
local: false
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { KeyValue as BrunoKeyValue } from '@usebruno/schema-types/common/key-value';
|
||||
import type { Assertion } from '@opencollection/types/common/assertions';
|
||||
import { uuid } from '../../../utils';
|
||||
import { uuid, ensureString } from '../../../utils';
|
||||
|
||||
const OPERATORS = [
|
||||
'eq',
|
||||
@@ -119,14 +119,14 @@ export const toBrunoAssertions = (assertions: Assertion[] | null | undefined): B
|
||||
|
||||
const brunoAssertions: BrunoKeyValue[] = assertions.map((assertion: Assertion): BrunoKeyValue => {
|
||||
// Reconstruct the "operator value" format that Bruno uses
|
||||
let valueString = assertion.operator;
|
||||
let valueString = ensureString(assertion.operator);
|
||||
if (assertion.value !== undefined && assertion.value !== null) {
|
||||
valueString = `${assertion.operator} ${assertion.value}`;
|
||||
valueString = `${assertion.operator} ${ensureString(assertion.value)}`;
|
||||
}
|
||||
|
||||
const brunoAssertion: BrunoKeyValue = {
|
||||
uid: uuid(),
|
||||
name: assertion.expression || '',
|
||||
name: ensureString(assertion.expression),
|
||||
value: valueString,
|
||||
enabled: assertion.disabled !== true
|
||||
};
|
||||
|
||||
@@ -10,7 +10,7 @@ import type {
|
||||
FileBodyEntry
|
||||
} from '@opencollection/types/requests/http';
|
||||
import type { KeyValue as BrunoKeyValue } from '@usebruno/schema-types/common/key-value';
|
||||
import { uuid } from '../../../utils';
|
||||
import { uuid, ensureString } from '../../../utils';
|
||||
|
||||
export const toOpenCollectionBody = (body: BrunoHttpRequestBody | null | undefined): HttpRequestBody | undefined => {
|
||||
if (!body) {
|
||||
@@ -179,8 +179,8 @@ export const toBrunoBody = (body: HttpRequestBody | null | undefined): BrunoHttp
|
||||
brunoBody.formUrlEncoded = body.data?.map((entry): BrunoKeyValue => {
|
||||
const formEntry: BrunoKeyValue = {
|
||||
uid: uuid(),
|
||||
name: entry.name || '',
|
||||
value: entry.value || '',
|
||||
name: ensureString(entry.name),
|
||||
value: ensureString(entry.value),
|
||||
enabled: entry.disabled !== true
|
||||
};
|
||||
|
||||
@@ -202,8 +202,8 @@ export const toBrunoBody = (body: HttpRequestBody | null | undefined): BrunoHttp
|
||||
const multipartEntry: any = {
|
||||
uid: uuid(),
|
||||
type: entry.type,
|
||||
name: entry.name || '',
|
||||
value: entry.value || (entry.type === 'file' ? [] : ''),
|
||||
name: ensureString(entry.name),
|
||||
value: entry.type === 'file' ? (entry.value || []) : ensureString(entry.value),
|
||||
contentType: entry.contentType || null,
|
||||
enabled: entry.disabled !== true
|
||||
};
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
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 { HttpRequestHeader, HttpResponseHeader } from '@opencollection/types/requests/http';
|
||||
import { uuid } from '../../../utils';
|
||||
import { uuid, ensureString } from '../../../utils';
|
||||
|
||||
export const toOpenCollectionHttpHeaders = (headers: BrunoFolderRequest['headers']): HttpRequestHeader[] | undefined => {
|
||||
if (!headers?.length) {
|
||||
@@ -46,8 +46,8 @@ export const toBrunoHttpHeaders = (headers: HttpRequestHeader[] | HttpResponseHe
|
||||
const brunoHeaders = headers.map((header): BrunoKeyValue => {
|
||||
const brunoHeader: BrunoKeyValue = {
|
||||
uid: uuid(),
|
||||
name: header.name || '',
|
||||
value: header.value || '',
|
||||
name: ensureString(header.name),
|
||||
value: ensureString(header.value),
|
||||
enabled: ('disabled' in header) ? header.disabled !== true : true
|
||||
};
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { HttpRequestParam as BrunoHttpRequestParam } from '@usebruno/schema-types/requests/http';
|
||||
import type { HttpRequestParam } from '@opencollection/types/requests/http';
|
||||
import { uuid } from '../../../utils';
|
||||
import { uuid, ensureString } from '../../../utils';
|
||||
|
||||
export const toOpenCollectionParams = (params: BrunoHttpRequestParam[] | null | undefined): HttpRequestParam[] | undefined => {
|
||||
if (!params?.length) {
|
||||
@@ -36,8 +36,8 @@ export const toBrunoParams = (params: HttpRequestParam[] | null | undefined): Br
|
||||
const brunoParams = params.map((param: HttpRequestParam): BrunoHttpRequestParam => {
|
||||
const brunoParam: BrunoHttpRequestParam = {
|
||||
uid: uuid(),
|
||||
name: param.name || '',
|
||||
value: param.value || '',
|
||||
name: ensureString(param.name),
|
||||
value: ensureString(param.value),
|
||||
type: param.type,
|
||||
enabled: param.disabled !== true
|
||||
};
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Variable } from '@opencollection/types/common/variables';
|
||||
import { FolderRequest as BrunoFolderRequest } from '@usebruno/schema-types/collection/folder';
|
||||
import { Variable as BrunoVariable, Variables as BrunoVariables } from '@usebruno/schema-types/common/variables';
|
||||
import { uuid } from '../../../utils';
|
||||
import { uuid, ensureString } from '../../../utils';
|
||||
|
||||
/**
|
||||
* Convert Bruno pre-request variables to OpenCollection variables format.
|
||||
@@ -51,8 +51,8 @@ export const toBrunoVariables = (variables: Variable[] | null | undefined): { re
|
||||
variables.forEach((v: Variable) => {
|
||||
const variable: BrunoVariable = {
|
||||
uid: uuid(),
|
||||
name: v.name || '',
|
||||
value: v.value as string || '',
|
||||
name: ensureString(v.name),
|
||||
value: ensureString(v.value),
|
||||
enabled: v.disabled !== true,
|
||||
local: false
|
||||
};
|
||||
|
||||
@@ -8,7 +8,7 @@ import { toBrunoVariables } from '../common/variables';
|
||||
import { toBrunoPostResponseVariables } from '../common/actions';
|
||||
import { toBrunoScripts } from '../common/scripts';
|
||||
import { toBrunoAssertions } from '../common/assertions';
|
||||
import { uuid } from '../../../utils';
|
||||
import { uuid, ensureString } from '../../../utils';
|
||||
|
||||
const parseGraphQLRequest = (ocRequest: GraphQLRequest): BrunoItem => {
|
||||
const info = ocRequest.info;
|
||||
@@ -16,8 +16,8 @@ const parseGraphQLRequest = (ocRequest: GraphQLRequest): BrunoItem => {
|
||||
const runtime = ocRequest.runtime;
|
||||
|
||||
const brunoRequest: BrunoHttpRequest = {
|
||||
url: graphql?.url || '',
|
||||
method: graphql?.method || 'POST',
|
||||
url: ensureString(graphql?.url),
|
||||
method: ensureString(graphql?.method, 'POST'),
|
||||
headers: toBrunoHttpHeaders(graphql?.headers) || [],
|
||||
params: toBrunoParams(graphql?.params) || [],
|
||||
auth: toBrunoAuth(graphql?.auth),
|
||||
@@ -86,7 +86,7 @@ const parseGraphQLRequest = (ocRequest: GraphQLRequest): BrunoItem => {
|
||||
uid: uuid(),
|
||||
type: 'graphql-request',
|
||||
seq: info?.seq || 1,
|
||||
name: info?.name || 'Untitled Request',
|
||||
name: ensureString(info?.name, 'Untitled Request'),
|
||||
tags: info?.tags || [],
|
||||
request: brunoRequest,
|
||||
settings: null,
|
||||
|
||||
@@ -6,7 +6,7 @@ import { toBrunoAuth } from '../common/auth';
|
||||
import { toBrunoVariables } from '../common/variables';
|
||||
import { toBrunoScripts } from '../common/scripts';
|
||||
import { toBrunoAssertions } from '../common/assertions';
|
||||
import { isNonEmptyString, uuid } from '../../../utils';
|
||||
import { isNonEmptyString, uuid, ensureString } from '../../../utils';
|
||||
|
||||
const toBrunoGrpcMetadata = (metadata: GrpcMetadata[] | null | undefined): BrunoKeyValue[] | undefined => {
|
||||
if (!metadata?.length) {
|
||||
@@ -16,8 +16,8 @@ const toBrunoGrpcMetadata = (metadata: GrpcMetadata[] | null | undefined): Bruno
|
||||
const brunoMetadata = metadata.map((meta: GrpcMetadata): BrunoKeyValue => {
|
||||
const brunoMeta: BrunoKeyValue = {
|
||||
uid: uuid(),
|
||||
name: meta.name || '',
|
||||
value: meta.value || '',
|
||||
name: ensureString(meta.name),
|
||||
value: ensureString(meta.value),
|
||||
enabled: meta.disabled !== true
|
||||
};
|
||||
|
||||
@@ -33,8 +33,8 @@ const parseGrpcRequest = (ocRequest: GrpcRequest): BrunoItem => {
|
||||
const runtime = ocRequest.runtime;
|
||||
|
||||
const brunoRequest: BrunoGrpcRequest = {
|
||||
url: grpc?.url || '',
|
||||
method: grpc?.method || '',
|
||||
url: ensureString(grpc?.url),
|
||||
method: ensureString(grpc?.method),
|
||||
methodType: grpc?.methodType || '',
|
||||
protoPath: grpc?.protoFilePath || null,
|
||||
headers: toBrunoGrpcMetadata(grpc?.metadata) || [],
|
||||
@@ -98,7 +98,7 @@ const parseGrpcRequest = (ocRequest: GrpcRequest): BrunoItem => {
|
||||
uid: uuid(),
|
||||
type: 'grpc-request',
|
||||
seq: info?.seq || 1,
|
||||
name: info?.name || 'Untitled Request',
|
||||
name: ensureString(info?.name, 'Untitled Request'),
|
||||
tags: info?.tags || [],
|
||||
request: brunoRequest,
|
||||
settings: {},
|
||||
|
||||
@@ -9,7 +9,7 @@ import { toBrunoVariables } from '../common/variables';
|
||||
import { toBrunoPostResponseVariables } from '../common/actions';
|
||||
import { toBrunoScripts } from '../common/scripts';
|
||||
import { toBrunoAssertions } from '../common/assertions';
|
||||
import { uuid } from '../../../utils';
|
||||
import { uuid, ensureString } from '../../../utils';
|
||||
|
||||
const parseHttpRequest = (ocRequest: HttpRequest): BrunoItem => {
|
||||
const info = ocRequest.info;
|
||||
@@ -17,8 +17,8 @@ const parseHttpRequest = (ocRequest: HttpRequest): BrunoItem => {
|
||||
const runtime = ocRequest.runtime;
|
||||
|
||||
const brunoRequest: BrunoHttpRequest = {
|
||||
url: http?.url || '',
|
||||
method: http?.method || 'GET',
|
||||
url: ensureString(http?.url),
|
||||
method: ensureString(http?.method, 'GET'),
|
||||
headers: toBrunoHttpHeaders(http?.headers) || [],
|
||||
params: toBrunoParams(http?.params) || [],
|
||||
auth: toBrunoAuth(http?.auth),
|
||||
@@ -84,7 +84,7 @@ const parseHttpRequest = (ocRequest: HttpRequest): BrunoItem => {
|
||||
uid: uuid(),
|
||||
type: 'http-request',
|
||||
seq: info?.seq || 1,
|
||||
name: info?.name || 'Untitled Request',
|
||||
name: ensureString(info?.name, 'Untitled Request'),
|
||||
tags: info?.tags || [],
|
||||
request: brunoRequest,
|
||||
settings: null,
|
||||
@@ -135,7 +135,7 @@ const parseHttpRequest = (ocRequest: HttpRequest): BrunoItem => {
|
||||
const brunoExample: any = {
|
||||
uid: uuid(),
|
||||
itemUid: uuid(),
|
||||
name: example.name || 'Untitled Example',
|
||||
name: ensureString(example.name, 'Untitled Example'),
|
||||
type: 'http-request',
|
||||
request: null,
|
||||
response: null
|
||||
@@ -151,8 +151,8 @@ const parseHttpRequest = (ocRequest: HttpRequest): BrunoItem => {
|
||||
|
||||
if (example.request) {
|
||||
brunoExample.request = {
|
||||
url: example.request.url || '',
|
||||
method: example.request.method || 'GET',
|
||||
url: ensureString(example.request.url),
|
||||
method: ensureString(example.request.method, 'GET'),
|
||||
headers: toBrunoHttpHeaders(example.request.headers) || [],
|
||||
params: toBrunoParams(example.request.params) || [],
|
||||
body: toBrunoBody(example.request.body) || {
|
||||
|
||||
@@ -5,7 +5,7 @@ import { toBrunoAuth } from '../common/auth';
|
||||
import { toBrunoHttpHeaders } from '../common/headers';
|
||||
import { toBrunoVariables } from '../common/variables';
|
||||
import { toBrunoScripts } from '../common/scripts';
|
||||
import { uuid } from '../../../utils';
|
||||
import { uuid, ensureString } from '../../../utils';
|
||||
|
||||
const parseWebsocketRequest = (ocRequest: WebSocketRequest): BrunoItem => {
|
||||
const info = ocRequest.info;
|
||||
@@ -13,7 +13,7 @@ const parseWebsocketRequest = (ocRequest: WebSocketRequest): BrunoItem => {
|
||||
const runtime = ocRequest.runtime;
|
||||
|
||||
const brunoRequest: BrunoWebSocketRequest = {
|
||||
url: websocket?.url || '',
|
||||
url: ensureString(websocket?.url),
|
||||
headers: toBrunoHttpHeaders(websocket?.headers) || [],
|
||||
auth: toBrunoAuth(websocket?.auth),
|
||||
body: {
|
||||
@@ -36,11 +36,12 @@ const parseWebsocketRequest = (ocRequest: WebSocketRequest): BrunoItem => {
|
||||
// message
|
||||
if (websocket?.message) {
|
||||
const message = websocket.message as WebSocketMessage;
|
||||
if (message.data?.trim().length) {
|
||||
const messageData = ensureString(message.data);
|
||||
if (messageData.trim().length) {
|
||||
brunoRequest.body.ws = [{
|
||||
name: '',
|
||||
type: message.type || 'text',
|
||||
content: message.data
|
||||
content: messageData
|
||||
}];
|
||||
}
|
||||
}
|
||||
@@ -88,7 +89,7 @@ const parseWebsocketRequest = (ocRequest: WebSocketRequest): BrunoItem => {
|
||||
uid: uuid(),
|
||||
type: 'ws-request',
|
||||
seq: info?.seq || 1,
|
||||
name: info?.name || 'Untitled Request',
|
||||
name: ensureString(info?.name, 'Untitled Request'),
|
||||
tags: info?.tags || [],
|
||||
request: brunoRequest,
|
||||
settings: wsSettings as any,
|
||||
|
||||
@@ -5,6 +5,7 @@ import { toBrunoAuth } from './common/auth';
|
||||
import { toBrunoHttpHeaders } from './common/headers';
|
||||
import { toBrunoVariables } from './common/variables';
|
||||
import { toBrunoScripts } from './common/scripts';
|
||||
import { ensureString } from '../../utils';
|
||||
|
||||
interface ParsedCollection {
|
||||
collectionRoot: FolderRoot;
|
||||
@@ -18,7 +19,7 @@ const parseCollection = (ymlString: string): ParsedCollection => {
|
||||
// bruno config
|
||||
const brunoConfig: Record<string, any> = {
|
||||
opencollection: oc.opencollection || '1.0.0',
|
||||
name: oc.info?.name || 'Untitled Collection',
|
||||
name: ensureString(oc.info?.name, 'Untitled Collection'),
|
||||
type: 'collection',
|
||||
ignore: []
|
||||
};
|
||||
|
||||
@@ -2,7 +2,7 @@ import type { Environment as BrunoEnvironment, EnvironmentVariable as BrunoEnvir
|
||||
import type { Environment } from '@opencollection/types/config/environments';
|
||||
import type { Variable, SecretVariable } from '@opencollection/types/common/variables';
|
||||
import { parseYml } from './utils';
|
||||
import { uuid } from '../../utils';
|
||||
import { uuid, ensureString } from '../../utils';
|
||||
|
||||
const isSecretVariable = (v: Variable | SecretVariable): v is SecretVariable => {
|
||||
return 'secret' in v && v.secret === true;
|
||||
@@ -17,7 +17,7 @@ const toBrunoEnvironmentVariables = (variables: (Variable | SecretVariable)[] |
|
||||
if (isSecretVariable(v)) {
|
||||
return {
|
||||
uid: uuid(),
|
||||
name: v.name || '',
|
||||
name: ensureString(v.name),
|
||||
value: '',
|
||||
type: 'text',
|
||||
enabled: v.disabled !== true,
|
||||
@@ -26,8 +26,8 @@ const toBrunoEnvironmentVariables = (variables: (Variable | SecretVariable)[] |
|
||||
}
|
||||
const variable: BrunoEnvironmentVariable = {
|
||||
uid: uuid(),
|
||||
name: v.name || '',
|
||||
value: (typeof v.value === 'string' ? v.value : '') || '',
|
||||
name: ensureString(v.name),
|
||||
value: ensureString(v.value),
|
||||
type: 'text',
|
||||
enabled: v.disabled !== true,
|
||||
secret: false
|
||||
@@ -42,7 +42,7 @@ const parseEnvironment = (ymlString: string): BrunoEnvironment => {
|
||||
|
||||
const brunoEnvironment: BrunoEnvironment = {
|
||||
uid: uuid(),
|
||||
name: ocEnvironment.name || 'Untitled Environment',
|
||||
name: ensureString(ocEnvironment.name, 'Untitled Environment'),
|
||||
variables: toBrunoEnvironmentVariables(ocEnvironment.variables)
|
||||
};
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import { toBrunoAuth } from './common/auth';
|
||||
import { toBrunoHttpHeaders } from './common/headers';
|
||||
import { toBrunoVariables } from './common/variables';
|
||||
import { toBrunoScripts } from './common/scripts';
|
||||
import { isNonEmptyString } from '../../utils';
|
||||
import { ensureString } from '../../utils';
|
||||
|
||||
const parseFolder = (ymlString: string): FolderRoot => {
|
||||
try {
|
||||
@@ -15,7 +15,7 @@ const parseFolder = (ymlString: string): FolderRoot => {
|
||||
|
||||
const folderRoot: FolderRoot = {
|
||||
meta: {
|
||||
name: info?.name || 'Untitled Folder',
|
||||
name: ensureString(info?.name, 'Untitled Folder'),
|
||||
seq: info?.seq || 1
|
||||
},
|
||||
request: null,
|
||||
|
||||
@@ -6,6 +6,16 @@ export const isNumber = (value: unknown): value is number => typeof value === 'n
|
||||
|
||||
export const isNonEmptyString = (value: unknown): value is string => isString(value) && value.trim().length > 0;
|
||||
|
||||
export const ensureString = (value: unknown, fallback: string = ''): string => {
|
||||
if (value === null || value === undefined) {
|
||||
return fallback;
|
||||
}
|
||||
if (typeof value === 'string') {
|
||||
return value;
|
||||
}
|
||||
return String(value);
|
||||
};
|
||||
|
||||
export const uuid = () => {
|
||||
// https://github.com/ai/nanoid/blob/main/url-alphabet/index.js
|
||||
const urlAlphabet = 'useandom26T198340PX75pxJACKVERYMINDBUSHWOLFGQZbfghjklqvwyzrict';
|
||||
|
||||
Reference in New Issue
Block a user