@bleedingdev/modern-js-create-request 3.5.0-ultramodern.5 → 3.5.0-ultramodern.75

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.
@@ -0,0 +1,316 @@
1
+ "use strict";
2
+ var __webpack_require__ = {};
3
+ (()=>{
4
+ __webpack_require__.d = (exports1, getters, values)=>{
5
+ var define = (defs, kind)=>{
6
+ for(var key in defs)if (__webpack_require__.o(defs, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
7
+ enumerable: true,
8
+ [kind]: defs[key]
9
+ });
10
+ };
11
+ define(getters, "get");
12
+ define(values, "value");
13
+ };
14
+ })();
15
+ (()=>{
16
+ __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
17
+ })();
18
+ (()=>{
19
+ __webpack_require__.r = (exports1)=>{
20
+ if ("u" > typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
21
+ value: 'Module'
22
+ });
23
+ Object.defineProperty(exports1, '__esModule', {
24
+ value: true
25
+ });
26
+ };
27
+ })();
28
+ var __webpack_exports__ = {};
29
+ __webpack_require__.r(__webpack_exports__);
30
+ __webpack_require__.d(__webpack_exports__, {
31
+ createRequestFactory: ()=>createRequestFactory
32
+ });
33
+ const external_path_to_regexp_namespaceObject = require("path-to-regexp");
34
+ const external_qs_namespaceObject = require("qs");
35
+ const external_policyCore_js_namespaceObject = require("./policyCore.js");
36
+ const external_transport_js_namespaceObject = require("./transport.js");
37
+ const external_types_js_namespaceObject = require("./types.js");
38
+ const external_utiles_js_namespaceObject = require("./utiles.js");
39
+ const OPERATION_CONTEXT_DETAIL_HEADER = external_types_js_namespaceObject.BFF_OPERATION_CONTEXT_DETAIL_HEADER;
40
+ const createRequestFactory = (environment)=>{
41
+ const isServerTarget = 'server' === environment.target;
42
+ const realRequest = new Map();
43
+ const realAllowedHeaders = new Map();
44
+ const realResolveHeaders = new Map();
45
+ const realRequireEnvelope = new Map();
46
+ const realAllowCrossOriginEnvelope = new Map();
47
+ const realTransportResilience = new Map();
48
+ const realIdentityBinding = new Map();
49
+ const realOperationContract = new Map();
50
+ const domainMap = new Map();
51
+ const attachEnvelopeHeaderIfRequired = (headers, requestId, url, incomingHeaders)=>{
52
+ const shouldRequireEnvelope = realRequireEnvelope.get(requestId) ?? (0, external_policyCore_js_namespaceObject.isSecuredRequestId)(requestId);
53
+ if (!shouldRequireEnvelope) return;
54
+ headers[external_types_js_namespaceObject.BFF_ENVELOPE_HEADER] = (0, external_policyCore_js_namespaceObject.buildEnvelopeHeaderValue)({
55
+ requestId,
56
+ target: environment.target,
57
+ sourceOrigin: environment.resolveSourceOrigin(incomingHeaders),
58
+ targetOrigin: (0, external_policyCore_js_namespaceObject.toOrigin)(url),
59
+ traceContext: (0, external_policyCore_js_namespaceObject.parseTraceparentValue)((0, external_policyCore_js_namespaceObject.readHeader)(headers, external_policyCore_js_namespaceObject.TRACEPARENT_HEADER)),
60
+ allowCrossOriginEnvelope: realAllowCrossOriginEnvelope.get(requestId)
61
+ });
62
+ };
63
+ const attachSecuredOperationHeaders = (headers, requestId, method, path, operationContext)=>{
64
+ if (!(0, external_policyCore_js_namespaceObject.isSecuredRequestId)(requestId)) return;
65
+ (0, external_policyCore_js_namespaceObject.attachOperationContextHeaders)({
66
+ headers,
67
+ requestId,
68
+ target: environment.target,
69
+ method,
70
+ path,
71
+ operationContext,
72
+ operationContract: realOperationContract.get(requestId),
73
+ operationContextHeader: external_types_js_namespaceObject.BFF_OPERATION_CONTEXT_HEADER,
74
+ operationContextDetailHeader: OPERATION_CONTEXT_DETAIL_HEADER
75
+ });
76
+ };
77
+ const applyIdentityAndForwardedHeaders = (headers, requestId, incomingHeaders)=>{
78
+ const identityBinding = realIdentityBinding.get(requestId);
79
+ const identityBindingEnabled = identityBinding?.enabled ?? (0, external_policyCore_js_namespaceObject.isSecuredRequestId)(requestId);
80
+ const identityBindingStrict = identityBinding?.strict ?? (0, external_policyCore_js_namespaceObject.isSecuredRequestId)(requestId);
81
+ const protectedIdentityHeaders = (identityBinding?.protectedHeaders || external_types_js_namespaceObject.BFF_DEFAULT_PROTECTED_IDENTITY_HEADERS).map((header)=>header.toLowerCase());
82
+ const targetAllowedHeaders = realAllowedHeaders.get(requestId) || [];
83
+ const forwardedHeaders = {};
84
+ if (isServerTarget) {
85
+ for (const key of targetAllowedHeaders)if (void 0 !== incomingHeaders[key]) forwardedHeaders[key] = incomingHeaders[key];
86
+ }
87
+ if (identityBindingEnabled) {
88
+ const derivedIdentityHeaders = {};
89
+ if (isServerTarget) for (const header of protectedIdentityHeaders){
90
+ const incomingHeaderValue = (0, external_policyCore_js_namespaceObject.readHeader)(incomingHeaders, header);
91
+ if (void 0 !== incomingHeaderValue) (0, external_policyCore_js_namespaceObject.writeHeader)(derivedIdentityHeaders, header, incomingHeaderValue);
92
+ }
93
+ const customDerivedHeaders = identityBinding?.deriveHeaders?.({
94
+ requestId,
95
+ target: environment.target,
96
+ incomingHeaders: isServerTarget ? {
97
+ ...incomingHeaders
98
+ } : {},
99
+ protectedHeaders: [
100
+ ...protectedIdentityHeaders
101
+ ]
102
+ });
103
+ if (customDerivedHeaders && 'object' == typeof customDerivedHeaders) for (const header of protectedIdentityHeaders){
104
+ const customValue = (0, external_policyCore_js_namespaceObject.readHeader)(customDerivedHeaders, header);
105
+ if (void 0 !== customValue) (0, external_policyCore_js_namespaceObject.writeHeader)(derivedIdentityHeaders, header, customValue);
106
+ }
107
+ for (const header of protectedIdentityHeaders){
108
+ const attemptedValue = (0, external_policyCore_js_namespaceObject.readHeader)(headers, header);
109
+ if (void 0 === attemptedValue) continue;
110
+ const violation = {
111
+ requestId,
112
+ target: environment.target,
113
+ header,
114
+ attemptedValue,
115
+ derivedValue: (0, external_policyCore_js_namespaceObject.readHeader)(derivedIdentityHeaders, header),
116
+ reason: 'client_override_blocked'
117
+ };
118
+ identityBinding?.onViolation?.(violation);
119
+ if (identityBindingStrict) throw new external_policyCore_js_namespaceObject.IdentityBindingViolationError(violation);
120
+ (0, external_policyCore_js_namespaceObject.deleteHeader)(headers, header);
121
+ }
122
+ Object.keys(derivedIdentityHeaders).forEach((header)=>{
123
+ if (isServerTarget) (0, external_policyCore_js_namespaceObject.writeHeader)(forwardedHeaders, header, derivedIdentityHeaders[header]);
124
+ else (0, external_policyCore_js_namespaceObject.writeHeader)(headers, header, derivedIdentityHeaders[header]);
125
+ });
126
+ }
127
+ if (isServerTarget) {
128
+ const resolveHeaders = realResolveHeaders.get(requestId);
129
+ if (resolveHeaders) {
130
+ const resolvedHeaders = resolveHeaders({
131
+ requestId,
132
+ allowedHeaders: targetAllowedHeaders,
133
+ incomingHeaders: {
134
+ ...forwardedHeaders
135
+ }
136
+ });
137
+ if (resolvedHeaders && 'object' == typeof resolvedHeaders) {
138
+ for (const key of targetAllowedHeaders)if (void 0 !== resolvedHeaders[key]) {
139
+ if (identityBindingEnabled && protectedIdentityHeaders.includes(key.toLowerCase())) {
140
+ (0, external_policyCore_js_namespaceObject.writeHeader)(forwardedHeaders, key.toLowerCase(), resolvedHeaders[key]);
141
+ continue;
142
+ }
143
+ forwardedHeaders[key] = resolvedHeaders[key];
144
+ }
145
+ }
146
+ }
147
+ }
148
+ if (isServerTarget) return {
149
+ ...headers,
150
+ ...forwardedHeaders
151
+ };
152
+ return headers;
153
+ };
154
+ const configure = (options)=>{
155
+ const { request, interceptor, allowedHeaders, resolveHeaders, transport, requireEnvelope, allowCrossOriginEnvelope, identityBinding, operationContract, setDomain, requestId = 'default' } = options;
156
+ const hasExistingDomain = domainMap.has(requestId);
157
+ if ('default' !== requestId && !setDomain && !hasExistingDomain) throw new external_policyCore_js_namespaceObject.ProducerDomainNotConfiguredError(requestId);
158
+ let configuredRequest = request || environment.originFetch;
159
+ if (interceptor && !request) configuredRequest = interceptor(environment.getFetch());
160
+ if (Array.isArray(allowedHeaders)) realAllowedHeaders.set(requestId, allowedHeaders);
161
+ if (isServerTarget && 'function' == typeof resolveHeaders) realResolveHeaders.set(requestId, resolveHeaders);
162
+ if (transport && 'object' == typeof transport) realTransportResilience.set(requestId, transport);
163
+ if (identityBinding && 'object' == typeof identityBinding) realIdentityBinding.set(requestId, identityBinding);
164
+ if (operationContract && 'object' == typeof operationContract) realOperationContract.set(requestId, operationContract);
165
+ if ('boolean' == typeof requireEnvelope) realRequireEnvelope.set(requestId, requireEnvelope);
166
+ if ('boolean' == typeof allowCrossOriginEnvelope || 'function' == typeof allowCrossOriginEnvelope) realAllowCrossOriginEnvelope.set(requestId, allowCrossOriginEnvelope);
167
+ if (setDomain) {
168
+ const resolvedDomain = setDomain({
169
+ target: environment.target,
170
+ requestId
171
+ });
172
+ if ('default' !== requestId && (0, external_policyCore_js_namespaceObject.isEmptyDomain)(resolvedDomain)) throw new external_policyCore_js_namespaceObject.ProducerDomainNotConfiguredError(requestId);
173
+ if ('string' == typeof resolvedDomain) domainMap.set(requestId, resolvedDomain);
174
+ }
175
+ realRequest.set(requestId, configuredRequest);
176
+ };
177
+ const createRequest = (...args)=>{
178
+ const options = 'object' == typeof args[0] && null !== args[0] ? args[0] : {
179
+ path: args[0],
180
+ method: args[1],
181
+ port: args[2],
182
+ httpMethodDecider: args[3],
183
+ fetch: args[4],
184
+ requestId: args[5],
185
+ operationContext: args[6]
186
+ };
187
+ const { path, method, port, httpMethodDecider = 'functionName', fetch = environment.originFetch, requestId = 'default', operationContext } = options;
188
+ const getFinalPath = (0, external_path_to_regexp_namespaceObject.compile)(path, {
189
+ encode: encodeURIComponent
190
+ });
191
+ const keyNames = (0, external_policyCore_js_namespaceObject.extractPathParamNames)(path);
192
+ const send = (...senderArgs)=>{
193
+ const fetcher = (0, external_policyCore_js_namespaceObject.resolveConfiguredRequest)(realRequest, requestId, fetch);
194
+ const incomingHeaders = environment.readIncomingHeaders();
195
+ let body;
196
+ let headers;
197
+ let url;
198
+ if ('inputParams' === httpMethodDecider) {
199
+ const configDomain = domainMap.get(requestId);
200
+ if ('default' !== requestId && (0, external_policyCore_js_namespaceObject.isEmptyDomain)(configDomain)) throw new external_policyCore_js_namespaceObject.ProducerDomainNotConfiguredError(requestId);
201
+ url = environment.resolveRequestUrl({
202
+ configDomain,
203
+ port,
204
+ path
205
+ });
206
+ body = environment.createInputParamsBody(senderArgs);
207
+ headers = {
208
+ 'Content-Type': 'application/json'
209
+ };
210
+ } else {
211
+ const payload = 'object' == typeof senderArgs[senderArgs.length - 1] ? senderArgs[senderArgs.length - 1] : {};
212
+ payload.params = payload.params || {};
213
+ const requestParams = senderArgs[0];
214
+ if ('object' == typeof requestParams && requestParams.params) {
215
+ const { params } = requestParams;
216
+ keyNames.forEach((keyName)=>{
217
+ payload.params[keyName] = params[keyName];
218
+ });
219
+ } else keyNames.forEach((keyName, index)=>{
220
+ payload.params[keyName] = senderArgs[index];
221
+ });
222
+ const plainPath = getFinalPath(payload.params);
223
+ const finalPath = payload.query ? `${plainPath}?${(0, external_qs_namespaceObject.stringify)(payload.query)}` : plainPath;
224
+ headers = payload.headers ? {
225
+ ...payload.headers
226
+ } : {};
227
+ headers = applyIdentityAndForwardedHeaders(headers, requestId, incomingHeaders);
228
+ if (payload.data) {
229
+ headers['Content-Type'] = 'application/json';
230
+ body = 'object' == typeof payload.data ? JSON.stringify(payload.data) : payload.body;
231
+ } else if (payload.body) {
232
+ headers['Content-Type'] = 'text/plain';
233
+ body = payload.body;
234
+ } else if (payload.formData) body = payload.formData;
235
+ else if (payload.formUrlencoded) {
236
+ headers['Content-Type'] = 'application/x-www-form-urlencoded';
237
+ body = !isServerTarget && "u" > typeof URLSearchParams && payload.formUrlencoded instanceof URLSearchParams ? payload.formUrlencoded : 'object' == typeof payload.formUrlencoded ? (0, external_qs_namespaceObject.stringify)(payload.formUrlencoded) : payload.formUrlencoded;
238
+ }
239
+ const configDomain = domainMap.get(requestId);
240
+ if ('default' !== requestId && (0, external_policyCore_js_namespaceObject.isEmptyDomain)(configDomain)) throw new external_policyCore_js_namespaceObject.ProducerDomainNotConfiguredError(requestId);
241
+ url = environment.resolveRequestUrl({
242
+ configDomain,
243
+ port,
244
+ path: finalPath
245
+ });
246
+ }
247
+ if (!isServerTarget) (0, external_policyCore_js_namespaceObject.writeHeader)(headers, 'accept', "application/json,*/*;q=0.8");
248
+ if (isServerTarget) {
249
+ if (void 0 === (0, external_policyCore_js_namespaceObject.readHeader)(headers, external_policyCore_js_namespaceObject.TRACEPARENT_HEADER)) {
250
+ const incomingTraceparent = (0, external_policyCore_js_namespaceObject.firstHeaderValue)((0, external_policyCore_js_namespaceObject.readHeader)(incomingHeaders, external_policyCore_js_namespaceObject.TRACEPARENT_HEADER));
251
+ if ('string' == typeof incomingTraceparent) (0, external_policyCore_js_namespaceObject.writeHeader)(headers, external_policyCore_js_namespaceObject.TRACEPARENT_HEADER, incomingTraceparent);
252
+ }
253
+ if (void 0 === (0, external_policyCore_js_namespaceObject.readHeader)(headers, external_policyCore_js_namespaceObject.TRACEPARENT_HEADER) && operationContext?.traceparent) (0, external_policyCore_js_namespaceObject.writeHeader)(headers, external_policyCore_js_namespaceObject.TRACEPARENT_HEADER, operationContext.traceparent);
254
+ }
255
+ attachEnvelopeHeaderIfRequired(headers, requestId, url, incomingHeaders);
256
+ attachSecuredOperationHeaders(headers, requestId, method, path, operationContext);
257
+ if ('get' === method.toLowerCase()) body = void 0;
258
+ if (isServerTarget) (0, external_policyCore_js_namespaceObject.writeHeader)(headers, 'accept', "application/json,*/*;q=0.8");
259
+ return (0, external_transport_js_namespaceObject.executeWithResilience)({
260
+ requestId,
261
+ target: environment.target,
262
+ method,
263
+ url,
264
+ init: {
265
+ method,
266
+ body,
267
+ headers
268
+ },
269
+ fetcher: fetcher,
270
+ transport: realTransportResilience.get(requestId)
271
+ });
272
+ };
273
+ const sender = isServerTarget ? send : async (...senderArgs)=>send(...senderArgs);
274
+ return sender;
275
+ };
276
+ const createUploader = ({ path, domain, requestId = 'default', operationContext })=>{
277
+ const getUploadPath = isServerTarget ? void 0 : (0, external_path_to_regexp_namespaceObject.compile)(path, {
278
+ encode: encodeURIComponent
279
+ });
280
+ const sender = (...args)=>{
281
+ const fetcher = (0, external_policyCore_js_namespaceObject.resolveConfiguredRequest)(realRequest, requestId, environment.originFetch);
282
+ const { body, headers: uploadHeaders, params } = (0, external_utiles_js_namespaceObject.getUploadPayload)(args);
283
+ const headers = {
284
+ ...uploadHeaders
285
+ };
286
+ const finalPath = getUploadPath ? getUploadPath(params) : path;
287
+ const configDomain = domainMap.get(requestId);
288
+ const finalURL = environment.resolveUploadUrl({
289
+ configDomain,
290
+ domain,
291
+ path: finalPath
292
+ });
293
+ const incomingHeaders = environment.readIncomingHeaders();
294
+ attachEnvelopeHeaderIfRequired(headers, requestId, finalURL, incomingHeaders);
295
+ attachSecuredOperationHeaders(headers, requestId, 'POST', path, operationContext);
296
+ return fetcher(finalURL, {
297
+ method: 'POST',
298
+ body,
299
+ headers
300
+ });
301
+ };
302
+ return sender;
303
+ };
304
+ return {
305
+ configure,
306
+ createRequest,
307
+ createUploader
308
+ };
309
+ };
310
+ exports.createRequestFactory = __webpack_exports__.createRequestFactory;
311
+ for(var __rspack_i in __webpack_exports__)if (-1 === [
312
+ "createRequestFactory"
313
+ ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
314
+ Object.defineProperty(exports, '__esModule', {
315
+ value: true
316
+ });
@@ -39,6 +39,14 @@ const DEFAULT_RETRYABLE_STATUS_CODES = [
39
39
  const DEFAULT_BASE_DELAY_MS = 100;
40
40
  const DEFAULT_MAX_DELAY_MS = 1000;
41
41
  const DEFAULT_JITTER_RATIO = 0.1;
42
+ const DEFAULT_RETRYABLE_METHODS = new Set([
43
+ 'DELETE',
44
+ 'GET',
45
+ 'HEAD',
46
+ 'OPTIONS',
47
+ 'PUT',
48
+ 'TRACE'
49
+ ]);
42
50
  const createTimeoutError = (timeoutMs)=>{
43
51
  const error = new Error(`Request timed out after ${timeoutMs}ms`);
44
52
  error.name = 'TimeoutError';
@@ -58,7 +66,7 @@ const toStatusCode = (error)=>{
58
66
  const isRetryableNetworkError = (error)=>{
59
67
  if (!error || 'object' != typeof error) return false;
60
68
  const name = error.name;
61
- if ('AbortError' === name || 'FetchError' === name || 'TimeoutError' === name || 'TypeError' === name) return true;
69
+ if ('FetchError' === name || 'TimeoutError' === name || 'TypeError' === name) return true;
62
70
  const code = error.code;
63
71
  return 'ECONNRESET' === code || 'ETIMEDOUT' === code || 'ECONNREFUSED' === code || 'EPIPE' === code;
64
72
  };
@@ -68,7 +76,8 @@ const normalizeJitterRatio = (value)=>{
68
76
  if ('number' != typeof value || !Number.isFinite(value)) return DEFAULT_JITTER_RATIO;
69
77
  return Math.max(0, Math.min(1, value));
70
78
  };
71
- const shouldRetryWithDefaults = (statusCode, error, retryableStatusCodes)=>{
79
+ const shouldRetryWithDefaults = (method, statusCode, error, retryableStatusCodes)=>{
80
+ if (!DEFAULT_RETRYABLE_METHODS.has(method.toUpperCase())) return false;
72
81
  if ('number' == typeof statusCode) return retryableStatusCodes.includes(statusCode);
73
82
  return isRetryableNetworkError(error);
74
83
  };
@@ -78,7 +87,7 @@ const shouldRetry = (retryOptions, context, retryableStatusCodes)=>{
78
87
  } catch (error) {
79
88
  return false;
80
89
  }
81
- return shouldRetryWithDefaults(context.statusCode, context.error, retryableStatusCodes);
90
+ return shouldRetryWithDefaults(context.method, context.statusCode, context.error, retryableStatusCodes);
82
91
  };
83
92
  const getBackoffMs = (retryOptions, attempt)=>{
84
93
  const baseDelayMs = normalizePositiveNumber(retryOptions?.baseDelayMs, DEFAULT_BASE_DELAY_MS);
@@ -1,218 +1,26 @@
1
- import { compile } from "path-to-regexp";
2
- import { stringify } from "qs";
3
1
  import { handleRes } from "./handleRes.mjs";
4
- import { CrossOriginEnvelopePolicyError, IdentityBindingViolationError, OperationContractViolationError, ProducerClientNotInitializedError, ProducerDomainNotConfiguredError, TRACEPARENT_HEADER, attachOperationContextHeaders, buildEnvelopeHeaderValue, deleteHeader, extractPathParamNames, isEmptyDomain, isSecuredRequestId, parseTraceparentValue, readHeader, resolveConfiguredRequest, toOrigin, writeHeader } from "./policyCore.mjs";
5
- import { executeWithResilience } from "./transport.mjs";
6
- import { BFF_DEFAULT_PROTECTED_IDENTITY_HEADERS, BFF_ENVELOPE_HEADER, BFF_OPERATION_CONTEXT_DETAIL_HEADER, BFF_OPERATION_CONTEXT_HEADER } from "./types.mjs";
7
- import { getUploadPayload } from "./utiles.mjs";
2
+ import { createRequestFactory } from "./requestFactory.mjs";
8
3
  export * from "./requestContext.mjs";
9
4
  export * from "./traceparent.mjs";
10
5
  export * from "./types.mjs";
11
- const realRequest = new Map();
12
- const realAllowedHeaders = new Map();
13
- const realRequireEnvelope = new Map();
14
- const realAllowCrossOriginEnvelope = new Map();
15
- const realTransportResilience = new Map();
16
- const realIdentityBinding = new Map();
17
- const realOperationContract = new Map();
18
- const domainMap = new Map();
19
- const OPERATION_CONTEXT_DETAIL_HEADER = BFF_OPERATION_CONTEXT_DETAIL_HEADER;
20
6
  const resolveBrowserOrigin = ()=>"u" > typeof window ? window.location.origin : void 0;
21
7
  const originFetch = (...params)=>{
22
8
  const [url, init] = params;
23
9
  if (init?.method?.toLowerCase() === 'get') init.body = void 0;
24
10
  return fetch(url, init).then(handleRes);
25
11
  };
26
- const attachEnvelopeHeaderIfRequired = (headers, requestId, finalURL)=>{
27
- const shouldRequireEnvelope = realRequireEnvelope.get(requestId) ?? isSecuredRequestId(requestId);
28
- if (!shouldRequireEnvelope) return;
29
- headers[BFF_ENVELOPE_HEADER] = buildEnvelopeHeaderValue({
30
- requestId,
31
- target: 'browser',
32
- sourceOrigin: resolveBrowserOrigin(),
33
- targetOrigin: toOrigin(finalURL),
34
- traceContext: parseTraceparentValue(readHeader(headers, TRACEPARENT_HEADER)),
35
- allowCrossOriginEnvelope: realAllowCrossOriginEnvelope.get(requestId)
36
- });
37
- };
38
- const attachSecuredOperationHeaders = (headers, requestId, method, path, operationContext)=>{
39
- if (!isSecuredRequestId(requestId)) return;
40
- attachOperationContextHeaders({
41
- headers,
42
- requestId,
43
- target: 'browser',
44
- method,
45
- path,
46
- operationContext,
47
- operationContract: realOperationContract.get(requestId),
48
- operationContextHeader: BFF_OPERATION_CONTEXT_HEADER,
49
- operationContextDetailHeader: OPERATION_CONTEXT_DETAIL_HEADER
50
- });
51
- };
52
- const configure = (options)=>{
53
- const { request, interceptor, allowedHeaders, transport, requireEnvelope, allowCrossOriginEnvelope, identityBinding, operationContract, setDomain, requestId = 'default' } = options;
54
- const hasExistingDomain = domainMap.has(requestId);
55
- if ('default' !== requestId && !setDomain && !hasExistingDomain) throw new ProducerDomainNotConfiguredError(requestId);
56
- let configuredRequest = request || originFetch;
57
- if (interceptor && !request) configuredRequest = interceptor(fetch);
58
- if (Array.isArray(allowedHeaders)) realAllowedHeaders.set(requestId, allowedHeaders);
59
- if (transport && 'object' == typeof transport) realTransportResilience.set(requestId, transport);
60
- if (identityBinding && 'object' == typeof identityBinding) realIdentityBinding.set(requestId, identityBinding);
61
- if (operationContract && 'object' == typeof operationContract) realOperationContract.set(requestId, operationContract);
62
- if ('boolean' == typeof requireEnvelope) realRequireEnvelope.set(requestId, requireEnvelope);
63
- if ('boolean' == typeof allowCrossOriginEnvelope || 'function' == typeof allowCrossOriginEnvelope) realAllowCrossOriginEnvelope.set(requestId, allowCrossOriginEnvelope);
64
- if (setDomain) {
65
- const resolvedDomain = setDomain({
66
- target: 'browser',
67
- requestId
68
- });
69
- if ('default' !== requestId && isEmptyDomain(resolvedDomain)) throw new ProducerDomainNotConfiguredError(requestId);
70
- if ('string' == typeof resolvedDomain) domainMap.set(requestId, resolvedDomain);
71
- }
72
- realRequest.set(requestId, configuredRequest);
73
- };
74
- const normalizeRequestOptions = (...args)=>{
75
- if ('object' == typeof args[0] && null !== args[0]) return args[0];
76
- const [path, method, port, httpMethodDecider, fetch1, requestId, operationContext] = args;
77
- return {
78
- path,
79
- method,
80
- port,
81
- httpMethodDecider,
82
- fetch: fetch1,
83
- requestId,
84
- operationContext
85
- };
86
- };
87
- const createRequest = (...args)=>{
88
- const { path, method, port, httpMethodDecider = 'functionName', fetch: fetch1 = originFetch, domain, requestId = 'default', operationContext } = normalizeRequestOptions(...args);
89
- const getFinalPath = compile(path, {
90
- encode: encodeURIComponent
91
- });
92
- const keyNames = extractPathParamNames(path);
93
- const sender = async (...args)=>{
94
- const fetcher = resolveConfiguredRequest(realRequest, requestId, fetch1);
95
- let body;
96
- let finalURL;
97
- let headers;
98
- if ('inputParams' === httpMethodDecider) {
99
- finalURL = path;
100
- body = JSON.stringify({
101
- args
102
- });
103
- headers = {
104
- 'Content-Type': 'application/json'
105
- };
106
- } else {
107
- const payload = 'object' == typeof args[args.length - 1] ? args[args.length - 1] : {};
108
- payload.params = payload.params || {};
109
- const requestParams = args[0];
110
- if ('object' == typeof requestParams && requestParams.params) {
111
- const { params } = requestParams;
112
- keyNames.forEach((keyName)=>{
113
- payload.params[keyName] = params[keyName];
114
- });
115
- } else keyNames.forEach((keyName, index)=>{
116
- payload.params[keyName] = args[index];
117
- });
118
- const finalPath = getFinalPath(payload.params);
119
- finalURL = payload.query ? `${finalPath}?${stringify(payload.query)}` : finalPath;
120
- headers = payload.headers ? {
121
- ...payload.headers
122
- } : {};
123
- const identityBinding = realIdentityBinding.get(requestId);
124
- const identityBindingEnabled = identityBinding?.enabled ?? isSecuredRequestId(requestId);
125
- const identityBindingStrict = identityBinding?.strict ?? isSecuredRequestId(requestId);
126
- const protectedIdentityHeaders = (identityBinding?.protectedHeaders || BFF_DEFAULT_PROTECTED_IDENTITY_HEADERS).map((header)=>header.toLowerCase());
127
- if (identityBindingEnabled) {
128
- const derivedIdentityHeaders = {};
129
- const customDerivedHeaders = identityBinding?.deriveHeaders?.({
130
- requestId,
131
- target: 'browser',
132
- incomingHeaders: {},
133
- protectedHeaders: [
134
- ...protectedIdentityHeaders
135
- ]
136
- });
137
- if (customDerivedHeaders && 'object' == typeof customDerivedHeaders) for (const header of protectedIdentityHeaders){
138
- const customValue = readHeader(customDerivedHeaders, header);
139
- if (void 0 !== customValue) writeHeader(derivedIdentityHeaders, header, customValue);
140
- }
141
- for (const header of protectedIdentityHeaders){
142
- const attemptedValue = readHeader(headers, header);
143
- if (void 0 === attemptedValue) continue;
144
- const violation = {
145
- requestId,
146
- target: 'browser',
147
- header,
148
- attemptedValue,
149
- derivedValue: readHeader(derivedIdentityHeaders, header),
150
- reason: identityBindingStrict ? 'client_override_rejected' : 'client_override_blocked'
151
- };
152
- identityBinding?.onViolation?.(violation);
153
- if (identityBindingStrict) throw new IdentityBindingViolationError(violation);
154
- deleteHeader(headers, header);
155
- }
156
- Object.keys(derivedIdentityHeaders).forEach((header)=>{
157
- writeHeader(headers, header, derivedIdentityHeaders[header]);
158
- });
159
- }
160
- body = payload.data && 'object' == typeof payload.data ? JSON.stringify(payload.data) : payload.body;
161
- if (payload.data) {
162
- headers['Content-Type'] = 'application/json';
163
- body = 'object' == typeof payload.data ? JSON.stringify(payload.data) : payload.body;
164
- } else if (payload.body) {
165
- headers['Content-Type'] = 'text/plain';
166
- body = payload.body;
167
- } else if (payload.formData) body = payload.formData;
168
- else if (payload.formUrlencoded) {
169
- headers['Content-Type'] = 'application/x-www-form-urlencoded';
170
- body = 'object' != typeof payload.formUrlencoded || payload.formUrlencoded instanceof URLSearchParams ? payload.formUrlencoded : stringify(payload.formUrlencoded);
171
- }
172
- }
173
- headers.accept = "application/json,*/*;q=0.8";
174
- const configDomain = domainMap.get(requestId);
175
- if ('default' !== requestId && isEmptyDomain(configDomain)) throw new ProducerDomainNotConfiguredError(requestId);
176
- finalURL = `${configDomain || ''}${finalURL}`;
177
- attachEnvelopeHeaderIfRequired(headers, requestId, finalURL);
178
- attachSecuredOperationHeaders(headers, requestId, method, path, operationContext);
179
- return executeWithResilience({
180
- requestId,
181
- target: 'browser',
182
- method,
183
- url: finalURL,
184
- init: {
185
- method,
186
- body,
187
- headers
188
- },
189
- fetcher,
190
- transport: realTransportResilience.get(requestId)
191
- });
192
- };
193
- return sender;
194
- };
195
- const createUploader = ({ path, domain, requestId = 'default', operationContext })=>{
196
- const getFinalPath = compile(path, {
197
- encode: encodeURIComponent
198
- });
199
- const sender = (...args)=>{
200
- const fetcher = resolveConfiguredRequest(realRequest, requestId, originFetch);
201
- const { body, headers: uploadHeaders, params } = getUploadPayload(args);
202
- const headers = {
203
- ...uploadHeaders
204
- };
205
- const finalPath = getFinalPath(params);
206
- const configDomain = domainMap.get(requestId);
207
- const finalURL = `${configDomain || domain || ''}${finalPath}`;
208
- attachEnvelopeHeaderIfRequired(headers, requestId, finalURL);
209
- attachSecuredOperationHeaders(headers, requestId, 'POST', path, operationContext);
210
- return fetcher(finalURL, {
211
- method: 'POST',
212
- body,
213
- headers
214
- });
215
- };
216
- return sender;
217
- };
218
- export { CrossOriginEnvelopePolicyError, IdentityBindingViolationError, OperationContractViolationError, ProducerClientNotInitializedError, ProducerDomainNotConfiguredError, configure, createRequest, createUploader };
12
+ const requestFactory = createRequestFactory({
13
+ target: 'browser',
14
+ getFetch: ()=>fetch,
15
+ originFetch: originFetch,
16
+ readIncomingHeaders: ()=>({}),
17
+ resolveSourceOrigin: resolveBrowserOrigin,
18
+ createInputParamsBody: (args)=>JSON.stringify({
19
+ args
20
+ }),
21
+ resolveRequestUrl: ({ configDomain, path })=>`${configDomain || ''}${path}`,
22
+ resolveUploadUrl: ({ configDomain, domain, path })=>`${configDomain || domain || ''}${path}`
23
+ });
24
+ const { configure: configure, createRequest: createRequest, createUploader: createUploader } = requestFactory;
25
+ export { CrossOriginEnvelopePolicyError, IdentityBindingViolationError, OperationContractViolationError, ProducerClientNotInitializedError, ProducerDomainNotConfiguredError } from "./policyCore.mjs";
26
+ export { configure, createRequest, createUploader };