@usebruno/filestore 0.8.0 → 0.9.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/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/tests/example-status-swap.spec.d.ts +2 -0
- package/dist/formats/bru/tests/example-status-swap.spec.d.ts.map +1 -0
- package/dist/formats/yml/common/auth.d.ts.map +1 -1
- package/package.json +6 -6
- package/src/formats/bru/index.ts +15 -3
- package/src/formats/bru/tests/example-status-swap.spec.js +109 -0
- package/src/formats/yml/common/auth.ts +54 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/formats/bru/index.ts"],"names":[],"mappings":"AAWA,eAAO,MAAM,eAAe,SAAU,MAAM,GAAG,GAAG,WAAU,OAAO,KAAW,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/formats/bru/index.ts"],"names":[],"mappings":"AAWA,eAAO,MAAM,eAAe,SAAU,MAAM,GAAG,GAAG,WAAU,OAAO,KAAW,GAwG7E,CAAC;AAEF,eAAO,MAAM,mBAAmB,SAAU,GAAG,KAAG,MA+G/C,CAAC;AAEF,eAAO,MAAM,kBAAkB,SAAU,MAAM,GAAG,GAAG,WAAU,OAAO,KAAW,GA4ChF,CAAC;AAEF,eAAO,MAAM,sBAAsB,SAAU,GAAG,aAAa,OAAO,KAAG,MAuCtE,CAAC;AAEF,eAAO,MAAM,mBAAmB,QAAS,MAAM,KAAG,GAejD,CAAC;AAEF,eAAO,MAAM,uBAAuB,SAAU,GAAG,KAAG,MAOnD,CAAC;AAGF,eAAO,MAAM,gBAAgB,SAAU,MAAM,GAAG,GAAG,WAAU,OAAO,eAAuB,MAAM,iBAAiB,MAAM,KAAG,GAwE1H,CAAC;AAEF,eAAO,MAAM,gBAAgB,SAAU,GAAG;;;;;;;;;;;CAsBzC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"example-status-swap.spec.d.ts","sourceRoot":"","sources":["../../../../src/formats/bru/tests/example-status-swap.spec.js"],"names":[],"mappings":""}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../../../src/formats/yml/common/auth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,IAAI,
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../../../src/formats/yml/common/auth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,IAAI,EASL,MAAM,mCAAmC,CAAC;AAC3C,OAAO,KAAK,EAAE,IAAI,IAAI,SAAS,EAAiC,MAAM,oCAAoC,CAAC;AAwI3G,eAAO,MAAM,oBAAoB,UAAW,SAAS,GAAG,IAAI,KAAG,IAAI,GAAG,SAgCrE,CAAC;AAEF,eAAO,MAAM,WAAW,SAAU,IAAI,GAAG,IAAI,GAAG,SAAS,KAAG,SAAS,GAAG,IAoHvE,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@usebruno/filestore",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"main": "dist/cjs/index.js",
|
|
6
6
|
"module": "dist/esm/index.js",
|
|
@@ -29,23 +29,23 @@
|
|
|
29
29
|
"@types/jest": "^29.5.11",
|
|
30
30
|
"@types/lodash": "^4.14.191",
|
|
31
31
|
"@types/node": "^24.1.0",
|
|
32
|
-
"@usebruno/schema-types": "0.
|
|
32
|
+
"@usebruno/schema-types": "0.4.0",
|
|
33
33
|
"babel-jest": "^29.7.0",
|
|
34
34
|
"jest": "^29.2.0",
|
|
35
35
|
"nanoid": "3.3.8",
|
|
36
36
|
"rimraf": "^3.0.2",
|
|
37
|
-
"rollup": "3.
|
|
37
|
+
"rollup": "3.30.0",
|
|
38
38
|
"rollup-plugin-dts": "^5.0.0",
|
|
39
39
|
"rollup-plugin-peer-deps-external": "^2.2.4",
|
|
40
|
-
"rollup
|
|
40
|
+
"@rollup/plugin-terser": "^1.0.0",
|
|
41
41
|
"typescript": "^4.8.4"
|
|
42
42
|
},
|
|
43
43
|
"overrides": {
|
|
44
|
-
"rollup": "3.
|
|
44
|
+
"rollup": "3.30.0"
|
|
45
45
|
},
|
|
46
46
|
"dependencies": {
|
|
47
47
|
"@types/nanoid": "^2.1.0",
|
|
48
|
-
"@usebruno/lang": "0.
|
|
48
|
+
"@usebruno/lang": "0.36.0",
|
|
49
49
|
"ajv": "^8.17.1",
|
|
50
50
|
"lodash": "^4.17.21",
|
|
51
51
|
"yaml": "^2.3.4"
|
package/src/formats/bru/index.ts
CHANGED
|
@@ -32,6 +32,7 @@ export const parseBruRequest = (data: string | any, parsed: boolean = false): an
|
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
const sequence = _.get(json, 'meta.seq');
|
|
35
|
+
const tags = _.get(json, 'meta.tags', []);
|
|
35
36
|
const urlPath: Record<typeof requestType, string> = {
|
|
36
37
|
'grpc-request': 'grpc.url',
|
|
37
38
|
'ws-request': 'ws.url',
|
|
@@ -42,7 +43,7 @@ export const parseBruRequest = (data: string | any, parsed: boolean = false): an
|
|
|
42
43
|
name: _.get(json, 'meta.name'),
|
|
43
44
|
seq: !_.isNaN(sequence) ? Number(sequence) : 1,
|
|
44
45
|
settings: _.get(json, 'settings', {}),
|
|
45
|
-
tags:
|
|
46
|
+
tags: Array.isArray(tags) ? tags : [],
|
|
46
47
|
request: {
|
|
47
48
|
// Preserving special characters in custom methods. Using _.upperCase strips special characters.
|
|
48
49
|
method:
|
|
@@ -367,6 +368,17 @@ export const bruExampleToJson = (data: string | any, parsed: boolean = false, pa
|
|
|
367
368
|
transformedType = 'http-request';
|
|
368
369
|
}
|
|
369
370
|
|
|
371
|
+
/**
|
|
372
|
+
* Backward compatibility (pre-v3.0.2 - v3.2.0): Postman imports before PR #6876 stored status/statusText swapped
|
|
373
|
+
* (code: "OK", text: "202" instead of code: 202, text: "OK"). Detect and swap back.
|
|
374
|
+
* TODO(Sid / Shubh): Remove after v5 — all collections should be migrated by then.
|
|
375
|
+
*/
|
|
376
|
+
let status = _.get(json, 'response.status', '200');
|
|
377
|
+
let statusText = _.get(json, 'response.statusText', 'OK');
|
|
378
|
+
if (isNaN(Number(status)) && !isNaN(Number(statusText))) {
|
|
379
|
+
[status, statusText] = [statusText, status];
|
|
380
|
+
}
|
|
381
|
+
|
|
370
382
|
// Follow the same structure as the main request, but with missing fields for examples
|
|
371
383
|
const transformedJson = {
|
|
372
384
|
type: transformedType,
|
|
@@ -388,8 +400,8 @@ export const bruExampleToJson = (data: string | any, parsed: boolean = false, pa
|
|
|
388
400
|
name: header.name,
|
|
389
401
|
value: header.value
|
|
390
402
|
})),
|
|
391
|
-
status:
|
|
392
|
-
statusText:
|
|
403
|
+
status: Number(status) || 200,
|
|
404
|
+
statusText: statusText || 'OK',
|
|
393
405
|
body: {
|
|
394
406
|
type: _.get(json, 'response.body.type', 'json'),
|
|
395
407
|
content: _.get(json, 'response.body.content', '')
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
const { bruExampleToJson } = require('../index');
|
|
2
|
+
|
|
3
|
+
describe('bruExampleToJson - status/statusText swap fix', () => {
|
|
4
|
+
it('should parse normal status and statusText correctly', () => {
|
|
5
|
+
const parsed = {
|
|
6
|
+
name: 'Normal Example',
|
|
7
|
+
description: '',
|
|
8
|
+
request: { url: 'https://api.example.com/test', method: 'get' },
|
|
9
|
+
response: {
|
|
10
|
+
headers: [],
|
|
11
|
+
status: '200',
|
|
12
|
+
statusText: 'OK',
|
|
13
|
+
body: { type: 'json', content: '{}' }
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
const result = bruExampleToJson(parsed, true, 'http', 'GET');
|
|
18
|
+
expect(result.response.status).toBe(200);
|
|
19
|
+
expect(result.response.statusText).toBe('OK');
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it('should swap back status and statusText when they are reversed (pre-fix Postman import)', () => {
|
|
23
|
+
const parsed = {
|
|
24
|
+
name: 'Swapped Example',
|
|
25
|
+
description: '',
|
|
26
|
+
request: { url: 'https://api.example.com/test', method: 'get' },
|
|
27
|
+
response: {
|
|
28
|
+
headers: [],
|
|
29
|
+
status: 'Accepted',
|
|
30
|
+
statusText: '202',
|
|
31
|
+
body: { type: 'json', content: '{}' }
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
const result = bruExampleToJson(parsed, true, 'http', 'GET');
|
|
36
|
+
expect(result.response.status).toBe(202);
|
|
37
|
+
expect(result.response.statusText).toBe('Accepted');
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it('should swap back status OK and statusText 200', () => {
|
|
41
|
+
const parsed = {
|
|
42
|
+
name: 'Swapped OK Example',
|
|
43
|
+
description: '',
|
|
44
|
+
request: { url: 'https://api.example.com/test', method: 'get' },
|
|
45
|
+
response: {
|
|
46
|
+
headers: [],
|
|
47
|
+
status: 'OK',
|
|
48
|
+
statusText: '200',
|
|
49
|
+
body: { type: 'json', content: '{}' }
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
const result = bruExampleToJson(parsed, true, 'http', 'GET');
|
|
54
|
+
expect(result.response.status).toBe(200);
|
|
55
|
+
expect(result.response.statusText).toBe('OK');
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it('should swap back status Not Found and statusText 404', () => {
|
|
59
|
+
const parsed = {
|
|
60
|
+
name: 'Swapped Not Found Example',
|
|
61
|
+
description: '',
|
|
62
|
+
request: { url: 'https://api.example.com/test', method: 'get' },
|
|
63
|
+
response: {
|
|
64
|
+
headers: [],
|
|
65
|
+
status: 'Not Found',
|
|
66
|
+
statusText: '404',
|
|
67
|
+
body: { type: 'json', content: '{}' }
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
const result = bruExampleToJson(parsed, true, 'http', 'GET');
|
|
72
|
+
expect(result.response.status).toBe(404);
|
|
73
|
+
expect(result.response.statusText).toBe('Not Found');
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
it('should not swap when status is already numeric and statusText is text (correct order)', () => {
|
|
77
|
+
const parsed = {
|
|
78
|
+
name: 'Correct Order Example',
|
|
79
|
+
description: '',
|
|
80
|
+
request: { url: 'https://api.example.com/test', method: 'get' },
|
|
81
|
+
response: {
|
|
82
|
+
headers: [],
|
|
83
|
+
status: '404',
|
|
84
|
+
statusText: 'Not Found',
|
|
85
|
+
body: { type: 'json', content: '{}' }
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
const result = bruExampleToJson(parsed, true, 'http', 'GET');
|
|
90
|
+
expect(result.response.status).toBe(404);
|
|
91
|
+
expect(result.response.statusText).toBe('Not Found');
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
it('should use defaults when response has no status', () => {
|
|
95
|
+
const parsed = {
|
|
96
|
+
name: 'No Status Example',
|
|
97
|
+
description: '',
|
|
98
|
+
request: { url: 'https://api.example.com/test', method: 'get' },
|
|
99
|
+
response: {
|
|
100
|
+
headers: [],
|
|
101
|
+
body: { type: 'json', content: '{}' }
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
const result = bruExampleToJson(parsed, true, 'http', 'GET');
|
|
106
|
+
expect(result.response.status).toBe(200);
|
|
107
|
+
expect(result.response.statusText).toBe('OK');
|
|
108
|
+
});
|
|
109
|
+
});
|
|
@@ -6,9 +6,10 @@ import type {
|
|
|
6
6
|
AuthBearer,
|
|
7
7
|
AuthDigest,
|
|
8
8
|
AuthNTLM,
|
|
9
|
+
AuthOAuth1,
|
|
9
10
|
AuthWsse
|
|
10
11
|
} from '@opencollection/types/common/auth';
|
|
11
|
-
import type { Auth as BrunoAuth } from '@usebruno/schema-types/common/auth';
|
|
12
|
+
import type { Auth as BrunoAuth, AuthOauth1 as BrunoAuthOauth1 } from '@usebruno/schema-types/common/auth';
|
|
12
13
|
import { isString } from '../../../utils';
|
|
13
14
|
import { toOpenCollectionOAuth2, toBrunoOAuth2 } from './auth-oauth2';
|
|
14
15
|
|
|
@@ -115,6 +116,35 @@ const buildApiKeyAuth = (config?: BrunoAuth['apikey']): AuthApiKey => {
|
|
|
115
116
|
return auth;
|
|
116
117
|
};
|
|
117
118
|
|
|
119
|
+
const buildOAuth1Auth = (config?: BrunoAuth['oauth1']): AuthOAuth1 => {
|
|
120
|
+
const auth: AuthOAuth1 = { type: 'oauth1' };
|
|
121
|
+
|
|
122
|
+
if (!config) {
|
|
123
|
+
return auth;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
if (isString(config.consumerKey)) auth.consumerKey = config.consumerKey;
|
|
127
|
+
if (isString(config.consumerSecret)) auth.consumerSecret = config.consumerSecret;
|
|
128
|
+
if (isString(config.accessToken)) auth.accessToken = config.accessToken;
|
|
129
|
+
if (isString(config.accessTokenSecret)) auth.accessTokenSecret = config.accessTokenSecret;
|
|
130
|
+
if (isString(config.callbackUrl)) auth.callbackUrl = config.callbackUrl;
|
|
131
|
+
if (isString(config.verifier)) auth.verifier = config.verifier;
|
|
132
|
+
if (isString(config.signatureMethod)) auth.signatureMethod = config.signatureMethod;
|
|
133
|
+
if (isString(config.privateKey)) {
|
|
134
|
+
auth.privateKey = config.privateKeyType === 'file'
|
|
135
|
+
? { type: 'file' as const, value: config.privateKey }
|
|
136
|
+
: { type: 'text' as const, value: config.privateKey };
|
|
137
|
+
}
|
|
138
|
+
if (isString(config.timestamp)) auth.timestamp = config.timestamp;
|
|
139
|
+
if (isString(config.nonce)) auth.nonce = config.nonce;
|
|
140
|
+
if (isString(config.version)) auth.version = config.version;
|
|
141
|
+
if (isString(config.realm)) auth.realm = config.realm;
|
|
142
|
+
if (isString(config.placement)) auth.placement = config.placement as AuthOAuth1['placement'];
|
|
143
|
+
if (typeof config.includeBodyHash === 'boolean') auth.includeBodyHash = config.includeBodyHash;
|
|
144
|
+
|
|
145
|
+
return auth;
|
|
146
|
+
};
|
|
147
|
+
|
|
118
148
|
export const toOpenCollectionAuth = (auth?: BrunoAuth | null): Auth | undefined => {
|
|
119
149
|
if (!auth || auth.mode === 'none') {
|
|
120
150
|
return undefined;
|
|
@@ -139,6 +169,8 @@ export const toOpenCollectionAuth = (auth?: BrunoAuth | null): Auth | undefined
|
|
|
139
169
|
return buildWsseAuth(auth.wsse);
|
|
140
170
|
case 'apikey':
|
|
141
171
|
return buildApiKeyAuth(auth.apikey);
|
|
172
|
+
case 'oauth1':
|
|
173
|
+
return buildOAuth1Auth(auth.oauth1);
|
|
142
174
|
case 'oauth2':
|
|
143
175
|
return toOpenCollectionOAuth2(auth.oauth2);
|
|
144
176
|
default:
|
|
@@ -231,6 +263,27 @@ export const toBrunoAuth = (auth: Auth | null | undefined): BrunoAuth | null =>
|
|
|
231
263
|
};
|
|
232
264
|
break;
|
|
233
265
|
|
|
266
|
+
case 'oauth1':
|
|
267
|
+
brunoAuth.mode = 'oauth1';
|
|
268
|
+
brunoAuth.oauth1 = {
|
|
269
|
+
consumerKey: auth.consumerKey || null,
|
|
270
|
+
consumerSecret: auth.consumerSecret || null,
|
|
271
|
+
accessToken: auth.accessToken || null,
|
|
272
|
+
accessTokenSecret: auth.accessTokenSecret || null,
|
|
273
|
+
callbackUrl: auth.callbackUrl || null,
|
|
274
|
+
verifier: auth.verifier || null,
|
|
275
|
+
signatureMethod: (auth.signatureMethod as BrunoAuthOauth1['signatureMethod']) || 'HMAC-SHA1',
|
|
276
|
+
privateKey: (typeof auth.privateKey === 'object' && auth.privateKey ? auth.privateKey.value : auth.privateKey) || null,
|
|
277
|
+
privateKeyType: (typeof auth.privateKey === 'object' && auth.privateKey ? auth.privateKey.type : 'text') as BrunoAuthOauth1['privateKeyType'],
|
|
278
|
+
timestamp: auth.timestamp || null,
|
|
279
|
+
nonce: auth.nonce || null,
|
|
280
|
+
version: auth.version || '1.0',
|
|
281
|
+
realm: auth.realm || null,
|
|
282
|
+
placement: (auth.placement as BrunoAuthOauth1['placement']) || 'header',
|
|
283
|
+
includeBodyHash: auth.includeBodyHash || false
|
|
284
|
+
};
|
|
285
|
+
break;
|
|
286
|
+
|
|
234
287
|
case 'oauth2':
|
|
235
288
|
brunoAuth.mode = 'oauth2';
|
|
236
289
|
brunoAuth.oauth2 = toBrunoOAuth2(auth);
|