@bleedingdev/modern-js-plugin-bff 3.4.0-ultramodern.9 → 3.5.0-ultramodern.1

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.
@@ -39,7 +39,6 @@ __webpack_require__.r(__webpack_exports__);
39
39
  __webpack_require__.d(__webpack_exports__, {
40
40
  EffectAdapter: ()=>EffectAdapter
41
41
  });
42
- const bff_core_namespaceObject = require("@modern-js/bff-core");
43
42
  const utils_namespaceObject = require("@modern-js/utils");
44
43
  const httpapi_namespaceObject = require("effect/unstable/httpapi");
45
44
  const external_path_namespaceObject = require("path");
@@ -94,43 +93,12 @@ class EffectAdapter {
94
93
  const { appDirectory, apiDirectory } = this.api.getServerContext();
95
94
  const bffConfig = this.api.getServerConfig()?.bff;
96
95
  const configuredEntry = bffConfig?.effect?.entry;
97
- const defaultEntry = external_path_default().resolve(appDirectory || process.cwd(), apiDirectory || utils_namespaceObject.API_DIR, 'effect', 'index');
98
- const entryWithoutExt = configuredEntry ? external_path_default().isAbsolute(configuredEntry) ? configuredEntry : external_path_default().resolve(appDirectory || process.cwd(), configuredEntry) : defaultEntry;
99
- return resolveJsOrTsEntry(entryWithoutExt);
100
- }
101
- isApiRequestPath(requestPath, prefix, enableHandleWeb) {
102
- if (!enableHandleWeb) return true;
103
- const normalized = normalizePrefix(prefix);
104
- if (!normalized) return true;
105
- return requestPath === normalized || requestPath.startsWith(`${normalized}/`);
106
- }
107
- async collectLambdaContractSources() {
108
- try {
109
- const serverContext = this.api.getServerContext();
110
- const appDir = serverContext.distDirectory || serverContext.appDirectory;
111
- if (!appDir) return [];
112
- const apiDir = 'string' == typeof serverContext.apiDirectory ? serverContext.apiDirectory : external_path_default().resolve(appDir, utils_namespaceObject.API_DIR);
113
- const lambdaDir = 'string' == typeof serverContext.lambdaDirectory ? serverContext.lambdaDirectory : external_path_default().join(apiDir, 'lambda');
114
- if (!await utils_namespaceObject.fs.pathExists(lambdaDir)) return [];
115
- const apiRouter = new bff_core_namespaceObject.ApiRouter({
116
- appDir,
117
- apiDir,
118
- lambdaDir,
119
- prefix: this.prefix,
120
- httpMethodDecider: this.api.getServerConfig()?.bff?.httpMethodDecider
121
- });
122
- const handlerInfos = await apiRouter.getApiHandlers();
123
- return handlerInfos.map((info)=>({
124
- name: info.name,
125
- httpMethod: info.httpMethod,
126
- routePath: info.routePath,
127
- filename: info.filename,
128
- handler: info.handler
129
- }));
130
- } catch (error) {
131
- utils_namespaceObject.logger.warn(`[BFF][Effect] Failed to derive lambda operation contracts for the cross-project policy: ${String(error)}`);
132
- return [];
96
+ if (configuredEntry) {
97
+ const entryWithoutExt = external_path_default().isAbsolute(configuredEntry) ? configuredEntry : external_path_default().resolve(appDirectory || process.cwd(), configuredEntry);
98
+ return resolveJsOrTsEntry(entryWithoutExt);
133
99
  }
100
+ const apiRoot = external_path_default().resolve(appDirectory || process.cwd(), apiDirectory || utils_namespaceObject.API_DIR);
101
+ return resolveJsOrTsEntry(external_path_default().resolve(apiRoot, 'index'));
134
102
  }
135
103
  async refreshCrossProjectPolicy(mod) {
136
104
  let contractSources = [];
@@ -146,24 +114,15 @@ class EffectAdapter {
146
114
  } catch (error) {
147
115
  utils_namespaceObject.logger.warn(`[BFF][Effect] Failed to reflect HttpApi endpoints for the cross-project policy: ${String(error)}`);
148
116
  }
149
- let policy = (0, crossProjectServerPolicy_js_namespaceObject.resolveAdapterCrossProjectPolicy)(this.api, contractSources);
150
- if (policy?.enabled) {
151
- const lambdaSources = await this.collectLambdaContractSources();
152
- if (lambdaSources.length > 0) {
153
- contractSources = [
154
- ...contractSources,
155
- ...lambdaSources
156
- ];
157
- policy = (0, crossProjectServerPolicy_js_namespaceObject.resolveAdapterCrossProjectPolicy)(this.api, contractSources);
158
- }
159
- }
117
+ const policy = (0, crossProjectServerPolicy_js_namespaceObject.resolveAdapterCrossProjectPolicy)(this.api, contractSources);
160
118
  this.crossProjectPolicy = policy;
161
119
  if (this.crossProjectPolicy?.enabled && 0 === contractSources.length) utils_namespaceObject.logger.warn('[BFF][Effect] Cross-project policy is enabled but no HttpApi endpoints could be reflected; operation-contract matching is disabled for this server (envelope and operation-context checks still apply).');
162
120
  }
163
121
  async loadEffectHandlerFromModule(mod) {
122
+ const effectConfig = this.api.getServerConfig()?.bff?.effect;
164
123
  return (0, external_module_js_namespaceObject.resolveEffectBffModuleHandler)(mod, {
165
- openapi: this.api.getServerConfig()?.bff?.effect?.openapi,
166
- dataPlatform: this.api.getServerConfig()?.bff?.effect?.dataPlatform,
124
+ openapi: effectConfig?.openapi,
125
+ dataPlatform: effectConfig?.dataPlatform,
167
126
  validateRequest: (request)=>(0, crossProjectServerPolicy_js_namespaceObject.checkCrossProjectPolicyForRequest)(request, this.crossProjectPolicy),
168
127
  onWarning: (message)=>{
169
128
  utils_namespaceObject.logger.warn(message);
@@ -197,13 +156,12 @@ class EffectAdapter {
197
156
  await this.refreshCrossProjectPolicy(mod);
198
157
  const loaded = await this.loadEffectHandlerFromModule(mod);
199
158
  if (!loaded) {
200
- utils_namespaceObject.logger.warn(`[BFF][Effect] Invalid Effect entry module: ${entryFile}. Export { api, layer } or handler.`);
159
+ utils_namespaceObject.logger.warn(`[BFF][Effect] Invalid Effect entry module: ${entryFile}. Export defineEffectBff(...) or a { api, layer } HttpApi module.`);
201
160
  this.handler = null;
202
161
  return;
203
162
  }
204
163
  this.handler = loaded.handler;
205
164
  this.dispose = loaded.dispose || null;
206
- this.policyEnforcedInMiddleware = !loaded.appliesRequestValidator;
207
165
  }
208
166
  async disposeCurrentHandler() {
209
167
  if (!this.dispose) return;
@@ -255,7 +213,6 @@ class EffectAdapter {
255
213
  this.handler = null;
256
214
  this.dispose = null;
257
215
  this.prefix = '/api';
258
- this.policyEnforcedInMiddleware = false;
259
216
  this.registerMiddleware = async (options)=>{
260
217
  const { prefix, enableHandleWeb } = options;
261
218
  const { bffRuntimeFramework, middlewares: globalMiddlewares } = this.api.getServerContext();
@@ -266,7 +223,7 @@ class EffectAdapter {
266
223
  this.prefix = prefix || this.prefix;
267
224
  await this.reloadHandler();
268
225
  this.effectMiddleware = {
269
- name: 'effect-bff-handler',
226
+ name: 'effect-api-handler',
270
227
  path: enableHandleWeb ? '*' : `${prefix}/*`,
271
228
  method: 'all',
272
229
  order: 'post',
@@ -274,11 +231,7 @@ class EffectAdapter {
274
231
  handler: async (c, next)=>{
275
232
  if (!this.handler) {
276
233
  if (enableHandleWeb) return void await next();
277
- return this.handleRuntimeError(new Error('[BFF][Effect] Missing Effect entry. Define api/effect/index or configure bff.effect.entry.'), c);
278
- }
279
- if (this.crossProjectPolicy?.enabled && this.policyEnforcedInMiddleware && this.isApiRequestPath(c.req.path, prefix, enableHandleWeb)) {
280
- const denial = (0, crossProjectServerPolicy_js_namespaceObject.checkCrossProjectPolicyForRequest)(c.req.raw, this.crossProjectPolicy);
281
- if (denial) return denial;
234
+ return this.handleRuntimeError(new Error('[BFF][Effect] Missing Effect entry. Define api/index or configure bff.effect.entry.'), c);
282
235
  }
283
236
  let response;
284
237
  try {
@@ -0,0 +1,81 @@
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
+ createEffectOperationContext: ()=>external_operation_context_js_namespaceObject.createEffectOperationContext,
32
+ runWithEffectContext: ()=>runWithEffectContext,
33
+ useEffectContext: ()=>useEffectContext,
34
+ useOperationContext: ()=>useOperationContext
35
+ });
36
+ const external_operation_context_js_namespaceObject = require("./operation-context.js");
37
+ const kEffectContext = Symbol.for('modernjs.plugin-bff.edgeEffectContext');
38
+ const kEffectContextStorage = Symbol.for('modernjs.plugin-bff.edgeEffectContextStorage');
39
+ const globalStore = globalThis;
40
+ const isPromiseLike = (value)=>'object' == typeof value && null !== value && 'then' in value && 'function' == typeof value.then;
41
+ const getRuntimeStorage = ()=>{
42
+ if (globalStore[kEffectContextStorage]) return globalStore[kEffectContextStorage];
43
+ if ('function' == typeof globalStore.AsyncLocalStorage) globalStore[kEffectContextStorage] = new globalStore.AsyncLocalStorage();
44
+ return globalStore[kEffectContextStorage];
45
+ };
46
+ const runWithEffectContext = (context, cb)=>{
47
+ const storage = getRuntimeStorage();
48
+ if (storage) return storage.run(context, cb);
49
+ const previous = globalStore[kEffectContext];
50
+ globalStore[kEffectContext] = context;
51
+ try {
52
+ const result = cb();
53
+ if (isPromiseLike(result)) return Promise.resolve(result).finally(()=>{
54
+ globalStore[kEffectContext] = previous;
55
+ });
56
+ globalStore[kEffectContext] = previous;
57
+ return result;
58
+ } catch (error) {
59
+ globalStore[kEffectContext] = previous;
60
+ throw error;
61
+ }
62
+ };
63
+ const useEffectContext = ()=>{
64
+ const context = getRuntimeStorage()?.getStore() ?? globalStore[kEffectContext];
65
+ if (!context) throw new Error("Can't call useEffectContext out of Effect runtime scope");
66
+ return context;
67
+ };
68
+ const useOperationContext = ()=>useEffectContext().operationContext;
69
+ exports.createEffectOperationContext = __webpack_exports__.createEffectOperationContext;
70
+ exports.runWithEffectContext = __webpack_exports__.runWithEffectContext;
71
+ exports.useEffectContext = __webpack_exports__.useEffectContext;
72
+ exports.useOperationContext = __webpack_exports__.useOperationContext;
73
+ for(var __rspack_i in __webpack_exports__)if (-1 === [
74
+ "createEffectOperationContext",
75
+ "runWithEffectContext",
76
+ "useEffectContext",
77
+ "useOperationContext"
78
+ ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
79
+ Object.defineProperty(exports, '__esModule', {
80
+ value: true
81
+ });
@@ -3,6 +3,9 @@ var __webpack_modules__ = {
3
3
  "../safe-failure" (module) {
4
4
  module.exports = require("../safe-failure.js");
5
5
  },
6
+ "./edge-context" (module) {
7
+ module.exports = require("./edge-context.js");
8
+ },
6
9
  "./handler" (module) {
7
10
  module.exports = require("./handler.js");
8
11
  },
@@ -61,16 +64,21 @@ var __webpack_exports__ = {};
61
64
  (()=>{
62
65
  __webpack_require__.r(__webpack_exports__);
63
66
  var _safe_failure__rspack_import_0 = __webpack_require__("../safe-failure");
64
- var _module__rspack_import_1 = __webpack_require__("./module");
65
- var _operation_context__rspack_import_2 = __webpack_require__("./operation-context");
66
- var _handler__rspack_import_3 = __webpack_require__("./handler");
67
+ var _edge_context__rspack_import_1 = __webpack_require__("./edge-context");
68
+ var _module__rspack_import_2 = __webpack_require__("./module");
69
+ var _operation_context__rspack_import_3 = __webpack_require__("./operation-context");
70
+ var _handler__rspack_import_4 = __webpack_require__("./handler");
67
71
  var __rspack_reexport = {};
68
- for(const __rspack_import_key in _handler__rspack_import_3)if ([
72
+ for(const __rspack_import_key in _handler__rspack_import_4)if ([
73
+ "runWithEffectContext",
74
+ "useEffectContext",
69
75
  "default",
70
- "dispatchEffectBffRequest",
76
+ "useOperationContext",
71
77
  "createEffectOperationContext",
78
+ "dispatchEffectBffRequest",
79
+ "createEffectBffTestHandler",
72
80
  "createEffectBffEdgeHandler"
73
- ].indexOf(__rspack_import_key) < 0) __rspack_reexport[__rspack_import_key] = ()=>_handler__rspack_import_3[__rspack_import_key];
81
+ ].indexOf(__rspack_import_key) < 0) __rspack_reexport[__rspack_import_key] = ()=>_handler__rspack_import_4[__rspack_import_key];
74
82
  __webpack_require__.d(__webpack_exports__, __rspack_reexport);
75
83
  function normalizePrefix(prefix) {
76
84
  if (!prefix || '/' === prefix) return '';
@@ -101,7 +109,7 @@ var __webpack_exports__ = {};
101
109
  env: options.env || {},
102
110
  path: originalPath,
103
111
  method,
104
- operationContext: (0, _operation_context__rspack_import_2.createEffectOperationContext)({
112
+ operationContext: (0, _operation_context__rspack_import_3.createEffectOperationContext)({
105
113
  request: effectRequest,
106
114
  env: options.env || {},
107
115
  path: originalPath,
@@ -120,7 +128,7 @@ var __webpack_exports__ = {};
120
128
  const effectRequest = createRequestForMountedPrefix(request, options.prefix);
121
129
  const effectContext = createEdgeEffectContext(request, effectRequest, options);
122
130
  try {
123
- const response = handler.length > 1 ? await handler(effectRequest, effectContext) : await handler(effectRequest);
131
+ const response = await (0, _edge_context__rspack_import_1.runWithEffectContext)(effectContext, ()=>handler.length > 1 ? handler(effectRequest, effectContext) : handler(effectRequest));
124
132
  if (!(response instanceof Response)) throw new Error('[BFF][Effect] Effect handler must return a Response instance.');
125
133
  return new Response(response.body, response);
126
134
  } catch (error) {
@@ -132,13 +140,14 @@ var __webpack_exports__ = {};
132
140
  return createRuntimeErrorResponse(error);
133
141
  }
134
142
  }
143
+ const createEffectBffTestHandler = createEffectBffEdgeHandler;
135
144
  async function createEffectBffEdgeHandler(options) {
136
- const loaded = await (0, _module__rspack_import_1.resolveEffectBffModuleHandler)(options.module, {
145
+ const loaded = await (0, _module__rspack_import_2.resolveEffectBffModuleHandler)(options.module, {
137
146
  openapi: options.openapi,
138
147
  dataPlatform: options.dataPlatform,
139
148
  onWarning: options.onWarning
140
149
  });
141
- if (!loaded) throw new Error('[BFF][Effect] Invalid Effect edge module. Export { api, layer }, createHandler, or handler.');
150
+ if (!loaded) throw new Error('[BFF][Effect] Invalid Effect edge module. Export defineEffectBff(...) or a { api, layer } HttpApi module.');
142
151
  return {
143
152
  handler: (request, dispatchOptions = {})=>dispatchEffectBffRequest(loaded.handler, request, {
144
153
  ...dispatchOptions,
@@ -152,17 +161,30 @@ var __webpack_exports__ = {};
152
161
  }
153
162
  __webpack_require__.d(__webpack_exports__, {
154
163
  createEffectBffEdgeHandler: ()=>createEffectBffEdgeHandler,
155
- createEffectOperationContext: ()=>_operation_context__rspack_import_2.createEffectOperationContext,
156
- dispatchEffectBffRequest: ()=>dispatchEffectBffRequest
164
+ createEffectOperationContext: ()=>_operation_context__rspack_import_3.createEffectOperationContext,
165
+ dispatchEffectBffRequest: ()=>dispatchEffectBffRequest,
166
+ runWithEffectContext: ()=>_edge_context__rspack_import_1.runWithEffectContext,
167
+ useEffectContext: ()=>_edge_context__rspack_import_1.useEffectContext,
168
+ useOperationContext: ()=>_edge_context__rspack_import_1.useOperationContext
169
+ }, {
170
+ createEffectBffTestHandler: createEffectBffTestHandler
157
171
  });
158
172
  })();
159
173
  exports.createEffectBffEdgeHandler = __webpack_exports__.createEffectBffEdgeHandler;
174
+ exports.createEffectBffTestHandler = __webpack_exports__.createEffectBffTestHandler;
160
175
  exports.createEffectOperationContext = __webpack_exports__.createEffectOperationContext;
161
176
  exports.dispatchEffectBffRequest = __webpack_exports__.dispatchEffectBffRequest;
177
+ exports.runWithEffectContext = __webpack_exports__.runWithEffectContext;
178
+ exports.useEffectContext = __webpack_exports__.useEffectContext;
179
+ exports.useOperationContext = __webpack_exports__.useOperationContext;
162
180
  for(var __rspack_i in __webpack_exports__)if (-1 === [
163
181
  "createEffectBffEdgeHandler",
182
+ "createEffectBffTestHandler",
164
183
  "createEffectOperationContext",
165
- "dispatchEffectBffRequest"
184
+ "dispatchEffectBffRequest",
185
+ "runWithEffectContext",
186
+ "useEffectContext",
187
+ "useOperationContext"
166
188
  ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
167
189
  Object.defineProperty(exports, '__esModule', {
168
190
  value: true
@@ -140,6 +140,8 @@ var __webpack_exports__ = {};
140
140
  ].indexOf(__rspack_import_key) < 0) __rspack_reexport[__rspack_import_key] = ()=>effect_unstable_rpc__rspack_import_4[__rspack_import_key];
141
141
  __webpack_require__.d(__webpack_exports__, __rspack_reexport);
142
142
  const emptyEffectServiceContext = effect_Context__rspack_import_0.empty();
143
+ const isEffectServiceContext = (context)=>'object' == typeof context && null !== context && 'mapUnsafe' in context;
144
+ const toEffectServiceContext = (context)=>isEffectServiceContext(context) ? context : emptyEffectServiceContext;
143
145
  const EFFECT_VALIDATOR_AWARE_FACTORY = Symbol.for('modernjs.effect.validatorAware');
144
146
  function isValidatorAwareHandlerFactory(factory) {
145
147
  return 'function' == typeof factory && true === factory[EFFECT_VALIDATOR_AWARE_FACTORY];
@@ -457,7 +459,7 @@ var __webpack_exports__ = {};
457
459
  ]);
458
460
  function createLoaderMaterializedClientPlaceholder() {
459
461
  const explain = (property)=>{
460
- throw new Error(`[BFF][Effect] effectBff.client.${String(property)} is not available here: the typed client only exists when this module is imported through the "@api/effect/*" transformed path (the BFF loader replaces it with generated client code). On the server, use HttpApiClient or call the Effect layer directly.`);
462
+ throw new Error(`[BFF][Effect] client.${String(property)} is not available here: the typed client only exists when the API entry is imported through the "@api/index" transformed path (the BFF loader replaces it with generated client code). On the server, use HttpApiClient or call the Effect layer directly.`);
461
463
  };
462
464
  return new Proxy(Object.create(null), {
463
465
  get (_target, property) {
@@ -498,7 +500,7 @@ var __webpack_exports__ = {};
498
500
  if (preparedRequest instanceof Response) return preparedRequest;
499
501
  const validationError = validateDataPlatformRequestEnvelope(preparedRequest, options.dataPlatform);
500
502
  if (validationError) return validationError;
501
- return httpApiHandler.handler(preparedRequest, context ?? emptyEffectServiceContext);
503
+ return httpApiHandler.handler(preparedRequest, toEffectServiceContext(context));
502
504
  };
503
505
  const handleBatchRequest = async (request, context)=>{
504
506
  const mountedPrefix = getMountedPrefixFromContext(request, context);
@@ -620,7 +622,7 @@ var __webpack_exports__ = {};
620
622
  if (isRpcRequest(request, rpcPath)) {
621
623
  const policyDenial = options.validateRequest?.(request);
622
624
  if (policyDenial) return policyDenial;
623
- return rpcHandler.handler(request, context ?? emptyEffectServiceContext);
625
+ return rpcHandler.handler(request, toEffectServiceContext(context));
624
626
  }
625
627
  return handleHttpApiRequest(request);
626
628
  },
@@ -3,6 +3,9 @@ var __webpack_modules__ = {
3
3
  "./context" (module) {
4
4
  module.exports = require("./context.js");
5
5
  },
6
+ "./edge" (module) {
7
+ module.exports = require("./edge.js");
8
+ },
6
9
  "./handler" (module) {
7
10
  module.exports = require("./handler.js");
8
11
  },
@@ -59,30 +62,47 @@ var __webpack_exports__ = {};
59
62
  __webpack_require__.r(__webpack_exports__);
60
63
  var _effect_opentelemetry__rspack_import_0 = __webpack_require__("@effect/opentelemetry");
61
64
  var _context__rspack_import_1 = __webpack_require__("./context");
62
- var _handler__rspack_import_2 = __webpack_require__("./handler");
65
+ var _edge__rspack_import_2 = __webpack_require__("./edge");
66
+ var _handler__rspack_import_3 = __webpack_require__("./handler");
63
67
  var __rspack_reexport = {};
64
- for(const __rspack_import_key in _handler__rspack_import_2)if ([
68
+ for(const __rspack_import_key in _handler__rspack_import_3)if ([
69
+ "runWithEffectContext",
65
70
  "useEffectContext",
66
71
  "default",
67
- "OpenTelemetry",
72
+ "useOperationContext",
68
73
  "createEffectOperationContext",
69
- "useOperationContext"
70
- ].indexOf(__rspack_import_key) < 0) __rspack_reexport[__rspack_import_key] = ()=>_handler__rspack_import_2[__rspack_import_key];
74
+ "dispatchEffectBffRequest",
75
+ "createEffectBffTestHandler",
76
+ "OpenTelemetry",
77
+ "createEffectBffEdgeHandler"
78
+ ].indexOf(__rspack_import_key) < 0) __rspack_reexport[__rspack_import_key] = ()=>_handler__rspack_import_3[__rspack_import_key];
71
79
  __webpack_require__.d(__webpack_exports__, __rspack_reexport);
72
80
  __webpack_require__.d(__webpack_exports__, {
73
81
  OpenTelemetry: ()=>_effect_opentelemetry__rspack_import_0,
82
+ createEffectBffEdgeHandler: ()=>_edge__rspack_import_2.createEffectBffEdgeHandler,
83
+ createEffectBffTestHandler: ()=>_edge__rspack_import_2.createEffectBffTestHandler,
74
84
  createEffectOperationContext: ()=>_context__rspack_import_1.createEffectOperationContext,
85
+ dispatchEffectBffRequest: ()=>_edge__rspack_import_2.dispatchEffectBffRequest,
86
+ runWithEffectContext: ()=>_context__rspack_import_1.runWithEffectContext,
75
87
  useEffectContext: ()=>_context__rspack_import_1.useEffectContext,
76
88
  useOperationContext: ()=>_context__rspack_import_1.useOperationContext
77
89
  });
78
90
  })();
79
91
  exports.OpenTelemetry = __webpack_exports__.OpenTelemetry;
92
+ exports.createEffectBffEdgeHandler = __webpack_exports__.createEffectBffEdgeHandler;
93
+ exports.createEffectBffTestHandler = __webpack_exports__.createEffectBffTestHandler;
80
94
  exports.createEffectOperationContext = __webpack_exports__.createEffectOperationContext;
95
+ exports.dispatchEffectBffRequest = __webpack_exports__.dispatchEffectBffRequest;
96
+ exports.runWithEffectContext = __webpack_exports__.runWithEffectContext;
81
97
  exports.useEffectContext = __webpack_exports__.useEffectContext;
82
98
  exports.useOperationContext = __webpack_exports__.useOperationContext;
83
99
  for(var __rspack_i in __webpack_exports__)if (-1 === [
84
100
  "OpenTelemetry",
101
+ "createEffectBffEdgeHandler",
102
+ "createEffectBffTestHandler",
85
103
  "createEffectOperationContext",
104
+ "dispatchEffectBffRequest",
105
+ "runWithEffectContext",
86
106
  "useEffectContext",
87
107
  "useOperationContext"
88
108
  ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
@@ -49,16 +49,18 @@ function isEffectServiceContext(context) {
49
49
  return 'object' == typeof context && null !== context && 'mapUnsafe' in context;
50
50
  }
51
51
  const emptyEffectServiceContext = Context_namespaceObject.empty();
52
+ const strictEffectApproachMessage = '[BFF][Effect] strictEffectApproach is enforced: Effect API entries must export defineEffectBff(...) or a { api, layer } HttpApi module. Raw handler exports, default request handlers, and unbranded custom createHandler factories are not valid Effect API entries.';
53
+ function rejectLegacyEffectModuleShape(options, shape) {
54
+ options.onWarning?.(`${strictEffectApproachMessage} Rejected ${shape}.`);
55
+ return true;
56
+ }
52
57
  function callEffectBffRequestHandler(handler, request, context) {
53
58
  return void 0 === context ? handler(request) : handler(request, context);
54
59
  }
55
- function createLoadedHandler(webHandler, appliesRequestValidator) {
60
+ function createLoadedHandler(webHandler) {
56
61
  return {
57
62
  handler: (request, context)=>callEffectBffRequestHandler(webHandler.handler, request, context),
58
- dispose: webHandler.dispose,
59
- ...appliesRequestValidator ? {
60
- appliesRequestValidator: true
61
- } : {}
63
+ dispose: webHandler.dispose
62
64
  };
63
65
  }
64
66
  function createLoadedHttpApiHandler(webHandler) {
@@ -67,18 +69,23 @@ function createLoadedHttpApiHandler(webHandler) {
67
69
  const effectContext = isEffectServiceContext(context) ? context : emptyEffectServiceContext;
68
70
  return webHandler.handler(request, effectContext);
69
71
  },
70
- dispose: webHandler.dispose,
71
- appliesRequestValidator: true
72
+ dispose: webHandler.dispose
72
73
  };
73
74
  }
74
75
  function resolveNormalizedEffectBffModuleHandler(normalizedModule, options = {}) {
75
- if (isRequestHandler(normalizedModule.handler)) return {
76
- handler: normalizedModule.handler
77
- };
76
+ if (isRequestHandler(normalizedModule.handler)) {
77
+ if (rejectLegacyEffectModuleShape(options, '`handler` export')) return null;
78
+ return {
79
+ handler: normalizedModule.handler
80
+ };
81
+ }
78
82
  const entry = normalizedModule.default;
79
- if (isRequestHandler(entry)) return {
80
- handler: entry
81
- };
83
+ if (isRequestHandler(entry)) {
84
+ if (rejectLegacyEffectModuleShape(options, 'default request handler')) return null;
85
+ return {
86
+ handler: entry
87
+ };
88
+ }
82
89
  if (isRecord(entry)) normalizedModule = {
83
90
  ...normalizedModule,
84
91
  ...entry
@@ -90,19 +97,22 @@ function resolveNormalizedEffectBffModuleHandler(normalizedModule, options = {})
90
97
  handler: maybeHandler
91
98
  };
92
99
  }
93
- if (isRequestHandler(normalizedModule.handler)) return {
94
- handler: normalizedModule.handler
95
- };
100
+ if (isRequestHandler(normalizedModule.handler)) {
101
+ if (rejectLegacyEffectModuleShape(options, '`handler` export')) return null;
102
+ return {
103
+ handler: normalizedModule.handler
104
+ };
105
+ }
96
106
  if ('function' == typeof normalizedModule.createHandler) {
97
107
  const factory = normalizedModule.createHandler;
98
108
  const validatorAware = (0, external_handler_js_namespaceObject.isValidatorAwareHandlerFactory)(factory);
99
- if (!validatorAware && void 0 !== options.validateRequest) options.onWarning?.('[BFF][Effect] Custom createHandler export detected: it cannot be verified to apply validateRequest (cross-project policy), so the policy is enforced by the adapter middleware on the outer request. Batched calls will be denied at the batch POST (it carries no per-operation contract); export defineEffectBff(...) to get per-batch-item enforcement.');
109
+ if (!validatorAware && rejectLegacyEffectModuleShape(options, 'unbranded `createHandler` export')) return null;
100
110
  const webHandler = factory({
101
111
  openapi: options.openapi,
102
112
  dataPlatform: options.dataPlatform,
103
113
  validateRequest: options.validateRequest
104
114
  });
105
- return createLoadedHandler(webHandler, validatorAware);
115
+ return createLoadedHandler(webHandler);
106
116
  }
107
117
  if (isEffectApiDefinition(normalizedModule)) {
108
118
  options.onWarning?.('[BFF][Effect] Detected { api, layer } export without createHandler. Prefer `defineEffectBff(...)` from @modern-js/plugin-bff/server to avoid module instance mismatch.');
@@ -126,17 +136,26 @@ function resolveEffectBffModuleHandler(mod, options = {}) {
126
136
  ...value
127
137
  };
128
138
  };
129
- if (isRequestHandler(normalizedModule.handler)) return Promise.resolve({
130
- handler: normalizedModule.handler
131
- });
139
+ if (isRequestHandler(normalizedModule.handler)) {
140
+ if (rejectLegacyEffectModuleShape(options, '`handler` export')) return Promise.resolve(null);
141
+ return Promise.resolve({
142
+ handler: normalizedModule.handler
143
+ });
144
+ }
132
145
  const entry = normalizedModule.default;
133
- if (isRequestHandler(entry)) return Promise.resolve({
134
- handler: entry
135
- });
146
+ if (isRequestHandler(entry)) {
147
+ if (rejectLegacyEffectModuleShape(options, 'default request handler')) return Promise.resolve(null);
148
+ return Promise.resolve({
149
+ handler: entry
150
+ });
151
+ }
136
152
  if ('function' == typeof entry && 0 === entry.length) return Promise.resolve(entry()).then((out)=>{
137
- if (isRequestHandler(out)) return {
138
- handler: out
139
- };
153
+ if (isRequestHandler(out)) {
154
+ if (rejectLegacyEffectModuleShape(options, 'default factory returning a request handler')) return null;
155
+ return {
156
+ handler: out
157
+ };
158
+ }
140
159
  mergeRuntimeExports(out);
141
160
  return resolveNormalizedEffectBffModuleHandler(normalizedModule, options);
142
161
  });
@@ -172,14 +172,14 @@ const __generated = createGeneratedEffectClient(__manifest, __config, __requestR
172
172
  const client = __generated.client;
173
173
  const operationManifest = __generated.operationManifest;
174
174
  const createEffectRequestContext = __generated.createEffectRequestContext;
175
- const effectBffModule = {
175
+ const apiModule = {
176
176
  client,
177
177
  operationManifest,
178
178
  createEffectRequestContext,
179
179
  };
180
180
 
181
181
  export { client, createEffectRequestContext, operationManifest };
182
- export default effectBffModule;
182
+ export default apiModule;
183
183
  `;
184
184
  }
185
185
  function renderClientShape(endpoints, valueType) {
@@ -252,13 +252,13 @@ export declare const createEffectRequestContext: (
252
252
  requestContext: Record<string, unknown>,
253
253
  ) => EffectRequestContext;
254
254
  export declare const operationManifest: GeneratedEffectOperationManifest;
255
- declare const effectBffModule: {
255
+ declare const apiModule: {
256
256
  client: GeneratedEffectClient;
257
257
  createEffectRequestContext: typeof createEffectRequestContext;
258
258
  operationManifest: GeneratedEffectOperationManifest;
259
259
  };
260
260
 
261
- export default effectBffModule;
261
+ export default apiModule;
262
262
  `;
263
263
  }
264
264
  async function generateEffectClient(options) {
@@ -281,10 +281,15 @@ async function generateEffectClientCode(options) {
281
281
  }
282
282
  function resolveEffectEntryFile(options) {
283
283
  const { appDir, apiDir, effectEntry } = options;
284
- const defaultEntry = external_path_default().resolve(apiDir, 'effect', 'index');
285
- const entryWithoutExt = effectEntry ? external_path_default().isAbsolute(effectEntry) ? effectEntry : external_path_default().resolve(appDir, effectEntry) : defaultEntry;
286
- if (external_path_default().extname(entryWithoutExt)) return utils_namespaceObject.fs.existsSync(entryWithoutExt) ? entryWithoutExt : void 0;
287
- return (0, utils_namespaceObject.findExists)(JS_OR_TS_EXTS.map((ext)=>`${entryWithoutExt}${ext}`));
284
+ const resolveEntry = (entryWithoutExt)=>{
285
+ if (external_path_default().extname(entryWithoutExt)) return utils_namespaceObject.fs.existsSync(entryWithoutExt) ? entryWithoutExt : void 0;
286
+ return (0, utils_namespaceObject.findExists)(JS_OR_TS_EXTS.map((ext)=>`${entryWithoutExt}${ext}`));
287
+ };
288
+ if (effectEntry) {
289
+ const entryWithoutExt = external_path_default().isAbsolute(effectEntry) ? effectEntry : external_path_default().resolve(appDir, effectEntry);
290
+ return resolveEntry(entryWithoutExt);
291
+ }
292
+ return resolveEntry(external_path_default().resolve(apiDir, 'index'));
288
293
  }
289
294
  exports.generateEffectClient = __webpack_exports__.generateEffectClient;
290
295
  exports.generateEffectClientCode = __webpack_exports__.generateEffectClientCode;