@usebruno/filestore 0.5.0 → 0.6.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.
Files changed (157) hide show
  1. package/dist/cjs/index.js +1 -1
  2. package/dist/cjs/index.js.map +1 -1
  3. package/dist/cjs/workers/worker-script.js +1 -1
  4. package/dist/cjs/workers/worker-script.js.map +1 -1
  5. package/dist/esm/index.js +1 -1
  6. package/dist/esm/index.js.map +1 -1
  7. package/dist/esm/workers/worker-script.js +1 -1
  8. package/dist/esm/workers/worker-script.js.map +1 -1
  9. package/dist/formats/bru/index.d.ts +20 -0
  10. package/dist/formats/bru/index.d.ts.map +1 -0
  11. package/dist/formats/bru/tests/fixtures/oauth2-additional-params.d.ts +57 -0
  12. package/dist/formats/bru/tests/fixtures/oauth2-additional-params.d.ts.map +1 -0
  13. package/dist/formats/bru/tests/oauth2-additional-params.spec.d.ts +2 -0
  14. package/dist/formats/bru/tests/oauth2-additional-params.spec.d.ts.map +1 -0
  15. package/dist/formats/bru/tests/request-parse-and-redact-body-data.spec.d.ts +2 -0
  16. package/dist/formats/bru/tests/request-parse-and-redact-body-data.spec.d.ts.map +1 -0
  17. package/dist/{cjs/workers/formats → formats}/bru/utils/oauth2-additional-params.d.ts +1 -0
  18. package/dist/formats/bru/utils/oauth2-additional-params.d.ts.map +1 -0
  19. package/dist/{esm/formats → formats}/bru/utils/request-parse-and-redact-body-data.d.ts +1 -0
  20. package/dist/formats/bru/utils/request-parse-and-redact-body-data.d.ts.map +1 -0
  21. package/dist/formats/yml/common/actions.d.ts +14 -0
  22. package/dist/formats/yml/common/actions.d.ts.map +1 -0
  23. package/dist/formats/yml/common/assertions.d.ts +5 -0
  24. package/dist/formats/yml/common/assertions.d.ts.map +1 -0
  25. package/dist/formats/yml/common/auth-oauth2.d.ts +5 -0
  26. package/dist/formats/yml/common/auth-oauth2.d.ts.map +1 -0
  27. package/dist/formats/yml/common/auth.d.ts +5 -0
  28. package/dist/formats/yml/common/auth.d.ts.map +1 -0
  29. package/dist/formats/yml/common/body.d.ts +5 -0
  30. package/dist/formats/yml/common/body.d.ts.map +1 -0
  31. package/dist/formats/yml/common/headers.d.ts +7 -0
  32. package/dist/formats/yml/common/headers.d.ts.map +1 -0
  33. package/dist/formats/yml/common/params.d.ts +5 -0
  34. package/dist/formats/yml/common/params.d.ts.map +1 -0
  35. package/dist/formats/yml/common/scripts.d.ts +14 -0
  36. package/dist/formats/yml/common/scripts.d.ts.map +1 -0
  37. package/dist/formats/yml/common/variables.d.ts +17 -0
  38. package/dist/formats/yml/common/variables.d.ts.map +1 -0
  39. package/dist/formats/yml/index.d.ts +10 -0
  40. package/dist/formats/yml/index.d.ts.map +1 -0
  41. package/dist/formats/yml/items/parseGraphQLRequest.d.ts +5 -0
  42. package/dist/formats/yml/items/parseGraphQLRequest.d.ts.map +1 -0
  43. package/dist/formats/yml/items/parseGrpcRequest.d.ts +5 -0
  44. package/dist/formats/yml/items/parseGrpcRequest.d.ts.map +1 -0
  45. package/dist/formats/yml/items/parseHttpRequest.d.ts +5 -0
  46. package/dist/formats/yml/items/parseHttpRequest.d.ts.map +1 -0
  47. package/dist/formats/yml/items/parseScript.d.ts +5 -0
  48. package/dist/formats/yml/items/parseScript.d.ts.map +1 -0
  49. package/dist/formats/yml/items/parseWebsocketRequest.d.ts +5 -0
  50. package/dist/formats/yml/items/parseWebsocketRequest.d.ts.map +1 -0
  51. package/dist/formats/yml/items/stringifyGraphQLRequest.d.ts +4 -0
  52. package/dist/formats/yml/items/stringifyGraphQLRequest.d.ts.map +1 -0
  53. package/dist/formats/yml/items/stringifyGrpcRequest.d.ts +4 -0
  54. package/dist/formats/yml/items/stringifyGrpcRequest.d.ts.map +1 -0
  55. package/dist/formats/yml/items/stringifyHttpRequest.d.ts +4 -0
  56. package/dist/formats/yml/items/stringifyHttpRequest.d.ts.map +1 -0
  57. package/dist/formats/yml/items/stringifyScript.d.ts +4 -0
  58. package/dist/formats/yml/items/stringifyScript.d.ts.map +1 -0
  59. package/dist/formats/yml/items/stringifyWebsocketRequest.d.ts +4 -0
  60. package/dist/formats/yml/items/stringifyWebsocketRequest.d.ts.map +1 -0
  61. package/dist/formats/yml/parseCollection.d.ts +8 -0
  62. package/dist/formats/yml/parseCollection.d.ts.map +1 -0
  63. package/dist/formats/yml/parseEnvironment.d.ts +4 -0
  64. package/dist/formats/yml/parseEnvironment.d.ts.map +1 -0
  65. package/dist/formats/yml/parseFolder.d.ts +4 -0
  66. package/dist/formats/yml/parseFolder.d.ts.map +1 -0
  67. package/dist/formats/yml/parseItem.d.ts +4 -0
  68. package/dist/formats/yml/parseItem.d.ts.map +1 -0
  69. package/dist/formats/yml/stringifyCollection.d.ts +3 -0
  70. package/dist/formats/yml/stringifyCollection.d.ts.map +1 -0
  71. package/dist/formats/yml/stringifyEnvironment.d.ts +4 -0
  72. package/dist/formats/yml/stringifyEnvironment.d.ts.map +1 -0
  73. package/dist/formats/yml/stringifyFolder.d.ts +4 -0
  74. package/dist/formats/yml/stringifyFolder.d.ts.map +1 -0
  75. package/dist/formats/yml/stringifyItem.d.ts +4 -0
  76. package/dist/formats/yml/stringifyItem.d.ts.map +1 -0
  77. package/dist/formats/yml/utils.d.ts +3 -0
  78. package/dist/formats/yml/utils.d.ts.map +1 -0
  79. package/dist/{cjs/workers/index.d.ts → index.d.ts} +13 -6
  80. package/dist/index.d.ts.map +1 -0
  81. package/dist/types.d.ts +19 -0
  82. package/dist/types.d.ts.map +1 -0
  83. package/dist/utils/index.d.ts +5 -0
  84. package/dist/utils/index.d.ts.map +1 -0
  85. package/dist/{esm/workers → workers}/WorkerQueue/index.d.ts +1 -0
  86. package/dist/workers/WorkerQueue/index.d.ts.map +1 -0
  87. package/dist/workers/index.d.ts +12 -0
  88. package/dist/workers/index.d.ts.map +1 -0
  89. package/dist/workers/worker-script.d.ts +2 -0
  90. package/dist/workers/worker-script.d.ts.map +1 -0
  91. package/package.json +12 -6
  92. package/src/formats/bru/index.ts +9 -9
  93. package/src/formats/bru/tests/oauth2-additional-params.spec.js +1 -1
  94. package/src/formats/bru/utils/oauth2-additional-params.ts +17 -18
  95. package/src/formats/bru/utils/request-parse-and-redact-body-data.ts +13 -13
  96. package/src/formats/yml/common/actions.ts +78 -0
  97. package/src/formats/yml/common/assertions.ts +146 -0
  98. package/src/formats/yml/common/auth-oauth2.ts +555 -0
  99. package/src/formats/yml/common/auth.ts +245 -0
  100. package/src/formats/yml/common/body.ts +238 -0
  101. package/src/formats/yml/common/headers.ts +58 -0
  102. package/src/formats/yml/common/params.ts +57 -0
  103. package/src/formats/yml/common/scripts.ts +64 -0
  104. package/src/formats/yml/common/variables.ts +68 -0
  105. package/src/formats/yml/index.ts +20 -0
  106. package/src/formats/yml/items/parseGraphQLRequest.ts +137 -0
  107. package/src/formats/yml/items/parseGrpcRequest.ts +116 -0
  108. package/src/formats/yml/items/parseHttpRequest.ts +195 -0
  109. package/src/formats/yml/items/parseScript.ts +25 -0
  110. package/src/formats/yml/items/parseWebsocketRequest.ts +106 -0
  111. package/src/formats/yml/items/stringifyGraphQLRequest.ts +168 -0
  112. package/src/formats/yml/items/stringifyGrpcRequest.ts +137 -0
  113. package/src/formats/yml/items/stringifyHttpRequest.ts +221 -0
  114. package/src/formats/yml/items/stringifyScript.ts +22 -0
  115. package/src/formats/yml/items/stringifyWebsocketRequest.ts +114 -0
  116. package/src/formats/yml/parseCollection.ts +198 -0
  117. package/src/formats/yml/parseEnvironment.ts +56 -0
  118. package/src/formats/yml/parseFolder.ts +88 -0
  119. package/src/formats/yml/parseItem.ts +102 -0
  120. package/src/formats/yml/stringifyCollection.ts +230 -0
  121. package/src/formats/yml/stringifyEnvironment.ts +64 -0
  122. package/src/formats/yml/stringifyFolder.ts +96 -0
  123. package/src/formats/yml/stringifyItem.ts +37 -0
  124. package/src/formats/yml/utils.ts +38 -0
  125. package/src/index.ts +57 -27
  126. package/src/types/bruno-lang.d.ts +1 -1
  127. package/src/types.ts +5 -124
  128. package/src/utils/index.ts +15 -0
  129. package/src/workers/WorkerQueue/index.ts +10 -10
  130. package/src/workers/index.ts +20 -20
  131. package/src/workers/worker-script.ts +20 -6
  132. package/dist/cjs/formats/bru/index.d.ts +0 -19
  133. package/dist/cjs/formats/bru/utils/oauth2-additional-params.d.ts +0 -38
  134. package/dist/cjs/formats/bru/utils/request-parse-and-redact-body-data.d.ts +0 -9
  135. package/dist/cjs/index.d.ts +0 -16
  136. package/dist/cjs/types.d.ts +0 -142
  137. package/dist/cjs/workers/WorkerQueue/index.d.ts +0 -26
  138. package/dist/cjs/workers/formats/bru/index.d.ts +0 -19
  139. package/dist/cjs/workers/formats/bru/utils/request-parse-and-redact-body-data.d.ts +0 -9
  140. package/dist/cjs/workers/types.d.ts +0 -142
  141. package/dist/cjs/workers/worker-script.d.ts +0 -1
  142. package/dist/cjs/workers/workers/WorkerQueue/index.d.ts +0 -26
  143. package/dist/cjs/workers/workers/index.d.ts +0 -10
  144. package/dist/cjs/workers/workers/worker-script.d.ts +0 -1
  145. package/dist/esm/formats/bru/index.d.ts +0 -19
  146. package/dist/esm/formats/bru/utils/oauth2-additional-params.d.ts +0 -38
  147. package/dist/esm/index.d.ts +0 -16
  148. package/dist/esm/types.d.ts +0 -142
  149. package/dist/esm/workers/formats/bru/index.d.ts +0 -19
  150. package/dist/esm/workers/formats/bru/utils/oauth2-additional-params.d.ts +0 -38
  151. package/dist/esm/workers/formats/bru/utils/request-parse-and-redact-body-data.d.ts +0 -9
  152. package/dist/esm/workers/index.d.ts +0 -16
  153. package/dist/esm/workers/types.d.ts +0 -142
  154. package/dist/esm/workers/worker-script.d.ts +0 -1
  155. package/dist/esm/workers/workers/WorkerQueue/index.d.ts +0 -26
  156. package/dist/esm/workers/workers/index.d.ts +0 -10
  157. package/dist/esm/workers/workers/worker-script.d.ts +0 -1
@@ -0,0 +1,555 @@
1
+ import type {
2
+ AuthOAuth2,
3
+ OAuth2AdditionalParameter,
4
+ OAuth2AuthorizationCodeFlow,
5
+ OAuth2ClientCredentials,
6
+ OAuth2ClientCredentialsFlow,
7
+ OAuth2ImplicitFlow,
8
+ OAuth2PKCE,
9
+ OAuth2ResourceOwner,
10
+ OAuth2ResourceOwnerPasswordFlow,
11
+ OAuth2Settings,
12
+ OAuth2TokenConfig
13
+ } from '@opencollection/types/common/auth';
14
+ import type {
15
+ OAuth2 as BrunoOAuth2,
16
+ OAuthAdditionalParameter as BrunoOAuthAdditionalParameter
17
+ } from '@usebruno/schema-types/common/auth';
18
+ import { isString, isNonEmptyString } from '../../../utils';
19
+
20
+ const normalizeBoolean = (value?: boolean | null): boolean | undefined =>
21
+ typeof value === 'boolean' ? value : undefined;
22
+
23
+ const mapSendIn = (sendIn?: string | null): OAuth2AdditionalParameter['placement'] | undefined => {
24
+ if (!isString(sendIn)) {
25
+ return undefined;
26
+ }
27
+
28
+ switch (sendIn.trim().toLowerCase()) {
29
+ case 'headers':
30
+ return 'header';
31
+ case 'queryparams':
32
+ return 'query';
33
+ case 'body':
34
+ return 'body';
35
+ default:
36
+ return undefined;
37
+ }
38
+ };
39
+
40
+ const mapAdditionalParameters = (params?: BrunoOAuthAdditionalParameter[] | null): OAuth2AdditionalParameter[] | undefined => {
41
+ if (!Array.isArray(params) || params.length === 0) {
42
+ return undefined;
43
+ }
44
+
45
+ const mapped = params
46
+ .filter((param) => param && isNonEmptyString(param.name))
47
+ .map((param) => {
48
+ const placement = mapSendIn(param!.sendIn);
49
+ if (!placement) {
50
+ return undefined;
51
+ }
52
+
53
+ const mappedParam: OAuth2AdditionalParameter = {
54
+ name: param!.name!.trim(),
55
+ placement
56
+ };
57
+
58
+ isNonEmptyString(param!.value) && (mappedParam.value = param.value);
59
+
60
+ return mappedParam;
61
+ })
62
+ .filter((param): param is OAuth2AdditionalParameter => Boolean(param));
63
+
64
+ return mapped.length > 0 ? mapped : undefined;
65
+ };
66
+
67
+ const buildClientCredentials = (oauth: BrunoOAuth2): OAuth2ClientCredentials | undefined => {
68
+ const credentials: OAuth2ClientCredentials = {};
69
+
70
+ isNonEmptyString(oauth.clientId) && (credentials.clientId = oauth.clientId);
71
+ isNonEmptyString(oauth.clientSecret) && (credentials.clientSecret = oauth.clientSecret);
72
+ isNonEmptyString(oauth.credentialsPlacement) && (credentials.placement = oauth.credentialsPlacement);
73
+
74
+ return Object.keys(credentials).length > 0 ? credentials : undefined;
75
+ };
76
+
77
+ const buildResourceOwner = (oauth: BrunoOAuth2): OAuth2ResourceOwner | undefined => {
78
+ const resourceOwner: OAuth2ResourceOwner = {};
79
+
80
+ isNonEmptyString(oauth.username) && (resourceOwner.username = oauth.username);
81
+ isNonEmptyString(oauth.password) && (resourceOwner.password = oauth.password);
82
+
83
+ return Object.keys(resourceOwner).length > 0 ? resourceOwner : undefined;
84
+ };
85
+
86
+ const buildPkce = (pkce?: boolean | null): OAuth2PKCE | undefined => {
87
+ if (pkce === null || pkce === undefined) {
88
+ return undefined;
89
+ }
90
+
91
+ // If pkce is false, set disabled: true; if true, return empty object (enabled by default)
92
+ return pkce ? {} : { disabled: true };
93
+ };
94
+
95
+ const buildTokenConfig = (oauth: BrunoOAuth2): OAuth2TokenConfig | undefined => {
96
+ const tokenConfig: OAuth2TokenConfig = {};
97
+
98
+ isNonEmptyString(oauth.credentialsId) && (tokenConfig.id = oauth.credentialsId);
99
+
100
+ if (!isNonEmptyString(oauth.tokenPlacement)) {
101
+ // default to header
102
+ tokenConfig.placement = { header: '' };
103
+ }
104
+
105
+ if (oauth.tokenPlacement === 'header') {
106
+ tokenConfig.placement = {
107
+ header: oauth.tokenHeaderPrefix as string
108
+ };
109
+ }
110
+
111
+ if (oauth.tokenPlacement === 'url') {
112
+ tokenConfig.placement = {
113
+ query: oauth.tokenQueryKey as string
114
+ };
115
+ }
116
+
117
+ return Object.keys(tokenConfig).length > 0 ? tokenConfig : undefined;
118
+ };
119
+
120
+ const buildSettings = (oauth: BrunoOAuth2): OAuth2Settings | undefined => {
121
+ const autoFetchToken = normalizeBoolean(oauth.autoFetchToken);
122
+ const autoRefreshToken = normalizeBoolean(oauth.autoRefreshToken);
123
+
124
+ const settings: OAuth2Settings = {};
125
+ if (autoFetchToken !== undefined) settings.autoFetchToken = autoFetchToken;
126
+ if (autoRefreshToken !== undefined) settings.autoRefreshToken = autoRefreshToken;
127
+
128
+ return Object.keys(settings).length > 0 ? settings : undefined;
129
+ };
130
+
131
+ const buildClientCredentialsFlow = (oauth: BrunoOAuth2): OAuth2ClientCredentialsFlow => {
132
+ const flow: OAuth2ClientCredentialsFlow = {
133
+ type: 'oauth2',
134
+ flow: 'client_credentials'
135
+ };
136
+
137
+ isNonEmptyString(oauth.accessTokenUrl) && (flow.accessTokenUrl = oauth.accessTokenUrl);
138
+ isNonEmptyString(oauth.refreshTokenUrl) && (flow.refreshTokenUrl = oauth.refreshTokenUrl);
139
+
140
+ const credentials = buildClientCredentials(oauth);
141
+ if (credentials) flow.credentials = credentials;
142
+
143
+ isNonEmptyString(oauth.scope) && (flow.scope = oauth.scope);
144
+
145
+ const accessTokenRequest = mapAdditionalParameters(oauth.additionalParameters?.token);
146
+ if (accessTokenRequest) {
147
+ flow.additionalParameters = { accessTokenRequest };
148
+ }
149
+
150
+ const refreshTokenRequest = mapAdditionalParameters(oauth.additionalParameters?.refresh);
151
+ if (refreshTokenRequest) {
152
+ flow.additionalParameters = { refreshTokenRequest };
153
+ }
154
+
155
+ const tokenConfig = buildTokenConfig(oauth);
156
+ if (tokenConfig) flow.tokenConfig = tokenConfig;
157
+
158
+ const settings = buildSettings(oauth);
159
+ if (settings) flow.settings = settings;
160
+
161
+ return flow;
162
+ };
163
+
164
+ const buildResourceOwnerPasswordFlow = (oauth: BrunoOAuth2): OAuth2ResourceOwnerPasswordFlow => {
165
+ const flow: OAuth2ResourceOwnerPasswordFlow = {
166
+ type: 'oauth2',
167
+ flow: 'resource_owner_password_credentials'
168
+ };
169
+
170
+ isNonEmptyString(oauth.accessTokenUrl) && (flow.accessTokenUrl = oauth.accessTokenUrl);
171
+ isNonEmptyString(oauth.refreshTokenUrl) && (flow.refreshTokenUrl = oauth.refreshTokenUrl);
172
+
173
+ const credentials = buildClientCredentials(oauth);
174
+ if (credentials) flow.credentials = credentials;
175
+
176
+ const resourceOwner = buildResourceOwner(oauth);
177
+ if (resourceOwner) flow.resourceOwner = resourceOwner;
178
+
179
+ isNonEmptyString(oauth.scope) && (flow.scope = oauth.scope);
180
+
181
+ const accessTokenRequest = mapAdditionalParameters(oauth.additionalParameters?.token);
182
+ if (accessTokenRequest) {
183
+ flow.additionalParameters = { accessTokenRequest };
184
+ }
185
+
186
+ const refreshTokenRequest = mapAdditionalParameters(oauth.additionalParameters?.refresh);
187
+ if (refreshTokenRequest) {
188
+ flow.additionalParameters = { refreshTokenRequest };
189
+ }
190
+
191
+ const tokenConfig = buildTokenConfig(oauth);
192
+ if (tokenConfig) flow.tokenConfig = tokenConfig;
193
+
194
+ const settings = buildSettings(oauth);
195
+ if (settings) flow.settings = settings;
196
+
197
+ return flow;
198
+ };
199
+
200
+ const buildAuthorizationCodeFlow = (oauth: BrunoOAuth2): OAuth2AuthorizationCodeFlow => {
201
+ const flow: OAuth2AuthorizationCodeFlow = {
202
+ type: 'oauth2',
203
+ flow: 'authorization_code'
204
+ };
205
+
206
+ isNonEmptyString(oauth.authorizationUrl) && (flow.authorizationUrl = oauth.authorizationUrl);
207
+ isNonEmptyString(oauth.accessTokenUrl) && (flow.accessTokenUrl = oauth.accessTokenUrl);
208
+ isNonEmptyString(oauth.refreshTokenUrl) && (flow.refreshTokenUrl = oauth.refreshTokenUrl);
209
+ isNonEmptyString(oauth.callbackUrl) && (flow.callbackUrl = oauth.callbackUrl);
210
+
211
+ const credentials = buildClientCredentials(oauth);
212
+ if (credentials) flow.credentials = credentials;
213
+
214
+ const authorizationRequest = mapAdditionalParameters(oauth.additionalParameters?.authorization);
215
+ if (authorizationRequest) {
216
+ flow.additionalParameters = { authorizationRequest };
217
+ }
218
+
219
+ const accessTokenRequest = mapAdditionalParameters(oauth.additionalParameters?.token);
220
+ if (accessTokenRequest) {
221
+ flow.additionalParameters = { accessTokenRequest };
222
+ }
223
+
224
+ const refreshTokenRequest = mapAdditionalParameters(oauth.additionalParameters?.refresh);
225
+ if (refreshTokenRequest) {
226
+ flow.additionalParameters = { refreshTokenRequest };
227
+ }
228
+
229
+ isNonEmptyString(oauth.scope) && (flow.scope = oauth.scope);
230
+ isNonEmptyString(oauth.state) && (flow.state = oauth.state);
231
+
232
+ const pkce = buildPkce(oauth.pkce);
233
+ if (pkce) flow.pkce = pkce;
234
+
235
+ const tokenConfig = buildTokenConfig(oauth);
236
+ if (tokenConfig) flow.tokenConfig = tokenConfig;
237
+
238
+ const settings = buildSettings(oauth);
239
+ if (settings) flow.settings = settings;
240
+
241
+ return flow;
242
+ };
243
+
244
+ const buildImplicitFlow = (oauth: BrunoOAuth2): OAuth2ImplicitFlow => {
245
+ const flow: OAuth2ImplicitFlow = {
246
+ type: 'oauth2',
247
+ flow: 'implicit'
248
+ };
249
+
250
+ isNonEmptyString(oauth.authorizationUrl) && (flow.authorizationUrl = oauth.authorizationUrl);
251
+ isNonEmptyString(oauth.callbackUrl) && (flow.callbackUrl = oauth.callbackUrl);
252
+ isNonEmptyString(oauth.clientId) && (flow.credentials = { clientId: oauth.clientId });
253
+ isNonEmptyString(oauth.scope) && (flow.scope = oauth.scope);
254
+ isNonEmptyString(oauth.state) && (flow.state = oauth.state);
255
+
256
+ const authorizationRequest = mapAdditionalParameters(oauth.additionalParameters?.authorization);
257
+ if (authorizationRequest) {
258
+ flow.additionalParameters = { authorizationRequest };
259
+ }
260
+
261
+ const tokenConfig = buildTokenConfig(oauth);
262
+ if (tokenConfig) flow.tokenConfig = tokenConfig;
263
+
264
+ const settings = buildSettings(oauth);
265
+ if (settings) flow.settings = settings;
266
+
267
+ return flow;
268
+ };
269
+
270
+ export const toOpenCollectionOAuth2 = (oauth?: BrunoOAuth2 | null): AuthOAuth2 | undefined => {
271
+ if (!oauth) {
272
+ return undefined;
273
+ }
274
+
275
+ switch (oauth.grantType) {
276
+ case 'client_credentials':
277
+ return buildClientCredentialsFlow(oauth);
278
+ case 'password':
279
+ return buildResourceOwnerPasswordFlow(oauth);
280
+ case 'authorization_code':
281
+ return buildAuthorizationCodeFlow(oauth);
282
+ case 'implicit':
283
+ return buildImplicitFlow(oauth);
284
+ default:
285
+ console.warn(`toOpenCollectionOAuth2: Unsupported OAuth2 grant type "${oauth.grantType}".`);
286
+ return undefined;
287
+ }
288
+ };
289
+
290
+ const reversePlacementMapping = (placement?: OAuth2AdditionalParameter['placement']): 'headers' | 'queryparams' | 'body' | null => {
291
+ if (!placement) {
292
+ return null;
293
+ }
294
+
295
+ switch (placement) {
296
+ case 'header':
297
+ return 'headers';
298
+ case 'query':
299
+ return 'queryparams';
300
+ case 'body':
301
+ return 'body';
302
+ default:
303
+ return null;
304
+ }
305
+ };
306
+
307
+ const reverseAdditionalParameters = (params?: OAuth2AdditionalParameter[]): BrunoOAuthAdditionalParameter[] | null => {
308
+ if (!Array.isArray(params) || params.length === 0) {
309
+ return null;
310
+ }
311
+
312
+ const mapped = params.map((param): BrunoOAuthAdditionalParameter => {
313
+ const sendIn = reversePlacementMapping(param.placement);
314
+
315
+ return {
316
+ name: param.name || null,
317
+ value: param.value || null,
318
+ sendIn: sendIn || 'headers',
319
+ enabled: true
320
+ };
321
+ });
322
+
323
+ return mapped.length > 0 ? mapped : null;
324
+ };
325
+
326
+ export const toBrunoOAuth2 = (oauth: AuthOAuth2 | null | undefined): BrunoOAuth2 | null => {
327
+ if (!oauth) {
328
+ return null;
329
+ }
330
+
331
+ const brunoOAuth: BrunoOAuth2 = {
332
+ grantType: 'authorization_code',
333
+ username: null,
334
+ password: null,
335
+ callbackUrl: null,
336
+ authorizationUrl: null,
337
+ accessTokenUrl: null,
338
+ clientId: null,
339
+ clientSecret: null,
340
+ scope: null,
341
+ state: null,
342
+ pkce: false, // Default to false for all grant types
343
+ credentialsPlacement: null,
344
+ credentialsId: null,
345
+ tokenPlacement: null,
346
+ tokenHeaderPrefix: null,
347
+ tokenQueryKey: null,
348
+ refreshTokenUrl: null,
349
+ autoRefreshToken: false, // Default to false
350
+ autoFetchToken: true, // Default to true
351
+ additionalParameters: null
352
+ };
353
+
354
+ switch (oauth.flow) {
355
+ case 'client_credentials':
356
+ brunoOAuth.grantType = 'client_credentials';
357
+ if (oauth.accessTokenUrl) brunoOAuth.accessTokenUrl = oauth.accessTokenUrl;
358
+ if (oauth.refreshTokenUrl) brunoOAuth.refreshTokenUrl = oauth.refreshTokenUrl;
359
+ if (oauth.credentials?.clientId) brunoOAuth.clientId = oauth.credentials.clientId;
360
+ if (oauth.credentials?.clientSecret) brunoOAuth.clientSecret = oauth.credentials.clientSecret;
361
+ if (oauth.credentials?.placement) brunoOAuth.credentialsPlacement = oauth.credentials.placement;
362
+ if (oauth.scope) brunoOAuth.scope = oauth.scope;
363
+
364
+ // token config
365
+ if (oauth.tokenConfig?.id) brunoOAuth.credentialsId = oauth.tokenConfig.id;
366
+ if (oauth.tokenConfig?.placement) {
367
+ if ('header' in oauth.tokenConfig.placement) {
368
+ brunoOAuth.tokenPlacement = 'header';
369
+ brunoOAuth.tokenHeaderPrefix = oauth.tokenConfig.placement.header || '';
370
+ } else if ('query' in oauth.tokenConfig.placement) {
371
+ brunoOAuth.tokenPlacement = 'url';
372
+ brunoOAuth.tokenQueryKey = oauth.tokenConfig.placement.query || '';
373
+ }
374
+ }
375
+
376
+ // additional parameters
377
+ if (oauth.additionalParameters) {
378
+ const tempParams: Record<string, any> = {};
379
+ if (oauth.additionalParameters.accessTokenRequest) {
380
+ const tokenParams = reverseAdditionalParameters(oauth.additionalParameters.accessTokenRequest);
381
+ if (tokenParams) {
382
+ tempParams.token = tokenParams;
383
+ }
384
+ }
385
+ if (oauth.additionalParameters.refreshTokenRequest) {
386
+ const refreshParams = reverseAdditionalParameters(oauth.additionalParameters.refreshTokenRequest);
387
+ if (refreshParams) {
388
+ tempParams.refresh = refreshParams;
389
+ }
390
+ }
391
+ // Only set additionalParameters if there are actual parameters
392
+ if (Object.keys(tempParams).length > 0) {
393
+ brunoOAuth.additionalParameters = tempParams;
394
+ }
395
+ }
396
+ break;
397
+
398
+ case 'resource_owner_password_credentials':
399
+ brunoOAuth.grantType = 'password';
400
+ if (oauth.accessTokenUrl) brunoOAuth.accessTokenUrl = oauth.accessTokenUrl;
401
+ if (oauth.refreshTokenUrl) brunoOAuth.refreshTokenUrl = oauth.refreshTokenUrl;
402
+ if (oauth.credentials?.clientId) brunoOAuth.clientId = oauth.credentials.clientId;
403
+ if (oauth.credentials?.clientSecret) brunoOAuth.clientSecret = oauth.credentials.clientSecret;
404
+ if (oauth.credentials?.placement) brunoOAuth.credentialsPlacement = oauth.credentials.placement;
405
+ if (oauth.resourceOwner?.username) brunoOAuth.username = oauth.resourceOwner.username;
406
+ if (oauth.resourceOwner?.password) brunoOAuth.password = oauth.resourceOwner.password;
407
+ if (oauth.scope) brunoOAuth.scope = oauth.scope;
408
+
409
+ // token config
410
+ if (oauth.tokenConfig?.id) brunoOAuth.credentialsId = oauth.tokenConfig.id;
411
+ if (oauth.tokenConfig?.placement) {
412
+ if ('header' in oauth.tokenConfig.placement) {
413
+ brunoOAuth.tokenPlacement = 'header';
414
+ brunoOAuth.tokenHeaderPrefix = oauth.tokenConfig.placement.header || '';
415
+ } else if ('query' in oauth.tokenConfig.placement) {
416
+ brunoOAuth.tokenPlacement = 'url';
417
+ brunoOAuth.tokenQueryKey = oauth.tokenConfig.placement.query || '';
418
+ }
419
+ }
420
+
421
+ // additional parameters
422
+ if (oauth.additionalParameters) {
423
+ const tempParams: Record<string, any> = {};
424
+ if (oauth.additionalParameters.accessTokenRequest) {
425
+ const tokenParams = reverseAdditionalParameters(oauth.additionalParameters.accessTokenRequest);
426
+ if (tokenParams) {
427
+ tempParams.token = tokenParams;
428
+ }
429
+ }
430
+ if (oauth.additionalParameters.refreshTokenRequest) {
431
+ const refreshParams = reverseAdditionalParameters(oauth.additionalParameters.refreshTokenRequest);
432
+ if (refreshParams) {
433
+ tempParams.refresh = refreshParams;
434
+ }
435
+ }
436
+ // Only set additionalParameters if there are actual parameters
437
+ if (Object.keys(tempParams).length > 0) {
438
+ brunoOAuth.additionalParameters = tempParams;
439
+ }
440
+ }
441
+ break;
442
+
443
+ case 'authorization_code':
444
+ brunoOAuth.grantType = 'authorization_code';
445
+ if (oauth.authorizationUrl) brunoOAuth.authorizationUrl = oauth.authorizationUrl;
446
+ if (oauth.accessTokenUrl) brunoOAuth.accessTokenUrl = oauth.accessTokenUrl;
447
+ if (oauth.refreshTokenUrl) brunoOAuth.refreshTokenUrl = oauth.refreshTokenUrl;
448
+ if (oauth.callbackUrl) brunoOAuth.callbackUrl = oauth.callbackUrl;
449
+ if (oauth.credentials?.clientId) brunoOAuth.clientId = oauth.credentials.clientId;
450
+ if (oauth.credentials?.clientSecret) brunoOAuth.clientSecret = oauth.credentials.clientSecret;
451
+ if (oauth.credentials?.placement) brunoOAuth.credentialsPlacement = oauth.credentials.placement;
452
+ if (oauth.scope) brunoOAuth.scope = oauth.scope;
453
+ if (oauth.state) brunoOAuth.state = oauth.state;
454
+
455
+ // token config
456
+ if (oauth.tokenConfig?.id) brunoOAuth.credentialsId = oauth.tokenConfig.id;
457
+ if (oauth.tokenConfig?.placement) {
458
+ if ('header' in oauth.tokenConfig.placement) {
459
+ brunoOAuth.tokenPlacement = 'header';
460
+ brunoOAuth.tokenHeaderPrefix = oauth.tokenConfig.placement.header || '';
461
+ } else if ('query' in oauth.tokenConfig.placement) {
462
+ brunoOAuth.tokenPlacement = 'url';
463
+ brunoOAuth.tokenQueryKey = oauth.tokenConfig.placement.query || '';
464
+ }
465
+ }
466
+
467
+ // additional parameters
468
+ if (oauth.additionalParameters) {
469
+ const tempParams: Record<string, any> = {};
470
+ if (oauth.additionalParameters.authorizationRequest) {
471
+ const authParams = reverseAdditionalParameters(oauth.additionalParameters.authorizationRequest);
472
+ if (authParams) {
473
+ tempParams.authorization = authParams;
474
+ }
475
+ }
476
+ if (oauth.additionalParameters.accessTokenRequest) {
477
+ const tokenParams = reverseAdditionalParameters(oauth.additionalParameters.accessTokenRequest);
478
+ if (tokenParams) {
479
+ tempParams.token = tokenParams;
480
+ }
481
+ }
482
+ if (oauth.additionalParameters.refreshTokenRequest) {
483
+ const refreshParams = reverseAdditionalParameters(oauth.additionalParameters.refreshTokenRequest);
484
+ if (refreshParams) {
485
+ tempParams.refresh = refreshParams;
486
+ }
487
+ }
488
+ // Only set additionalParameters if there are actual parameters
489
+ if (Object.keys(tempParams).length > 0) {
490
+ brunoOAuth.additionalParameters = tempParams;
491
+ }
492
+ }
493
+ break;
494
+
495
+ case 'implicit':
496
+ brunoOAuth.grantType = 'implicit';
497
+ if (oauth.authorizationUrl) brunoOAuth.authorizationUrl = oauth.authorizationUrl;
498
+ if (oauth.callbackUrl) brunoOAuth.callbackUrl = oauth.callbackUrl;
499
+ if (oauth.credentials?.clientId) brunoOAuth.clientId = oauth.credentials.clientId;
500
+ if (oauth.scope) brunoOAuth.scope = oauth.scope;
501
+ if (oauth.state) brunoOAuth.state = oauth.state;
502
+
503
+ // token config
504
+ if (oauth.tokenConfig?.id) brunoOAuth.credentialsId = oauth.tokenConfig.id;
505
+ if (oauth.tokenConfig?.placement) {
506
+ if ('header' in oauth.tokenConfig.placement) {
507
+ brunoOAuth.tokenPlacement = 'header';
508
+ brunoOAuth.tokenHeaderPrefix = oauth.tokenConfig.placement.header || '';
509
+ } else if ('query' in oauth.tokenConfig.placement) {
510
+ brunoOAuth.tokenPlacement = 'url';
511
+ brunoOAuth.tokenQueryKey = oauth.tokenConfig.placement.query || '';
512
+ }
513
+ }
514
+
515
+ // additional parameters
516
+ if (oauth.additionalParameters) {
517
+ const tempParams: Record<string, any> = {};
518
+ if (oauth.additionalParameters.authorizationRequest) {
519
+ const authParams = reverseAdditionalParameters(oauth.additionalParameters.authorizationRequest);
520
+ if (authParams) {
521
+ tempParams.authorization = authParams;
522
+ }
523
+ }
524
+ // Only set additionalParameters if there are actual parameters
525
+ if (Object.keys(tempParams).length > 0) {
526
+ brunoOAuth.additionalParameters = tempParams;
527
+ }
528
+ }
529
+ break;
530
+
531
+ default:
532
+ return null;
533
+ }
534
+
535
+ if (oauth.settings?.autoFetchToken !== undefined) {
536
+ brunoOAuth.autoFetchToken = oauth.settings.autoFetchToken;
537
+ }
538
+ if (oauth.settings?.autoRefreshToken !== undefined) {
539
+ brunoOAuth.autoRefreshToken = oauth.settings.autoRefreshToken;
540
+ }
541
+
542
+ if (brunoOAuth.grantType === 'authorization_code' && oauth.flow === 'authorization_code') {
543
+ const authCodeFlow = oauth as OAuth2AuthorizationCodeFlow;
544
+ if (authCodeFlow.pkce !== undefined) {
545
+ // If pkce.disabled is true, set pkce to false; otherwise set to true
546
+ brunoOAuth.pkce = !authCodeFlow.pkce.disabled;
547
+ }
548
+ }
549
+
550
+ if (brunoOAuth.additionalParameters === null) {
551
+ delete brunoOAuth.additionalParameters;
552
+ }
553
+
554
+ return brunoOAuth;
555
+ };