@bleedingdev/modern-js-plugin-bff 3.2.0-ultramodern.99 → 3.4.0-ultramodern.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 (72) hide show
  1. package/dist/cjs/cli.js +9 -5
  2. package/dist/cjs/constants.js +13 -9
  3. package/dist/cjs/index.js +9 -5
  4. package/dist/cjs/loader.js +9 -5
  5. package/dist/cjs/runtime/create-request/index.js +9 -5
  6. package/dist/cjs/runtime/data-platform/index.js +11 -18
  7. package/dist/cjs/runtime/effect/adapter.js +87 -14
  8. package/dist/cjs/runtime/effect/context.js +9 -5
  9. package/dist/cjs/runtime/effect/edge.js +26 -26
  10. package/dist/cjs/runtime/effect/endpoint-contracts.js +130 -0
  11. package/dist/cjs/runtime/effect/handler.js +107 -63
  12. package/dist/cjs/runtime/effect/index.js +28 -16
  13. package/dist/cjs/runtime/effect/module.js +71 -35
  14. package/dist/cjs/runtime/effect/operation-context.js +10 -18
  15. package/dist/cjs/runtime/effect-client/index.js +10 -6
  16. package/dist/cjs/runtime/effect-client/runtime.js +266 -0
  17. package/dist/cjs/runtime/hono/adapter.js +30 -14
  18. package/dist/cjs/runtime/hono/index.js +9 -5
  19. package/dist/cjs/runtime/hono/operators.js +9 -5
  20. package/dist/cjs/runtime/safe-failure.js +83 -0
  21. package/dist/cjs/server.js +9 -5
  22. package/dist/cjs/utils/clientGenerator.js +13 -9
  23. package/dist/cjs/utils/createHonoRoutes.js +9 -5
  24. package/dist/cjs/utils/crossProjectApiPlugin.js +9 -5
  25. package/dist/cjs/utils/crossProjectServerPolicy.js +104 -0
  26. package/dist/cjs/utils/effectClientGenerator.js +99 -488
  27. package/dist/cjs/utils/pluginGenerator.js +9 -5
  28. package/dist/cjs/utils/runtimeGenerator.js +9 -5
  29. package/dist/esm/runtime/data-platform/index.mjs +2 -13
  30. package/dist/esm/runtime/effect/adapter.mjs +78 -9
  31. package/dist/esm/runtime/effect/edge.mjs +2 -9
  32. package/dist/esm/runtime/effect/endpoint-contracts.mjs +68 -0
  33. package/dist/esm/runtime/effect/handler.mjs +41 -8
  34. package/dist/esm/runtime/effect/index.mjs +2 -0
  35. package/dist/esm/runtime/effect/module.mjs +63 -31
  36. package/dist/esm/runtime/effect/operation-context.mjs +1 -13
  37. package/dist/esm/runtime/effect-client/index.mjs +1 -1
  38. package/dist/esm/runtime/effect-client/runtime.mjs +228 -0
  39. package/dist/esm/runtime/hono/adapter.mjs +21 -9
  40. package/dist/esm/runtime/safe-failure.mjs +45 -0
  41. package/dist/esm/utils/clientGenerator.mjs +5 -5
  42. package/dist/esm/utils/crossProjectServerPolicy.mjs +50 -0
  43. package/dist/esm/utils/effectClientGenerator.mjs +88 -484
  44. package/dist/esm-node/runtime/data-platform/index.mjs +2 -13
  45. package/dist/esm-node/runtime/effect/adapter.mjs +78 -9
  46. package/dist/esm-node/runtime/effect/edge.mjs +2 -9
  47. package/dist/esm-node/runtime/effect/endpoint-contracts.mjs +69 -0
  48. package/dist/esm-node/runtime/effect/handler.mjs +41 -8
  49. package/dist/esm-node/runtime/effect/index.mjs +2 -0
  50. package/dist/esm-node/runtime/effect/module.mjs +63 -31
  51. package/dist/esm-node/runtime/effect/operation-context.mjs +1 -13
  52. package/dist/esm-node/runtime/effect-client/index.mjs +1 -1
  53. package/dist/esm-node/runtime/effect-client/runtime.mjs +229 -0
  54. package/dist/esm-node/runtime/hono/adapter.mjs +21 -9
  55. package/dist/esm-node/runtime/safe-failure.mjs +46 -0
  56. package/dist/esm-node/utils/clientGenerator.mjs +5 -5
  57. package/dist/esm-node/utils/crossProjectServerPolicy.mjs +52 -0
  58. package/dist/esm-node/utils/effectClientGenerator.mjs +88 -484
  59. package/dist/types/runtime/effect/adapter.d.ts +25 -0
  60. package/dist/types/runtime/effect/context.d.ts +1 -1
  61. package/dist/types/runtime/effect/endpoint-contracts.d.ts +62 -0
  62. package/dist/types/runtime/effect/handler.d.ts +37 -4
  63. package/dist/types/runtime/effect/index.d.ts +1 -0
  64. package/dist/types/runtime/effect/module.d.ts +22 -2
  65. package/dist/types/runtime/effect-client/runtime.d.ts +71 -0
  66. package/dist/types/runtime/hono/adapter.d.ts +3 -0
  67. package/dist/types/runtime/safe-failure.d.ts +1 -0
  68. package/dist/types/server.d.ts +1 -1
  69. package/dist/types/utils/createHonoRoutes.d.ts +3 -3
  70. package/dist/types/utils/crossProjectServerPolicy.d.ts +35 -0
  71. package/dist/types/utils/effectClientGenerator.d.ts +16 -2
  72. package/package.json +40 -27
@@ -3,12 +3,12 @@ var __webpack_modules__ = {
3
3
  "../data-platform" (module) {
4
4
  module.exports = require("../data-platform/index.js");
5
5
  },
6
- "@effect/opentelemetry" (module) {
7
- module.exports = require("@effect/opentelemetry");
8
- },
9
6
  "effect/Config" (module) {
10
7
  module.exports = require("effect/Config");
11
8
  },
9
+ "effect/Context" (module) {
10
+ module.exports = require("effect/Context");
11
+ },
12
12
  "effect/Effect" (module) {
13
13
  module.exports = require("effect/Effect");
14
14
  },
@@ -51,11 +51,15 @@ function __webpack_require__(moduleId) {
51
51
  };
52
52
  })();
53
53
  (()=>{
54
- __webpack_require__.d = (exports1, definition)=>{
55
- for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
56
- enumerable: true,
57
- get: definition[key]
58
- });
54
+ __webpack_require__.d = (exports1, getters, values)=>{
55
+ var define = (defs, kind)=>{
56
+ for(var key in defs)if (__webpack_require__.o(defs, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
57
+ enumerable: true,
58
+ [kind]: defs[key]
59
+ });
60
+ };
61
+ define(getters, "get");
62
+ define(values, "value");
59
63
  };
60
64
  })();
61
65
  (()=>{
@@ -74,31 +78,18 @@ function __webpack_require__(moduleId) {
74
78
  var __webpack_exports__ = {};
75
79
  (()=>{
76
80
  __webpack_require__.r(__webpack_exports__);
77
- __webpack_require__.d(__webpack_exports__, {
78
- Config: ()=>effect_Config__rspack_import_6,
79
- Effect: ()=>effect_Effect__rspack_import_7,
80
- HttpApiBuilder: ()=>effect_unstable_httpapi__rspack_import_2.HttpApiBuilder,
81
- HttpTraceContext: ()=>effect_unstable_http__rspack_import_1.HttpTraceContext,
82
- Layer: ()=>effect_Layer__rspack_import_0,
83
- OpenTelemetry: ()=>_effect_opentelemetry__rspack_import_5,
84
- Option: ()=>effect_Option__rspack_import_8,
85
- Schema: ()=>effect_Schema__rspack_import_9,
86
- createHttpApiHandler: ()=>createHttpApiHandler,
87
- defineEffectBff: ()=>defineEffectBff,
88
- defineEffectRpcBff: ()=>defineEffectRpcBff
89
- });
90
- var effect_Layer__rspack_import_0 = __webpack_require__("effect/Layer");
91
- var effect_unstable_http__rspack_import_1 = __webpack_require__("effect/unstable/http");
92
- var effect_unstable_httpapi__rspack_import_2 = __webpack_require__("effect/unstable/httpapi");
93
- var effect_unstable_rpc__rspack_import_3 = __webpack_require__("effect/unstable/rpc");
94
- var _data_platform__rspack_import_4 = __webpack_require__("../data-platform");
95
- var _effect_opentelemetry__rspack_import_5 = __webpack_require__("@effect/opentelemetry");
81
+ var effect_Context__rspack_import_0 = __webpack_require__("effect/Context");
82
+ var effect_Layer__rspack_import_1 = __webpack_require__("effect/Layer");
83
+ var effect_unstable_http__rspack_import_2 = __webpack_require__("effect/unstable/http");
84
+ var effect_unstable_httpapi__rspack_import_3 = __webpack_require__("effect/unstable/httpapi");
85
+ var effect_unstable_rpc__rspack_import_4 = __webpack_require__("effect/unstable/rpc");
86
+ var _data_platform__rspack_import_5 = __webpack_require__("../data-platform");
96
87
  var effect_Config__rspack_import_6 = __webpack_require__("effect/Config");
97
88
  var effect_Effect__rspack_import_7 = __webpack_require__("effect/Effect");
98
89
  var effect_Option__rspack_import_8 = __webpack_require__("effect/Option");
99
90
  var effect_Schema__rspack_import_9 = __webpack_require__("effect/Schema");
100
91
  var __rspack_reexport = {};
101
- for(const __rspack_import_key in effect_unstable_http__rspack_import_1)if ([
92
+ for(const __rspack_import_key in effect_unstable_http__rspack_import_2)if ([
102
93
  "Config",
103
94
  "Layer",
104
95
  "Schema",
@@ -109,12 +100,13 @@ var __webpack_exports__ = {};
109
100
  "Effect",
110
101
  "defineEffectRpcBff",
111
102
  "createHttpApiHandler",
112
- "OpenTelemetry",
103
+ "EFFECT_VALIDATOR_AWARE_FACTORY",
104
+ "isValidatorAwareHandlerFactory",
113
105
  "Option"
114
- ].indexOf(__rspack_import_key) < 0) __rspack_reexport[__rspack_import_key] = ()=>effect_unstable_http__rspack_import_1[__rspack_import_key];
106
+ ].indexOf(__rspack_import_key) < 0) __rspack_reexport[__rspack_import_key] = ()=>effect_unstable_http__rspack_import_2[__rspack_import_key];
115
107
  __webpack_require__.d(__webpack_exports__, __rspack_reexport);
116
108
  var __rspack_reexport = {};
117
- for(const __rspack_import_key in effect_unstable_httpapi__rspack_import_2)if ([
109
+ for(const __rspack_import_key in effect_unstable_httpapi__rspack_import_3)if ([
118
110
  "Config",
119
111
  "Layer",
120
112
  "Schema",
@@ -125,12 +117,13 @@ var __webpack_exports__ = {};
125
117
  "Effect",
126
118
  "defineEffectRpcBff",
127
119
  "createHttpApiHandler",
128
- "OpenTelemetry",
120
+ "EFFECT_VALIDATOR_AWARE_FACTORY",
121
+ "isValidatorAwareHandlerFactory",
129
122
  "Option"
130
- ].indexOf(__rspack_import_key) < 0) __rspack_reexport[__rspack_import_key] = ()=>effect_unstable_httpapi__rspack_import_2[__rspack_import_key];
123
+ ].indexOf(__rspack_import_key) < 0) __rspack_reexport[__rspack_import_key] = ()=>effect_unstable_httpapi__rspack_import_3[__rspack_import_key];
131
124
  __webpack_require__.d(__webpack_exports__, __rspack_reexport);
132
125
  var __rspack_reexport = {};
133
- for(const __rspack_import_key in effect_unstable_rpc__rspack_import_3)if ([
126
+ for(const __rspack_import_key in effect_unstable_rpc__rspack_import_4)if ([
134
127
  "Config",
135
128
  "Layer",
136
129
  "Schema",
@@ -141,10 +134,16 @@ var __webpack_exports__ = {};
141
134
  "Effect",
142
135
  "defineEffectRpcBff",
143
136
  "createHttpApiHandler",
144
- "OpenTelemetry",
137
+ "EFFECT_VALIDATOR_AWARE_FACTORY",
138
+ "isValidatorAwareHandlerFactory",
145
139
  "Option"
146
- ].indexOf(__rspack_import_key) < 0) __rspack_reexport[__rspack_import_key] = ()=>effect_unstable_rpc__rspack_import_3[__rspack_import_key];
140
+ ].indexOf(__rspack_import_key) < 0) __rspack_reexport[__rspack_import_key] = ()=>effect_unstable_rpc__rspack_import_4[__rspack_import_key];
147
141
  __webpack_require__.d(__webpack_exports__, __rspack_reexport);
142
+ const emptyEffectServiceContext = effect_Context__rspack_import_0.empty();
143
+ const EFFECT_VALIDATOR_AWARE_FACTORY = Symbol.for('modernjs.effect.validatorAware');
144
+ function isValidatorAwareHandlerFactory(factory) {
145
+ return 'function' == typeof factory && true === factory[EFFECT_VALIDATOR_AWARE_FACTORY];
146
+ }
148
147
  function normalizeOpenApiPath(pathname) {
149
148
  if (!pathname.startsWith('/')) return `/${pathname}`;
150
149
  return pathname;
@@ -162,7 +161,7 @@ var __webpack_exports__ = {};
162
161
  return pathname;
163
162
  }
164
163
  function normalizeBatchPath(pathname) {
165
- if (!pathname || '/' === pathname) return _data_platform__rspack_import_4.DEFAULT_DATA_BATCH_ENDPOINT;
164
+ if (!pathname || '/' === pathname) return _data_platform__rspack_import_5.DEFAULT_DATA_BATCH_ENDPOINT;
166
165
  if (!pathname.startsWith('/')) return `/${pathname}`;
167
166
  return pathname;
168
167
  }
@@ -299,33 +298,33 @@ var __webpack_exports__ = {};
299
298
  function getRpcSerializationLayer(serialization) {
300
299
  switch(serialization){
301
300
  case 'ndjson':
302
- return effect_unstable_rpc__rspack_import_3.RpcSerialization.layerNdjson;
301
+ return effect_unstable_rpc__rspack_import_4.RpcSerialization.layerNdjson;
303
302
  case 'jsonRpc':
304
- return effect_unstable_rpc__rspack_import_3.RpcSerialization.layerJsonRpc();
303
+ return effect_unstable_rpc__rspack_import_4.RpcSerialization.layerJsonRpc();
305
304
  case 'ndJsonRpc':
306
- return effect_unstable_rpc__rspack_import_3.RpcSerialization.layerNdJsonRpc();
305
+ return effect_unstable_rpc__rspack_import_4.RpcSerialization.layerNdJsonRpc();
307
306
  case 'msgPack':
308
- return effect_unstable_rpc__rspack_import_3.RpcSerialization.layerMsgPack;
307
+ return effect_unstable_rpc__rspack_import_4.RpcSerialization.layerMsgPack;
309
308
  default:
310
- return effect_unstable_rpc__rspack_import_3.RpcSerialization.layerJsonRpc();
309
+ return effect_unstable_rpc__rspack_import_4.RpcSerialization.layerJsonRpc();
311
310
  }
312
311
  }
313
312
  function createRpcApiHandler(options) {
314
313
  const rpcPath = normalizeRpcPath(options.path);
315
- const rpcLayer = effect_Layer__rspack_import_0.provide(effect_unstable_rpc__rspack_import_3.RpcServer.layerHttp({
314
+ const rpcLayer = effect_Layer__rspack_import_1.provide(effect_unstable_rpc__rspack_import_4.RpcServer.layerHttp({
316
315
  group: options.group,
317
316
  path: rpcPath,
318
317
  protocol: 'http',
319
318
  disableTracing: options.disableTracing,
320
319
  spanPrefix: options.spanPrefix,
321
320
  spanAttributes: options.spanAttributes
322
- }), effect_Layer__rspack_import_0.mergeAll(options.layer, getRpcSerializationLayer(options.serialization)));
323
- return effect_unstable_http__rspack_import_1.HttpRouter.toWebHandler(rpcLayer);
321
+ }), effect_Layer__rspack_import_1.mergeAll(options.layer, getRpcSerializationLayer(options.serialization)));
322
+ return effect_unstable_http__rspack_import_2.HttpRouter.toWebHandler(rpcLayer);
324
323
  }
325
324
  function createOpenApiLayer(api, openapi) {
326
325
  const openApiOptions = getOpenApiOptions(openapi);
327
326
  if (!openApiOptions) return null;
328
- return effect_unstable_http__rspack_import_1.HttpRouter.add('GET', openApiOptions.path, effect_unstable_http__rspack_import_1.HttpServerResponse.jsonUnsafe(effect_unstable_httpapi__rspack_import_2.OpenApi.fromApi(api)));
327
+ return effect_unstable_http__rspack_import_2.HttpRouter.add('GET', openApiOptions.path, effect_unstable_http__rspack_import_2.HttpServerResponse.jsonUnsafe(effect_unstable_httpapi__rspack_import_3.OpenApi.fromApi(api)));
329
328
  }
330
329
  function createInvalidEnvelopeResponse(message, errors) {
331
330
  return new Response(JSON.stringify({
@@ -343,15 +342,15 @@ var __webpack_exports__ = {};
343
342
  function validateDataPlatformRequestEnvelope(request, options) {
344
343
  const isEnabled = options?.enabled ?? true;
345
344
  if (!isEnabled) return null;
346
- const envelopeHeader = options?.envelopeHeader || _data_platform__rspack_import_4.DEFAULT_DATA_ENVELOPE_HEADER;
345
+ const envelopeHeader = options?.envelopeHeader || _data_platform__rspack_import_5.DEFAULT_DATA_ENVELOPE_HEADER;
347
346
  const encodedEnvelope = request.headers.get(envelopeHeader);
348
347
  if (!encodedEnvelope) {
349
348
  if (options?.requireEnvelope) return createInvalidEnvelopeResponse(`Missing required data envelope header: ${envelopeHeader}`);
350
349
  return null;
351
350
  }
352
- const envelope = (0, _data_platform__rspack_import_4.decodeRequestEnvelopeHeader)(encodedEnvelope);
351
+ const envelope = (0, _data_platform__rspack_import_5.decodeRequestEnvelopeHeader)(encodedEnvelope);
353
352
  if (!envelope) return createInvalidEnvelopeResponse(`Invalid data envelope header format: ${envelopeHeader}`);
354
- const validation = (0, _data_platform__rspack_import_4.validateRequestEnvelope)(envelope, {
353
+ const validation = (0, _data_platform__rspack_import_5.validateRequestEnvelope)(envelope, {
355
354
  expectedProtocolVersion: 1,
356
355
  expectedNamespace: options?.expectedNamespace,
357
356
  expectedOrigin: options?.validateOrigin === false ? void 0 : getExpectedEnvelopeOrigin(request),
@@ -359,7 +358,7 @@ var __webpack_exports__ = {};
359
358
  });
360
359
  if (!validation.ok) return createInvalidEnvelopeResponse('Invalid data envelope', validation.errors);
361
360
  if (envelope.selectionPlan) {
362
- const selectionValidation = (0, _data_platform__rspack_import_4.validateSelectionPlan)(envelope.selectionPlan, {
361
+ const selectionValidation = (0, _data_platform__rspack_import_5.validateSelectionPlan)(envelope.selectionPlan, {
363
362
  maxDepth: options?.selection?.maxDepth,
364
363
  maxFields: options?.selection?.maxFields,
365
364
  allowedLeafPaths: options?.selection?.allowedLeafPaths
@@ -400,16 +399,38 @@ var __webpack_exports__ = {};
400
399
  layer: definition.layer,
401
400
  openapi: options?.openapi,
402
401
  rpc: mergedRpcOptions,
403
- dataPlatform: mergeDataPlatformOptions(definition.dataPlatform, options?.dataPlatform)
402
+ dataPlatform: mergeDataPlatformOptions(definition.dataPlatform, options?.dataPlatform),
403
+ validateRequest: options?.validateRequest
404
404
  });
405
405
  };
406
- const client = void 0;
406
+ Object.defineProperty(createHandler, EFFECT_VALIDATOR_AWARE_FACTORY, {
407
+ value: true
408
+ });
409
+ const client = createLoaderMaterializedClientPlaceholder();
407
410
  return {
408
411
  ...definition,
409
412
  createHandler,
410
413
  client
411
414
  };
412
415
  }
416
+ const LOADER_CLIENT_IGNORED_KEYS = new Set([
417
+ 'then',
418
+ 'catch',
419
+ 'finally',
420
+ 'toJSON',
421
+ '$$typeof'
422
+ ]);
423
+ function createLoaderMaterializedClientPlaceholder() {
424
+ const explain = (property)=>{
425
+ 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.`);
426
+ };
427
+ return new Proxy(Object.create(null), {
428
+ get (_target, property) {
429
+ if ('symbol' == typeof property || LOADER_CLIENT_IGNORED_KEYS.has(property)) return;
430
+ return explain(property);
431
+ }
432
+ });
433
+ }
413
434
  function defineEffectRpcBff(definition) {
414
435
  const createHandler = (options)=>createRpcApiHandler({
415
436
  ...definition,
@@ -421,10 +442,10 @@ var __webpack_exports__ = {};
421
442
  };
422
443
  }
423
444
  function createHttpApiHandler(options) {
424
- const apiLayer = options.layer;
445
+ const apiLayer = options.layer.pipe(effect_Layer__rspack_import_1.provide(effect_unstable_http__rspack_import_2.HttpServer.layerServices));
425
446
  const openApiLayer = createOpenApiLayer(options.api, options.openapi);
426
- const mergedLayer = openApiLayer ? effect_Layer__rspack_import_0.mergeAll(apiLayer, openApiLayer) : apiLayer;
427
- const httpApiHandler = effect_unstable_http__rspack_import_1.HttpRouter.toWebHandler(mergedLayer);
447
+ const mergedLayer = openApiLayer ? effect_Layer__rspack_import_1.mergeAll(apiLayer, openApiLayer) : apiLayer;
448
+ const httpApiHandler = effect_unstable_http__rspack_import_2.HttpRouter.toWebHandler(mergedLayer);
428
449
  const dataPlatformBatchOptions = options.dataPlatform?.batch;
429
450
  const batchEnabled = dataPlatformBatchOptions?.enabled !== false;
430
451
  const batchPath = normalizeBatchPath(dataPlatformBatchOptions?.endpoint);
@@ -433,12 +454,14 @@ var __webpack_exports__ = {};
433
454
  const batchConcurrency = Math.max(1, dataPlatformBatchOptions?.maxConcurrency ?? 4);
434
455
  const batchItemTimeoutMs = Math.max(0, dataPlatformBatchOptions?.requestTimeoutMs ?? 10000);
435
456
  const batchAllowedMethods = normalizeBatchAllowedMethods(dataPlatformBatchOptions?.allowedMethods);
436
- const envelopeHeader = options.dataPlatform?.envelopeHeader || _data_platform__rspack_import_4.DEFAULT_DATA_ENVELOPE_HEADER;
457
+ const envelopeHeader = options.dataPlatform?.envelopeHeader || _data_platform__rspack_import_5.DEFAULT_DATA_ENVELOPE_HEADER;
437
458
  const normalizedEnvelopeHeader = envelopeHeader.toLowerCase();
438
459
  const withDataPlatformValidation = async (request, context)=>{
460
+ const policyDenial = options.validateRequest?.(request);
461
+ if (policyDenial) return policyDenial;
439
462
  const validationError = validateDataPlatformRequestEnvelope(request, options.dataPlatform);
440
463
  if (validationError) return validationError;
441
- return httpApiHandler.handler(request, context);
464
+ return httpApiHandler.handler(request, context ?? emptyEffectServiceContext);
442
465
  };
443
466
  const handleBatchRequest = async (request, context)=>{
444
467
  const mountedPrefix = getMountedPrefixFromContext(request, context);
@@ -481,7 +504,7 @@ var __webpack_exports__ = {};
481
504
  if (!normalizedHeaders.traceparent) {
482
505
  const encodedEnvelope = normalizedHeaders[normalizedEnvelopeHeader];
483
506
  if ('string' == typeof encodedEnvelope) {
484
- const envelope = (0, _data_platform__rspack_import_4.decodeRequestEnvelopeHeader)(encodedEnvelope);
507
+ const envelope = (0, _data_platform__rspack_import_5.decodeRequestEnvelopeHeader)(encodedEnvelope);
485
508
  if (envelope?.traceparent) normalizedHeaders.traceparent = envelope.traceparent;
486
509
  }
487
510
  }
@@ -537,7 +560,7 @@ var __webpack_exports__ = {};
537
560
  status: 200,
538
561
  headers: {
539
562
  'content-type': 'application/json; charset=utf-8',
540
- [_data_platform__rspack_import_4.DEFAULT_DATA_BATCH_HEADER]: '1',
563
+ [_data_platform__rspack_import_5.DEFAULT_DATA_BATCH_HEADER]: '1',
541
564
  'x-modernjs-data-batch-id': payload.batchId
542
565
  }
543
566
  });
@@ -557,7 +580,11 @@ var __webpack_exports__ = {};
557
580
  const rpcHandler = createRpcApiHandler(options.rpc);
558
581
  return {
559
582
  handler: async (request, context)=>{
560
- if (isRpcRequest(request, rpcPath)) return rpcHandler.handler(request, context);
583
+ if (isRpcRequest(request, rpcPath)) {
584
+ const policyDenial = options.validateRequest?.(request);
585
+ if (policyDenial) return policyDenial;
586
+ return rpcHandler.handler(request, context ?? emptyEffectServiceContext);
587
+ }
561
588
  return handleHttpApiRequest(request);
562
589
  },
563
590
  dispose: async ()=>{
@@ -568,30 +595,47 @@ var __webpack_exports__ = {};
568
595
  }
569
596
  };
570
597
  }
598
+ __webpack_require__.d(__webpack_exports__, {
599
+ Config: ()=>effect_Config__rspack_import_6,
600
+ Effect: ()=>effect_Effect__rspack_import_7,
601
+ HttpApiBuilder: ()=>effect_unstable_httpapi__rspack_import_3.HttpApiBuilder,
602
+ HttpTraceContext: ()=>effect_unstable_http__rspack_import_2.HttpTraceContext,
603
+ Layer: ()=>effect_Layer__rspack_import_1,
604
+ Option: ()=>effect_Option__rspack_import_8,
605
+ Schema: ()=>effect_Schema__rspack_import_9,
606
+ createHttpApiHandler: ()=>createHttpApiHandler,
607
+ defineEffectBff: ()=>defineEffectBff,
608
+ defineEffectRpcBff: ()=>defineEffectRpcBff,
609
+ isValidatorAwareHandlerFactory: ()=>isValidatorAwareHandlerFactory
610
+ }, {
611
+ EFFECT_VALIDATOR_AWARE_FACTORY: EFFECT_VALIDATOR_AWARE_FACTORY
612
+ });
571
613
  })();
572
614
  exports.Config = __webpack_exports__.Config;
615
+ exports.EFFECT_VALIDATOR_AWARE_FACTORY = __webpack_exports__.EFFECT_VALIDATOR_AWARE_FACTORY;
573
616
  exports.Effect = __webpack_exports__.Effect;
574
617
  exports.HttpApiBuilder = __webpack_exports__.HttpApiBuilder;
575
618
  exports.HttpTraceContext = __webpack_exports__.HttpTraceContext;
576
619
  exports.Layer = __webpack_exports__.Layer;
577
- exports.OpenTelemetry = __webpack_exports__.OpenTelemetry;
578
620
  exports.Option = __webpack_exports__.Option;
579
621
  exports.Schema = __webpack_exports__.Schema;
580
622
  exports.createHttpApiHandler = __webpack_exports__.createHttpApiHandler;
581
623
  exports.defineEffectBff = __webpack_exports__.defineEffectBff;
582
624
  exports.defineEffectRpcBff = __webpack_exports__.defineEffectRpcBff;
625
+ exports.isValidatorAwareHandlerFactory = __webpack_exports__.isValidatorAwareHandlerFactory;
583
626
  for(var __rspack_i in __webpack_exports__)if (-1 === [
584
627
  "Config",
628
+ "EFFECT_VALIDATOR_AWARE_FACTORY",
585
629
  "Effect",
586
630
  "HttpApiBuilder",
587
631
  "HttpTraceContext",
588
632
  "Layer",
589
- "OpenTelemetry",
590
633
  "Option",
591
634
  "Schema",
592
635
  "createHttpApiHandler",
593
636
  "defineEffectBff",
594
- "defineEffectRpcBff"
637
+ "defineEffectRpcBff",
638
+ "isValidatorAwareHandlerFactory"
595
639
  ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
596
640
  Object.defineProperty(exports, '__esModule', {
597
641
  value: true
@@ -5,6 +5,9 @@ var __webpack_modules__ = {
5
5
  },
6
6
  "./handler" (module) {
7
7
  module.exports = require("./handler.js");
8
+ },
9
+ "@effect/opentelemetry" (module) {
10
+ module.exports = require("@effect/opentelemetry");
8
11
  }
9
12
  };
10
13
  var __webpack_module_cache__ = {};
@@ -27,11 +30,15 @@ function __webpack_require__(moduleId) {
27
30
  };
28
31
  })();
29
32
  (()=>{
30
- __webpack_require__.d = (exports1, definition)=>{
31
- for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
32
- enumerable: true,
33
- get: definition[key]
34
- });
33
+ __webpack_require__.d = (exports1, getters, values)=>{
34
+ var define = (defs, kind)=>{
35
+ for(var key in defs)if (__webpack_require__.o(defs, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
36
+ enumerable: true,
37
+ [kind]: defs[key]
38
+ });
39
+ };
40
+ define(getters, "get");
41
+ define(values, "value");
35
42
  };
36
43
  })();
37
44
  (()=>{
@@ -50,26 +57,31 @@ function __webpack_require__(moduleId) {
50
57
  var __webpack_exports__ = {};
51
58
  (()=>{
52
59
  __webpack_require__.r(__webpack_exports__);
53
- __webpack_require__.d(__webpack_exports__, {
54
- createEffectOperationContext: ()=>_context__rspack_import_0.createEffectOperationContext,
55
- useEffectContext: ()=>_context__rspack_import_0.useEffectContext,
56
- useOperationContext: ()=>_context__rspack_import_0.useOperationContext
57
- });
58
- var _context__rspack_import_0 = __webpack_require__("./context");
59
- var _handler__rspack_import_1 = __webpack_require__("./handler");
60
+ var _effect_opentelemetry__rspack_import_0 = __webpack_require__("@effect/opentelemetry");
61
+ var _context__rspack_import_1 = __webpack_require__("./context");
62
+ var _handler__rspack_import_2 = __webpack_require__("./handler");
60
63
  var __rspack_reexport = {};
61
- for(const __rspack_import_key in _handler__rspack_import_1)if ([
64
+ for(const __rspack_import_key in _handler__rspack_import_2)if ([
62
65
  "useEffectContext",
63
66
  "default",
64
- "useOperationContext",
65
- "createEffectOperationContext"
66
- ].indexOf(__rspack_import_key) < 0) __rspack_reexport[__rspack_import_key] = ()=>_handler__rspack_import_1[__rspack_import_key];
67
+ "OpenTelemetry",
68
+ "createEffectOperationContext",
69
+ "useOperationContext"
70
+ ].indexOf(__rspack_import_key) < 0) __rspack_reexport[__rspack_import_key] = ()=>_handler__rspack_import_2[__rspack_import_key];
67
71
  __webpack_require__.d(__webpack_exports__, __rspack_reexport);
72
+ __webpack_require__.d(__webpack_exports__, {
73
+ OpenTelemetry: ()=>_effect_opentelemetry__rspack_import_0,
74
+ createEffectOperationContext: ()=>_context__rspack_import_1.createEffectOperationContext,
75
+ useEffectContext: ()=>_context__rspack_import_1.useEffectContext,
76
+ useOperationContext: ()=>_context__rspack_import_1.useOperationContext
77
+ });
68
78
  })();
79
+ exports.OpenTelemetry = __webpack_exports__.OpenTelemetry;
69
80
  exports.createEffectOperationContext = __webpack_exports__.createEffectOperationContext;
70
81
  exports.useEffectContext = __webpack_exports__.useEffectContext;
71
82
  exports.useOperationContext = __webpack_exports__.useOperationContext;
72
83
  for(var __rspack_i in __webpack_exports__)if (-1 === [
84
+ "OpenTelemetry",
73
85
  "createEffectOperationContext",
74
86
  "useEffectContext",
75
87
  "useOperationContext"
@@ -1,11 +1,15 @@
1
1
  "use strict";
2
2
  var __webpack_require__ = {};
3
3
  (()=>{
4
- __webpack_require__.d = (exports1, definition)=>{
5
- for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
6
- enumerable: true,
7
- get: definition[key]
8
- });
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");
9
13
  };
10
14
  })();
11
15
  (()=>{
@@ -26,6 +30,7 @@ __webpack_require__.r(__webpack_exports__);
26
30
  __webpack_require__.d(__webpack_exports__, {
27
31
  resolveEffectBffModuleHandler: ()=>resolveEffectBffModuleHandler
28
32
  });
33
+ const Context_namespaceObject = require("effect/Context");
29
34
  const httpapi_namespaceObject = require("effect/unstable/httpapi");
30
35
  const external_handler_js_namespaceObject = require("./handler.js");
31
36
  function isRecord(value) {
@@ -40,15 +45,33 @@ function isRequestHandler(value) {
40
45
  function isEffectApiDefinition(module) {
41
46
  return httpapi_namespaceObject.HttpApi.isHttpApi(module.api) && void 0 !== module.layer;
42
47
  }
43
- async function resolveEffectBffModuleHandler(mod, options = {}) {
44
- let normalizedModule = mod;
45
- const mergeRuntimeExports = (value)=>{
46
- if (!isRecord(value) || !includesRuntimeExports(value)) return;
47
- normalizedModule = {
48
- ...normalizedModule,
49
- ...value
50
- };
48
+ function isEffectServiceContext(context) {
49
+ return 'object' == typeof context && null !== context && 'mapUnsafe' in context;
50
+ }
51
+ const emptyEffectServiceContext = Context_namespaceObject.empty();
52
+ function callEffectBffRequestHandler(handler, request, context) {
53
+ return void 0 === context ? handler(request) : handler(request, context);
54
+ }
55
+ function createLoadedHandler(webHandler, appliesRequestValidator) {
56
+ return {
57
+ handler: (request, context)=>callEffectBffRequestHandler(webHandler.handler, request, context),
58
+ dispose: webHandler.dispose,
59
+ ...appliesRequestValidator ? {
60
+ appliesRequestValidator: true
61
+ } : {}
62
+ };
63
+ }
64
+ function createLoadedHttpApiHandler(webHandler) {
65
+ return {
66
+ handler: (request, context)=>{
67
+ const effectContext = isEffectServiceContext(context) ? context : emptyEffectServiceContext;
68
+ return webHandler.handler(request, effectContext);
69
+ },
70
+ dispose: webHandler.dispose,
71
+ appliesRequestValidator: true
51
72
  };
73
+ }
74
+ function resolveNormalizedEffectBffModuleHandler(normalizedModule, options = {}) {
52
75
  if (isRequestHandler(normalizedModule.handler)) return {
53
76
  handler: normalizedModule.handler
54
77
  };
@@ -56,13 +79,6 @@ async function resolveEffectBffModuleHandler(mod, options = {}) {
56
79
  if (isRequestHandler(entry)) return {
57
80
  handler: entry
58
81
  };
59
- if ('function' == typeof entry && 0 === entry.length) {
60
- const out = await entry();
61
- if (isRequestHandler(out)) return {
62
- handler: out
63
- };
64
- mergeRuntimeExports(out);
65
- }
66
82
  if (isRecord(entry)) normalizedModule = {
67
83
  ...normalizedModule,
68
84
  ...entry
@@ -78,16 +94,15 @@ async function resolveEffectBffModuleHandler(mod, options = {}) {
78
94
  handler: normalizedModule.handler
79
95
  };
80
96
  if ('function' == typeof normalizedModule.createHandler) {
81
- const webHandler = normalizedModule.createHandler({
97
+ const factory = normalizedModule.createHandler;
98
+ 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.');
100
+ const webHandler = factory({
82
101
  openapi: options.openapi,
83
- dataPlatform: options.dataPlatform
102
+ dataPlatform: options.dataPlatform,
103
+ validateRequest: options.validateRequest
84
104
  });
85
- return {
86
- handler: async (request, context)=>webHandler.handler(request, context),
87
- dispose: async ()=>{
88
- await webHandler.dispose();
89
- }
90
- };
105
+ return createLoadedHandler(webHandler, validatorAware);
91
106
  }
92
107
  if (isEffectApiDefinition(normalizedModule)) {
93
108
  options.onWarning?.('[BFF][Effect] Detected { api, layer } export without createHandler. Prefer `defineEffectBff(...)` from @modern-js/plugin-bff/server to avoid module instance mismatch.');
@@ -95,17 +110,38 @@ async function resolveEffectBffModuleHandler(mod, options = {}) {
95
110
  api: normalizedModule.api,
96
111
  layer: normalizedModule.layer,
97
112
  openapi: options.openapi,
98
- dataPlatform: options.dataPlatform
113
+ dataPlatform: options.dataPlatform,
114
+ validateRequest: options.validateRequest
99
115
  });
100
- return {
101
- handler: async (request, context)=>webHandler.handler(request, context),
102
- dispose: async ()=>{
103
- await webHandler.dispose();
104
- }
105
- };
116
+ return createLoadedHttpApiHandler(webHandler);
106
117
  }
107
118
  return null;
108
119
  }
120
+ function resolveEffectBffModuleHandler(mod, options = {}) {
121
+ let normalizedModule = mod;
122
+ const mergeRuntimeExports = (value)=>{
123
+ if (!isRecord(value) || !includesRuntimeExports(value)) return;
124
+ normalizedModule = {
125
+ ...normalizedModule,
126
+ ...value
127
+ };
128
+ };
129
+ if (isRequestHandler(normalizedModule.handler)) return Promise.resolve({
130
+ handler: normalizedModule.handler
131
+ });
132
+ const entry = normalizedModule.default;
133
+ if (isRequestHandler(entry)) return Promise.resolve({
134
+ handler: entry
135
+ });
136
+ if ('function' == typeof entry && 0 === entry.length) return Promise.resolve(entry()).then((out)=>{
137
+ if (isRequestHandler(out)) return {
138
+ handler: out
139
+ };
140
+ mergeRuntimeExports(out);
141
+ return resolveNormalizedEffectBffModuleHandler(normalizedModule, options);
142
+ });
143
+ return Promise.resolve(resolveNormalizedEffectBffModuleHandler(normalizedModule, options));
144
+ }
109
145
  exports.resolveEffectBffModuleHandler = __webpack_exports__.resolveEffectBffModuleHandler;
110
146
  for(var __rspack_i in __webpack_exports__)if (-1 === [
111
147
  "resolveEffectBffModuleHandler"
@@ -1,11 +1,15 @@
1
1
  "use strict";
2
2
  var __webpack_require__ = {};
3
3
  (()=>{
4
- __webpack_require__.d = (exports1, definition)=>{
5
- for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
6
- enumerable: true,
7
- get: definition[key]
8
- });
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");
9
13
  };
10
14
  })();
11
15
  (()=>{
@@ -27,7 +31,6 @@ __webpack_require__.d(__webpack_exports__, {
27
31
  createEffectOperationContext: ()=>createEffectOperationContext
28
32
  });
29
33
  const create_request_namespaceObject = require("@modern-js/create-request");
30
- const TRACEPARENT_REGEX = /^00-([0-9a-f]{32})-([0-9a-f]{16})-[0-9a-f]{2}$/i;
31
34
  const readHeader = (headers, header)=>{
32
35
  const value = headers.get(header);
33
36
  return value && value.length > 0 ? value : void 0;
@@ -36,17 +39,6 @@ const copyStringField = (target, details, key)=>{
36
39
  const value = details[key];
37
40
  if ('string' == typeof value && value.length > 0) target[key] = value;
38
41
  };
39
- const parseTraceparent = (traceparent)=>{
40
- if (!traceparent) return;
41
- const match = traceparent.trim().match(TRACEPARENT_REGEX);
42
- if (!match) return;
43
- const [, traceId, spanId] = match;
44
- if (!traceId || !spanId) return;
45
- return {
46
- traceId: traceId.toLowerCase(),
47
- spanId: spanId.toLowerCase()
48
- };
49
- };
50
42
  const readOperationContextDetails = (request)=>{
51
43
  const rawDetails = readHeader(request.headers, create_request_namespaceObject.BFF_OPERATION_CONTEXT_DETAIL_HEADER);
52
44
  if (!rawDetails) return {};
@@ -74,7 +66,7 @@ const createEffectOperationContext = ({ request, path, method })=>{
74
66
  const parsedTraceparent = details.traceId && details.spanId ? {
75
67
  traceId: details.traceId,
76
68
  spanId: details.spanId
77
- } : parseTraceparent(traceparent);
69
+ } : (0, create_request_namespaceObject.parseTraceparent)(traceparent);
78
70
  const locale = readHeader(request.headers, create_request_namespaceObject.BFF_LOCALE_HEADER);
79
71
  const headerOperationId = readHeader(request.headers, create_request_namespaceObject.BFF_OPERATION_CONTEXT_HEADER);
80
72
  return {