@bleedingdev/modern-js-plugin-bff 3.2.0-ultramodern.9 → 3.2.0-ultramodern.90
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/loader.js +23 -0
- package/dist/cjs/runtime/data-platform/index.js +39 -8
- package/dist/cjs/runtime/effect/adapter.js +15 -82
- package/dist/cjs/runtime/effect/context.js +10 -2
- package/dist/cjs/runtime/effect/edge.js +169 -0
- package/dist/cjs/runtime/effect/handler.js +598 -0
- package/dist/cjs/runtime/effect/index.js +16 -545
- package/dist/cjs/runtime/effect/module.js +115 -0
- package/dist/cjs/runtime/effect/operation-context.js +111 -0
- package/dist/cjs/runtime/effect-client/index.js +13 -1
- package/dist/cjs/utils/effectClientGenerator.js +17 -0
- package/dist/esm/loader.mjs +23 -0
- package/dist/esm/runtime/data-platform/index.mjs +31 -9
- package/dist/esm/runtime/effect/adapter.mjs +16 -83
- package/dist/esm/runtime/effect/context.mjs +3 -1
- package/dist/esm/runtime/effect/edge.mjs +90 -0
- package/dist/esm/runtime/effect/handler.mjs +437 -0
- package/dist/esm/runtime/effect/index.mjs +2 -438
- package/dist/esm/runtime/effect/module.mjs +81 -0
- package/dist/esm/runtime/effect/operation-context.mjs +77 -0
- package/dist/esm/runtime/effect-client/index.mjs +14 -2
- package/dist/esm/utils/effectClientGenerator.mjs +17 -0
- package/dist/esm-node/loader.mjs +23 -0
- package/dist/esm-node/runtime/data-platform/index.mjs +31 -9
- package/dist/esm-node/runtime/effect/adapter.mjs +16 -83
- package/dist/esm-node/runtime/effect/context.mjs +3 -1
- package/dist/esm-node/runtime/effect/edge.mjs +91 -0
- package/dist/esm-node/runtime/effect/handler.mjs +438 -0
- package/dist/esm-node/runtime/effect/index.mjs +2 -438
- package/dist/esm-node/runtime/effect/module.mjs +82 -0
- package/dist/esm-node/runtime/effect/operation-context.mjs +78 -0
- package/dist/esm-node/runtime/effect-client/index.mjs +14 -2
- package/dist/esm-node/utils/effectClientGenerator.mjs +17 -0
- package/dist/types/runtime/create-request/index.d.ts +1 -0
- package/dist/types/runtime/data-platform/index.d.ts +4 -0
- package/dist/types/runtime/effect/context.d.ts +3 -6
- package/dist/types/runtime/effect/edge.d.ts +25 -0
- package/dist/types/runtime/effect/handler.d.ts +170 -0
- package/dist/types/runtime/effect/index.d.ts +2 -171
- package/dist/types/runtime/effect/module.d.ts +28 -0
- package/dist/types/runtime/effect/operation-context.d.ts +10 -0
- package/dist/types/runtime/effect-client/index.d.ts +6 -1
- package/package.json +27 -18
package/dist/esm-node/loader.mjs
CHANGED
|
@@ -4,6 +4,24 @@ import { generateClient } from "@modern-js/bff-core";
|
|
|
4
4
|
import { logger } from "@modern-js/utils";
|
|
5
5
|
import path from "path";
|
|
6
6
|
import { generateEffectClientCode, resolveEffectEntryFile } from "./utils/effectClientGenerator.mjs";
|
|
7
|
+
async function transformEffectRuntimeSource(source, filename) {
|
|
8
|
+
const swc = await import("@swc/core");
|
|
9
|
+
const result = await swc.transform(source, {
|
|
10
|
+
filename,
|
|
11
|
+
sourceMaps: false,
|
|
12
|
+
jsc: {
|
|
13
|
+
parser: {
|
|
14
|
+
syntax: "typescript",
|
|
15
|
+
tsx: filename.endsWith('.tsx') || filename.endsWith('.jsx')
|
|
16
|
+
},
|
|
17
|
+
target: 'es2022'
|
|
18
|
+
},
|
|
19
|
+
module: {
|
|
20
|
+
type: 'es6'
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
return result.code;
|
|
24
|
+
}
|
|
7
25
|
async function loader(source) {
|
|
8
26
|
this.cacheable();
|
|
9
27
|
const { resourcePath } = this;
|
|
@@ -15,6 +33,11 @@ async function loader(source) {
|
|
|
15
33
|
apiDir: draftOptions.apiDir,
|
|
16
34
|
effectEntry: draftOptions.effectEntry
|
|
17
35
|
});
|
|
36
|
+
if ('effect' === draftOptions.bffRuntimeFramework && effectEntryFile && path.resolve(effectEntryFile) === path.resolve(resourcePath) && this.resourceQuery.includes('modern-bff-runtime')) {
|
|
37
|
+
const code = await transformEffectRuntimeSource(source, resourcePath);
|
|
38
|
+
callback(void 0, code);
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
18
41
|
if ('effect' === draftOptions.bffRuntimeFramework && effectEntryFile && path.resolve(effectEntryFile) === path.resolve(resourcePath)) {
|
|
19
42
|
const code = await generateEffectClientCode({
|
|
20
43
|
appDir: draftOptions.appDir,
|
|
@@ -1,4 +1,26 @@
|
|
|
1
1
|
import "node:module";
|
|
2
|
+
import { trace as api_trace } from "@opentelemetry/api";
|
|
3
|
+
const DATA_BATCH_TRANSPORT_OTEL_EVENT = 'modernjs.data.batch';
|
|
4
|
+
function createDataBatchTransportTelemetryAttributes(event) {
|
|
5
|
+
return {
|
|
6
|
+
'modernjs.data.batch.type': event.type,
|
|
7
|
+
'modernjs.data.batch.endpoint': event.endpoint,
|
|
8
|
+
'modernjs.data.batch.degraded': 'fallback' === event.type || 'disable' === event.type,
|
|
9
|
+
...event.batchId ? {
|
|
10
|
+
'modernjs.data.batch.id': event.batchId
|
|
11
|
+
} : {},
|
|
12
|
+
...'number' == typeof event.size ? {
|
|
13
|
+
'modernjs.data.batch.size': event.size
|
|
14
|
+
} : {},
|
|
15
|
+
...event.reason ? {
|
|
16
|
+
'modernjs.data.batch.reason': event.reason
|
|
17
|
+
} : {}
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
function emitDataBatchTransportEvent(onEvent, event) {
|
|
21
|
+
onEvent?.(event);
|
|
22
|
+
api_trace.getActiveSpan()?.addEvent(DATA_BATCH_TRANSPORT_OTEL_EVENT, createDataBatchTransportTelemetryAttributes(event));
|
|
23
|
+
}
|
|
2
24
|
const DEFAULT_DATA_ENVELOPE_HEADER = 'x-modernjs-data-envelope';
|
|
3
25
|
const DEFAULT_DATA_BATCH_ENDPOINT = '/_data/batch';
|
|
4
26
|
const DEFAULT_DATA_BATCH_HEADER = 'x-modernjs-data-batch';
|
|
@@ -416,7 +438,7 @@ function createDataBatchTransport(options = {}) {
|
|
|
416
438
|
bucket.items = [];
|
|
417
439
|
bucket.bytes = 0;
|
|
418
440
|
if (1 === items.length || disabledEndpoints.has(endpoint)) {
|
|
419
|
-
onEvent
|
|
441
|
+
emitDataBatchTransportEvent(onEvent, {
|
|
420
442
|
type: disabledEndpoints.has(endpoint) ? 'fallback' : 'flush',
|
|
421
443
|
endpoint,
|
|
422
444
|
size: items.length,
|
|
@@ -433,7 +455,7 @@ function createDataBatchTransport(options = {}) {
|
|
|
433
455
|
sentAt: Date.now(),
|
|
434
456
|
items: items.map((item)=>item.item)
|
|
435
457
|
};
|
|
436
|
-
onEvent
|
|
458
|
+
emitDataBatchTransportEvent(onEvent, {
|
|
437
459
|
type: 'flush',
|
|
438
460
|
endpoint,
|
|
439
461
|
batchId,
|
|
@@ -460,7 +482,7 @@ function createDataBatchTransport(options = {}) {
|
|
|
460
482
|
requestInit.signal = controller.signal;
|
|
461
483
|
timeoutHandle = setTimeout(()=>{
|
|
462
484
|
controller.abort();
|
|
463
|
-
onEvent
|
|
485
|
+
emitDataBatchTransportEvent(onEvent, {
|
|
464
486
|
type: 'fallback',
|
|
465
487
|
endpoint,
|
|
466
488
|
batchId,
|
|
@@ -473,13 +495,13 @@ function createDataBatchTransport(options = {}) {
|
|
|
473
495
|
if (!response.ok) {
|
|
474
496
|
if (404 === response.status || 405 === response.status) {
|
|
475
497
|
disabledEndpoints.add(endpoint);
|
|
476
|
-
onEvent
|
|
498
|
+
emitDataBatchTransportEvent(onEvent, {
|
|
477
499
|
type: 'disable',
|
|
478
500
|
endpoint,
|
|
479
501
|
batchId,
|
|
480
502
|
reason: `batch-endpoint-unavailable-${String(response.status)}`
|
|
481
503
|
});
|
|
482
|
-
} else onEvent
|
|
504
|
+
} else emitDataBatchTransportEvent(onEvent, {
|
|
483
505
|
type: 'fallback',
|
|
484
506
|
endpoint,
|
|
485
507
|
batchId,
|
|
@@ -492,7 +514,7 @@ function createDataBatchTransport(options = {}) {
|
|
|
492
514
|
}
|
|
493
515
|
const result = await response.json();
|
|
494
516
|
if (!isBatchResponsePayload(result)) {
|
|
495
|
-
onEvent
|
|
517
|
+
emitDataBatchTransportEvent(onEvent, {
|
|
496
518
|
type: 'fallback',
|
|
497
519
|
endpoint,
|
|
498
520
|
batchId,
|
|
@@ -515,7 +537,7 @@ function createDataBatchTransport(options = {}) {
|
|
|
515
537
|
return parseResponseLikeCreateRequest(reconstructedResponse);
|
|
516
538
|
});
|
|
517
539
|
} catch (error) {
|
|
518
|
-
onEvent
|
|
540
|
+
emitDataBatchTransportEvent(onEvent, {
|
|
519
541
|
type: 'fallback',
|
|
520
542
|
endpoint,
|
|
521
543
|
batchId,
|
|
@@ -582,7 +604,7 @@ function createDataBatchTransport(options = {}) {
|
|
|
582
604
|
};
|
|
583
605
|
bucket.items.push(queued);
|
|
584
606
|
bucket.bytes += size;
|
|
585
|
-
onEvent
|
|
607
|
+
emitDataBatchTransportEvent(onEvent, {
|
|
586
608
|
type: 'enqueue',
|
|
587
609
|
endpoint,
|
|
588
610
|
size: bucket.items.length
|
|
@@ -597,4 +619,4 @@ function createDataBatchTransport(options = {}) {
|
|
|
597
619
|
return promise;
|
|
598
620
|
};
|
|
599
621
|
}
|
|
600
|
-
export { DEFAULT_DATA_BATCH_ENDPOINT, DEFAULT_DATA_BATCH_HEADER, DEFAULT_DATA_ENVELOPE_HEADER, buildQueryKey, buildScopeKey, createDataBatchTransport, createHydrationEnvelope, createInvalidationEvent, createOperationId, createRequestEnvelope, decodeRequestEnvelopeHeader, deriveChildTraceContext, encodeRequestEnvelopeHeader, formatTraceparentHeader, normalizeOrigin, parseTraceparentHeader, shouldApplyInvalidation, stableStringify, validateHydrationEnvelope, validateRequestEnvelope, validateSelectionPlan };
|
|
622
|
+
export { DATA_BATCH_TRANSPORT_OTEL_EVENT, DEFAULT_DATA_BATCH_ENDPOINT, DEFAULT_DATA_BATCH_HEADER, DEFAULT_DATA_ENVELOPE_HEADER, buildQueryKey, buildScopeKey, createDataBatchTransport, createDataBatchTransportTelemetryAttributes, createHydrationEnvelope, createInvalidationEvent, createOperationId, createRequestEnvelope, decodeRequestEnvelopeHeader, deriveChildTraceContext, emitDataBatchTransportEvent, encodeRequestEnvelopeHeader, formatTraceparentHeader, normalizeOrigin, parseTraceparentHeader, shouldApplyInvalidation, stableStringify, validateHydrationEnvelope, validateRequestEnvelope, validateSelectionPlan };
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import __rslib_shim_module__ from "node:module";
|
|
2
2
|
const require = /*#__PURE__*/ __rslib_shim_module__.createRequire(/*#__PURE__*/ (()=>import.meta.url)());
|
|
3
3
|
import { API_DIR, compatibleRequire, findExists, fs, isProd, logger } from "@modern-js/utils";
|
|
4
|
-
import { HttpApi } from "effect/unstable/httpapi";
|
|
5
4
|
import path from "path";
|
|
6
|
-
import { runWithEffectContext } from "./context.mjs";
|
|
7
|
-
import {
|
|
5
|
+
import { createEffectOperationContext, runWithEffectContext } from "./context.mjs";
|
|
6
|
+
import { resolveEffectBffModuleHandler } from "./module.mjs";
|
|
8
7
|
const before = [
|
|
9
8
|
'custom-server-hook',
|
|
10
9
|
'custom-server-middleware',
|
|
@@ -37,24 +36,9 @@ function createRequestForMountedPrefix(req, prefix) {
|
|
|
37
36
|
url.pathname = nextPath;
|
|
38
37
|
return new Request(url, req);
|
|
39
38
|
}
|
|
40
|
-
function isRequestHandler(value) {
|
|
41
|
-
return 'function' == typeof value;
|
|
42
|
-
}
|
|
43
39
|
function maybeResponse(value) {
|
|
44
40
|
return value instanceof Response;
|
|
45
41
|
}
|
|
46
|
-
function isRecord(value) {
|
|
47
|
-
return 'object' == typeof value && null !== value;
|
|
48
|
-
}
|
|
49
|
-
function includesRuntimeExports(value) {
|
|
50
|
-
return 'api' in value || 'layer' in value || 'createHandler' in value || 'handler' in value;
|
|
51
|
-
}
|
|
52
|
-
function isHttpApiWithProps(value) {
|
|
53
|
-
return HttpApi.isHttpApi(value) && isRecord(value) && 'string' == typeof value.identifier && isRecord(value.groups);
|
|
54
|
-
}
|
|
55
|
-
function isEffectApiDefinition(module) {
|
|
56
|
-
return isHttpApiWithProps(module.api) && void 0 !== module.layer;
|
|
57
|
-
}
|
|
58
42
|
class EffectAdapter {
|
|
59
43
|
resolveEntryFile() {
|
|
60
44
|
const { appDirectory, apiDirectory } = this.api.getServerContext();
|
|
@@ -65,70 +49,13 @@ class EffectAdapter {
|
|
|
65
49
|
return findExists(JS_OR_TS_EXTS.map((ext)=>`${entryWithoutExt}${ext}`));
|
|
66
50
|
}
|
|
67
51
|
async loadEffectHandlerFromModule(mod) {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
};
|
|
76
|
-
if (isRequestHandler(normalizedModule.handler)) return {
|
|
77
|
-
handler: normalizedModule.handler
|
|
78
|
-
};
|
|
79
|
-
const entry = normalizedModule.default;
|
|
80
|
-
if (isRequestHandler(entry)) return {
|
|
81
|
-
handler: entry
|
|
82
|
-
};
|
|
83
|
-
if ('function' == typeof entry && 0 === entry.length) {
|
|
84
|
-
const out = await entry();
|
|
85
|
-
if (isRequestHandler(out)) return {
|
|
86
|
-
handler: out
|
|
87
|
-
};
|
|
88
|
-
mergeRuntimeExports(out);
|
|
89
|
-
}
|
|
90
|
-
if (isRecord(entry)) normalizedModule = {
|
|
91
|
-
...normalizedModule,
|
|
92
|
-
...entry
|
|
93
|
-
};
|
|
94
|
-
if (isRecord(entry) && 'handler' in entry) {
|
|
95
|
-
const maybeHandler = entry.handler;
|
|
96
|
-
if (isRequestHandler(maybeHandler)) normalizedModule = {
|
|
97
|
-
...normalizedModule,
|
|
98
|
-
handler: maybeHandler
|
|
99
|
-
};
|
|
100
|
-
}
|
|
101
|
-
if (isRequestHandler(normalizedModule.handler)) return {
|
|
102
|
-
handler: normalizedModule.handler
|
|
103
|
-
};
|
|
104
|
-
if ('function' == typeof normalizedModule.createHandler) {
|
|
105
|
-
const webHandler = normalizedModule.createHandler({
|
|
106
|
-
openapi: this.api.getServerConfig()?.bff?.effect?.openapi,
|
|
107
|
-
dataPlatform: this.api.getServerConfig()?.bff?.effect?.dataPlatform
|
|
108
|
-
});
|
|
109
|
-
return {
|
|
110
|
-
handler: async (request)=>webHandler.handler(request),
|
|
111
|
-
dispose: async ()=>{
|
|
112
|
-
await webHandler.dispose();
|
|
113
|
-
}
|
|
114
|
-
};
|
|
115
|
-
}
|
|
116
|
-
if (isEffectApiDefinition(normalizedModule)) {
|
|
117
|
-
logger.warn('[BFF][Effect] Detected { api, layer } export without createHandler. Prefer `defineEffectBff(...)` from @modern-js/plugin-bff/server to avoid module instance mismatch.');
|
|
118
|
-
const webHandler = createHttpApiHandler({
|
|
119
|
-
api: normalizedModule.api,
|
|
120
|
-
layer: normalizedModule.layer,
|
|
121
|
-
openapi: this.api.getServerConfig()?.bff?.effect?.openapi,
|
|
122
|
-
dataPlatform: this.api.getServerConfig()?.bff?.effect?.dataPlatform
|
|
123
|
-
});
|
|
124
|
-
return {
|
|
125
|
-
handler: async (request)=>webHandler.handler(request),
|
|
126
|
-
dispose: async ()=>{
|
|
127
|
-
await webHandler.dispose();
|
|
128
|
-
}
|
|
129
|
-
};
|
|
130
|
-
}
|
|
131
|
-
return null;
|
|
52
|
+
return resolveEffectBffModuleHandler(mod, {
|
|
53
|
+
openapi: this.api.getServerConfig()?.bff?.effect?.openapi,
|
|
54
|
+
dataPlatform: this.api.getServerConfig()?.bff?.effect?.dataPlatform,
|
|
55
|
+
onWarning: (message)=>{
|
|
56
|
+
logger.warn(message);
|
|
57
|
+
}
|
|
58
|
+
});
|
|
132
59
|
}
|
|
133
60
|
async reloadHandler() {
|
|
134
61
|
if (!this.isEffect) return;
|
|
@@ -246,7 +173,13 @@ class EffectAdapter {
|
|
|
246
173
|
request: effectRequest,
|
|
247
174
|
env: c.env,
|
|
248
175
|
path: c.req.path,
|
|
249
|
-
method: c.req.method
|
|
176
|
+
method: c.req.method,
|
|
177
|
+
operationContext: createEffectOperationContext({
|
|
178
|
+
request: effectRequest,
|
|
179
|
+
env: c.env,
|
|
180
|
+
path: c.req.path,
|
|
181
|
+
method: c.req.method
|
|
182
|
+
})
|
|
250
183
|
};
|
|
251
184
|
response = await runWithEffectContext(effectContext, ()=>this.handler.length > 1 ? this.handler(effectRequest, effectContext) : this.handler(effectRequest));
|
|
252
185
|
} catch (error) {
|
|
@@ -9,4 +9,6 @@ const useEffectContext = ()=>{
|
|
|
9
9
|
if (!context) throw new Error("Can't call useEffectContext out of Effect runtime scope");
|
|
10
10
|
return context;
|
|
11
11
|
};
|
|
12
|
-
|
|
12
|
+
const useOperationContext = ()=>useEffectContext().operationContext;
|
|
13
|
+
export { createEffectOperationContext } from "./operation-context.mjs";
|
|
14
|
+
export { runWithEffectContext, useEffectContext, useOperationContext };
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import "node:module";
|
|
2
|
+
import { resolveEffectBffModuleHandler } from "./module.mjs";
|
|
3
|
+
import { createEffectOperationContext } from "./operation-context.mjs";
|
|
4
|
+
export * from "./handler.mjs";
|
|
5
|
+
function normalizePrefix(prefix) {
|
|
6
|
+
if (!prefix || '/' === prefix) return '';
|
|
7
|
+
return prefix.endsWith('/') ? prefix.slice(0, -1) : prefix;
|
|
8
|
+
}
|
|
9
|
+
function removePrefixFromPath(pathname, prefix) {
|
|
10
|
+
const normalized = normalizePrefix(prefix);
|
|
11
|
+
if (!normalized || pathname !== normalized && !pathname.startsWith(`${normalized}/`)) return pathname;
|
|
12
|
+
const sliced = pathname.slice(normalized.length);
|
|
13
|
+
return sliced.startsWith('/') ? sliced : `/${sliced}`;
|
|
14
|
+
}
|
|
15
|
+
function matchesPrefix(pathname, prefix) {
|
|
16
|
+
const normalized = normalizePrefix(prefix);
|
|
17
|
+
return !normalized || pathname === normalized || pathname.startsWith(`${normalized}/`);
|
|
18
|
+
}
|
|
19
|
+
function createRequestForMountedPrefix(req, prefix) {
|
|
20
|
+
const url = new URL(req.url);
|
|
21
|
+
const nextPath = removePrefixFromPath(url.pathname, prefix);
|
|
22
|
+
if (nextPath === url.pathname) return req;
|
|
23
|
+
url.pathname = nextPath;
|
|
24
|
+
return new Request(url, req);
|
|
25
|
+
}
|
|
26
|
+
function createEdgeEffectContext(originalRequest, effectRequest, options) {
|
|
27
|
+
const originalPath = options.path || new URL(originalRequest.url).pathname;
|
|
28
|
+
const method = options.method || originalRequest.method;
|
|
29
|
+
return {
|
|
30
|
+
request: effectRequest,
|
|
31
|
+
env: options.env || {},
|
|
32
|
+
path: originalPath,
|
|
33
|
+
method,
|
|
34
|
+
operationContext: createEffectOperationContext({
|
|
35
|
+
request: effectRequest,
|
|
36
|
+
env: options.env || {},
|
|
37
|
+
path: originalPath,
|
|
38
|
+
method
|
|
39
|
+
})
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
function createRuntimeErrorResponse(error) {
|
|
43
|
+
const status = 'object' == typeof error && null !== error && 'status' in error && 'number' == typeof error.status ? error.status : 500;
|
|
44
|
+
return new Response(JSON.stringify({
|
|
45
|
+
message: error instanceof Error ? error.message : '[BFF] Internal Server Error'
|
|
46
|
+
}), {
|
|
47
|
+
status,
|
|
48
|
+
headers: {
|
|
49
|
+
'content-type': 'application/json; charset=utf-8'
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
async function dispatchEffectBffRequest(handler, request, options = {}) {
|
|
54
|
+
const requestPathname = new URL(request.url).pathname;
|
|
55
|
+
if (!matchesPrefix(requestPathname, options.prefix)) return new Response(null, {
|
|
56
|
+
status: 404
|
|
57
|
+
});
|
|
58
|
+
const effectRequest = createRequestForMountedPrefix(request, options.prefix);
|
|
59
|
+
const effectContext = createEdgeEffectContext(request, effectRequest, options);
|
|
60
|
+
try {
|
|
61
|
+
const response = handler.length > 1 ? await handler(effectRequest, effectContext) : await handler(effectRequest);
|
|
62
|
+
if (!(response instanceof Response)) throw new Error('[BFF][Effect] Effect handler must return a Response instance.');
|
|
63
|
+
return new Response(response.body, response);
|
|
64
|
+
} catch (error) {
|
|
65
|
+
if (error instanceof Response) return new Response(error.body, error);
|
|
66
|
+
if (options.onError) {
|
|
67
|
+
const errorResponse = await options.onError(error, effectContext);
|
|
68
|
+
if (errorResponse instanceof Response) return errorResponse;
|
|
69
|
+
}
|
|
70
|
+
return createRuntimeErrorResponse(error);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
async function createEffectBffEdgeHandler(options) {
|
|
74
|
+
const loaded = await resolveEffectBffModuleHandler(options.module, {
|
|
75
|
+
openapi: options.openapi,
|
|
76
|
+
dataPlatform: options.dataPlatform,
|
|
77
|
+
onWarning: options.onWarning
|
|
78
|
+
});
|
|
79
|
+
if (!loaded) throw new Error('[BFF][Effect] Invalid Effect edge module. Export { api, layer }, createHandler, or handler.');
|
|
80
|
+
return {
|
|
81
|
+
handler: (request, dispatchOptions = {})=>dispatchEffectBffRequest(loaded.handler, request, {
|
|
82
|
+
...dispatchOptions,
|
|
83
|
+
prefix: options.prefix,
|
|
84
|
+
onError: options.onError
|
|
85
|
+
}),
|
|
86
|
+
dispose: async ()=>{
|
|
87
|
+
await loaded.dispose?.();
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
export { createEffectBffEdgeHandler, createEffectOperationContext, dispatchEffectBffRequest };
|