@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.
- package/dist/cjs/backend-federation-build/codegen.js +7 -2
- package/dist/cjs/backend-federation-build/config.js +86 -36
- package/dist/cjs/backend-federation-build/emit.js +17 -13
- package/dist/cjs/cloudflare/delivery-unit.js +16 -26
- package/dist/cjs/cloudflare/index.js +7 -1
- package/dist/cjs/cloudflare/worker-manifest.js +13 -4
- package/dist/cjs/cloudflare/wrangler-config.js +35 -7
- package/dist/cjs/cloudflare-builder.js +247 -16
- package/dist/cjs/cloudflare-output-contract.js +32 -2
- package/dist/cjs/cloudflare-output-verifier/identity.js +26 -24
- package/dist/cjs/cloudflare-output-verifier/index.js +10 -0
- package/dist/cjs/cloudflare-output-verifier/manifest.js +46 -0
- package/dist/cjs/cloudflare-output-verifier/mutation-policy.js +7 -1
- package/dist/cjs/cloudflare-output-verifier/worker-bundles.js +10 -5
- package/dist/cjs/deploy-output/npmAliases.js +28 -3
- package/dist/cjs/release-envelope/framework-output.js +62 -49
- package/dist/cjs/release-envelope/index.js +10 -4
- package/dist/cjs/templates/cloudflare-entry.004-rendering-css.mjs +4 -0
- package/dist/cjs/templates/cloudflare-entry.005-worker-dispatch.mjs +46 -0
- package/dist/cjs/templates/cloudflare-entry.006-fetch-handler.mjs +9 -2
- package/dist/cjs/templates/cloudflare-worker-route-data.mjs +1069 -0
- package/dist/esm/backend-federation-build/codegen.mjs +7 -2
- package/dist/esm/backend-federation-build/config.mjs +78 -31
- package/dist/esm/backend-federation-build/emit.mjs +18 -14
- package/dist/esm/cloudflare/delivery-unit.mjs +16 -26
- package/dist/esm/cloudflare/index.mjs +7 -1
- package/dist/esm/cloudflare/worker-manifest.mjs +13 -4
- package/dist/esm/cloudflare/wrangler-config.mjs +35 -7
- package/dist/esm/cloudflare-builder.mjs +241 -19
- package/dist/esm/cloudflare-output-contract.mjs +25 -1
- package/dist/esm/cloudflare-output-verifier/identity.mjs +26 -24
- package/dist/esm/cloudflare-output-verifier/index.mjs +10 -0
- package/dist/esm/cloudflare-output-verifier/manifest.mjs +46 -0
- package/dist/esm/cloudflare-output-verifier/mutation-policy.mjs +7 -1
- package/dist/esm/cloudflare-output-verifier/worker-bundles.mjs +11 -6
- package/dist/esm/deploy-output/npmAliases.mjs +28 -3
- package/dist/esm/release-envelope/framework-output.mjs +62 -49
- package/dist/esm/release-envelope/index.mjs +10 -4
- package/dist/esm/templates/cloudflare-entry.004-rendering-css.mjs +4 -0
- package/dist/esm/templates/cloudflare-entry.005-worker-dispatch.mjs +46 -0
- package/dist/esm/templates/cloudflare-entry.006-fetch-handler.mjs +9 -2
- package/dist/esm/templates/cloudflare-worker-route-data.mjs +1069 -0
- package/dist/esm-node/backend-federation-build/codegen.mjs +7 -2
- package/dist/esm-node/backend-federation-build/config.mjs +78 -31
- package/dist/esm-node/backend-federation-build/emit.mjs +18 -14
- package/dist/esm-node/cloudflare/delivery-unit.mjs +16 -26
- package/dist/esm-node/cloudflare/index.mjs +7 -1
- package/dist/esm-node/cloudflare/worker-manifest.mjs +13 -4
- package/dist/esm-node/cloudflare/wrangler-config.mjs +35 -7
- package/dist/esm-node/cloudflare-builder.mjs +241 -19
- package/dist/esm-node/cloudflare-output-contract.mjs +25 -1
- package/dist/esm-node/cloudflare-output-verifier/identity.mjs +26 -24
- package/dist/esm-node/cloudflare-output-verifier/index.mjs +10 -0
- package/dist/esm-node/cloudflare-output-verifier/manifest.mjs +46 -0
- package/dist/esm-node/cloudflare-output-verifier/mutation-policy.mjs +7 -1
- package/dist/esm-node/cloudflare-output-verifier/worker-bundles.mjs +11 -6
- package/dist/esm-node/deploy-output/npmAliases.mjs +28 -3
- package/dist/esm-node/release-envelope/framework-output.mjs +62 -49
- package/dist/esm-node/release-envelope/index.mjs +10 -4
- package/dist/esm-node/templates/cloudflare-entry.004-rendering-css.mjs +4 -0
- package/dist/esm-node/templates/cloudflare-entry.005-worker-dispatch.mjs +46 -0
- package/dist/esm-node/templates/cloudflare-entry.006-fetch-handler.mjs +9 -2
- package/dist/esm-node/templates/cloudflare-worker-route-data.mjs +1069 -0
- package/dist/types/backend-federation-build/codegen.d.ts +30 -0
- package/dist/types/backend-federation-build/config.d.ts +32 -13
- package/dist/types/cloudflare/delivery-unit.d.ts +1 -1
- package/dist/types/cloudflare/wrangler-config.d.ts +6 -0
- package/dist/types/cloudflare-builder.d.ts +45 -1
- package/dist/types/cloudflare-output-contract.d.ts +3 -1
- package/dist/types/cloudflare-output-verifier/worker-bundles.d.ts +2 -2
- package/dist/types/templates/cloudflare-worker-route-data.d.mts +14 -0
- package/package.json +25 -21
- package/src/backend-federation-build/codegen.ts +6 -2
- package/src/backend-federation-build/config.ts +207 -71
- package/src/backend-federation-build/emit.ts +33 -22
- package/src/cloudflare/delivery-unit.ts +39 -33
- package/src/cloudflare/index.ts +20 -6
- package/src/cloudflare/worker-manifest.ts +19 -3
- package/src/cloudflare/wrangler-config.ts +86 -10
- package/src/cloudflare-builder.ts +464 -15
- package/src/cloudflare-output-contract.ts +35 -2
- package/src/cloudflare-output-verifier/identity.ts +4 -0
- package/src/cloudflare-output-verifier/index.ts +20 -0
- package/src/cloudflare-output-verifier/manifest.ts +77 -0
- package/src/cloudflare-output-verifier/mutation-policy.ts +11 -1
- package/src/cloudflare-output-verifier/worker-bundles.ts +27 -11
- package/src/deploy-output/npmAliases.ts +52 -3
- package/src/release-envelope/framework-output.ts +163 -90
- package/src/release-envelope/index.ts +26 -5
- package/src/templates/cloudflare-entry.004-rendering-css.mjs +4 -0
- package/src/templates/cloudflare-entry.005-worker-dispatch.mjs +46 -0
- package/src/templates/cloudflare-entry.006-fetch-handler.mjs +9 -2
- 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(
|
|
125
|
-
|
|
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 (
|
|
60
|
-
if (
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
(
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
const
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
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
|
-
|
|
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?.
|
|
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 ('
|
|
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
|
};
|