@usebruno/filestore 0.10.0 → 0.12.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/index.d.ts +3 -1
- package/dist/formats/yml/index.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/mockServerTypes.d.ts +95 -0
- package/dist/formats/yml/mockServerTypes.d.ts.map +1 -0
- 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/parseMockServer.d.ts +4 -0
- package/dist/formats/yml/parseMockServer.d.ts.map +1 -0
- 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/stringifyFolder.d.ts.map +1 -1
- package/dist/formats/yml/stringifyItem.d.ts.map +1 -1
- package/dist/formats/yml/stringifyMockServer.d.ts +4 -0
- package/dist/formats/yml/stringifyMockServer.d.ts.map +1 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/types.d.ts +7 -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/dist/workers/WorkerQueue/index.d.ts +3 -2
- package/dist/workers/WorkerQueue/index.d.ts.map +1 -1
- package/dist/workers/index.d.ts +4 -0
- package/dist/workers/index.d.ts.map +1 -1
- package/package.json +7 -5
- package/src/constants.ts +13 -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 +472 -0
- package/src/formats/bru/utils/redact-large-text-blocks.ts +143 -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/index.ts +5 -1
- package/src/formats/yml/items/parseApp.ts +37 -0
- package/src/formats/yml/items/parseGraphQLRequest.ts +14 -16
- package/src/formats/yml/items/parseGrpcRequest.ts +24 -3
- package/src/formats/yml/items/parseHttpRequest.ts +19 -16
- 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 +7 -6
- package/src/formats/yml/items/stringifyGrpcRequest.ts +9 -11
- package/src/formats/yml/items/stringifyHttpRequest.ts +14 -6
- package/src/formats/yml/items/stringifyWebsocketRequest.ts +22 -9
- package/src/formats/yml/mockServerTypes.ts +95 -0
- package/src/formats/yml/parseCollection.spec.ts +193 -0
- package/src/formats/yml/parseCollection.ts +24 -6
- package/src/formats/yml/parseEnvironment.spec.ts +99 -0
- package/src/formats/yml/parseEnvironment.ts +41 -19
- package/src/formats/yml/parseFolder.spec.ts +70 -0
- package/src/formats/yml/parseFolder.ts +19 -22
- package/src/formats/yml/parseItem.spec.ts +147 -0
- package/src/formats/yml/parseItem.ts +4 -0
- package/src/formats/yml/parseMockServer.spec.ts +180 -0
- package/src/formats/yml/parseMockServer.ts +113 -0
- package/src/formats/yml/stringifyCollection.spec.ts +223 -0
- package/src/formats/yml/stringifyCollection.ts +26 -9
- package/src/formats/yml/stringifyEnvironment.spec.ts +91 -0
- package/src/formats/yml/stringifyEnvironment.ts +55 -20
- package/src/formats/yml/stringifyFolder.spec.ts +70 -0
- package/src/formats/yml/stringifyFolder.ts +7 -2
- package/src/formats/yml/stringifyItem.spec.ts +53 -0
- package/src/formats/yml/stringifyItem.ts +4 -0
- package/src/formats/yml/stringifyMockServer.spec.ts +177 -0
- package/src/formats/yml/stringifyMockServer.ts +129 -0
- package/src/formats/yml/tests/defaultEnvironment.spec.js +50 -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 +230 -0
- package/src/formats/yml/tests/variables.spec.js +7 -7
- package/src/formats/yml/utils.ts +1 -1
- package/src/index.ts +39 -1
- package/src/types/bruno-lang.d.ts +1 -0
- package/src/types.ts +8 -0
- package/src/utils/secretsJsonToEnvironments.spec.ts +211 -0
- package/src/utils/secretsJsonToEnvironments.ts +129 -0
- package/src/workers/WorkerQueue/index.ts +10 -2
- package/src/workers/index.ts +25 -1
- package/src/workers/worker-script.ts +45 -21
- 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
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { toOpenCollectionVariables, toBrunoVariables } from './variables';
|
|
2
|
+
|
|
3
|
+
describe('toOpenCollectionVariables', () => {
|
|
4
|
+
it('returns undefined for null / empty input', () => {
|
|
5
|
+
expect(toOpenCollectionVariables(null)).toBeUndefined();
|
|
6
|
+
expect(toOpenCollectionVariables(undefined)).toBeUndefined();
|
|
7
|
+
expect(toOpenCollectionVariables([])).toBeUndefined();
|
|
8
|
+
expect(toOpenCollectionVariables({ req: [], res: [] })).toBeUndefined();
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
it('serializes plain string variables as a raw string value', () => {
|
|
12
|
+
const out = toOpenCollectionVariables([
|
|
13
|
+
{ uid: 'u1', name: 'apiKey', value: 'abc', enabled: true } as any
|
|
14
|
+
]);
|
|
15
|
+
|
|
16
|
+
expect(out).toEqual([{ name: 'apiKey', value: 'abc' }]);
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it('serializes typed variables as a {type, data} struct', () => {
|
|
20
|
+
const out = toOpenCollectionVariables([
|
|
21
|
+
{ uid: 'u1', name: 'port', value: 3000, enabled: true, dataType: 'number' } as any,
|
|
22
|
+
{ uid: 'u2', name: 'flag', value: true, enabled: true, dataType: 'boolean' } as any,
|
|
23
|
+
{ uid: 'u3', name: 'config', value: { a: 1 }, enabled: true, dataType: 'object' } as any
|
|
24
|
+
]);
|
|
25
|
+
|
|
26
|
+
expect(out).toEqual([
|
|
27
|
+
{ name: 'port', value: { type: 'number', data: '3000' } },
|
|
28
|
+
{ name: 'flag', value: { type: 'boolean', data: 'true' } },
|
|
29
|
+
{ name: 'config', value: { type: 'object', data: '{\n "a": 1\n}' } }
|
|
30
|
+
]);
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
it('does not emit a typed struct for the string default dataType', () => {
|
|
34
|
+
const out = toOpenCollectionVariables([
|
|
35
|
+
{ uid: 'u1', name: 'apiKey', value: 'abc', enabled: true, dataType: 'string' } as any
|
|
36
|
+
]);
|
|
37
|
+
|
|
38
|
+
expect(out).toEqual([{ name: 'apiKey', value: 'abc' }]);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it('marks disabled variables and preserves description', () => {
|
|
42
|
+
const out = toOpenCollectionVariables([
|
|
43
|
+
{ uid: 'u1', name: 'apiKey', value: 'abc', enabled: false, description: 'auth key' } as any
|
|
44
|
+
]);
|
|
45
|
+
|
|
46
|
+
expect(out).toEqual([
|
|
47
|
+
{ name: 'apiKey', value: 'abc', description: 'auth key', disabled: true }
|
|
48
|
+
]);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it('accepts the folder { req, res } shape and only emits req vars', () => {
|
|
52
|
+
const out = toOpenCollectionVariables({
|
|
53
|
+
req: [{ uid: 'u1', name: 'a', value: '1', enabled: true } as any],
|
|
54
|
+
res: [{ uid: 'u2', name: 'b', value: '2', enabled: true } as any]
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
expect(out).toEqual([{ name: 'a', value: '1' }]);
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
describe('toBrunoVariables', () => {
|
|
62
|
+
it('returns empty req/res for null / empty input', () => {
|
|
63
|
+
expect(toBrunoVariables(null)).toEqual({ req: [], res: [] });
|
|
64
|
+
expect(toBrunoVariables(undefined)).toEqual({ req: [], res: [] });
|
|
65
|
+
expect(toBrunoVariables([])).toEqual({ req: [], res: [] });
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
it('parses plain string variables into Bruno req vars', () => {
|
|
69
|
+
const { req } = toBrunoVariables([
|
|
70
|
+
{ name: 'apiKey', value: 'abc' } as any
|
|
71
|
+
]);
|
|
72
|
+
|
|
73
|
+
expect(req).toHaveLength(1);
|
|
74
|
+
const v = req![0];
|
|
75
|
+
expect(v).toMatchObject({
|
|
76
|
+
name: 'apiKey',
|
|
77
|
+
value: 'abc',
|
|
78
|
+
enabled: true,
|
|
79
|
+
local: false
|
|
80
|
+
});
|
|
81
|
+
expect(v.uid).toEqual(expect.any(String));
|
|
82
|
+
expect(v.dataType).toBeUndefined();
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
it('parses typed-value variables into typed Bruno variables', () => {
|
|
86
|
+
const { req } = toBrunoVariables([
|
|
87
|
+
{ name: 'port', value: { type: 'number', data: '3000' } } as any,
|
|
88
|
+
{ name: 'flag', value: { type: 'boolean', data: 'true' } } as any,
|
|
89
|
+
{ name: 'config', value: { type: 'object', data: '{"a":1}' } } as any
|
|
90
|
+
]);
|
|
91
|
+
|
|
92
|
+
expect(req![0]).toMatchObject({ name: 'port', value: 3000, dataType: 'number' });
|
|
93
|
+
expect(req![1]).toMatchObject({ name: 'flag', value: true, dataType: 'boolean' });
|
|
94
|
+
expect(req![2]).toMatchObject({ name: 'config', value: { a: 1 }, dataType: 'object' });
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
it('falls back to the raw string when typed data fails to coerce', () => {
|
|
98
|
+
const { req } = toBrunoVariables([
|
|
99
|
+
{ name: 'port', value: { type: 'number', data: 'not-a-number' } } as any,
|
|
100
|
+
{ name: 'flag', value: { type: 'boolean', data: 'not-a-boolean' } } as any,
|
|
101
|
+
{ name: 'config', value: { type: 'object', data: 'not-a-object' } } as any
|
|
102
|
+
]);
|
|
103
|
+
|
|
104
|
+
expect(req![0]).toMatchObject({ name: 'port', value: 'not-a-number', dataType: 'number' });
|
|
105
|
+
expect(typeof req![0].value).toBe('string');
|
|
106
|
+
expect(req![1]).toMatchObject({ name: 'flag', value: 'not-a-boolean', dataType: 'boolean' });
|
|
107
|
+
expect(typeof req![1].value).toBe('string');
|
|
108
|
+
expect(req![2]).toMatchObject({ name: 'config', value: 'not-a-object', dataType: 'object' });
|
|
109
|
+
expect(typeof req![2].value).toBe('string');
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
it('respects the disabled flag', () => {
|
|
113
|
+
const { req } = toBrunoVariables([
|
|
114
|
+
{ name: 'a', value: '1', disabled: true } as any
|
|
115
|
+
]);
|
|
116
|
+
|
|
117
|
+
expect(req![0].enabled).toBe(false);
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
it('extracts description.content when description is a structured object', () => {
|
|
121
|
+
const { req } = toBrunoVariables([
|
|
122
|
+
{ name: 'a', value: '1', description: { content: 'note' } } as any
|
|
123
|
+
]);
|
|
124
|
+
|
|
125
|
+
expect(req![0].description).toBe('note');
|
|
126
|
+
});
|
|
127
|
+
});
|
|
@@ -2,16 +2,13 @@ import { Variable, VariableTypedValue } from '@opencollection/types/common/varia
|
|
|
2
2
|
import { FolderRequest as BrunoFolderRequest } from '@usebruno/schema-types/collection/folder';
|
|
3
3
|
import { Variable as BrunoVariable, Variables as BrunoVariables } from '@usebruno/schema-types/common/variables';
|
|
4
4
|
import { uuid, ensureString } from '../../../utils';
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
&& 'data' in value
|
|
13
|
-
);
|
|
14
|
-
};
|
|
5
|
+
import {
|
|
6
|
+
isTypedValue,
|
|
7
|
+
hasTypedMetadata,
|
|
8
|
+
toOpenCollectionTypedValue,
|
|
9
|
+
fromOpenCollectionTypedValue,
|
|
10
|
+
serializeVariableValue
|
|
11
|
+
} from './datatype';
|
|
15
12
|
|
|
16
13
|
/**
|
|
17
14
|
* Convert Bruno pre-request variables to OpenCollection variables format.
|
|
@@ -29,12 +26,10 @@ export const toOpenCollectionVariables = (variables: BrunoFolderRequest['vars']
|
|
|
29
26
|
}
|
|
30
27
|
|
|
31
28
|
const ocVariables: Variable[] = reqVarsArray.map((v: BrunoVariable): Variable => {
|
|
29
|
+
const valueStr = serializeVariableValue(v.value);
|
|
32
30
|
const variable: Variable = {
|
|
33
31
|
name: v.name || '',
|
|
34
|
-
value:
|
|
35
|
-
v.datatype && v.datatype !== 'string'
|
|
36
|
-
? { type: v.datatype, data: ensureString(v.value) }
|
|
37
|
-
: v.value || ''
|
|
32
|
+
value: hasTypedMetadata(v) ? toOpenCollectionTypedValue(v, valueStr) : valueStr
|
|
38
33
|
};
|
|
39
34
|
|
|
40
35
|
if (v?.description?.trim().length) {
|
|
@@ -62,7 +57,7 @@ export const toBrunoVariables = (variables: Variable[] | null | undefined): { re
|
|
|
62
57
|
const reqVars: BrunoVariables = [];
|
|
63
58
|
|
|
64
59
|
variables.forEach((v: Variable) => {
|
|
65
|
-
const
|
|
60
|
+
const base: BrunoVariable = {
|
|
66
61
|
uid: uuid(),
|
|
67
62
|
name: ensureString(v.name),
|
|
68
63
|
value: '',
|
|
@@ -71,19 +66,16 @@ export const toBrunoVariables = (variables: Variable[] | null | undefined): { re
|
|
|
71
66
|
};
|
|
72
67
|
|
|
73
68
|
if (isTypedValue(v.value)) {
|
|
74
|
-
|
|
75
|
-
if (v.value.type !== 'string' && v.value.type !== 'null') {
|
|
76
|
-
variable.datatype = v.value.type;
|
|
77
|
-
}
|
|
69
|
+
Object.assign(base, fromOpenCollectionTypedValue(v.value));
|
|
78
70
|
} else {
|
|
79
|
-
|
|
71
|
+
base.value = ensureString(v.value);
|
|
80
72
|
}
|
|
81
73
|
|
|
82
74
|
if (v.description) {
|
|
83
|
-
|
|
75
|
+
base.description = typeof v.description === 'string' ? v.description : (v.description as any)?.content || '';
|
|
84
76
|
}
|
|
85
77
|
|
|
86
|
-
reqVars.push(
|
|
78
|
+
reqVars.push(base);
|
|
87
79
|
});
|
|
88
80
|
|
|
89
81
|
return { req: reqVars, res: [] };
|
package/src/formats/yml/index.ts
CHANGED
|
@@ -2,19 +2,23 @@ import parseYmlItem from './parseItem';
|
|
|
2
2
|
import parseYmlFolder from './parseFolder';
|
|
3
3
|
import parseYmlCollection from './parseCollection';
|
|
4
4
|
import parseYmlEnvironment from './parseEnvironment';
|
|
5
|
+
import parseYmlMockServer from './parseMockServer';
|
|
5
6
|
|
|
6
7
|
import stringifyYmlItem from './stringifyItem';
|
|
7
8
|
import stringifyYmlFolder from './stringifyFolder';
|
|
8
9
|
import stringifyYmlCollection from './stringifyCollection';
|
|
9
10
|
import stringifyYmlEnvironment from './stringifyEnvironment';
|
|
11
|
+
import stringifyYmlMockServer from './stringifyMockServer';
|
|
10
12
|
|
|
11
13
|
export {
|
|
12
14
|
parseYmlItem,
|
|
13
15
|
parseYmlFolder,
|
|
14
16
|
parseYmlCollection,
|
|
15
17
|
parseYmlEnvironment,
|
|
18
|
+
parseYmlMockServer,
|
|
16
19
|
stringifyYmlItem,
|
|
17
20
|
stringifyYmlFolder,
|
|
18
21
|
stringifyYmlCollection,
|
|
19
|
-
stringifyYmlEnvironment
|
|
22
|
+
stringifyYmlEnvironment,
|
|
23
|
+
stringifyYmlMockServer
|
|
20
24
|
};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { Item as BrunoItem } from '@usebruno/schema-types/collection/item';
|
|
2
|
+
import { uuid } from '../../../utils';
|
|
3
|
+
|
|
4
|
+
export interface AppFile {
|
|
5
|
+
info: {
|
|
6
|
+
name?: string;
|
|
7
|
+
type: 'app';
|
|
8
|
+
seq?: number;
|
|
9
|
+
tags?: string[];
|
|
10
|
+
};
|
|
11
|
+
code?: string;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const parseApp = (ocApp: AppFile): BrunoItem => {
|
|
15
|
+
const info = ocApp.info || ({} as AppFile['info']);
|
|
16
|
+
|
|
17
|
+
const brunoItem: BrunoItem = {
|
|
18
|
+
uid: uuid(),
|
|
19
|
+
type: 'app',
|
|
20
|
+
seq: typeof info.seq === 'number' ? info.seq : 1,
|
|
21
|
+
name: info.name || 'App',
|
|
22
|
+
tags: Array.isArray(info.tags) ? info.tags : [],
|
|
23
|
+
request: null,
|
|
24
|
+
settings: null,
|
|
25
|
+
app: { code: ocApp.code || '' },
|
|
26
|
+
fileContent: null,
|
|
27
|
+
root: null,
|
|
28
|
+
items: [],
|
|
29
|
+
examples: [],
|
|
30
|
+
filename: null,
|
|
31
|
+
pathname: null
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
return brunoItem;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export default parseApp;
|
|
@@ -9,6 +9,8 @@ import { toBrunoPostResponseVariables } from '../common/actions';
|
|
|
9
9
|
import { toBrunoScripts } from '../common/scripts';
|
|
10
10
|
import { toBrunoAssertions } from '../common/assertions';
|
|
11
11
|
import { uuid, ensureString } from '../../../utils';
|
|
12
|
+
import { utils } from '@usebruno/common';
|
|
13
|
+
const { toBool, toNumber } = utils;
|
|
12
14
|
|
|
13
15
|
const parseGraphQLRequest = (ocRequest: GraphQLRequest): BrunoItem => {
|
|
14
16
|
const info = ocRequest.info;
|
|
@@ -98,15 +100,19 @@ const parseGraphQLRequest = (ocRequest: GraphQLRequest): BrunoItem => {
|
|
|
98
100
|
pathname: null
|
|
99
101
|
};
|
|
100
102
|
|
|
103
|
+
// description
|
|
104
|
+
if (info?.description) {
|
|
105
|
+
const desc = typeof info.description === 'string' ? info.description : (info.description as any)?.content || '';
|
|
106
|
+
if (desc.trim().length) {
|
|
107
|
+
brunoItem.description = desc;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
101
111
|
// settings
|
|
102
112
|
if (ocRequest.settings) {
|
|
103
113
|
const settings: BrunoHttpItemSettings = {};
|
|
104
114
|
|
|
105
|
-
|
|
106
|
-
settings.encodeUrl = ocRequest.settings.encodeUrl;
|
|
107
|
-
} else {
|
|
108
|
-
settings.encodeUrl = true;
|
|
109
|
-
}
|
|
115
|
+
settings.encodeUrl = toBool(ocRequest.settings.encodeUrl, true);
|
|
110
116
|
|
|
111
117
|
if (typeof ocRequest.settings.timeout === 'number') {
|
|
112
118
|
settings.timeout = ocRequest.settings.timeout;
|
|
@@ -116,17 +122,9 @@ const parseGraphQLRequest = (ocRequest: GraphQLRequest): BrunoItem => {
|
|
|
116
122
|
settings.timeout = 0;
|
|
117
123
|
}
|
|
118
124
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
settings.followRedirects = true;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
if (typeof ocRequest.settings.maxRedirects === 'number') {
|
|
126
|
-
settings.maxRedirects = ocRequest.settings.maxRedirects;
|
|
127
|
-
} else {
|
|
128
|
-
settings.maxRedirects = 5;
|
|
129
|
-
}
|
|
125
|
+
settings.followRedirects = toBool(ocRequest.settings.followRedirects, true);
|
|
126
|
+
settings.maxRedirects = toNumber(ocRequest.settings.maxRedirects, 5);
|
|
127
|
+
settings.forwardAuthorizationHeader = toBool(ocRequest.settings.forwardAuthorizationHeader, true);
|
|
130
128
|
|
|
131
129
|
brunoItem.settings = settings;
|
|
132
130
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Item as BrunoItem } from '@usebruno/schema-types/collection/item';
|
|
2
2
|
import type { GrpcRequest as BrunoGrpcRequest } from '@usebruno/schema-types/requests/grpc';
|
|
3
|
-
import type { GrpcRequest, GrpcMetadata } from '@opencollection/types/requests/grpc';
|
|
3
|
+
import type { GrpcRequest, GrpcMetadata, GrpcMessageVariant } from '@opencollection/types/requests/grpc';
|
|
4
4
|
import type { KeyValue as BrunoKeyValue } from '@usebruno/schema-types/common/key-value';
|
|
5
5
|
import { toBrunoAuth } from '../common/auth';
|
|
6
6
|
import { toBrunoVariables } from '../common/variables';
|
|
@@ -21,6 +21,13 @@ const toBrunoGrpcMetadata = (metadata: GrpcMetadata[] | null | undefined): Bruno
|
|
|
21
21
|
enabled: meta.disabled !== true
|
|
22
22
|
};
|
|
23
23
|
|
|
24
|
+
if (meta.description) {
|
|
25
|
+
const desc = typeof meta.description === 'string' ? meta.description : (meta.description as any)?.content || '';
|
|
26
|
+
if (desc.trim().length) {
|
|
27
|
+
brunoMeta.description = desc;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
24
31
|
return brunoMeta;
|
|
25
32
|
});
|
|
26
33
|
|
|
@@ -57,10 +64,16 @@ const parseGrpcRequest = (ocRequest: GrpcRequest): BrunoItem => {
|
|
|
57
64
|
};
|
|
58
65
|
|
|
59
66
|
// message
|
|
60
|
-
|
|
67
|
+
const rawMessage = grpc?.message;
|
|
68
|
+
if (Array.isArray(rawMessage)) {
|
|
69
|
+
brunoRequest.body.grpc = (rawMessage as GrpcMessageVariant[]).map(({ title, message }, index) => ({
|
|
70
|
+
name: title || `message ${index + 1}`,
|
|
71
|
+
content: ensureString(message)
|
|
72
|
+
}));
|
|
73
|
+
} else if (isNonEmptyString(rawMessage)) {
|
|
61
74
|
brunoRequest.body.grpc = [{
|
|
62
75
|
name: '',
|
|
63
|
-
content:
|
|
76
|
+
content: rawMessage as string
|
|
64
77
|
}];
|
|
65
78
|
}
|
|
66
79
|
|
|
@@ -110,6 +123,14 @@ const parseGrpcRequest = (ocRequest: GrpcRequest): BrunoItem => {
|
|
|
110
123
|
pathname: null
|
|
111
124
|
};
|
|
112
125
|
|
|
126
|
+
// description
|
|
127
|
+
if (info?.description) {
|
|
128
|
+
const desc = typeof info.description === 'string' ? info.description : (info.description as any)?.content || '';
|
|
129
|
+
if (desc.trim().length) {
|
|
130
|
+
brunoItem.description = desc;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
113
134
|
return brunoItem;
|
|
114
135
|
};
|
|
115
136
|
|
|
@@ -9,7 +9,10 @@ import { toBrunoVariables } from '../common/variables';
|
|
|
9
9
|
import { toBrunoPostResponseVariables } from '../common/actions';
|
|
10
10
|
import { toBrunoScripts } from '../common/scripts';
|
|
11
11
|
import { toBrunoAssertions } from '../common/assertions';
|
|
12
|
+
import { toBrunoApp } from '../common/app';
|
|
12
13
|
import { uuid, ensureString } from '../../../utils';
|
|
14
|
+
import { utils } from '@usebruno/common';
|
|
15
|
+
const { toBool, toNumber } = utils;
|
|
13
16
|
|
|
14
17
|
const parseHttpRequest = (ocRequest: HttpRequest): BrunoItem => {
|
|
15
18
|
const info = ocRequest.info;
|
|
@@ -79,6 +82,9 @@ const parseHttpRequest = (ocRequest: HttpRequest): BrunoItem => {
|
|
|
79
82
|
brunoRequest.docs = ocRequest.docs;
|
|
80
83
|
}
|
|
81
84
|
|
|
85
|
+
// app
|
|
86
|
+
const app = toBrunoApp((ocRequest as any).app);
|
|
87
|
+
|
|
82
88
|
// bruno item
|
|
83
89
|
const brunoItem: BrunoItem = {
|
|
84
90
|
uid: uuid(),
|
|
@@ -88,6 +94,7 @@ const parseHttpRequest = (ocRequest: HttpRequest): BrunoItem => {
|
|
|
88
94
|
tags: info?.tags || [],
|
|
89
95
|
request: brunoRequest,
|
|
90
96
|
settings: null,
|
|
97
|
+
app,
|
|
91
98
|
fileContent: null,
|
|
92
99
|
root: null,
|
|
93
100
|
items: [],
|
|
@@ -96,15 +103,19 @@ const parseHttpRequest = (ocRequest: HttpRequest): BrunoItem => {
|
|
|
96
103
|
pathname: null
|
|
97
104
|
};
|
|
98
105
|
|
|
106
|
+
// description
|
|
107
|
+
if (info?.description) {
|
|
108
|
+
const desc = typeof info.description === 'string' ? info.description : (info.description as any)?.content || '';
|
|
109
|
+
if (desc.trim().length) {
|
|
110
|
+
brunoItem.description = desc;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
99
114
|
// settings
|
|
100
115
|
if (ocRequest.settings) {
|
|
101
116
|
const settings: BrunoHttpItemSettings = {};
|
|
102
117
|
|
|
103
|
-
|
|
104
|
-
settings.encodeUrl = ocRequest.settings.encodeUrl;
|
|
105
|
-
} else {
|
|
106
|
-
settings.encodeUrl = true;
|
|
107
|
-
}
|
|
118
|
+
settings.encodeUrl = toBool(ocRequest.settings.encodeUrl, true);
|
|
108
119
|
|
|
109
120
|
if (typeof ocRequest.settings.timeout === 'number') {
|
|
110
121
|
settings.timeout = ocRequest.settings.timeout;
|
|
@@ -114,17 +125,9 @@ const parseHttpRequest = (ocRequest: HttpRequest): BrunoItem => {
|
|
|
114
125
|
settings.timeout = 0;
|
|
115
126
|
}
|
|
116
127
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
settings.followRedirects = true;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
if (typeof ocRequest.settings.maxRedirects === 'number') {
|
|
124
|
-
settings.maxRedirects = ocRequest.settings.maxRedirects;
|
|
125
|
-
} else {
|
|
126
|
-
settings.maxRedirects = 5;
|
|
127
|
-
}
|
|
128
|
+
settings.followRedirects = toBool(ocRequest.settings.followRedirects, true);
|
|
129
|
+
settings.maxRedirects = toNumber(ocRequest.settings.maxRedirects, 5);
|
|
130
|
+
settings.forwardAuthorizationHeader = toBool(ocRequest.settings.forwardAuthorizationHeader, true);
|
|
128
131
|
|
|
129
132
|
brunoItem.settings = settings;
|
|
130
133
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Item as BrunoItem } from '@usebruno/schema-types/collection/item';
|
|
2
2
|
import type { WebSocketRequest as BrunoWebSocketRequest } from '@usebruno/schema-types/requests/websocket';
|
|
3
|
-
import type { WebSocketRequest, WebSocketMessage } from '@opencollection/types/requests/websocket';
|
|
3
|
+
import type { WebSocketRequest, WebSocketMessage, WebSocketMessageVariant } from '@opencollection/types/requests/websocket';
|
|
4
4
|
import { toBrunoAuth } from '../common/auth';
|
|
5
5
|
import { toBrunoHttpHeaders } from '../common/headers';
|
|
6
6
|
import { toBrunoVariables } from '../common/variables';
|
|
@@ -35,14 +35,26 @@ const parseWebsocketRequest = (ocRequest: WebSocketRequest): BrunoItem => {
|
|
|
35
35
|
|
|
36
36
|
// message
|
|
37
37
|
if (websocket?.message) {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
brunoRequest.body.ws =
|
|
42
|
-
name:
|
|
43
|
-
type: message
|
|
44
|
-
content:
|
|
45
|
-
|
|
38
|
+
if (Array.isArray(websocket.message)) {
|
|
39
|
+
// multiple messages: WebSocketMessageVariant[]
|
|
40
|
+
const variants = websocket.message as WebSocketMessageVariant[];
|
|
41
|
+
brunoRequest.body.ws = variants.map((variant, index) => ({
|
|
42
|
+
name: variant.title || `message ${index + 1}`,
|
|
43
|
+
type: variant.message?.type || 'text',
|
|
44
|
+
content: ensureString(variant.message?.data),
|
|
45
|
+
selected: variant.selected || false
|
|
46
|
+
}));
|
|
47
|
+
} else {
|
|
48
|
+
// single message uses flat WebSocketMessage
|
|
49
|
+
const message = websocket.message as WebSocketMessage;
|
|
50
|
+
const messageData = ensureString(message.data);
|
|
51
|
+
if (messageData.trim().length) {
|
|
52
|
+
brunoRequest.body.ws = [{
|
|
53
|
+
name: '',
|
|
54
|
+
type: message.type || 'text',
|
|
55
|
+
content: messageData
|
|
56
|
+
}];
|
|
57
|
+
}
|
|
46
58
|
}
|
|
47
59
|
}
|
|
48
60
|
|
|
@@ -101,6 +113,14 @@ const parseWebsocketRequest = (ocRequest: WebSocketRequest): BrunoItem => {
|
|
|
101
113
|
pathname: null
|
|
102
114
|
};
|
|
103
115
|
|
|
116
|
+
// description
|
|
117
|
+
if (info?.description) {
|
|
118
|
+
const desc = typeof info.description === 'string' ? info.description : (info.description as any)?.content || '';
|
|
119
|
+
if (desc.trim().length) {
|
|
120
|
+
brunoItem.description = desc;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
104
124
|
return brunoItem;
|
|
105
125
|
};
|
|
106
126
|
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { Item as BrunoItem } from '@usebruno/schema-types/collection/item';
|
|
2
|
+
import { stringifyYml } from '../utils';
|
|
3
|
+
|
|
4
|
+
interface AppFileInfo {
|
|
5
|
+
name: string;
|
|
6
|
+
type: 'app';
|
|
7
|
+
seq?: number;
|
|
8
|
+
tags?: string[];
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
interface AppFile {
|
|
12
|
+
info: AppFileInfo;
|
|
13
|
+
code?: string;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// Mirror the request shape (info.name/type/seq/tags + body) so apps round-trip
|
|
17
|
+
// the same fields and can be reordered via seq like every other item.
|
|
18
|
+
const stringifyApp = (item: BrunoItem): string => {
|
|
19
|
+
try {
|
|
20
|
+
const info: AppFileInfo = {
|
|
21
|
+
name: item.name && item.name.trim().length ? item.name : 'App',
|
|
22
|
+
type: 'app'
|
|
23
|
+
};
|
|
24
|
+
if (typeof item.seq === 'number') {
|
|
25
|
+
info.seq = item.seq;
|
|
26
|
+
}
|
|
27
|
+
if (Array.isArray(item.tags) && item.tags.length) {
|
|
28
|
+
info.tags = item.tags;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const ocApp: AppFile = { info };
|
|
32
|
+
|
|
33
|
+
const code = item.app?.code;
|
|
34
|
+
if (code && code.trim().length) {
|
|
35
|
+
ocApp.code = code;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return stringifyYml(ocApp);
|
|
39
|
+
} catch (error) {
|
|
40
|
+
console.error('Error stringifying app:', error);
|
|
41
|
+
throw error;
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export default stringifyApp;
|
|
@@ -16,6 +16,7 @@ import { toOpenCollectionVariables } from '../common/variables';
|
|
|
16
16
|
import { toOpenCollectionActions } from '../common/actions';
|
|
17
17
|
import { toOpenCollectionScripts } from '../common/scripts';
|
|
18
18
|
import { toOpenCollectionAssertions } from '../common/assertions';
|
|
19
|
+
import { resolveTimeoutSetting } from '@usebruno/common/utils';
|
|
19
20
|
|
|
20
21
|
const stringifyGraphQLRequest = (item: BrunoItem): string => {
|
|
21
22
|
try {
|
|
@@ -33,6 +34,9 @@ const stringifyGraphQLRequest = (item: BrunoItem): string => {
|
|
|
33
34
|
if (item.tags?.length) {
|
|
34
35
|
info.tags = item.tags;
|
|
35
36
|
}
|
|
37
|
+
if (isNonEmptyString(item.description)) {
|
|
38
|
+
info.description = item.description;
|
|
39
|
+
}
|
|
36
40
|
ocRequest.info = info;
|
|
37
41
|
|
|
38
42
|
// graphql block
|
|
@@ -129,12 +133,7 @@ const stringifyGraphQLRequest = (item: BrunoItem): string => {
|
|
|
129
133
|
settings.encodeUrl = true;
|
|
130
134
|
}
|
|
131
135
|
|
|
132
|
-
|
|
133
|
-
if (isNumber(timeout)) {
|
|
134
|
-
settings.timeout = timeout;
|
|
135
|
-
} else {
|
|
136
|
-
settings.timeout = 0;
|
|
137
|
-
}
|
|
136
|
+
settings.timeout = resolveTimeoutSetting(httpSettings?.timeout);
|
|
138
137
|
|
|
139
138
|
if (httpSettings?.followRedirects === true) {
|
|
140
139
|
settings.followRedirects = true;
|
|
@@ -151,6 +150,8 @@ const stringifyGraphQLRequest = (item: BrunoItem): string => {
|
|
|
151
150
|
settings.maxRedirects = 5;
|
|
152
151
|
}
|
|
153
152
|
|
|
153
|
+
settings.forwardAuthorizationHeader = httpSettings?.forwardAuthorizationHeader ?? true;
|
|
154
|
+
|
|
154
155
|
ocRequest.settings = settings;
|
|
155
156
|
|
|
156
157
|
// docs
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Item as BrunoItem } from '@usebruno/schema-types/collection/item';
|
|
2
2
|
import type { KeyValue as BrunoKeyValue } from '@usebruno/schema-types/common/key-value';
|
|
3
3
|
import type { GrpcRequest as BrunoGrpcRequest } from '@usebruno/schema-types/requests/grpc';
|
|
4
|
-
import type { GrpcRequest, GrpcMetadata, GrpcMessage, GrpcRequestInfo, GrpcRequestDetails, GrpcRequestRuntime } from '@opencollection/types/requests/grpc';
|
|
4
|
+
import type { GrpcRequest, GrpcMetadata, GrpcMessageVariant, GrpcMessage, GrpcRequestInfo, GrpcRequestDetails, GrpcRequestRuntime } from '@opencollection/types/requests/grpc';
|
|
5
5
|
import type { Auth } from '@opencollection/types/common/auth';
|
|
6
6
|
import type { Scripts } from '@opencollection/types/common/scripts';
|
|
7
7
|
import type { Variable } from '@opencollection/types/common/variables';
|
|
@@ -29,6 +29,9 @@ const stringifyGrpcRequest = (item: BrunoItem): string => {
|
|
|
29
29
|
if (item.tags?.length) {
|
|
30
30
|
info.tags = item.tags;
|
|
31
31
|
}
|
|
32
|
+
if (isNonEmptyString(item.description)) {
|
|
33
|
+
info.description = item.description;
|
|
34
|
+
}
|
|
32
35
|
ocRequest.info = info;
|
|
33
36
|
|
|
34
37
|
// grpc block
|
|
@@ -73,16 +76,11 @@ const stringifyGrpcRequest = (item: BrunoItem): string => {
|
|
|
73
76
|
|
|
74
77
|
// message
|
|
75
78
|
if (brunoRequest.body?.mode === 'grpc' && brunoRequest.body.grpc?.length) {
|
|
76
|
-
const messages = brunoRequest.body.grpc
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
const message: GrpcMessage = messages[0].content || '';
|
|
82
|
-
if (message.trim().length) {
|
|
83
|
-
grpc.message = message;
|
|
84
|
-
}
|
|
85
|
-
}
|
|
79
|
+
const messages: GrpcMessageVariant[] = brunoRequest.body.grpc.map(({ name, content }, index) => ({
|
|
80
|
+
title: name || `message ${index + 1}`,
|
|
81
|
+
message: content || ''
|
|
82
|
+
}));
|
|
83
|
+
grpc.message = messages;
|
|
86
84
|
}
|
|
87
85
|
|
|
88
86
|
// auth
|