@usebruno/filestore 0.10.0 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/index.js +1 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/workers/worker-script.js +1 -1
- package/dist/cjs/workers/worker-script.js.map +1 -1
- package/dist/constants.d.ts +2 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/esm/index.js +1 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/workers/worker-script.js +1 -1
- package/dist/esm/workers/worker-script.js.map +1 -1
- package/dist/formats/bru/index.d.ts.map +1 -1
- package/dist/formats/bru/utils/redact-large-text-blocks.d.ts +11 -0
- package/dist/formats/bru/utils/redact-large-text-blocks.d.ts.map +1 -0
- package/dist/formats/yml/common/app.d.ts +8 -0
- package/dist/formats/yml/common/app.d.ts.map +1 -0
- package/dist/formats/yml/common/auth.d.ts.map +1 -1
- package/dist/formats/yml/common/body.d.ts.map +1 -1
- package/dist/formats/yml/common/datatype.d.ts +14 -0
- package/dist/formats/yml/common/datatype.d.ts.map +1 -0
- package/dist/formats/yml/common/headers.d.ts.map +1 -1
- package/dist/formats/yml/common/variables.d.ts +1 -2
- package/dist/formats/yml/common/variables.d.ts.map +1 -1
- package/dist/formats/yml/items/parseApp.d.ts +13 -0
- package/dist/formats/yml/items/parseApp.d.ts.map +1 -0
- package/dist/formats/yml/items/parseGraphQLRequest.d.ts.map +1 -1
- package/dist/formats/yml/items/parseGrpcRequest.d.ts.map +1 -1
- package/dist/formats/yml/items/parseHttpRequest.d.ts.map +1 -1
- package/dist/formats/yml/items/parseWebsocketRequest.d.ts.map +1 -1
- package/dist/formats/yml/items/stringifyApp.d.ts +4 -0
- package/dist/formats/yml/items/stringifyApp.d.ts.map +1 -0
- package/dist/formats/yml/items/stringifyGraphQLRequest.d.ts.map +1 -1
- package/dist/formats/yml/items/stringifyGrpcRequest.d.ts.map +1 -1
- package/dist/formats/yml/items/stringifyHttpRequest.d.ts.map +1 -1
- package/dist/formats/yml/items/stringifyWebsocketRequest.d.ts.map +1 -1
- package/dist/formats/yml/parseCollection.d.ts.map +1 -1
- package/dist/formats/yml/parseEnvironment.d.ts +3 -1
- package/dist/formats/yml/parseEnvironment.d.ts.map +1 -1
- package/dist/formats/yml/parseFolder.d.ts.map +1 -1
- package/dist/formats/yml/parseItem.d.ts.map +1 -1
- package/dist/formats/yml/stringifyCollection.d.ts.map +1 -1
- package/dist/formats/yml/stringifyEnvironment.d.ts +3 -1
- package/dist/formats/yml/stringifyEnvironment.d.ts.map +1 -1
- package/dist/formats/yml/stringifyItem.d.ts.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/types.d.ts +6 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/secretsJsonToEnvironments.d.ts +38 -0
- package/dist/utils/secretsJsonToEnvironments.d.ts.map +1 -0
- package/package.json +7 -5
- package/src/constants.ts +9 -0
- package/src/formats/bru/index.ts +52 -0
- package/src/formats/bru/tests/parseBruEnvironment.spec.js +63 -0
- package/src/formats/bru/tests/redact-large-text-blocks.spec.js +313 -0
- package/src/formats/bru/utils/redact-large-text-blocks.ts +102 -0
- package/src/formats/yml/common/actions.ts +1 -1
- package/src/formats/yml/common/app.ts +27 -0
- package/src/formats/yml/common/auth.ts +53 -1
- package/src/formats/yml/common/body.spec.ts +62 -0
- package/src/formats/yml/common/body.ts +27 -9
- package/src/formats/yml/common/datatype.spec.ts +110 -0
- package/src/formats/yml/common/datatype.ts +57 -0
- package/src/formats/yml/common/headers.ts +4 -0
- package/src/formats/yml/common/variables.spec.ts +127 -0
- package/src/formats/yml/common/variables.ts +14 -22
- package/src/formats/yml/items/parseApp.ts +37 -0
- package/src/formats/yml/items/parseGraphQLRequest.ts +8 -0
- package/src/formats/yml/items/parseGrpcRequest.ts +24 -3
- package/src/formats/yml/items/parseHttpRequest.ts +13 -0
- package/src/formats/yml/items/parseWebsocketRequest.ts +29 -9
- package/src/formats/yml/items/stringifyApp.ts +45 -0
- package/src/formats/yml/items/stringifyGraphQLRequest.ts +3 -0
- package/src/formats/yml/items/stringifyGrpcRequest.ts +9 -11
- package/src/formats/yml/items/stringifyHttpRequest.ts +10 -0
- package/src/formats/yml/items/stringifyWebsocketRequest.ts +22 -9
- package/src/formats/yml/parseCollection.spec.ts +70 -0
- package/src/formats/yml/parseCollection.ts +8 -3
- package/src/formats/yml/parseEnvironment.spec.ts +99 -0
- package/src/formats/yml/parseEnvironment.ts +41 -19
- package/src/formats/yml/parseFolder.spec.ts +52 -0
- package/src/formats/yml/parseFolder.ts +14 -21
- package/src/formats/yml/parseItem.spec.ts +147 -0
- package/src/formats/yml/parseItem.ts +4 -0
- package/src/formats/yml/stringifyCollection.spec.ts +77 -0
- package/src/formats/yml/stringifyCollection.ts +4 -0
- package/src/formats/yml/stringifyEnvironment.spec.ts +91 -0
- package/src/formats/yml/stringifyEnvironment.ts +55 -20
- package/src/formats/yml/stringifyFolder.spec.ts +47 -0
- package/src/formats/yml/stringifyItem.spec.ts +53 -0
- package/src/formats/yml/stringifyItem.ts +4 -0
- package/src/formats/yml/tests/fixtures/presets/empty-request.yml +7 -0
- package/src/formats/yml/tests/fixtures/presets/no-presets.yml +3 -0
- package/src/formats/yml/tests/fixtures/presets/no-request-key.yml +6 -0
- package/src/formats/yml/tests/fixtures/presets/type-only-realistic.yml +24 -0
- package/src/formats/yml/tests/fixtures/presets/url-only-realistic.yml +25 -0
- package/src/formats/yml/tests/fixtures/presets/with-type-and-url.yml +9 -0
- package/src/formats/yml/tests/parseCollection.spec.js +63 -0
- package/src/formats/yml/tests/parseEnvironment.spec.js +24 -63
- package/src/formats/yml/tests/parseEnvironment.spec.ts +160 -0
- package/src/formats/yml/tests/stringifyEnvironment.spec.ts +204 -0
- package/src/formats/yml/tests/variables.spec.js +7 -7
- package/src/index.ts +5 -0
- package/src/types/bruno-lang.d.ts +1 -0
- package/src/types.ts +7 -0
- package/src/utils/secretsJsonToEnvironments.spec.ts +211 -0
- package/src/utils/secretsJsonToEnvironments.ts +129 -0
- package/dist/formats/bru/tests/example-status-swap.spec.d.ts +0 -2
- package/dist/formats/bru/tests/example-status-swap.spec.d.ts.map +0 -1
- package/dist/formats/bru/tests/fixtures/oauth2-additional-params.d.ts +0 -57
- package/dist/formats/bru/tests/fixtures/oauth2-additional-params.d.ts.map +0 -1
- package/dist/formats/bru/tests/oauth2-additional-params.spec.d.ts +0 -2
- package/dist/formats/bru/tests/oauth2-additional-params.spec.d.ts.map +0 -1
- package/dist/formats/bru/tests/request-parse-and-redact-body-data.spec.d.ts +0 -2
- package/dist/formats/bru/tests/request-parse-and-redact-body-data.spec.d.ts.map +0 -1
- package/dist/formats/yml/tests/parseEnvironment.spec.d.ts +0 -2
- package/dist/formats/yml/tests/parseEnvironment.spec.d.ts.map +0 -1
- package/dist/formats/yml/tests/variables.spec.d.ts +0 -2
- package/dist/formats/yml/tests/variables.spec.d.ts.map +0 -1
package/dist/esm/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../src/formats/bru/utils/oauth2-additional-params.ts","../../src/formats/bru/index.ts","../../src/formats/yml/utils.ts","../../src/utils/index.ts","../../src/formats/yml/common/auth-oauth2.ts","../../src/formats/yml/common/auth.ts","../../src/formats/yml/common/headers.ts","../../src/formats/yml/common/params.ts","../../src/formats/yml/common/body.ts","../../src/formats/yml/common/variables.ts","../../src/formats/yml/common/actions.ts","../../src/formats/yml/common/scripts.ts","../../src/formats/yml/common/assertions.ts","../../src/formats/yml/items/parseGrpcRequest.ts","../../src/formats/yml/parseItem.ts","../../src/formats/yml/items/parseHttpRequest.ts","../../src/formats/yml/items/parseGraphQLRequest.ts","../../src/formats/yml/items/parseWebsocketRequest.ts","../../src/formats/yml/items/parseScript.ts","../../src/formats/yml/parseEnvironment.ts","../../src/formats/yml/stringifyItem.ts","../../src/formats/yml/items/stringifyHttpRequest.ts","../../src/formats/yml/items/stringifyGraphQLRequest.ts","../../src/formats/yml/items/stringifyGrpcRequest.ts","../../src/formats/yml/items/stringifyWebsocketRequest.ts","../../src/formats/yml/items/stringifyScript.ts","../../src/formats/yml/stringifyFolder.ts","../../src/formats/yml/stringifyCollection.ts","../../src/formats/yml/stringifyEnvironment.ts","../../src/workers/WorkerQueue/index.ts","../../src/constants.ts","../../src/workers/index.ts","../../src/formats/bru/utils/request-parse-and-redact-body-data.ts","../../src/index.ts","../../src/formats/yml/parseCollection.ts","../../src/formats/yml/parseFolder.ts"],"sourcesContent":["type T_Oauth2ParameterType = 'authorization' | 'token' | 'refresh';\ntype T_Oauth2ParameterSendInType = 'headers' | 'queryparams' | 'body';\n\nexport interface T_OAuth2AdditionalParam {\n name: string;\n value: string;\n enabled: boolean;\n sendIn: T_Oauth2ParameterSendInType;\n}\n\nexport interface T_OAuth2AdditionalParameters {\n authorization?: T_OAuth2AdditionalParam[];\n token?: T_OAuth2AdditionalParam[];\n refresh?: T_OAuth2AdditionalParam[];\n}\n\nexport interface T_Oauth2Auth {\n grantType: string;\n additionalParameters?: T_OAuth2AdditionalParameters;\n}\n\nexport interface T_BruJson {\n auth: {\n oauth2: T_Oauth2Auth;\n };\n oauth2_additional_parameters_auth_req_headers?: any[];\n oauth2_additional_parameters_auth_req_queryparams?: any[];\n oauth2_additional_parameters_access_token_req_headers?: any[];\n oauth2_additional_parameters_access_token_req_queryparams?: any[];\n oauth2_additional_parameters_access_token_req_bodyvalues?: any[];\n oauth2_additional_parameters_refresh_token_req_headers?: any[];\n oauth2_additional_parameters_refresh_token_req_queryparams?: any[];\n oauth2_additional_parameters_refresh_token_req_bodyvalues?: any[];\n}\n\ninterface T_Oauth2ParameterMapping {\n type: T_Oauth2ParameterType;\n sendIn: T_Oauth2ParameterSendInType;\n source: keyof T_BruJson;\n}\n\nconst PARAMETER_MAPPINGS: T_Oauth2ParameterMapping[] = [\n // Authorization parameters (only for authorization_code grant type)\n { type: 'authorization', sendIn: 'headers', source: 'oauth2_additional_parameters_auth_req_headers' },\n { type: 'authorization', sendIn: 'queryparams', source: 'oauth2_additional_parameters_auth_req_queryparams' },\n\n // Token parameters (for all grant types)\n { type: 'token', sendIn: 'headers', source: 'oauth2_additional_parameters_access_token_req_headers' },\n { type: 'token', sendIn: 'queryparams', source: 'oauth2_additional_parameters_access_token_req_queryparams' },\n { type: 'token', sendIn: 'body', source: 'oauth2_additional_parameters_access_token_req_bodyvalues' },\n\n // Refresh parameters (for grant types that support refresh)\n { type: 'refresh', sendIn: 'headers', source: 'oauth2_additional_parameters_refresh_token_req_headers' },\n { type: 'refresh', sendIn: 'queryparams', source: 'oauth2_additional_parameters_refresh_token_req_queryparams' },\n { type: 'refresh', sendIn: 'body', source: 'oauth2_additional_parameters_refresh_token_req_bodyvalues' }\n];\n\n/**\n * Maps source parameters to T_OAuth2AdditionalParam format\n */\nconst mapParametersFromSource = (sourceParams: any[], sendIn: T_Oauth2ParameterSendInType): T_OAuth2AdditionalParam[] => {\n if (!sourceParams?.length) {\n return [];\n }\n\n return sourceParams.map((param) => ({\n ...param,\n sendIn\n }));\n};\n\n/**\n * Checks if a parameter type should be included based on grant type\n */\nconst shouldIncludeParameterType = (type: T_Oauth2ParameterType, grantType: string): boolean => {\n // Authorization parameters are only valid for authorization_code grant type\n if (type === 'authorization') {\n return grantType === 'authorization_code' || grantType === 'implicit';\n }\n\n if (type === 'token' || type === 'refresh') {\n return grantType !== 'implicit';\n }\n\n // Token and refresh parameters are valid for all grant types\n return true;\n};\n\n/**\n * Collects all parameters for a specific type (authorization, token, or refresh)\n */\nconst collectParametersForType = (\n json: T_BruJson,\n type: T_Oauth2ParameterType,\n grantType: string\n): T_OAuth2AdditionalParam[] => {\n if (!shouldIncludeParameterType(type, grantType)) {\n return [];\n }\n\n const relevantMappings = PARAMETER_MAPPINGS.filter((mapping) => mapping.type === type);\n const allParams: T_OAuth2AdditionalParam[] = [];\n\n for (const mapping of relevantMappings) {\n const sourceParams = json[mapping.source] as any[];\n const mappedParams = mapParametersFromSource(sourceParams, mapping.sendIn);\n allParams.push(...mappedParams);\n }\n\n return allParams;\n};\n\n/**\n * This function extracts OAuth2 additional parameters from various sources in the bru json data and organizes\n * them into a structured format based on their usage context (authorization, token, refresh).\n *\n * @param json - json object containing OAuth2 configuration and additional parameters\n * @returns OAuth2 additional parameters\n */\nexport const getOauth2AdditionalParameters = (json: T_BruJson): T_OAuth2AdditionalParameters => {\n const grantType = json.auth.oauth2.grantType;\n const additionalParameters: T_OAuth2AdditionalParameters = {};\n\n try {\n // Collect parameters for each type\n const parameterTypes: T_Oauth2ParameterType[] = ['authorization', 'token', 'refresh'];\n\n for (const type of parameterTypes) {\n const params = collectParametersForType(json, type, grantType);\n if (params.length > 0) {\n additionalParameters[type] = params;\n }\n }\n } catch (error) {\n console.error(error);\n console.error('Error while getting the oauth2 additional parameters!');\n }\n\n return additionalParameters;\n};\n","import * as _ from 'lodash';\nimport {\n bruToJsonV2,\n jsonToBruV2,\n bruToEnvJsonV2,\n envJsonToBruV2,\n collectionBruToJson as _collectionBruToJson,\n jsonToCollectionBru as _jsonToCollectionBru\n} from '@usebruno/lang';\nimport { getOauth2AdditionalParameters } from './utils/oauth2-additional-params';\n\nexport const parseBruRequest = (data: string | any, parsed: boolean = false): any => {\n try {\n const json = parsed ? data : bruToJsonV2(data);\n\n let requestType = _.get(json, 'meta.type');\n switch (requestType) {\n case 'http':\n requestType = 'http-request';\n break;\n case 'graphql':\n requestType = 'graphql-request';\n break;\n case 'grpc':\n requestType = 'grpc-request';\n break;\n case 'ws':\n requestType = 'ws-request';\n break;\n default:\n requestType = 'http-request';\n }\n\n const sequence = _.get(json, 'meta.seq');\n const tags = _.get(json, 'meta.tags', []);\n const urlPath: Record<typeof requestType, string> = {\n 'grpc-request': 'grpc.url',\n 'ws-request': 'ws.url',\n 'default': 'http.url'\n };\n const transformedJson = {\n type: requestType,\n name: _.get(json, 'meta.name'),\n seq: !_.isNaN(sequence) ? Number(sequence) : 1,\n settings: _.get(json, 'settings', {}),\n tags: Array.isArray(tags) ? tags : [],\n request: {\n // Preserving special characters in custom methods. Using _.upperCase strips special characters.\n method:\n requestType === 'grpc-request'\n ? _.get(json, 'grpc.method', '')\n : String(_.get(json, 'http.method') ?? '').toUpperCase(),\n url: _.get(json, urlPath[requestType], _.get(json, urlPath.default)),\n headers: requestType === 'grpc-request' ? _.get(json, 'metadata', []) : _.get(json, 'headers', []),\n auth: _.get(json, 'auth', {}),\n body: _.get(json, 'body', {}),\n script: _.get(json, 'script', {}),\n vars: _.get(json, 'vars', {}),\n assertions: _.get(json, 'assertions', []),\n tests: _.get(json, 'tests', ''),\n docs: _.get(json, 'docs', '')\n },\n examples: _.get(json, 'examples', []).map((e: any) => {\n return bruExampleToJson(e, true, requestType, _.get(json, 'http.method'));\n })\n } as any;\n\n // Add request type specific fields\n if (requestType === 'grpc-request') {\n const selectedMethodType = _.get(json, 'grpc.methodType');\n selectedMethodType && ((transformedJson.request as any).methodType = selectedMethodType);\n const protoPath = _.get(json, 'grpc.protoPath');\n protoPath && ((transformedJson.request as any).protoPath = protoPath);\n transformedJson.request.auth.mode = _.get(json, 'grpc.auth', 'none');\n transformedJson.request.body = _.get(json, 'body', {\n mode: 'grpc',\n grpc: _.get(json, 'body.grpc', [\n {\n name: 'message 1',\n content: '{}'\n }\n ])\n });\n } else if (requestType === 'ws-request') {\n transformedJson.request.auth.mode = _.get(json, 'ws.auth', 'none');\n transformedJson.request.body = _.get(json, 'body', {\n mode: 'ws',\n ws: _.get(json, 'body.ws', [\n {\n name: 'message 1',\n content: '{}'\n }\n ])\n });\n } else {\n // For HTTP and GraphQL\n (transformedJson.request as any).params = _.get(json, 'params', []);\n transformedJson.request.auth.mode = _.get(json, 'http.auth', 'none');\n transformedJson.request.body.mode = _.get(json, 'http.body', 'none');\n }\n\n // add oauth2 additional parameters if they exist\n const hasOauth2GrantType = json?.auth?.oauth2?.grantType;\n if (hasOauth2GrantType) {\n const additionalParameters = getOauth2AdditionalParameters(json);\n const hasAdditionalParameters = Object.keys(additionalParameters || {}).length > 0;\n if (hasAdditionalParameters) {\n transformedJson.request.auth.oauth2.additionalParameters = additionalParameters;\n }\n }\n return transformedJson;\n } catch (error) {\n console.log('parseBruRequest error', error);\n throw error;\n }\n};\n\nexport const stringifyBruRequest = (json: any): string => {\n try {\n let type = _.get(json, 'type');\n switch (type) {\n case 'http-request':\n type = 'http';\n break;\n case 'graphql-request':\n type = 'graphql';\n break;\n case 'grpc-request':\n type = 'grpc';\n break;\n case 'ws-request':\n type = 'ws';\n break;\n default:\n type = 'http';\n }\n\n const sequence = _.get(json, 'seq');\n\n // Start with the common meta section\n const bruJson = {\n meta: {\n name: _.get(json, 'name'),\n type: type,\n seq: !_.isNaN(sequence) ? Number(sequence) : 1,\n tags: _.get(json, 'tags', [])\n }\n } as any;\n\n // For HTTP and GraphQL requests, maintain the current structure\n if (type === 'http' || type === 'graphql') {\n bruJson.http = {\n // Preserve special characters in custom request methods. Avoid _.lowerCase which strips symbols.\n method: String(_.get(json, 'request.method') ?? '').toLowerCase(),\n url: _.get(json, 'request.url'),\n auth: _.get(json, 'request.auth.mode', 'none'),\n body: _.get(json, 'request.body.mode', 'none')\n };\n bruJson.params = _.get(json, 'request.params', []);\n bruJson.body = _.get(json, 'request.body', {\n mode: 'json',\n json: '{}'\n });\n } else if (type === 'grpc') {\n // For gRPC, add gRPC-specific structure but maintain field names\n bruJson.grpc = {\n url: _.get(json, 'request.url'),\n auth: _.get(json, 'request.auth.mode', 'none'),\n body: _.get(json, 'request.body.mode', 'grpc')\n };\n // Only add method if it exists\n const method = _.get(json, 'request.method');\n const methodType = _.get(json, 'request.methodType');\n const protoPath = _.get(json, 'request.protoPath');\n if (method) bruJson.grpc.method = method;\n if (methodType) bruJson.grpc.methodType = methodType;\n if (protoPath) bruJson.grpc.protoPath = protoPath;\n bruJson.body = _.get(json, 'request.body', {\n mode: 'grpc',\n grpc: _.get(json, 'request.body.grpc', [\n {\n name: 'message 1',\n content: '{}'\n }\n ])\n });\n } else if (type === 'ws') {\n bruJson.ws = {\n url: _.get(json, 'request.url'),\n auth: _.get(json, 'request.auth.mode', 'none'),\n body: _.get(json, 'request.body.mode', 'ws')\n };\n\n bruJson.body = _.get(json, 'request.body', {\n mode: 'ws',\n ws: _.get(json, 'request.body.ws', [\n {\n name: 'message 1',\n content: '{}'\n }\n ])\n });\n }\n\n // Common fields for all request types\n if (type === 'grpc') {\n bruJson.metadata = _.get(json, 'request.headers', []); // Use metadata for gRPC\n } else {\n bruJson.headers = _.get(json, 'request.headers', []); // Use headers for HTTP/GraphQL\n }\n bruJson.auth = _.get(json, 'request.auth', {});\n bruJson.script = _.get(json, 'request.script', {});\n bruJson.vars = {\n req: _.get(json, 'request.vars.req', []),\n res: _.get(json, 'request.vars.res', [])\n };\n // should we add assertions and tests for grpc requests?\n bruJson.assertions = _.get(json, 'request.assertions', []);\n bruJson.tests = _.get(json, 'request.tests', '');\n bruJson.settings = _.get(json, 'settings', {});\n bruJson.docs = _.get(json, 'request.docs', '');\n bruJson.examples = _.get(json, 'examples', []).map((e: any) => jsonExampleToBru(e));\n\n const bru = jsonToBruV2(bruJson);\n return bru;\n } catch (error) {\n throw error;\n }\n};\n\nexport const parseBruCollection = (data: string | any, parsed: boolean = false): any => {\n try {\n const json = parsed ? data : _collectionBruToJson(data);\n\n const transformedJson: any = {\n request: {\n headers: _.get(json, 'headers', []),\n auth: _.get(json, 'auth', {}),\n script: _.get(json, 'script', {}),\n vars: _.get(json, 'vars', {}),\n tests: _.get(json, 'tests', '')\n },\n settings: _.get(json, 'settings', {}),\n docs: _.get(json, 'docs', '')\n };\n\n // add meta if it exists\n // this is only for folder bru file\n if (json.meta) {\n transformedJson.meta = {\n name: json.meta.name\n };\n\n // Include seq if it exists\n if (json.meta.seq !== undefined) {\n const sequence = json.meta.seq;\n transformedJson.meta.seq = !isNaN(sequence) ? Number(sequence) : 1;\n }\n }\n\n // add oauth2 additional parameters if they exist\n const hasOauth2GrantType = json?.auth?.oauth2?.grantType;\n if (hasOauth2GrantType) {\n const additionalParameters = getOauth2AdditionalParameters(json);\n const hasAdditionalParameters = Object.keys(additionalParameters).length > 0;\n if (hasAdditionalParameters) {\n transformedJson.request.auth.oauth2.additionalParameters = additionalParameters;\n }\n }\n\n return transformedJson;\n } catch (error) {\n return Promise.reject(error);\n }\n};\n\nexport const stringifyBruCollection = (json: any, isFolder?: boolean): string => {\n try {\n const collectionBruJson: any = {\n headers: _.get(json, 'request.headers', []),\n script: {\n req: _.get(json, 'request.script.req', ''),\n res: _.get(json, 'request.script.res', '')\n },\n vars: {\n req: _.get(json, 'request.vars.req', []),\n res: _.get(json, 'request.vars.res', [])\n },\n tests: _.get(json, 'request.tests', ''),\n auth: _.get(json, 'request.auth', {}),\n docs: _.get(json, 'docs', '')\n };\n\n // add meta if it exists\n // this is only for folder bru file\n if (json?.meta) {\n collectionBruJson.meta = {\n name: json.meta.name\n };\n\n // Include seq if it exists\n if (json.meta.seq !== undefined) {\n const sequence = json.meta.seq;\n collectionBruJson.meta.seq = !isNaN(sequence) ? Number(sequence) : 1;\n }\n }\n\n if (!isFolder) {\n collectionBruJson.auth = _.get(json, 'request.auth', {});\n }\n\n return _jsonToCollectionBru(collectionBruJson);\n } catch (error) {\n throw error;\n }\n};\n\nexport const parseBruEnvironment = (bru: string): any => {\n try {\n const json = bruToEnvJsonV2(bru);\n\n // the app env format requires each variable to have a type\n // this need to be evaluated and safely removed\n // i don't see it being used in schema validation\n if (json && json.variables && json.variables.length) {\n _.each(json.variables, (v: any) => (v.type = 'text'));\n }\n\n return json;\n } catch (error) {\n return Promise.reject(error);\n }\n};\n\nexport const stringifyBruEnvironment = (json: any): string => {\n try {\n const bru = envJsonToBruV2(json);\n return bru;\n } catch (error) {\n throw error;\n }\n};\n\n// New functions for example handling\nexport const bruExampleToJson = (data: string | any, parsed: boolean = false, parentType?: string, parentMethod?: string): any => {\n try {\n const json = parsed ? data : bruToJsonV2(data);\n\n // Use parent request's type and method if provided\n const requestType = parentType || _.get(json, 'meta.type', 'http');\n const requestMethod = parentMethod || _.get(json, 'http.method', 'GET');\n\n let transformedType = requestType;\n switch (requestType) {\n case 'http':\n transformedType = 'http-request';\n break;\n case 'graphql':\n transformedType = 'graphql-request';\n break;\n case 'grpc':\n transformedType = 'grpc-request';\n break;\n case 'ws':\n transformedType = 'ws-request';\n break;\n default:\n transformedType = 'http-request';\n }\n\n /**\n * Backward compatibility (pre-v3.0.2 - v3.2.0): Postman imports before PR #6876 stored status/statusText swapped\n * (code: \"OK\", text: \"202\" instead of code: 202, text: \"OK\"). Detect and swap back.\n * TODO(Sid / Shubh): Remove after v5 — all collections should be migrated by then.\n */\n let status = _.get(json, 'response.status', '200');\n let statusText = _.get(json, 'response.statusText', 'OK');\n if (isNaN(Number(status)) && !isNaN(Number(statusText))) {\n [status, statusText] = [statusText, status];\n }\n\n // Follow the same structure as the main request, but with missing fields for examples\n const transformedJson = {\n type: transformedType,\n name: _.get(json, 'name'),\n description: _.get(json, 'description', ''),\n // Examples don't have seq, settings, tags\n request: {\n method: _.get(json, 'request.method') || requestMethod,\n url: _.get(json, 'request.url'),\n headers: _.get(json, 'request.headers', []),\n body: _.get(json, 'request.body', {\n mode: 'none'\n }),\n // Examples don't have script, vars, assertions, tests, docs\n params: _.get(json, 'request.params', [])\n },\n response: {\n headers: _.get(json, 'response.headers', []).map((header: any) => ({\n name: header.name,\n value: header.value\n })),\n status: Number(status) || 200,\n statusText: statusText || 'OK',\n body: {\n type: _.get(json, 'response.body.type', 'json'),\n content: _.get(json, 'response.body.content', '')\n }\n }\n } as any;\n\n return transformedJson;\n } catch (error) {\n console.log('bruExampleToJson error', error);\n throw error;\n }\n};\n\nexport const jsonExampleToBru = (json: any) => {\n try {\n // Transform the JSON to match the same structure as main request, but with missing fields\n const exampleJson = {\n name: _.get(json, 'name'),\n description: _.get(json, 'description', ''),\n // Examples don't have seq, settings, tags\n request: {\n method: _.get(json, 'request.method'),\n url: _.get(json, 'request.url'),\n headers: _.get(json, 'request.headers', []),\n body: _.get(json, 'request.body', {}),\n // Examples don't have script, vars, assertions, tests, docs\n params: _.get(json, 'request.params', [])\n },\n response: _.get(json, 'response', {})\n };\n\n return exampleJson;\n } catch (error) {\n throw error;\n }\n};\n","import * as YAML from 'yaml';\n\n// Top-level keys that should have a blank line before them\nconst BLOCK_KEYS = ['info', 'http', 'graphql', 'grpc', 'websocket', 'runtime', 'settings', 'examples', 'docs', 'items', 'request'];\n\nexport const stringifyYml = (obj: any): string => {\n const yamlStr = YAML.stringify(obj, {\n lineWidth: 0,\n indent: 2,\n minContentWidth: 0,\n defaultStringType: 'PLAIN'\n });\n\n // Add blank lines before major blocks (only at the top level, not indented)\n const lines = yamlStr.split('\\n');\n const result: string[] = [];\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n // Check if this is a top-level key (no leading whitespace) that should have a blank line\n if (i > 0 && !line.startsWith(' ') && !line.startsWith('\\t')) {\n const key = line.split(':')[0];\n if (BLOCK_KEYS.includes(key)) {\n // Add blank line before this block (if previous line isn't already blank)\n if (result.length > 0 && result[result.length - 1].trim() !== '') {\n result.push('');\n }\n }\n }\n result.push(line);\n }\n\n return result.join('\\n');\n};\n\nexport const parseYml = (ymlString: string): any => {\n return YAML.parse(ymlString);\n};\n","const { customAlphabet } = require('nanoid');\n\nexport const isString = (value: unknown): value is string => typeof value === 'string';\n\nexport const isNumber = (value: unknown): value is number => typeof value === 'number';\n\nexport const isNonEmptyString = (value: unknown): value is string => isString(value) && value.trim().length > 0;\n\nexport const ensureString = (value: unknown, fallback: string = ''): string => {\n if (value === null || value === undefined) {\n return fallback;\n }\n if (typeof value === 'string') {\n return value;\n }\n return String(value);\n};\n\nexport const uuid = () => {\n // https://github.com/ai/nanoid/blob/main/url-alphabet/index.js\n const urlAlphabet = 'useandom26T198340PX75pxJACKVERYMINDBUSHWOLFGQZbfghjklqvwyzrict';\n const customNanoId = customAlphabet(urlAlphabet, 21);\n\n return customNanoId();\n};\n","import type {\n AuthOAuth2,\n OAuth2AdditionalParameter,\n OAuth2AuthorizationCodeFlow,\n OAuth2ClientCredentials,\n OAuth2ClientCredentialsFlow,\n OAuth2ImplicitFlow,\n OAuth2PKCE,\n OAuth2ResourceOwner,\n OAuth2ResourceOwnerPasswordFlow,\n OAuth2Settings,\n OAuth2TokenConfig\n} from '@opencollection/types/common/auth';\nimport type {\n OAuth2 as BrunoOAuth2,\n OAuthAdditionalParameter as BrunoOAuthAdditionalParameter\n} from '@usebruno/schema-types/common/auth';\nimport { isString, isNonEmptyString } from '../../../utils';\n\nconst normalizeBoolean = (value?: boolean | null): boolean | undefined =>\n typeof value === 'boolean' ? value : undefined;\n\nconst mapSendIn = (sendIn?: string | null): OAuth2AdditionalParameter['placement'] | undefined => {\n if (!isString(sendIn)) {\n return undefined;\n }\n\n switch (sendIn.trim().toLowerCase()) {\n case 'headers':\n return 'header';\n case 'queryparams':\n return 'query';\n case 'body':\n return 'body';\n default:\n return undefined;\n }\n};\n\nconst mapAdditionalParameters = (params?: BrunoOAuthAdditionalParameter[] | null): OAuth2AdditionalParameter[] | undefined => {\n if (!Array.isArray(params) || params.length === 0) {\n return undefined;\n }\n\n const mapped = params\n .filter((param) => param && isNonEmptyString(param.name))\n .map((param) => {\n const placement = mapSendIn(param!.sendIn);\n if (!placement) {\n return undefined;\n }\n\n const mappedParam: OAuth2AdditionalParameter = {\n name: param!.name!.trim(),\n placement\n };\n\n isNonEmptyString(param!.value) && (mappedParam.value = param.value);\n\n return mappedParam;\n })\n .filter((param): param is OAuth2AdditionalParameter => Boolean(param));\n\n return mapped.length > 0 ? mapped : undefined;\n};\n\nconst buildClientCredentials = (oauth: BrunoOAuth2): OAuth2ClientCredentials | undefined => {\n const credentials: OAuth2ClientCredentials = {};\n\n isNonEmptyString(oauth.clientId) && (credentials.clientId = oauth.clientId);\n isNonEmptyString(oauth.clientSecret) && (credentials.clientSecret = oauth.clientSecret);\n isNonEmptyString(oauth.credentialsPlacement) && (credentials.placement = oauth.credentialsPlacement);\n\n return Object.keys(credentials).length > 0 ? credentials : undefined;\n};\n\nconst buildResourceOwner = (oauth: BrunoOAuth2): OAuth2ResourceOwner | undefined => {\n const resourceOwner: OAuth2ResourceOwner = {};\n\n isNonEmptyString(oauth.username) && (resourceOwner.username = oauth.username);\n isNonEmptyString(oauth.password) && (resourceOwner.password = oauth.password);\n\n return Object.keys(resourceOwner).length > 0 ? resourceOwner : undefined;\n};\n\nconst buildPkce = (pkce?: boolean | null): OAuth2PKCE | undefined => {\n if (pkce === null || pkce === undefined) {\n return undefined;\n }\n\n // If pkce is false, set disabled: true; if true, return empty object (enabled by default)\n return pkce ? {} : { disabled: true };\n};\n\nconst buildTokenConfig = (oauth: BrunoOAuth2): OAuth2TokenConfig | undefined => {\n const tokenConfig: OAuth2TokenConfig = {};\n\n isNonEmptyString(oauth.credentialsId) && (tokenConfig.id = oauth.credentialsId);\n\n if (!isNonEmptyString(oauth.tokenPlacement)) {\n // default to header\n tokenConfig.placement = { header: '' };\n }\n\n if (oauth.tokenPlacement === 'header') {\n tokenConfig.placement = {\n header: oauth.tokenHeaderPrefix as string\n };\n }\n\n if (oauth.tokenPlacement === 'url') {\n tokenConfig.placement = {\n query: oauth.tokenQueryKey as string\n };\n }\n\n tokenConfig.source = oauth.tokenSource || 'access_token';\n\n return Object.keys(tokenConfig).length > 0 ? tokenConfig : undefined;\n};\n\nconst buildSettings = (oauth: BrunoOAuth2): OAuth2Settings | undefined => {\n const autoFetchToken = normalizeBoolean(oauth.autoFetchToken);\n const autoRefreshToken = normalizeBoolean(oauth.autoRefreshToken);\n\n const settings: OAuth2Settings = {};\n if (autoFetchToken !== undefined) settings.autoFetchToken = autoFetchToken;\n if (autoRefreshToken !== undefined) settings.autoRefreshToken = autoRefreshToken;\n\n return Object.keys(settings).length > 0 ? settings : undefined;\n};\n\nconst buildClientCredentialsFlow = (oauth: BrunoOAuth2): OAuth2ClientCredentialsFlow => {\n const flow: OAuth2ClientCredentialsFlow = {\n type: 'oauth2',\n flow: 'client_credentials'\n };\n\n isNonEmptyString(oauth.accessTokenUrl) && (flow.accessTokenUrl = oauth.accessTokenUrl);\n isNonEmptyString(oauth.refreshTokenUrl) && (flow.refreshTokenUrl = oauth.refreshTokenUrl);\n\n const credentials = buildClientCredentials(oauth);\n if (credentials) flow.credentials = credentials;\n\n isNonEmptyString(oauth.scope) && (flow.scope = oauth.scope);\n\n const accessTokenRequest = mapAdditionalParameters(oauth.additionalParameters?.token);\n const refreshTokenRequest = mapAdditionalParameters(oauth.additionalParameters?.refresh);\n\n if (accessTokenRequest || refreshTokenRequest) {\n flow.additionalParameters = {};\n if (accessTokenRequest) {\n flow.additionalParameters.accessTokenRequest = accessTokenRequest;\n }\n if (refreshTokenRequest) {\n flow.additionalParameters.refreshTokenRequest = refreshTokenRequest;\n }\n }\n\n const tokenConfig = buildTokenConfig(oauth);\n if (tokenConfig) flow.tokenConfig = tokenConfig;\n\n const settings = buildSettings(oauth);\n if (settings) flow.settings = settings;\n\n return flow;\n};\n\nconst buildResourceOwnerPasswordFlow = (oauth: BrunoOAuth2): OAuth2ResourceOwnerPasswordFlow => {\n const flow: OAuth2ResourceOwnerPasswordFlow = {\n type: 'oauth2',\n flow: 'resource_owner_password_credentials'\n };\n\n isNonEmptyString(oauth.accessTokenUrl) && (flow.accessTokenUrl = oauth.accessTokenUrl);\n isNonEmptyString(oauth.refreshTokenUrl) && (flow.refreshTokenUrl = oauth.refreshTokenUrl);\n\n const credentials = buildClientCredentials(oauth);\n if (credentials) flow.credentials = credentials;\n\n const resourceOwner = buildResourceOwner(oauth);\n if (resourceOwner) flow.resourceOwner = resourceOwner;\n\n isNonEmptyString(oauth.scope) && (flow.scope = oauth.scope);\n\n const accessTokenRequest = mapAdditionalParameters(oauth.additionalParameters?.token);\n const refreshTokenRequest = mapAdditionalParameters(oauth.additionalParameters?.refresh);\n\n if (accessTokenRequest || refreshTokenRequest) {\n flow.additionalParameters = {};\n if (accessTokenRequest) {\n flow.additionalParameters.accessTokenRequest = accessTokenRequest;\n }\n if (refreshTokenRequest) {\n flow.additionalParameters.refreshTokenRequest = refreshTokenRequest;\n }\n }\n\n const tokenConfig = buildTokenConfig(oauth);\n if (tokenConfig) flow.tokenConfig = tokenConfig;\n\n const settings = buildSettings(oauth);\n if (settings) flow.settings = settings;\n\n return flow;\n};\n\nconst buildAuthorizationCodeFlow = (oauth: BrunoOAuth2): OAuth2AuthorizationCodeFlow => {\n const flow: OAuth2AuthorizationCodeFlow = {\n type: 'oauth2',\n flow: 'authorization_code'\n };\n\n isNonEmptyString(oauth.authorizationUrl) && (flow.authorizationUrl = oauth.authorizationUrl);\n isNonEmptyString(oauth.accessTokenUrl) && (flow.accessTokenUrl = oauth.accessTokenUrl);\n isNonEmptyString(oauth.refreshTokenUrl) && (flow.refreshTokenUrl = oauth.refreshTokenUrl);\n isNonEmptyString(oauth.callbackUrl) && (flow.callbackUrl = oauth.callbackUrl);\n\n const credentials = buildClientCredentials(oauth);\n if (credentials) flow.credentials = credentials;\n\n const authorizationRequest = mapAdditionalParameters(oauth.additionalParameters?.authorization);\n const accessTokenRequest = mapAdditionalParameters(oauth.additionalParameters?.token);\n const refreshTokenRequest = mapAdditionalParameters(oauth.additionalParameters?.refresh);\n\n if (authorizationRequest || accessTokenRequest || refreshTokenRequest) {\n flow.additionalParameters = {};\n if (authorizationRequest) {\n flow.additionalParameters.authorizationRequest = authorizationRequest;\n }\n if (accessTokenRequest) {\n flow.additionalParameters.accessTokenRequest = accessTokenRequest;\n }\n if (refreshTokenRequest) {\n flow.additionalParameters.refreshTokenRequest = refreshTokenRequest;\n }\n }\n\n isNonEmptyString(oauth.scope) && (flow.scope = oauth.scope);\n isNonEmptyString(oauth.state) && (flow.state = oauth.state);\n\n const pkce = buildPkce(oauth.pkce);\n if (pkce) flow.pkce = pkce;\n\n const tokenConfig = buildTokenConfig(oauth);\n if (tokenConfig) flow.tokenConfig = tokenConfig;\n\n const settings = buildSettings(oauth);\n if (settings) flow.settings = settings;\n\n return flow;\n};\n\nconst buildImplicitFlow = (oauth: BrunoOAuth2): OAuth2ImplicitFlow => {\n const flow: OAuth2ImplicitFlow = {\n type: 'oauth2',\n flow: 'implicit'\n };\n\n isNonEmptyString(oauth.authorizationUrl) && (flow.authorizationUrl = oauth.authorizationUrl);\n isNonEmptyString(oauth.callbackUrl) && (flow.callbackUrl = oauth.callbackUrl);\n isNonEmptyString(oauth.clientId) && (flow.credentials = { clientId: oauth.clientId });\n isNonEmptyString(oauth.scope) && (flow.scope = oauth.scope);\n isNonEmptyString(oauth.state) && (flow.state = oauth.state);\n\n const authorizationRequest = mapAdditionalParameters(oauth.additionalParameters?.authorization);\n if (authorizationRequest) {\n flow.additionalParameters = { authorizationRequest };\n }\n\n const tokenConfig = buildTokenConfig(oauth);\n if (tokenConfig) flow.tokenConfig = tokenConfig;\n\n const settings = buildSettings(oauth);\n if (settings) flow.settings = settings;\n\n return flow;\n};\n\nexport const toOpenCollectionOAuth2 = (oauth?: BrunoOAuth2 | null): AuthOAuth2 | undefined => {\n if (!oauth) {\n return undefined;\n }\n\n switch (oauth.grantType) {\n case 'client_credentials':\n return buildClientCredentialsFlow(oauth);\n case 'password':\n return buildResourceOwnerPasswordFlow(oauth);\n case 'authorization_code':\n return buildAuthorizationCodeFlow(oauth);\n case 'implicit':\n return buildImplicitFlow(oauth);\n default:\n console.warn(`toOpenCollectionOAuth2: Unsupported OAuth2 grant type \"${oauth.grantType}\".`);\n return undefined;\n }\n};\n\nconst reversePlacementMapping = (placement?: OAuth2AdditionalParameter['placement']): 'headers' | 'queryparams' | 'body' | null => {\n if (!placement) {\n return null;\n }\n\n switch (placement) {\n case 'header':\n return 'headers';\n case 'query':\n return 'queryparams';\n case 'body':\n return 'body';\n default:\n return null;\n }\n};\n\nconst reverseAdditionalParameters = (params?: OAuth2AdditionalParameter[]): BrunoOAuthAdditionalParameter[] | null => {\n if (!Array.isArray(params) || params.length === 0) {\n return null;\n }\n\n const mapped = params.map((param): BrunoOAuthAdditionalParameter => {\n const sendIn = reversePlacementMapping(param.placement);\n\n return {\n name: param.name || null,\n value: param.value || null,\n sendIn: sendIn || 'headers',\n enabled: true\n };\n });\n\n return mapped.length > 0 ? mapped : null;\n};\n\nexport const toBrunoOAuth2 = (oauth: AuthOAuth2 | null | undefined): BrunoOAuth2 | null => {\n if (!oauth) {\n return null;\n }\n\n const brunoOAuth: BrunoOAuth2 = {\n grantType: 'authorization_code',\n username: null,\n password: null,\n callbackUrl: null,\n authorizationUrl: null,\n accessTokenUrl: null,\n clientId: null,\n clientSecret: null,\n scope: null,\n state: null,\n pkce: false, // Default to false for all grant types\n credentialsPlacement: null,\n credentialsId: null,\n tokenPlacement: null,\n tokenHeaderPrefix: null,\n tokenQueryKey: null,\n tokenSource: 'access_token',\n refreshTokenUrl: null,\n autoRefreshToken: false, // Default to false\n autoFetchToken: true, // Default to true\n additionalParameters: null\n };\n\n switch (oauth.flow) {\n case 'client_credentials':\n brunoOAuth.grantType = 'client_credentials';\n if (oauth.accessTokenUrl) brunoOAuth.accessTokenUrl = oauth.accessTokenUrl;\n if (oauth.refreshTokenUrl) brunoOAuth.refreshTokenUrl = oauth.refreshTokenUrl;\n if (oauth.credentials?.clientId) brunoOAuth.clientId = oauth.credentials.clientId;\n if (oauth.credentials?.clientSecret) brunoOAuth.clientSecret = oauth.credentials.clientSecret;\n if (oauth.credentials?.placement) brunoOAuth.credentialsPlacement = oauth.credentials.placement;\n if (oauth.scope) brunoOAuth.scope = oauth.scope;\n\n // token config\n if (oauth.tokenConfig?.id) brunoOAuth.credentialsId = oauth.tokenConfig.id;\n if (oauth.tokenConfig?.source) brunoOAuth.tokenSource = oauth.tokenConfig.source || 'access_token';\n if (oauth.tokenConfig?.placement) {\n if ('header' in oauth.tokenConfig.placement) {\n brunoOAuth.tokenPlacement = 'header';\n brunoOAuth.tokenHeaderPrefix = oauth.tokenConfig.placement.header || '';\n } else if ('query' in oauth.tokenConfig.placement) {\n brunoOAuth.tokenPlacement = 'url';\n brunoOAuth.tokenQueryKey = oauth.tokenConfig.placement.query || '';\n }\n }\n\n // additional parameters\n if (oauth.additionalParameters) {\n const tempParams: Record<string, any> = {};\n if (oauth.additionalParameters.accessTokenRequest) {\n const tokenParams = reverseAdditionalParameters(oauth.additionalParameters.accessTokenRequest);\n if (tokenParams) {\n tempParams.token = tokenParams;\n }\n }\n if (oauth.additionalParameters.refreshTokenRequest) {\n const refreshParams = reverseAdditionalParameters(oauth.additionalParameters.refreshTokenRequest);\n if (refreshParams) {\n tempParams.refresh = refreshParams;\n }\n }\n // Only set additionalParameters if there are actual parameters\n if (Object.keys(tempParams).length > 0) {\n brunoOAuth.additionalParameters = tempParams;\n }\n }\n break;\n\n case 'resource_owner_password_credentials':\n brunoOAuth.grantType = 'password';\n if (oauth.accessTokenUrl) brunoOAuth.accessTokenUrl = oauth.accessTokenUrl;\n if (oauth.refreshTokenUrl) brunoOAuth.refreshTokenUrl = oauth.refreshTokenUrl;\n if (oauth.credentials?.clientId) brunoOAuth.clientId = oauth.credentials.clientId;\n if (oauth.credentials?.clientSecret) brunoOAuth.clientSecret = oauth.credentials.clientSecret;\n if (oauth.credentials?.placement) brunoOAuth.credentialsPlacement = oauth.credentials.placement;\n if (oauth.resourceOwner?.username) brunoOAuth.username = oauth.resourceOwner.username;\n if (oauth.resourceOwner?.password) brunoOAuth.password = oauth.resourceOwner.password;\n if (oauth.scope) brunoOAuth.scope = oauth.scope;\n\n // token config\n if (oauth.tokenConfig?.id) brunoOAuth.credentialsId = oauth.tokenConfig.id;\n if (oauth.tokenConfig?.source) brunoOAuth.tokenSource = oauth.tokenConfig.source || 'access_token';\n if (oauth.tokenConfig?.placement) {\n if ('header' in oauth.tokenConfig.placement) {\n brunoOAuth.tokenPlacement = 'header';\n brunoOAuth.tokenHeaderPrefix = oauth.tokenConfig.placement.header || '';\n } else if ('query' in oauth.tokenConfig.placement) {\n brunoOAuth.tokenPlacement = 'url';\n brunoOAuth.tokenQueryKey = oauth.tokenConfig.placement.query || '';\n }\n }\n\n // additional parameters\n if (oauth.additionalParameters) {\n const tempParams: Record<string, any> = {};\n if (oauth.additionalParameters.accessTokenRequest) {\n const tokenParams = reverseAdditionalParameters(oauth.additionalParameters.accessTokenRequest);\n if (tokenParams) {\n tempParams.token = tokenParams;\n }\n }\n if (oauth.additionalParameters.refreshTokenRequest) {\n const refreshParams = reverseAdditionalParameters(oauth.additionalParameters.refreshTokenRequest);\n if (refreshParams) {\n tempParams.refresh = refreshParams;\n }\n }\n // Only set additionalParameters if there are actual parameters\n if (Object.keys(tempParams).length > 0) {\n brunoOAuth.additionalParameters = tempParams;\n }\n }\n break;\n\n case 'authorization_code':\n brunoOAuth.grantType = 'authorization_code';\n if (oauth.authorizationUrl) brunoOAuth.authorizationUrl = oauth.authorizationUrl;\n if (oauth.accessTokenUrl) brunoOAuth.accessTokenUrl = oauth.accessTokenUrl;\n if (oauth.refreshTokenUrl) brunoOAuth.refreshTokenUrl = oauth.refreshTokenUrl;\n if (oauth.callbackUrl) brunoOAuth.callbackUrl = oauth.callbackUrl;\n if (oauth.credentials?.clientId) brunoOAuth.clientId = oauth.credentials.clientId;\n if (oauth.credentials?.clientSecret) brunoOAuth.clientSecret = oauth.credentials.clientSecret;\n if (oauth.credentials?.placement) brunoOAuth.credentialsPlacement = oauth.credentials.placement;\n if (oauth.scope) brunoOAuth.scope = oauth.scope;\n if (oauth.state) brunoOAuth.state = oauth.state;\n\n // token config\n if (oauth.tokenConfig?.id) brunoOAuth.credentialsId = oauth.tokenConfig.id;\n if (oauth.tokenConfig?.source) brunoOAuth.tokenSource = oauth.tokenConfig.source || 'access_token';\n if (oauth.tokenConfig?.placement) {\n if ('header' in oauth.tokenConfig.placement) {\n brunoOAuth.tokenPlacement = 'header';\n brunoOAuth.tokenHeaderPrefix = oauth.tokenConfig.placement.header || '';\n } else if ('query' in oauth.tokenConfig.placement) {\n brunoOAuth.tokenPlacement = 'url';\n brunoOAuth.tokenQueryKey = oauth.tokenConfig.placement.query || '';\n }\n }\n\n // additional parameters\n if (oauth.additionalParameters) {\n const tempParams: Record<string, any> = {};\n if (oauth.additionalParameters.authorizationRequest) {\n const authParams = reverseAdditionalParameters(oauth.additionalParameters.authorizationRequest);\n if (authParams) {\n tempParams.authorization = authParams;\n }\n }\n if (oauth.additionalParameters.accessTokenRequest) {\n const tokenParams = reverseAdditionalParameters(oauth.additionalParameters.accessTokenRequest);\n if (tokenParams) {\n tempParams.token = tokenParams;\n }\n }\n if (oauth.additionalParameters.refreshTokenRequest) {\n const refreshParams = reverseAdditionalParameters(oauth.additionalParameters.refreshTokenRequest);\n if (refreshParams) {\n tempParams.refresh = refreshParams;\n }\n }\n // Only set additionalParameters if there are actual parameters\n if (Object.keys(tempParams).length > 0) {\n brunoOAuth.additionalParameters = tempParams;\n }\n }\n break;\n\n case 'implicit':\n brunoOAuth.grantType = 'implicit';\n if (oauth.authorizationUrl) brunoOAuth.authorizationUrl = oauth.authorizationUrl;\n if (oauth.callbackUrl) brunoOAuth.callbackUrl = oauth.callbackUrl;\n if (oauth.credentials?.clientId) brunoOAuth.clientId = oauth.credentials.clientId;\n if (oauth.scope) brunoOAuth.scope = oauth.scope;\n if (oauth.state) brunoOAuth.state = oauth.state;\n\n // token config\n if (oauth.tokenConfig?.id) brunoOAuth.credentialsId = oauth.tokenConfig.id;\n if (oauth.tokenConfig?.source) brunoOAuth.tokenSource = oauth.tokenConfig.source || 'access_token';\n if (oauth.tokenConfig?.placement) {\n if ('header' in oauth.tokenConfig.placement) {\n brunoOAuth.tokenPlacement = 'header';\n brunoOAuth.tokenHeaderPrefix = oauth.tokenConfig.placement.header || '';\n } else if ('query' in oauth.tokenConfig.placement) {\n brunoOAuth.tokenPlacement = 'url';\n brunoOAuth.tokenQueryKey = oauth.tokenConfig.placement.query || '';\n }\n }\n\n // additional parameters\n if (oauth.additionalParameters) {\n const tempParams: Record<string, any> = {};\n if (oauth.additionalParameters.authorizationRequest) {\n const authParams = reverseAdditionalParameters(oauth.additionalParameters.authorizationRequest);\n if (authParams) {\n tempParams.authorization = authParams;\n }\n }\n // Only set additionalParameters if there are actual parameters\n if (Object.keys(tempParams).length > 0) {\n brunoOAuth.additionalParameters = tempParams;\n }\n }\n break;\n\n default:\n return null;\n }\n\n if (oauth.settings?.autoFetchToken !== undefined) {\n brunoOAuth.autoFetchToken = oauth.settings.autoFetchToken;\n }\n if (oauth.settings?.autoRefreshToken !== undefined) {\n brunoOAuth.autoRefreshToken = oauth.settings.autoRefreshToken;\n }\n\n if (brunoOAuth.grantType === 'authorization_code' && oauth.flow === 'authorization_code') {\n const authCodeFlow = oauth as OAuth2AuthorizationCodeFlow;\n if (authCodeFlow.pkce !== undefined) {\n // If pkce.disabled is true, set pkce to false; otherwise set to true\n brunoOAuth.pkce = !authCodeFlow.pkce.disabled;\n }\n }\n\n if (brunoOAuth.additionalParameters === null) {\n delete brunoOAuth.additionalParameters;\n }\n\n return brunoOAuth;\n};\n","import type {\n Auth,\n AuthApiKey,\n AuthAwsV4,\n AuthBasic,\n AuthBearer,\n AuthDigest,\n AuthNTLM,\n AuthOAuth1,\n AuthWsse\n} from '@opencollection/types/common/auth';\nimport type { Auth as BrunoAuth, AuthOauth1 as BrunoAuthOauth1 } from '@usebruno/schema-types/common/auth';\nimport { isString } from '../../../utils';\nimport { toOpenCollectionOAuth2, toBrunoOAuth2 } from './auth-oauth2';\n\nconst buildAwsV4Auth = (config?: BrunoAuth['awsv4']): AuthAwsV4 => {\n const auth: AuthAwsV4 = { type: 'awsv4' };\n\n if (!config) {\n return auth;\n }\n\n if (isString(config.accessKeyId)) auth.accessKeyId = config.accessKeyId;\n if (isString(config.secretAccessKey)) auth.secretAccessKey = config.secretAccessKey;\n if (isString(config.sessionToken)) auth.sessionToken = config.sessionToken;\n if (isString(config.service)) auth.service = config.service;\n if (isString(config.region)) auth.region = config.region;\n if (isString(config.profileName)) auth.profileName = config.profileName;\n\n return auth;\n};\n\nconst buildBasicAuth = (config?: BrunoAuth['basic']): AuthBasic => {\n const auth: AuthBasic = { type: 'basic' };\n\n if (!config) {\n return auth;\n }\n\n if (isString(config.username)) auth.username = config.username;\n if (isString(config.password)) auth.password = config.password;\n\n return auth;\n};\n\nconst buildBearerAuth = (config?: BrunoAuth['bearer']): AuthBearer => {\n const auth: AuthBearer = { type: 'bearer' };\n\n if (!config) {\n return auth;\n }\n\n if (isString(config.token)) auth.token = config.token;\n\n return auth;\n};\n\nconst buildDigestAuth = (config?: BrunoAuth['digest']): AuthDigest => {\n const auth: AuthDigest = { type: 'digest' };\n\n if (!config) {\n return auth;\n }\n\n if (isString(config.username)) auth.username = config.username;\n if (isString(config.password)) auth.password = config.password;\n\n return auth;\n};\n\nconst buildNtlmAuth = (config?: BrunoAuth['ntlm']): AuthNTLM => {\n const auth: AuthNTLM = { type: 'ntlm' };\n\n if (!config) {\n return auth;\n }\n\n if (isString(config.username)) auth.username = config.username;\n if (isString(config.password)) auth.password = config.password;\n if (isString(config.domain)) auth.domain = config.domain;\n\n return auth;\n};\n\nconst buildWsseAuth = (config?: BrunoAuth['wsse']): AuthWsse => {\n const auth: AuthWsse = { type: 'wsse' };\n\n if (!config) {\n return auth;\n }\n\n if (isString(config.username)) auth.username = config.username;\n if (isString(config.password)) auth.password = config.password;\n\n return auth;\n};\n\nconst buildApiKeyAuth = (config?: BrunoAuth['apikey']): AuthApiKey => {\n const auth: AuthApiKey = { type: 'apikey' };\n\n if (!config) {\n return auth;\n }\n\n if (isString(config.key)) auth.key = config.key;\n if (isString(config.value)) auth.value = config.value;\n\n if (isString(config.placement)) {\n if (config.placement === 'header') {\n auth.placement = 'header';\n } else if (config.placement === 'queryparams') {\n auth.placement = 'query';\n }\n }\n\n return auth;\n};\n\nconst buildOAuth1Auth = (config?: BrunoAuth['oauth1']): AuthOAuth1 => {\n const auth: AuthOAuth1 = { type: 'oauth1' };\n\n if (!config) {\n return auth;\n }\n\n if (isString(config.consumerKey)) auth.consumerKey = config.consumerKey;\n if (isString(config.consumerSecret)) auth.consumerSecret = config.consumerSecret;\n if (isString(config.accessToken)) auth.accessToken = config.accessToken;\n if (isString(config.accessTokenSecret)) auth.accessTokenSecret = config.accessTokenSecret;\n if (isString(config.callbackUrl)) auth.callbackUrl = config.callbackUrl;\n if (isString(config.verifier)) auth.verifier = config.verifier;\n if (isString(config.signatureMethod)) auth.signatureMethod = config.signatureMethod;\n if (isString(config.privateKey)) {\n auth.privateKey = config.privateKeyType === 'file'\n ? { type: 'file' as const, value: config.privateKey }\n : { type: 'text' as const, value: config.privateKey };\n }\n if (isString(config.timestamp)) auth.timestamp = config.timestamp;\n if (isString(config.nonce)) auth.nonce = config.nonce;\n if (isString(config.version)) auth.version = config.version;\n if (isString(config.realm)) auth.realm = config.realm;\n if (isString(config.placement)) auth.placement = config.placement as AuthOAuth1['placement'];\n if (typeof config.includeBodyHash === 'boolean') auth.includeBodyHash = config.includeBodyHash;\n\n return auth;\n};\n\nexport const toOpenCollectionAuth = (auth?: BrunoAuth | null): Auth | undefined => {\n if (!auth || auth.mode === 'none') {\n return undefined;\n }\n\n if (auth.mode === 'inherit') {\n return 'inherit';\n }\n\n switch (auth.mode) {\n case 'awsv4':\n return buildAwsV4Auth(auth.awsv4);\n case 'basic':\n return buildBasicAuth(auth.basic);\n case 'bearer':\n return buildBearerAuth(auth.bearer);\n case 'digest':\n return buildDigestAuth(auth.digest);\n case 'ntlm':\n return buildNtlmAuth(auth.ntlm);\n case 'wsse':\n return buildWsseAuth(auth.wsse);\n case 'apikey':\n return buildApiKeyAuth(auth.apikey);\n case 'oauth1':\n return buildOAuth1Auth(auth.oauth1);\n case 'oauth2':\n return toOpenCollectionOAuth2(auth.oauth2);\n default:\n console.warn(`toOpenCollectionAuth failed: Unsupported auth mode \"${auth.mode}\".`);\n return undefined;\n }\n};\n\nexport const toBrunoAuth = (auth: Auth | null | undefined): BrunoAuth | null => {\n const brunoAuth: BrunoAuth = {\n mode: 'none',\n awsv4: null,\n basic: null,\n bearer: null,\n digest: null,\n ntlm: null,\n oauth2: null,\n wsse: null,\n apikey: null\n };\n\n if (!auth) {\n return brunoAuth;\n }\n\n if (auth === 'inherit') {\n brunoAuth.mode = 'inherit';\n return brunoAuth;\n }\n\n switch (auth.type) {\n case 'awsv4':\n brunoAuth.mode = 'awsv4';\n brunoAuth.awsv4 = {\n accessKeyId: auth.accessKeyId || null,\n secretAccessKey: auth.secretAccessKey || null,\n sessionToken: auth.sessionToken || null,\n service: auth.service || null,\n region: auth.region || null,\n profileName: auth.profileName || null\n };\n break;\n\n case 'basic':\n brunoAuth.mode = 'basic';\n brunoAuth.basic = {\n username: auth.username || null,\n password: auth.password || null\n };\n break;\n\n case 'bearer':\n brunoAuth.mode = 'bearer';\n brunoAuth.bearer = {\n token: auth.token || ''\n };\n break;\n\n case 'digest':\n brunoAuth.mode = 'digest';\n brunoAuth.digest = {\n username: auth.username || null,\n password: auth.password || null\n };\n break;\n\n case 'ntlm':\n brunoAuth.mode = 'ntlm';\n brunoAuth.ntlm = {\n username: auth.username || null,\n password: auth.password || null,\n domain: auth.domain || null\n };\n break;\n\n case 'wsse':\n brunoAuth.mode = 'wsse';\n brunoAuth.wsse = {\n username: auth.username || null,\n password: auth.password || null\n };\n break;\n\n case 'apikey':\n brunoAuth.mode = 'apikey';\n brunoAuth.apikey = {\n key: auth.key || null,\n value: auth.value || null,\n placement: auth.placement === 'query' ? 'queryparams' : (auth.placement === 'header' ? 'header' : null)\n };\n break;\n\n case 'oauth1':\n brunoAuth.mode = 'oauth1';\n brunoAuth.oauth1 = {\n consumerKey: auth.consumerKey || null,\n consumerSecret: auth.consumerSecret || null,\n accessToken: auth.accessToken || null,\n accessTokenSecret: auth.accessTokenSecret || null,\n callbackUrl: auth.callbackUrl || null,\n verifier: auth.verifier || null,\n signatureMethod: (auth.signatureMethod as BrunoAuthOauth1['signatureMethod']) || 'HMAC-SHA1',\n privateKey: (typeof auth.privateKey === 'object' && auth.privateKey ? auth.privateKey.value : auth.privateKey) || null,\n privateKeyType: (typeof auth.privateKey === 'object' && auth.privateKey ? auth.privateKey.type : 'text') as BrunoAuthOauth1['privateKeyType'],\n timestamp: auth.timestamp || null,\n nonce: auth.nonce || null,\n version: auth.version || '1.0',\n realm: auth.realm || null,\n placement: (auth.placement as BrunoAuthOauth1['placement']) || 'header',\n includeBodyHash: auth.includeBodyHash || false\n };\n break;\n\n case 'oauth2':\n brunoAuth.mode = 'oauth2';\n brunoAuth.oauth2 = toBrunoOAuth2(auth);\n break;\n\n default:\n console.warn('toBrunoAuth failed: Unsupported auth type');\n break;\n }\n\n return brunoAuth;\n};\n","import type { FolderRequest as BrunoFolderRequest } from '@usebruno/schema-types/collection/folder';\nimport type { KeyValue as BrunoKeyValue } from '@usebruno/schema-types/common/key-value';\nimport type { HttpRequestHeader, HttpResponseHeader } from '@opencollection/types/requests/http';\nimport { uuid, ensureString } from '../../../utils';\n\nexport const toOpenCollectionHttpHeaders = (headers: BrunoFolderRequest['headers']): HttpRequestHeader[] | undefined => {\n if (!headers?.length) {\n return undefined;\n }\n\n const ocHeaders = headers.map((header: BrunoKeyValue): HttpRequestHeader => {\n const httpHeader: HttpRequestHeader = {\n name: header.name || '',\n value: header.value || ''\n };\n if (header?.description?.trim().length) {\n httpHeader.description = header.description;\n }\n if (header.enabled === false) {\n httpHeader.disabled = true;\n }\n return httpHeader;\n });\n\n return ocHeaders.length ? ocHeaders : undefined;\n};\n\nexport const toOpenCollectionResponseHeaders = (headers: BrunoFolderRequest['headers']): HttpResponseHeader[] | undefined => {\n if (!headers?.length) {\n return undefined;\n }\n\n const ocHeaders = headers.map((header: BrunoKeyValue): HttpResponseHeader => ({\n name: header.name || '',\n value: header.value || ''\n }));\n\n return ocHeaders.length ? ocHeaders : undefined;\n};\n\nexport const toBrunoHttpHeaders = (headers: HttpRequestHeader[] | HttpResponseHeader[] | null | undefined): BrunoKeyValue[] | undefined => {\n if (!headers?.length) {\n return undefined;\n }\n\n const brunoHeaders = headers.map((header): BrunoKeyValue => {\n const brunoHeader: BrunoKeyValue = {\n uid: uuid(),\n name: ensureString(header.name),\n value: ensureString(header.value),\n enabled: ('disabled' in header) ? header.disabled !== true : true\n };\n\n return brunoHeader;\n });\n\n return brunoHeaders.length ? brunoHeaders : undefined;\n};\n","import type { HttpRequestParam as BrunoHttpRequestParam } from '@usebruno/schema-types/requests/http';\nimport type { HttpRequestParam } from '@opencollection/types/requests/http';\nimport { uuid, ensureString } from '../../../utils';\n\nexport const toOpenCollectionParams = (params: BrunoHttpRequestParam[] | null | undefined): HttpRequestParam[] | undefined => {\n if (!params?.length) {\n return undefined;\n }\n\n const ocParams = params.map((param: BrunoHttpRequestParam): HttpRequestParam => {\n const ocParam: HttpRequestParam = {\n name: param.name || '',\n value: param.value || '',\n type: param.type\n };\n\n if (param?.description?.trim().length) {\n ocParam.description = param.description;\n }\n\n if (param.enabled === false) {\n ocParam.disabled = true;\n }\n\n return ocParam;\n });\n\n return ocParams.length ? ocParams : undefined;\n};\n\nexport const toBrunoParams = (params: HttpRequestParam[] | null | undefined): BrunoHttpRequestParam[] | undefined => {\n if (!params?.length) {\n return undefined;\n }\n\n const brunoParams = params.map((param: HttpRequestParam): BrunoHttpRequestParam => {\n const brunoParam: BrunoHttpRequestParam = {\n uid: uuid(),\n name: ensureString(param.name),\n value: ensureString(param.value),\n type: param.type,\n enabled: param.disabled !== true\n };\n\n if (param.description) {\n if (typeof param.description === 'string' && param.description.trim().length) {\n brunoParam.description = param.description;\n } else if (typeof param.description === 'object' && param.description.content?.trim().length) {\n brunoParam.description = param.description.content;\n }\n }\n\n return brunoParam;\n });\n\n return brunoParams.length ? brunoParams : undefined;\n};\n","import type { HttpRequestBody as BrunoHttpRequestBody } from '@usebruno/schema-types/requests/http';\nimport type {\n HttpRequestBody,\n RawBody,\n FormUrlEncodedBody,\n FormUrlEncodedEntry,\n MultipartFormBody,\n MultipartFormEntry,\n FileBody,\n FileBodyEntry\n} from '@opencollection/types/requests/http';\nimport type { KeyValue as BrunoKeyValue } from '@usebruno/schema-types/common/key-value';\nimport { uuid, ensureString } from '../../../utils';\n\nexport const toOpenCollectionBody = (body: BrunoHttpRequestBody | null | undefined): HttpRequestBody | undefined => {\n if (!body) {\n return undefined;\n }\n\n switch (body.mode) {\n case 'none':\n return undefined;\n\n case 'json':\n const rawBody: RawBody = {\n type: 'json',\n data: body.json || ''\n };\n return rawBody;\n\n case 'text':\n const textBody: RawBody = {\n type: 'text',\n data: body.text || ''\n };\n return textBody;\n\n case 'xml':\n const xmlBody: RawBody = {\n type: 'xml',\n data: body.xml || ''\n };\n return xmlBody;\n\n case 'sparql':\n const sparqlBody: RawBody = {\n type: 'sparql',\n data: body.sparql || ''\n };\n return sparqlBody;\n\n case 'formUrlEncoded':\n const formEntries: FormUrlEncodedEntry[] = body.formUrlEncoded?.map((entry: BrunoKeyValue): FormUrlEncodedEntry => {\n const formEntry: FormUrlEncodedEntry = {\n name: entry.name || '',\n value: entry.value || ''\n };\n\n if (entry?.description?.trim().length) {\n formEntry.description = entry.description;\n }\n\n if (entry.enabled === false) {\n formEntry.disabled = true;\n }\n\n return formEntry;\n }) || [];\n\n const formBody: FormUrlEncodedBody = {\n type: 'form-urlencoded',\n ...(formEntries.length > 0 && { data: formEntries })\n } as FormUrlEncodedBody;\n return formBody;\n\n case 'multipartForm':\n const multipartEntries: MultipartFormEntry[] = body.multipartForm?.map((entry): MultipartFormEntry => {\n const multipartEntry: MultipartFormEntry = {\n name: entry.name || '',\n type: entry.type,\n value: entry.value || (entry.type === 'file' ? [] : '')\n };\n\n if (entry?.contentType?.trim().length) {\n multipartEntry.contentType = entry.contentType;\n }\n\n if (entry?.description?.trim().length) {\n multipartEntry.description = entry.description;\n }\n\n if (entry.enabled === false) {\n multipartEntry.disabled = true;\n }\n\n return multipartEntry;\n }) || [];\n\n const multipartBody: MultipartFormBody = {\n type: 'multipart-form',\n ...(multipartEntries.length > 0 && { data: multipartEntries })\n } as MultipartFormBody;\n return multipartBody;\n\n case 'file':\n const fileEntries: FileBodyEntry[] = body.file?.map((file): FileBodyEntry => {\n return {\n filePath: file.filePath || '',\n contentType: file.contentType || '',\n selected: file.selected ?? false\n };\n }) || [];\n\n const fileBody: FileBody = {\n type: 'file',\n ...(fileEntries.length > 0 && { data: fileEntries })\n } as FileBody;\n return fileBody;\n\n case 'graphql':\n // GraphQL body is handled separately in GraphQL request stringify\n return undefined;\n\n default:\n return undefined;\n }\n};\n\nexport const toBrunoBody = (body: HttpRequestBody | null | undefined): BrunoHttpRequestBody | undefined => {\n if (!body) {\n return {\n mode: 'none',\n json: null,\n text: null,\n xml: null,\n sparql: null,\n formUrlEncoded: [],\n multipartForm: [],\n graphql: null,\n file: []\n };\n }\n\n const brunoBody: BrunoHttpRequestBody = {\n mode: 'none',\n json: null,\n text: null,\n xml: null,\n sparql: null,\n formUrlEncoded: [],\n multipartForm: [],\n graphql: null,\n file: []\n };\n\n switch (body.type) {\n case 'json':\n brunoBody.mode = 'json';\n brunoBody.json = body.data || '';\n break;\n\n case 'text':\n brunoBody.mode = 'text';\n brunoBody.text = body.data || '';\n break;\n\n case 'xml':\n brunoBody.mode = 'xml';\n brunoBody.xml = body.data || '';\n break;\n\n case 'sparql':\n brunoBody.mode = 'sparql';\n brunoBody.sparql = body.data || '';\n break;\n\n case 'form-urlencoded':\n brunoBody.mode = 'formUrlEncoded';\n brunoBody.formUrlEncoded = body.data?.map((entry): BrunoKeyValue => {\n const formEntry: BrunoKeyValue = {\n uid: uuid(),\n name: ensureString(entry.name),\n value: ensureString(entry.value),\n enabled: entry.disabled !== true\n };\n\n if (entry.description) {\n if (typeof entry.description === 'string' && entry.description.trim().length) {\n formEntry.description = entry.description;\n } else if (typeof entry.description === 'object' && entry.description.content?.trim().length) {\n formEntry.description = entry.description.content;\n }\n }\n\n return formEntry;\n }) || [];\n break;\n\n case 'multipart-form':\n brunoBody.mode = 'multipartForm';\n brunoBody.multipartForm = body.data?.map((entry): any => {\n const multipartEntry: any = {\n uid: uuid(),\n type: entry.type,\n name: ensureString(entry.name),\n value: entry.type === 'file' ? (entry.value || []) : ensureString(entry.value),\n contentType: entry.contentType || null,\n enabled: entry.disabled !== true\n };\n\n if (entry.description) {\n if (typeof entry.description === 'string' && entry.description.trim().length) {\n multipartEntry.description = entry.description;\n } else if (typeof entry.description === 'object' && entry.description.content?.trim().length) {\n multipartEntry.description = entry.description.content;\n }\n }\n\n return multipartEntry;\n }) || [];\n break;\n\n case 'file':\n brunoBody.mode = 'file';\n brunoBody.file = body.data?.map((file): any => ({\n uid: uuid(),\n filePath: file.filePath || '',\n contentType: file.contentType || '',\n selected: file.selected ?? false\n })) || [];\n break;\n\n default:\n break;\n }\n\n return brunoBody;\n};\n","import { Variable, VariableTypedValue } from '@opencollection/types/common/variables';\nimport { FolderRequest as BrunoFolderRequest } from '@usebruno/schema-types/collection/folder';\nimport { Variable as BrunoVariable, Variables as BrunoVariables } from '@usebruno/schema-types/common/variables';\nimport { uuid, ensureString } from '../../../utils';\n\nexport const isTypedValue = (value: unknown): value is VariableTypedValue => {\n return (\n typeof value === 'object'\n && value !== null\n && !Array.isArray(value)\n && 'type' in value\n && 'data' in value\n );\n};\n\n/**\n * Convert Bruno pre-request variables to OpenCollection variables format.\n * Note: Post-response variables are now converted to actions (see actions.ts).\n */\nexport const toOpenCollectionVariables = (variables: BrunoFolderRequest['vars'] | BrunoVariables | null | undefined): Variable[] | undefined => {\n // Handle folder variables (has req/res structure) - only use req vars\n const hasReqRes = variables && 'req' in variables;\n const reqVars = hasReqRes ? variables.req : variables as BrunoVariables;\n\n const reqVarsArray = Array.isArray(reqVars) ? reqVars : [];\n\n if (!reqVarsArray.length) {\n return undefined;\n }\n\n const ocVariables: Variable[] = reqVarsArray.map((v: BrunoVariable): Variable => {\n const variable: Variable = {\n name: v.name || '',\n value:\n v.datatype && v.datatype !== 'string'\n ? { type: v.datatype, data: ensureString(v.value) }\n : v.value || ''\n };\n\n if (v?.description?.trim().length) {\n variable.description = v.description;\n }\n\n if (v.enabled === false) {\n variable.disabled = true;\n }\n return variable;\n });\n\n return ocVariables.length > 0 ? ocVariables : undefined;\n};\n\n/**\n * Convert OpenCollection variables to Bruno pre-request variables format.\n * Note: Post-response variables come from actions (see actions.ts).\n */\nexport const toBrunoVariables = (variables: Variable[] | null | undefined): { req: BrunoVariables; res: BrunoVariables } => {\n if (!variables?.length) {\n return { req: [], res: [] };\n }\n\n const reqVars: BrunoVariables = [];\n\n variables.forEach((v: Variable) => {\n const variable: BrunoVariable = {\n uid: uuid(),\n name: ensureString(v.name),\n value: '',\n enabled: v.disabled !== true,\n local: false\n };\n\n if (isTypedValue(v.value)) {\n variable.value = ensureString(v.value.data);\n if (v.value.type !== 'string' && v.value.type !== 'null') {\n variable.datatype = v.value.type;\n }\n } else {\n variable.value = ensureString(v.value);\n }\n\n if (v.description) {\n variable.description = typeof v.description === 'string' ? v.description : (v.description as any)?.content || '';\n }\n\n reqVars.push(variable);\n });\n\n return { req: reqVars, res: [] };\n};\n","import type { Action, ActionSetVariable, ActionVariableScope } from '@opencollection/types/common/actions';\nimport type { Variable as BrunoVariable, Variables as BrunoVariables } from '@usebruno/schema-types/common/variables';\nimport { uuid, ensureString } from '../../../utils';\n\n/**\n * Convert Bruno post-response variables to OpenCollection actions.\n * Post-response variables in Bruno are converted to 'set-variable' actions\n * with phase 'after-response'.\n */\nexport const toOpenCollectionActions = (resVariables: BrunoVariables | null | undefined): Action[] | undefined => {\n if (!resVariables?.length) {\n return undefined;\n }\n\n const actions: Action[] = resVariables.map((v: BrunoVariable): ActionSetVariable => {\n const action: ActionSetVariable = {\n type: 'set-variable',\n phase: 'after-response',\n selector: {\n expression: v.value || '',\n method: 'jsonq'\n },\n variable: {\n name: v.name || '',\n scope: v.local ? 'request' : 'runtime' as ActionVariableScope\n }\n };\n\n if (v.description?.trim().length) {\n action.description = v.description;\n }\n\n if (v.enabled === false) {\n action.disabled = true;\n }\n\n return action;\n });\n\n return actions.length > 0 ? actions : undefined;\n};\n\n/**\n * Convert OpenCollection actions to Bruno post-response variables.\n * Only 'set-variable' actions with phase 'after-response' are converted.\n */\nexport const toBrunoPostResponseVariables = (actions: Action[] | null | undefined): BrunoVariables => {\n if (!actions?.length) {\n return [];\n }\n\n const resVars: BrunoVariables = [];\n\n actions.forEach((action: Action) => {\n // Only process 'set-variable' actions with 'after-response' phase\n if (action.type === 'set-variable' && action.phase === 'after-response') {\n const setVarAction = action as ActionSetVariable;\n\n const variable: BrunoVariable = {\n uid: uuid(),\n name: ensureString(setVarAction.variable?.name),\n value: ensureString(setVarAction.selector?.expression),\n enabled: setVarAction.disabled !== true,\n local: false\n };\n\n if (setVarAction.description) {\n variable.description = typeof setVarAction.description === 'string'\n ? setVarAction.description\n : (setVarAction.description as any)?.content || '';\n }\n\n resVars.push(variable);\n }\n });\n\n return resVars;\n};\n","import type { Scripts, Script } from '@opencollection/types/common/scripts';\nimport type { FolderRequest as BrunoFolderRequest } from '@usebruno/schema-types/collection/folder';\nimport type { HttpRequest as BrunoHttpRequest } from '@usebruno/schema-types/requests/http';\nimport type { WebSocketRequest as BrunoWebSocketRequest } from '@usebruno/schema-types/requests/websocket';\nimport type { GrpcRequest as BrunoGrpcRequest } from '@usebruno/schema-types/requests/grpc';\n\nexport const toOpenCollectionScripts = (request: BrunoFolderRequest | BrunoHttpRequest | BrunoWebSocketRequest | BrunoGrpcRequest | null | undefined): Scripts | undefined => {\n const ocScripts: Scripts = [];\n\n if (request?.script?.req?.trim().length) {\n ocScripts.push({\n type: 'before-request',\n code: request.script.req.trim()\n });\n }\n if (request?.script?.res?.trim().length) {\n ocScripts.push({\n type: 'after-response',\n code: request.script.res.trim()\n });\n }\n if (request?.tests?.trim().length) {\n ocScripts.push({\n type: 'tests',\n code: request.tests.trim()\n });\n }\n\n return ocScripts.length > 0 ? ocScripts : undefined;\n};\n\nexport const toBrunoScripts = (scripts: Scripts | null | undefined): {\n script?: { req?: string; res?: string };\n tests?: string;\n} | undefined => {\n if (!scripts || !Array.isArray(scripts) || scripts.length === 0) {\n return undefined;\n }\n\n const brunoScripts: {\n script?: { req?: string; res?: string };\n tests?: string;\n } = {};\n\n for (const script of scripts) {\n if (script.type === 'before-request' && script.code) {\n if (!brunoScripts.script) {\n brunoScripts.script = {};\n }\n brunoScripts.script.req = script.code;\n }\n if (script.type === 'after-response' && script.code) {\n if (!brunoScripts.script) {\n brunoScripts.script = {};\n }\n brunoScripts.script.res = script.code;\n }\n if (script.type === 'tests' && script.code) {\n brunoScripts.tests = script.code;\n }\n }\n\n return Object.keys(brunoScripts).length > 0 ? brunoScripts : undefined;\n};\n","import type { KeyValue as BrunoKeyValue } from '@usebruno/schema-types/common/key-value';\nimport type { Assertion } from '@opencollection/types/common/assertions';\nimport { uuid, ensureString } from '../../../utils';\n\nconst OPERATORS = [\n 'eq',\n 'neq',\n 'gt',\n 'gte',\n 'lt',\n 'lte',\n 'in',\n 'notIn',\n 'contains',\n 'notContains',\n 'length',\n 'matches',\n 'notMatches',\n 'startsWith',\n 'endsWith',\n 'between',\n 'isEmpty',\n 'isNotEmpty',\n 'isNull',\n 'isUndefined',\n 'isDefined',\n 'isTruthy',\n 'isFalsy',\n 'isJson',\n 'isNumber',\n 'isString',\n 'isBoolean',\n 'isArray'\n] as const;\n\nconst UNARY_OPERATORS = [\n 'isEmpty',\n 'isNotEmpty',\n 'isNull',\n 'isUndefined',\n 'isDefined',\n 'isTruthy',\n 'isFalsy',\n 'isJson',\n 'isNumber',\n 'isString',\n 'isBoolean',\n 'isArray'\n] as const;\n\ntype Operator = typeof OPERATORS[number];\n\nconst parseAssertionOperator = (str: string = ''): { operator: Operator; value: string | undefined } => {\n if (!str || typeof str !== 'string' || !str.length) {\n return {\n operator: 'eq',\n value: str\n };\n }\n\n const [firstWord, ...rest] = str.trim().split(' ');\n const remainingValue = rest.join(' ');\n\n // Check if first word is a unary operator\n if (UNARY_OPERATORS.includes(firstWord as any)) {\n return {\n operator: firstWord as Operator,\n value: undefined\n };\n }\n\n // Check if first word is any recognized operator\n if (OPERATORS.includes(firstWord as any)) {\n return {\n operator: firstWord as Operator,\n value: remainingValue\n };\n }\n\n // If not a recognized operator, treat the whole string as value with 'eq' operator\n return {\n operator: 'eq',\n value: str\n };\n};\n\nexport const toOpenCollectionAssertions = (assertions: BrunoKeyValue[] | null | undefined): Assertion[] | undefined => {\n if (!assertions?.length) {\n return undefined;\n }\n\n const ocAssertions: Assertion[] = assertions.map((assertion: BrunoKeyValue): Assertion => {\n const { operator, value } = parseAssertionOperator(assertion.value || '');\n\n const ocAssertion: Assertion = {\n expression: assertion.name || '',\n operator,\n ...(value !== undefined && { value })\n };\n\n if (assertion?.description?.trim().length) {\n ocAssertion.description = assertion.description;\n }\n\n if (assertion.enabled === false) {\n ocAssertion.disabled = true;\n }\n\n return ocAssertion;\n });\n\n return ocAssertions.length > 0 ? ocAssertions : undefined;\n};\n\nexport const toBrunoAssertions = (assertions: Assertion[] | null | undefined): BrunoKeyValue[] | undefined => {\n if (!assertions?.length) {\n return undefined;\n }\n\n const brunoAssertions: BrunoKeyValue[] = assertions.map((assertion: Assertion): BrunoKeyValue => {\n // Reconstruct the \"operator value\" format that Bruno uses\n let valueString = ensureString(assertion.operator);\n if (assertion.value !== undefined && assertion.value !== null) {\n valueString = `${assertion.operator} ${ensureString(assertion.value)}`;\n }\n\n const brunoAssertion: BrunoKeyValue = {\n uid: uuid(),\n name: ensureString(assertion.expression),\n value: valueString,\n enabled: assertion.disabled !== true\n };\n\n if (assertion.description) {\n if (typeof assertion.description === 'string' && assertion.description.trim().length) {\n brunoAssertion.description = assertion.description;\n } else if (typeof assertion.description === 'object' && assertion.description.content?.trim().length) {\n brunoAssertion.description = assertion.description.content;\n }\n }\n\n return brunoAssertion;\n });\n\n return brunoAssertions.length > 0 ? brunoAssertions : undefined;\n};\n","import type { Item as BrunoItem } from '@usebruno/schema-types/collection/item';\nimport type { GrpcRequest as BrunoGrpcRequest } from '@usebruno/schema-types/requests/grpc';\nimport type { GrpcRequest, GrpcMetadata } from '@opencollection/types/requests/grpc';\nimport type { KeyValue as BrunoKeyValue } from '@usebruno/schema-types/common/key-value';\nimport { toBrunoAuth } from '../common/auth';\nimport { toBrunoVariables } from '../common/variables';\nimport { toBrunoScripts } from '../common/scripts';\nimport { toBrunoAssertions } from '../common/assertions';\nimport { isNonEmptyString, uuid, ensureString } from '../../../utils';\n\nconst toBrunoGrpcMetadata = (metadata: GrpcMetadata[] | null | undefined): BrunoKeyValue[] | undefined => {\n if (!metadata?.length) {\n return undefined;\n }\n\n const brunoMetadata = metadata.map((meta: GrpcMetadata): BrunoKeyValue => {\n const brunoMeta: BrunoKeyValue = {\n uid: uuid(),\n name: ensureString(meta.name),\n value: ensureString(meta.value),\n enabled: meta.disabled !== true\n };\n\n return brunoMeta;\n });\n\n return brunoMetadata.length ? brunoMetadata : undefined;\n};\n\nconst parseGrpcRequest = (ocRequest: GrpcRequest): BrunoItem => {\n const info = ocRequest.info;\n const grpc = ocRequest.grpc;\n const runtime = ocRequest.runtime;\n\n const brunoRequest: BrunoGrpcRequest = {\n url: ensureString(grpc?.url),\n method: ensureString(grpc?.method),\n methodType: grpc?.methodType || '',\n protoPath: grpc?.protoFilePath || null,\n headers: toBrunoGrpcMetadata(grpc?.metadata) || [],\n auth: toBrunoAuth(grpc?.auth),\n body: {\n mode: 'grpc',\n grpc: []\n },\n script: {\n req: null,\n res: null\n },\n vars: {\n req: [],\n res: []\n },\n assertions: [],\n tests: null,\n docs: null\n };\n\n // message\n if (isNonEmptyString(grpc?.message)) {\n brunoRequest.body.grpc = [{\n name: '',\n content: grpc?.message as string\n }];\n }\n\n // scripts\n const scripts = toBrunoScripts(runtime?.scripts);\n if (scripts?.script && brunoRequest.script) {\n if (scripts.script.req) {\n brunoRequest.script.req = scripts.script.req;\n }\n if (scripts.script.res) {\n brunoRequest.script.res = scripts.script.res;\n }\n }\n if (scripts?.tests) {\n brunoRequest.tests = scripts.tests;\n }\n\n // variables\n const variables = toBrunoVariables(runtime?.variables);\n brunoRequest.vars = variables;\n\n // assertions\n const assertions = toBrunoAssertions(runtime?.assertions);\n if (assertions) {\n brunoRequest.assertions = assertions;\n }\n\n // docs\n if (ocRequest.docs) {\n brunoRequest.docs = ocRequest.docs;\n }\n\n // bruno item\n const brunoItem: BrunoItem = {\n uid: uuid(),\n type: 'grpc-request',\n seq: info?.seq || 1,\n name: ensureString(info?.name, 'Untitled Request'),\n tags: info?.tags || [],\n request: brunoRequest,\n settings: {},\n fileContent: null,\n root: null,\n items: [],\n examples: [],\n filename: null,\n pathname: null\n };\n\n return brunoItem;\n};\n\nexport default parseGrpcRequest;\n","import type { Item as BrunoItem } from '@usebruno/schema-types/collection/item';\nimport type { Item, ScriptFile } from '@opencollection/types/collection/item';\nimport type { HttpRequest } from '@opencollection/types/requests/http';\nimport type { GraphQLRequest } from '@opencollection/types/requests/graphql';\nimport type { GrpcRequest } from '@opencollection/types/requests/grpc';\nimport type { WebSocketRequest } from '@opencollection/types/requests/websocket';\nimport { parseYml } from './utils';\nimport parseHttpRequest from './items/parseHttpRequest';\nimport parseGraphQLRequest from './items/parseGraphQLRequest';\nimport parseGrpcRequest from './items/parseGrpcRequest';\nimport parseWebsocketRequest from './items/parseWebsocketRequest';\nimport parseScript from './items/parseScript';\n\n// Helper to get the type from an item (now in info block)\nconst getItemType = (item: Item): string | undefined => {\n if ('info' in item && item.info && 'type' in item.info) {\n return item.info.type;\n }\n // For ScriptFile which still has type at root\n if ('type' in item) {\n return (item as ScriptFile).type;\n }\n return undefined;\n};\n\n/**\n * In v3.0.0-rc1 release auth was present under runtime property for all requests\n * This has now been moved to the respective request properties\n * This backward compatibility has been put in place for folks who tried out our early preview\n * Should be safe to remove this in 3 months. Delete after 5 Apr 2026\n */\nconst ensureAuthV3Rc1BackwardsCompatibility = (parsedItemYml: any): any => {\n const itemType = parsedItemYml?.info?.type;\n\n switch (itemType) {\n case 'http':\n if (parsedItemYml.runtime?.auth && !parsedItemYml.http?.auth) {\n parsedItemYml.http.auth = parsedItemYml.runtime.auth;\n }\n break;\n case 'graphql':\n if (parsedItemYml.runtime?.auth && !parsedItemYml.graphql?.auth) {\n parsedItemYml.graphql.auth = parsedItemYml.runtime.auth;\n }\n break;\n case 'grpc':\n if (parsedItemYml.runtime?.auth && !parsedItemYml.grpc?.auth) {\n parsedItemYml.grpc.auth = parsedItemYml.runtime.auth;\n }\n break;\n case 'websocket':\n if (parsedItemYml.runtime?.auth && !parsedItemYml.websocket?.auth) {\n parsedItemYml.websocket.auth = parsedItemYml.runtime.auth;\n }\n break;\n default:\n break;\n }\n\n return parsedItemYml;\n};\n\nconst parseItem = (ymlString: string): BrunoItem => {\n try {\n const parsedYml = parseYml(ymlString);\n\n const ocItem: Item = ensureAuthV3Rc1BackwardsCompatibility(parsedYml);\n const itemType = getItemType(ocItem);\n\n if (!ocItem || !itemType) {\n throw new Error('Invalid item: missing type');\n }\n\n switch (itemType) {\n case 'http':\n return parseHttpRequest(ocItem as HttpRequest);\n\n case 'graphql':\n return parseGraphQLRequest(ocItem as GraphQLRequest);\n\n case 'grpc':\n return parseGrpcRequest(ocItem as GrpcRequest);\n\n case 'websocket':\n return parseWebsocketRequest(ocItem as WebSocketRequest);\n\n case 'script':\n return parseScript(ocItem as ScriptFile);\n\n case 'folder':\n throw new Error('Folder items should be handled separately using parseFolder');\n\n default:\n throw new Error(`Unsupported item type: ${itemType}`);\n }\n } catch (error) {\n console.error('Error parsing item:', error);\n throw error;\n }\n};\n\nexport default parseItem;\n","import type { Item as BrunoItem, HttpItemSettings as BrunoHttpItemSettings } from '@usebruno/schema-types/collection/item';\nimport type { HttpRequest as BrunoHttpRequest } from '@usebruno/schema-types/requests/http';\nimport type { HttpRequest, HttpRequestBody } from '@opencollection/types/requests/http';\nimport { toBrunoAuth } from '../common/auth';\nimport { toBrunoHttpHeaders } from '../common/headers';\nimport { toBrunoParams } from '../common/params';\nimport { toBrunoBody } from '../common/body';\nimport { toBrunoVariables } from '../common/variables';\nimport { toBrunoPostResponseVariables } from '../common/actions';\nimport { toBrunoScripts } from '../common/scripts';\nimport { toBrunoAssertions } from '../common/assertions';\nimport { uuid, ensureString } from '../../../utils';\n\nconst parseHttpRequest = (ocRequest: HttpRequest): BrunoItem => {\n const info = ocRequest.info;\n const http = ocRequest.http;\n const runtime = ocRequest.runtime;\n\n const brunoRequest: BrunoHttpRequest = {\n url: ensureString(http?.url),\n method: ensureString(http?.method, 'GET'),\n headers: toBrunoHttpHeaders(http?.headers) || [],\n params: toBrunoParams(http?.params) || [],\n auth: toBrunoAuth(http?.auth),\n body: toBrunoBody(http?.body as HttpRequestBody) || {\n mode: 'none',\n json: null,\n text: null,\n xml: null,\n sparql: null,\n formUrlEncoded: [],\n multipartForm: [],\n graphql: null,\n file: []\n },\n script: {\n req: null,\n res: null\n },\n vars: {\n req: [],\n res: []\n },\n assertions: [],\n tests: null,\n docs: null\n };\n\n // scripts\n const scripts = toBrunoScripts(runtime?.scripts);\n if (scripts?.script && brunoRequest.script) {\n if (scripts.script.req) {\n brunoRequest.script.req = scripts.script.req;\n }\n if (scripts.script.res) {\n brunoRequest.script.res = scripts.script.res;\n }\n }\n if (scripts?.tests) {\n brunoRequest.tests = scripts.tests;\n }\n\n // variables (pre-request from variables, post-response from actions)\n const variables = toBrunoVariables(runtime?.variables);\n const postResponseVars = toBrunoPostResponseVariables(runtime?.actions);\n brunoRequest.vars = {\n req: variables.req,\n res: postResponseVars\n };\n\n // assertions\n const assertions = toBrunoAssertions(runtime?.assertions);\n if (assertions) {\n brunoRequest.assertions = assertions;\n }\n\n // docs\n if (ocRequest.docs) {\n brunoRequest.docs = ocRequest.docs;\n }\n\n // bruno item\n const brunoItem: BrunoItem = {\n uid: uuid(),\n type: 'http-request',\n seq: info?.seq || 1,\n name: ensureString(info?.name, 'Untitled Request'),\n tags: info?.tags || [],\n request: brunoRequest,\n settings: null,\n fileContent: null,\n root: null,\n items: [],\n examples: [],\n filename: null,\n pathname: null\n };\n\n // settings\n if (ocRequest.settings) {\n const settings: BrunoHttpItemSettings = {};\n\n if (typeof ocRequest.settings.encodeUrl === 'boolean') {\n settings.encodeUrl = ocRequest.settings.encodeUrl;\n } else {\n settings.encodeUrl = true;\n }\n\n if (typeof ocRequest.settings.timeout === 'number') {\n settings.timeout = ocRequest.settings.timeout;\n } else if (ocRequest.settings.timeout === 'inherit') {\n settings.timeout = 'inherit';\n } else {\n settings.timeout = 0;\n }\n\n if (typeof ocRequest.settings.followRedirects === 'boolean') {\n settings.followRedirects = ocRequest.settings.followRedirects;\n } else {\n settings.followRedirects = true;\n }\n\n if (typeof ocRequest.settings.maxRedirects === 'number') {\n settings.maxRedirects = ocRequest.settings.maxRedirects;\n } else {\n settings.maxRedirects = 5;\n }\n\n brunoItem.settings = settings;\n }\n\n // examples\n if (ocRequest.examples?.length) {\n brunoItem.examples = ocRequest.examples.map((example) => {\n const brunoExample: any = {\n uid: uuid(),\n itemUid: uuid(),\n name: ensureString(example.name, 'Untitled Example'),\n type: 'http-request',\n request: null,\n response: null\n };\n\n if (example.description) {\n if (typeof example.description === 'string' && example.description.trim().length) {\n brunoExample.description = example.description;\n } else if (typeof example.description === 'object' && example.description.content?.trim().length) {\n brunoExample.description = example.description.content;\n }\n }\n\n if (example.request) {\n brunoExample.request = {\n url: ensureString(example.request.url),\n method: ensureString(example.request.method, 'GET'),\n headers: toBrunoHttpHeaders(example.request.headers) || [],\n params: toBrunoParams(example.request.params) || [],\n body: toBrunoBody(example.request.body) || {\n mode: 'none',\n json: null,\n text: null,\n xml: null,\n sparql: null,\n formUrlEncoded: null,\n multipartForm: null,\n graphql: null,\n file: null\n }\n };\n }\n\n if (example.response) {\n brunoExample.response = {\n status: typeof example.response.status === 'number' ? example.response.status\n : example.response.status !== undefined ? Number(example.response.status) : null,\n statusText: example.response.statusText || null,\n headers: toBrunoHttpHeaders(example.response.headers) || [],\n body: null\n };\n\n if (example.response.body) {\n brunoExample.response.body = {\n type: example.response.body.type || 'text',\n content: example.response.body.data || ''\n };\n }\n }\n\n return brunoExample;\n });\n }\n\n return brunoItem;\n};\n\nexport default parseHttpRequest;\n","import type { Item as BrunoItem, HttpItemSettings as BrunoHttpItemSettings } from '@usebruno/schema-types/collection/item';\nimport type { HttpRequest as BrunoHttpRequest } from '@usebruno/schema-types/requests/http';\nimport type { GraphQLRequest, GraphQLRequestSettings, GraphQLBody } from '@opencollection/types/requests/graphql';\nimport { toBrunoAuth } from '../common/auth';\nimport { toBrunoHttpHeaders } from '../common/headers';\nimport { toBrunoParams } from '../common/params';\nimport { toBrunoVariables } from '../common/variables';\nimport { toBrunoPostResponseVariables } from '../common/actions';\nimport { toBrunoScripts } from '../common/scripts';\nimport { toBrunoAssertions } from '../common/assertions';\nimport { uuid, ensureString } from '../../../utils';\n\nconst parseGraphQLRequest = (ocRequest: GraphQLRequest): BrunoItem => {\n const info = ocRequest.info;\n const graphql = ocRequest.graphql;\n const runtime = ocRequest.runtime;\n\n const brunoRequest: BrunoHttpRequest = {\n url: ensureString(graphql?.url),\n method: ensureString(graphql?.method, 'POST'),\n headers: toBrunoHttpHeaders(graphql?.headers) || [],\n params: toBrunoParams(graphql?.params) || [],\n auth: toBrunoAuth(graphql?.auth),\n body: {\n mode: 'graphql',\n json: null,\n text: null,\n xml: null,\n sparql: null,\n formUrlEncoded: [],\n multipartForm: [],\n graphql: {\n query: (graphql?.body as GraphQLBody)?.query || '',\n variables: (graphql?.body as GraphQLBody)?.variables || ''\n },\n file: []\n },\n script: {\n req: null,\n res: null\n },\n vars: {\n req: [],\n res: []\n },\n assertions: [],\n tests: null,\n docs: null\n };\n\n // scripts\n const scripts = toBrunoScripts(runtime?.scripts);\n if (scripts?.script && brunoRequest.script) {\n if (scripts.script.req) {\n brunoRequest.script.req = scripts.script.req;\n }\n if (scripts.script.res) {\n brunoRequest.script.res = scripts.script.res;\n }\n }\n if (scripts?.tests) {\n brunoRequest.tests = scripts.tests;\n }\n\n // variables (pre-request from variables, post-response from actions)\n const variables = toBrunoVariables(runtime?.variables);\n const postResponseVars = toBrunoPostResponseVariables(runtime?.actions);\n brunoRequest.vars = {\n req: variables.req,\n res: postResponseVars\n };\n\n // assertions\n const assertions = toBrunoAssertions(runtime?.assertions);\n if (assertions) {\n brunoRequest.assertions = assertions;\n }\n\n // docs\n if (ocRequest.docs) {\n brunoRequest.docs = ocRequest.docs;\n }\n\n // bruno item\n const brunoItem: BrunoItem = {\n uid: uuid(),\n type: 'graphql-request',\n seq: info?.seq || 1,\n name: ensureString(info?.name, 'Untitled Request'),\n tags: info?.tags || [],\n request: brunoRequest,\n settings: null,\n fileContent: null,\n root: null,\n items: [],\n examples: [],\n filename: null,\n pathname: null\n };\n\n // settings\n if (ocRequest.settings) {\n const settings: BrunoHttpItemSettings = {};\n\n if (typeof ocRequest.settings.encodeUrl === 'boolean') {\n settings.encodeUrl = ocRequest.settings.encodeUrl;\n } else {\n settings.encodeUrl = true;\n }\n\n if (typeof ocRequest.settings.timeout === 'number') {\n settings.timeout = ocRequest.settings.timeout;\n } else if (ocRequest.settings.timeout === 'inherit') {\n settings.timeout = 'inherit';\n } else {\n settings.timeout = 0;\n }\n\n if (typeof ocRequest.settings.followRedirects === 'boolean') {\n settings.followRedirects = ocRequest.settings.followRedirects;\n } else {\n settings.followRedirects = true;\n }\n\n if (typeof ocRequest.settings.maxRedirects === 'number') {\n settings.maxRedirects = ocRequest.settings.maxRedirects;\n } else {\n settings.maxRedirects = 5;\n }\n\n brunoItem.settings = settings;\n }\n\n return brunoItem;\n};\n\nexport default parseGraphQLRequest;\n","import type { Item as BrunoItem } from '@usebruno/schema-types/collection/item';\nimport type { WebSocketRequest as BrunoWebSocketRequest } from '@usebruno/schema-types/requests/websocket';\nimport type { WebSocketRequest, WebSocketMessage } from '@opencollection/types/requests/websocket';\nimport { toBrunoAuth } from '../common/auth';\nimport { toBrunoHttpHeaders } from '../common/headers';\nimport { toBrunoVariables } from '../common/variables';\nimport { toBrunoScripts } from '../common/scripts';\nimport { uuid, ensureString } from '../../../utils';\n\nconst parseWebsocketRequest = (ocRequest: WebSocketRequest): BrunoItem => {\n const info = ocRequest.info;\n const websocket = ocRequest.websocket;\n const runtime = ocRequest.runtime;\n\n const brunoRequest: BrunoWebSocketRequest = {\n url: ensureString(websocket?.url),\n headers: toBrunoHttpHeaders(websocket?.headers) || [],\n auth: toBrunoAuth(websocket?.auth),\n body: {\n mode: 'ws',\n ws: []\n },\n script: {\n req: null,\n res: null\n },\n vars: {\n req: [],\n res: []\n },\n assertions: [],\n tests: null,\n docs: null\n };\n\n // message\n if (websocket?.message) {\n const message = websocket.message as WebSocketMessage;\n const messageData = ensureString(message.data);\n if (messageData.trim().length) {\n brunoRequest.body.ws = [{\n name: '',\n type: message.type || 'text',\n content: messageData\n }];\n }\n }\n\n // scripts\n const scripts = toBrunoScripts(runtime?.scripts);\n if (scripts?.script && brunoRequest.script) {\n if (scripts.script.req) {\n brunoRequest.script.req = scripts.script.req;\n }\n if (scripts.script.res) {\n brunoRequest.script.res = scripts.script.res;\n }\n }\n if (scripts?.tests) {\n brunoRequest.tests = scripts.tests;\n }\n\n // variables\n const variables = toBrunoVariables(runtime?.variables);\n brunoRequest.vars = variables;\n\n // docs\n if (ocRequest.docs) {\n brunoRequest.docs = ocRequest.docs;\n }\n\n // settings\n const wsSettings: Record<string, number> = {\n timeout: 0,\n keepAliveInterval: 0\n };\n\n if (ocRequest.settings) {\n if (typeof ocRequest.settings.timeout === 'number') {\n wsSettings.timeout = ocRequest.settings.timeout;\n }\n if (typeof ocRequest.settings.keepAliveInterval === 'number') {\n wsSettings.keepAliveInterval = ocRequest.settings.keepAliveInterval;\n }\n }\n\n // bruno item\n const brunoItem: BrunoItem = {\n uid: uuid(),\n type: 'ws-request',\n seq: info?.seq || 1,\n name: ensureString(info?.name, 'Untitled Request'),\n tags: info?.tags || [],\n request: brunoRequest,\n settings: wsSettings as any,\n fileContent: null,\n root: null,\n items: [],\n examples: [],\n filename: null,\n pathname: null\n };\n\n return brunoItem;\n};\n\nexport default parseWebsocketRequest;\n","import type { Item as BrunoItem } from '@usebruno/schema-types/collection/item';\nimport type { ScriptFile } from '@opencollection/types/collection/item';\nimport { uuid } from '../../../utils';\n\nconst parseScript = (ocScript: ScriptFile): BrunoItem => {\n const brunoItem: BrunoItem = {\n uid: uuid(),\n type: 'js',\n seq: 1,\n name: 'Script',\n tags: [],\n request: null,\n settings: null,\n fileContent: ocScript.script || '',\n root: null,\n items: [],\n examples: [],\n filename: null,\n pathname: null\n };\n\n return brunoItem;\n};\n\nexport default parseScript;\n","import type { Environment as BrunoEnvironment, EnvironmentVariable as BrunoEnvironmentVariable } from '@usebruno/schema-types/collection/environment';\nimport type { Environment } from '@opencollection/types/config/environments';\nimport type { Variable, SecretVariable } from '@opencollection/types/common/variables';\nimport { parseYml } from './utils';\nimport { uuid, ensureString } from '../../utils';\nimport { isTypedValue } from './common/variables';\n\nconst isSecretVariable = (v: Variable | SecretVariable): v is SecretVariable => {\n return 'secret' in v && v.secret === true;\n};\n\nconst toBrunoEnvironmentVariables = (variables: (Variable | SecretVariable)[] | null | undefined): BrunoEnvironmentVariable[] => {\n if (!variables?.length) {\n return [];\n }\n\n return variables.map((v): BrunoEnvironmentVariable => {\n if (isSecretVariable(v)) {\n const variable: BrunoEnvironmentVariable = {\n uid: uuid(),\n name: ensureString(v.name),\n value: '',\n type: 'text',\n enabled: v.disabled !== true,\n secret: true\n };\n\n if (v.type && v.type !== 'string' && v.type !== 'null') {\n variable.datatype = v.type;\n }\n\n return variable;\n }\n const variable: BrunoEnvironmentVariable = {\n uid: uuid(),\n name: ensureString(v.name),\n value: '',\n type: 'text',\n enabled: v.disabled !== true,\n secret: false\n };\n\n if (isTypedValue(v.value)) {\n variable.value = ensureString(v.value.data);\n if (v.value.type !== 'string' && v.value.type !== 'null') {\n variable.datatype = v.value.type;\n }\n } else {\n variable.value = ensureString(v.value);\n }\n\n return variable;\n });\n};\n\nconst toBrunoExternalSecrets = (externalSecrets: any): BrunoEnvironment['externalSecrets'] | undefined => {\n if (!externalSecrets || typeof externalSecrets !== 'object') {\n return undefined;\n }\n\n const variables = Array.isArray(externalSecrets.variables)\n ? externalSecrets.variables.map((variable: any) => {\n const result: Record<string, string> = { name: ensureString(variable?.name) };\n Object.keys(variable || {}).forEach((key) => {\n if (key !== 'name') {\n result[key] = ensureString(variable[key]);\n }\n });\n return result;\n })\n : [];\n\n return { type: ensureString(externalSecrets.type), variables } as BrunoEnvironment['externalSecrets'];\n};\n\nconst parseEnvironment = (ymlString: string): BrunoEnvironment => {\n try {\n const ocEnvironment: Environment = parseYml(ymlString);\n\n const brunoEnvironment: BrunoEnvironment = {\n uid: uuid(),\n name: ensureString(ocEnvironment.name, 'Untitled Environment'),\n variables: toBrunoEnvironmentVariables(ocEnvironment.variables),\n color: ocEnvironment.color || null\n };\n\n const externalSecrets = toBrunoExternalSecrets((ocEnvironment as any).externalSecrets);\n if (externalSecrets) {\n brunoEnvironment.externalSecrets = externalSecrets;\n }\n\n return brunoEnvironment;\n } catch (error) {\n console.error('Error parsing environment:', error);\n throw error;\n }\n};\n\nexport default parseEnvironment;\n","import type { Item as BrunoItem } from '@usebruno/schema-types/collection/item';\nimport stringifyHttpRequest from './items/stringifyHttpRequest';\nimport stringifyGraphqlRequest from './items/stringifyGraphQLRequest';\nimport stringifyGrpcRequest from './items/stringifyGrpcRequest';\nimport stringifyWebsocketRequest from './items/stringifyWebsocketRequest';\nimport stringifyScript from './items/stringifyScript';\n\nconst stringifyItem = (item: BrunoItem): string => {\n try {\n switch (item.type) {\n case 'http-request':\n return stringifyHttpRequest(item);\n\n case 'graphql-request':\n return stringifyGraphqlRequest(item);\n\n case 'grpc-request':\n return stringifyGrpcRequest(item);\n\n case 'ws-request':\n return stringifyWebsocketRequest(item);\n\n case 'js':\n return stringifyScript(item);\n\n case 'folder':\n throw new Error('Folder items should be handled separately using stringifyFolder');\n\n default:\n throw new Error(`Unsupported item type: ${item.type}`);\n }\n } catch (error) {\n console.error('Error stringifying item:', error);\n throw error;\n }\n};\nexport default stringifyItem;\n","import type { Item as BrunoItem, HttpItemSettings as BrunoHttpItemSettings } from '@usebruno/schema-types/collection/item';\nimport type { HttpRequest as BrunoHttpRequest } from '@usebruno/schema-types/requests/http';\nimport type { HttpRequest, HttpRequestSettings, HttpRequestExample, HttpRequestInfo, HttpRequestDetails, HttpRequestRuntime, HttpRequestHeader } from '@opencollection/types/requests/http';\nimport type { Auth } from '@opencollection/types/common/auth';\nimport type { Scripts } from '@opencollection/types/common/scripts';\nimport type { Variable } from '@opencollection/types/common/variables';\nimport type { Assertion } from '@opencollection/types/common/assertions';\nimport type { Action } from '@opencollection/types/common/actions';\nimport type { HttpRequestParam, HttpRequestBody } from '@opencollection/types/requests/http';\nimport { stringifyYml } from '../utils';\nimport { toOpenCollectionAuth } from '../common/auth';\nimport { toOpenCollectionHttpHeaders, toOpenCollectionResponseHeaders } from '../common/headers';\nimport { toOpenCollectionParams } from '../common/params';\nimport { toOpenCollectionBody } from '../common/body';\nimport { toOpenCollectionVariables } from '../common/variables';\nimport { toOpenCollectionActions } from '../common/actions';\nimport { toOpenCollectionScripts } from '../common/scripts';\nimport { toOpenCollectionAssertions } from '../common/assertions';\nimport { isNumber, isNonEmptyString } from '../../../utils';\n\nconst stringifyHttpRequest = (item: BrunoItem): string => {\n try {\n const ocRequest: HttpRequest = {};\n const brunoRequest = item.request as BrunoHttpRequest;\n\n // info block\n const info: HttpRequestInfo = {\n name: isNonEmptyString(item.name) ? item.name : 'Untitled Request',\n type: 'http'\n };\n if (item.seq) {\n info.seq = item.seq;\n }\n if (item.tags?.length) {\n info.tags = item.tags;\n }\n ocRequest.info = info;\n\n // http block\n const http: HttpRequestDetails = {\n method: isNonEmptyString(brunoRequest.method) ? brunoRequest.method : 'GET',\n url: isNonEmptyString(brunoRequest.url) ? brunoRequest.url : ''\n };\n\n // headers\n const headers: HttpRequestHeader[] | undefined = toOpenCollectionHttpHeaders(brunoRequest.headers);\n if (headers) {\n http.headers = headers;\n }\n\n // params\n const params: HttpRequestParam[] | undefined = toOpenCollectionParams(brunoRequest.params);\n if (params) {\n http.params = params;\n }\n\n // body\n const body: HttpRequestBody | undefined = toOpenCollectionBody(brunoRequest.body);\n if (body) {\n http.body = body;\n }\n\n // auth\n const auth: Auth | undefined = toOpenCollectionAuth(brunoRequest.auth);\n if (auth) {\n http.auth = auth;\n }\n\n ocRequest.http = http;\n\n // runtime block\n const runtime: HttpRequestRuntime = {};\n let hasRuntime = false;\n\n // variables\n const variables: Variable[] | undefined = toOpenCollectionVariables(brunoRequest.vars);\n if (variables) {\n runtime.variables = variables;\n hasRuntime = true;\n }\n\n // scripts\n const scripts: Scripts | undefined = toOpenCollectionScripts(brunoRequest);\n if (scripts) {\n runtime.scripts = scripts;\n hasRuntime = true;\n }\n\n // assertions\n const assertions: Assertion[] | undefined = toOpenCollectionAssertions(brunoRequest.assertions);\n if (assertions) {\n runtime.assertions = assertions;\n hasRuntime = true;\n }\n\n // actions (from post-response variables)\n const resVars = brunoRequest.vars?.res;\n const actions: Action[] | undefined = toOpenCollectionActions(resVars);\n if (actions) {\n runtime.actions = actions;\n hasRuntime = true;\n }\n\n if (hasRuntime) {\n ocRequest.runtime = runtime;\n }\n\n // settings\n const httpSettings = item.settings as BrunoHttpItemSettings | undefined;\n const settings: HttpRequestSettings = {};\n if (httpSettings?.encodeUrl === true) {\n settings.encodeUrl = true;\n } else if (httpSettings?.encodeUrl === false) {\n settings.encodeUrl = false;\n } else {\n settings.encodeUrl = true;\n }\n\n const timeout = httpSettings?.timeout;\n if (isNumber(timeout)) {\n settings.timeout = timeout;\n } else {\n settings.timeout = 0;\n }\n\n if (httpSettings?.followRedirects === true) {\n settings.followRedirects = true;\n } else if (httpSettings?.followRedirects === false) {\n settings.followRedirects = false;\n } else {\n settings.followRedirects = true;\n }\n\n const maxRedirects = httpSettings?.maxRedirects;\n if (isNumber(maxRedirects)) {\n settings.maxRedirects = maxRedirects;\n } else {\n settings.maxRedirects = 5;\n }\n\n ocRequest.settings = settings;\n\n // examples\n if (item.examples?.length) {\n const examples: HttpRequestExample[] = item.examples.map((example) => {\n const ocExample: HttpRequestExample = {};\n ocExample.name = example?.name || 'Untitled Example';\n\n if (isNonEmptyString(example.description)) {\n ocExample.description = example.description;\n }\n\n if (example.request) {\n ocExample.request = {};\n ocExample.request.url = example.request.url || '';\n ocExample.request.method = example.request.method || 'GET';\n\n const exampleHeaders = toOpenCollectionHttpHeaders(example.request.headers);\n if (exampleHeaders) {\n ocExample.request.headers = exampleHeaders;\n }\n\n const exampleParams = toOpenCollectionParams(example.request.params);\n if (exampleParams) {\n ocExample.request.params = exampleParams;\n }\n\n const exampleBody = toOpenCollectionBody(example.request.body);\n if (exampleBody !== undefined) {\n ocExample.request.body = exampleBody;\n }\n }\n\n if (example.response) {\n ocExample.response = {};\n\n const statusNum = Number(example.response.status);\n if (Number.isInteger(statusNum) && statusNum > 0) {\n ocExample.response.status = statusNum;\n }\n\n if (isNonEmptyString(example.response.statusText)) {\n ocExample.response.statusText = example.response.statusText;\n }\n\n const responseHeaders = toOpenCollectionResponseHeaders(example.response.headers);\n if (responseHeaders) {\n ocExample.response.headers = responseHeaders;\n }\n\n if (example.response.body && example.response.body.type && example.response.body.content !== undefined) {\n const content = example.response.body.content;\n const contentString = typeof content === 'string' ? content : JSON.stringify(content, null, 2);\n\n ocExample.response.body = {\n type: example.response.body.type as 'json' | 'text' | 'xml' | 'html' | 'binary',\n data: contentString\n };\n }\n }\n\n return ocExample;\n });\n\n if (examples?.length) {\n ocRequest.examples = examples;\n }\n }\n\n // docs\n if (isNonEmptyString(brunoRequest.docs)) {\n ocRequest.docs = brunoRequest.docs;\n }\n\n return stringifyYml(ocRequest);\n } catch (error) {\n console.error('Error stringifying HTTP request:', error);\n throw error;\n }\n};\n\nexport default stringifyHttpRequest;\n","import type { Item as BrunoItem, HttpItemSettings as BrunoHttpItemSettings } from '@usebruno/schema-types/collection/item';\nimport type { HttpRequest as BrunoHttpRequest } from '@usebruno/schema-types/requests/http';\nimport type { GraphQLRequest, GraphQLRequestSettings, GraphQLBody, GraphQLRequestInfo, GraphQLRequestDetails, GraphQLRequestRuntime } from '@opencollection/types/requests/graphql';\nimport type { Auth } from '@opencollection/types/common/auth';\nimport type { Scripts } from '@opencollection/types/common/scripts';\nimport type { Variable } from '@opencollection/types/common/variables';\nimport type { Assertion } from '@opencollection/types/common/assertions';\nimport type { Action } from '@opencollection/types/common/actions';\nimport type { HttpRequestParam, HttpRequestHeader } from '@opencollection/types/requests/http';\nimport { stringifyYml } from '../utils';\nimport { isNonEmptyString, isNumber } from '../../../utils';\nimport { toOpenCollectionAuth } from '../common/auth';\nimport { toOpenCollectionHttpHeaders } from '../common/headers';\nimport { toOpenCollectionParams } from '../common/params';\nimport { toOpenCollectionVariables } from '../common/variables';\nimport { toOpenCollectionActions } from '../common/actions';\nimport { toOpenCollectionScripts } from '../common/scripts';\nimport { toOpenCollectionAssertions } from '../common/assertions';\n\nconst stringifyGraphQLRequest = (item: BrunoItem): string => {\n try {\n const ocRequest: GraphQLRequest = {};\n const brunoRequest = item.request as BrunoHttpRequest;\n\n // info block\n const info: GraphQLRequestInfo = {\n name: isNonEmptyString(item.name) ? item.name : 'Untitled Request',\n type: 'graphql'\n };\n if (item.seq) {\n info.seq = item.seq;\n }\n if (item.tags?.length) {\n info.tags = item.tags;\n }\n ocRequest.info = info;\n\n // graphql block\n const graphql: GraphQLRequestDetails = {\n method: isNonEmptyString(brunoRequest.method) ? brunoRequest.method : 'POST',\n url: isNonEmptyString(brunoRequest.url) ? brunoRequest.url : ''\n };\n\n // headers\n const headers: HttpRequestHeader[] | undefined = toOpenCollectionHttpHeaders(brunoRequest.headers);\n if (headers) {\n graphql.headers = headers;\n }\n\n // params\n const params: HttpRequestParam[] | undefined = toOpenCollectionParams(brunoRequest.params);\n if (params) {\n graphql.params = params;\n }\n\n // body\n if (brunoRequest.body?.mode === 'graphql' && brunoRequest.body.graphql) {\n const graphqlBody: GraphQLBody = {};\n let hasBody = false;\n\n if (isNonEmptyString(brunoRequest.body.graphql.query)) {\n graphqlBody.query = brunoRequest.body.graphql.query;\n hasBody = true;\n }\n\n if (isNonEmptyString(brunoRequest.body.graphql.variables)) {\n graphqlBody.variables = brunoRequest.body.graphql.variables;\n hasBody = true;\n }\n\n if (hasBody) {\n graphql.body = graphqlBody;\n }\n }\n\n // auth (in graphql block, not runtime)\n const auth: Auth | undefined = toOpenCollectionAuth(brunoRequest.auth);\n if (auth) {\n graphql.auth = auth;\n }\n\n ocRequest.graphql = graphql;\n\n // runtime block\n const runtime: GraphQLRequestRuntime = {};\n let hasRuntime = false;\n\n // variables\n const variables: Variable[] | undefined = toOpenCollectionVariables(brunoRequest.vars);\n if (variables) {\n runtime.variables = variables;\n hasRuntime = true;\n }\n\n // scripts\n const scripts: Scripts | undefined = toOpenCollectionScripts(brunoRequest);\n if (scripts) {\n runtime.scripts = scripts;\n hasRuntime = true;\n }\n\n // assertions\n const assertions: Assertion[] | undefined = toOpenCollectionAssertions(brunoRequest.assertions);\n if (assertions) {\n runtime.assertions = assertions;\n hasRuntime = true;\n }\n\n // actions (from post-response variables)\n const resVars = brunoRequest.vars?.res;\n const actions: Action[] | undefined = toOpenCollectionActions(resVars);\n if (actions) {\n runtime.actions = actions;\n hasRuntime = true;\n }\n\n if (hasRuntime) {\n ocRequest.runtime = runtime;\n }\n\n // settings\n const httpSettings = item.settings as BrunoHttpItemSettings | undefined;\n const settings: GraphQLRequestSettings = {};\n if (httpSettings?.encodeUrl === true) {\n settings.encodeUrl = true;\n } else if (httpSettings?.encodeUrl === false) {\n settings.encodeUrl = false;\n } else {\n settings.encodeUrl = true;\n }\n\n const timeout = httpSettings?.timeout;\n if (isNumber(timeout)) {\n settings.timeout = timeout;\n } else {\n settings.timeout = 0;\n }\n\n if (httpSettings?.followRedirects === true) {\n settings.followRedirects = true;\n } else if (httpSettings?.followRedirects === false) {\n settings.followRedirects = false;\n } else {\n settings.followRedirects = true;\n }\n\n const maxRedirects = httpSettings?.maxRedirects;\n if (isNumber(maxRedirects)) {\n settings.maxRedirects = maxRedirects;\n } else {\n settings.maxRedirects = 5;\n }\n\n ocRequest.settings = settings;\n\n // docs\n if (isNonEmptyString(brunoRequest.docs)) {\n ocRequest.docs = brunoRequest.docs;\n }\n\n return stringifyYml(ocRequest);\n } catch (error) {\n console.error('Error stringifying GraphQL request:', error);\n throw error;\n }\n};\n\nexport default stringifyGraphQLRequest;\n","import type { Item as BrunoItem } from '@usebruno/schema-types/collection/item';\nimport type { KeyValue as BrunoKeyValue } from '@usebruno/schema-types/common/key-value';\nimport type { GrpcRequest as BrunoGrpcRequest } from '@usebruno/schema-types/requests/grpc';\nimport type { GrpcRequest, GrpcMetadata, GrpcMessage, GrpcRequestInfo, GrpcRequestDetails, GrpcRequestRuntime } from '@opencollection/types/requests/grpc';\nimport type { Auth } from '@opencollection/types/common/auth';\nimport type { Scripts } from '@opencollection/types/common/scripts';\nimport type { Variable } from '@opencollection/types/common/variables';\nimport type { Assertion } from '@opencollection/types/common/assertions';\nimport { stringifyYml } from '../utils';\nimport { isNonEmptyString } from '../../../utils';\nimport { toOpenCollectionAuth } from '../common/auth';\nimport { toOpenCollectionVariables } from '../common/variables';\nimport { toOpenCollectionScripts } from '../common/scripts';\nimport { toOpenCollectionAssertions } from '../common/assertions';\n\nconst stringifyGrpcRequest = (item: BrunoItem): string => {\n try {\n const ocRequest: GrpcRequest = {};\n const brunoRequest = item.request as BrunoGrpcRequest;\n\n // info block\n const info: GrpcRequestInfo = {\n name: isNonEmptyString(item.name) ? item.name : 'Untitled Request',\n type: 'grpc'\n };\n if (item.seq) {\n info.seq = item.seq;\n }\n if (item.tags?.length) {\n info.tags = item.tags;\n }\n ocRequest.info = info;\n\n // grpc block\n const grpc: GrpcRequestDetails = {\n url: isNonEmptyString(brunoRequest.url) ? brunoRequest.url : '',\n method: isNonEmptyString(brunoRequest.method) ? brunoRequest.method : ''\n };\n\n // method type\n if (brunoRequest.methodType) {\n grpc.methodType = brunoRequest.methodType;\n }\n\n // proto file path\n if (isNonEmptyString(brunoRequest.protoPath)) {\n grpc.protoFilePath = brunoRequest.protoPath;\n }\n\n // metadata\n if (brunoRequest.headers?.length) {\n const metadata: GrpcMetadata[] = brunoRequest.headers.map((header: BrunoKeyValue) => {\n const metadataItem: GrpcMetadata = {\n name: header.name || '',\n value: header.value || ''\n };\n\n if (header?.description?.trim().length) {\n metadataItem.description = header.description;\n }\n\n if (header.enabled === false) {\n metadataItem.disabled = true;\n }\n\n return metadataItem;\n });\n\n if (metadata.length) {\n grpc.metadata = metadata;\n }\n }\n\n // message\n if (brunoRequest.body?.mode === 'grpc' && brunoRequest.body.grpc?.length) {\n const messages = brunoRequest.body.grpc;\n\n // todo: bruno app supports only one message for now\n // update this when bruno app supports multiple messages\n if (messages.length) {\n const message: GrpcMessage = messages[0].content || '';\n if (message.trim().length) {\n grpc.message = message;\n }\n }\n }\n\n // auth\n const auth: Auth | undefined = toOpenCollectionAuth(brunoRequest.auth);\n if (auth) {\n grpc.auth = auth;\n }\n\n ocRequest.grpc = grpc;\n\n // runtime block\n const runtime: GrpcRequestRuntime = {};\n let hasRuntime = false;\n\n // variables\n const variables: Variable[] | undefined = toOpenCollectionVariables(brunoRequest.vars);\n if (variables) {\n runtime.variables = variables;\n hasRuntime = true;\n }\n\n // scripts\n const scripts: Scripts | undefined = toOpenCollectionScripts(brunoRequest);\n if (scripts) {\n runtime.scripts = scripts;\n hasRuntime = true;\n }\n\n // assertions\n const assertions: Assertion[] | undefined = toOpenCollectionAssertions(brunoRequest.assertions);\n if (assertions) {\n runtime.assertions = assertions;\n hasRuntime = true;\n }\n\n if (hasRuntime) {\n ocRequest.runtime = runtime;\n }\n\n // docs\n if (isNonEmptyString(brunoRequest.docs)) {\n ocRequest.docs = brunoRequest.docs;\n }\n\n return stringifyYml(ocRequest);\n } catch (error) {\n console.error('Error stringifying gRPC request:', error);\n throw error;\n }\n};\n\nexport default stringifyGrpcRequest;\n","import type { Item as BrunoItem } from '@usebruno/schema-types/collection/item';\nimport type { WebSocketRequest as BrunoWebSocketRequest } from '@usebruno/schema-types/requests/websocket';\nimport type { WebSocketRequest, WebSocketMessage, WebSocketRequestInfo, WebSocketRequestDetails, WebSocketRequestRuntime } from '@opencollection/types/requests/websocket';\nimport type { Auth } from '@opencollection/types/common/auth';\nimport type { Scripts } from '@opencollection/types/common/scripts';\nimport type { Variable } from '@opencollection/types/common/variables';\nimport type { HttpRequestHeader } from '@opencollection/types/requests/http';\nimport { stringifyYml } from '../utils';\nimport { isNonEmptyString } from '../../../utils';\nimport { toOpenCollectionAuth } from '../common/auth';\nimport { toOpenCollectionHttpHeaders } from '../common/headers';\nimport { toOpenCollectionVariables } from '../common/variables';\nimport { toOpenCollectionScripts } from '../common/scripts';\n\nconst stringifyWebsocketRequest = (item: BrunoItem): string => {\n try {\n const ocRequest: WebSocketRequest = {};\n const brunoRequest = item.request as BrunoWebSocketRequest;\n\n // info block\n const info: WebSocketRequestInfo = {\n name: isNonEmptyString(item.name) ? item.name : 'Untitled Request',\n type: 'websocket'\n };\n if (item.seq) {\n info.seq = item.seq;\n }\n if (item.tags?.length) {\n info.tags = item.tags;\n }\n ocRequest.info = info;\n\n // websocket block\n const websocket: WebSocketRequestDetails = {\n url: isNonEmptyString(brunoRequest.url) ? brunoRequest.url : ''\n };\n\n // headers\n const headers: HttpRequestHeader[] | undefined = toOpenCollectionHttpHeaders(brunoRequest.headers);\n if (headers) {\n websocket.headers = headers;\n }\n\n // message\n if (brunoRequest.body?.mode === 'ws' && brunoRequest.body.ws?.length) {\n const messages = brunoRequest.body.ws;\n\n // todo: bruno app supports only one message for now\n // update this when bruno app supports multiple messages\n if (messages.length) {\n const msg = messages[0];\n const message: WebSocketMessage = {\n type: (msg.type as 'text' | 'json' | 'xml' | 'binary') || 'text',\n data: msg.content || ''\n };\n if (message.data.trim().length) {\n websocket.message = message;\n }\n }\n }\n\n // auth\n const auth: Auth | undefined = toOpenCollectionAuth(brunoRequest.auth);\n if (auth) {\n websocket.auth = auth;\n }\n\n ocRequest.websocket = websocket;\n\n // runtime block\n const runtime: WebSocketRequestRuntime = {};\n let hasRuntime = false;\n\n // variables\n const variables: Variable[] | undefined = toOpenCollectionVariables(brunoRequest.vars);\n if (variables) {\n runtime.variables = variables;\n hasRuntime = true;\n }\n\n // scripts\n const scripts: Scripts | undefined = toOpenCollectionScripts(brunoRequest);\n if (scripts) {\n runtime.scripts = scripts;\n hasRuntime = true;\n }\n\n if (hasRuntime) {\n ocRequest.runtime = runtime;\n }\n\n // settings\n const wsSettings = item.settings as Record<string, number | string | undefined> | undefined;\n if (wsSettings) {\n ocRequest.settings = {};\n const timeout = Number(wsSettings.timeout);\n ocRequest.settings.timeout = !isNaN(timeout) ? timeout : 0;\n const keepAliveInterval = Number(wsSettings.keepAliveInterval);\n ocRequest.settings.keepAliveInterval = !isNaN(keepAliveInterval) ? keepAliveInterval : 0;\n }\n\n // docs\n if (isNonEmptyString(brunoRequest.docs)) {\n ocRequest.docs = brunoRequest.docs;\n }\n\n return stringifyYml(ocRequest);\n } catch (error) {\n console.error('Error stringifying WebSocket request:', error);\n throw error;\n }\n};\n\nexport default stringifyWebsocketRequest;\n","import type { Item as BrunoItem } from '@usebruno/schema-types/collection/item';\nimport type { ScriptFile } from '@opencollection/types/collection/item';\nimport { stringifyYml } from '../utils';\n\nconst stringifyScript = (item: BrunoItem): string => {\n try {\n const ocScript: ScriptFile = {\n type: 'script'\n };\n\n if (item.fileContent?.trim().length) {\n ocScript.script = item.fileContent;\n }\n\n return stringifyYml(ocScript);\n } catch (error) {\n console.error('Error stringifying script:', error);\n throw error;\n }\n};\n\nexport default stringifyScript;\n","import type { FolderRoot } from '@usebruno/schema-types/collection/folder';\nimport type { Folder, FolderInfo } from '@opencollection/types/collection/item';\nimport type { Variable } from '@opencollection/types/common/variables';\nimport type { Action } from '@opencollection/types/common/actions';\nimport type { Scripts } from '@opencollection/types/common/scripts';\nimport type { Auth } from '@opencollection/types/common/auth';\nimport type { HttpRequestHeader } from '@opencollection/types/requests/http';\nimport type { RequestDefaults } from '@opencollection/types/common/request-defaults';\nimport { toOpenCollectionAuth } from './common/auth';\nimport { toOpenCollectionHttpHeaders } from './common/headers';\nimport { toOpenCollectionVariables } from './common/variables';\nimport { toOpenCollectionActions } from './common/actions';\nimport { toOpenCollectionScripts } from './common/scripts';\nimport { stringifyYml } from './utils';\n\nconst hasRequestDefaults = (folderRoot: FolderRoot): boolean => {\n const requestDefaults = folderRoot?.request;\n\n return Boolean((requestDefaults?.headers?.length)\n || (requestDefaults?.vars?.req?.length)\n || (requestDefaults?.vars?.res?.length)\n || hasRequestScripts(folderRoot)\n || hasRequestAuth(folderRoot));\n};\n\nconst hasRequestAuth = (folderRoot: FolderRoot): boolean => {\n return Boolean((folderRoot.request?.auth?.mode !== 'none'));\n};\n\nconst hasRequestScripts = (folderRoot: FolderRoot): boolean => {\n return Boolean((folderRoot.request?.script?.req)\n || (folderRoot.request?.script?.res)\n || (folderRoot.request?.tests));\n};\n\nconst stringifyFolder = (folderRoot: FolderRoot): string => {\n try {\n const ocFolder: Folder = {};\n\n // info block\n const info: FolderInfo = {\n name: folderRoot.meta?.name || 'Untitled Folder',\n type: 'folder',\n seq: folderRoot.meta?.seq || 1\n };\n ocFolder.info = info;\n\n // request defaults\n if (hasRequestDefaults(folderRoot)) {\n ocFolder.request = {} as RequestDefaults;\n\n // headers\n if (folderRoot.request?.headers?.length) {\n const ocHeaders: HttpRequestHeader[] | undefined = toOpenCollectionHttpHeaders(folderRoot.request?.headers);\n if (ocHeaders) {\n ocFolder.request.headers = ocHeaders;\n }\n }\n\n // auth\n if (hasRequestAuth(folderRoot)) {\n const ocAuth: Auth | undefined = toOpenCollectionAuth(folderRoot.request?.auth);\n if (ocAuth) {\n ocFolder.request.auth = ocAuth;\n }\n }\n\n // variables\n if (folderRoot.request?.vars?.req?.length) {\n const ocVariables: Variable[] | undefined = toOpenCollectionVariables(folderRoot.request?.vars);\n if (ocVariables) {\n ocFolder.request.variables = ocVariables;\n }\n }\n\n // actions (post-response variables)\n if (folderRoot.request?.vars?.res?.length) {\n const ocActions: Action[] | undefined = toOpenCollectionActions(folderRoot.request?.vars?.res);\n if (ocActions) {\n (ocFolder.request as any).actions = ocActions;\n }\n }\n\n // scripts\n if (hasRequestScripts(folderRoot)) {\n const ocScripts: Scripts | undefined = toOpenCollectionScripts(folderRoot?.request);\n if (ocScripts) {\n ocFolder.request.scripts = ocScripts;\n }\n }\n }\n\n // docs\n if (folderRoot.docs?.trim().length) {\n ocFolder.docs = {\n content: folderRoot.docs,\n type: 'text/markdown'\n };\n }\n\n return stringifyYml(ocFolder);\n } catch (error) {\n console.error('Error stringifying folder.yml:', error);\n throw error;\n }\n};\nexport default stringifyFolder;\n","import type { OpenCollection } from '@opencollection/types';\nimport type { ProtoFileItem, ProtoFileImportPath } from '@opencollection/types/config/protobuf';\nimport type { HttpRequestHeader } from '@opencollection/types/requests/http';\nimport type { ClientCertificate, PemCertificate, Pkcs12Certificate } from '@opencollection/types/config/certificates';\nimport type { Variable } from '@opencollection/types/common/variables';\nimport type { Action } from '@opencollection/types/common/actions';\nimport type { Scripts } from '@opencollection/types/common/scripts';\nimport { stringifyYml } from './utils';\nimport { toOpenCollectionAuth } from './common/auth';\nimport { toOpenCollectionHttpHeaders } from './common/headers';\nimport { toOpenCollectionVariables } from './common/variables';\nimport { toOpenCollectionActions } from './common/actions';\nimport { toOpenCollectionScripts } from './common/scripts';\nimport type { Auth } from '@opencollection/types/common/auth';\n\nconst hasCollectionConfig = (brunoConfig: any): boolean => {\n // protobuf\n const hasProtobuf = (\n brunoConfig.protobuf?.protoFiles?.length > 0\n || brunoConfig.protobuf?.importPaths?.length > 0\n );\n\n // proxy - check if proxy is configured in newer format\n // Valid newer format: has 'inherit' property and 'config' object\n const isValidProxyFormat = brunoConfig.proxy\n && typeof brunoConfig.proxy === 'object'\n && 'inherit' in brunoConfig.proxy\n && brunoConfig.proxy.config\n && typeof brunoConfig.proxy.config === 'object';\n\n const hasProxy = isValidProxyFormat;\n\n // client certificates\n const hasClientCertificates = brunoConfig.clientCertificates?.certs?.length > 0;\n\n return hasProtobuf || hasProxy || hasClientCertificates;\n};\n\nconst hasRequestDefaults = (collectionRoot: any): boolean => {\n const requestRoot = collectionRoot?.request;\n\n return Boolean((requestRoot?.headers?.length)\n || (requestRoot?.vars?.req?.length)\n || (requestRoot?.vars?.res?.length)\n || hasRequestScripts(collectionRoot)\n || hasRequestAuth(collectionRoot));\n};\n\nconst hasRequestAuth = (collectionRoot: any): boolean => {\n const reqAuthMode = collectionRoot?.request?.auth?.mode;\n return Boolean(reqAuthMode && reqAuthMode !== 'none');\n};\n\nconst hasRequestScripts = (collectionRoot: any): boolean => {\n if (!collectionRoot?.request) return false;\n\n return (collectionRoot.request.script?.req)\n || (collectionRoot.request.script?.res)\n || (collectionRoot.request.tests);\n};\n\nconst hasPresets = (brunoConfig: any): boolean => {\n return brunoConfig?.presets?.requestType?.length\n || brunoConfig?.presets?.requestUrl?.length;\n};\n\nconst stringifyCollection = (collectionRoot: any, brunoConfig: any): string => {\n try {\n const oc: OpenCollection = {};\n\n oc.opencollection = '1.0.0';\n oc.info = {\n name: brunoConfig.name || 'Untitled Collection'\n };\n\n // collection config\n if (hasCollectionConfig(brunoConfig)) {\n oc.config = {};\n\n if (brunoConfig.protobuf?.protoFiles?.length || brunoConfig.protobuf?.importPaths?.length) {\n oc.config.protobuf = {};\n\n if (brunoConfig.protobuf.protoFiles?.length) {\n oc.config.protobuf.protoFiles = brunoConfig.protobuf.protoFiles.map((protoFile: any): ProtoFileItem => ({\n type: 'file' as const,\n path: protoFile.path\n }));\n }\n\n if (brunoConfig.protobuf.importPaths?.length) {\n oc.config.protobuf.importPaths = brunoConfig.protobuf.importPaths.map((importPath: any): ProtoFileImportPath => {\n const item: ProtoFileImportPath = { path: importPath.path };\n if (importPath.enabled === false) {\n item.disabled = true;\n }\n return item;\n });\n }\n }\n\n // proxy - only write newer format\n // Validate that brunoConfig.proxy is in newer format before writing\n const isValidProxyFormat = brunoConfig.proxy\n && typeof brunoConfig.proxy === 'object'\n && 'inherit' in brunoConfig.proxy\n && brunoConfig.proxy.config\n && typeof brunoConfig.proxy.config === 'object';\n\n if (isValidProxyFormat) {\n oc.config.proxy = {\n inherit: brunoConfig.proxy.inherit,\n config: {\n protocol: brunoConfig.proxy.config.protocol || 'http',\n hostname: brunoConfig.proxy.config.hostname || '',\n port: brunoConfig.proxy.config.port || '',\n auth: {\n username: brunoConfig.proxy.config.auth?.username || '',\n password: brunoConfig.proxy.config.auth?.password || ''\n },\n bypassProxy: brunoConfig.proxy.config.bypassProxy || ''\n }\n };\n\n // Add optional disabled field if true\n if (brunoConfig.proxy.disabled === true) {\n oc.config.proxy.disabled = true;\n }\n\n // Add optional auth.disabled field if true\n if (brunoConfig.proxy.config?.auth?.disabled === true) {\n if (oc.config.proxy.config && oc.config.proxy.config.auth) {\n oc.config.proxy.config.auth.disabled = true;\n }\n }\n }\n\n // client certificates\n if (brunoConfig.clientCertificates?.certs?.length) {\n oc.config.clientCertificates = brunoConfig.clientCertificates.certs\n .map((cert: any): ClientCertificate | null => {\n if (cert.type === 'cert') {\n const pemCert: PemCertificate = {\n domain: cert.domain,\n type: 'pem',\n certificateFilePath: cert.certFilePath,\n privateKeyFilePath: cert.keyFilePath,\n ...(cert.passphrase && { passphrase: cert.passphrase })\n };\n return pemCert;\n } else if (cert.type === 'pfx') {\n const pkcs12Cert: Pkcs12Certificate = {\n domain: cert.domain,\n type: 'pkcs12',\n pkcs12FilePath: cert.pfxFilePath,\n ...(cert.passphrase && { passphrase: cert.passphrase })\n };\n return pkcs12Cert;\n } else {\n // Unsupported certificate type - ignore silently\n return null;\n }\n })\n .filter((cert: ClientCertificate | null): cert is ClientCertificate => cert !== null);\n }\n }\n\n // request defaults\n if (hasRequestDefaults(collectionRoot)) {\n oc.request = {};\n\n // headers\n if (collectionRoot.request?.headers?.length) {\n const ocHeaders: HttpRequestHeader[] | undefined = toOpenCollectionHttpHeaders(collectionRoot.request?.headers);\n if (ocHeaders) {\n oc.request.headers = ocHeaders;\n }\n }\n\n // auth\n if (hasRequestAuth(collectionRoot)) {\n const ocAuth: Auth | undefined = toOpenCollectionAuth(collectionRoot.request?.auth);\n if (ocAuth) {\n oc.request.auth = ocAuth;\n }\n }\n\n // variables\n if (collectionRoot.request?.vars?.req?.length) {\n const ocVariables: Variable[] | undefined = toOpenCollectionVariables(collectionRoot.request?.vars);\n if (ocVariables) {\n oc.request.variables = ocVariables;\n }\n }\n\n // actions (post-response variables)\n if (collectionRoot.request?.vars?.res?.length) {\n const ocActions: Action[] | undefined = toOpenCollectionActions(collectionRoot.request?.vars?.res);\n if (ocActions) {\n (oc.request as any).actions = ocActions;\n }\n }\n\n // scripts\n if (hasRequestScripts(collectionRoot)) {\n const ocScripts: Scripts | undefined = toOpenCollectionScripts(collectionRoot.request);\n if (ocScripts) {\n oc.request.scripts = ocScripts;\n }\n }\n }\n\n // docs\n if (collectionRoot?.docs?.trim().length) {\n oc.docs = {\n content: collectionRoot.docs,\n type: 'text/markdown'\n };\n }\n\n // bundled\n oc.bundled = false;\n\n // extensions\n oc.extensions = {};\n\n const hasBrunoExtensions = brunoConfig.ignore?.length || hasPresets(brunoConfig);\n\n if (hasBrunoExtensions) {\n const brunoExtension: any = {};\n\n if (brunoConfig.ignore?.length) {\n const ignoreList: string[] = [];\n brunoConfig.ignore.forEach((ignore: string) => {\n ignoreList.push(ignore);\n });\n brunoExtension.ignore = ignoreList;\n }\n\n if (hasPresets(brunoConfig)) {\n const presetsRequest: any = {};\n if (brunoConfig.presets.requestType?.length) {\n presetsRequest.type = brunoConfig.presets.requestType;\n }\n if (brunoConfig.presets.requestUrl?.length) {\n presetsRequest.url = brunoConfig.presets.requestUrl;\n }\n brunoExtension.presets = {\n request: presetsRequest\n };\n }\n\n oc.extensions.bruno = brunoExtension;\n }\n\n // bruno-specific script extensions\n if (brunoConfig.scripts?.additionalContextRoots?.length) {\n if (!oc.extensions.bruno) {\n oc.extensions.bruno = {};\n }\n (oc.extensions.bruno as any).scripts = {\n additionalContextRoots: brunoConfig.scripts.additionalContextRoots\n };\n }\n\n // bruno-specific extensions\n if (Array.isArray(brunoConfig.openapi) && brunoConfig.openapi.length > 0) {\n if (!oc.extensions.bruno) {\n oc.extensions.bruno = {};\n }\n (oc.extensions.bruno as any).openapi = brunoConfig.openapi.map((entry: any) => ({\n sourceUrl: entry.sourceUrl,\n groupBy: entry.groupBy,\n ...(entry.lastSyncDate && { lastSyncDate: entry.lastSyncDate }),\n ...(entry.specHash && { specHash: entry.specHash }),\n autoCheck: entry.autoCheck !== false,\n autoCheckInterval: entry.autoCheckInterval || 5\n }));\n }\n\n return stringifyYml(oc);\n } catch (error) {\n console.error('Error stringifying opencollection.yml:', error);\n throw error;\n }\n};\n\nexport default stringifyCollection;\n","import type { Environment as BrunoEnvironment, EnvironmentVariable as BrunoEnvironmentVariable } from '@usebruno/schema-types/collection/environment';\nimport type { Environment } from '@opencollection/types/config/environments';\nimport type { Variable, SecretVariable } from '@opencollection/types/common/variables';\nimport { stringifyYml } from './utils';\nimport { ensureString } from '../../utils';\n\nconst toOpenCollectionEnvironmentVariables = (variables: BrunoEnvironmentVariable[]): (Variable | SecretVariable)[] | undefined => {\n if (!variables?.length) {\n return undefined;\n }\n\n const ocVariables: (Variable | SecretVariable)[] = variables\n .filter((v: BrunoEnvironmentVariable) => {\n // todo: currently neither bru lang nor bruno app supports non-string values\n // update this when bruno app supports non-string values\n return typeof v.value === 'string';\n })\n .map((v: BrunoEnvironmentVariable): Variable | SecretVariable => {\n if (v.secret === true) {\n const secretVar: SecretVariable = {\n secret: true,\n name: v.name || ''\n };\n if (v.datatype && v.datatype !== 'string') {\n secretVar.type = v.datatype;\n }\n if (v.enabled === false) {\n secretVar.disabled = true;\n }\n return secretVar;\n }\n\n const variable: Variable = {\n name: v.name || '',\n value:\n v.datatype && v.datatype !== 'string'\n ? { type: v.datatype, data: ensureString(v.value) }\n : ensureString(v.value)\n };\n\n if (v.enabled === false) {\n variable.disabled = true;\n }\n\n return variable;\n });\n\n return ocVariables.length > 0 ? ocVariables : undefined;\n};\n\nconst stringifyEnvironment = (environment: BrunoEnvironment): string => {\n try {\n const ocEnvironment: Environment = {\n name: environment.name\n };\n\n if (environment.color) {\n ocEnvironment.color = environment.color;\n }\n\n if (environment.variables?.length) {\n const ocVariables = toOpenCollectionEnvironmentVariables(environment.variables);\n if (ocVariables) {\n ocEnvironment.variables = ocVariables;\n }\n }\n\n if (environment.externalSecrets) {\n (ocEnvironment as any).externalSecrets = {\n type: environment.externalSecrets.type,\n variables: (environment.externalSecrets.variables || []).map((variable) => ({ ...variable }))\n };\n }\n\n return stringifyYml(ocEnvironment);\n } catch (error) {\n console.error('Error stringifying environment:', error);\n throw error;\n }\n};\nexport default stringifyEnvironment;\n","import { Worker } from 'node:worker_threads';\n\ninterface QueuedTask {\n priority: number;\n scriptPath: string;\n data: any;\n taskType: 'parse' | 'stringify';\n resolve?: (value: any) => void;\n reject?: (reason?: any) => void;\n}\n\nclass WorkerQueue {\n private queue: QueuedTask[];\n private isProcessing: boolean;\n private workers: Record<string, Worker>;\n\n constructor() {\n this.queue = [];\n this.isProcessing = false;\n this.workers = {};\n }\n\n async getWorkerForScriptPath(scriptPath: string) {\n if (!this.workers) this.workers = {};\n let worker = this.workers[scriptPath];\n if (!worker || worker.threadId === -1) {\n this.workers[scriptPath] = worker = new Worker(scriptPath);\n }\n return worker;\n }\n\n async enqueue(task: QueuedTask) {\n const { priority, scriptPath, data, taskType } = task;\n\n return new Promise((resolve, reject) => {\n this.queue.push({ priority, scriptPath, data, taskType, resolve, reject });\n this.queue?.sort((taskX, taskY) => taskX?.priority - taskY?.priority);\n this.processQueue();\n });\n }\n\n async processQueue() {\n if (this.isProcessing || this.queue.length === 0) {\n return;\n }\n\n this.isProcessing = true;\n const { scriptPath, data, taskType, resolve, reject } = this.queue.shift() as QueuedTask;\n\n try {\n const result = await this.runWorker({ scriptPath, data, taskType });\n resolve?.(result);\n } catch (error) {\n reject?.(error);\n } finally {\n this.isProcessing = false;\n this.processQueue();\n }\n }\n\n async runWorker({ scriptPath, data, taskType }: { scriptPath: string; data: any; taskType: 'parse' | 'stringify' }) {\n return new Promise(async (resolve, reject) => {\n let worker = await this.getWorkerForScriptPath(scriptPath);\n\n const messageHandler = (data: any) => {\n worker.off('message', messageHandler);\n worker.off('error', errorHandler);\n worker.off('exit', exitHandler);\n\n if (data?.error) {\n reject(new Error(data?.error));\n } else {\n resolve(data);\n }\n };\n\n const errorHandler = (error: Error) => {\n worker.off('message', messageHandler);\n worker.off('error', errorHandler);\n worker.off('exit', exitHandler);\n reject(error);\n };\n\n const exitHandler = (code: number) => {\n worker.off('message', messageHandler);\n worker.off('error', errorHandler);\n worker.off('exit', exitHandler);\n // Remove dead worker from cache\n delete this.workers[scriptPath];\n reject(new Error(`Worker stopped with exit code ${code}`));\n };\n\n worker.on('message', messageHandler);\n worker.on('error', errorHandler);\n worker.on('exit', exitHandler);\n\n worker.postMessage({ taskType, data });\n });\n }\n\n async cleanup() {\n const promises = Object.values(this.workers).map((worker) => {\n if (worker.threadId !== -1) {\n return worker.terminate();\n }\n return Promise.resolve();\n });\n\n await Promise.allSettled(promises);\n this.workers = {};\n }\n}\n\nexport default WorkerQueue;\n","import type { CollectionFormat } from './types';\n\nexport const DEFAULT_COLLECTION_FORMAT: CollectionFormat = 'yml';\n","import WorkerQueue from './WorkerQueue';\nimport { Lane, CollectionFormat } from '../types';\nimport { DEFAULT_COLLECTION_FORMAT } from '../constants';\nimport path from 'node:path';\n\nconst sizeInMB = (size: number): number => {\n return size / (1024 * 1024);\n};\n\nconst getSize = (data: any): number => {\n return sizeInMB(typeof data === 'string' ? Buffer.byteLength(data, 'utf8') : Buffer.byteLength(JSON.stringify(data), 'utf8'));\n};\n\n/**\n * Lanes are used to determine which worker queue to use based on the size of the data.\n *\n * The first lane is for smaller files (<0.1MB), the second lane is for larger files (>=0.1MB).\n * This helps with parsing performance.\n */\nconst LANES: Lane[] = [{\n maxSize: 0.005\n}, {\n maxSize: 0.1\n}, {\n maxSize: 1\n}, {\n maxSize: 10\n}, {\n maxSize: 100\n}];\n\ninterface WorkerQueueWithSize {\n maxSize: number;\n workerQueue: WorkerQueue;\n\n}\n\nclass BruParserWorker {\n private workerQueues: WorkerQueueWithSize[];\n\n constructor() {\n this.workerQueues = LANES?.map((lane) => ({\n maxSize: lane?.maxSize,\n workerQueue: new WorkerQueue()\n }));\n }\n\n private getWorkerQueue(size: number): WorkerQueue {\n // Find the first queue that can handle the given size\n // or fallback to the last queue for largest files\n const queueForSize = this.workerQueues.find((queue) =>\n queue.maxSize >= size\n );\n\n return queueForSize?.workerQueue ?? this.workerQueues[this.workerQueues.length - 1].workerQueue;\n }\n\n private async enqueueTask({ data, taskType, format = DEFAULT_COLLECTION_FORMAT }: { data: any; taskType: 'parse' | 'stringify'; format?: CollectionFormat }): Promise<any> {\n const size = getSize(data);\n const workerQueue = this.getWorkerQueue(size);\n const workerScriptPath = path.join(__dirname, './workers/worker-script.js');\n\n return workerQueue.enqueue({\n data: { data, format },\n priority: size,\n scriptPath: workerScriptPath,\n taskType\n });\n }\n\n async parseRequest(data: any, format: CollectionFormat = DEFAULT_COLLECTION_FORMAT): Promise<any> {\n return this.enqueueTask({ data, taskType: 'parse', format });\n }\n\n async stringifyRequest(data: any, format: CollectionFormat = DEFAULT_COLLECTION_FORMAT): Promise<any> {\n return this.enqueueTask({ data, taskType: 'stringify', format });\n }\n\n async cleanup(): Promise<void> {\n const cleanupPromises = this.workerQueues.map(({ workerQueue }) =>\n workerQueue.cleanup()\n );\n await Promise.allSettled(cleanupPromises);\n }\n}\n\nexport default BruParserWorker;\n","/**\n * Parses a .bru file and extracts body content while redacting it from the main content\n * @param {string} bruFileContent - The raw content of the .bru file\n * @returns {Object} Object containing redacted file content and extracted body data\n */\nexport const bruRequestParseAndRedactBodyData = (bruFileContent: string) => {\n try {\n // Define the patterns that indicate the start of different body types\n const bodyTypePatterns = [\n 'body:json {',\n 'body:text {',\n 'body:xml {',\n 'body:sparql {',\n 'body:graphql {'\n ];\n\n // Normalize line endings to LF\n bruFileContent = (bruFileContent || '').replace(/\\r\\n/g, '\\n');\n\n const EOL = `\\n`;\n\n /**\n * Removes the leading 2-space indentation from each line of a string\n * @param {string} indentedString - The string with leading spaces to remove\n * @returns {string} The string with indentation removed\n */\n const removeLeadingIndentation = (indentedString: string) => {\n if (!indentedString || !indentedString.length) {\n return indentedString || '';\n }\n\n return indentedString\n .split(EOL)\n .map((line) => line.replace(/^ /, ''))\n .join(EOL);\n };\n\n // Split the file content into blocks\n let fileContentBlocks = bruFileContent.split(`${EOL}}${EOL}`);\n fileContentBlocks = fileContentBlocks.filter(Boolean).map((_) => _.trim());\n\n // Extract body blocks and their content\n const extractedBodyBlocks = fileContentBlocks\n .filter((block) => bodyTypePatterns.some((pattern) => block.startsWith(pattern)))\n .reduce((bodyContentMap: Record<string, string>, bodyBlock) => {\n // Extract the body type (json, text, xml, etc.) from the first line\n const firstLine = bodyBlock.split(EOL)[0];\n const bodyType = firstLine.split(`body:`)[1].split(/\\s/)[0];\n\n // Extract the body content (everything between the opening and closing braces)\n const bodyContentLines = bodyBlock.split(EOL).slice(1);\n const rawBodyContent = bodyContentLines.join(EOL);\n\n // Remove indentation from the body content\n const cleanBodyContent = removeLeadingIndentation(rawBodyContent);\n\n bodyContentMap[bodyType] = cleanBodyContent;\n return bodyContentMap;\n }, {});\n\n // Filter out body blocks to get the remaining file content\n const fileContentWithoutBodyBlocks = fileContentBlocks.filter((block) =>\n !bodyTypePatterns.some((pattern) => block.startsWith(pattern))\n );\n\n return {\n bruFileStringWithRedactedBody: fileContentWithoutBodyBlocks.join(`${EOL}}${EOL}${EOL}`).concat(`${EOL}}${EOL}`),\n extractedBodyContent: extractedBodyBlocks\n };\n } catch (error) {\n console.error('Error parsing and redacting body data:', error);\n return {\n bruFileStringWithRedactedBody: bruFileContent,\n extractedBodyContent: {}\n };\n }\n};\n","import type { BrunoCollection, BrunoItem, BrunoEnvironment } from '@usebruno/schema-types';\n\nimport {\n parseBruRequest,\n parseBruCollection,\n parseBruEnvironment,\n stringifyBruRequest,\n stringifyBruCollection,\n stringifyBruEnvironment\n} from './formats/bru';\nimport {\n parseYmlItem,\n parseYmlCollection,\n parseYmlFolder,\n parseYmlEnvironment,\n stringifyYmlItem,\n stringifyYmlFolder,\n stringifyYmlCollection,\n stringifyYmlEnvironment\n} from './formats/yml';\nimport { dotenvToJson } from '@usebruno/lang';\nimport BruParserWorker from './workers';\nimport {\n ParseOptions,\n StringifyOptions,\n CollectionFormat\n} from './types';\nimport { DEFAULT_COLLECTION_FORMAT } from './constants';\nimport { bruRequestParseAndRedactBodyData } from './formats/bru/utils/request-parse-and-redact-body-data';\n\n// request\nexport const parseRequest = (content: string, options: ParseOptions = { format: DEFAULT_COLLECTION_FORMAT }): any => {\n if (options.format === 'bru') {\n return parseBruRequest(content);\n } else if (options.format === 'yml') {\n return parseYmlItem(content);\n }\n throw new Error(`Unsupported format: ${options.format}`);\n};\n\nexport const parseRequestAndRedactBody = (content: string, options: ParseOptions = { format: 'bru' }): any => {\n if (options.format === 'bru') {\n return bruRequestParseAndRedactBodyData(content);\n }\n throw new Error(`Unsupported format: ${options.format}`);\n};\n\nexport const stringifyRequest = (requestObj: BrunoItem, options: StringifyOptions = { format: DEFAULT_COLLECTION_FORMAT }): string => {\n if (options.format === 'bru') {\n return stringifyBruRequest(requestObj);\n } else if (options.format === 'yml') {\n return stringifyYmlItem(requestObj);\n }\n throw new Error(`Unsupported format: ${options.format}`);\n};\n\n// request via worker\nlet globalWorkerInstance: BruParserWorker | null = null;\nconst getWorkerInstance = (): BruParserWorker => {\n if (!globalWorkerInstance) {\n globalWorkerInstance = new BruParserWorker();\n }\n return globalWorkerInstance;\n};\n\nexport const parseRequestViaWorker = async (content: string, options: { format: CollectionFormat; filename?: string }): Promise<any> => {\n const fileParserWorker = getWorkerInstance();\n\n return await fileParserWorker.parseRequest(content, options.format);\n};\n\nexport const stringifyRequestViaWorker = async (requestObj: any, options: { format: CollectionFormat }): Promise<string> => {\n const fileParserWorker = getWorkerInstance();\n return await fileParserWorker.stringifyRequest(requestObj, options.format);\n};\n\n// collection\nexport const parseCollection = (content: string, options: ParseOptions = { format: DEFAULT_COLLECTION_FORMAT }): any => {\n if (options.format === 'bru') {\n return parseBruCollection(content);\n } else if (options.format === 'yml') {\n return parseYmlCollection(content);\n }\n throw new Error(`Unsupported format: ${options.format}`);\n};\n\nexport const stringifyCollection = (collectionObj: BrunoCollection, brunoConfig: any, options: StringifyOptions = { format: DEFAULT_COLLECTION_FORMAT }): string => {\n if (options.format === 'bru') {\n return stringifyBruCollection(collectionObj, false);\n } else if (options.format === 'yml') {\n return stringifyYmlCollection(collectionObj, brunoConfig);\n }\n throw new Error(`Unsupported format: ${options.format}`);\n};\n\n// folder\nexport const parseFolder = (content: string, options: ParseOptions = { format: DEFAULT_COLLECTION_FORMAT }): any => {\n if (options.format === 'bru') {\n return parseBruCollection(content);\n } else if (options.format === 'yml') {\n return parseYmlFolder(content);\n }\n throw new Error(`Unsupported format: ${options.format}`);\n};\n\nexport const stringifyFolder = (folderObj: any, options: StringifyOptions = { format: DEFAULT_COLLECTION_FORMAT }): string => {\n if (options.format === 'bru') {\n return stringifyBruCollection(folderObj, true);\n } else if (options.format === 'yml') {\n return stringifyYmlFolder(folderObj);\n }\n throw new Error(`Unsupported format: ${options.format}`);\n};\n\n// environment\nexport const parseEnvironment = (content: string, options: ParseOptions = { format: DEFAULT_COLLECTION_FORMAT }): any => {\n if (options.format === 'bru') {\n return parseBruEnvironment(content);\n } else if (options.format === 'yml') {\n return parseYmlEnvironment(content);\n }\n throw new Error(`Unsupported format: ${options.format}`);\n};\n\nexport const stringifyEnvironment = (envObj: BrunoEnvironment, options: StringifyOptions = { format: DEFAULT_COLLECTION_FORMAT }): string => {\n if (options.format === 'bru') {\n return stringifyBruEnvironment(envObj);\n } else if (options.format === 'yml') {\n return stringifyYmlEnvironment(envObj);\n }\n throw new Error(`Unsupported format: ${options.format}`);\n};\n\nexport const parseDotEnv = (content: string): Record<string, string> => {\n return dotenvToJson(content);\n};\n\nexport { BruParserWorker };\nexport * from './types';\nexport * from './constants';\n","import type { OpenCollection } from '@opencollection/types';\nimport type { FolderRoot } from '@usebruno/schema-types/collection/folder';\nimport { parseYml } from './utils';\nimport { toBrunoAuth } from './common/auth';\nimport { toBrunoHttpHeaders } from './common/headers';\nimport { toBrunoVariables } from './common/variables';\nimport { toBrunoPostResponseVariables } from './common/actions';\nimport { toBrunoScripts } from './common/scripts';\nimport { ensureString } from '../../utils';\n\ninterface ParsedCollection {\n collectionRoot: FolderRoot;\n brunoConfig: Record<string, any>;\n}\n\nconst parseCollection = (ymlString: string): ParsedCollection => {\n try {\n const oc: OpenCollection = parseYml(ymlString);\n\n // bruno config\n const brunoConfig: Record<string, any> = {\n opencollection: oc.opencollection || '1.0.0',\n name: ensureString(oc.info?.name, 'Untitled Collection'),\n type: 'collection',\n ignore: []\n };\n\n const brunoExtension = (oc.extensions as any)?.bruno;\n if (brunoExtension?.ignore && Array.isArray(brunoExtension.ignore)) {\n brunoConfig.ignore = brunoExtension.ignore;\n }\n\n // presets\n if (brunoExtension?.presets) {\n const presets = brunoExtension.presets as any;\n if (presets.request) {\n brunoConfig.presets = {\n requestType: presets.request.type || [],\n requestUrl: presets.request.url || []\n };\n }\n }\n\n // bruno-specific extensions\n const brunoExtensions = oc.extensions?.bruno as any;\n if (Array.isArray(brunoExtensions?.scripts?.additionalContextRoots)) {\n const sanitizedRoots = brunoExtensions.scripts.additionalContextRoots\n .filter((item: any) => typeof item === 'string');\n\n if (sanitizedRoots.length > 0) {\n brunoConfig.scripts = {\n ...brunoConfig.scripts,\n additionalContextRoots: sanitizedRoots\n };\n }\n }\n if (Array.isArray(brunoExtensions?.openapi) && brunoExtensions.openapi.length > 0) {\n brunoConfig.openapi = brunoExtensions.openapi.map((entry: any) => ({\n sourceUrl: entry.sourceUrl,\n groupBy: entry.groupBy,\n ...(entry.lastSyncDate && { lastSyncDate: entry.lastSyncDate }),\n ...(entry.specHash && { specHash: entry.specHash }),\n autoCheck: entry.autoCheck !== false,\n autoCheckInterval: entry.autoCheckInterval || 5\n }));\n }\n\n // protobuf\n if (oc.config?.protobuf) {\n brunoConfig.protobuf = {\n protoFiles: oc.config.protobuf.protoFiles?.map((protoFile: any) => ({\n path: protoFile.path\n })) || [],\n importPaths: oc.config.protobuf.importPaths?.map((importPath: any) => ({\n path: importPath.path,\n enabled: importPath.disabled !== true\n })) || []\n };\n }\n\n // proxy - only support newer format\n // Default: inherit from global preferences\n brunoConfig.proxy = {\n inherit: true,\n config: {\n protocol: 'http',\n hostname: '',\n port: '',\n auth: {\n username: '',\n password: ''\n },\n bypassProxy: ''\n }\n };\n\n if (oc.config?.proxy && typeof oc.config.proxy === 'object') {\n // Validate newer format: must have 'inherit' and 'config' properties\n const proxyConfig = oc.config.proxy as any;\n\n if ('inherit' in proxyConfig && typeof proxyConfig.inherit === 'boolean' && proxyConfig.config && typeof proxyConfig.config === 'object') {\n // Valid newer format\n brunoConfig.proxy = {\n inherit: proxyConfig.inherit,\n config: {\n protocol: proxyConfig.config.protocol || 'http',\n hostname: proxyConfig.config.hostname || '',\n port: proxyConfig.config.port || '',\n auth: {\n username: proxyConfig.config.auth?.username || '',\n password: proxyConfig.config.auth?.password || ''\n },\n bypassProxy: proxyConfig.config.bypassProxy || ''\n }\n };\n\n // Handle optional disabled field\n if (proxyConfig.disabled === true) {\n brunoConfig.proxy.disabled = true;\n }\n\n // Handle optional auth.disabled field\n if (proxyConfig.config.auth?.disabled === true) {\n brunoConfig.proxy.config.auth.disabled = true;\n }\n }\n // If not in newer format, use default (inherit: true)\n }\n\n // client certificates\n if (oc.config?.clientCertificates?.length) {\n brunoConfig.clientCertificates = {\n certs: oc.config.clientCertificates.map((cert: any) => {\n if (cert.type === 'pem') {\n return {\n domain: cert.domain,\n type: 'cert',\n certFilePath: cert.certificateFilePath,\n keyFilePath: cert.privateKeyFilePath,\n passphrase: cert.passphrase || ''\n };\n } else if (cert.type === 'pkcs12') {\n return {\n domain: cert.domain,\n type: 'pfx',\n pfxFilePath: cert.pkcs12FilePath,\n passphrase: cert.passphrase || ''\n };\n }\n return null;\n }).filter((cert: any) => cert !== null)\n };\n }\n\n // collection root\n const collectionRoot: FolderRoot = {\n meta: null,\n request: null,\n docs: null\n };\n\n // request defaults\n if (oc.request) {\n collectionRoot.request = {\n headers: null,\n auth: null,\n script: {\n req: null,\n res: null\n },\n vars: {\n req: [],\n res: []\n },\n tests: null\n };\n\n // headers\n const headers = toBrunoHttpHeaders(oc.request.headers);\n collectionRoot.request.headers = headers || [];\n\n // auth\n const auth = toBrunoAuth(oc.request.auth);\n if (auth) {\n collectionRoot.request.auth = auth;\n }\n\n // variables\n const variables = toBrunoVariables(oc.request.variables);\n const postResponseVars = toBrunoPostResponseVariables((oc.request as any).actions);\n collectionRoot.request.vars = {\n req: variables.req,\n res: postResponseVars\n };\n\n // scripts\n const scripts = toBrunoScripts(oc.request.scripts);\n if (scripts?.script && collectionRoot.request.script) {\n if (scripts.script.req) {\n collectionRoot.request.script.req = scripts.script.req;\n }\n if (scripts.script.res) {\n collectionRoot.request.script.res = scripts.script.res;\n }\n }\n if (scripts?.tests) {\n collectionRoot.request.tests = scripts.tests;\n }\n }\n\n // docs\n if (oc.docs) {\n if (typeof oc.docs === 'string') {\n collectionRoot.docs = oc.docs;\n } else if (typeof oc.docs === 'object' && oc.docs.content) {\n collectionRoot.docs = oc.docs.content;\n }\n }\n\n return {\n collectionRoot,\n brunoConfig\n };\n } catch (error) {\n console.error('Error parsing collection:', error);\n throw error;\n }\n};\n\nexport default parseCollection;\n","import type { FolderRoot } from '@usebruno/schema-types/collection/folder';\nimport type { Folder } from '@opencollection/types/collection/item';\nimport { parseYml } from './utils';\nimport { toBrunoAuth } from './common/auth';\nimport { toBrunoHttpHeaders } from './common/headers';\nimport { toBrunoVariables } from './common/variables';\nimport { toBrunoPostResponseVariables } from './common/actions';\nimport { toBrunoScripts } from './common/scripts';\nimport { ensureString } from '../../utils';\n\nconst parseFolder = (ymlString: string): FolderRoot => {\n try {\n const ocFolder: Folder = parseYml(ymlString);\n\n const info = ocFolder.info;\n\n const folderRoot: FolderRoot = {\n meta: {\n name: ensureString(info?.name, 'Untitled Folder'),\n seq: info?.seq || 1\n },\n request: null,\n docs: null\n };\n\n // request defaults\n if (ocFolder.request) {\n folderRoot.request = {\n headers: [],\n auth: null,\n script: {\n req: null,\n res: null\n },\n vars: {\n req: [],\n res: []\n },\n tests: null\n };\n\n // headers\n const headers = toBrunoHttpHeaders(ocFolder.request.headers);\n if (headers) {\n folderRoot.request.headers = headers;\n }\n\n // auth\n const auth = toBrunoAuth(ocFolder.request.auth);\n if (auth) {\n folderRoot.request.auth = auth;\n }\n\n // variables\n const variables = toBrunoVariables(ocFolder.request.variables);\n const postResponseVars = toBrunoPostResponseVariables((ocFolder.request as any).actions);\n folderRoot.request.vars = {\n req: variables.req,\n res: postResponseVars\n };\n\n // scripts\n const scripts = toBrunoScripts(ocFolder.request.scripts);\n if (scripts?.script && folderRoot.request.script) {\n if (scripts.script.req) {\n folderRoot.request.script.req = scripts.script.req;\n }\n if (scripts.script.res) {\n folderRoot.request.script.res = scripts.script.res;\n }\n }\n if (scripts?.tests) {\n folderRoot.request.tests = scripts.tests;\n }\n }\n\n // docs (now at root level)\n if (ocFolder.docs) {\n if (typeof ocFolder.docs === 'string' && ocFolder.docs.trim().length) {\n folderRoot.docs = ocFolder.docs;\n } else if (typeof ocFolder.docs === 'object' && ocFolder.docs.content?.trim().length) {\n folderRoot.docs = ocFolder.docs.content;\n }\n }\n\n return folderRoot;\n } catch (error) {\n console.error('Error parsing folder:', error);\n throw error;\n }\n};\n\nexport default parseFolder;\n"],"names":["PARAMETER_MAPPINGS","type","sendIn","source","mapParametersFromSource","sourceParams","length","map","param","collectParametersForType","json","grantType","shouldIncludeParameterType","relevantMappings","filter","mapping","allParams","mappedParams","push","getOauth2AdditionalParameters","auth","oauth2","additionalParameters","parameterTypes","params","error","console","parseBruCollection","data","parsed","_collectionBruToJson","transformedJson","request","headers","_","get","script","vars","tests","settings","docs","meta","name","undefined","seq","sequence","isNaN","Number","hasOauth2GrantType","Object","keys","Promise","reject","stringifyBruCollection","isFolder","collectionBruJson","req","res","_jsonToCollectionBru","bruExampleToJson","parentType","parentMethod","bruToJsonV2","requestType","requestMethod","transformedType","status","statusText","description","method","url","body","mode","response","header","value","content","log","jsonExampleToBru","BLOCK_KEYS","stringifyYml","obj","lines","YAML","stringify","lineWidth","indent","minContentWidth","defaultStringType","split","result","i","line","startsWith","key","includes","trim","join","parseYml","ymlString","parse","customAlphabet","require","isString","isNumber","isNonEmptyString","ensureString","fallback","String","uuid","customNanoId","normalizeBoolean","mapAdditionalParameters","Array","isArray","mapped","placement","toLowerCase","mapSendIn","mappedParam","Boolean","buildClientCredentials","oauth","credentials","clientId","clientSecret","credentialsPlacement","buildTokenConfig","tokenConfig","credentialsId","id","tokenPlacement","tokenHeaderPrefix","query","tokenQueryKey","tokenSource","buildSettings","autoFetchToken","autoRefreshToken","buildResourceOwnerPasswordFlow","flow","accessTokenUrl","refreshTokenUrl","resourceOwner","username","password","buildResourceOwner","scope","accessTokenRequest","token","refreshTokenRequest","refresh","toOpenCollectionOAuth2","buildClientCredentialsFlow","authorizationUrl","callbackUrl","authorizationRequest","authorization","state","pkce","disabled","buildPkce","buildAuthorizationCodeFlow","buildImplicitFlow","warn","reverseAdditionalParameters","reversePlacementMapping","enabled","toOpenCollectionAuth","config","accessKeyId","secretAccessKey","sessionToken","service","region","profileName","buildAwsV4Auth","awsv4","buildBasicAuth","basic","buildBearerAuth","bearer","buildDigestAuth","digest","domain","buildNtlmAuth","ntlm","buildWsseAuth","wsse","buildApiKeyAuth","apikey","consumerKey","consumerSecret","accessToken","accessTokenSecret","verifier","signatureMethod","privateKey","privateKeyType","timestamp","nonce","version","realm","includeBodyHash","buildOAuth1Auth","oauth1","toBrunoAuth","brunoAuth","brunoOAuth","tempParams","tokenParams","refreshParams","authParams","authCodeFlow","toBrunoOAuth2","toOpenCollectionHttpHeaders","ocHeaders","httpHeader","toBrunoHttpHeaders","brunoHeaders","uid","toOpenCollectionParams","ocParams","ocParam","toBrunoParams","brunoParams","brunoParam","toOpenCollectionBody","text","xml","sparql","formEntries","formUrlEncoded","entry","formEntry","multipartEntries","multipartForm","multipartEntry","contentType","fileEntries","file","filePath","selected","toBrunoBody","graphql","brunoBody","isTypedValue","toOpenCollectionVariables","variables","reqVars","reqVarsArray","ocVariables","v","variable","datatype","toBrunoVariables","forEach","local","toOpenCollectionActions","resVariables","actions","action","phase","selector","expression","toBrunoPostResponseVariables","resVars","setVarAction","toOpenCollectionScripts","ocScripts","code","toBrunoScripts","scripts","brunoScripts","OPERATORS","UNARY_OPERATORS","toOpenCollectionAssertions","assertions","ocAssertions","assertion","operator","str","firstWord","rest","remainingValue","parseAssertionOperator","ocAssertion","toBrunoAssertions","brunoAssertions","valueString","brunoAssertion","toBrunoGrpcMetadata","metadata","brunoMetadata","parseItem","ocItem","parsedItemYml","itemType","info","runtime","http","grpc","websocket","ensureAuthV3Rc1BackwardsCompatibility","item","Error","ocRequest","brunoRequest","postResponseVars","brunoItem","tags","fileContent","root","items","examples","filename","pathname","encodeUrl","timeout","followRedirects","maxRedirects","example","brunoExample","itemUid","parseHttpRequest","parseGraphQLRequest","methodType","protoPath","protoFilePath","message","parseGrpcRequest","ws","messageData","wsSettings","keepAliveInterval","parseWebsocketRequest","ocScript","parseEnvironment","ocEnvironment","brunoEnvironment","secret","isSecretVariable","color","externalSecrets","toBrunoExternalSecrets","stringifyItem","hasRuntime","httpSettings","ocExample","exampleHeaders","exampleParams","exampleBody","statusNum","isInteger","responseHeaders","toOpenCollectionResponseHeaders","contentString","JSON","stringifyHttpRequest","graphqlBody","hasBody","stringifyGraphqlRequest","metadataItem","messages","stringifyGrpcRequest","msg","stringifyWebsocketRequest","stringifyScript","hasRequestAuth","folderRoot","hasRequestScripts","stringifyFolder","ocFolder","requestDefaults","hasRequestDefaults","ocAuth","ocActions","collectionRoot","reqAuthMode","hasPresets","brunoConfig","presets","requestUrl","stringifyCollection","oc","hasProtobuf","protobuf","protoFiles","importPaths","hasProxy","proxy","hasClientCertificates","clientCertificates","certs","hasCollectionConfig","protoFile","path","importPath","inherit","protocol","hostname","port","bypassProxy","cert","certificateFilePath","certFilePath","privateKeyFilePath","keyFilePath","passphrase","pkcs12FilePath","pfxFilePath","requestRoot","bundled","extensions","ignore","brunoExtension","ignoreList","presetsRequest","bruno","additionalContextRoots","openapi","sourceUrl","groupBy","lastSyncDate","specHash","autoCheck","autoCheckInterval","stringifyEnvironment","environment","secretVar","toOpenCollectionEnvironmentVariables","WorkerQueue","constructor","this","queue","isProcessing","workers","getWorkerForScriptPath","scriptPath","worker","threadId","Worker","enqueue","task","priority","taskType","resolve","sort","taskX","taskY","processQueue","shift","runWorker","async","messageHandler","off","errorHandler","exitHandler","on","postMessage","cleanup","promises","values","terminate","allSettled","DEFAULT_COLLECTION_FORMAT","LANES","maxSize","BruParserWorker","workerQueues","lane","workerQueue","getWorkerQueue","size","queueForSize","find","enqueueTask","format","Buffer","byteLength","getSize","workerScriptPath","__dirname","parseRequest","stringifyRequest","cleanupPromises","options","urlPath","default","toUpperCase","e","selectedMethodType","parseBruRequest","parseYmlItem","parseRequestAndRedactBody","bruFileContent","bodyTypePatterns","replace","EOL","removeLeadingIndentation","indentedString","fileContentBlocks","extractedBodyBlocks","block","some","pattern","reduce","bodyContentMap","bodyBlock","bodyType","rawBodyContent","slice","cleanBodyContent","bruFileStringWithRedactedBody","concat","extractedBodyContent","bruRequestParseAndRedactBodyData","requestObj","bruJson","jsonToBruV2","stringifyBruRequest","stringifyYmlItem","globalWorkerInstance","getWorkerInstance","parseRequestViaWorker","fileParserWorker","stringifyRequestViaWorker","parseCollection","opencollection","brunoExtensions","sanitizedRoots","proxyConfig","parseYmlCollection","collectionObj","stringifyYmlCollection","parseFolder","parseYmlFolder","folderObj","stringifyYmlFolder","bru","bruToEnvJsonV2","each","parseBruEnvironment","parseYmlEnvironment","envObj","envJsonToBruV2","stringifyBruEnvironment","stringifyYmlEnvironment","parseDotEnv","dotenvToJson"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../src/formats/bru/utils/oauth2-additional-params.ts","../../src/utils/index.ts","../../src/formats/bru/index.ts","../../src/formats/yml/utils.ts","../../src/formats/yml/common/auth-oauth2.ts","../../src/formats/yml/common/auth.ts","../../src/formats/yml/common/headers.ts","../../src/formats/yml/common/params.ts","../../src/formats/yml/common/body.ts","../../src/formats/yml/common/datatype.ts","../../src/formats/yml/common/variables.ts","../../src/formats/yml/common/actions.ts","../../src/formats/yml/common/scripts.ts","../../src/formats/yml/common/assertions.ts","../../src/formats/yml/items/parseGrpcRequest.ts","../../src/formats/yml/parseItem.ts","../../src/formats/yml/items/parseHttpRequest.ts","../../src/formats/yml/common/app.ts","../../src/formats/yml/items/parseGraphQLRequest.ts","../../src/formats/yml/items/parseWebsocketRequest.ts","../../src/formats/yml/items/parseScript.ts","../../src/formats/yml/items/parseApp.ts","../../src/constants.ts","../../src/formats/yml/parseEnvironment.ts","../../src/formats/yml/stringifyItem.ts","../../src/formats/yml/items/stringifyHttpRequest.ts","../../src/formats/yml/items/stringifyGraphQLRequest.ts","../../src/formats/yml/items/stringifyGrpcRequest.ts","../../src/formats/yml/items/stringifyWebsocketRequest.ts","../../src/formats/yml/items/stringifyScript.ts","../../src/formats/yml/items/stringifyApp.ts","../../src/formats/yml/stringifyFolder.ts","../../src/formats/yml/stringifyCollection.ts","../../src/formats/yml/stringifyEnvironment.ts","../../src/workers/WorkerQueue/index.ts","../../src/workers/index.ts","../../src/formats/bru/utils/request-parse-and-redact-body-data.ts","../../src/formats/bru/utils/redact-large-text-blocks.ts","../../src/utils/secretsJsonToEnvironments.ts","../../src/index.ts","../../src/formats/yml/parseCollection.ts","../../src/formats/yml/parseFolder.ts"],"sourcesContent":["type T_Oauth2ParameterType = 'authorization' | 'token' | 'refresh';\ntype T_Oauth2ParameterSendInType = 'headers' | 'queryparams' | 'body';\n\nexport interface T_OAuth2AdditionalParam {\n name: string;\n value: string;\n enabled: boolean;\n sendIn: T_Oauth2ParameterSendInType;\n}\n\nexport interface T_OAuth2AdditionalParameters {\n authorization?: T_OAuth2AdditionalParam[];\n token?: T_OAuth2AdditionalParam[];\n refresh?: T_OAuth2AdditionalParam[];\n}\n\nexport interface T_Oauth2Auth {\n grantType: string;\n additionalParameters?: T_OAuth2AdditionalParameters;\n}\n\nexport interface T_BruJson {\n auth: {\n oauth2: T_Oauth2Auth;\n };\n oauth2_additional_parameters_auth_req_headers?: any[];\n oauth2_additional_parameters_auth_req_queryparams?: any[];\n oauth2_additional_parameters_access_token_req_headers?: any[];\n oauth2_additional_parameters_access_token_req_queryparams?: any[];\n oauth2_additional_parameters_access_token_req_bodyvalues?: any[];\n oauth2_additional_parameters_refresh_token_req_headers?: any[];\n oauth2_additional_parameters_refresh_token_req_queryparams?: any[];\n oauth2_additional_parameters_refresh_token_req_bodyvalues?: any[];\n}\n\ninterface T_Oauth2ParameterMapping {\n type: T_Oauth2ParameterType;\n sendIn: T_Oauth2ParameterSendInType;\n source: keyof T_BruJson;\n}\n\nconst PARAMETER_MAPPINGS: T_Oauth2ParameterMapping[] = [\n // Authorization parameters (only for authorization_code grant type)\n { type: 'authorization', sendIn: 'headers', source: 'oauth2_additional_parameters_auth_req_headers' },\n { type: 'authorization', sendIn: 'queryparams', source: 'oauth2_additional_parameters_auth_req_queryparams' },\n\n // Token parameters (for all grant types)\n { type: 'token', sendIn: 'headers', source: 'oauth2_additional_parameters_access_token_req_headers' },\n { type: 'token', sendIn: 'queryparams', source: 'oauth2_additional_parameters_access_token_req_queryparams' },\n { type: 'token', sendIn: 'body', source: 'oauth2_additional_parameters_access_token_req_bodyvalues' },\n\n // Refresh parameters (for grant types that support refresh)\n { type: 'refresh', sendIn: 'headers', source: 'oauth2_additional_parameters_refresh_token_req_headers' },\n { type: 'refresh', sendIn: 'queryparams', source: 'oauth2_additional_parameters_refresh_token_req_queryparams' },\n { type: 'refresh', sendIn: 'body', source: 'oauth2_additional_parameters_refresh_token_req_bodyvalues' }\n];\n\n/**\n * Maps source parameters to T_OAuth2AdditionalParam format\n */\nconst mapParametersFromSource = (sourceParams: any[], sendIn: T_Oauth2ParameterSendInType): T_OAuth2AdditionalParam[] => {\n if (!sourceParams?.length) {\n return [];\n }\n\n return sourceParams.map((param) => ({\n ...param,\n sendIn\n }));\n};\n\n/**\n * Checks if a parameter type should be included based on grant type\n */\nconst shouldIncludeParameterType = (type: T_Oauth2ParameterType, grantType: string): boolean => {\n // Authorization parameters are only valid for authorization_code grant type\n if (type === 'authorization') {\n return grantType === 'authorization_code' || grantType === 'implicit';\n }\n\n if (type === 'token' || type === 'refresh') {\n return grantType !== 'implicit';\n }\n\n // Token and refresh parameters are valid for all grant types\n return true;\n};\n\n/**\n * Collects all parameters for a specific type (authorization, token, or refresh)\n */\nconst collectParametersForType = (\n json: T_BruJson,\n type: T_Oauth2ParameterType,\n grantType: string\n): T_OAuth2AdditionalParam[] => {\n if (!shouldIncludeParameterType(type, grantType)) {\n return [];\n }\n\n const relevantMappings = PARAMETER_MAPPINGS.filter((mapping) => mapping.type === type);\n const allParams: T_OAuth2AdditionalParam[] = [];\n\n for (const mapping of relevantMappings) {\n const sourceParams = json[mapping.source] as any[];\n const mappedParams = mapParametersFromSource(sourceParams, mapping.sendIn);\n allParams.push(...mappedParams);\n }\n\n return allParams;\n};\n\n/**\n * This function extracts OAuth2 additional parameters from various sources in the bru json data and organizes\n * them into a structured format based on their usage context (authorization, token, refresh).\n *\n * @param json - json object containing OAuth2 configuration and additional parameters\n * @returns OAuth2 additional parameters\n */\nexport const getOauth2AdditionalParameters = (json: T_BruJson): T_OAuth2AdditionalParameters => {\n const grantType = json.auth.oauth2.grantType;\n const additionalParameters: T_OAuth2AdditionalParameters = {};\n\n try {\n // Collect parameters for each type\n const parameterTypes: T_Oauth2ParameterType[] = ['authorization', 'token', 'refresh'];\n\n for (const type of parameterTypes) {\n const params = collectParametersForType(json, type, grantType);\n if (params.length > 0) {\n additionalParameters[type] = params;\n }\n }\n } catch (error) {\n console.error(error);\n console.error('Error while getting the oauth2 additional parameters!');\n }\n\n return additionalParameters;\n};\n","const { customAlphabet } = require('nanoid');\n\nexport const isString = (value: unknown): value is string => typeof value === 'string';\n\nexport const isNumber = (value: unknown): value is number => typeof value === 'number';\n\nexport const isNonEmptyString = (value: unknown): value is string => isString(value) && value.trim().length > 0;\n\nexport const ensureString = (value: unknown, fallback: string = ''): string => {\n if (value === null || value === undefined) {\n return fallback;\n }\n if (typeof value === 'string') {\n return value;\n }\n return String(value);\n};\n\nexport const uuid = () => {\n // https://github.com/ai/nanoid/blob/main/url-alphabet/index.js\n const urlAlphabet = 'useandom26T198340PX75pxJACKVERYMINDBUSHWOLFGQZbfghjklqvwyzrict';\n const customNanoId = customAlphabet(urlAlphabet, 21);\n\n return customNanoId();\n};\n","import * as _ from 'lodash';\nimport {\n bruToJsonV2,\n jsonToBruV2,\n bruToEnvJsonV2,\n envJsonToBruV2,\n collectionBruToJson as _collectionBruToJson,\n jsonToCollectionBru as _jsonToCollectionBru\n} from '@usebruno/lang';\nimport { getOauth2AdditionalParameters } from './utils/oauth2-additional-params';\nimport { uuid } from '../../utils';\n\nexport const parseBruRequest = (data: string | any, parsed: boolean = false): any => {\n try {\n const json = parsed ? data : bruToJsonV2(data);\n\n if (_.get(json, 'meta.type') === 'app') {\n const seq = _.get(json, 'meta.seq');\n const tags = _.get(json, 'meta.tags', []);\n return {\n type: 'app',\n name: _.get(json, 'meta.name'),\n seq: !_.isNaN(seq) ? Number(seq) : 1,\n tags: Array.isArray(tags) ? tags : [],\n settings: _.get(json, 'settings', {}),\n app: { code: _.get(json, 'app.code', null) },\n request: null\n };\n }\n\n let requestType = _.get(json, 'meta.type');\n switch (requestType) {\n case 'http':\n requestType = 'http-request';\n break;\n case 'graphql':\n requestType = 'graphql-request';\n break;\n case 'grpc':\n requestType = 'grpc-request';\n break;\n case 'ws':\n requestType = 'ws-request';\n break;\n default:\n requestType = 'http-request';\n }\n\n const sequence = _.get(json, 'meta.seq');\n const tags = _.get(json, 'meta.tags', []);\n const urlPath: Record<typeof requestType, string> = {\n 'grpc-request': 'grpc.url',\n 'ws-request': 'ws.url',\n 'default': 'http.url'\n };\n\n const appData = _.get(json, 'app');\n const app = appData\n ? { code: _.get(appData, 'code', null), enabled: _.get(appData, 'enabled', false) === true }\n : null;\n\n const transformedJson = {\n type: requestType,\n name: _.get(json, 'meta.name'),\n seq: !_.isNaN(sequence) ? Number(sequence) : 1,\n settings: _.get(json, 'settings', {}),\n app,\n tags: Array.isArray(tags) ? tags : [],\n request: {\n // Preserving special characters in custom methods. Using _.upperCase strips special characters.\n method:\n requestType === 'grpc-request'\n ? _.get(json, 'grpc.method', '')\n : String(_.get(json, 'http.method') ?? '').toUpperCase(),\n url: _.get(json, urlPath[requestType], _.get(json, urlPath.default)),\n headers: requestType === 'grpc-request' ? _.get(json, 'metadata', []) : _.get(json, 'headers', []),\n auth: _.get(json, 'auth', {}),\n body: _.get(json, 'body', {}),\n script: _.get(json, 'script', {}),\n vars: _.get(json, 'vars', {}),\n assertions: _.get(json, 'assertions', []),\n tests: _.get(json, 'tests', ''),\n docs: _.get(json, 'docs', '')\n },\n examples: _.get(json, 'examples', []).map((e: any) => {\n return bruExampleToJson(e, true, requestType, _.get(json, 'http.method'));\n })\n } as any;\n\n // Add request type specific fields\n if (requestType === 'grpc-request') {\n const selectedMethodType = _.get(json, 'grpc.methodType');\n selectedMethodType && ((transformedJson.request as any).methodType = selectedMethodType);\n const protoPath = _.get(json, 'grpc.protoPath');\n protoPath && ((transformedJson.request as any).protoPath = protoPath);\n transformedJson.request.auth.mode = _.get(json, 'grpc.auth', 'none');\n transformedJson.request.body = _.get(json, 'body', {\n mode: 'grpc',\n grpc: _.get(json, 'body.grpc', [\n {\n name: 'message 1',\n content: '{}'\n }\n ])\n });\n } else if (requestType === 'ws-request') {\n transformedJson.request.auth.mode = _.get(json, 'ws.auth', 'none');\n transformedJson.request.body = _.get(json, 'body', {\n mode: 'ws',\n ws: _.get(json, 'body.ws', [\n {\n name: 'message 1',\n content: '{}'\n }\n ])\n });\n } else {\n // For HTTP and GraphQL\n (transformedJson.request as any).params = _.get(json, 'params', []);\n transformedJson.request.auth.mode = _.get(json, 'http.auth', 'none');\n transformedJson.request.body.mode = _.get(json, 'http.body', 'none');\n }\n\n // add oauth2 additional parameters if they exist\n const hasOauth2GrantType = json?.auth?.oauth2?.grantType;\n if (hasOauth2GrantType) {\n const additionalParameters = getOauth2AdditionalParameters(json);\n const hasAdditionalParameters = Object.keys(additionalParameters || {}).length > 0;\n if (hasAdditionalParameters) {\n transformedJson.request.auth.oauth2.additionalParameters = additionalParameters;\n }\n }\n return transformedJson;\n } catch (error) {\n console.log('parseBruRequest error', error);\n throw error;\n }\n};\n\nexport const stringifyBruRequest = (json: any): string => {\n try {\n // Standalone app item — emit only meta + the app code block.\n if (_.get(json, 'type') === 'app') {\n const seq = _.get(json, 'seq');\n const bruJson: any = {\n meta: {\n name: _.get(json, 'name'),\n type: 'app',\n seq: !_.isNaN(seq) ? Number(seq) : 1,\n tags: _.get(json, 'tags', [])\n },\n settings: _.get(json, 'settings', {}),\n app: { code: _.get(json, 'app.code', '') }\n };\n return jsonToBruV2(bruJson);\n }\n\n let type = _.get(json, 'type');\n switch (type) {\n case 'http-request':\n type = 'http';\n break;\n case 'graphql-request':\n type = 'graphql';\n break;\n case 'grpc-request':\n type = 'grpc';\n break;\n case 'ws-request':\n type = 'ws';\n break;\n default:\n type = 'http';\n }\n\n const sequence = _.get(json, 'seq');\n\n // Start with the common meta section\n const bruJson = {\n meta: {\n name: _.get(json, 'name'),\n type: type,\n seq: !_.isNaN(sequence) ? Number(sequence) : 1,\n tags: _.get(json, 'tags', [])\n }\n } as any;\n\n // For HTTP and GraphQL requests, maintain the current structure\n if (type === 'http' || type === 'graphql') {\n bruJson.http = {\n // Preserve special characters in custom request methods. Avoid _.lowerCase which strips symbols.\n method: String(_.get(json, 'request.method') ?? '').toLowerCase(),\n url: _.get(json, 'request.url'),\n auth: _.get(json, 'request.auth.mode', 'none'),\n body: _.get(json, 'request.body.mode', 'none')\n };\n bruJson.params = _.get(json, 'request.params', []);\n bruJson.body = _.get(json, 'request.body', {\n mode: 'json',\n json: '{}'\n });\n } else if (type === 'grpc') {\n // For gRPC, add gRPC-specific structure but maintain field names\n bruJson.grpc = {\n url: _.get(json, 'request.url'),\n auth: _.get(json, 'request.auth.mode', 'none'),\n body: _.get(json, 'request.body.mode', 'grpc')\n };\n // Only add method if it exists\n const method = _.get(json, 'request.method');\n const methodType = _.get(json, 'request.methodType');\n const protoPath = _.get(json, 'request.protoPath');\n if (method) bruJson.grpc.method = method;\n if (methodType) bruJson.grpc.methodType = methodType;\n if (protoPath) bruJson.grpc.protoPath = protoPath;\n bruJson.body = _.get(json, 'request.body', {\n mode: 'grpc',\n grpc: _.get(json, 'request.body.grpc', [\n {\n name: 'message 1',\n content: '{}'\n }\n ])\n });\n } else if (type === 'ws') {\n bruJson.ws = {\n url: _.get(json, 'request.url'),\n auth: _.get(json, 'request.auth.mode', 'none'),\n body: _.get(json, 'request.body.mode', 'ws')\n };\n\n bruJson.body = _.get(json, 'request.body', {\n mode: 'ws',\n ws: _.get(json, 'request.body.ws', [\n {\n name: 'message 1',\n content: '{}'\n }\n ])\n });\n }\n\n // Common fields for all request types\n if (type === 'grpc') {\n bruJson.metadata = _.get(json, 'request.headers', []); // Use metadata for gRPC\n } else {\n bruJson.headers = _.get(json, 'request.headers', []); // Use headers for HTTP/GraphQL\n }\n bruJson.auth = _.get(json, 'request.auth', {});\n bruJson.script = _.get(json, 'request.script', {});\n bruJson.vars = {\n req: _.get(json, 'request.vars.req', []),\n res: _.get(json, 'request.vars.res', [])\n };\n // should we add assertions and tests for grpc requests?\n bruJson.assertions = _.get(json, 'request.assertions', []);\n bruJson.tests = _.get(json, 'request.tests', '');\n bruJson.settings = _.get(json, 'settings', {});\n bruJson.docs = _.get(json, 'request.docs', '');\n bruJson.examples = _.get(json, 'examples', []).map((e: any) => jsonExampleToBru(e));\n\n const app = _.get(json, 'app');\n if (app && (app.enabled === true || (app.code && app.code.length))) {\n bruJson.app = { code: app.code || null, enabled: app.enabled === true };\n }\n\n const bru = jsonToBruV2(bruJson);\n return bru;\n } catch (error) {\n throw error;\n }\n};\n\nexport const parseBruCollection = (data: string | any, parsed: boolean = false): any => {\n try {\n const json = parsed ? data : _collectionBruToJson(data);\n\n const transformedJson: any = {\n request: {\n headers: _.get(json, 'headers', []),\n auth: _.get(json, 'auth', {}),\n script: _.get(json, 'script', {}),\n vars: _.get(json, 'vars', {}),\n tests: _.get(json, 'tests', '')\n },\n settings: _.get(json, 'settings', {}),\n docs: _.get(json, 'docs', '')\n };\n\n // add meta if it exists\n // this is only for folder bru file\n if (json.meta) {\n transformedJson.meta = {\n name: json.meta.name\n };\n\n // Include seq if it exists\n if (json.meta.seq !== undefined) {\n const sequence = json.meta.seq;\n transformedJson.meta.seq = !isNaN(sequence) ? Number(sequence) : 1;\n }\n }\n\n // add oauth2 additional parameters if they exist\n const hasOauth2GrantType = json?.auth?.oauth2?.grantType;\n if (hasOauth2GrantType) {\n const additionalParameters = getOauth2AdditionalParameters(json);\n const hasAdditionalParameters = Object.keys(additionalParameters).length > 0;\n if (hasAdditionalParameters) {\n transformedJson.request.auth.oauth2.additionalParameters = additionalParameters;\n }\n }\n\n return transformedJson;\n } catch (error) {\n return Promise.reject(error);\n }\n};\n\nexport const stringifyBruCollection = (json: any, isFolder?: boolean): string => {\n try {\n const collectionBruJson: any = {\n headers: _.get(json, 'request.headers', []),\n script: {\n req: _.get(json, 'request.script.req', ''),\n res: _.get(json, 'request.script.res', '')\n },\n vars: {\n req: _.get(json, 'request.vars.req', []),\n res: _.get(json, 'request.vars.res', [])\n },\n tests: _.get(json, 'request.tests', ''),\n auth: _.get(json, 'request.auth', {}),\n docs: _.get(json, 'docs', '')\n };\n\n // add meta if it exists\n // this is only for folder bru file\n if (json?.meta) {\n collectionBruJson.meta = {\n name: json.meta.name\n };\n\n // Include seq if it exists\n if (json.meta.seq !== undefined) {\n const sequence = json.meta.seq;\n collectionBruJson.meta.seq = !isNaN(sequence) ? Number(sequence) : 1;\n }\n }\n\n if (!isFolder) {\n collectionBruJson.auth = _.get(json, 'request.auth', {});\n }\n\n return _jsonToCollectionBru(collectionBruJson);\n } catch (error) {\n throw error;\n }\n};\n\nexport const parseBruEnvironment = (bru: string): any => {\n try {\n const json = bruToEnvJsonV2(bru);\n\n // the app env format requires each variable to have a type\n // this need to be evaluated and safely removed\n // i don't see it being used in schema validation\n if (json && json.variables && json.variables.length) {\n _.each(json.variables, (v: any) => (v.type = 'text'));\n }\n\n // bruToEnvJsonV2 emits the nested `externalSecrets: { type, variables: [{ name,\n // <identifier>, enabled }] }`. The app/schema additionally expect a `uid` per variable.\n if (json?.externalSecrets && Array.isArray(json.externalSecrets.variables)) {\n json.externalSecrets.variables = json.externalSecrets.variables.map((v: any) => ({\n uid: uuid(),\n ...v\n }));\n }\n\n return json;\n } catch (error) {\n return Promise.reject(error);\n }\n};\n\nexport const stringifyBruEnvironment = (json: any): string => {\n try {\n const bru = envJsonToBruV2(json);\n return bru;\n } catch (error) {\n throw error;\n }\n};\n\n// New functions for example handling\nexport const bruExampleToJson = (data: string | any, parsed: boolean = false, parentType?: string, parentMethod?: string): any => {\n try {\n const json = parsed ? data : bruToJsonV2(data);\n\n // Use parent request's type and method if provided\n const requestType = parentType || _.get(json, 'meta.type', 'http');\n const requestMethod = parentMethod || _.get(json, 'http.method', 'GET');\n\n let transformedType = requestType;\n switch (requestType) {\n case 'http':\n transformedType = 'http-request';\n break;\n case 'graphql':\n transformedType = 'graphql-request';\n break;\n case 'grpc':\n transformedType = 'grpc-request';\n break;\n case 'ws':\n transformedType = 'ws-request';\n break;\n default:\n transformedType = 'http-request';\n }\n\n /**\n * Backward compatibility (pre-v3.0.2 - v3.2.0): Postman imports before PR #6876 stored status/statusText swapped\n * (code: \"OK\", text: \"202\" instead of code: 202, text: \"OK\"). Detect and swap back.\n * TODO(Sid / Shubh): Remove after v5 — all collections should be migrated by then.\n */\n let status = _.get(json, 'response.status', '200');\n let statusText = _.get(json, 'response.statusText', 'OK');\n if (isNaN(Number(status)) && !isNaN(Number(statusText))) {\n [status, statusText] = [statusText, status];\n }\n\n // Follow the same structure as the main request, but with missing fields for examples\n const transformedJson = {\n type: transformedType,\n name: _.get(json, 'name'),\n description: _.get(json, 'description', ''),\n // Examples don't have seq, settings, tags\n request: {\n method: _.get(json, 'request.method') || requestMethod,\n url: _.get(json, 'request.url'),\n headers: _.get(json, 'request.headers', []),\n body: _.get(json, 'request.body', {\n mode: 'none'\n }),\n // Examples don't have script, vars, assertions, tests, docs\n params: _.get(json, 'request.params', [])\n },\n response: {\n headers: _.get(json, 'response.headers', []).map((header: any) => ({\n name: header.name,\n value: header.value\n })),\n status: Number(status) || 200,\n statusText: statusText || 'OK',\n body: {\n type: _.get(json, 'response.body.type', 'json'),\n content: _.get(json, 'response.body.content', '')\n }\n }\n } as any;\n\n return transformedJson;\n } catch (error) {\n console.log('bruExampleToJson error', error);\n throw error;\n }\n};\n\nexport const jsonExampleToBru = (json: any) => {\n try {\n // Transform the JSON to match the same structure as main request, but with missing fields\n const exampleJson = {\n name: _.get(json, 'name'),\n description: _.get(json, 'description', ''),\n // Examples don't have seq, settings, tags\n request: {\n method: _.get(json, 'request.method'),\n url: _.get(json, 'request.url'),\n headers: _.get(json, 'request.headers', []),\n body: _.get(json, 'request.body', {}),\n // Examples don't have script, vars, assertions, tests, docs\n params: _.get(json, 'request.params', [])\n },\n response: _.get(json, 'response', {})\n };\n\n return exampleJson;\n } catch (error) {\n throw error;\n }\n};\n","import * as YAML from 'yaml';\n\n// Top-level keys that should have a blank line before them\nconst BLOCK_KEYS = ['info', 'http', 'graphql', 'grpc', 'websocket', 'runtime', 'settings', 'examples', 'docs', 'items', 'request'];\n\nexport const stringifyYml = (obj: any): string => {\n const yamlStr = YAML.stringify(obj, {\n lineWidth: 0,\n indent: 2,\n minContentWidth: 0,\n defaultStringType: 'PLAIN'\n });\n\n // Add blank lines before major blocks (only at the top level, not indented)\n const lines = yamlStr.split('\\n');\n const result: string[] = [];\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n // Check if this is a top-level key (no leading whitespace) that should have a blank line\n if (i > 0 && !line.startsWith(' ') && !line.startsWith('\\t')) {\n const key = line.split(':')[0];\n if (BLOCK_KEYS.includes(key)) {\n // Add blank line before this block (if previous line isn't already blank)\n if (result.length > 0 && result[result.length - 1].trim() !== '') {\n result.push('');\n }\n }\n }\n result.push(line);\n }\n\n return result.join('\\n');\n};\n\nexport const parseYml = (ymlString: string): any => {\n return YAML.parse(ymlString);\n};\n","import type {\n AuthOAuth2,\n OAuth2AdditionalParameter,\n OAuth2AuthorizationCodeFlow,\n OAuth2ClientCredentials,\n OAuth2ClientCredentialsFlow,\n OAuth2ImplicitFlow,\n OAuth2PKCE,\n OAuth2ResourceOwner,\n OAuth2ResourceOwnerPasswordFlow,\n OAuth2Settings,\n OAuth2TokenConfig\n} from '@opencollection/types/common/auth';\nimport type {\n OAuth2 as BrunoOAuth2,\n OAuthAdditionalParameter as BrunoOAuthAdditionalParameter\n} from '@usebruno/schema-types/common/auth';\nimport { isString, isNonEmptyString } from '../../../utils';\n\nconst normalizeBoolean = (value?: boolean | null): boolean | undefined =>\n typeof value === 'boolean' ? value : undefined;\n\nconst mapSendIn = (sendIn?: string | null): OAuth2AdditionalParameter['placement'] | undefined => {\n if (!isString(sendIn)) {\n return undefined;\n }\n\n switch (sendIn.trim().toLowerCase()) {\n case 'headers':\n return 'header';\n case 'queryparams':\n return 'query';\n case 'body':\n return 'body';\n default:\n return undefined;\n }\n};\n\nconst mapAdditionalParameters = (params?: BrunoOAuthAdditionalParameter[] | null): OAuth2AdditionalParameter[] | undefined => {\n if (!Array.isArray(params) || params.length === 0) {\n return undefined;\n }\n\n const mapped = params\n .filter((param) => param && isNonEmptyString(param.name))\n .map((param) => {\n const placement = mapSendIn(param!.sendIn);\n if (!placement) {\n return undefined;\n }\n\n const mappedParam: OAuth2AdditionalParameter = {\n name: param!.name!.trim(),\n placement\n };\n\n isNonEmptyString(param!.value) && (mappedParam.value = param.value);\n\n return mappedParam;\n })\n .filter((param): param is OAuth2AdditionalParameter => Boolean(param));\n\n return mapped.length > 0 ? mapped : undefined;\n};\n\nconst buildClientCredentials = (oauth: BrunoOAuth2): OAuth2ClientCredentials | undefined => {\n const credentials: OAuth2ClientCredentials = {};\n\n isNonEmptyString(oauth.clientId) && (credentials.clientId = oauth.clientId);\n isNonEmptyString(oauth.clientSecret) && (credentials.clientSecret = oauth.clientSecret);\n isNonEmptyString(oauth.credentialsPlacement) && (credentials.placement = oauth.credentialsPlacement);\n\n return Object.keys(credentials).length > 0 ? credentials : undefined;\n};\n\nconst buildResourceOwner = (oauth: BrunoOAuth2): OAuth2ResourceOwner | undefined => {\n const resourceOwner: OAuth2ResourceOwner = {};\n\n isNonEmptyString(oauth.username) && (resourceOwner.username = oauth.username);\n isNonEmptyString(oauth.password) && (resourceOwner.password = oauth.password);\n\n return Object.keys(resourceOwner).length > 0 ? resourceOwner : undefined;\n};\n\nconst buildPkce = (pkce?: boolean | null): OAuth2PKCE | undefined => {\n if (pkce === null || pkce === undefined) {\n return undefined;\n }\n\n // If pkce is false, set disabled: true; if true, return empty object (enabled by default)\n return pkce ? {} : { disabled: true };\n};\n\nconst buildTokenConfig = (oauth: BrunoOAuth2): OAuth2TokenConfig | undefined => {\n const tokenConfig: OAuth2TokenConfig = {};\n\n isNonEmptyString(oauth.credentialsId) && (tokenConfig.id = oauth.credentialsId);\n\n if (!isNonEmptyString(oauth.tokenPlacement)) {\n // default to header\n tokenConfig.placement = { header: '' };\n }\n\n if (oauth.tokenPlacement === 'header') {\n tokenConfig.placement = {\n header: oauth.tokenHeaderPrefix as string\n };\n }\n\n if (oauth.tokenPlacement === 'url') {\n tokenConfig.placement = {\n query: oauth.tokenQueryKey as string\n };\n }\n\n tokenConfig.source = oauth.tokenSource || 'access_token';\n\n return Object.keys(tokenConfig).length > 0 ? tokenConfig : undefined;\n};\n\nconst buildSettings = (oauth: BrunoOAuth2): OAuth2Settings | undefined => {\n const autoFetchToken = normalizeBoolean(oauth.autoFetchToken);\n const autoRefreshToken = normalizeBoolean(oauth.autoRefreshToken);\n\n const settings: OAuth2Settings = {};\n if (autoFetchToken !== undefined) settings.autoFetchToken = autoFetchToken;\n if (autoRefreshToken !== undefined) settings.autoRefreshToken = autoRefreshToken;\n\n return Object.keys(settings).length > 0 ? settings : undefined;\n};\n\nconst buildClientCredentialsFlow = (oauth: BrunoOAuth2): OAuth2ClientCredentialsFlow => {\n const flow: OAuth2ClientCredentialsFlow = {\n type: 'oauth2',\n flow: 'client_credentials'\n };\n\n isNonEmptyString(oauth.accessTokenUrl) && (flow.accessTokenUrl = oauth.accessTokenUrl);\n isNonEmptyString(oauth.refreshTokenUrl) && (flow.refreshTokenUrl = oauth.refreshTokenUrl);\n\n const credentials = buildClientCredentials(oauth);\n if (credentials) flow.credentials = credentials;\n\n isNonEmptyString(oauth.scope) && (flow.scope = oauth.scope);\n\n const accessTokenRequest = mapAdditionalParameters(oauth.additionalParameters?.token);\n const refreshTokenRequest = mapAdditionalParameters(oauth.additionalParameters?.refresh);\n\n if (accessTokenRequest || refreshTokenRequest) {\n flow.additionalParameters = {};\n if (accessTokenRequest) {\n flow.additionalParameters.accessTokenRequest = accessTokenRequest;\n }\n if (refreshTokenRequest) {\n flow.additionalParameters.refreshTokenRequest = refreshTokenRequest;\n }\n }\n\n const tokenConfig = buildTokenConfig(oauth);\n if (tokenConfig) flow.tokenConfig = tokenConfig;\n\n const settings = buildSettings(oauth);\n if (settings) flow.settings = settings;\n\n return flow;\n};\n\nconst buildResourceOwnerPasswordFlow = (oauth: BrunoOAuth2): OAuth2ResourceOwnerPasswordFlow => {\n const flow: OAuth2ResourceOwnerPasswordFlow = {\n type: 'oauth2',\n flow: 'resource_owner_password_credentials'\n };\n\n isNonEmptyString(oauth.accessTokenUrl) && (flow.accessTokenUrl = oauth.accessTokenUrl);\n isNonEmptyString(oauth.refreshTokenUrl) && (flow.refreshTokenUrl = oauth.refreshTokenUrl);\n\n const credentials = buildClientCredentials(oauth);\n if (credentials) flow.credentials = credentials;\n\n const resourceOwner = buildResourceOwner(oauth);\n if (resourceOwner) flow.resourceOwner = resourceOwner;\n\n isNonEmptyString(oauth.scope) && (flow.scope = oauth.scope);\n\n const accessTokenRequest = mapAdditionalParameters(oauth.additionalParameters?.token);\n const refreshTokenRequest = mapAdditionalParameters(oauth.additionalParameters?.refresh);\n\n if (accessTokenRequest || refreshTokenRequest) {\n flow.additionalParameters = {};\n if (accessTokenRequest) {\n flow.additionalParameters.accessTokenRequest = accessTokenRequest;\n }\n if (refreshTokenRequest) {\n flow.additionalParameters.refreshTokenRequest = refreshTokenRequest;\n }\n }\n\n const tokenConfig = buildTokenConfig(oauth);\n if (tokenConfig) flow.tokenConfig = tokenConfig;\n\n const settings = buildSettings(oauth);\n if (settings) flow.settings = settings;\n\n return flow;\n};\n\nconst buildAuthorizationCodeFlow = (oauth: BrunoOAuth2): OAuth2AuthorizationCodeFlow => {\n const flow: OAuth2AuthorizationCodeFlow = {\n type: 'oauth2',\n flow: 'authorization_code'\n };\n\n isNonEmptyString(oauth.authorizationUrl) && (flow.authorizationUrl = oauth.authorizationUrl);\n isNonEmptyString(oauth.accessTokenUrl) && (flow.accessTokenUrl = oauth.accessTokenUrl);\n isNonEmptyString(oauth.refreshTokenUrl) && (flow.refreshTokenUrl = oauth.refreshTokenUrl);\n isNonEmptyString(oauth.callbackUrl) && (flow.callbackUrl = oauth.callbackUrl);\n\n const credentials = buildClientCredentials(oauth);\n if (credentials) flow.credentials = credentials;\n\n const authorizationRequest = mapAdditionalParameters(oauth.additionalParameters?.authorization);\n const accessTokenRequest = mapAdditionalParameters(oauth.additionalParameters?.token);\n const refreshTokenRequest = mapAdditionalParameters(oauth.additionalParameters?.refresh);\n\n if (authorizationRequest || accessTokenRequest || refreshTokenRequest) {\n flow.additionalParameters = {};\n if (authorizationRequest) {\n flow.additionalParameters.authorizationRequest = authorizationRequest;\n }\n if (accessTokenRequest) {\n flow.additionalParameters.accessTokenRequest = accessTokenRequest;\n }\n if (refreshTokenRequest) {\n flow.additionalParameters.refreshTokenRequest = refreshTokenRequest;\n }\n }\n\n isNonEmptyString(oauth.scope) && (flow.scope = oauth.scope);\n isNonEmptyString(oauth.state) && (flow.state = oauth.state);\n\n const pkce = buildPkce(oauth.pkce);\n if (pkce) flow.pkce = pkce;\n\n const tokenConfig = buildTokenConfig(oauth);\n if (tokenConfig) flow.tokenConfig = tokenConfig;\n\n const settings = buildSettings(oauth);\n if (settings) flow.settings = settings;\n\n return flow;\n};\n\nconst buildImplicitFlow = (oauth: BrunoOAuth2): OAuth2ImplicitFlow => {\n const flow: OAuth2ImplicitFlow = {\n type: 'oauth2',\n flow: 'implicit'\n };\n\n isNonEmptyString(oauth.authorizationUrl) && (flow.authorizationUrl = oauth.authorizationUrl);\n isNonEmptyString(oauth.callbackUrl) && (flow.callbackUrl = oauth.callbackUrl);\n isNonEmptyString(oauth.clientId) && (flow.credentials = { clientId: oauth.clientId });\n isNonEmptyString(oauth.scope) && (flow.scope = oauth.scope);\n isNonEmptyString(oauth.state) && (flow.state = oauth.state);\n\n const authorizationRequest = mapAdditionalParameters(oauth.additionalParameters?.authorization);\n if (authorizationRequest) {\n flow.additionalParameters = { authorizationRequest };\n }\n\n const tokenConfig = buildTokenConfig(oauth);\n if (tokenConfig) flow.tokenConfig = tokenConfig;\n\n const settings = buildSettings(oauth);\n if (settings) flow.settings = settings;\n\n return flow;\n};\n\nexport const toOpenCollectionOAuth2 = (oauth?: BrunoOAuth2 | null): AuthOAuth2 | undefined => {\n if (!oauth) {\n return undefined;\n }\n\n switch (oauth.grantType) {\n case 'client_credentials':\n return buildClientCredentialsFlow(oauth);\n case 'password':\n return buildResourceOwnerPasswordFlow(oauth);\n case 'authorization_code':\n return buildAuthorizationCodeFlow(oauth);\n case 'implicit':\n return buildImplicitFlow(oauth);\n default:\n console.warn(`toOpenCollectionOAuth2: Unsupported OAuth2 grant type \"${oauth.grantType}\".`);\n return undefined;\n }\n};\n\nconst reversePlacementMapping = (placement?: OAuth2AdditionalParameter['placement']): 'headers' | 'queryparams' | 'body' | null => {\n if (!placement) {\n return null;\n }\n\n switch (placement) {\n case 'header':\n return 'headers';\n case 'query':\n return 'queryparams';\n case 'body':\n return 'body';\n default:\n return null;\n }\n};\n\nconst reverseAdditionalParameters = (params?: OAuth2AdditionalParameter[]): BrunoOAuthAdditionalParameter[] | null => {\n if (!Array.isArray(params) || params.length === 0) {\n return null;\n }\n\n const mapped = params.map((param): BrunoOAuthAdditionalParameter => {\n const sendIn = reversePlacementMapping(param.placement);\n\n return {\n name: param.name || null,\n value: param.value || null,\n sendIn: sendIn || 'headers',\n enabled: true\n };\n });\n\n return mapped.length > 0 ? mapped : null;\n};\n\nexport const toBrunoOAuth2 = (oauth: AuthOAuth2 | null | undefined): BrunoOAuth2 | null => {\n if (!oauth) {\n return null;\n }\n\n const brunoOAuth: BrunoOAuth2 = {\n grantType: 'authorization_code',\n username: null,\n password: null,\n callbackUrl: null,\n authorizationUrl: null,\n accessTokenUrl: null,\n clientId: null,\n clientSecret: null,\n scope: null,\n state: null,\n pkce: false, // Default to false for all grant types\n credentialsPlacement: null,\n credentialsId: null,\n tokenPlacement: null,\n tokenHeaderPrefix: null,\n tokenQueryKey: null,\n tokenSource: 'access_token',\n refreshTokenUrl: null,\n autoRefreshToken: false, // Default to false\n autoFetchToken: true, // Default to true\n additionalParameters: null\n };\n\n switch (oauth.flow) {\n case 'client_credentials':\n brunoOAuth.grantType = 'client_credentials';\n if (oauth.accessTokenUrl) brunoOAuth.accessTokenUrl = oauth.accessTokenUrl;\n if (oauth.refreshTokenUrl) brunoOAuth.refreshTokenUrl = oauth.refreshTokenUrl;\n if (oauth.credentials?.clientId) brunoOAuth.clientId = oauth.credentials.clientId;\n if (oauth.credentials?.clientSecret) brunoOAuth.clientSecret = oauth.credentials.clientSecret;\n if (oauth.credentials?.placement) brunoOAuth.credentialsPlacement = oauth.credentials.placement;\n if (oauth.scope) brunoOAuth.scope = oauth.scope;\n\n // token config\n if (oauth.tokenConfig?.id) brunoOAuth.credentialsId = oauth.tokenConfig.id;\n if (oauth.tokenConfig?.source) brunoOAuth.tokenSource = oauth.tokenConfig.source || 'access_token';\n if (oauth.tokenConfig?.placement) {\n if ('header' in oauth.tokenConfig.placement) {\n brunoOAuth.tokenPlacement = 'header';\n brunoOAuth.tokenHeaderPrefix = oauth.tokenConfig.placement.header || '';\n } else if ('query' in oauth.tokenConfig.placement) {\n brunoOAuth.tokenPlacement = 'url';\n brunoOAuth.tokenQueryKey = oauth.tokenConfig.placement.query || '';\n }\n }\n\n // additional parameters\n if (oauth.additionalParameters) {\n const tempParams: Record<string, any> = {};\n if (oauth.additionalParameters.accessTokenRequest) {\n const tokenParams = reverseAdditionalParameters(oauth.additionalParameters.accessTokenRequest);\n if (tokenParams) {\n tempParams.token = tokenParams;\n }\n }\n if (oauth.additionalParameters.refreshTokenRequest) {\n const refreshParams = reverseAdditionalParameters(oauth.additionalParameters.refreshTokenRequest);\n if (refreshParams) {\n tempParams.refresh = refreshParams;\n }\n }\n // Only set additionalParameters if there are actual parameters\n if (Object.keys(tempParams).length > 0) {\n brunoOAuth.additionalParameters = tempParams;\n }\n }\n break;\n\n case 'resource_owner_password_credentials':\n brunoOAuth.grantType = 'password';\n if (oauth.accessTokenUrl) brunoOAuth.accessTokenUrl = oauth.accessTokenUrl;\n if (oauth.refreshTokenUrl) brunoOAuth.refreshTokenUrl = oauth.refreshTokenUrl;\n if (oauth.credentials?.clientId) brunoOAuth.clientId = oauth.credentials.clientId;\n if (oauth.credentials?.clientSecret) brunoOAuth.clientSecret = oauth.credentials.clientSecret;\n if (oauth.credentials?.placement) brunoOAuth.credentialsPlacement = oauth.credentials.placement;\n if (oauth.resourceOwner?.username) brunoOAuth.username = oauth.resourceOwner.username;\n if (oauth.resourceOwner?.password) brunoOAuth.password = oauth.resourceOwner.password;\n if (oauth.scope) brunoOAuth.scope = oauth.scope;\n\n // token config\n if (oauth.tokenConfig?.id) brunoOAuth.credentialsId = oauth.tokenConfig.id;\n if (oauth.tokenConfig?.source) brunoOAuth.tokenSource = oauth.tokenConfig.source || 'access_token';\n if (oauth.tokenConfig?.placement) {\n if ('header' in oauth.tokenConfig.placement) {\n brunoOAuth.tokenPlacement = 'header';\n brunoOAuth.tokenHeaderPrefix = oauth.tokenConfig.placement.header || '';\n } else if ('query' in oauth.tokenConfig.placement) {\n brunoOAuth.tokenPlacement = 'url';\n brunoOAuth.tokenQueryKey = oauth.tokenConfig.placement.query || '';\n }\n }\n\n // additional parameters\n if (oauth.additionalParameters) {\n const tempParams: Record<string, any> = {};\n if (oauth.additionalParameters.accessTokenRequest) {\n const tokenParams = reverseAdditionalParameters(oauth.additionalParameters.accessTokenRequest);\n if (tokenParams) {\n tempParams.token = tokenParams;\n }\n }\n if (oauth.additionalParameters.refreshTokenRequest) {\n const refreshParams = reverseAdditionalParameters(oauth.additionalParameters.refreshTokenRequest);\n if (refreshParams) {\n tempParams.refresh = refreshParams;\n }\n }\n // Only set additionalParameters if there are actual parameters\n if (Object.keys(tempParams).length > 0) {\n brunoOAuth.additionalParameters = tempParams;\n }\n }\n break;\n\n case 'authorization_code':\n brunoOAuth.grantType = 'authorization_code';\n if (oauth.authorizationUrl) brunoOAuth.authorizationUrl = oauth.authorizationUrl;\n if (oauth.accessTokenUrl) brunoOAuth.accessTokenUrl = oauth.accessTokenUrl;\n if (oauth.refreshTokenUrl) brunoOAuth.refreshTokenUrl = oauth.refreshTokenUrl;\n if (oauth.callbackUrl) brunoOAuth.callbackUrl = oauth.callbackUrl;\n if (oauth.credentials?.clientId) brunoOAuth.clientId = oauth.credentials.clientId;\n if (oauth.credentials?.clientSecret) brunoOAuth.clientSecret = oauth.credentials.clientSecret;\n if (oauth.credentials?.placement) brunoOAuth.credentialsPlacement = oauth.credentials.placement;\n if (oauth.scope) brunoOAuth.scope = oauth.scope;\n if (oauth.state) brunoOAuth.state = oauth.state;\n\n // token config\n if (oauth.tokenConfig?.id) brunoOAuth.credentialsId = oauth.tokenConfig.id;\n if (oauth.tokenConfig?.source) brunoOAuth.tokenSource = oauth.tokenConfig.source || 'access_token';\n if (oauth.tokenConfig?.placement) {\n if ('header' in oauth.tokenConfig.placement) {\n brunoOAuth.tokenPlacement = 'header';\n brunoOAuth.tokenHeaderPrefix = oauth.tokenConfig.placement.header || '';\n } else if ('query' in oauth.tokenConfig.placement) {\n brunoOAuth.tokenPlacement = 'url';\n brunoOAuth.tokenQueryKey = oauth.tokenConfig.placement.query || '';\n }\n }\n\n // additional parameters\n if (oauth.additionalParameters) {\n const tempParams: Record<string, any> = {};\n if (oauth.additionalParameters.authorizationRequest) {\n const authParams = reverseAdditionalParameters(oauth.additionalParameters.authorizationRequest);\n if (authParams) {\n tempParams.authorization = authParams;\n }\n }\n if (oauth.additionalParameters.accessTokenRequest) {\n const tokenParams = reverseAdditionalParameters(oauth.additionalParameters.accessTokenRequest);\n if (tokenParams) {\n tempParams.token = tokenParams;\n }\n }\n if (oauth.additionalParameters.refreshTokenRequest) {\n const refreshParams = reverseAdditionalParameters(oauth.additionalParameters.refreshTokenRequest);\n if (refreshParams) {\n tempParams.refresh = refreshParams;\n }\n }\n // Only set additionalParameters if there are actual parameters\n if (Object.keys(tempParams).length > 0) {\n brunoOAuth.additionalParameters = tempParams;\n }\n }\n break;\n\n case 'implicit':\n brunoOAuth.grantType = 'implicit';\n if (oauth.authorizationUrl) brunoOAuth.authorizationUrl = oauth.authorizationUrl;\n if (oauth.callbackUrl) brunoOAuth.callbackUrl = oauth.callbackUrl;\n if (oauth.credentials?.clientId) brunoOAuth.clientId = oauth.credentials.clientId;\n if (oauth.scope) brunoOAuth.scope = oauth.scope;\n if (oauth.state) brunoOAuth.state = oauth.state;\n\n // token config\n if (oauth.tokenConfig?.id) brunoOAuth.credentialsId = oauth.tokenConfig.id;\n if (oauth.tokenConfig?.source) brunoOAuth.tokenSource = oauth.tokenConfig.source || 'access_token';\n if (oauth.tokenConfig?.placement) {\n if ('header' in oauth.tokenConfig.placement) {\n brunoOAuth.tokenPlacement = 'header';\n brunoOAuth.tokenHeaderPrefix = oauth.tokenConfig.placement.header || '';\n } else if ('query' in oauth.tokenConfig.placement) {\n brunoOAuth.tokenPlacement = 'url';\n brunoOAuth.tokenQueryKey = oauth.tokenConfig.placement.query || '';\n }\n }\n\n // additional parameters\n if (oauth.additionalParameters) {\n const tempParams: Record<string, any> = {};\n if (oauth.additionalParameters.authorizationRequest) {\n const authParams = reverseAdditionalParameters(oauth.additionalParameters.authorizationRequest);\n if (authParams) {\n tempParams.authorization = authParams;\n }\n }\n // Only set additionalParameters if there are actual parameters\n if (Object.keys(tempParams).length > 0) {\n brunoOAuth.additionalParameters = tempParams;\n }\n }\n break;\n\n default:\n return null;\n }\n\n if (oauth.settings?.autoFetchToken !== undefined) {\n brunoOAuth.autoFetchToken = oauth.settings.autoFetchToken;\n }\n if (oauth.settings?.autoRefreshToken !== undefined) {\n brunoOAuth.autoRefreshToken = oauth.settings.autoRefreshToken;\n }\n\n if (brunoOAuth.grantType === 'authorization_code' && oauth.flow === 'authorization_code') {\n const authCodeFlow = oauth as OAuth2AuthorizationCodeFlow;\n if (authCodeFlow.pkce !== undefined) {\n // If pkce.disabled is true, set pkce to false; otherwise set to true\n brunoOAuth.pkce = !authCodeFlow.pkce.disabled;\n }\n }\n\n if (brunoOAuth.additionalParameters === null) {\n delete brunoOAuth.additionalParameters;\n }\n\n return brunoOAuth;\n};\n","import type {\n Auth,\n AuthApiKey,\n AuthAwsV4,\n AuthBasic,\n AuthBearer,\n AuthDigest,\n AuthNTLM,\n AuthOAuth1,\n AuthWsse\n} from '@opencollection/types/common/auth';\nimport type { Auth as BrunoAuth, AuthOauth1 as BrunoAuthOauth1 } from '@usebruno/schema-types/common/auth';\nimport { isString } from '../../../utils';\nimport { toOpenCollectionOAuth2, toBrunoOAuth2 } from './auth-oauth2';\n\n// EdgeGrid is a Bruno-specific auth mode that is not part of the OpenCollection spec,\n// so its shape is defined locally and serialized using the same field names as Bruno.\ninterface AkamaiEdgeGridAuthValues {\n type: 'akamai-edgegrid';\n accessToken?: string;\n clientToken?: string;\n clientSecret?: string;\n baseURL?: string | null;\n nonce?: string | null;\n timestamp?: string | null;\n headersToSign?: string | null;\n maxBodySize?: number | null;\n}\n\nconst buildAwsV4Auth = (config?: BrunoAuth['awsv4']): AuthAwsV4 => {\n const auth: AuthAwsV4 = { type: 'awsv4' };\n\n if (!config) {\n return auth;\n }\n\n if (isString(config.accessKeyId)) auth.accessKeyId = config.accessKeyId;\n if (isString(config.secretAccessKey)) auth.secretAccessKey = config.secretAccessKey;\n if (isString(config.sessionToken)) auth.sessionToken = config.sessionToken;\n if (isString(config.service)) auth.service = config.service;\n if (isString(config.region)) auth.region = config.region;\n if (isString(config.profileName)) auth.profileName = config.profileName;\n\n return auth;\n};\n\nconst buildBasicAuth = (config?: BrunoAuth['basic']): AuthBasic => {\n const auth: AuthBasic = { type: 'basic' };\n\n if (!config) {\n return auth;\n }\n\n if (isString(config.username)) auth.username = config.username;\n if (isString(config.password)) auth.password = config.password;\n\n return auth;\n};\n\nconst buildBearerAuth = (config?: BrunoAuth['bearer']): AuthBearer => {\n const auth: AuthBearer = { type: 'bearer' };\n\n if (!config) {\n return auth;\n }\n\n if (isString(config.token)) auth.token = config.token;\n\n return auth;\n};\n\nconst buildDigestAuth = (config?: BrunoAuth['digest']): AuthDigest => {\n const auth: AuthDigest = { type: 'digest' };\n\n if (!config) {\n return auth;\n }\n\n if (isString(config.username)) auth.username = config.username;\n if (isString(config.password)) auth.password = config.password;\n\n return auth;\n};\n\nconst buildNtlmAuth = (config?: BrunoAuth['ntlm']): AuthNTLM => {\n const auth: AuthNTLM = { type: 'ntlm' };\n\n if (!config) {\n return auth;\n }\n\n if (isString(config.username)) auth.username = config.username;\n if (isString(config.password)) auth.password = config.password;\n if (isString(config.domain)) auth.domain = config.domain;\n\n return auth;\n};\n\nconst buildWsseAuth = (config?: BrunoAuth['wsse']): AuthWsse => {\n const auth: AuthWsse = { type: 'wsse' };\n\n if (!config) {\n return auth;\n }\n\n if (isString(config.username)) auth.username = config.username;\n if (isString(config.password)) auth.password = config.password;\n\n return auth;\n};\n\nconst buildApiKeyAuth = (config?: BrunoAuth['apikey']): AuthApiKey => {\n const auth: AuthApiKey = { type: 'apikey' };\n\n if (!config) {\n return auth;\n }\n\n if (isString(config.key)) auth.key = config.key;\n if (isString(config.value)) auth.value = config.value;\n\n if (isString(config.placement)) {\n if (config.placement === 'header') {\n auth.placement = 'header';\n } else if (config.placement === 'queryparams') {\n auth.placement = 'query';\n }\n }\n\n return auth;\n};\n\nconst buildEdgeGridAuth = (config?: BrunoAuth['akamaiEdgegrid']): AkamaiEdgeGridAuthValues => {\n const auth: AkamaiEdgeGridAuthValues = { type: 'akamai-edgegrid' };\n\n if (!config) {\n return auth;\n }\n\n if (isString(config.accessToken)) auth.accessToken = config.accessToken;\n if (isString(config.clientToken)) auth.clientToken = config.clientToken;\n if (isString(config.clientSecret)) auth.clientSecret = config.clientSecret;\n if (isString(config.nonce)) auth.nonce = config.nonce;\n if (isString(config.timestamp)) auth.timestamp = config.timestamp;\n if (isString(config.baseURL)) auth.baseURL = config.baseURL;\n if (isString(config.headersToSign)) auth.headersToSign = config.headersToSign;\n if (typeof config.maxBodySize === 'number') auth.maxBodySize = config.maxBodySize;\n\n return auth;\n};\n\nconst buildOAuth1Auth = (config?: BrunoAuth['oauth1']): AuthOAuth1 => {\n const auth: AuthOAuth1 = { type: 'oauth1' };\n\n if (!config) {\n return auth;\n }\n\n if (isString(config.consumerKey)) auth.consumerKey = config.consumerKey;\n if (isString(config.consumerSecret)) auth.consumerSecret = config.consumerSecret;\n if (isString(config.accessToken)) auth.accessToken = config.accessToken;\n if (isString(config.accessTokenSecret)) auth.accessTokenSecret = config.accessTokenSecret;\n if (isString(config.callbackUrl)) auth.callbackUrl = config.callbackUrl;\n if (isString(config.verifier)) auth.verifier = config.verifier;\n if (isString(config.signatureMethod)) auth.signatureMethod = config.signatureMethod;\n if (isString(config.privateKey)) {\n auth.privateKey = config.privateKeyType === 'file'\n ? { type: 'file' as const, value: config.privateKey }\n : { type: 'text' as const, value: config.privateKey };\n }\n if (isString(config.timestamp)) auth.timestamp = config.timestamp;\n if (isString(config.nonce)) auth.nonce = config.nonce;\n if (isString(config.version)) auth.version = config.version;\n if (isString(config.realm)) auth.realm = config.realm;\n if (isString(config.placement)) auth.placement = config.placement as AuthOAuth1['placement'];\n if (typeof config.includeBodyHash === 'boolean') auth.includeBodyHash = config.includeBodyHash;\n\n return auth;\n};\n\nexport const toOpenCollectionAuth = (auth?: BrunoAuth | null): Auth | undefined => {\n if (!auth || auth.mode === 'none') {\n return undefined;\n }\n\n if (auth.mode === 'inherit') {\n return 'inherit';\n }\n\n switch (auth.mode) {\n case 'awsv4':\n return buildAwsV4Auth(auth.awsv4);\n case 'basic':\n return buildBasicAuth(auth.basic);\n case 'bearer':\n return buildBearerAuth(auth.bearer);\n case 'digest':\n return buildDigestAuth(auth.digest);\n case 'ntlm':\n return buildNtlmAuth(auth.ntlm);\n case 'wsse':\n return buildWsseAuth(auth.wsse);\n case 'apikey':\n return buildApiKeyAuth(auth.apikey);\n case 'oauth1':\n return buildOAuth1Auth(auth.oauth1);\n case 'oauth2':\n return toOpenCollectionOAuth2(auth.oauth2);\n case 'akamai-edgegrid':\n return buildEdgeGridAuth(auth.akamaiEdgegrid) as unknown as Auth;\n default:\n console.warn(`toOpenCollectionAuth failed: Unsupported auth mode \"${auth.mode}\".`);\n return undefined;\n }\n};\n\nexport const toBrunoAuth = (auth: Auth | null | undefined): BrunoAuth | null => {\n const brunoAuth: BrunoAuth = {\n mode: 'none',\n awsv4: null,\n basic: null,\n bearer: null,\n digest: null,\n ntlm: null,\n oauth2: null,\n wsse: null,\n apikey: null,\n akamaiEdgegrid: null\n };\n\n if (!auth) {\n return brunoAuth;\n }\n\n if (auth === 'inherit') {\n brunoAuth.mode = 'inherit';\n return brunoAuth;\n }\n\n if ((auth as unknown as AkamaiEdgeGridAuthValues).type === 'akamai-edgegrid') {\n const edgegrid = auth as unknown as AkamaiEdgeGridAuthValues;\n brunoAuth.mode = 'akamai-edgegrid';\n brunoAuth.akamaiEdgegrid = {\n accessToken: edgegrid.accessToken || '',\n clientToken: edgegrid.clientToken || '',\n clientSecret: edgegrid.clientSecret || '',\n nonce: edgegrid.nonce || '',\n timestamp: edgegrid.timestamp || '',\n baseURL: edgegrid.baseURL || '',\n headersToSign: edgegrid.headersToSign || '',\n maxBodySize: typeof edgegrid.maxBodySize === 'number' ? edgegrid.maxBodySize : null\n };\n return brunoAuth;\n }\n\n switch (auth.type) {\n case 'awsv4':\n brunoAuth.mode = 'awsv4';\n brunoAuth.awsv4 = {\n accessKeyId: auth.accessKeyId || null,\n secretAccessKey: auth.secretAccessKey || null,\n sessionToken: auth.sessionToken || null,\n service: auth.service || null,\n region: auth.region || null,\n profileName: auth.profileName || null\n };\n break;\n\n case 'basic':\n brunoAuth.mode = 'basic';\n brunoAuth.basic = {\n username: auth.username || null,\n password: auth.password || null\n };\n break;\n\n case 'bearer':\n brunoAuth.mode = 'bearer';\n brunoAuth.bearer = {\n token: auth.token || ''\n };\n break;\n\n case 'digest':\n brunoAuth.mode = 'digest';\n brunoAuth.digest = {\n username: auth.username || null,\n password: auth.password || null\n };\n break;\n\n case 'ntlm':\n brunoAuth.mode = 'ntlm';\n brunoAuth.ntlm = {\n username: auth.username || null,\n password: auth.password || null,\n domain: auth.domain || null\n };\n break;\n\n case 'wsse':\n brunoAuth.mode = 'wsse';\n brunoAuth.wsse = {\n username: auth.username || null,\n password: auth.password || null\n };\n break;\n\n case 'apikey':\n brunoAuth.mode = 'apikey';\n brunoAuth.apikey = {\n key: auth.key || null,\n value: auth.value || null,\n placement: auth.placement === 'query' ? 'queryparams' : (auth.placement === 'header' ? 'header' : null)\n };\n break;\n\n case 'oauth1':\n brunoAuth.mode = 'oauth1';\n brunoAuth.oauth1 = {\n consumerKey: auth.consumerKey || null,\n consumerSecret: auth.consumerSecret || null,\n accessToken: auth.accessToken || null,\n accessTokenSecret: auth.accessTokenSecret || null,\n callbackUrl: auth.callbackUrl || null,\n verifier: auth.verifier || null,\n signatureMethod: (auth.signatureMethod as BrunoAuthOauth1['signatureMethod']) || 'HMAC-SHA1',\n privateKey: (typeof auth.privateKey === 'object' && auth.privateKey ? auth.privateKey.value : auth.privateKey) || null,\n privateKeyType: (typeof auth.privateKey === 'object' && auth.privateKey ? auth.privateKey.type : 'text') as BrunoAuthOauth1['privateKeyType'],\n timestamp: auth.timestamp || null,\n nonce: auth.nonce || null,\n version: auth.version || '1.0',\n realm: auth.realm || null,\n placement: (auth.placement as BrunoAuthOauth1['placement']) || 'header',\n includeBodyHash: auth.includeBodyHash || false\n };\n break;\n\n case 'oauth2':\n brunoAuth.mode = 'oauth2';\n brunoAuth.oauth2 = toBrunoOAuth2(auth);\n break;\n\n default:\n console.warn('toBrunoAuth failed: Unsupported auth type');\n break;\n }\n\n return brunoAuth;\n};\n","import type { FolderRequest as BrunoFolderRequest } from '@usebruno/schema-types/collection/folder';\nimport type { KeyValue as BrunoKeyValue } from '@usebruno/schema-types/common/key-value';\nimport type { HttpRequestHeader, HttpResponseHeader } from '@opencollection/types/requests/http';\nimport { uuid, ensureString } from '../../../utils';\n\nexport const toOpenCollectionHttpHeaders = (headers: BrunoFolderRequest['headers']): HttpRequestHeader[] | undefined => {\n if (!headers?.length) {\n return undefined;\n }\n\n const ocHeaders = headers.map((header: BrunoKeyValue): HttpRequestHeader => {\n const httpHeader: HttpRequestHeader = {\n name: header.name || '',\n value: header.value || ''\n };\n if (header?.description?.trim().length) {\n httpHeader.description = header.description;\n }\n if (header.enabled === false) {\n httpHeader.disabled = true;\n }\n return httpHeader;\n });\n\n return ocHeaders.length ? ocHeaders : undefined;\n};\n\nexport const toOpenCollectionResponseHeaders = (headers: BrunoFolderRequest['headers']): HttpResponseHeader[] | undefined => {\n if (!headers?.length) {\n return undefined;\n }\n\n const ocHeaders = headers.map((header: BrunoKeyValue): HttpResponseHeader => ({\n name: header.name || '',\n value: header.value || ''\n }));\n\n return ocHeaders.length ? ocHeaders : undefined;\n};\n\nexport const toBrunoHttpHeaders = (headers: HttpRequestHeader[] | HttpResponseHeader[] | null | undefined): BrunoKeyValue[] | undefined => {\n if (!headers?.length) {\n return undefined;\n }\n\n const brunoHeaders = headers.map((header): BrunoKeyValue => {\n const brunoHeader: BrunoKeyValue = {\n uid: uuid(),\n name: ensureString(header.name),\n value: ensureString(header.value),\n enabled: ('disabled' in header) ? header.disabled !== true : true\n };\n\n if ('description' in header && header.description) {\n brunoHeader.description = typeof header.description === 'string' ? header.description : (header.description as any)?.content || '';\n }\n\n return brunoHeader;\n });\n\n return brunoHeaders.length ? brunoHeaders : undefined;\n};\n","import type { HttpRequestParam as BrunoHttpRequestParam } from '@usebruno/schema-types/requests/http';\nimport type { HttpRequestParam } from '@opencollection/types/requests/http';\nimport { uuid, ensureString } from '../../../utils';\n\nexport const toOpenCollectionParams = (params: BrunoHttpRequestParam[] | null | undefined): HttpRequestParam[] | undefined => {\n if (!params?.length) {\n return undefined;\n }\n\n const ocParams = params.map((param: BrunoHttpRequestParam): HttpRequestParam => {\n const ocParam: HttpRequestParam = {\n name: param.name || '',\n value: param.value || '',\n type: param.type\n };\n\n if (param?.description?.trim().length) {\n ocParam.description = param.description;\n }\n\n if (param.enabled === false) {\n ocParam.disabled = true;\n }\n\n return ocParam;\n });\n\n return ocParams.length ? ocParams : undefined;\n};\n\nexport const toBrunoParams = (params: HttpRequestParam[] | null | undefined): BrunoHttpRequestParam[] | undefined => {\n if (!params?.length) {\n return undefined;\n }\n\n const brunoParams = params.map((param: HttpRequestParam): BrunoHttpRequestParam => {\n const brunoParam: BrunoHttpRequestParam = {\n uid: uuid(),\n name: ensureString(param.name),\n value: ensureString(param.value),\n type: param.type,\n enabled: param.disabled !== true\n };\n\n if (param.description) {\n if (typeof param.description === 'string' && param.description.trim().length) {\n brunoParam.description = param.description;\n } else if (typeof param.description === 'object' && param.description.content?.trim().length) {\n brunoParam.description = param.description.content;\n }\n }\n\n return brunoParam;\n });\n\n return brunoParams.length ? brunoParams : undefined;\n};\n","import type { HttpRequestBody as BrunoHttpRequestBody } from '@usebruno/schema-types/requests/http';\nimport type {\n HttpRequestBody,\n RawBody,\n FormUrlEncodedBody,\n FormUrlEncodedEntry,\n MultipartFormBody,\n MultipartFormEntry,\n FileBody,\n FileBodyVariant\n} from '@opencollection/types/requests/http';\nimport type { FileEntry as BrunoFileEntry } from '@usebruno/schema-types/common/file';\n\nimport type { KeyValue as BrunoKeyValue } from '@usebruno/schema-types/common/key-value';\nimport { uuid, ensureString } from '../../../utils';\n\nexport const toOpenCollectionBody = (body: BrunoHttpRequestBody | null | undefined): HttpRequestBody | undefined => {\n if (!body) {\n return undefined;\n }\n\n switch (body.mode) {\n case 'none':\n return undefined;\n\n case 'json':\n const rawBody: RawBody = {\n type: 'json',\n data: body.json || ''\n };\n return rawBody;\n\n case 'text':\n const textBody: RawBody = {\n type: 'text',\n data: body.text || ''\n };\n return textBody;\n\n case 'xml':\n const xmlBody: RawBody = {\n type: 'xml',\n data: body.xml || ''\n };\n return xmlBody;\n\n case 'sparql':\n const sparqlBody: RawBody = {\n type: 'sparql',\n data: body.sparql || ''\n };\n return sparqlBody;\n\n case 'formUrlEncoded':\n const formEntries: FormUrlEncodedEntry[] = body.formUrlEncoded?.map((entry: BrunoKeyValue): FormUrlEncodedEntry => {\n const formEntry: FormUrlEncodedEntry = {\n name: entry.name || '',\n value: entry.value || ''\n };\n\n if (entry?.description?.trim().length) {\n formEntry.description = entry.description;\n }\n\n if (entry.enabled === false) {\n formEntry.disabled = true;\n }\n\n return formEntry;\n }) || [];\n\n const formBody: FormUrlEncodedBody = {\n type: 'form-urlencoded',\n ...(formEntries.length > 0 && { data: formEntries })\n } as FormUrlEncodedBody;\n return formBody;\n\n case 'multipartForm':\n const multipartEntries: MultipartFormEntry[] = body.multipartForm?.map((entry): MultipartFormEntry => {\n const multipartEntry: MultipartFormEntry = {\n name: entry.name || '',\n type: entry.type,\n value: entry.value || (entry.type === 'file' ? [] : '')\n };\n\n if (entry?.contentType?.trim().length) {\n multipartEntry.contentType = entry.contentType;\n }\n\n if (entry?.description?.trim().length) {\n multipartEntry.description = entry.description;\n }\n\n if (entry.enabled === false) {\n multipartEntry.disabled = true;\n }\n\n return multipartEntry;\n }) || [];\n\n const multipartBody: MultipartFormBody = {\n type: 'multipart-form',\n ...(multipartEntries.length > 0 && { data: multipartEntries })\n } as MultipartFormBody;\n return multipartBody;\n\n case 'file':\n const fileEntries: FileBodyVariant[] = body.file?.map((file): FileBodyVariant => {\n const fileEntry: FileBodyVariant = {\n filePath: file.filePath || '',\n contentType: file.contentType || '',\n selected: file.selected ?? false\n };\n\n if (file?.description?.trim().length) {\n fileEntry.description = file.description;\n }\n\n return fileEntry;\n }) || [];\n\n const fileBody: FileBody = {\n type: 'file',\n ...(fileEntries.length > 0 && { data: fileEntries })\n } as FileBody;\n return fileBody;\n\n case 'graphql':\n // GraphQL body is handled separately in GraphQL request stringify\n return undefined;\n\n default:\n return undefined;\n }\n};\n\nexport const toBrunoBody = (body: HttpRequestBody | null | undefined): BrunoHttpRequestBody | undefined => {\n if (!body) {\n return {\n mode: 'none',\n json: null,\n text: null,\n xml: null,\n sparql: null,\n formUrlEncoded: [],\n multipartForm: [],\n graphql: null,\n file: []\n };\n }\n\n const brunoBody: BrunoHttpRequestBody = {\n mode: 'none',\n json: null,\n text: null,\n xml: null,\n sparql: null,\n formUrlEncoded: [],\n multipartForm: [],\n graphql: null,\n file: []\n };\n\n switch (body.type) {\n case 'json':\n brunoBody.mode = 'json';\n brunoBody.json = body.data || '';\n break;\n\n case 'text':\n brunoBody.mode = 'text';\n brunoBody.text = body.data || '';\n break;\n\n case 'xml':\n brunoBody.mode = 'xml';\n brunoBody.xml = body.data || '';\n break;\n\n case 'sparql':\n brunoBody.mode = 'sparql';\n brunoBody.sparql = body.data || '';\n break;\n\n case 'form-urlencoded':\n brunoBody.mode = 'formUrlEncoded';\n brunoBody.formUrlEncoded = body.data?.map((entry): BrunoKeyValue => {\n const formEntry: BrunoKeyValue = {\n uid: uuid(),\n name: ensureString(entry.name),\n value: ensureString(entry.value),\n enabled: entry.disabled !== true\n };\n\n if (entry.description) {\n if (typeof entry.description === 'string' && entry.description.trim().length) {\n formEntry.description = entry.description;\n } else if (typeof entry.description === 'object' && entry.description.content?.trim().length) {\n formEntry.description = entry.description.content;\n }\n }\n\n return formEntry;\n }) || [];\n break;\n\n case 'multipart-form':\n brunoBody.mode = 'multipartForm';\n brunoBody.multipartForm = body.data?.map((entry): any => {\n const multipartEntry: any = {\n uid: uuid(),\n type: entry.type,\n name: ensureString(entry.name),\n value: entry.type === 'file' ? (entry.value || []) : ensureString(entry.value),\n contentType: entry.contentType || null,\n enabled: entry.disabled !== true\n };\n\n if (entry.description) {\n if (typeof entry.description === 'string' && entry.description.trim().length) {\n multipartEntry.description = entry.description;\n } else if (typeof entry.description === 'object' && entry.description.content?.trim().length) {\n multipartEntry.description = entry.description.content;\n }\n }\n\n return multipartEntry;\n }) || [];\n break;\n\n case 'file':\n brunoBody.mode = 'file';\n brunoBody.file = body.data?.map((file): BrunoFileEntry => {\n const fileEntry: BrunoFileEntry = {\n uid: uuid(),\n filePath: file.filePath || '',\n contentType: file.contentType || '',\n selected: file.selected ?? false\n };\n\n const fileWithDescription = file as FileBodyVariant;\n const desc = typeof fileWithDescription.description === 'string'\n ? fileWithDescription.description\n : (fileWithDescription.description as { content?: string } | undefined)?.content;\n if (desc && desc.trim().length) fileEntry.description = desc;\n\n return fileEntry;\n }) || [];\n break;\n\n default:\n break;\n }\n\n return brunoBody;\n};\n","import type { VariableTypedValue } from '@opencollection/types/common/variables';\nimport {\n parseValueByDataType,\n BrunoVariableDataType,\n isBrunoVariableDataType,\n valueToString\n} from '@usebruno/common/utils';\n\nexport { BrunoVariableDataType, isBrunoVariableDataType };\n\nexport const serializeVariableValue = (value: unknown): string => {\n if (value !== null && typeof value === 'object') {\n return JSON.stringify(value, null, 2);\n }\n return valueToString(value);\n};\n\nexport const isTypedValue = (value: unknown): value is VariableTypedValue => {\n return typeof value === 'object'\n && value !== null\n && !Array.isArray(value)\n && 'type' in value\n && 'data' in value;\n};\n\nexport interface TypedVariableFields {\n dataType?: BrunoVariableDataType;\n}\n\nexport const hasTypedMetadata = (v: TypedVariableFields): boolean => {\n return !!v.dataType && v.dataType !== 'string';\n};\n\nexport const toOpenCollectionTypedValue = (\n v: TypedVariableFields,\n dataStr: string\n): VariableTypedValue => {\n return {\n type: (v.dataType || 'string') as VariableTypedValue['type'],\n data: dataStr\n };\n};\n\n// `'string'` is the implicit default — omitted from the result.\nexport const fromOpenCollectionTypedValue = (\n typed: VariableTypedValue\n): { value: any } & TypedVariableFields => {\n const dataStr = typeof typed.data === 'string' ? typed.data : String(typed.data ?? '');\n const dataType: BrunoVariableDataType = isBrunoVariableDataType(typed.type) ? typed.type : 'string';\n const result: { value: any } & TypedVariableFields = {\n value: parseValueByDataType(dataStr, dataType)\n };\n if (dataType !== 'string') {\n result.dataType = dataType;\n }\n return result;\n};\n","import { Variable, VariableTypedValue } from '@opencollection/types/common/variables';\nimport { FolderRequest as BrunoFolderRequest } from '@usebruno/schema-types/collection/folder';\nimport { Variable as BrunoVariable, Variables as BrunoVariables } from '@usebruno/schema-types/common/variables';\nimport { uuid, ensureString } from '../../../utils';\nimport {\n isTypedValue,\n hasTypedMetadata,\n toOpenCollectionTypedValue,\n fromOpenCollectionTypedValue,\n serializeVariableValue\n} from './datatype';\n\n/**\n * Convert Bruno pre-request variables to OpenCollection variables format.\n * Note: Post-response variables are now converted to actions (see actions.ts).\n */\nexport const toOpenCollectionVariables = (variables: BrunoFolderRequest['vars'] | BrunoVariables | null | undefined): Variable[] | undefined => {\n // Handle folder variables (has req/res structure) - only use req vars\n const hasReqRes = variables && 'req' in variables;\n const reqVars = hasReqRes ? variables.req : variables as BrunoVariables;\n\n const reqVarsArray = Array.isArray(reqVars) ? reqVars : [];\n\n if (!reqVarsArray.length) {\n return undefined;\n }\n\n const ocVariables: Variable[] = reqVarsArray.map((v: BrunoVariable): Variable => {\n const valueStr = serializeVariableValue(v.value);\n const variable: Variable = {\n name: v.name || '',\n value: hasTypedMetadata(v) ? toOpenCollectionTypedValue(v, valueStr) : valueStr\n };\n\n if (v?.description?.trim().length) {\n variable.description = v.description;\n }\n\n if (v.enabled === false) {\n variable.disabled = true;\n }\n return variable;\n });\n\n return ocVariables.length > 0 ? ocVariables : undefined;\n};\n\n/**\n * Convert OpenCollection variables to Bruno pre-request variables format.\n * Note: Post-response variables come from actions (see actions.ts).\n */\nexport const toBrunoVariables = (variables: Variable[] | null | undefined): { req: BrunoVariables; res: BrunoVariables } => {\n if (!variables?.length) {\n return { req: [], res: [] };\n }\n\n const reqVars: BrunoVariables = [];\n\n variables.forEach((v: Variable) => {\n const base: BrunoVariable = {\n uid: uuid(),\n name: ensureString(v.name),\n value: '',\n enabled: v.disabled !== true,\n local: false\n };\n\n if (isTypedValue(v.value)) {\n Object.assign(base, fromOpenCollectionTypedValue(v.value));\n } else {\n base.value = ensureString(v.value);\n }\n\n if (v.description) {\n base.description = typeof v.description === 'string' ? v.description : (v.description as any)?.content || '';\n }\n\n reqVars.push(base);\n });\n\n return { req: reqVars, res: [] };\n};\n","import type { Action, ActionSetVariable, ActionVariableScope } from '@opencollection/types/common/actions';\nimport type { Variable as BrunoVariable, Variables as BrunoVariables } from '@usebruno/schema-types/common/variables';\nimport { uuid, ensureString } from '../../../utils';\n\n/**\n * Convert Bruno post-response variables to OpenCollection actions.\n * Post-response variables in Bruno are converted to 'set-variable' actions\n * with phase 'after-response'.\n */\nexport const toOpenCollectionActions = (resVariables: BrunoVariables | null | undefined): Action[] | undefined => {\n if (!resVariables?.length) {\n return undefined;\n }\n\n const actions: Action[] = resVariables.map((v: BrunoVariable): ActionSetVariable => {\n const action: ActionSetVariable = {\n type: 'set-variable',\n phase: 'after-response',\n selector: {\n expression: ensureString(v.value),\n method: 'jsonq'\n },\n variable: {\n name: v.name || '',\n scope: v.local ? 'request' : 'runtime' as ActionVariableScope\n }\n };\n\n if (v.description?.trim().length) {\n action.description = v.description;\n }\n\n if (v.enabled === false) {\n action.disabled = true;\n }\n\n return action;\n });\n\n return actions.length > 0 ? actions : undefined;\n};\n\n/**\n * Convert OpenCollection actions to Bruno post-response variables.\n * Only 'set-variable' actions with phase 'after-response' are converted.\n */\nexport const toBrunoPostResponseVariables = (actions: Action[] | null | undefined): BrunoVariables => {\n if (!actions?.length) {\n return [];\n }\n\n const resVars: BrunoVariables = [];\n\n actions.forEach((action: Action) => {\n // Only process 'set-variable' actions with 'after-response' phase\n if (action.type === 'set-variable' && action.phase === 'after-response') {\n const setVarAction = action as ActionSetVariable;\n\n const variable: BrunoVariable = {\n uid: uuid(),\n name: ensureString(setVarAction.variable?.name),\n value: ensureString(setVarAction.selector?.expression),\n enabled: setVarAction.disabled !== true,\n local: false\n };\n\n if (setVarAction.description) {\n variable.description = typeof setVarAction.description === 'string'\n ? setVarAction.description\n : (setVarAction.description as any)?.content || '';\n }\n\n resVars.push(variable);\n }\n });\n\n return resVars;\n};\n","import type { Scripts, Script } from '@opencollection/types/common/scripts';\nimport type { FolderRequest as BrunoFolderRequest } from '@usebruno/schema-types/collection/folder';\nimport type { HttpRequest as BrunoHttpRequest } from '@usebruno/schema-types/requests/http';\nimport type { WebSocketRequest as BrunoWebSocketRequest } from '@usebruno/schema-types/requests/websocket';\nimport type { GrpcRequest as BrunoGrpcRequest } from '@usebruno/schema-types/requests/grpc';\n\nexport const toOpenCollectionScripts = (request: BrunoFolderRequest | BrunoHttpRequest | BrunoWebSocketRequest | BrunoGrpcRequest | null | undefined): Scripts | undefined => {\n const ocScripts: Scripts = [];\n\n if (request?.script?.req?.trim().length) {\n ocScripts.push({\n type: 'before-request',\n code: request.script.req.trim()\n });\n }\n if (request?.script?.res?.trim().length) {\n ocScripts.push({\n type: 'after-response',\n code: request.script.res.trim()\n });\n }\n if (request?.tests?.trim().length) {\n ocScripts.push({\n type: 'tests',\n code: request.tests.trim()\n });\n }\n\n return ocScripts.length > 0 ? ocScripts : undefined;\n};\n\nexport const toBrunoScripts = (scripts: Scripts | null | undefined): {\n script?: { req?: string; res?: string };\n tests?: string;\n} | undefined => {\n if (!scripts || !Array.isArray(scripts) || scripts.length === 0) {\n return undefined;\n }\n\n const brunoScripts: {\n script?: { req?: string; res?: string };\n tests?: string;\n } = {};\n\n for (const script of scripts) {\n if (script.type === 'before-request' && script.code) {\n if (!brunoScripts.script) {\n brunoScripts.script = {};\n }\n brunoScripts.script.req = script.code;\n }\n if (script.type === 'after-response' && script.code) {\n if (!brunoScripts.script) {\n brunoScripts.script = {};\n }\n brunoScripts.script.res = script.code;\n }\n if (script.type === 'tests' && script.code) {\n brunoScripts.tests = script.code;\n }\n }\n\n return Object.keys(brunoScripts).length > 0 ? brunoScripts : undefined;\n};\n","import type { KeyValue as BrunoKeyValue } from '@usebruno/schema-types/common/key-value';\nimport type { Assertion } from '@opencollection/types/common/assertions';\nimport { uuid, ensureString } from '../../../utils';\n\nconst OPERATORS = [\n 'eq',\n 'neq',\n 'gt',\n 'gte',\n 'lt',\n 'lte',\n 'in',\n 'notIn',\n 'contains',\n 'notContains',\n 'length',\n 'matches',\n 'notMatches',\n 'startsWith',\n 'endsWith',\n 'between',\n 'isEmpty',\n 'isNotEmpty',\n 'isNull',\n 'isUndefined',\n 'isDefined',\n 'isTruthy',\n 'isFalsy',\n 'isJson',\n 'isNumber',\n 'isString',\n 'isBoolean',\n 'isArray'\n] as const;\n\nconst UNARY_OPERATORS = [\n 'isEmpty',\n 'isNotEmpty',\n 'isNull',\n 'isUndefined',\n 'isDefined',\n 'isTruthy',\n 'isFalsy',\n 'isJson',\n 'isNumber',\n 'isString',\n 'isBoolean',\n 'isArray'\n] as const;\n\ntype Operator = typeof OPERATORS[number];\n\nconst parseAssertionOperator = (str: string = ''): { operator: Operator; value: string | undefined } => {\n if (!str || typeof str !== 'string' || !str.length) {\n return {\n operator: 'eq',\n value: str\n };\n }\n\n const [firstWord, ...rest] = str.trim().split(' ');\n const remainingValue = rest.join(' ');\n\n // Check if first word is a unary operator\n if (UNARY_OPERATORS.includes(firstWord as any)) {\n return {\n operator: firstWord as Operator,\n value: undefined\n };\n }\n\n // Check if first word is any recognized operator\n if (OPERATORS.includes(firstWord as any)) {\n return {\n operator: firstWord as Operator,\n value: remainingValue\n };\n }\n\n // If not a recognized operator, treat the whole string as value with 'eq' operator\n return {\n operator: 'eq',\n value: str\n };\n};\n\nexport const toOpenCollectionAssertions = (assertions: BrunoKeyValue[] | null | undefined): Assertion[] | undefined => {\n if (!assertions?.length) {\n return undefined;\n }\n\n const ocAssertions: Assertion[] = assertions.map((assertion: BrunoKeyValue): Assertion => {\n const { operator, value } = parseAssertionOperator(assertion.value || '');\n\n const ocAssertion: Assertion = {\n expression: assertion.name || '',\n operator,\n ...(value !== undefined && { value })\n };\n\n if (assertion?.description?.trim().length) {\n ocAssertion.description = assertion.description;\n }\n\n if (assertion.enabled === false) {\n ocAssertion.disabled = true;\n }\n\n return ocAssertion;\n });\n\n return ocAssertions.length > 0 ? ocAssertions : undefined;\n};\n\nexport const toBrunoAssertions = (assertions: Assertion[] | null | undefined): BrunoKeyValue[] | undefined => {\n if (!assertions?.length) {\n return undefined;\n }\n\n const brunoAssertions: BrunoKeyValue[] = assertions.map((assertion: Assertion): BrunoKeyValue => {\n // Reconstruct the \"operator value\" format that Bruno uses\n let valueString = ensureString(assertion.operator);\n if (assertion.value !== undefined && assertion.value !== null) {\n valueString = `${assertion.operator} ${ensureString(assertion.value)}`;\n }\n\n const brunoAssertion: BrunoKeyValue = {\n uid: uuid(),\n name: ensureString(assertion.expression),\n value: valueString,\n enabled: assertion.disabled !== true\n };\n\n if (assertion.description) {\n if (typeof assertion.description === 'string' && assertion.description.trim().length) {\n brunoAssertion.description = assertion.description;\n } else if (typeof assertion.description === 'object' && assertion.description.content?.trim().length) {\n brunoAssertion.description = assertion.description.content;\n }\n }\n\n return brunoAssertion;\n });\n\n return brunoAssertions.length > 0 ? brunoAssertions : undefined;\n};\n","import type { Item as BrunoItem } from '@usebruno/schema-types/collection/item';\nimport type { GrpcRequest as BrunoGrpcRequest } from '@usebruno/schema-types/requests/grpc';\nimport type { GrpcRequest, GrpcMetadata, GrpcMessageVariant } from '@opencollection/types/requests/grpc';\nimport type { KeyValue as BrunoKeyValue } from '@usebruno/schema-types/common/key-value';\nimport { toBrunoAuth } from '../common/auth';\nimport { toBrunoVariables } from '../common/variables';\nimport { toBrunoScripts } from '../common/scripts';\nimport { toBrunoAssertions } from '../common/assertions';\nimport { isNonEmptyString, uuid, ensureString } from '../../../utils';\n\nconst toBrunoGrpcMetadata = (metadata: GrpcMetadata[] | null | undefined): BrunoKeyValue[] | undefined => {\n if (!metadata?.length) {\n return undefined;\n }\n\n const brunoMetadata = metadata.map((meta: GrpcMetadata): BrunoKeyValue => {\n const brunoMeta: BrunoKeyValue = {\n uid: uuid(),\n name: ensureString(meta.name),\n value: ensureString(meta.value),\n enabled: meta.disabled !== true\n };\n\n if (meta.description) {\n const desc = typeof meta.description === 'string' ? meta.description : (meta.description as any)?.content || '';\n if (desc.trim().length) {\n brunoMeta.description = desc;\n }\n }\n\n return brunoMeta;\n });\n\n return brunoMetadata.length ? brunoMetadata : undefined;\n};\n\nconst parseGrpcRequest = (ocRequest: GrpcRequest): BrunoItem => {\n const info = ocRequest.info;\n const grpc = ocRequest.grpc;\n const runtime = ocRequest.runtime;\n\n const brunoRequest: BrunoGrpcRequest = {\n url: ensureString(grpc?.url),\n method: ensureString(grpc?.method),\n methodType: grpc?.methodType || '',\n protoPath: grpc?.protoFilePath || null,\n headers: toBrunoGrpcMetadata(grpc?.metadata) || [],\n auth: toBrunoAuth(grpc?.auth),\n body: {\n mode: 'grpc',\n grpc: []\n },\n script: {\n req: null,\n res: null\n },\n vars: {\n req: [],\n res: []\n },\n assertions: [],\n tests: null,\n docs: null\n };\n\n // message\n const rawMessage = grpc?.message;\n if (Array.isArray(rawMessage)) {\n brunoRequest.body.grpc = (rawMessage as GrpcMessageVariant[]).map(({ title, message }, index) => ({\n name: title || `message ${index + 1}`,\n content: ensureString(message)\n }));\n } else if (isNonEmptyString(rawMessage)) {\n brunoRequest.body.grpc = [{\n name: '',\n content: rawMessage as string\n }];\n }\n\n // scripts\n const scripts = toBrunoScripts(runtime?.scripts);\n if (scripts?.script && brunoRequest.script) {\n if (scripts.script.req) {\n brunoRequest.script.req = scripts.script.req;\n }\n if (scripts.script.res) {\n brunoRequest.script.res = scripts.script.res;\n }\n }\n if (scripts?.tests) {\n brunoRequest.tests = scripts.tests;\n }\n\n // variables\n const variables = toBrunoVariables(runtime?.variables);\n brunoRequest.vars = variables;\n\n // assertions\n const assertions = toBrunoAssertions(runtime?.assertions);\n if (assertions) {\n brunoRequest.assertions = assertions;\n }\n\n // docs\n if (ocRequest.docs) {\n brunoRequest.docs = ocRequest.docs;\n }\n\n // bruno item\n const brunoItem: BrunoItem = {\n uid: uuid(),\n type: 'grpc-request',\n seq: info?.seq || 1,\n name: ensureString(info?.name, 'Untitled Request'),\n tags: info?.tags || [],\n request: brunoRequest,\n settings: {},\n fileContent: null,\n root: null,\n items: [],\n examples: [],\n filename: null,\n pathname: null\n };\n\n // description\n if (info?.description) {\n const desc = typeof info.description === 'string' ? info.description : (info.description as any)?.content || '';\n if (desc.trim().length) {\n brunoItem.description = desc;\n }\n }\n\n return brunoItem;\n};\n\nexport default parseGrpcRequest;\n","import type { Item as BrunoItem } from '@usebruno/schema-types/collection/item';\nimport type { Item, ScriptFile } from '@opencollection/types/collection/item';\nimport type { HttpRequest } from '@opencollection/types/requests/http';\nimport type { GraphQLRequest } from '@opencollection/types/requests/graphql';\nimport type { GrpcRequest } from '@opencollection/types/requests/grpc';\nimport type { WebSocketRequest } from '@opencollection/types/requests/websocket';\nimport { parseYml } from './utils';\nimport parseHttpRequest from './items/parseHttpRequest';\nimport parseGraphQLRequest from './items/parseGraphQLRequest';\nimport parseGrpcRequest from './items/parseGrpcRequest';\nimport parseWebsocketRequest from './items/parseWebsocketRequest';\nimport parseScript from './items/parseScript';\nimport parseApp, { type AppFile } from './items/parseApp';\n\n// Helper to get the type from an item (now in info block)\nconst getItemType = (item: Item): string | undefined => {\n if ('info' in item && item.info && 'type' in item.info) {\n return item.info.type;\n }\n // For ScriptFile which still has type at root\n if ('type' in item) {\n return (item as ScriptFile).type;\n }\n return undefined;\n};\n\n/**\n * In v3.0.0-rc1 release auth was present under runtime property for all requests\n * This has now been moved to the respective request properties\n * This backward compatibility has been put in place for folks who tried out our early preview\n * Should be safe to remove this in 3 months. Delete after 5 Apr 2026\n */\nconst ensureAuthV3Rc1BackwardsCompatibility = (parsedItemYml: any): any => {\n const itemType = parsedItemYml?.info?.type;\n\n switch (itemType) {\n case 'http':\n if (parsedItemYml.runtime?.auth && !parsedItemYml.http?.auth) {\n parsedItemYml.http.auth = parsedItemYml.runtime.auth;\n }\n break;\n case 'graphql':\n if (parsedItemYml.runtime?.auth && !parsedItemYml.graphql?.auth) {\n parsedItemYml.graphql.auth = parsedItemYml.runtime.auth;\n }\n break;\n case 'grpc':\n if (parsedItemYml.runtime?.auth && !parsedItemYml.grpc?.auth) {\n parsedItemYml.grpc.auth = parsedItemYml.runtime.auth;\n }\n break;\n case 'websocket':\n if (parsedItemYml.runtime?.auth && !parsedItemYml.websocket?.auth) {\n parsedItemYml.websocket.auth = parsedItemYml.runtime.auth;\n }\n break;\n default:\n break;\n }\n\n return parsedItemYml;\n};\n\nconst parseItem = (ymlString: string): BrunoItem => {\n try {\n const parsedYml = parseYml(ymlString);\n\n const ocItem: Item = ensureAuthV3Rc1BackwardsCompatibility(parsedYml);\n const itemType = getItemType(ocItem);\n\n if (!ocItem || !itemType) {\n throw new Error('Invalid item: missing type');\n }\n\n switch (itemType) {\n case 'http':\n return parseHttpRequest(ocItem as HttpRequest);\n\n case 'graphql':\n return parseGraphQLRequest(ocItem as GraphQLRequest);\n\n case 'grpc':\n return parseGrpcRequest(ocItem as GrpcRequest);\n\n case 'websocket':\n return parseWebsocketRequest(ocItem as WebSocketRequest);\n\n case 'script':\n return parseScript(ocItem as ScriptFile);\n\n case 'app':\n return parseApp(ocItem as unknown as AppFile);\n\n case 'folder':\n throw new Error('Folder items should be handled separately using parseFolder');\n\n default:\n throw new Error(`Unsupported item type: ${itemType}`);\n }\n } catch (error) {\n console.error('Error parsing item:', error);\n throw error;\n }\n};\n\nexport default parseItem;\n","import type { Item as BrunoItem, HttpItemSettings as BrunoHttpItemSettings } from '@usebruno/schema-types/collection/item';\nimport type { HttpRequest as BrunoHttpRequest } from '@usebruno/schema-types/requests/http';\nimport type { HttpRequest, HttpRequestBody } from '@opencollection/types/requests/http';\nimport { toBrunoAuth } from '../common/auth';\nimport { toBrunoHttpHeaders } from '../common/headers';\nimport { toBrunoParams } from '../common/params';\nimport { toBrunoBody } from '../common/body';\nimport { toBrunoVariables } from '../common/variables';\nimport { toBrunoPostResponseVariables } from '../common/actions';\nimport { toBrunoScripts } from '../common/scripts';\nimport { toBrunoAssertions } from '../common/assertions';\nimport { toBrunoApp } from '../common/app';\nimport { uuid, ensureString } from '../../../utils';\n\nconst parseHttpRequest = (ocRequest: HttpRequest): BrunoItem => {\n const info = ocRequest.info;\n const http = ocRequest.http;\n const runtime = ocRequest.runtime;\n\n const brunoRequest: BrunoHttpRequest = {\n url: ensureString(http?.url),\n method: ensureString(http?.method, 'GET'),\n headers: toBrunoHttpHeaders(http?.headers) || [],\n params: toBrunoParams(http?.params) || [],\n auth: toBrunoAuth(http?.auth),\n body: toBrunoBody(http?.body as HttpRequestBody) || {\n mode: 'none',\n json: null,\n text: null,\n xml: null,\n sparql: null,\n formUrlEncoded: [],\n multipartForm: [],\n graphql: null,\n file: []\n },\n script: {\n req: null,\n res: null\n },\n vars: {\n req: [],\n res: []\n },\n assertions: [],\n tests: null,\n docs: null\n };\n\n // scripts\n const scripts = toBrunoScripts(runtime?.scripts);\n if (scripts?.script && brunoRequest.script) {\n if (scripts.script.req) {\n brunoRequest.script.req = scripts.script.req;\n }\n if (scripts.script.res) {\n brunoRequest.script.res = scripts.script.res;\n }\n }\n if (scripts?.tests) {\n brunoRequest.tests = scripts.tests;\n }\n\n // variables (pre-request from variables, post-response from actions)\n const variables = toBrunoVariables(runtime?.variables);\n const postResponseVars = toBrunoPostResponseVariables(runtime?.actions);\n brunoRequest.vars = {\n req: variables.req,\n res: postResponseVars\n };\n\n // assertions\n const assertions = toBrunoAssertions(runtime?.assertions);\n if (assertions) {\n brunoRequest.assertions = assertions;\n }\n\n // docs\n if (ocRequest.docs) {\n brunoRequest.docs = ocRequest.docs;\n }\n\n // app\n const app = toBrunoApp((ocRequest as any).app);\n\n // bruno item\n const brunoItem: BrunoItem = {\n uid: uuid(),\n type: 'http-request',\n seq: info?.seq || 1,\n name: ensureString(info?.name, 'Untitled Request'),\n tags: info?.tags || [],\n request: brunoRequest,\n settings: null,\n app,\n fileContent: null,\n root: null,\n items: [],\n examples: [],\n filename: null,\n pathname: null\n };\n\n // description\n if (info?.description) {\n const desc = typeof info.description === 'string' ? info.description : (info.description as any)?.content || '';\n if (desc.trim().length) {\n brunoItem.description = desc;\n }\n }\n\n // settings\n if (ocRequest.settings) {\n const settings: BrunoHttpItemSettings = {};\n\n if (typeof ocRequest.settings.encodeUrl === 'boolean') {\n settings.encodeUrl = ocRequest.settings.encodeUrl;\n } else {\n settings.encodeUrl = true;\n }\n\n if (typeof ocRequest.settings.timeout === 'number') {\n settings.timeout = ocRequest.settings.timeout;\n } else if (ocRequest.settings.timeout === 'inherit') {\n settings.timeout = 'inherit';\n } else {\n settings.timeout = 0;\n }\n\n if (typeof ocRequest.settings.followRedirects === 'boolean') {\n settings.followRedirects = ocRequest.settings.followRedirects;\n } else {\n settings.followRedirects = true;\n }\n\n if (typeof ocRequest.settings.maxRedirects === 'number') {\n settings.maxRedirects = ocRequest.settings.maxRedirects;\n } else {\n settings.maxRedirects = 5;\n }\n\n brunoItem.settings = settings;\n }\n\n // examples\n if (ocRequest.examples?.length) {\n brunoItem.examples = ocRequest.examples.map((example) => {\n const brunoExample: any = {\n uid: uuid(),\n itemUid: uuid(),\n name: ensureString(example.name, 'Untitled Example'),\n type: 'http-request',\n request: null,\n response: null\n };\n\n if (example.description) {\n if (typeof example.description === 'string' && example.description.trim().length) {\n brunoExample.description = example.description;\n } else if (typeof example.description === 'object' && example.description.content?.trim().length) {\n brunoExample.description = example.description.content;\n }\n }\n\n if (example.request) {\n brunoExample.request = {\n url: ensureString(example.request.url),\n method: ensureString(example.request.method, 'GET'),\n headers: toBrunoHttpHeaders(example.request.headers) || [],\n params: toBrunoParams(example.request.params) || [],\n body: toBrunoBody(example.request.body) || {\n mode: 'none',\n json: null,\n text: null,\n xml: null,\n sparql: null,\n formUrlEncoded: null,\n multipartForm: null,\n graphql: null,\n file: null\n }\n };\n }\n\n if (example.response) {\n brunoExample.response = {\n status: typeof example.response.status === 'number' ? example.response.status\n : example.response.status !== undefined ? Number(example.response.status) : null,\n statusText: example.response.statusText || null,\n headers: toBrunoHttpHeaders(example.response.headers) || [],\n body: null\n };\n\n if (example.response.body) {\n brunoExample.response.body = {\n type: example.response.body.type || 'text',\n content: example.response.body.data || ''\n };\n }\n }\n\n return brunoExample;\n });\n }\n\n return brunoItem;\n};\n\nexport default parseHttpRequest;\n","import type { App as BrunoApp } from '@usebruno/schema-types/collection/item';\n\nexport interface OpenCollectionApp {\n enabled?: boolean;\n code?: string;\n}\n\nexport const toOpenCollectionApp = (app: BrunoApp | null | undefined): OpenCollectionApp | undefined => {\n // The app block persists when enabled even before any code is written.\n if (!app || (!app.code && app.enabled !== true)) return undefined;\n const ocApp: OpenCollectionApp = {};\n if (app.enabled === true) {\n ocApp.enabled = true;\n }\n if (app.code) {\n ocApp.code = app.code;\n }\n return ocApp;\n};\n\nexport const toBrunoApp = (app: OpenCollectionApp | null | undefined): BrunoApp | null => {\n if (!app) return null;\n return {\n enabled: app.enabled === true,\n code: app.code || null\n };\n};\n","import type { Item as BrunoItem, HttpItemSettings as BrunoHttpItemSettings } from '@usebruno/schema-types/collection/item';\nimport type { HttpRequest as BrunoHttpRequest } from '@usebruno/schema-types/requests/http';\nimport type { GraphQLRequest, GraphQLRequestSettings, GraphQLBody } from '@opencollection/types/requests/graphql';\nimport { toBrunoAuth } from '../common/auth';\nimport { toBrunoHttpHeaders } from '../common/headers';\nimport { toBrunoParams } from '../common/params';\nimport { toBrunoVariables } from '../common/variables';\nimport { toBrunoPostResponseVariables } from '../common/actions';\nimport { toBrunoScripts } from '../common/scripts';\nimport { toBrunoAssertions } from '../common/assertions';\nimport { uuid, ensureString } from '../../../utils';\n\nconst parseGraphQLRequest = (ocRequest: GraphQLRequest): BrunoItem => {\n const info = ocRequest.info;\n const graphql = ocRequest.graphql;\n const runtime = ocRequest.runtime;\n\n const brunoRequest: BrunoHttpRequest = {\n url: ensureString(graphql?.url),\n method: ensureString(graphql?.method, 'POST'),\n headers: toBrunoHttpHeaders(graphql?.headers) || [],\n params: toBrunoParams(graphql?.params) || [],\n auth: toBrunoAuth(graphql?.auth),\n body: {\n mode: 'graphql',\n json: null,\n text: null,\n xml: null,\n sparql: null,\n formUrlEncoded: [],\n multipartForm: [],\n graphql: {\n query: (graphql?.body as GraphQLBody)?.query || '',\n variables: (graphql?.body as GraphQLBody)?.variables || ''\n },\n file: []\n },\n script: {\n req: null,\n res: null\n },\n vars: {\n req: [],\n res: []\n },\n assertions: [],\n tests: null,\n docs: null\n };\n\n // scripts\n const scripts = toBrunoScripts(runtime?.scripts);\n if (scripts?.script && brunoRequest.script) {\n if (scripts.script.req) {\n brunoRequest.script.req = scripts.script.req;\n }\n if (scripts.script.res) {\n brunoRequest.script.res = scripts.script.res;\n }\n }\n if (scripts?.tests) {\n brunoRequest.tests = scripts.tests;\n }\n\n // variables (pre-request from variables, post-response from actions)\n const variables = toBrunoVariables(runtime?.variables);\n const postResponseVars = toBrunoPostResponseVariables(runtime?.actions);\n brunoRequest.vars = {\n req: variables.req,\n res: postResponseVars\n };\n\n // assertions\n const assertions = toBrunoAssertions(runtime?.assertions);\n if (assertions) {\n brunoRequest.assertions = assertions;\n }\n\n // docs\n if (ocRequest.docs) {\n brunoRequest.docs = ocRequest.docs;\n }\n\n // bruno item\n const brunoItem: BrunoItem = {\n uid: uuid(),\n type: 'graphql-request',\n seq: info?.seq || 1,\n name: ensureString(info?.name, 'Untitled Request'),\n tags: info?.tags || [],\n request: brunoRequest,\n settings: null,\n fileContent: null,\n root: null,\n items: [],\n examples: [],\n filename: null,\n pathname: null\n };\n\n // description\n if (info?.description) {\n const desc = typeof info.description === 'string' ? info.description : (info.description as any)?.content || '';\n if (desc.trim().length) {\n brunoItem.description = desc;\n }\n }\n\n // settings\n if (ocRequest.settings) {\n const settings: BrunoHttpItemSettings = {};\n\n if (typeof ocRequest.settings.encodeUrl === 'boolean') {\n settings.encodeUrl = ocRequest.settings.encodeUrl;\n } else {\n settings.encodeUrl = true;\n }\n\n if (typeof ocRequest.settings.timeout === 'number') {\n settings.timeout = ocRequest.settings.timeout;\n } else if (ocRequest.settings.timeout === 'inherit') {\n settings.timeout = 'inherit';\n } else {\n settings.timeout = 0;\n }\n\n if (typeof ocRequest.settings.followRedirects === 'boolean') {\n settings.followRedirects = ocRequest.settings.followRedirects;\n } else {\n settings.followRedirects = true;\n }\n\n if (typeof ocRequest.settings.maxRedirects === 'number') {\n settings.maxRedirects = ocRequest.settings.maxRedirects;\n } else {\n settings.maxRedirects = 5;\n }\n\n brunoItem.settings = settings;\n }\n\n return brunoItem;\n};\n\nexport default parseGraphQLRequest;\n","import type { Item as BrunoItem } from '@usebruno/schema-types/collection/item';\nimport type { WebSocketRequest as BrunoWebSocketRequest } from '@usebruno/schema-types/requests/websocket';\nimport type { WebSocketRequest, WebSocketMessage, WebSocketMessageVariant } from '@opencollection/types/requests/websocket';\nimport { toBrunoAuth } from '../common/auth';\nimport { toBrunoHttpHeaders } from '../common/headers';\nimport { toBrunoVariables } from '../common/variables';\nimport { toBrunoScripts } from '../common/scripts';\nimport { uuid, ensureString } from '../../../utils';\n\nconst parseWebsocketRequest = (ocRequest: WebSocketRequest): BrunoItem => {\n const info = ocRequest.info;\n const websocket = ocRequest.websocket;\n const runtime = ocRequest.runtime;\n\n const brunoRequest: BrunoWebSocketRequest = {\n url: ensureString(websocket?.url),\n headers: toBrunoHttpHeaders(websocket?.headers) || [],\n auth: toBrunoAuth(websocket?.auth),\n body: {\n mode: 'ws',\n ws: []\n },\n script: {\n req: null,\n res: null\n },\n vars: {\n req: [],\n res: []\n },\n assertions: [],\n tests: null,\n docs: null\n };\n\n // message\n if (websocket?.message) {\n if (Array.isArray(websocket.message)) {\n // multiple messages: WebSocketMessageVariant[]\n const variants = websocket.message as WebSocketMessageVariant[];\n brunoRequest.body.ws = variants.map((variant, index) => ({\n name: variant.title || `message ${index + 1}`,\n type: variant.message?.type || 'text',\n content: ensureString(variant.message?.data),\n selected: variant.selected || false\n }));\n } else {\n // single message uses flat WebSocketMessage\n const message = websocket.message as WebSocketMessage;\n const messageData = ensureString(message.data);\n if (messageData.trim().length) {\n brunoRequest.body.ws = [{\n name: '',\n type: message.type || 'text',\n content: messageData\n }];\n }\n }\n }\n\n // scripts\n const scripts = toBrunoScripts(runtime?.scripts);\n if (scripts?.script && brunoRequest.script) {\n if (scripts.script.req) {\n brunoRequest.script.req = scripts.script.req;\n }\n if (scripts.script.res) {\n brunoRequest.script.res = scripts.script.res;\n }\n }\n if (scripts?.tests) {\n brunoRequest.tests = scripts.tests;\n }\n\n // variables\n const variables = toBrunoVariables(runtime?.variables);\n brunoRequest.vars = variables;\n\n // docs\n if (ocRequest.docs) {\n brunoRequest.docs = ocRequest.docs;\n }\n\n // settings\n const wsSettings: Record<string, number> = {\n timeout: 0,\n keepAliveInterval: 0\n };\n\n if (ocRequest.settings) {\n if (typeof ocRequest.settings.timeout === 'number') {\n wsSettings.timeout = ocRequest.settings.timeout;\n }\n if (typeof ocRequest.settings.keepAliveInterval === 'number') {\n wsSettings.keepAliveInterval = ocRequest.settings.keepAliveInterval;\n }\n }\n\n // bruno item\n const brunoItem: BrunoItem = {\n uid: uuid(),\n type: 'ws-request',\n seq: info?.seq || 1,\n name: ensureString(info?.name, 'Untitled Request'),\n tags: info?.tags || [],\n request: brunoRequest,\n settings: wsSettings as any,\n fileContent: null,\n root: null,\n items: [],\n examples: [],\n filename: null,\n pathname: null\n };\n\n // description\n if (info?.description) {\n const desc = typeof info.description === 'string' ? info.description : (info.description as any)?.content || '';\n if (desc.trim().length) {\n brunoItem.description = desc;\n }\n }\n\n return brunoItem;\n};\n\nexport default parseWebsocketRequest;\n","import type { Item as BrunoItem } from '@usebruno/schema-types/collection/item';\nimport type { ScriptFile } from '@opencollection/types/collection/item';\nimport { uuid } from '../../../utils';\n\nconst parseScript = (ocScript: ScriptFile): BrunoItem => {\n const brunoItem: BrunoItem = {\n uid: uuid(),\n type: 'js',\n seq: 1,\n name: 'Script',\n tags: [],\n request: null,\n settings: null,\n fileContent: ocScript.script || '',\n root: null,\n items: [],\n examples: [],\n filename: null,\n pathname: null\n };\n\n return brunoItem;\n};\n\nexport default parseScript;\n","import type { Item as BrunoItem } from '@usebruno/schema-types/collection/item';\nimport { uuid } from '../../../utils';\n\nexport interface AppFile {\n info: {\n name?: string;\n type: 'app';\n seq?: number;\n tags?: string[];\n };\n code?: string;\n}\n\nconst parseApp = (ocApp: AppFile): BrunoItem => {\n const info = ocApp.info || ({} as AppFile['info']);\n\n const brunoItem: BrunoItem = {\n uid: uuid(),\n type: 'app',\n seq: typeof info.seq === 'number' ? info.seq : 1,\n name: info.name || 'App',\n tags: Array.isArray(info.tags) ? info.tags : [],\n request: null,\n settings: null,\n app: { code: ocApp.code || '' },\n fileContent: null,\n root: null,\n items: [],\n examples: [],\n filename: null,\n pathname: null\n };\n\n return brunoItem;\n};\n\nexport default parseApp;\n","import type { CollectionFormat } from './types';\nimport type { ExternalSecretProviderType } from '@usebruno/schema-types/collection/environment';\n\nexport const DEFAULT_COLLECTION_FORMAT: CollectionFormat = 'yml';\n\n// Each provider type stores its secret reference under a different key.\nexport const SECRET_PROVIDER_IDENTIFIER_FIELDS: Record<ExternalSecretProviderType, 'path' | 'secretName' | 'vaultName'> = {\n 'aws-secrets-manager': 'secretName',\n 'azure-key-vault': 'vaultName',\n 'hashicorp-vault-cloud': 'path',\n 'hashicorp-vault-server': 'path'\n};\n","import type {\n Environment as BrunoEnvironment,\n EnvironmentVariable as BrunoEnvironmentVariable,\n SecretEnvironmentVariable as BrunoSecretEnvironmentVariable,\n ExternalSecretProviderType as BrunoExternalSecretProviderType\n} from '@usebruno/schema-types/collection/environment';\nimport type { Environment } from '@opencollection/types/config/environments';\nimport type { Variable, SecretVariable } from '@opencollection/types/common/variables';\nimport { parseYml } from './utils';\nimport { uuid, ensureString } from '../../utils';\nimport { SECRET_PROVIDER_IDENTIFIER_FIELDS } from '../../constants';\nimport { isTypedValue, fromOpenCollectionTypedValue } from './common/datatype';\n\nconst isSecretVariable = (v: Variable | SecretVariable): v is SecretVariable => {\n return 'secret' in v && v.secret === true;\n};\n\nexport const toBrunoEnvironmentVariables = (variables: (Variable | SecretVariable)[] | null | undefined): (BrunoEnvironmentVariable | BrunoSecretEnvironmentVariable)[] => {\n if (!variables?.length) {\n return [];\n }\n\n return variables.map((v): (BrunoEnvironmentVariable | BrunoSecretEnvironmentVariable) => {\n if (isSecretVariable(v)) {\n const variable: BrunoEnvironmentVariable = {\n uid: uuid(),\n name: ensureString(v.name),\n value: '',\n type: 'text',\n enabled: v.disabled !== true,\n secret: true\n };\n\n if (v.type && v.type !== 'string' && v.type !== 'null') {\n variable.dataType = v.type;\n }\n\n if (v.description) {\n variable.description = typeof v.description === 'string' ? v.description : (v.description as any)?.content || '';\n }\n\n return variable;\n }\n\n const variable: BrunoEnvironmentVariable = {\n uid: uuid(),\n name: ensureString(v.name),\n value: '',\n type: 'text',\n enabled: v.disabled !== true,\n secret: false\n };\n\n if (isTypedValue(v.value)) {\n Object.assign(variable, fromOpenCollectionTypedValue(v.value));\n } else {\n variable.value = ensureString(v.value);\n }\n\n if (v.description) {\n variable.description = typeof v.description === 'string' ? v.description : (v.description as any)?.content || '';\n }\n\n return variable;\n });\n};\n\n// Parses the yml `externalSecrets: { type, variables: [{ name, path|secretName|vaultName }] }`\n// block into the runtime shape. `uid` and `enabled` are added here; the fetched `value`,\n// `providerConfig` and `lastSyncedAt` are runtime-only and never present in the file.\nconst toBrunoExternalSecrets = (externalSecrets: any): BrunoEnvironment['externalSecrets'] | undefined => {\n if (!externalSecrets || typeof externalSecrets !== 'object') {\n return undefined;\n }\n\n const type = ensureString(externalSecrets.type) as BrunoExternalSecretProviderType;\n const identifierField = SECRET_PROVIDER_IDENTIFIER_FIELDS[type];\n if (!identifierField) {\n return undefined;\n }\n\n // Keep any named entry, even one with an empty identifier — a half-filled secret row is the user's\n // data; dropping it here would silently delete it on the next save.\n const variables = Array.isArray(externalSecrets.variables)\n ? externalSecrets.variables\n .filter((v: any) => v && v.name)\n .map((v: any) => ({\n uid: uuid(),\n name: ensureString(v.name),\n enabled: v.disabled !== true,\n [identifierField]: ensureString(v[identifierField])\n }))\n : [];\n\n return { type, variables } as BrunoEnvironment['externalSecrets'];\n};\n\nconst parseEnvironment = (ymlString: string): BrunoEnvironment => {\n try {\n const ocEnvironment: Environment = parseYml(ymlString);\n\n const brunoEnvironment: BrunoEnvironment = {\n uid: uuid(),\n name: ensureString(ocEnvironment.name, 'Untitled Environment'),\n variables: toBrunoEnvironmentVariables(ocEnvironment.variables),\n color: ocEnvironment.color || null\n };\n\n const externalSecrets = toBrunoExternalSecrets((ocEnvironment as any).externalSecrets);\n if (externalSecrets) {\n brunoEnvironment.externalSecrets = externalSecrets;\n }\n\n return brunoEnvironment;\n } catch (error) {\n console.error('Error parsing environment:', error);\n throw error;\n }\n};\n\nexport default parseEnvironment;\n","import type { Item as BrunoItem } from '@usebruno/schema-types/collection/item';\nimport stringifyHttpRequest from './items/stringifyHttpRequest';\nimport stringifyGraphqlRequest from './items/stringifyGraphQLRequest';\nimport stringifyGrpcRequest from './items/stringifyGrpcRequest';\nimport stringifyWebsocketRequest from './items/stringifyWebsocketRequest';\nimport stringifyScript from './items/stringifyScript';\nimport stringifyApp from './items/stringifyApp';\n\nconst stringifyItem = (item: BrunoItem): string => {\n try {\n switch (item.type) {\n case 'http-request':\n return stringifyHttpRequest(item);\n\n case 'graphql-request':\n return stringifyGraphqlRequest(item);\n\n case 'grpc-request':\n return stringifyGrpcRequest(item);\n\n case 'ws-request':\n return stringifyWebsocketRequest(item);\n\n case 'js':\n return stringifyScript(item);\n\n case 'app':\n return stringifyApp(item);\n\n case 'folder':\n throw new Error('Folder items should be handled separately using stringifyFolder');\n\n default:\n throw new Error(`Unsupported item type: ${item.type}`);\n }\n } catch (error) {\n console.error('Error stringifying item:', error);\n throw error;\n }\n};\nexport default stringifyItem;\n","import type { Item as BrunoItem, HttpItemSettings as BrunoHttpItemSettings } from '@usebruno/schema-types/collection/item';\nimport type { HttpRequest as BrunoHttpRequest } from '@usebruno/schema-types/requests/http';\nimport type { HttpRequest, HttpRequestSettings, HttpRequestExample, HttpRequestInfo, HttpRequestDetails, HttpRequestRuntime, HttpRequestHeader } from '@opencollection/types/requests/http';\nimport type { Auth } from '@opencollection/types/common/auth';\nimport type { Scripts } from '@opencollection/types/common/scripts';\nimport type { Variable } from '@opencollection/types/common/variables';\nimport type { Assertion } from '@opencollection/types/common/assertions';\nimport type { Action } from '@opencollection/types/common/actions';\nimport type { HttpRequestParam, HttpRequestBody } from '@opencollection/types/requests/http';\nimport { stringifyYml } from '../utils';\nimport { toOpenCollectionApp, OpenCollectionApp } from '../common/app';\nimport { toOpenCollectionAuth } from '../common/auth';\nimport { toOpenCollectionHttpHeaders, toOpenCollectionResponseHeaders } from '../common/headers';\nimport { toOpenCollectionParams } from '../common/params';\nimport { toOpenCollectionBody } from '../common/body';\nimport { toOpenCollectionVariables } from '../common/variables';\nimport { toOpenCollectionActions } from '../common/actions';\nimport { toOpenCollectionScripts } from '../common/scripts';\nimport { toOpenCollectionAssertions } from '../common/assertions';\nimport { isNumber, isNonEmptyString } from '../../../utils';\n\nconst stringifyHttpRequest = (item: BrunoItem): string => {\n try {\n const ocRequest: HttpRequest = {};\n const brunoRequest = item.request as BrunoHttpRequest;\n\n // info block\n const info: HttpRequestInfo = {\n name: isNonEmptyString(item.name) ? item.name : 'Untitled Request',\n type: 'http'\n };\n if (item.seq) {\n info.seq = item.seq;\n }\n if (item.tags?.length) {\n info.tags = item.tags;\n }\n if (isNonEmptyString(item.description)) {\n info.description = item.description;\n }\n ocRequest.info = info;\n\n // http block\n const http: HttpRequestDetails = {\n method: isNonEmptyString(brunoRequest.method) ? brunoRequest.method : 'GET',\n url: isNonEmptyString(brunoRequest.url) ? brunoRequest.url : ''\n };\n\n // headers\n const headers: HttpRequestHeader[] | undefined = toOpenCollectionHttpHeaders(brunoRequest.headers);\n if (headers) {\n http.headers = headers;\n }\n\n // params\n const params: HttpRequestParam[] | undefined = toOpenCollectionParams(brunoRequest.params);\n if (params) {\n http.params = params;\n }\n\n // body\n const body: HttpRequestBody | undefined = toOpenCollectionBody(brunoRequest.body);\n if (body) {\n http.body = body;\n }\n\n // auth\n const auth: Auth | undefined = toOpenCollectionAuth(brunoRequest.auth);\n if (auth) {\n http.auth = auth;\n }\n\n ocRequest.http = http;\n\n // runtime block\n const runtime: HttpRequestRuntime = {};\n let hasRuntime = false;\n\n // variables\n const variables: Variable[] | undefined = toOpenCollectionVariables(brunoRequest.vars);\n if (variables) {\n runtime.variables = variables;\n hasRuntime = true;\n }\n\n // scripts\n const scripts: Scripts | undefined = toOpenCollectionScripts(brunoRequest);\n if (scripts) {\n runtime.scripts = scripts;\n hasRuntime = true;\n }\n\n // assertions\n const assertions: Assertion[] | undefined = toOpenCollectionAssertions(brunoRequest.assertions);\n if (assertions) {\n runtime.assertions = assertions;\n hasRuntime = true;\n }\n\n // actions (from post-response variables)\n const resVars = brunoRequest.vars?.res;\n const actions: Action[] | undefined = toOpenCollectionActions(resVars);\n if (actions) {\n runtime.actions = actions;\n hasRuntime = true;\n }\n\n if (hasRuntime) {\n ocRequest.runtime = runtime;\n }\n\n // settings\n const httpSettings = item.settings as BrunoHttpItemSettings | undefined;\n const settings: HttpRequestSettings = {};\n if (httpSettings?.encodeUrl === true) {\n settings.encodeUrl = true;\n } else if (httpSettings?.encodeUrl === false) {\n settings.encodeUrl = false;\n } else {\n settings.encodeUrl = true;\n }\n\n const timeout = httpSettings?.timeout;\n if (isNumber(timeout)) {\n settings.timeout = timeout;\n } else {\n settings.timeout = 0;\n }\n\n if (httpSettings?.followRedirects === true) {\n settings.followRedirects = true;\n } else if (httpSettings?.followRedirects === false) {\n settings.followRedirects = false;\n } else {\n settings.followRedirects = true;\n }\n\n const maxRedirects = httpSettings?.maxRedirects;\n if (isNumber(maxRedirects)) {\n settings.maxRedirects = maxRedirects;\n } else {\n settings.maxRedirects = 5;\n }\n\n ocRequest.settings = settings;\n\n // examples\n if (item.examples?.length) {\n const examples: HttpRequestExample[] = item.examples.map((example) => {\n const ocExample: HttpRequestExample = {};\n ocExample.name = example?.name || 'Untitled Example';\n\n if (isNonEmptyString(example.description)) {\n ocExample.description = example.description;\n }\n\n if (example.request) {\n ocExample.request = {};\n ocExample.request.url = example.request.url || '';\n ocExample.request.method = example.request.method || 'GET';\n\n const exampleHeaders = toOpenCollectionHttpHeaders(example.request.headers);\n if (exampleHeaders) {\n ocExample.request.headers = exampleHeaders;\n }\n\n const exampleParams = toOpenCollectionParams(example.request.params);\n if (exampleParams) {\n ocExample.request.params = exampleParams;\n }\n\n const exampleBody = toOpenCollectionBody(example.request.body);\n if (exampleBody !== undefined) {\n ocExample.request.body = exampleBody;\n }\n }\n\n if (example.response) {\n ocExample.response = {};\n\n const statusNum = Number(example.response.status);\n if (Number.isInteger(statusNum) && statusNum > 0) {\n ocExample.response.status = statusNum;\n }\n\n if (isNonEmptyString(example.response.statusText)) {\n ocExample.response.statusText = example.response.statusText;\n }\n\n const responseHeaders = toOpenCollectionResponseHeaders(example.response.headers);\n if (responseHeaders) {\n ocExample.response.headers = responseHeaders;\n }\n\n if (example.response.body && example.response.body.type && example.response.body.content !== undefined) {\n const content = example.response.body.content;\n const contentString = typeof content === 'string' ? content : JSON.stringify(content, null, 2);\n\n ocExample.response.body = {\n type: example.response.body.type as 'json' | 'text' | 'xml' | 'html' | 'binary',\n data: contentString\n };\n }\n }\n\n return ocExample;\n });\n\n if (examples?.length) {\n ocRequest.examples = examples;\n }\n }\n\n // docs\n if (isNonEmptyString(brunoRequest.docs)) {\n ocRequest.docs = brunoRequest.docs;\n }\n\n // app\n const app: OpenCollectionApp | undefined = toOpenCollectionApp(item.app);\n if (app) {\n (ocRequest as any).app = app;\n }\n\n return stringifyYml(ocRequest);\n } catch (error) {\n console.error('Error stringifying HTTP request:', error);\n throw error;\n }\n};\n\nexport default stringifyHttpRequest;\n","import type { Item as BrunoItem, HttpItemSettings as BrunoHttpItemSettings } from '@usebruno/schema-types/collection/item';\nimport type { HttpRequest as BrunoHttpRequest } from '@usebruno/schema-types/requests/http';\nimport type { GraphQLRequest, GraphQLRequestSettings, GraphQLBody, GraphQLRequestInfo, GraphQLRequestDetails, GraphQLRequestRuntime } from '@opencollection/types/requests/graphql';\nimport type { Auth } from '@opencollection/types/common/auth';\nimport type { Scripts } from '@opencollection/types/common/scripts';\nimport type { Variable } from '@opencollection/types/common/variables';\nimport type { Assertion } from '@opencollection/types/common/assertions';\nimport type { Action } from '@opencollection/types/common/actions';\nimport type { HttpRequestParam, HttpRequestHeader } from '@opencollection/types/requests/http';\nimport { stringifyYml } from '../utils';\nimport { isNonEmptyString, isNumber } from '../../../utils';\nimport { toOpenCollectionAuth } from '../common/auth';\nimport { toOpenCollectionHttpHeaders } from '../common/headers';\nimport { toOpenCollectionParams } from '../common/params';\nimport { toOpenCollectionVariables } from '../common/variables';\nimport { toOpenCollectionActions } from '../common/actions';\nimport { toOpenCollectionScripts } from '../common/scripts';\nimport { toOpenCollectionAssertions } from '../common/assertions';\n\nconst stringifyGraphQLRequest = (item: BrunoItem): string => {\n try {\n const ocRequest: GraphQLRequest = {};\n const brunoRequest = item.request as BrunoHttpRequest;\n\n // info block\n const info: GraphQLRequestInfo = {\n name: isNonEmptyString(item.name) ? item.name : 'Untitled Request',\n type: 'graphql'\n };\n if (item.seq) {\n info.seq = item.seq;\n }\n if (item.tags?.length) {\n info.tags = item.tags;\n }\n if (isNonEmptyString(item.description)) {\n info.description = item.description;\n }\n ocRequest.info = info;\n\n // graphql block\n const graphql: GraphQLRequestDetails = {\n method: isNonEmptyString(brunoRequest.method) ? brunoRequest.method : 'POST',\n url: isNonEmptyString(brunoRequest.url) ? brunoRequest.url : ''\n };\n\n // headers\n const headers: HttpRequestHeader[] | undefined = toOpenCollectionHttpHeaders(brunoRequest.headers);\n if (headers) {\n graphql.headers = headers;\n }\n\n // params\n const params: HttpRequestParam[] | undefined = toOpenCollectionParams(brunoRequest.params);\n if (params) {\n graphql.params = params;\n }\n\n // body\n if (brunoRequest.body?.mode === 'graphql' && brunoRequest.body.graphql) {\n const graphqlBody: GraphQLBody = {};\n let hasBody = false;\n\n if (isNonEmptyString(brunoRequest.body.graphql.query)) {\n graphqlBody.query = brunoRequest.body.graphql.query;\n hasBody = true;\n }\n\n if (isNonEmptyString(brunoRequest.body.graphql.variables)) {\n graphqlBody.variables = brunoRequest.body.graphql.variables;\n hasBody = true;\n }\n\n if (hasBody) {\n graphql.body = graphqlBody;\n }\n }\n\n // auth (in graphql block, not runtime)\n const auth: Auth | undefined = toOpenCollectionAuth(brunoRequest.auth);\n if (auth) {\n graphql.auth = auth;\n }\n\n ocRequest.graphql = graphql;\n\n // runtime block\n const runtime: GraphQLRequestRuntime = {};\n let hasRuntime = false;\n\n // variables\n const variables: Variable[] | undefined = toOpenCollectionVariables(brunoRequest.vars);\n if (variables) {\n runtime.variables = variables;\n hasRuntime = true;\n }\n\n // scripts\n const scripts: Scripts | undefined = toOpenCollectionScripts(brunoRequest);\n if (scripts) {\n runtime.scripts = scripts;\n hasRuntime = true;\n }\n\n // assertions\n const assertions: Assertion[] | undefined = toOpenCollectionAssertions(brunoRequest.assertions);\n if (assertions) {\n runtime.assertions = assertions;\n hasRuntime = true;\n }\n\n // actions (from post-response variables)\n const resVars = brunoRequest.vars?.res;\n const actions: Action[] | undefined = toOpenCollectionActions(resVars);\n if (actions) {\n runtime.actions = actions;\n hasRuntime = true;\n }\n\n if (hasRuntime) {\n ocRequest.runtime = runtime;\n }\n\n // settings\n const httpSettings = item.settings as BrunoHttpItemSettings | undefined;\n const settings: GraphQLRequestSettings = {};\n if (httpSettings?.encodeUrl === true) {\n settings.encodeUrl = true;\n } else if (httpSettings?.encodeUrl === false) {\n settings.encodeUrl = false;\n } else {\n settings.encodeUrl = true;\n }\n\n const timeout = httpSettings?.timeout;\n if (isNumber(timeout)) {\n settings.timeout = timeout;\n } else {\n settings.timeout = 0;\n }\n\n if (httpSettings?.followRedirects === true) {\n settings.followRedirects = true;\n } else if (httpSettings?.followRedirects === false) {\n settings.followRedirects = false;\n } else {\n settings.followRedirects = true;\n }\n\n const maxRedirects = httpSettings?.maxRedirects;\n if (isNumber(maxRedirects)) {\n settings.maxRedirects = maxRedirects;\n } else {\n settings.maxRedirects = 5;\n }\n\n ocRequest.settings = settings;\n\n // docs\n if (isNonEmptyString(brunoRequest.docs)) {\n ocRequest.docs = brunoRequest.docs;\n }\n\n return stringifyYml(ocRequest);\n } catch (error) {\n console.error('Error stringifying GraphQL request:', error);\n throw error;\n }\n};\n\nexport default stringifyGraphQLRequest;\n","import type { Item as BrunoItem } from '@usebruno/schema-types/collection/item';\nimport type { KeyValue as BrunoKeyValue } from '@usebruno/schema-types/common/key-value';\nimport type { GrpcRequest as BrunoGrpcRequest } from '@usebruno/schema-types/requests/grpc';\nimport type { GrpcRequest, GrpcMetadata, GrpcMessageVariant, GrpcMessage, GrpcRequestInfo, GrpcRequestDetails, GrpcRequestRuntime } from '@opencollection/types/requests/grpc';\nimport type { Auth } from '@opencollection/types/common/auth';\nimport type { Scripts } from '@opencollection/types/common/scripts';\nimport type { Variable } from '@opencollection/types/common/variables';\nimport type { Assertion } from '@opencollection/types/common/assertions';\nimport { stringifyYml } from '../utils';\nimport { isNonEmptyString } from '../../../utils';\nimport { toOpenCollectionAuth } from '../common/auth';\nimport { toOpenCollectionVariables } from '../common/variables';\nimport { toOpenCollectionScripts } from '../common/scripts';\nimport { toOpenCollectionAssertions } from '../common/assertions';\n\nconst stringifyGrpcRequest = (item: BrunoItem): string => {\n try {\n const ocRequest: GrpcRequest = {};\n const brunoRequest = item.request as BrunoGrpcRequest;\n\n // info block\n const info: GrpcRequestInfo = {\n name: isNonEmptyString(item.name) ? item.name : 'Untitled Request',\n type: 'grpc'\n };\n if (item.seq) {\n info.seq = item.seq;\n }\n if (item.tags?.length) {\n info.tags = item.tags;\n }\n if (isNonEmptyString(item.description)) {\n info.description = item.description;\n }\n ocRequest.info = info;\n\n // grpc block\n const grpc: GrpcRequestDetails = {\n url: isNonEmptyString(brunoRequest.url) ? brunoRequest.url : '',\n method: isNonEmptyString(brunoRequest.method) ? brunoRequest.method : ''\n };\n\n // method type\n if (brunoRequest.methodType) {\n grpc.methodType = brunoRequest.methodType;\n }\n\n // proto file path\n if (isNonEmptyString(brunoRequest.protoPath)) {\n grpc.protoFilePath = brunoRequest.protoPath;\n }\n\n // metadata\n if (brunoRequest.headers?.length) {\n const metadata: GrpcMetadata[] = brunoRequest.headers.map((header: BrunoKeyValue) => {\n const metadataItem: GrpcMetadata = {\n name: header.name || '',\n value: header.value || ''\n };\n\n if (header?.description?.trim().length) {\n metadataItem.description = header.description;\n }\n\n if (header.enabled === false) {\n metadataItem.disabled = true;\n }\n\n return metadataItem;\n });\n\n if (metadata.length) {\n grpc.metadata = metadata;\n }\n }\n\n // message\n if (brunoRequest.body?.mode === 'grpc' && brunoRequest.body.grpc?.length) {\n const messages: GrpcMessageVariant[] = brunoRequest.body.grpc.map(({ name, content }, index) => ({\n title: name || `message ${index + 1}`,\n message: content || ''\n }));\n grpc.message = messages;\n }\n\n // auth\n const auth: Auth | undefined = toOpenCollectionAuth(brunoRequest.auth);\n if (auth) {\n grpc.auth = auth;\n }\n\n ocRequest.grpc = grpc;\n\n // runtime block\n const runtime: GrpcRequestRuntime = {};\n let hasRuntime = false;\n\n // variables\n const variables: Variable[] | undefined = toOpenCollectionVariables(brunoRequest.vars);\n if (variables) {\n runtime.variables = variables;\n hasRuntime = true;\n }\n\n // scripts\n const scripts: Scripts | undefined = toOpenCollectionScripts(brunoRequest);\n if (scripts) {\n runtime.scripts = scripts;\n hasRuntime = true;\n }\n\n // assertions\n const assertions: Assertion[] | undefined = toOpenCollectionAssertions(brunoRequest.assertions);\n if (assertions) {\n runtime.assertions = assertions;\n hasRuntime = true;\n }\n\n if (hasRuntime) {\n ocRequest.runtime = runtime;\n }\n\n // docs\n if (isNonEmptyString(brunoRequest.docs)) {\n ocRequest.docs = brunoRequest.docs;\n }\n\n return stringifyYml(ocRequest);\n } catch (error) {\n console.error('Error stringifying gRPC request:', error);\n throw error;\n }\n};\n\nexport default stringifyGrpcRequest;\n","import type { Item as BrunoItem } from '@usebruno/schema-types/collection/item';\nimport type { WebSocketRequest as BrunoWebSocketRequest } from '@usebruno/schema-types/requests/websocket';\nimport type { WebSocketRequest, WebSocketRequestInfo, WebSocketRequestDetails, WebSocketRequestRuntime, WebSocketMessage, WebSocketMessageVariant } from '@opencollection/types/requests/websocket';\nimport type { Auth } from '@opencollection/types/common/auth';\nimport type { Scripts } from '@opencollection/types/common/scripts';\nimport type { Variable } from '@opencollection/types/common/variables';\nimport type { HttpRequestHeader } from '@opencollection/types/requests/http';\nimport { stringifyYml } from '../utils';\nimport { isNonEmptyString } from '../../../utils';\nimport { toOpenCollectionAuth } from '../common/auth';\nimport { toOpenCollectionHttpHeaders } from '../common/headers';\nimport { toOpenCollectionVariables } from '../common/variables';\nimport { toOpenCollectionScripts } from '../common/scripts';\n\nconst stringifyWebsocketRequest = (item: BrunoItem): string => {\n try {\n const ocRequest: WebSocketRequest = {};\n const brunoRequest = item.request as BrunoWebSocketRequest;\n\n // info block\n const info: WebSocketRequestInfo = {\n name: isNonEmptyString(item.name) ? item.name : 'Untitled Request',\n type: 'websocket'\n };\n if (item.seq) {\n info.seq = item.seq;\n }\n if (item.tags?.length) {\n info.tags = item.tags;\n }\n if (isNonEmptyString(item.description)) {\n info.description = item.description;\n }\n ocRequest.info = info;\n\n // websocket block\n const websocket: WebSocketRequestDetails = {\n url: isNonEmptyString(brunoRequest.url) ? brunoRequest.url : ''\n };\n\n // headers\n const headers: HttpRequestHeader[] | undefined = toOpenCollectionHttpHeaders(brunoRequest.headers);\n if (headers) {\n websocket.headers = headers;\n }\n\n // message: single message without a custom name uses flat WebSocketMessage (backward compatible),\n // otherwise uses WebSocketMessageVariant[] to preserve names\n if (brunoRequest.body?.mode === 'ws' && brunoRequest.body.ws?.length) {\n const messages = brunoRequest.body.ws;\n const hasCustomName = messages.length === 1 && messages[0].name && messages[0].name.trim().length > 0;\n\n const hasContent = messages.length === 1 && (messages[0].content || '').trim().length > 0;\n\n if (messages.length === 1 && !hasCustomName && hasContent) {\n const msg = messages[0];\n const message: WebSocketMessage = {\n type: (msg.type as WebSocketMessage['type']) || 'text',\n data: msg.content || ''\n };\n websocket.message = message;\n } else {\n const variants: WebSocketMessageVariant[] = messages.map((msg, index) => ({\n title: msg.name || `message ${index + 1}`,\n selected: msg.selected || false,\n message: {\n type: (msg.type as WebSocketMessage['type']) || 'text',\n data: msg.content || ''\n }\n }));\n websocket.message = variants;\n }\n }\n\n // auth\n const auth: Auth | undefined = toOpenCollectionAuth(brunoRequest.auth);\n if (auth) {\n websocket.auth = auth;\n }\n\n ocRequest.websocket = websocket;\n\n // runtime block\n const runtime: WebSocketRequestRuntime = {};\n let hasRuntime = false;\n\n // variables\n const variables: Variable[] | undefined = toOpenCollectionVariables(brunoRequest.vars);\n if (variables) {\n runtime.variables = variables;\n hasRuntime = true;\n }\n\n // scripts\n const scripts: Scripts | undefined = toOpenCollectionScripts(brunoRequest);\n if (scripts) {\n runtime.scripts = scripts;\n hasRuntime = true;\n }\n\n if (hasRuntime) {\n ocRequest.runtime = runtime;\n }\n\n // settings\n const wsSettings = item.settings as Record<string, number | string | undefined> | undefined;\n if (wsSettings) {\n ocRequest.settings = {};\n const timeout = Number(wsSettings.timeout);\n ocRequest.settings.timeout = !isNaN(timeout) ? timeout : 0;\n const keepAliveInterval = Number(wsSettings.keepAliveInterval);\n ocRequest.settings.keepAliveInterval = !isNaN(keepAliveInterval) ? keepAliveInterval : 0;\n }\n\n // docs\n if (isNonEmptyString(brunoRequest.docs)) {\n ocRequest.docs = brunoRequest.docs;\n }\n\n return stringifyYml(ocRequest);\n } catch (error) {\n console.error('Error stringifying WebSocket request:', error);\n throw error;\n }\n};\n\nexport default stringifyWebsocketRequest;\n","import type { Item as BrunoItem } from '@usebruno/schema-types/collection/item';\nimport type { ScriptFile } from '@opencollection/types/collection/item';\nimport { stringifyYml } from '../utils';\n\nconst stringifyScript = (item: BrunoItem): string => {\n try {\n const ocScript: ScriptFile = {\n type: 'script'\n };\n\n if (item.fileContent?.trim().length) {\n ocScript.script = item.fileContent;\n }\n\n return stringifyYml(ocScript);\n } catch (error) {\n console.error('Error stringifying script:', error);\n throw error;\n }\n};\n\nexport default stringifyScript;\n","import type { Item as BrunoItem } from '@usebruno/schema-types/collection/item';\nimport { stringifyYml } from '../utils';\n\ninterface AppFileInfo {\n name: string;\n type: 'app';\n seq?: number;\n tags?: string[];\n}\n\ninterface AppFile {\n info: AppFileInfo;\n code?: string;\n}\n\n// Mirror the request shape (info.name/type/seq/tags + body) so apps round-trip\n// the same fields and can be reordered via seq like every other item.\nconst stringifyApp = (item: BrunoItem): string => {\n try {\n const info: AppFileInfo = {\n name: item.name && item.name.trim().length ? item.name : 'App',\n type: 'app'\n };\n if (typeof item.seq === 'number') {\n info.seq = item.seq;\n }\n if (Array.isArray(item.tags) && item.tags.length) {\n info.tags = item.tags;\n }\n\n const ocApp: AppFile = { info };\n\n const code = item.app?.code;\n if (code && code.trim().length) {\n ocApp.code = code;\n }\n\n return stringifyYml(ocApp);\n } catch (error) {\n console.error('Error stringifying app:', error);\n throw error;\n }\n};\n\nexport default stringifyApp;\n","import type { FolderRoot } from '@usebruno/schema-types/collection/folder';\nimport type { Folder, FolderInfo } from '@opencollection/types/collection/item';\nimport type { Variable } from '@opencollection/types/common/variables';\nimport type { Action } from '@opencollection/types/common/actions';\nimport type { Scripts } from '@opencollection/types/common/scripts';\nimport type { Auth } from '@opencollection/types/common/auth';\nimport type { HttpRequestHeader } from '@opencollection/types/requests/http';\nimport type { RequestDefaults } from '@opencollection/types/common/request-defaults';\nimport { toOpenCollectionAuth } from './common/auth';\nimport { toOpenCollectionHttpHeaders } from './common/headers';\nimport { toOpenCollectionVariables } from './common/variables';\nimport { toOpenCollectionActions } from './common/actions';\nimport { toOpenCollectionScripts } from './common/scripts';\nimport { stringifyYml } from './utils';\n\nconst hasRequestDefaults = (folderRoot: FolderRoot): boolean => {\n const requestDefaults = folderRoot?.request;\n\n return Boolean((requestDefaults?.headers?.length)\n || (requestDefaults?.vars?.req?.length)\n || (requestDefaults?.vars?.res?.length)\n || hasRequestScripts(folderRoot)\n || hasRequestAuth(folderRoot));\n};\n\nconst hasRequestAuth = (folderRoot: FolderRoot): boolean => {\n return Boolean((folderRoot.request?.auth?.mode !== 'none'));\n};\n\nconst hasRequestScripts = (folderRoot: FolderRoot): boolean => {\n return Boolean((folderRoot.request?.script?.req)\n || (folderRoot.request?.script?.res)\n || (folderRoot.request?.tests));\n};\n\nconst stringifyFolder = (folderRoot: FolderRoot): string => {\n try {\n const ocFolder: Folder = {};\n\n // info block\n const info: FolderInfo = {\n name: folderRoot.meta?.name || 'Untitled Folder',\n type: 'folder',\n seq: folderRoot.meta?.seq || 1\n };\n ocFolder.info = info;\n\n // request defaults\n if (hasRequestDefaults(folderRoot)) {\n ocFolder.request = {} as RequestDefaults;\n\n // headers\n if (folderRoot.request?.headers?.length) {\n const ocHeaders: HttpRequestHeader[] | undefined = toOpenCollectionHttpHeaders(folderRoot.request?.headers);\n if (ocHeaders) {\n ocFolder.request.headers = ocHeaders;\n }\n }\n\n // auth\n if (hasRequestAuth(folderRoot)) {\n const ocAuth: Auth | undefined = toOpenCollectionAuth(folderRoot.request?.auth);\n if (ocAuth) {\n ocFolder.request.auth = ocAuth;\n }\n }\n\n // variables\n if (folderRoot.request?.vars?.req?.length) {\n const ocVariables: Variable[] | undefined = toOpenCollectionVariables(folderRoot.request?.vars);\n if (ocVariables) {\n ocFolder.request.variables = ocVariables;\n }\n }\n\n // actions (post-response variables)\n if (folderRoot.request?.vars?.res?.length) {\n const ocActions: Action[] | undefined = toOpenCollectionActions(folderRoot.request?.vars?.res);\n if (ocActions) {\n (ocFolder.request as any).actions = ocActions;\n }\n }\n\n // scripts\n if (hasRequestScripts(folderRoot)) {\n const ocScripts: Scripts | undefined = toOpenCollectionScripts(folderRoot?.request);\n if (ocScripts) {\n ocFolder.request.scripts = ocScripts;\n }\n }\n }\n\n // docs\n if (folderRoot.docs?.trim().length) {\n ocFolder.docs = {\n content: folderRoot.docs,\n type: 'text/markdown'\n };\n }\n\n return stringifyYml(ocFolder);\n } catch (error) {\n console.error('Error stringifying folder.yml:', error);\n throw error;\n }\n};\nexport default stringifyFolder;\n","import type { OpenCollection } from '@opencollection/types';\nimport type { ProtoFileItem, ProtoFileImportPath } from '@opencollection/types/config/protobuf';\nimport type { HttpRequestHeader } from '@opencollection/types/requests/http';\nimport type { ClientCertificate, PemCertificate, Pkcs12Certificate } from '@opencollection/types/config/certificates';\nimport type { Variable } from '@opencollection/types/common/variables';\nimport type { Action } from '@opencollection/types/common/actions';\nimport type { Scripts } from '@opencollection/types/common/scripts';\nimport { stringifyYml } from './utils';\nimport { toOpenCollectionAuth } from './common/auth';\nimport { toOpenCollectionHttpHeaders } from './common/headers';\nimport { toOpenCollectionVariables } from './common/variables';\nimport { toOpenCollectionActions } from './common/actions';\nimport { toOpenCollectionScripts } from './common/scripts';\nimport type { Auth } from '@opencollection/types/common/auth';\n\nconst hasCollectionConfig = (brunoConfig: any): boolean => {\n // protobuf\n const hasProtobuf = (\n brunoConfig.protobuf?.protoFiles?.length > 0\n || brunoConfig.protobuf?.importPaths?.length > 0\n );\n\n // proxy - check if proxy is configured in newer format\n // Valid newer format: has 'inherit' property and 'config' object\n const isValidProxyFormat = brunoConfig.proxy\n && typeof brunoConfig.proxy === 'object'\n && 'inherit' in brunoConfig.proxy\n && brunoConfig.proxy.config\n && typeof brunoConfig.proxy.config === 'object';\n\n const hasProxy = isValidProxyFormat;\n\n // client certificates\n const hasClientCertificates = brunoConfig.clientCertificates?.certs?.length > 0;\n\n return hasProtobuf || hasProxy || hasClientCertificates;\n};\n\nconst hasRequestDefaults = (collectionRoot: any): boolean => {\n const requestRoot = collectionRoot?.request;\n\n return Boolean((requestRoot?.headers?.length)\n || (requestRoot?.vars?.req?.length)\n || (requestRoot?.vars?.res?.length)\n || hasRequestScripts(collectionRoot)\n || hasRequestAuth(collectionRoot));\n};\n\nconst hasRequestAuth = (collectionRoot: any): boolean => {\n const reqAuthMode = collectionRoot?.request?.auth?.mode;\n return Boolean(reqAuthMode && reqAuthMode !== 'none');\n};\n\nconst hasRequestScripts = (collectionRoot: any): boolean => {\n if (!collectionRoot?.request) return false;\n\n return (collectionRoot.request.script?.req)\n || (collectionRoot.request.script?.res)\n || (collectionRoot.request.tests);\n};\n\nconst hasPresets = (brunoConfig: any): boolean => {\n return brunoConfig?.presets?.requestType?.length\n || brunoConfig?.presets?.requestUrl?.length;\n};\n\nconst stringifyCollection = (collectionRoot: any, brunoConfig: any): string => {\n try {\n const oc: OpenCollection = {};\n\n oc.opencollection = '1.0.0';\n oc.info = {\n name: brunoConfig.name || 'Untitled Collection'\n };\n\n if (brunoConfig.version != null && brunoConfig.version !== '') {\n oc.info.version = String(brunoConfig.version);\n }\n\n // collection config\n if (hasCollectionConfig(brunoConfig)) {\n oc.config = {};\n\n if (brunoConfig.protobuf?.protoFiles?.length || brunoConfig.protobuf?.importPaths?.length) {\n oc.config.protobuf = {};\n\n if (brunoConfig.protobuf.protoFiles?.length) {\n oc.config.protobuf.protoFiles = brunoConfig.protobuf.protoFiles.map((protoFile: any): ProtoFileItem => ({\n type: 'file' as const,\n path: protoFile.path\n }));\n }\n\n if (brunoConfig.protobuf.importPaths?.length) {\n oc.config.protobuf.importPaths = brunoConfig.protobuf.importPaths.map((importPath: any): ProtoFileImportPath => {\n const item: ProtoFileImportPath = { path: importPath.path };\n if (importPath.enabled === false) {\n item.disabled = true;\n }\n return item;\n });\n }\n }\n\n // proxy - only write newer format\n // Validate that brunoConfig.proxy is in newer format before writing\n const isValidProxyFormat = brunoConfig.proxy\n && typeof brunoConfig.proxy === 'object'\n && 'inherit' in brunoConfig.proxy\n && brunoConfig.proxy.config\n && typeof brunoConfig.proxy.config === 'object';\n\n if (isValidProxyFormat) {\n oc.config.proxy = {\n inherit: brunoConfig.proxy.inherit,\n config: {\n protocol: brunoConfig.proxy.config.protocol || 'http',\n hostname: brunoConfig.proxy.config.hostname || '',\n port: brunoConfig.proxy.config.port || '',\n auth: {\n username: brunoConfig.proxy.config.auth?.username || '',\n password: brunoConfig.proxy.config.auth?.password || ''\n },\n bypassProxy: brunoConfig.proxy.config.bypassProxy || ''\n }\n };\n\n // Add optional disabled field if true\n if (brunoConfig.proxy.disabled === true) {\n oc.config.proxy.disabled = true;\n }\n\n // Add optional auth.disabled field if true\n if (brunoConfig.proxy.config?.auth?.disabled === true) {\n if (oc.config.proxy.config && oc.config.proxy.config.auth) {\n oc.config.proxy.config.auth.disabled = true;\n }\n }\n }\n\n // client certificates\n if (brunoConfig.clientCertificates?.certs?.length) {\n oc.config.clientCertificates = brunoConfig.clientCertificates.certs\n .map((cert: any): ClientCertificate | null => {\n if (cert.type === 'cert') {\n const pemCert: PemCertificate = {\n domain: cert.domain,\n type: 'pem',\n certificateFilePath: cert.certFilePath,\n privateKeyFilePath: cert.keyFilePath,\n ...(cert.passphrase && { passphrase: cert.passphrase })\n };\n return pemCert;\n } else if (cert.type === 'pfx') {\n const pkcs12Cert: Pkcs12Certificate = {\n domain: cert.domain,\n type: 'pkcs12',\n pkcs12FilePath: cert.pfxFilePath,\n ...(cert.passphrase && { passphrase: cert.passphrase })\n };\n return pkcs12Cert;\n } else {\n // Unsupported certificate type - ignore silently\n return null;\n }\n })\n .filter((cert: ClientCertificate | null): cert is ClientCertificate => cert !== null);\n }\n }\n\n // request defaults\n if (hasRequestDefaults(collectionRoot)) {\n oc.request = {};\n\n // headers\n if (collectionRoot.request?.headers?.length) {\n const ocHeaders: HttpRequestHeader[] | undefined = toOpenCollectionHttpHeaders(collectionRoot.request?.headers);\n if (ocHeaders) {\n oc.request.headers = ocHeaders;\n }\n }\n\n // auth\n if (hasRequestAuth(collectionRoot)) {\n const ocAuth: Auth | undefined = toOpenCollectionAuth(collectionRoot.request?.auth);\n if (ocAuth) {\n oc.request.auth = ocAuth;\n }\n }\n\n // variables\n if (collectionRoot.request?.vars?.req?.length) {\n const ocVariables: Variable[] | undefined = toOpenCollectionVariables(collectionRoot.request?.vars);\n if (ocVariables) {\n oc.request.variables = ocVariables;\n }\n }\n\n // actions (post-response variables)\n if (collectionRoot.request?.vars?.res?.length) {\n const ocActions: Action[] | undefined = toOpenCollectionActions(collectionRoot.request?.vars?.res);\n if (ocActions) {\n (oc.request as any).actions = ocActions;\n }\n }\n\n // scripts\n if (hasRequestScripts(collectionRoot)) {\n const ocScripts: Scripts | undefined = toOpenCollectionScripts(collectionRoot.request);\n if (ocScripts) {\n oc.request.scripts = ocScripts;\n }\n }\n }\n\n // docs\n if (collectionRoot?.docs?.trim().length) {\n oc.docs = {\n content: collectionRoot.docs,\n type: 'text/markdown'\n };\n }\n\n // bundled\n oc.bundled = false;\n\n // extensions\n oc.extensions = {};\n\n const hasBrunoExtensions = brunoConfig.ignore?.length || hasPresets(brunoConfig);\n\n if (hasBrunoExtensions) {\n const brunoExtension: any = {};\n\n if (brunoConfig.ignore?.length) {\n const ignoreList: string[] = [];\n brunoConfig.ignore.forEach((ignore: string) => {\n ignoreList.push(ignore);\n });\n brunoExtension.ignore = ignoreList;\n }\n\n if (hasPresets(brunoConfig)) {\n const presetsRequest: any = {};\n if (brunoConfig.presets.requestType?.length) {\n presetsRequest.type = brunoConfig.presets.requestType;\n }\n if (brunoConfig.presets.requestUrl?.length) {\n presetsRequest.url = brunoConfig.presets.requestUrl;\n }\n brunoExtension.presets = {\n request: presetsRequest\n };\n }\n\n oc.extensions.bruno = brunoExtension;\n }\n\n // bruno-specific script extensions\n if (brunoConfig.scripts?.additionalContextRoots?.length) {\n if (!oc.extensions.bruno) {\n oc.extensions.bruno = {};\n }\n (oc.extensions.bruno as any).scripts = {\n additionalContextRoots: brunoConfig.scripts.additionalContextRoots\n };\n }\n\n // bruno-specific extensions\n if (Array.isArray(brunoConfig.openapi) && brunoConfig.openapi.length > 0) {\n if (!oc.extensions.bruno) {\n oc.extensions.bruno = {};\n }\n (oc.extensions.bruno as any).openapi = brunoConfig.openapi.map((entry: any) => ({\n sourceUrl: entry.sourceUrl,\n groupBy: entry.groupBy,\n ...(entry.lastSyncDate && { lastSyncDate: entry.lastSyncDate }),\n ...(entry.specHash && { specHash: entry.specHash }),\n autoCheck: entry.autoCheck !== false,\n autoCheckInterval: entry.autoCheckInterval || 5\n }));\n }\n\n return stringifyYml(oc);\n } catch (error) {\n console.error('Error stringifying opencollection.yml:', error);\n throw error;\n }\n};\n\nexport default stringifyCollection;\n","import type {\n Environment as BrunoEnvironment,\n EnvironmentVariable as BrunoEnvironmentVariable,\n SecretEnvironmentVariable as BrunoSecretEnvironmentVariable,\n ExternalSecretProviderType as BrunoExternalSecretProviderType\n} from '@usebruno/schema-types/collection/environment';\nimport type { Environment } from '@opencollection/types/config/environments';\nimport type { Variable, SecretVariable } from '@opencollection/types/common/variables';\nimport { stringifyYml } from './utils';\nimport { ensureString } from '../../utils';\nimport { SECRET_PROVIDER_IDENTIFIER_FIELDS } from '../../constants';\nimport { hasTypedMetadata, toOpenCollectionTypedValue, serializeVariableValue } from './common/datatype';\n\nexport const toOpenCollectionEnvironmentVariables = (variables: (BrunoEnvironmentVariable | BrunoSecretEnvironmentVariable)[]): (Variable | SecretVariable)[] | undefined => {\n if (!variables?.length) {\n return undefined;\n }\n\n const ocVariables: (Variable | SecretVariable)[] = variables\n .map((v): Variable | SecretVariable => {\n if ('secret' in v && v.secret === true) {\n const secretVar: SecretVariable = {\n secret: true,\n name: v.name || ''\n };\n if (hasTypedMetadata(v)) {\n secretVar.type = v.dataType;\n }\n if (v.enabled === false) {\n secretVar.disabled = true;\n }\n if (v.description !== undefined) {\n secretVar.description = v.description;\n }\n return secretVar;\n }\n\n const valueStr = serializeVariableValue(v.value);\n\n const variable: Variable = {\n name: v.name || '',\n value: hasTypedMetadata(v) ? toOpenCollectionTypedValue(v, valueStr) : valueStr\n };\n\n if (v.enabled === false) {\n variable.disabled = true;\n }\n\n if (v.description !== undefined) {\n variable.description = v.description;\n }\n\n return variable;\n });\n\n return ocVariables.length > 0 ? ocVariables : undefined;\n};\n\n// Serializes the runtime externalSecrets block to yml `{ type, variables: [{ name,\n// path|secretName|vaultName, disabled? }] }`. Runtime-only fields (uid, value,\n// providerConfig, lastSyncedAt) are never written.\nconst toOpenCollectionExternalSecrets = (externalSecrets: BrunoEnvironment['externalSecrets']): { type: string; variables: Record<string, string | boolean>[] } | undefined => {\n const type = externalSecrets?.type as BrunoExternalSecretProviderType | undefined;\n const identifierField = type && SECRET_PROVIDER_IDENTIFIER_FIELDS[type];\n if (!type || !identifierField) {\n return undefined;\n }\n\n // Keep any named entry, even one with an empty identifier — a half-filled secret row is the user's\n // data; dropping it here would silently delete it on the next save.\n const variables = (externalSecrets?.variables || [])\n .filter((v: any) => v && v.name)\n .map((v: any) => {\n const secret: Record<string, string | boolean> = {\n name: v.name,\n [identifierField]: ensureString(v[identifierField])\n };\n if (v.enabled === false) {\n secret.disabled = true;\n }\n return secret;\n });\n\n return { type, variables };\n};\n\nconst stringifyEnvironment = (environment: BrunoEnvironment): string => {\n try {\n const ocEnvironment: Environment = {\n name: environment.name\n };\n\n if (environment.color) {\n ocEnvironment.color = environment.color;\n }\n\n if (environment.variables?.length) {\n const ocVariables = toOpenCollectionEnvironmentVariables(environment.variables);\n if (ocVariables) {\n ocEnvironment.variables = ocVariables;\n }\n }\n\n const ocExternalSecrets = toOpenCollectionExternalSecrets(environment.externalSecrets);\n if (ocExternalSecrets) {\n (ocEnvironment as any).externalSecrets = ocExternalSecrets;\n }\n\n return stringifyYml(ocEnvironment);\n } catch (error) {\n console.error('Error stringifying environment:', error);\n throw error;\n }\n};\n\nexport default stringifyEnvironment;\n","import { Worker } from 'node:worker_threads';\n\ninterface QueuedTask {\n priority: number;\n scriptPath: string;\n data: any;\n taskType: 'parse' | 'stringify';\n resolve?: (value: any) => void;\n reject?: (reason?: any) => void;\n}\n\nclass WorkerQueue {\n private queue: QueuedTask[];\n private isProcessing: boolean;\n private workers: Record<string, Worker>;\n\n constructor() {\n this.queue = [];\n this.isProcessing = false;\n this.workers = {};\n }\n\n async getWorkerForScriptPath(scriptPath: string) {\n if (!this.workers) this.workers = {};\n let worker = this.workers[scriptPath];\n if (!worker || worker.threadId === -1) {\n this.workers[scriptPath] = worker = new Worker(scriptPath);\n }\n return worker;\n }\n\n async enqueue(task: QueuedTask) {\n const { priority, scriptPath, data, taskType } = task;\n\n return new Promise((resolve, reject) => {\n this.queue.push({ priority, scriptPath, data, taskType, resolve, reject });\n this.queue?.sort((taskX, taskY) => taskX?.priority - taskY?.priority);\n this.processQueue();\n });\n }\n\n async processQueue() {\n if (this.isProcessing || this.queue.length === 0) {\n return;\n }\n\n this.isProcessing = true;\n const { scriptPath, data, taskType, resolve, reject } = this.queue.shift() as QueuedTask;\n\n try {\n const result = await this.runWorker({ scriptPath, data, taskType });\n resolve?.(result);\n } catch (error) {\n reject?.(error);\n } finally {\n this.isProcessing = false;\n this.processQueue();\n }\n }\n\n async runWorker({ scriptPath, data, taskType }: { scriptPath: string; data: any; taskType: 'parse' | 'stringify' }) {\n return new Promise(async (resolve, reject) => {\n let worker = await this.getWorkerForScriptPath(scriptPath);\n\n const messageHandler = (data: any) => {\n worker.off('message', messageHandler);\n worker.off('error', errorHandler);\n worker.off('exit', exitHandler);\n\n if (data?.error) {\n reject(new Error(data?.error));\n } else {\n resolve(data);\n }\n };\n\n const errorHandler = (error: Error) => {\n worker.off('message', messageHandler);\n worker.off('error', errorHandler);\n worker.off('exit', exitHandler);\n reject(error);\n };\n\n const exitHandler = (code: number) => {\n worker.off('message', messageHandler);\n worker.off('error', errorHandler);\n worker.off('exit', exitHandler);\n // Remove dead worker from cache\n delete this.workers[scriptPath];\n reject(new Error(`Worker stopped with exit code ${code}`));\n };\n\n worker.on('message', messageHandler);\n worker.on('error', errorHandler);\n worker.on('exit', exitHandler);\n\n worker.postMessage({ taskType, data });\n });\n }\n\n async cleanup() {\n const promises = Object.values(this.workers).map((worker) => {\n if (worker.threadId !== -1) {\n return worker.terminate();\n }\n return Promise.resolve();\n });\n\n await Promise.allSettled(promises);\n this.workers = {};\n }\n}\n\nexport default WorkerQueue;\n","import WorkerQueue from './WorkerQueue';\nimport { Lane, CollectionFormat } from '../types';\nimport { DEFAULT_COLLECTION_FORMAT } from '../constants';\nimport path from 'node:path';\n\nconst sizeInMB = (size: number): number => {\n return size / (1024 * 1024);\n};\n\nconst getSize = (data: any): number => {\n return sizeInMB(typeof data === 'string' ? Buffer.byteLength(data, 'utf8') : Buffer.byteLength(JSON.stringify(data), 'utf8'));\n};\n\n/**\n * Lanes are used to determine which worker queue to use based on the size of the data.\n *\n * The first lane is for smaller files (<0.1MB), the second lane is for larger files (>=0.1MB).\n * This helps with parsing performance.\n */\nconst LANES: Lane[] = [{\n maxSize: 0.005\n}, {\n maxSize: 0.1\n}, {\n maxSize: 1\n}, {\n maxSize: 10\n}, {\n maxSize: 100\n}];\n\ninterface WorkerQueueWithSize {\n maxSize: number;\n workerQueue: WorkerQueue;\n\n}\n\nclass BruParserWorker {\n private workerQueues: WorkerQueueWithSize[];\n\n constructor() {\n this.workerQueues = LANES?.map((lane) => ({\n maxSize: lane?.maxSize,\n workerQueue: new WorkerQueue()\n }));\n }\n\n private getWorkerQueue(size: number): WorkerQueue {\n // Find the first queue that can handle the given size\n // or fallback to the last queue for largest files\n const queueForSize = this.workerQueues.find((queue) =>\n queue.maxSize >= size\n );\n\n return queueForSize?.workerQueue ?? this.workerQueues[this.workerQueues.length - 1].workerQueue;\n }\n\n private async enqueueTask({ data, taskType, format = DEFAULT_COLLECTION_FORMAT }: { data: any; taskType: 'parse' | 'stringify'; format?: CollectionFormat }): Promise<any> {\n const size = getSize(data);\n const workerQueue = this.getWorkerQueue(size);\n const workerScriptPath = path.join(__dirname, './workers/worker-script.js');\n\n return workerQueue.enqueue({\n data: { data, format },\n priority: size,\n scriptPath: workerScriptPath,\n taskType\n });\n }\n\n async parseRequest(data: any, format: CollectionFormat = DEFAULT_COLLECTION_FORMAT): Promise<any> {\n return this.enqueueTask({ data, taskType: 'parse', format });\n }\n\n async stringifyRequest(data: any, format: CollectionFormat = DEFAULT_COLLECTION_FORMAT): Promise<any> {\n return this.enqueueTask({ data, taskType: 'stringify', format });\n }\n\n async cleanup(): Promise<void> {\n const cleanupPromises = this.workerQueues.map(({ workerQueue }) =>\n workerQueue.cleanup()\n );\n await Promise.allSettled(cleanupPromises);\n }\n}\n\nexport default BruParserWorker;\n","/**\n * Parses a .bru file and extracts body content while redacting it from the main content\n * @param {string} bruFileContent - The raw content of the .bru file\n * @returns {Object} Object containing redacted file content and extracted body data\n */\nexport const bruRequestParseAndRedactBodyData = (bruFileContent: string) => {\n try {\n // Define the patterns that indicate the start of different body types\n const bodyTypePatterns = [\n 'body:json {',\n 'body:text {',\n 'body:xml {',\n 'body:sparql {',\n 'body:graphql {'\n ];\n\n // Normalize line endings to LF\n bruFileContent = (bruFileContent || '').replace(/\\r\\n/g, '\\n');\n\n const EOL = `\\n`;\n\n /**\n * Removes the leading 2-space indentation from each line of a string\n * @param {string} indentedString - The string with leading spaces to remove\n * @returns {string} The string with indentation removed\n */\n const removeLeadingIndentation = (indentedString: string) => {\n if (!indentedString || !indentedString.length) {\n return indentedString || '';\n }\n\n return indentedString\n .split(EOL)\n .map((line) => line.replace(/^ /, ''))\n .join(EOL);\n };\n\n // Split the file content into blocks\n let fileContentBlocks = bruFileContent.split(`${EOL}}${EOL}`);\n fileContentBlocks = fileContentBlocks.filter(Boolean).map((_) => _.trim());\n\n // Extract body blocks and their content\n const extractedBodyBlocks = fileContentBlocks\n .filter((block) => bodyTypePatterns.some((pattern) => block.startsWith(pattern)))\n .reduce((bodyContentMap: Record<string, string>, bodyBlock) => {\n // Extract the body type (json, text, xml, etc.) from the first line\n const firstLine = bodyBlock.split(EOL)[0];\n const bodyType = firstLine.split(`body:`)[1].split(/\\s/)[0];\n\n // Extract the body content (everything between the opening and closing braces)\n const bodyContentLines = bodyBlock.split(EOL).slice(1);\n const rawBodyContent = bodyContentLines.join(EOL);\n\n // Remove indentation from the body content\n const cleanBodyContent = removeLeadingIndentation(rawBodyContent);\n\n bodyContentMap[bodyType] = cleanBodyContent;\n return bodyContentMap;\n }, {});\n\n // Filter out body blocks to get the remaining file content\n const fileContentWithoutBodyBlocks = fileContentBlocks.filter((block) =>\n !bodyTypePatterns.some((pattern) => block.startsWith(pattern))\n );\n\n return {\n bruFileStringWithRedactedBody: fileContentWithoutBodyBlocks.join(`${EOL}}${EOL}${EOL}`).concat(`${EOL}}${EOL}`),\n extractedBodyContent: extractedBodyBlocks\n };\n } catch (error) {\n console.error('Error parsing and redacting body data:', error);\n return {\n bruFileStringWithRedactedBody: bruFileContent,\n extractedBodyContent: {}\n };\n }\n};\n","import { createHash } from 'node:crypto';\nimport { outdentString } from '@usebruno/lang';\n\nexport interface RedactedBlock {\n token: string;\n value: string;\n}\n\nexport interface RedactionResult {\n skeleton: string;\n blocks: RedactedBlock[];\n}\n\nconst BLOCK_TAGS = [\n 'body:graphql:vars',\n 'body:graphql',\n 'body:json',\n 'body:text',\n 'body:xml',\n 'body:sparql',\n 'script:pre-request',\n 'script:post-response',\n 'tests',\n 'docs',\n 'body'\n];\n\nconst BLOCK_OPENING = new RegExp(`^(${BLOCK_TAGS.join('|')})[ \\\\t]*\\\\{\\\\r?$`);\n\nconst isOpening = (line: string): boolean => BLOCK_OPENING.test(line);\n\n// A top-level block's closing brace sits at column 0; braces inside the content are indented, so\n// nested braces are correctly treated as content rather than ending the block early.\nconst isClosing = (line: string): boolean => line.startsWith('}');\n\nconst tokenFor = (content: string): string => {\n const hash = createHash('sha256').update(content).digest('hex').slice(0, 16);\n return `__BRU_REDACTED_TEXT_BLOCK_${hash}__`;\n};\n\nconst blockValue = (content: string[]): string =>\n outdentString(content.join('\\n').replace(/^(?:\\r?\\n)+/, '').replace(/\\r$/, ''));\n\nexport const redactLargeBruTextBlocks = (content: string): RedactionResult => {\n const source = content || '';\n const skeleton: string[] = [];\n const blocks: RedactedBlock[] = [];\n\n let openTag: string | null = null;\n let openContent: string[] = [];\n\n for (const line of source.split('\\n')) {\n if (openTag === null && isOpening(line)) {\n openTag = line;\n openContent = [];\n continue;\n }\n\n if (openTag !== null && isClosing(line)) {\n const token = tokenFor(openContent.join('\\n'));\n blocks.push({ token, value: blockValue(openContent) });\n skeleton.push(openTag, ` ${token}`, line);\n openTag = null;\n continue;\n }\n\n (openTag === null ? skeleton : openContent).push(line);\n }\n\n if (openTag !== null) {\n skeleton.push(openTag, ...openContent);\n }\n\n if (blocks.some((block) => source.includes(block.token))) {\n console.warn('[bruno-filestore] Token collision detected; skipping redaction');\n return { skeleton: source, blocks: [] };\n }\n\n return { skeleton: skeleton.join('\\n'), blocks };\n};\n\nexport const restoreRedactedBlocks = <T>(parsed: T, blocks: RedactedBlock[]): T => {\n if (!blocks.length) {\n return parsed;\n }\n\n const valueByToken = new Map(blocks.map((block) => [block.token, block.value]));\n\n const walk = (node: any): any => {\n if (typeof node === 'string') {\n return valueByToken.get(node) ?? node;\n }\n if (node && typeof node === 'object') {\n for (const key of Object.keys(node)) {\n node[key] = walk(node[key]);\n }\n }\n return node;\n };\n\n return walk(parsed);\n};\n","import type {\n Environment as BrunoEnvironment,\n ExternalSecrets as BrunoExternalSecrets,\n ExternalSecretProviderType,\n HashicorpVaultEnvironmentVariable,\n AwsSecretsManagerEnvironmentVariable,\n AzureKeyVaultEnvironmentVariable\n} from '@usebruno/schema-types/collection/environment';\nimport { uuid } from './index';\n\ntype LegacySecretsJsonSecret = {\n name?: string;\n path?: string;\n secretName?: string;\n vaultName?: string;\n enabled?: boolean;\n};\n\nexport interface SecretsJsonData {\n type?: string;\n data?: { environment: string; type?: string; secrets: LegacySecretsJsonSecret[] }[];\n cli?: { type?: string };\n}\n\nexport interface EnvironmentFileResult {\n name: string;\n environment: BrunoEnvironment;\n changed: boolean;\n}\n\n// secrets.json is the legacy format being migrated away from; its provider group lives in\n// `type` (`'vault' | 'aws-secrets-manager' | 'azure-key-vault'`). `'vault'` doesn't distinguish\n// cloud vs server — that split lives in the legacy `cli.type` (`vault-cloud`/`vault-server`).\n// Fall back to server when no cli config is present.\nconst resolveSecretProviderType = (\n secretsJsonData: SecretsJsonData\n): ExternalSecretProviderType | null => {\n const fileType = secretsJsonData?.type;\n if (fileType === 'aws-secrets-manager') return 'aws-secrets-manager';\n if (fileType === 'azure-key-vault') return 'azure-key-vault';\n if (fileType === 'vault') {\n return secretsJsonData?.cli?.type === 'vault-cloud' ? 'hashicorp-vault-cloud' : 'hashicorp-vault-server';\n }\n return null;\n};\n\n// Builds the environment's external-secrets group for the given provider type. Invalid/empty\n// secrets are filtered out; the group is still returned with an empty `variables` list so the\n// provider type lands on the environment even when it has no usable secrets.\nconst buildExternalSecrets = (\n secrets: LegacySecretsJsonSecret[] | undefined,\n type: ExternalSecretProviderType\n): BrunoExternalSecrets | null => {\n if (type === 'aws-secrets-manager') {\n const variables = (secrets || [])\n .filter((s) => s?.name && typeof s.secretName === 'string' && s.secretName.length > 0)\n .map((s): AwsSecretsManagerEnvironmentVariable => ({\n uid: uuid(),\n name: s.name as string,\n secretName: s.secretName as string,\n enabled: s.enabled !== false\n }));\n return { type, variables };\n }\n if (type === 'azure-key-vault') {\n const variables = (secrets || [])\n .filter((s) => s?.name && typeof s.vaultName === 'string' && s.vaultName.length > 0)\n .map((s): AzureKeyVaultEnvironmentVariable => ({\n uid: uuid(),\n name: s.name as string,\n vaultName: s.vaultName as string,\n enabled: s.enabled !== false\n }));\n return { type, variables };\n }\n if (type === 'hashicorp-vault-cloud' || type === 'hashicorp-vault-server') {\n const variables = (secrets || [])\n .filter((s) => s?.name && typeof s.path === 'string' && s.path.length > 0)\n .map((s): HashicorpVaultEnvironmentVariable => ({\n uid: uuid(),\n name: s.name as string,\n path: s.path as string,\n enabled: s.enabled !== false\n }));\n return { type, variables };\n }\n return null;\n};\n\n/**\n * Applies the secrets.json provider `type` to every environment's `externalSecrets`, moving each\n * environment's matching secrets onto it. The provider type lands on every environment that\n * doesn't already have `externalSecrets` — including ones with no matching secrets.json entry or\n * only invalid secrets (those get the type with an empty `variables` list). Environments that\n * already carry `externalSecrets` are returned unchanged, as is everything when no provider type\n * can be resolved. Format-agnostic and pure; file IO is the caller's responsibility.\n */\nexport const migrateSecretsJsonToEnvironments = ({\n secretsJsonData,\n environments\n}: {\n secretsJsonData: SecretsJsonData;\n environments: BrunoEnvironment[];\n}): EnvironmentFileResult[] => {\n const secretProviderType = resolveSecretProviderType(secretsJsonData);\n\n return environments.map((environment) => {\n const unchanged = { name: environment.name, environment, changed: false };\n\n if (environment.externalSecrets || !secretProviderType) {\n return unchanged;\n }\n\n const entry = secretsJsonData?.data?.find((d) => d?.environment === environment.name);\n const externalSecrets = buildExternalSecrets(entry?.secrets, secretProviderType);\n if (!externalSecrets) {\n return unchanged;\n }\n\n return {\n name: environment.name,\n environment: {\n ...environment,\n externalSecrets\n },\n changed: true\n };\n });\n};\n","import type { BrunoCollection, BrunoItem, BrunoEnvironment } from '@usebruno/schema-types';\n\nimport {\n parseBruRequest,\n parseBruCollection,\n parseBruEnvironment,\n stringifyBruRequest,\n stringifyBruCollection,\n stringifyBruEnvironment\n} from './formats/bru';\nimport {\n parseYmlItem,\n parseYmlCollection,\n parseYmlFolder,\n parseYmlEnvironment,\n stringifyYmlItem,\n stringifyYmlFolder,\n stringifyYmlCollection,\n stringifyYmlEnvironment\n} from './formats/yml';\nimport { dotenvToJson } from '@usebruno/lang';\nimport BruParserWorker from './workers';\nimport {\n ParseOptions,\n StringifyOptions,\n CollectionFormat\n} from './types';\nimport { DEFAULT_COLLECTION_FORMAT } from './constants';\nimport { bruRequestParseAndRedactBodyData } from './formats/bru/utils/request-parse-and-redact-body-data';\nimport { redactLargeBruTextBlocks, restoreRedactedBlocks } from './formats/bru/utils/redact-large-text-blocks';\n\n// request\nexport const parseRequest = (content: string, options: ParseOptions = { format: DEFAULT_COLLECTION_FORMAT }): any => {\n if (options.format === 'bru') {\n return parseBruRequest(content);\n } else if (options.format === 'yml') {\n return parseYmlItem(content);\n }\n throw new Error(`Unsupported format: ${options.format}`);\n};\n\nexport const parseRequestAndRedactBody = (content: string, options: ParseOptions = { format: 'bru' }): any => {\n if (options.format === 'bru') {\n return bruRequestParseAndRedactBodyData(content);\n }\n throw new Error(`Unsupported format: ${options.format}`);\n};\n\nexport const stringifyRequest = (requestObj: BrunoItem, options: StringifyOptions = { format: DEFAULT_COLLECTION_FORMAT }): string => {\n if (options.format === 'bru') {\n return stringifyBruRequest(requestObj);\n } else if (options.format === 'yml') {\n return stringifyYmlItem(requestObj);\n }\n throw new Error(`Unsupported format: ${options.format}`);\n};\n\n// request via worker\nlet globalWorkerInstance: BruParserWorker | null = null;\nconst getWorkerInstance = (): BruParserWorker => {\n if (!globalWorkerInstance) {\n globalWorkerInstance = new BruParserWorker();\n }\n return globalWorkerInstance;\n};\n\nexport const parseRequestViaWorker = async (content: string, options: { format: CollectionFormat; filename?: string }): Promise<any> => {\n const fileParserWorker = getWorkerInstance();\n\n return await fileParserWorker.parseRequest(content, options.format);\n};\n\nexport const stringifyRequestViaWorker = async (requestObj: any, options: { format: CollectionFormat }): Promise<string> => {\n const fileParserWorker = getWorkerInstance();\n return await fileParserWorker.stringifyRequest(requestObj, options.format);\n};\n\n// collection\nexport const parseCollection = (content: string, options: ParseOptions = { format: DEFAULT_COLLECTION_FORMAT }): any => {\n if (options.format === 'bru') {\n return parseBruCollection(content);\n } else if (options.format === 'yml') {\n return parseYmlCollection(content);\n }\n throw new Error(`Unsupported format: ${options.format}`);\n};\n\nexport const stringifyCollection = (collectionObj: BrunoCollection, brunoConfig: any, options: StringifyOptions = { format: DEFAULT_COLLECTION_FORMAT }): string => {\n if (options.format === 'bru') {\n return stringifyBruCollection(collectionObj, false);\n } else if (options.format === 'yml') {\n return stringifyYmlCollection(collectionObj, brunoConfig);\n }\n throw new Error(`Unsupported format: ${options.format}`);\n};\n\n// folder\nexport const parseFolder = (content: string, options: ParseOptions = { format: DEFAULT_COLLECTION_FORMAT }): any => {\n if (options.format === 'bru') {\n return parseBruCollection(content);\n } else if (options.format === 'yml') {\n return parseYmlFolder(content);\n }\n throw new Error(`Unsupported format: ${options.format}`);\n};\n\nexport const stringifyFolder = (folderObj: any, options: StringifyOptions = { format: DEFAULT_COLLECTION_FORMAT }): string => {\n if (options.format === 'bru') {\n return stringifyBruCollection(folderObj, true);\n } else if (options.format === 'yml') {\n return stringifyYmlFolder(folderObj);\n }\n throw new Error(`Unsupported format: ${options.format}`);\n};\n\n// environment\nexport const parseEnvironment = (content: string, options: ParseOptions = { format: DEFAULT_COLLECTION_FORMAT }): any => {\n if (options.format === 'bru') {\n return parseBruEnvironment(content);\n } else if (options.format === 'yml') {\n return parseYmlEnvironment(content);\n }\n throw new Error(`Unsupported format: ${options.format}`);\n};\n\nexport const stringifyEnvironment = (envObj: BrunoEnvironment, options: StringifyOptions = { format: DEFAULT_COLLECTION_FORMAT }): string => {\n if (options.format === 'bru') {\n return stringifyBruEnvironment(envObj);\n } else if (options.format === 'yml') {\n return stringifyYmlEnvironment(envObj);\n }\n throw new Error(`Unsupported format: ${options.format}`);\n};\n\nexport const parseDotEnv = (content: string): Record<string, string> => {\n return dotenvToJson(content);\n};\n\nexport { redactLargeBruTextBlocks, restoreRedactedBlocks };\nexport type { RedactedBlock, RedactionResult } from './formats/bru/utils/redact-large-text-blocks';\nexport { migrateSecretsJsonToEnvironments } from './utils/secretsJsonToEnvironments';\n\nexport { BruParserWorker };\nexport * from './types';\nexport * from './constants';\n","import type { OpenCollection } from '@opencollection/types';\nimport type { FolderRoot } from '@usebruno/schema-types/collection/folder';\nimport { parseYml } from './utils';\nimport { toBrunoAuth } from './common/auth';\nimport { toBrunoHttpHeaders } from './common/headers';\nimport { toBrunoVariables } from './common/variables';\nimport { toBrunoPostResponseVariables } from './common/actions';\nimport { toBrunoScripts } from './common/scripts';\nimport { ensureString } from '../../utils';\nimport type { BrunoPresetsExtension } from '../../types';\n\ninterface ParsedCollection {\n collectionRoot: FolderRoot;\n brunoConfig: Record<string, any>;\n}\n\nconst parseCollection = (ymlString: string): ParsedCollection => {\n try {\n const oc: OpenCollection = parseYml(ymlString);\n\n // bruno config\n const brunoConfig: Record<string, any> = {\n opencollection: oc.opencollection || '1.0.0',\n name: ensureString(oc.info?.name, 'Untitled Collection'),\n type: 'collection',\n ignore: []\n };\n\n if (oc.info?.version != null && oc.info.version !== '') {\n brunoConfig.version = ensureString(oc.info.version, '');\n }\n\n const brunoExtension = (oc.extensions as any)?.bruno;\n if (brunoExtension?.ignore && Array.isArray(brunoExtension.ignore)) {\n brunoConfig.ignore = brunoExtension.ignore;\n }\n\n // presets\n if (brunoExtension?.presets) {\n const presets = brunoExtension.presets as BrunoPresetsExtension;\n if (presets.request) {\n brunoConfig.presets = {\n requestType: presets.request.type || '',\n requestUrl: presets.request.url || ''\n };\n }\n }\n\n // bruno-specific extensions\n const brunoExtensions = oc.extensions?.bruno as any;\n if (Array.isArray(brunoExtensions?.scripts?.additionalContextRoots)) {\n const sanitizedRoots = brunoExtensions.scripts.additionalContextRoots\n .filter((item: any) => typeof item === 'string');\n\n if (sanitizedRoots.length > 0) {\n brunoConfig.scripts = {\n ...brunoConfig.scripts,\n additionalContextRoots: sanitizedRoots\n };\n }\n }\n if (Array.isArray(brunoExtensions?.openapi) && brunoExtensions.openapi.length > 0) {\n brunoConfig.openapi = brunoExtensions.openapi.map((entry: any) => ({\n sourceUrl: entry.sourceUrl,\n groupBy: entry.groupBy,\n ...(entry.lastSyncDate && { lastSyncDate: entry.lastSyncDate }),\n ...(entry.specHash && { specHash: entry.specHash }),\n autoCheck: entry.autoCheck !== false,\n autoCheckInterval: entry.autoCheckInterval || 5\n }));\n }\n\n // protobuf\n if (oc.config?.protobuf) {\n brunoConfig.protobuf = {\n protoFiles: oc.config.protobuf.protoFiles?.map((protoFile: any) => ({\n path: protoFile.path\n })) || [],\n importPaths: oc.config.protobuf.importPaths?.map((importPath: any) => ({\n path: importPath.path,\n enabled: importPath.disabled !== true\n })) || []\n };\n }\n\n // proxy - only support newer format\n // Default: inherit from global preferences\n brunoConfig.proxy = {\n inherit: true,\n config: {\n protocol: 'http',\n hostname: '',\n port: '',\n auth: {\n username: '',\n password: ''\n },\n bypassProxy: ''\n }\n };\n\n if (oc.config?.proxy && typeof oc.config.proxy === 'object') {\n // Validate newer format: must have 'inherit' and 'config' properties\n const proxyConfig = oc.config.proxy as any;\n\n if ('inherit' in proxyConfig && typeof proxyConfig.inherit === 'boolean' && proxyConfig.config && typeof proxyConfig.config === 'object') {\n // Valid newer format\n brunoConfig.proxy = {\n inherit: proxyConfig.inherit,\n config: {\n protocol: proxyConfig.config.protocol || 'http',\n hostname: proxyConfig.config.hostname || '',\n port: proxyConfig.config.port || '',\n auth: {\n username: proxyConfig.config.auth?.username || '',\n password: proxyConfig.config.auth?.password || ''\n },\n bypassProxy: proxyConfig.config.bypassProxy || ''\n }\n };\n\n // Handle optional disabled field\n if (proxyConfig.disabled === true) {\n brunoConfig.proxy.disabled = true;\n }\n\n // Handle optional auth.disabled field\n if (proxyConfig.config.auth?.disabled === true) {\n brunoConfig.proxy.config.auth.disabled = true;\n }\n }\n // If not in newer format, use default (inherit: true)\n }\n\n // client certificates\n if (oc.config?.clientCertificates?.length) {\n brunoConfig.clientCertificates = {\n certs: oc.config.clientCertificates.map((cert: any) => {\n if (cert.type === 'pem') {\n return {\n domain: cert.domain,\n type: 'cert',\n certFilePath: cert.certificateFilePath,\n keyFilePath: cert.privateKeyFilePath,\n passphrase: cert.passphrase || ''\n };\n } else if (cert.type === 'pkcs12') {\n return {\n domain: cert.domain,\n type: 'pfx',\n pfxFilePath: cert.pkcs12FilePath,\n passphrase: cert.passphrase || ''\n };\n }\n return null;\n }).filter((cert: any) => cert !== null)\n };\n }\n\n // collection root\n const collectionRoot: FolderRoot = {\n meta: null,\n request: null,\n docs: null\n };\n\n // request defaults\n if (oc.request) {\n collectionRoot.request = {\n headers: null,\n auth: null,\n script: {\n req: null,\n res: null\n },\n vars: {\n req: [],\n res: []\n },\n tests: null\n };\n\n // headers\n const headers = toBrunoHttpHeaders(oc.request.headers);\n collectionRoot.request.headers = headers || [];\n\n // auth\n const auth = toBrunoAuth(oc.request.auth);\n if (auth) {\n collectionRoot.request.auth = auth;\n }\n\n // variables\n const variables = toBrunoVariables(oc.request.variables);\n const postResponseVars = toBrunoPostResponseVariables((oc.request as any).actions);\n collectionRoot.request.vars = {\n req: variables.req,\n res: postResponseVars\n };\n\n // scripts\n const scripts = toBrunoScripts(oc.request.scripts);\n if (scripts?.script && collectionRoot.request.script) {\n if (scripts.script.req) {\n collectionRoot.request.script.req = scripts.script.req;\n }\n if (scripts.script.res) {\n collectionRoot.request.script.res = scripts.script.res;\n }\n }\n if (scripts?.tests) {\n collectionRoot.request.tests = scripts.tests;\n }\n }\n\n // docs\n if (oc.docs) {\n if (typeof oc.docs === 'string') {\n collectionRoot.docs = oc.docs;\n } else if (typeof oc.docs === 'object' && oc.docs.content) {\n collectionRoot.docs = oc.docs.content;\n }\n }\n\n return {\n collectionRoot,\n brunoConfig\n };\n } catch (error) {\n console.error('Error parsing collection:', error);\n throw error;\n }\n};\n\nexport default parseCollection;\n","import type { FolderRoot } from '@usebruno/schema-types/collection/folder';\nimport type { Folder } from '@opencollection/types/collection/item';\nimport { parseYml } from './utils';\nimport { toBrunoAuth } from './common/auth';\nimport { toBrunoHttpHeaders } from './common/headers';\nimport { toBrunoVariables } from './common/variables';\nimport { toBrunoPostResponseVariables } from './common/actions';\nimport { toBrunoScripts } from './common/scripts';\nimport { ensureString } from '../../utils';\n\nconst parseFolder = (ymlString: string): FolderRoot => {\n try {\n const ocFolder: Folder = parseYml(ymlString);\n\n const info = ocFolder.info;\n\n const folderRoot: FolderRoot = {\n meta: {\n name: ensureString(info?.name, 'Untitled Folder'),\n seq: info?.seq || 1\n },\n request: {\n headers: [],\n auth: toBrunoAuth(ocFolder.request?.auth),\n script: {\n req: null,\n res: null\n },\n vars: {\n req: [],\n res: []\n },\n tests: null\n },\n docs: null\n };\n\n if (ocFolder.request) {\n const folderRequest = folderRoot.request!;\n\n // headers\n const headers = toBrunoHttpHeaders(ocFolder.request.headers);\n if (headers) {\n folderRequest.headers = headers;\n }\n\n // variables\n const variables = toBrunoVariables(ocFolder.request.variables);\n const postResponseVars = toBrunoPostResponseVariables((ocFolder.request as any).actions);\n folderRequest.vars = {\n req: variables.req,\n res: postResponseVars\n };\n\n // scripts\n const scripts = toBrunoScripts(ocFolder.request.scripts);\n if (scripts?.script && folderRequest.script) {\n if (scripts.script.req) {\n folderRequest.script.req = scripts.script.req;\n }\n if (scripts.script.res) {\n folderRequest.script.res = scripts.script.res;\n }\n }\n if (scripts?.tests) {\n folderRequest.tests = scripts.tests;\n }\n }\n\n // docs (now at root level)\n if (ocFolder.docs) {\n if (typeof ocFolder.docs === 'string' && ocFolder.docs.trim().length) {\n folderRoot.docs = ocFolder.docs;\n } else if (typeof ocFolder.docs === 'object' && ocFolder.docs.content?.trim().length) {\n folderRoot.docs = ocFolder.docs.content;\n }\n }\n\n return folderRoot;\n } catch (error) {\n console.error('Error parsing folder:', error);\n throw error;\n }\n};\n\nexport default parseFolder;\n"],"names":["PARAMETER_MAPPINGS","type","sendIn","source","mapParametersFromSource","sourceParams","length","map","param","collectParametersForType","json","grantType","shouldIncludeParameterType","relevantMappings","filter","mapping","allParams","mappedParams","push","getOauth2AdditionalParameters","auth","oauth2","additionalParameters","parameterTypes","params","error","console","customAlphabet","require","isString","value","isNumber","isNonEmptyString","trim","ensureString","fallback","String","uuid","customNanoId","parseBruCollection","data","parsed","_collectionBruToJson","transformedJson","request","headers","_","get","script","vars","tests","settings","docs","meta","name","undefined","seq","sequence","isNaN","Number","hasOauth2GrantType","Object","keys","Promise","reject","stringifyBruCollection","isFolder","collectionBruJson","req","res","_jsonToCollectionBru","bruExampleToJson","parentType","parentMethod","bruToJsonV2","requestType","requestMethod","transformedType","status","statusText","description","method","url","body","mode","response","header","content","log","jsonExampleToBru","BLOCK_KEYS","stringifyYml","obj","lines","YAML","stringify","lineWidth","indent","minContentWidth","defaultStringType","split","result","i","line","startsWith","key","includes","join","parseYml","ymlString","parse","normalizeBoolean","mapAdditionalParameters","Array","isArray","mapped","placement","toLowerCase","mapSendIn","mappedParam","Boolean","buildClientCredentials","oauth","credentials","clientId","clientSecret","credentialsPlacement","buildTokenConfig","tokenConfig","credentialsId","id","tokenPlacement","tokenHeaderPrefix","query","tokenQueryKey","tokenSource","buildSettings","autoFetchToken","autoRefreshToken","buildResourceOwnerPasswordFlow","flow","accessTokenUrl","refreshTokenUrl","resourceOwner","username","password","buildResourceOwner","scope","accessTokenRequest","token","refreshTokenRequest","refresh","toOpenCollectionOAuth2","buildClientCredentialsFlow","authorizationUrl","callbackUrl","authorizationRequest","authorization","state","pkce","disabled","buildPkce","buildAuthorizationCodeFlow","buildImplicitFlow","warn","reverseAdditionalParameters","reversePlacementMapping","enabled","toOpenCollectionAuth","config","accessKeyId","secretAccessKey","sessionToken","service","region","profileName","buildAwsV4Auth","awsv4","buildBasicAuth","basic","buildBearerAuth","bearer","buildDigestAuth","digest","domain","buildNtlmAuth","ntlm","buildWsseAuth","wsse","buildApiKeyAuth","apikey","consumerKey","consumerSecret","accessToken","accessTokenSecret","verifier","signatureMethod","privateKey","privateKeyType","timestamp","nonce","version","realm","includeBodyHash","buildOAuth1Auth","oauth1","clientToken","baseURL","headersToSign","maxBodySize","buildEdgeGridAuth","akamaiEdgegrid","toBrunoAuth","brunoAuth","edgegrid","brunoOAuth","tempParams","tokenParams","refreshParams","authParams","authCodeFlow","toBrunoOAuth2","toOpenCollectionHttpHeaders","ocHeaders","httpHeader","toBrunoHttpHeaders","brunoHeaders","brunoHeader","uid","toOpenCollectionParams","ocParams","ocParam","toBrunoParams","brunoParams","brunoParam","toOpenCollectionBody","text","xml","sparql","formEntries","formUrlEncoded","entry","formEntry","multipartEntries","multipartForm","multipartEntry","contentType","fileEntries","file","fileEntry","filePath","selected","toBrunoBody","graphql","brunoBody","fileWithDescription","desc","serializeVariableValue","JSON","valueToString","isTypedValue","hasTypedMetadata","v","dataType","toOpenCollectionTypedValue","dataStr","fromOpenCollectionTypedValue","typed","isBrunoVariableDataType","parseValueByDataType","toOpenCollectionVariables","variables","reqVars","reqVarsArray","ocVariables","valueStr","variable","toBrunoVariables","forEach","base","local","assign","toOpenCollectionActions","resVariables","actions","action","phase","selector","expression","toBrunoPostResponseVariables","resVars","setVarAction","toOpenCollectionScripts","ocScripts","code","toBrunoScripts","scripts","brunoScripts","OPERATORS","UNARY_OPERATORS","toOpenCollectionAssertions","assertions","ocAssertions","assertion","operator","str","firstWord","rest","remainingValue","parseAssertionOperator","ocAssertion","toBrunoAssertions","brunoAssertions","valueString","brunoAssertion","toBrunoGrpcMetadata","metadata","brunoMetadata","brunoMeta","parseItem","ocItem","parsedItemYml","itemType","info","runtime","http","grpc","websocket","ensureAuthV3Rc1BackwardsCompatibility","item","Error","ocRequest","brunoRequest","postResponseVars","app","toBrunoApp","brunoItem","tags","fileContent","root","items","examples","filename","pathname","encodeUrl","timeout","followRedirects","maxRedirects","example","brunoExample","itemUid","parseHttpRequest","parseGraphQLRequest","methodType","protoPath","protoFilePath","rawMessage","message","title","index","parseGrpcRequest","ws","variants","variant","messageData","wsSettings","keepAliveInterval","parseWebsocketRequest","ocScript","ocApp","parseApp","DEFAULT_COLLECTION_FORMAT","SECRET_PROVIDER_IDENTIFIER_FIELDS","parseEnvironment","ocEnvironment","brunoEnvironment","secret","isSecretVariable","color","externalSecrets","identifierField","toBrunoExternalSecrets","stringifyItem","hasRuntime","httpSettings","ocExample","exampleHeaders","exampleParams","exampleBody","statusNum","isInteger","responseHeaders","toOpenCollectionResponseHeaders","contentString","toOpenCollectionApp","stringifyHttpRequest","graphqlBody","hasBody","stringifyGraphqlRequest","metadataItem","messages","stringifyGrpcRequest","hasCustomName","hasContent","msg","stringifyWebsocketRequest","stringifyScript","stringifyApp","hasRequestAuth","folderRoot","hasRequestScripts","stringifyFolder","ocFolder","requestDefaults","hasRequestDefaults","ocAuth","ocActions","collectionRoot","reqAuthMode","hasPresets","brunoConfig","presets","requestUrl","stringifyCollection","oc","hasProtobuf","protobuf","protoFiles","importPaths","hasProxy","proxy","hasClientCertificates","clientCertificates","certs","hasCollectionConfig","protoFile","path","importPath","inherit","protocol","hostname","port","bypassProxy","cert","certificateFilePath","certFilePath","privateKeyFilePath","keyFilePath","passphrase","pkcs12FilePath","pfxFilePath","requestRoot","bundled","extensions","ignore","brunoExtension","ignoreList","presetsRequest","bruno","additionalContextRoots","openapi","sourceUrl","groupBy","lastSyncDate","specHash","autoCheck","autoCheckInterval","stringifyEnvironment","environment","secretVar","toOpenCollectionEnvironmentVariables","ocExternalSecrets","toOpenCollectionExternalSecrets","WorkerQueue","constructor","this","queue","isProcessing","workers","getWorkerForScriptPath","scriptPath","worker","threadId","Worker","enqueue","task","priority","taskType","resolve","sort","taskX","taskY","processQueue","shift","runWorker","async","messageHandler","off","errorHandler","exitHandler","on","postMessage","cleanup","promises","values","terminate","allSettled","LANES","maxSize","BruParserWorker","workerQueues","lane","workerQueue","getWorkerQueue","size","queueForSize","find","enqueueTask","format","Buffer","byteLength","getSize","workerScriptPath","__dirname","parseRequest","stringifyRequest","cleanupPromises","BLOCK_OPENING","RegExp","isOpening","test","isClosing","tokenFor","createHash","update","slice","blockValue","outdentString","replace","redactLargeBruTextBlocks","skeleton","blocks","openTag","openContent","some","block","restoreRedactedBlocks","valueByToken","Map","walk","node","migrateSecretsJsonToEnvironments","secretsJsonData","environments","secretProviderType","fileType","cli","resolveSecretProviderType","unchanged","changed","d","secrets","s","secretName","vaultName","buildExternalSecrets","options","urlPath","default","appData","toUpperCase","e","selectedMethodType","parseBruRequest","parseYmlItem","parseRequestAndRedactBody","bruFileContent","bodyTypePatterns","EOL","removeLeadingIndentation","indentedString","fileContentBlocks","extractedBodyBlocks","pattern","reduce","bodyContentMap","bodyBlock","bodyType","rawBodyContent","cleanBodyContent","bruFileStringWithRedactedBody","concat","extractedBodyContent","bruRequestParseAndRedactBodyData","requestObj","bruJson","jsonToBruV2","stringifyBruRequest","stringifyYmlItem","globalWorkerInstance","getWorkerInstance","parseRequestViaWorker","fileParserWorker","stringifyRequestViaWorker","parseCollection","opencollection","brunoExtensions","sanitizedRoots","proxyConfig","parseYmlCollection","collectionObj","stringifyYmlCollection","parseFolder","folderRequest","parseYmlFolder","folderObj","stringifyYmlFolder","bru","bruToEnvJsonV2","each","parseBruEnvironment","parseYmlEnvironment","envObj","envJsonToBruV2","stringifyBruEnvironment","stringifyYmlEnvironment","parseDotEnv","dotenvToJson"],"mappings":"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"}
|