@bleedingdev/modern-js-app-tools-extensions 3.9.0-ultramodern.12 → 3.9.0-ultramodern.14

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 (93) hide show
  1. package/dist/cjs/backend-federation-build/codegen.js +7 -2
  2. package/dist/cjs/backend-federation-build/config.js +86 -36
  3. package/dist/cjs/backend-federation-build/emit.js +17 -13
  4. package/dist/cjs/cloudflare/delivery-unit.js +16 -26
  5. package/dist/cjs/cloudflare/index.js +7 -1
  6. package/dist/cjs/cloudflare/worker-manifest.js +13 -4
  7. package/dist/cjs/cloudflare/wrangler-config.js +35 -7
  8. package/dist/cjs/cloudflare-builder.js +247 -16
  9. package/dist/cjs/cloudflare-output-contract.js +32 -2
  10. package/dist/cjs/cloudflare-output-verifier/identity.js +26 -24
  11. package/dist/cjs/cloudflare-output-verifier/index.js +10 -0
  12. package/dist/cjs/cloudflare-output-verifier/manifest.js +46 -0
  13. package/dist/cjs/cloudflare-output-verifier/mutation-policy.js +7 -1
  14. package/dist/cjs/cloudflare-output-verifier/worker-bundles.js +10 -5
  15. package/dist/cjs/deploy-output/npmAliases.js +28 -3
  16. package/dist/cjs/release-envelope/framework-output.js +62 -49
  17. package/dist/cjs/release-envelope/index.js +10 -4
  18. package/dist/cjs/templates/cloudflare-entry.004-rendering-css.mjs +4 -0
  19. package/dist/cjs/templates/cloudflare-entry.005-worker-dispatch.mjs +46 -0
  20. package/dist/cjs/templates/cloudflare-entry.006-fetch-handler.mjs +9 -2
  21. package/dist/cjs/templates/cloudflare-worker-route-data.mjs +1069 -0
  22. package/dist/esm/backend-federation-build/codegen.mjs +7 -2
  23. package/dist/esm/backend-federation-build/config.mjs +78 -31
  24. package/dist/esm/backend-federation-build/emit.mjs +18 -14
  25. package/dist/esm/cloudflare/delivery-unit.mjs +16 -26
  26. package/dist/esm/cloudflare/index.mjs +7 -1
  27. package/dist/esm/cloudflare/worker-manifest.mjs +13 -4
  28. package/dist/esm/cloudflare/wrangler-config.mjs +35 -7
  29. package/dist/esm/cloudflare-builder.mjs +241 -19
  30. package/dist/esm/cloudflare-output-contract.mjs +25 -1
  31. package/dist/esm/cloudflare-output-verifier/identity.mjs +26 -24
  32. package/dist/esm/cloudflare-output-verifier/index.mjs +10 -0
  33. package/dist/esm/cloudflare-output-verifier/manifest.mjs +46 -0
  34. package/dist/esm/cloudflare-output-verifier/mutation-policy.mjs +7 -1
  35. package/dist/esm/cloudflare-output-verifier/worker-bundles.mjs +11 -6
  36. package/dist/esm/deploy-output/npmAliases.mjs +28 -3
  37. package/dist/esm/release-envelope/framework-output.mjs +62 -49
  38. package/dist/esm/release-envelope/index.mjs +10 -4
  39. package/dist/esm/templates/cloudflare-entry.004-rendering-css.mjs +4 -0
  40. package/dist/esm/templates/cloudflare-entry.005-worker-dispatch.mjs +46 -0
  41. package/dist/esm/templates/cloudflare-entry.006-fetch-handler.mjs +9 -2
  42. package/dist/esm/templates/cloudflare-worker-route-data.mjs +1069 -0
  43. package/dist/esm-node/backend-federation-build/codegen.mjs +7 -2
  44. package/dist/esm-node/backend-federation-build/config.mjs +78 -31
  45. package/dist/esm-node/backend-federation-build/emit.mjs +18 -14
  46. package/dist/esm-node/cloudflare/delivery-unit.mjs +16 -26
  47. package/dist/esm-node/cloudflare/index.mjs +7 -1
  48. package/dist/esm-node/cloudflare/worker-manifest.mjs +13 -4
  49. package/dist/esm-node/cloudflare/wrangler-config.mjs +35 -7
  50. package/dist/esm-node/cloudflare-builder.mjs +241 -19
  51. package/dist/esm-node/cloudflare-output-contract.mjs +25 -1
  52. package/dist/esm-node/cloudflare-output-verifier/identity.mjs +26 -24
  53. package/dist/esm-node/cloudflare-output-verifier/index.mjs +10 -0
  54. package/dist/esm-node/cloudflare-output-verifier/manifest.mjs +46 -0
  55. package/dist/esm-node/cloudflare-output-verifier/mutation-policy.mjs +7 -1
  56. package/dist/esm-node/cloudflare-output-verifier/worker-bundles.mjs +11 -6
  57. package/dist/esm-node/deploy-output/npmAliases.mjs +28 -3
  58. package/dist/esm-node/release-envelope/framework-output.mjs +62 -49
  59. package/dist/esm-node/release-envelope/index.mjs +10 -4
  60. package/dist/esm-node/templates/cloudflare-entry.004-rendering-css.mjs +4 -0
  61. package/dist/esm-node/templates/cloudflare-entry.005-worker-dispatch.mjs +46 -0
  62. package/dist/esm-node/templates/cloudflare-entry.006-fetch-handler.mjs +9 -2
  63. package/dist/esm-node/templates/cloudflare-worker-route-data.mjs +1069 -0
  64. package/dist/types/backend-federation-build/codegen.d.ts +30 -0
  65. package/dist/types/backend-federation-build/config.d.ts +32 -13
  66. package/dist/types/cloudflare/delivery-unit.d.ts +1 -1
  67. package/dist/types/cloudflare/wrangler-config.d.ts +6 -0
  68. package/dist/types/cloudflare-builder.d.ts +45 -1
  69. package/dist/types/cloudflare-output-contract.d.ts +3 -1
  70. package/dist/types/cloudflare-output-verifier/worker-bundles.d.ts +2 -2
  71. package/dist/types/templates/cloudflare-worker-route-data.d.mts +14 -0
  72. package/package.json +25 -21
  73. package/src/backend-federation-build/codegen.ts +6 -2
  74. package/src/backend-federation-build/config.ts +207 -71
  75. package/src/backend-federation-build/emit.ts +33 -22
  76. package/src/cloudflare/delivery-unit.ts +39 -33
  77. package/src/cloudflare/index.ts +20 -6
  78. package/src/cloudflare/worker-manifest.ts +19 -3
  79. package/src/cloudflare/wrangler-config.ts +86 -10
  80. package/src/cloudflare-builder.ts +464 -15
  81. package/src/cloudflare-output-contract.ts +35 -2
  82. package/src/cloudflare-output-verifier/identity.ts +4 -0
  83. package/src/cloudflare-output-verifier/index.ts +20 -0
  84. package/src/cloudflare-output-verifier/manifest.ts +77 -0
  85. package/src/cloudflare-output-verifier/mutation-policy.ts +11 -1
  86. package/src/cloudflare-output-verifier/worker-bundles.ts +27 -11
  87. package/src/deploy-output/npmAliases.ts +52 -3
  88. package/src/release-envelope/framework-output.ts +163 -90
  89. package/src/release-envelope/index.ts +26 -5
  90. package/src/templates/cloudflare-entry.004-rendering-css.mjs +4 -0
  91. package/src/templates/cloudflare-entry.005-worker-dispatch.mjs +46 -0
  92. package/src/templates/cloudflare-entry.006-fetch-handler.mjs +9 -2
  93. package/src/templates/cloudflare-worker-route-data.mjs +1069 -0
@@ -43,7 +43,10 @@ __webpack_require__.d(__webpack_exports__, {
43
43
  applyCloudflareBuilderEnvironments: ()=>applyCloudflareBuilderEnvironments,
44
44
  applyCloudflareWorkerMfRuntimeBoundary: ()=>applyCloudflareWorkerMfRuntimeBoundary,
45
45
  applyCloudflareWorkerRspackConfig: ()=>applyCloudflareWorkerRspackConfig,
46
+ claimsByFunctionExternal: ()=>claimsByFunctionExternal,
47
+ createAbsentOptionalDependencyFilter: ()=>createAbsentOptionalDependencyFilter,
46
48
  createCloudflareBuilderPlugin: ()=>createCloudflareBuilderPlugin,
49
+ createRequestRedirectMatcher: ()=>createRequestRedirectMatcher,
47
50
  getCloudflareBuilderEnvironments: ()=>getCloudflareBuilderEnvironments,
48
51
  getCloudflareWorkerRspackConfig: ()=>getCloudflareWorkerRspackConfig
49
52
  });
@@ -60,8 +63,47 @@ const external_read_template_js_namespaceObject = require("./read-template.js");
60
63
  const moduleRequire = (0, external_node_module_namespaceObject.createRequire)(__rslib_import_meta_url__);
61
64
  const BFF_EFFECT_WORKER_ENTRY_NAME = '__modern_bff_effect';
62
65
  const BFF_EFFECT_WORKER_RUNTIME_QUERY = 'modern-bff-runtime';
66
+ const SERVER_LOADER_COMBINED_FILE = 'server-loader-combined.js';
67
+ const ROUTE_SERVER_LOADERS_FILE = 'route-server-loaders.js';
68
+ const WORKER_ROUTE_DATA_FILE = 'cloudflare-worker-route-data.js';
69
+ const WORKER_ROUTE_DATA_TEMPLATE = 'cloudflare-worker-route-data.mjs';
70
+ const DATA_LOADER_CLIENT_TRANSFORM = /plugin-data-loader[\\/](?:.+[\\/])?loader\.[cm]?js$/u;
63
71
  const MF_SSR_DATA_FETCH_RUNTIME_PLUGIN = '@module-federation/modern-js-v3/ssr-inject-data-fetch-function-plugin';
64
72
  const MF_SSR_DEV_RUNTIME_PLUGIN = '@module-federation/modern-js-v3/ssr-dev-plugin';
73
+ const WORKER_DEPENDENCY_CONDITIONS = [
74
+ [
75
+ 'esm',
76
+ 'import'
77
+ ],
78
+ [
79
+ 'wasm',
80
+ 'import'
81
+ ],
82
+ [
83
+ 'loaderImport',
84
+ 'import'
85
+ ],
86
+ [
87
+ 'worker',
88
+ 'import'
89
+ ],
90
+ [
91
+ 'commonjs',
92
+ 'require'
93
+ ],
94
+ [
95
+ 'amd',
96
+ 'require'
97
+ ],
98
+ [
99
+ 'loader',
100
+ 'require'
101
+ ],
102
+ [
103
+ 'unknown',
104
+ 'require'
105
+ ]
106
+ ];
65
107
  const JS_OR_TS_EXTENSIONS = new Set([
66
108
  '.js',
67
109
  '.jsx',
@@ -121,19 +163,154 @@ const resolvePackageFile = (packageName, filePath, paths)=>{
121
163
  const setAliasIfPresent = (alias, name, value)=>{
122
164
  if (value) alias.set(name, value);
123
165
  };
124
- const getCloudflareWorkerNodeExternals = ()=>Object.fromEntries(external_cloudflare_output_contract_js_namespaceObject.CLOUDFLARE_WORKER_NODE_BUILTINS.flatMap((builtin)=>{
125
- const nodeBuiltin = `node:${builtin}`;
166
+ const getCloudflareWorkerNodeExternals = ()=>Object.fromEntries([
167
+ ...external_cloudflare_output_contract_js_namespaceObject.CLOUDFLARE_WORKER_NODE_BUILTINS.flatMap((builtin)=>{
168
+ const nodeBuiltin = `node:${builtin}`;
169
+ const external = `module-import ${nodeBuiltin}`;
170
+ return (0, external_node_module_namespaceObject.isBuiltin)(builtin) ? [
171
+ [
172
+ builtin,
173
+ external
174
+ ],
175
+ [
176
+ nodeBuiltin,
177
+ external
178
+ ]
179
+ ] : [
180
+ [
181
+ nodeBuiltin,
182
+ external
183
+ ]
184
+ ];
185
+ }),
186
+ ...external_cloudflare_output_contract_js_namespaceObject.CLOUDFLARE_WORKER_PLATFORM_MODULES.map((platformModule)=>[
187
+ platformModule,
188
+ `module-import ${platformModule}`
189
+ ])
190
+ ]);
191
+ const getPackageNameFromRequest = (request)=>{
192
+ if (request.startsWith('.') || request.startsWith('/') || request.includes(':') || external_node_path_default().isAbsolute(request)) return;
193
+ const segments = request.split('/');
194
+ return request.startsWith('@') ? segments.length > 1 ? `${segments[0]}/${segments[1]}` : void 0 : segments[0];
195
+ };
196
+ const isRedirectedByAliasField = (manifest, aliasFields, request)=>aliasFields.some((field)=>{
197
+ let value = manifest;
198
+ for (const key of 'string' == typeof field ? [
199
+ field
200
+ ] : field)value = value && 'object' == typeof value ? value[key] : void 0;
201
+ return 'object' == typeof value && null !== value && Object.hasOwn(value, request);
202
+ });
203
+ const findOwningPackageManifest = (directory, cache)=>{
204
+ if (cache.has(directory)) return cache.get(directory);
205
+ let manifest;
206
+ const packageJsonPath = external_node_path_default().join(directory, 'package.json');
207
+ if (external_node_fs_default().existsSync(packageJsonPath)) try {
208
+ manifest = JSON.parse(external_node_fs_default().readFileSync(packageJsonPath, 'utf-8'));
209
+ } catch {
210
+ manifest = void 0;
211
+ }
212
+ else if (external_node_path_default().dirname(directory) !== directory) manifest = findOwningPackageManifest(external_node_path_default().dirname(directory), cache);
213
+ cache.set(directory, manifest);
214
+ return manifest;
215
+ };
216
+ const isPackageInstalled = (packageName, directory, moduleDirectories)=>moduleDirectories.some((moduleDirectory)=>{
217
+ if (external_node_path_default().isAbsolute(moduleDirectory)) return external_node_fs_default().existsSync(external_node_path_default().join(moduleDirectory, packageName));
218
+ let current = directory;
219
+ while(true){
220
+ if (external_node_fs_default().existsSync(external_node_path_default().join(current, moduleDirectory, packageName))) return true;
221
+ const parent = external_node_path_default().dirname(current);
222
+ if (parent === current) return false;
223
+ current = parent;
224
+ }
225
+ });
226
+ const createAbsentOptionalDependencyFilter = (isRedirected = ()=>false, moduleDirectories = [
227
+ 'node_modules'
228
+ ], aliasFields = [])=>{
229
+ const manifests = new Map();
230
+ return (request, context)=>{
231
+ const packageName = getPackageNameFromRequest(request);
232
+ if (!packageName || !context || isRedirected(request)) return false;
233
+ const manifest = findOwningPackageManifest(context, manifests);
234
+ if (!manifest) return false;
235
+ const optional = manifest.peerDependenciesMeta?.[packageName]?.optional === true || Object.hasOwn(manifest.optionalDependencies ?? {}, packageName);
236
+ return optional && !isRedirectedByAliasField(manifest, aliasFields, request) && !isPackageInstalled(packageName, context, moduleDirectories);
237
+ };
238
+ };
239
+ const getAliasNames = (alias)=>alias ? Array.isArray(alias) ? alias.map((entry)=>entry.onlyModule ? `${entry.name}$` : entry.name) : Object.keys(alias) : [];
240
+ const getExternalMatchers = (externals)=>{
241
+ if (Array.isArray(externals)) return externals.flatMap(getExternalMatchers);
242
+ if ('string' == typeof externals) return [
243
+ (request)=>request === externals
244
+ ];
245
+ if (externals instanceof RegExp) return [
246
+ (request)=>{
247
+ externals.lastIndex = 0;
248
+ return externals.test(request);
249
+ }
250
+ ];
251
+ if (externals && 'object' == typeof externals) {
252
+ const names = new Set(Object.entries(externals).filter(([, value])=>false !== value).map(([name])=>name));
126
253
  return [
127
- [
128
- builtin,
129
- `module-import ${nodeBuiltin}`
130
- ],
131
- [
132
- nodeBuiltin,
133
- `module-import ${nodeBuiltin}`
134
- ]
254
+ (request)=>names.has(request)
135
255
  ];
136
- }));
256
+ }
257
+ return [];
258
+ };
259
+ const createRequestRedirectMatcher = (options)=>{
260
+ const aliasNames = [
261
+ ...getAliasNames(options.resolve?.alias),
262
+ ...getAliasNames(options.resolve?.fallback)
263
+ ];
264
+ const externalMatchers = getExternalMatchers(options.externals);
265
+ return (request)=>externalMatchers.some((matches)=>matches(request)) || aliasNames.some((name)=>name.endsWith('$') ? request === name.slice(0, -1) : request === name || request.startsWith(`${name}/`));
266
+ };
267
+ const getFunctionExternals = (externals)=>Array.isArray(externals) ? externals.flatMap(getFunctionExternals) : 'function' == typeof externals ? [
268
+ externals
269
+ ] : [];
270
+ const callFunctionExternal = (external, data)=>new Promise((resolve, reject)=>{
271
+ const returned = external(data, (error, result)=>error ? reject(error) : resolve(result));
272
+ if (null !== returned && 'object' == typeof returned && 'function' == typeof returned.then) returned.then(resolve, reject);
273
+ else if (1 === external.length) resolve(returned);
274
+ });
275
+ const claimsByFunctionExternal = async (externals, data)=>{
276
+ for (const external of externals)try {
277
+ const result = await callFunctionExternal(external, data);
278
+ if (null != result && false !== result) return true;
279
+ } catch {
280
+ return true;
281
+ }
282
+ return false;
283
+ };
284
+ const PLUGIN_NAME = 'AbsentOptionalDependencyPlugin';
285
+ class AbsentOptionalDependencyPlugin {
286
+ apply(compiler) {
287
+ const isAbsent = createAbsentOptionalDependencyFilter(createRequestRedirectMatcher(compiler.options), compiler.options.resolve.modules, compiler.options.resolve.aliasFields);
288
+ const functionExternals = getFunctionExternals(compiler.options.externals);
289
+ compiler.hooks.normalModuleFactory.tap(PLUGIN_NAME, (factory)=>{
290
+ factory.hooks.beforeResolve.tapPromise(PLUGIN_NAME, async (data)=>{
291
+ if (!isAbsent(data.request, data.context)) return;
292
+ const claimed = await claimsByFunctionExternal(functionExternals, {
293
+ context: data.context,
294
+ contextInfo: {
295
+ issuer: data.contextInfo.issuer,
296
+ issuerLayer: data.contextInfo.issuerLayer ?? null
297
+ },
298
+ getResolve: (options)=>{
299
+ const resolver = factory.getResolver('normal', options ?? {});
300
+ return (context, request, callback)=>{
301
+ if (callback) return void resolver.resolve({}, context, request, {}, callback);
302
+ return new Promise((resolve, reject)=>{
303
+ resolver.resolve({}, context, request, {}, (error, result)=>error ? reject(error) : resolve(result || void 0));
304
+ });
305
+ };
306
+ },
307
+ request: data.request
308
+ });
309
+ return claimed ? void 0 : false;
310
+ });
311
+ });
312
+ }
313
+ }
137
314
  const normalizeWorkerOutputName = (name)=>external_node_path_default().posix.normalize(name.replace(/\\/gu, '/')).toLowerCase();
138
315
  const reserveWorkerChunkName = (baseName, reservedOutputNames)=>{
139
316
  let name = baseName;
@@ -183,6 +360,9 @@ function applyCloudflareWorkerRspackConfig(chain, workerEntryNames) {
183
360
  chain.optimization.runtimeChunk(config.optimization.runtimeChunk);
184
361
  chain.optimization.splitChunks(config.optimization.splitChunks);
185
362
  }
363
+ function removeCloudflareWorkerDataLoaderClientTransform(chain) {
364
+ for (const [name, rule] of Object.entries(chain.module.rules.entries() ?? {}))if (rule.uses.values().some((use)=>DATA_LOADER_CLIENT_TRANSFORM.test(String(use.get('loader'))))) chain.module.rules.delete(name);
365
+ }
186
366
  function applyCloudflareWorkerMfRuntimeBoundary(chain) {
187
367
  const runtimePlugin = (0, external_read_template_js_namespaceObject.getTemplatePath)('cloudflare-worker-mf-ssr-runtime-plugin.mjs');
188
368
  chain.plugins.delete('plugin-module-federation');
@@ -254,11 +434,40 @@ const prependBundlerChain = (environment, handler)=>{
254
434
  }
255
435
  };
256
436
  };
437
+ const createWorkerRouteDataModule = ()=>[
438
+ `import { routes } from './${ROUTE_SERVER_LOADERS_FILE}';`,
439
+ `import { createRouteDataRequestHandler } from ${JSON.stringify((0, external_read_template_js_namespaceObject.getTemplatePath)(WORKER_ROUTE_DATA_TEMPLATE))};`,
440
+ '',
441
+ `export const ${external_cloudflare_output_contract_js_namespaceObject.CLOUDFLARE_ROUTE_DATA_HANDLER_EXPORT} =`,
442
+ ' createRouteDataRequestHandler(routes);',
443
+ ''
444
+ ].join('\n');
445
+ const getWorkerRouteDataEntries = (appContext)=>{
446
+ const { entrypoints, internalDirectory } = appContext;
447
+ if (!entrypoints || !internalDirectory) return {};
448
+ return Object.fromEntries(entrypoints.flatMap(({ entryName })=>{
449
+ const entryDirectory = external_node_path_default().join(internalDirectory, entryName);
450
+ if (!external_node_fs_default().existsSync(external_node_path_default().join(entryDirectory, SERVER_LOADER_COMBINED_FILE)) || !external_node_fs_default().existsSync(external_node_path_default().join(entryDirectory, ROUTE_SERVER_LOADERS_FILE))) return [];
451
+ const routeDataFile = external_node_path_default().join(entryDirectory, WORKER_ROUTE_DATA_FILE);
452
+ external_node_fs_default().writeFileSync(routeDataFile, createWorkerRouteDataModule());
453
+ return [
454
+ [
455
+ (0, external_cloudflare_output_contract_js_namespaceObject.getCloudflareWorkerRouteDataEntryName)(entryName),
456
+ [
457
+ routeDataFile
458
+ ]
459
+ ]
460
+ ];
461
+ }));
462
+ };
257
463
  const getWorkerEntries = (environment, normalizedConfig, appContext)=>{
258
464
  const configuredEntries = environment.source?.entry;
259
- if (!configuredEntries) return;
260
- const entries = rewriteWorkerEntries(configuredEntries);
261
465
  const effectApiEntry = getEffectBffEntry(normalizedConfig, appContext);
466
+ if (!configuredEntries && !effectApiEntry) return;
467
+ const entries = configuredEntries ? {
468
+ ...rewriteWorkerEntries(configuredEntries),
469
+ ...getWorkerRouteDataEntries(appContext)
470
+ } : {};
262
471
  return effectApiEntry ? {
263
472
  ...entries,
264
473
  [BFF_EFFECT_WORKER_ENTRY_NAME]: [
@@ -291,6 +500,7 @@ const createCloudflareBundlerChain = (appContext, workerEntryNames)=>{
291
500
  ];
292
501
  return (chain)=>{
293
502
  applyCloudflareWorkerRspackConfig(chain, entryNames);
503
+ removeCloudflareWorkerDataLoaderClientTransform(chain);
294
504
  chain.output.module(true).library({
295
505
  type: 'module'
296
506
  }).publicPath('/').chunkFormat('module').chunkLoading('import').workerChunkLoading('import');
@@ -299,10 +509,15 @@ const createCloudflareBundlerChain = (appContext, workerEntryNames)=>{
299
509
  'worker',
300
510
  'webpack',
301
511
  (0, utils_namespaceObject.isProd)() ? 'production' : 'development',
302
- 'import',
303
- 'require',
304
512
  'module'
305
513
  ])chain.resolve.conditionNames.add(condition);
514
+ for (const [dependencyType, condition] of WORKER_DEPENDENCY_CONDITIONS)chain.resolve.byDependency.set(dependencyType, {
515
+ conditionNames: [
516
+ condition,
517
+ '...'
518
+ ]
519
+ });
520
+ chain.plugin('cloudflare-worker-absent-optional-dependencies').use(AbsentOptionalDependencyPlugin);
306
521
  applyCloudflareWorkerMfRuntimeBoundary(chain);
307
522
  if (tanstackRouterSsrServerFile) {
308
523
  chain.resolve.alias.set('@tanstack/router-core/ssr/server$', tanstackRouterSsrServerFile);
@@ -338,7 +553,14 @@ const createCloudflareBundlerChain = (appContext, workerEntryNames)=>{
338
553
  };
339
554
  function getCloudflareBuilderEnvironments({ appContext, environments, normalizedConfig, resolveDeployProvider = resolveStdEnvDeployProvider }) {
340
555
  if (!isCloudflareWorkerDeploy(normalizedConfig, resolveDeployProvider)) return environments;
341
- const workerEnvironment = environments[builder_namespaceObject.SERVICE_WORKER_ENVIRONMENT_NAME];
556
+ const workerEnvironment = environments[builder_namespaceObject.SERVICE_WORKER_ENVIRONMENT_NAME] ?? (appContext.apiOnly ? {
557
+ output: {
558
+ target: 'web-worker'
559
+ },
560
+ source: {
561
+ entry: {}
562
+ }
563
+ } : void 0);
342
564
  if (!workerEnvironment) return environments;
343
565
  const workerEntries = getWorkerEntries(workerEnvironment, normalizedConfig, appContext);
344
566
  if (!workerEntries) return environments;
@@ -354,6 +576,9 @@ function getCloudflareBuilderEnvironments({ appContext, environments, normalized
354
576
  entry: workerEntries
355
577
  }
356
578
  }, createCloudflareBundlerChain(appContext, Object.keys(workerEntries)));
579
+ if (appContext.apiOnly) return {
580
+ [builder_namespaceObject.SERVICE_WORKER_ENVIRONMENT_NAME]: cloudflareWorkerEnvironment
581
+ };
357
582
  return {
358
583
  ...environments,
359
584
  [builder_namespaceObject.SERVICE_WORKER_ENVIRONMENT_NAME]: cloudflareWorkerEnvironment
@@ -378,14 +603,20 @@ const createCloudflareBuilderPlugin = (resolveDeployProvider = resolveStdEnvDepl
378
603
  exports.applyCloudflareBuilderEnvironments = __webpack_exports__.applyCloudflareBuilderEnvironments;
379
604
  exports.applyCloudflareWorkerMfRuntimeBoundary = __webpack_exports__.applyCloudflareWorkerMfRuntimeBoundary;
380
605
  exports.applyCloudflareWorkerRspackConfig = __webpack_exports__.applyCloudflareWorkerRspackConfig;
606
+ exports.claimsByFunctionExternal = __webpack_exports__.claimsByFunctionExternal;
607
+ exports.createAbsentOptionalDependencyFilter = __webpack_exports__.createAbsentOptionalDependencyFilter;
381
608
  exports.createCloudflareBuilderPlugin = __webpack_exports__.createCloudflareBuilderPlugin;
609
+ exports.createRequestRedirectMatcher = __webpack_exports__.createRequestRedirectMatcher;
382
610
  exports.getCloudflareBuilderEnvironments = __webpack_exports__.getCloudflareBuilderEnvironments;
383
611
  exports.getCloudflareWorkerRspackConfig = __webpack_exports__.getCloudflareWorkerRspackConfig;
384
612
  for(var __rspack_i in __webpack_exports__)if (-1 === [
385
613
  "applyCloudflareBuilderEnvironments",
386
614
  "applyCloudflareWorkerMfRuntimeBoundary",
387
615
  "applyCloudflareWorkerRspackConfig",
616
+ "claimsByFunctionExternal",
617
+ "createAbsentOptionalDependencyFilter",
388
618
  "createCloudflareBuilderPlugin",
619
+ "createRequestRedirectMatcher",
389
620
  "getCloudflareBuilderEnvironments",
390
621
  "getCloudflareWorkerRspackConfig"
391
622
  ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
@@ -39,27 +39,49 @@ const CLOUDFLARE_RUNTIME_TYPE = 'cloudflare-module-worker';
39
39
  const CLOUDFLARE_OUTPUT_PACKAGE_TYPE = 'module';
40
40
  const CLOUDFLARE_WORKER_PACKAGE_TYPE = 'commonjs';
41
41
  const CLOUDFLARE_WORKER_BUNDLE_FORMAT = 'commonjs';
42
+ const CLOUDFLARE_ROUTE_DATA_HANDLER_EXPORT = 'handleRouteDataRequest';
43
+ const getCloudflareWorkerRouteDataEntryName = (entryName)=>`${entryName}-server-loaders`;
42
44
  const CLOUDFLARE_WORKER_NODE_BUILTINS = [
45
+ '_http_agent',
46
+ '_http_client',
47
+ '_http_common',
48
+ '_http_incoming',
49
+ '_http_outgoing',
50
+ '_http_server',
51
+ '_tls_common',
52
+ '_tls_wrap',
43
53
  'assert',
44
54
  'assert/strict',
45
55
  'async_hooks',
46
56
  'buffer',
47
57
  'child_process',
58
+ 'cluster',
59
+ 'console',
60
+ 'constants',
48
61
  'crypto',
49
62
  'dgram',
63
+ 'diagnostics_channel',
50
64
  'dns',
65
+ 'dns/promises',
51
66
  'domain',
52
67
  'events',
53
68
  'fs',
54
69
  'fs/promises',
55
70
  'http',
56
71
  'http2',
72
+ 'https',
57
73
  'inspector',
74
+ 'inspector/promises',
58
75
  'module',
59
76
  'net',
60
77
  'os',
61
78
  'path',
79
+ 'path/posix',
80
+ 'path/win32',
81
+ 'perf_hooks',
62
82
  'process',
83
+ 'punycode',
84
+ 'querystring',
63
85
  'readline',
64
86
  'readline/promises',
65
87
  'repl',
@@ -69,6 +91,8 @@ const CLOUDFLARE_WORKER_NODE_BUILTINS = [
69
91
  'stream/promises',
70
92
  'stream/web',
71
93
  'string_decoder',
94
+ 'sys',
95
+ 'test',
72
96
  'timers',
73
97
  'timers/promises',
74
98
  'tls',
@@ -96,6 +120,7 @@ __webpack_require__.d(__webpack_exports__, {}, {
96
120
  CLOUDFLARE_OUTPUT_PACKAGE_TYPE: CLOUDFLARE_OUTPUT_PACKAGE_TYPE,
97
121
  CLOUDFLARE_PUBLIC_ASSETS_DIRECTORY: CLOUDFLARE_PUBLIC_ASSETS_DIRECTORY,
98
122
  CLOUDFLARE_REQUIRED_COMPATIBILITY_FLAGS: CLOUDFLARE_REQUIRED_COMPATIBILITY_FLAGS,
123
+ CLOUDFLARE_ROUTE_DATA_HANDLER_EXPORT: CLOUDFLARE_ROUTE_DATA_HANDLER_EXPORT,
99
124
  CLOUDFLARE_RUNTIME_TYPE: CLOUDFLARE_RUNTIME_TYPE,
100
125
  CLOUDFLARE_WORKER_BUNDLE_DIRECTORY: CLOUDFLARE_WORKER_BUNDLE_DIRECTORY,
101
126
  CLOUDFLARE_WORKER_BUNDLE_FORMAT: CLOUDFLARE_WORKER_BUNDLE_FORMAT,
@@ -105,13 +130,15 @@ __webpack_require__.d(__webpack_exports__, {}, {
105
130
  CLOUDFLARE_WORKER_PACKAGE_FILE: CLOUDFLARE_WORKER_PACKAGE_FILE,
106
131
  CLOUDFLARE_WORKER_PACKAGE_TYPE: CLOUDFLARE_WORKER_PACKAGE_TYPE,
107
132
  CLOUDFLARE_WORKER_PLATFORM_MODULES: CLOUDFLARE_WORKER_PLATFORM_MODULES,
108
- CLOUDFLARE_WRANGLER_CONFIG_FILE: CLOUDFLARE_WRANGLER_CONFIG_FILE
133
+ CLOUDFLARE_WRANGLER_CONFIG_FILE: CLOUDFLARE_WRANGLER_CONFIG_FILE,
134
+ getCloudflareWorkerRouteDataEntryName: getCloudflareWorkerRouteDataEntryName
109
135
  });
110
136
  exports.CLOUDFLARE_ASSETS_BINDING = __webpack_exports__.CLOUDFLARE_ASSETS_BINDING;
111
137
  exports.CLOUDFLARE_OUTPUT_PACKAGE_FILE = __webpack_exports__.CLOUDFLARE_OUTPUT_PACKAGE_FILE;
112
138
  exports.CLOUDFLARE_OUTPUT_PACKAGE_TYPE = __webpack_exports__.CLOUDFLARE_OUTPUT_PACKAGE_TYPE;
113
139
  exports.CLOUDFLARE_PUBLIC_ASSETS_DIRECTORY = __webpack_exports__.CLOUDFLARE_PUBLIC_ASSETS_DIRECTORY;
114
140
  exports.CLOUDFLARE_REQUIRED_COMPATIBILITY_FLAGS = __webpack_exports__.CLOUDFLARE_REQUIRED_COMPATIBILITY_FLAGS;
141
+ exports.CLOUDFLARE_ROUTE_DATA_HANDLER_EXPORT = __webpack_exports__.CLOUDFLARE_ROUTE_DATA_HANDLER_EXPORT;
115
142
  exports.CLOUDFLARE_RUNTIME_TYPE = __webpack_exports__.CLOUDFLARE_RUNTIME_TYPE;
116
143
  exports.CLOUDFLARE_WORKER_BUNDLE_DIRECTORY = __webpack_exports__.CLOUDFLARE_WORKER_BUNDLE_DIRECTORY;
117
144
  exports.CLOUDFLARE_WORKER_BUNDLE_FORMAT = __webpack_exports__.CLOUDFLARE_WORKER_BUNDLE_FORMAT;
@@ -122,12 +149,14 @@ exports.CLOUDFLARE_WORKER_PACKAGE_FILE = __webpack_exports__.CLOUDFLARE_WORKER_P
122
149
  exports.CLOUDFLARE_WORKER_PACKAGE_TYPE = __webpack_exports__.CLOUDFLARE_WORKER_PACKAGE_TYPE;
123
150
  exports.CLOUDFLARE_WORKER_PLATFORM_MODULES = __webpack_exports__.CLOUDFLARE_WORKER_PLATFORM_MODULES;
124
151
  exports.CLOUDFLARE_WRANGLER_CONFIG_FILE = __webpack_exports__.CLOUDFLARE_WRANGLER_CONFIG_FILE;
152
+ exports.getCloudflareWorkerRouteDataEntryName = __webpack_exports__.getCloudflareWorkerRouteDataEntryName;
125
153
  for(var __rspack_i in __webpack_exports__)if (-1 === [
126
154
  "CLOUDFLARE_ASSETS_BINDING",
127
155
  "CLOUDFLARE_OUTPUT_PACKAGE_FILE",
128
156
  "CLOUDFLARE_OUTPUT_PACKAGE_TYPE",
129
157
  "CLOUDFLARE_PUBLIC_ASSETS_DIRECTORY",
130
158
  "CLOUDFLARE_REQUIRED_COMPATIBILITY_FLAGS",
159
+ "CLOUDFLARE_ROUTE_DATA_HANDLER_EXPORT",
131
160
  "CLOUDFLARE_RUNTIME_TYPE",
132
161
  "CLOUDFLARE_WORKER_BUNDLE_DIRECTORY",
133
162
  "CLOUDFLARE_WORKER_BUNDLE_FORMAT",
@@ -137,7 +166,8 @@ for(var __rspack_i in __webpack_exports__)if (-1 === [
137
166
  "CLOUDFLARE_WORKER_PACKAGE_FILE",
138
167
  "CLOUDFLARE_WORKER_PACKAGE_TYPE",
139
168
  "CLOUDFLARE_WORKER_PLATFORM_MODULES",
140
- "CLOUDFLARE_WRANGLER_CONFIG_FILE"
169
+ "CLOUDFLARE_WRANGLER_CONFIG_FILE",
170
+ "getCloudflareWorkerRouteDataEntryName"
141
171
  ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
142
172
  Object.defineProperty(exports, '__esModule', {
143
173
  value: true
@@ -56,30 +56,32 @@ const verifyDeliveryUnitIdentity = (issues, manifest, manifestPath, declared)=>{
56
56
  ]){
57
57
  const marker = stamped.surfaces[surface];
58
58
  const expected = declared?.surfaces?.[surface];
59
- if (declared?.surfaces && !expected) {
60
- if (marker) (0, external_issues_js_namespaceObject.addIssue)(issues, {
61
- code: 'delivery-unit-drift',
62
- message: `Cloudflare worker manifest declares an unexpected ${surface} delivery-unit surface for this topology profile.`,
63
- path: manifestPath
64
- });
65
- continue;
66
- }
67
- if (!marker || 'object' != typeof marker) {
68
- (0, external_issues_js_namespaceObject.addIssue)(issues, {
69
- code: 'missing-delivery-unit',
70
- message: `Cloudflare worker manifest is missing the ${surface} delivery-unit surface marker.`,
71
- path: manifestPath
72
- });
73
- continue;
74
- }
75
- for (const field of backend_federation_contracts_namespaceObject.DELIVERY_UNIT_IDENTITY_FIELDS){
76
- const markerValue = (0, backend_federation_contracts_namespaceObject.deliveryUnitIdentityFieldValue)(marker, field);
77
- const stampedValue = (0, backend_federation_contracts_namespaceObject.deliveryUnitIdentityFieldValue)(stamped, field);
78
- (0, external_issues_js_namespaceObject.assertEqual)(issues, markerValue, stampedValue, {
79
- code: 'delivery-unit-drift',
80
- message: `Cloudflare worker manifest ${surface} surface deliveryUnit.${field} must derive from one delivery-unit record (expected ${stampedValue ?? 'undefined'}, received ${markerValue ?? 'undefined'}).`,
81
- path: manifestPath
82
- });
59
+ if (expected || marker) {
60
+ if (declared?.surfaces && !expected) {
61
+ if (marker) (0, external_issues_js_namespaceObject.addIssue)(issues, {
62
+ code: 'delivery-unit-drift',
63
+ message: `Cloudflare worker manifest declares an unexpected ${surface} delivery-unit surface for this topology profile.`,
64
+ path: manifestPath
65
+ });
66
+ continue;
67
+ }
68
+ if (!marker || 'object' != typeof marker) {
69
+ (0, external_issues_js_namespaceObject.addIssue)(issues, {
70
+ code: 'missing-delivery-unit',
71
+ message: `Cloudflare worker manifest is missing the ${surface} delivery-unit surface marker.`,
72
+ path: manifestPath
73
+ });
74
+ continue;
75
+ }
76
+ for (const field of backend_federation_contracts_namespaceObject.DELIVERY_UNIT_IDENTITY_FIELDS){
77
+ const markerValue = (0, backend_federation_contracts_namespaceObject.deliveryUnitIdentityFieldValue)(marker, field);
78
+ const stampedValue = (0, backend_federation_contracts_namespaceObject.deliveryUnitIdentityFieldValue)(stamped, field);
79
+ (0, external_issues_js_namespaceObject.assertEqual)(issues, markerValue, stampedValue, {
80
+ code: 'delivery-unit-drift',
81
+ message: `Cloudflare worker manifest ${surface} surface deliveryUnit.${field} must derive from one delivery-unit record (expected ${stampedValue ?? 'undefined'}, received ${markerValue ?? 'undefined'}).`,
82
+ path: manifestPath
83
+ });
84
+ }
83
85
  }
84
86
  }
85
87
  };
@@ -118,6 +118,16 @@ const verifyCloudflareOutput = async (options)=>{
118
118
  }
119
119
  }
120
120
  if (wrangler) {
121
+ if ('string' != typeof wrangler.name || 0 === wrangler.name.trim().length) (0, external_issues_js_namespaceObject.addIssue)(issues, {
122
+ code: 'invalid-wrangler',
123
+ message: 'wrangler.json name must be a non-empty worker name.',
124
+ path: wranglerPath
125
+ });
126
+ if ('string' != typeof wrangler.compatibility_date || !/^\d{4}-\d{2}-\d{2}$/u.test(wrangler.compatibility_date)) (0, external_issues_js_namespaceObject.addIssue)(issues, {
127
+ code: 'invalid-wrangler',
128
+ message: 'wrangler.json compatibility_date must use YYYY-MM-DD.',
129
+ path: wranglerPath
130
+ });
121
131
  (0, external_issues_js_namespaceObject.assertEqual)(issues, wrangler.main, outputPlan.wrangler.main, {
122
132
  code: 'invalid-wrangler',
123
133
  message: `wrangler.json main must be ${outputPlan.wrangler.main}.`,
@@ -74,6 +74,52 @@ const verifyManifestShape = (issues, manifest, manifestPath)=>{
74
74
  message: 'Cloudflare output manifest routeSpec.routes must be array.',
75
75
  path: manifestPath
76
76
  });
77
+ const security = manifest.security;
78
+ if (security && 'object' == typeof security && 'boolean' == typeof security.enabled) {
79
+ const cors = security.cors;
80
+ if (!cors || 'object' != typeof cors || 'boolean' != typeof cors.assets || !Array.isArray(cors.allowedOrigins) || !Array.isArray(cors.allowedMethods) || !Array.isArray(cors.allowedHeaders)) (0, external_issues_js_namespaceObject.addIssue)(issues, {
81
+ code: 'invalid-manifest',
82
+ message: 'Cloudflare output manifest security.cors is incomplete.',
83
+ path: manifestPath
84
+ });
85
+ if (security.enabled) {
86
+ const headers = security.headers;
87
+ const csp = security.contentSecurityPolicy;
88
+ const noindex = security.noindex;
89
+ if (!headers || 'object' != typeof headers || ![
90
+ 'string',
91
+ 'boolean'
92
+ ].includes(typeof headers.referrerPolicy) || ![
93
+ 'string',
94
+ 'boolean'
95
+ ].includes(typeof headers.contentTypeOptions) || ![
96
+ 'string',
97
+ 'boolean'
98
+ ].includes(typeof headers.permissionsPolicy)) (0, external_issues_js_namespaceObject.addIssue)(issues, {
99
+ code: 'invalid-manifest',
100
+ message: 'Cloudflare output manifest security.headers is incomplete.',
101
+ path: manifestPath
102
+ });
103
+ if (!csp || ![
104
+ 'off',
105
+ 'report-only',
106
+ 'enforce'
107
+ ].includes(csp.mode) || !csp.directives || 'object' != typeof csp.directives || Array.isArray(csp.directives) || Object.values(csp.directives).some((value)=>!Array.isArray(value) || value.some((entry)=>'string' != typeof entry))) (0, external_issues_js_namespaceObject.addIssue)(issues, {
108
+ code: 'invalid-manifest',
109
+ message: 'Cloudflare output manifest security.contentSecurityPolicy is invalid.',
110
+ path: manifestPath
111
+ });
112
+ if (!noindex || 'boolean' != typeof noindex.workersDev || 'boolean' != typeof noindex.localhost || !Array.isArray(noindex.previewHostnames)) (0, external_issues_js_namespaceObject.addIssue)(issues, {
113
+ code: 'invalid-manifest',
114
+ message: 'Cloudflare output manifest security.noindex is incomplete.',
115
+ path: manifestPath
116
+ });
117
+ }
118
+ } else (0, external_issues_js_namespaceObject.addIssue)(issues, {
119
+ code: 'invalid-manifest',
120
+ message: 'Cloudflare output manifest security.enabled must be a boolean.',
121
+ path: manifestPath
122
+ });
77
123
  if (manifest.bff?.runtimeFramework === 'effect') (0, external_issues_js_namespaceObject.assertEqual)(issues, manifest.bff.dispatcherExport, constants_js_namespaceObject.BFF_EFFECT_WORKER_DISPATCHER_EXPORT, {
78
124
  code: 'invalid-manifest',
79
125
  message: `Cloudflare Effect BFF manifest dispatcherExport must be ${constants_js_namespaceObject.BFF_EFFECT_WORKER_DISPATCHER_EXPORT}.`,
@@ -128,7 +128,13 @@ const verifyCloudflareOutputMutationPolicy = async (options)=>{
128
128
  const files = (await Promise.all(options.scanRoots.map((scanRoot)=>walkFiles(external_node_path_default().resolve(scanRoot))))).flat();
129
129
  for (const file of files){
130
130
  if (excludedFiles.has(file)) continue;
131
- const source = await promises_default().readFile(file, 'utf-8');
131
+ let source;
132
+ try {
133
+ source = await promises_default().readFile(file, 'utf-8');
134
+ } catch (error) {
135
+ if ('ENOENT' === error.code) continue;
136
+ throw error;
137
+ }
132
138
  for (const forbidden of FORBIDDEN_MUTATION_PATTERNS)if (forbidden.pattern.test(source)) (0, external_issues_js_namespaceObject.addIssue)(issues, {
133
139
  code: forbidden.code,
134
140
  message: forbidden.message,
@@ -55,7 +55,7 @@ const traverse_namespaceObject = require("@babel/traverse");
55
55
  var traverse_default = /*#__PURE__*/ __webpack_require__.n(traverse_namespaceObject);
56
56
  const external_cloudflare_output_contract_js_namespaceObject = require("../cloudflare-output-contract.js");
57
57
  const external_issues_js_namespaceObject = require("./issues.js");
58
- const getReferencedRouteWorkers = (manifest)=>Array.isArray(manifest?.routeSpec?.routes) ? manifest.routeSpec.routes.map((route)=>'string' == typeof route?.worker && route.worker.length > 0 ? route.worker : void 0).filter((worker)=>'string' == typeof worker) : [];
58
+ const getReferencedRouteWorkers = (manifest, field)=>Array.isArray(manifest?.routeSpec?.routes) ? manifest.routeSpec.routes.map((route)=>'string' == typeof route?.[field] && route[field].length > 0 ? route[field] : void 0).filter((worker)=>'string' == typeof worker) : [];
59
59
  const getEffectBffWorker = (manifest)=>manifest?.bff?.runtimeFramework === 'effect' && 'string' == typeof manifest.bff.worker ? manifest.bff.worker : void 0;
60
60
  const getWorkerBundleReferences = (manifest)=>{
61
61
  const effectBffWorker = getEffectBffWorker(manifest);
@@ -67,9 +67,14 @@ const getWorkerBundleReferences = (manifest)=>{
67
67
  reference: effectBffWorker
68
68
  }
69
69
  ] : [],
70
- ...getReferencedRouteWorkers(manifest).map((reference)=>({
70
+ ...getReferencedRouteWorkers(manifest, 'worker').map((reference)=>({
71
71
  kind: 'route',
72
72
  reference
73
+ })),
74
+ ...getReferencedRouteWorkers(manifest, 'routeDataWorker').map((reference)=>({
75
+ dispatcherExport: external_cloudflare_output_contract_js_namespaceObject.CLOUDFLARE_ROUTE_DATA_HANDLER_EXPORT,
76
+ kind: 'route-data',
77
+ reference
73
78
  }))
74
79
  ];
75
80
  };
@@ -90,7 +95,7 @@ const resolveWorkerBundleReference = (issues, outputDirectory, reference, manife
90
95
  path: workerPath
91
96
  };
92
97
  };
93
- const missingWorkerBundleMessage = (reference)=>'effect-bff' === reference.kind ? 'Cloudflare Effect BFF manifest points to a missing worker bundle.' : 'Cloudflare route worker manifest points to a missing worker bundle.';
98
+ const missingWorkerBundleMessage = (reference)=>'effect-bff' === reference.kind ? 'Cloudflare Effect BFF manifest points to a missing worker bundle.' : 'route-data' === reference.kind ? 'Cloudflare route data worker manifest points to a missing worker bundle.' : 'Cloudflare route worker manifest points to a missing worker bundle.';
94
99
  const isAstNode = (value)=>null !== value && 'object' == typeof value && 'type' in value && 'string' == typeof value.type;
95
100
  const getNodeName = (node)=>{
96
101
  if (!isAstNode(node)) return;
@@ -334,9 +339,9 @@ const verifyWorkerModuleClosure = async (issues, entryPath, entrySource, contrac
334
339
  };
335
340
  const verifyWorkerBundleReferences = async (issues, worker, source, contract)=>{
336
341
  const entryAnalysis = await verifyWorkerModuleClosure(issues, worker.path, source, contract);
337
- if ('effect-bff' === worker.kind && 'string' == typeof worker.dispatcherExport && !entryAnalysis?.exports.has(worker.dispatcherExport)) (0, external_issues_js_namespaceObject.addIssue)(issues, {
342
+ if ('string' == typeof worker.dispatcherExport && !entryAnalysis?.exports.has(worker.dispatcherExport)) (0, external_issues_js_namespaceObject.addIssue)(issues, {
338
343
  code: 'invalid-worker-bundle',
339
- message: 'Cloudflare Effect BFF worker bundle must expose its manifest dispatcherExport.',
344
+ message: 'route-data' === worker.kind ? `Cloudflare route data worker bundle must expose ${worker.dispatcherExport}.` : 'Cloudflare Effect BFF worker bundle must expose its manifest dispatcherExport.',
340
345
  path: worker.path
341
346
  });
342
347
  };