@bleedingdev/modern-js-app-tools-extensions 3.9.0-ultramodern.12 → 3.9.0-ultramodern.13
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-builder.js +13 -3
- package/dist/cjs/cloudflare-output-contract.js +1 -0
- 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/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/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-builder.mjs +13 -3
- package/dist/esm/cloudflare-output-contract.mjs +1 -0
- 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/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-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-builder.mjs +13 -3
- package/dist/esm-node/cloudflare-output-contract.mjs +1 -0
- 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/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/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-builder.d.ts +1 -0
- package/dist/types/cloudflare-output-contract.d.ts +1 -1
- package/package.json +20 -20
- 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-builder.ts +18 -4
- package/src/cloudflare-output-contract.ts +1 -0
- 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/deploy-output/npmAliases.ts +52 -3
- package/src/release-envelope/framework-output.ts +163 -90
- package/src/release-envelope/index.ts +26 -5
|
@@ -10,6 +10,11 @@ const MICROVERTICAL_RELEASE_IDENTITY_CARRIERS_KIND = 'ultramodern-release-identi
|
|
|
10
10
|
const MICROVERTICAL_RELEASE_IDENTITY_CARRIERS_SCHEMA_VERSION = 1;
|
|
11
11
|
const COMPILED_MODULE_PATTERN = /\.(?:c|m)?js$/u;
|
|
12
12
|
const EFFECT_BFF_WORKER_PATTERN = /^worker\/__modern_bff_effect\.(?:c|m)?js$/u;
|
|
13
|
+
const EFFECT_BFF_WORKER_SUPPORT_PATTERN = /^worker\/__modern_worker_(?:runtime|shared)_*\.(?:c|m)?js$/u;
|
|
14
|
+
const isEffectBffWorkerArtifact = (logicalPath)=>EFFECT_BFF_WORKER_PATTERN.test(logicalPath) || EFFECT_BFF_WORKER_SUPPORT_PATTERN.test(logicalPath);
|
|
15
|
+
const CRAWLER_POLICY_PATH = 'public/robots.txt';
|
|
16
|
+
const isPublicMetadataPath = (logicalPath)=>'public/_headers' === logicalPath || /^public\/\.well-known\/[^/]+\.json$/u.test(logicalPath);
|
|
17
|
+
const PUBLIC_BUILD_ARTIFACT_PATH = `public/${ULTRAMODERN_BUILD_ARTIFACT_FILE}`;
|
|
13
18
|
const isRecord = (value)=>'object' == typeof value && null !== value && !Array.isArray(value);
|
|
14
19
|
const flattenStrings = (value)=>'string' == typeof value ? [
|
|
15
20
|
value
|
|
@@ -130,7 +135,7 @@ const readBuildArtifact = async (distDirectory, requirePromotable = true)=>{
|
|
|
130
135
|
if (!isUltramodernBuildArtifact(artifact)) throw new Error(`[ultramodern-release-envelope] ${ULTRAMODERN_BUILD_ARTIFACT_FILE} is missing or invalid.`);
|
|
131
136
|
if ('workspace' === artifact.deliveryUnit.sourceRevision) {
|
|
132
137
|
if (!requirePromotable) return;
|
|
133
|
-
throw new Error('[ultramodern-release-envelope] sourceRevision "workspace" cannot produce a promotable
|
|
138
|
+
throw new Error('[ultramodern-release-envelope] sourceRevision "workspace" cannot produce a promotable envelope.');
|
|
134
139
|
}
|
|
135
140
|
return artifact;
|
|
136
141
|
};
|
|
@@ -200,7 +205,7 @@ const releaseArtifact = (logicalPath, runtime)=>({
|
|
|
200
205
|
const writeReleaseIdentityCarrierMetadata = async (artifactRoot, identity, carrierPaths)=>{
|
|
201
206
|
const surfacesByPath = new Map();
|
|
202
207
|
for (const [surface, logicalPaths] of Object.entries(carrierPaths)){
|
|
203
|
-
if (0 === logicalPaths.length) throw new Error(`[ultramodern-release-envelope] ${surface} has no declared release-identity carrier artifact.`);
|
|
208
|
+
if (0 === logicalPaths.length && 'ssr' !== surface && 'uiClient' !== surface) throw new Error(`[ultramodern-release-envelope] ${surface} has no declared release-identity carrier artifact.`);
|
|
204
209
|
for (const logicalPath of logicalPaths){
|
|
205
210
|
const surfaces = surfacesByPath.get(logicalPath) ?? new Set();
|
|
206
211
|
surfaces.add(surface);
|
|
@@ -240,12 +245,12 @@ const writeReleaseIdentityCarrierMetadata = async (artifactRoot, identity, carri
|
|
|
240
245
|
}, null, 2)}\n`);
|
|
241
246
|
return releaseArtifact(MICROVERTICAL_RELEASE_IDENTITY_CARRIERS_PATH, 'release-identity-metadata');
|
|
242
247
|
};
|
|
243
|
-
const createReleaseArtifactInputs = async (distDirectory, identity, target)=>{
|
|
248
|
+
const createReleaseArtifactInputs = async (distDirectory, identity, target, apiOnly)=>{
|
|
244
249
|
const files = await collectFiles(distDirectory);
|
|
245
|
-
if ('node' === target && files.some(
|
|
250
|
+
if ('node' === target && files.some(isEffectBffWorkerArtifact)) throw new Error('[ultramodern-release-envelope] Node target conflicts with a Cloudflare Effect API/BFF worker artifact; resolve the canonical deploy target instead of emitting a Node envelope for Cloudflare output.');
|
|
246
251
|
const uiClientPaths = files.filter((logicalPath)=>{
|
|
247
252
|
const topLevel = logicalPath.split('/')[0];
|
|
248
|
-
return 'static' === topLevel || 'html' === topLevel || 'public' === topLevel || [
|
|
253
|
+
return 'static' === topLevel || 'html' === topLevel || 'public' === topLevel && logicalPath !== CRAWLER_POLICY_PATH && !isPublicMetadataPath(logicalPath) || [
|
|
249
254
|
'index.html',
|
|
250
255
|
'mf-manifest.json',
|
|
251
256
|
'mf-stats.json',
|
|
@@ -254,16 +259,17 @@ const createReleaseArtifactInputs = async (distDirectory, identity, target)=>{
|
|
|
254
259
|
'loadable-stats.json'
|
|
255
260
|
].includes(logicalPath);
|
|
256
261
|
});
|
|
257
|
-
const ssrPaths = 'node' === target ? files.filter((logicalPath)=>logicalPath.startsWith('bundles/') && COMPILED_MODULE_PATTERN.test(logicalPath)) : files.filter((logicalPath)=>logicalPath.startsWith('worker/') && COMPILED_MODULE_PATTERN.test(logicalPath) && !
|
|
262
|
+
const ssrPaths = 'node' === target ? files.filter((logicalPath)=>logicalPath.startsWith('bundles/') && COMPILED_MODULE_PATTERN.test(logicalPath)) : files.filter((logicalPath)=>logicalPath.startsWith('worker/') && COMPILED_MODULE_PATTERN.test(logicalPath) && !isEffectBffWorkerArtifact(logicalPath));
|
|
258
263
|
const nodeApiEntryPaths = files.filter((logicalPath)=>logicalPath.startsWith('api/') && COMPILED_MODULE_PATTERN.test(logicalPath));
|
|
259
|
-
const apiBackendPaths = 'node' === target ? files.filter((logicalPath)=>(logicalPath.startsWith('api/') || logicalPath.startsWith('shared/')) && COMPILED_MODULE_PATTERN.test(logicalPath)) : files.filter(
|
|
260
|
-
if (
|
|
261
|
-
if (0 ===
|
|
262
|
-
if (
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
264
|
+
const apiBackendPaths = 'node' === target ? files.filter((logicalPath)=>(logicalPath.startsWith('api/') || logicalPath.startsWith('shared/')) && COMPILED_MODULE_PATTERN.test(logicalPath)) : files.filter(isEffectBffWorkerArtifact);
|
|
265
|
+
if (apiOnly && (uiClientPaths.length > 0 || ssrPaths.length > 0)) throw new Error('[ultramodern-release-envelope] API-only MicroVertical emitted an undeclared UI/client or SSR surface.');
|
|
266
|
+
if (!apiOnly && 0 === uiClientPaths.length) throw new Error(`[ultramodern-release-envelope] ${target} full-stack MicroVertical has no UI/client artifacts.`);
|
|
267
|
+
if (!apiOnly && 0 === ssrPaths.length) throw new Error(`[ultramodern-release-envelope] ${target} full-stack MicroVertical has no ${'node' === target ? 'Node' : 'workerd'} SSR artifacts.`);
|
|
268
|
+
if ('node' === target && 0 === nodeApiEntryPaths.length || 'cloudflare' === target && !files.some((logicalPath)=>EFFECT_BFF_WORKER_PATTERN.test(logicalPath)) || 0 === apiBackendPaths.length) throw new Error(`[ultramodern-release-envelope] ${target} MicroVertical has no actual ${'node' === target ? 'compiled Node Effect API artifact' : 'Effect API/BFF worker artifact'}.`);
|
|
269
|
+
const clientExecutionPaths = apiOnly ? [] : await manifestReferencedClientModules(distDirectory, files);
|
|
270
|
+
if (!apiOnly && 0 === clientExecutionPaths.length) throw new Error('[ultramodern-release-envelope] UI/client manifest references no compiled execution module.');
|
|
271
|
+
const ssrExecutionPaths = apiOnly ? [] : await routeReferencedSsrModules(distDirectory, files, target);
|
|
272
|
+
if (!apiOnly && 0 === ssrExecutionPaths.length) throw new Error(`[ultramodern-release-envelope] route manifest references no emitted ${'node' === target ? 'Node' : 'Cloudflare'} SSR execution module.`);
|
|
267
273
|
const runtimeByPath = new Map();
|
|
268
274
|
const add = (paths, runtime)=>{
|
|
269
275
|
for (const logicalPath of paths){
|
|
@@ -273,6 +279,8 @@ const createReleaseArtifactInputs = async (distDirectory, identity, target)=>{
|
|
|
273
279
|
}
|
|
274
280
|
};
|
|
275
281
|
add(uiClientPaths, 'browser');
|
|
282
|
+
add(files.filter((logicalPath)=>logicalPath === CRAWLER_POLICY_PATH), 'crawler-policy');
|
|
283
|
+
add(files.filter(isPublicMetadataPath), 'public-metadata');
|
|
276
284
|
add(ssrPaths, 'node' === target ? 'nodejs' : 'workerd');
|
|
277
285
|
add(apiBackendPaths, 'node' === target ? 'nodejs' : 'workerd-effect');
|
|
278
286
|
add([
|
|
@@ -330,15 +338,14 @@ const pathExists = async (filePath)=>{
|
|
|
330
338
|
}
|
|
331
339
|
};
|
|
332
340
|
const emitFrameworkMicroVerticalReleaseEnvelope = async ({ apiOnly, distDirectory, requirePromotable = true, target })=>{
|
|
333
|
-
if (apiOnly) return;
|
|
334
341
|
const backendManifestPath = node_path.join(distDirectory, BACKEND_FEDERATION_MANIFEST_FILE);
|
|
335
342
|
const backendContainerPath = node_path.join(distDirectory, BACKEND_FEDERATION_REMOTE_ENTRY_FILE);
|
|
336
343
|
const [hasBackendManifest, hasBackendContainer] = await Promise.all([
|
|
337
344
|
pathExists(backendManifestPath),
|
|
338
345
|
pathExists(backendContainerPath)
|
|
339
346
|
]);
|
|
340
|
-
if (!hasBackendManifest && !hasBackendContainer) return;
|
|
341
|
-
if (!hasBackendManifest || !hasBackendContainer) throw new Error('[ultramodern-release-envelope]
|
|
347
|
+
if (!hasBackendManifest && !hasBackendContainer && !apiOnly) return;
|
|
348
|
+
if (!hasBackendManifest || !hasBackendContainer) throw new Error('[ultramodern-release-envelope] MicroVertical backend federation manifest and container must be emitted together.');
|
|
342
349
|
const buildArtifact = await readBuildArtifact(distDirectory, requirePromotable);
|
|
343
350
|
if (!buildArtifact) return;
|
|
344
351
|
const identity = {
|
|
@@ -348,7 +355,7 @@ const emitFrameworkMicroVerticalReleaseEnvelope = async ({ apiOnly, distDirector
|
|
|
348
355
|
releaseVersion: buildArtifact.deliveryUnit.version
|
|
349
356
|
};
|
|
350
357
|
await readBackendManifest(distDirectory, identity);
|
|
351
|
-
const { artifacts, surfaces } = await createReleaseArtifactInputs(distDirectory, identity, target);
|
|
358
|
+
const { artifacts, surfaces } = await createReleaseArtifactInputs(distDirectory, identity, target, apiOnly);
|
|
352
359
|
const envelope = await createMicroVerticalReleaseEnvelope({
|
|
353
360
|
artifactRoot: distDirectory,
|
|
354
361
|
target,
|
|
@@ -379,19 +386,16 @@ const readFrameworkMicroVerticalReleaseEnvelope = async ({ artifactRoot, expecte
|
|
|
379
386
|
});
|
|
380
387
|
};
|
|
381
388
|
const verifyBuildOutputReleaseEnvelope = async (distDirectory, expectedTarget)=>{
|
|
382
|
-
const [hasEnvelope, hasBuildArtifact
|
|
389
|
+
const [hasEnvelope, hasBuildArtifact] = await Promise.all([
|
|
383
390
|
pathExists(node_path.join(distDirectory, MICROVERTICAL_RELEASE_ENVELOPE_PATH)),
|
|
384
|
-
pathExists(node_path.join(distDirectory, ULTRAMODERN_BUILD_ARTIFACT_FILE))
|
|
385
|
-
pathExists(node_path.join(distDirectory, BACKEND_FEDERATION_MANIFEST_FILE)),
|
|
386
|
-
pathExists(node_path.join(distDirectory, BACKEND_FEDERATION_REMOTE_ENTRY_FILE))
|
|
391
|
+
pathExists(node_path.join(distDirectory, ULTRAMODERN_BUILD_ARTIFACT_FILE))
|
|
387
392
|
]);
|
|
388
|
-
const isFullStackMicroVertical = hasBuildArtifact && (hasBackendManifest || hasBackendEntry);
|
|
389
393
|
return readFrameworkMicroVerticalReleaseEnvelope({
|
|
390
394
|
artifactRoot: distDirectory,
|
|
391
395
|
...expectedTarget ? {
|
|
392
396
|
expectedTarget
|
|
393
397
|
} : {},
|
|
394
|
-
required: hasEnvelope ||
|
|
398
|
+
required: hasEnvelope || hasBuildArtifact
|
|
395
399
|
});
|
|
396
400
|
};
|
|
397
401
|
const verifyNodeReleaseEnvelopeStaging = async ({ outputDirectory })=>readFrameworkMicroVerticalReleaseEnvelope({
|
|
@@ -399,7 +403,7 @@ const verifyNodeReleaseEnvelopeStaging = async ({ outputDirectory })=>readFramew
|
|
|
399
403
|
expectedTarget: 'node',
|
|
400
404
|
required: true
|
|
401
405
|
});
|
|
402
|
-
const createNodeStagedReleaseArtifactInputs = async (outputDirectory, identity)=>{
|
|
406
|
+
const createNodeStagedReleaseArtifactInputs = async (outputDirectory, identity, apiOnly)=>{
|
|
403
407
|
const files = await collectFiles(outputDirectory);
|
|
404
408
|
for (const requiredPath of [
|
|
405
409
|
'index.js',
|
|
@@ -413,7 +417,7 @@ const createNodeStagedReleaseArtifactInputs = async (outputDirectory, identity)=
|
|
|
413
417
|
]);
|
|
414
418
|
const uiClientPaths = files.filter((logicalPath)=>{
|
|
415
419
|
const topLevel = logicalPath.split('/')[0];
|
|
416
|
-
return 'static' === topLevel || 'html' === topLevel || 'public' === topLevel || [
|
|
420
|
+
return 'static' === topLevel || 'html' === topLevel || 'public' === topLevel && logicalPath !== CRAWLER_POLICY_PATH && !isPublicMetadataPath(logicalPath) || [
|
|
417
421
|
'index.html',
|
|
418
422
|
'mf-manifest.json',
|
|
419
423
|
'mf-stats.json',
|
|
@@ -424,6 +428,7 @@ const createNodeStagedReleaseArtifactInputs = async (outputDirectory, identity)=
|
|
|
424
428
|
});
|
|
425
429
|
const ssrPaths = files.filter((logicalPath)=>'index.js' === logicalPath || logicalPath.startsWith('bundles/') && COMPILED_MODULE_PATTERN.test(logicalPath));
|
|
426
430
|
const apiBackendPaths = files.filter((logicalPath)=>(logicalPath.startsWith('api/') || logicalPath.startsWith('shared/')) && COMPILED_MODULE_PATTERN.test(logicalPath));
|
|
431
|
+
if (apiOnly && (uiClientPaths.length > 0 || ssrPaths.some((path)=>'index.js' !== path))) throw new Error('[ultramodern-release-envelope] final API-only Node staging contains an undeclared UI/client or SSR surface.');
|
|
427
432
|
for (const [surface, paths] of [
|
|
428
433
|
[
|
|
429
434
|
'UI/client',
|
|
@@ -431,22 +436,24 @@ const createNodeStagedReleaseArtifactInputs = async (outputDirectory, identity)=
|
|
|
431
436
|
],
|
|
432
437
|
[
|
|
433
438
|
'Node SSR',
|
|
434
|
-
ssrPaths
|
|
439
|
+
apiOnly ? [] : ssrPaths
|
|
435
440
|
],
|
|
436
441
|
[
|
|
437
442
|
'Node API/backend',
|
|
438
443
|
apiBackendPaths
|
|
439
444
|
]
|
|
440
|
-
])if (0 === paths.length) throw new Error(`[ultramodern-release-envelope] final Node staging has no ${surface} artifacts.`);
|
|
441
|
-
const clientExecutionPaths = await manifestReferencedClientModules(outputDirectory, files);
|
|
442
|
-
const ssrExecutionPaths = await routeReferencedSsrModules(outputDirectory, files, 'node');
|
|
443
|
-
if (0 === clientExecutionPaths.length || 0 === ssrExecutionPaths.length) throw new Error('[ultramodern-release-envelope] final Node manifests must reference emitted UI/client and SSR execution modules.');
|
|
445
|
+
])if (0 === paths.length && (!apiOnly || 'Node API/backend' === surface)) throw new Error(`[ultramodern-release-envelope] final Node staging has no ${surface} artifacts.`);
|
|
446
|
+
const clientExecutionPaths = apiOnly ? [] : await manifestReferencedClientModules(outputDirectory, files);
|
|
447
|
+
const ssrExecutionPaths = apiOnly ? [] : await routeReferencedSsrModules(outputDirectory, files, 'node');
|
|
448
|
+
if (!apiOnly && (0 === clientExecutionPaths.length || 0 === ssrExecutionPaths.length)) throw new Error('[ultramodern-release-envelope] final Node manifests must reference emitted UI/client and SSR execution modules.');
|
|
444
449
|
const runtimeByPath = new Map(files.filter((logicalPath)=>!backendFederationPaths.has(logicalPath)).map((logicalPath)=>[
|
|
445
450
|
logicalPath,
|
|
446
451
|
'nodejs-deployment'
|
|
447
452
|
]));
|
|
448
453
|
for (const logicalPath of uiClientPaths)runtimeByPath.set(logicalPath, 'browser');
|
|
449
|
-
|
|
454
|
+
if (files.includes(CRAWLER_POLICY_PATH)) runtimeByPath.set(CRAWLER_POLICY_PATH, 'crawler-policy');
|
|
455
|
+
for (const logicalPath of files.filter(isPublicMetadataPath))runtimeByPath.set(logicalPath, 'public-metadata');
|
|
456
|
+
for (const logicalPath of apiOnly ? [] : ssrPaths)runtimeByPath.set(logicalPath, 'nodejs');
|
|
450
457
|
for (const logicalPath of apiBackendPaths)runtimeByPath.set(logicalPath, 'nodejs');
|
|
451
458
|
runtimeByPath.set(BACKEND_FEDERATION_MANIFEST_FILE, 'module-federation-manifest');
|
|
452
459
|
runtimeByPath.set(BACKEND_FEDERATION_REMOTE_ENTRY_FILE, 'nodejs');
|
|
@@ -456,7 +463,7 @@ const createNodeStagedReleaseArtifactInputs = async (outputDirectory, identity)=
|
|
|
456
463
|
BACKEND_FEDERATION_MANIFEST_FILE,
|
|
457
464
|
BACKEND_FEDERATION_REMOTE_ENTRY_FILE
|
|
458
465
|
],
|
|
459
|
-
ssr: [
|
|
466
|
+
ssr: apiOnly ? [] : [
|
|
460
467
|
...new Set([
|
|
461
468
|
...ssrExecutionPaths,
|
|
462
469
|
...ssrPaths.filter((logicalPath)=>'index.js' !== logicalPath)
|
|
@@ -475,7 +482,7 @@ const createNodeStagedReleaseArtifactInputs = async (outputDirectory, identity)=
|
|
|
475
482
|
uiClient: [
|
|
476
483
|
...uiClientPaths
|
|
477
484
|
].sort((left, right)=>left.localeCompare(right)),
|
|
478
|
-
ssr: [
|
|
485
|
+
ssr: apiOnly ? [] : [
|
|
479
486
|
...ssrPaths
|
|
480
487
|
].sort((left, right)=>left.localeCompare(right)),
|
|
481
488
|
apiBackend: [
|
|
@@ -491,7 +498,7 @@ const createNodeStagedReleaseArtifactInputs = async (outputDirectory, identity)=
|
|
|
491
498
|
const emitNodeStagedReleaseEnvelope = async ({ distDirectory, outputDirectory })=>{
|
|
492
499
|
const source = await verifyBuildOutputReleaseEnvelope(distDirectory, 'node');
|
|
493
500
|
if (!source) return;
|
|
494
|
-
const { artifacts, surfaces } = await createNodeStagedReleaseArtifactInputs(outputDirectory, source.identity);
|
|
501
|
+
const { artifacts, surfaces } = await createNodeStagedReleaseArtifactInputs(outputDirectory, source.identity, 0 === source.surfaces.uiClient.length);
|
|
495
502
|
const staged = await createMicroVerticalReleaseEnvelope({
|
|
496
503
|
artifactRoot: outputDirectory,
|
|
497
504
|
target: 'node',
|
|
@@ -509,21 +516,25 @@ const stageCloudflareReleaseEnvelope = async ({ distDirectory, outputDirectory }
|
|
|
509
516
|
if (await pathExists(stagedEnvelopePath)) throw new Error('[ultramodern-release-envelope] Cloudflare staging contains a stale envelope before final output generation.');
|
|
510
517
|
return source;
|
|
511
518
|
};
|
|
512
|
-
const createCloudflareStagedReleaseArtifactInputs = async (outputDirectory, identity)=>{
|
|
519
|
+
const createCloudflareStagedReleaseArtifactInputs = async (outputDirectory, identity, apiOnly)=>{
|
|
513
520
|
const files = await collectFiles(outputDirectory);
|
|
514
521
|
for (const requiredPath of [
|
|
515
522
|
'server/index.mjs',
|
|
516
523
|
'server/modern-worker-manifest.json',
|
|
517
524
|
'wrangler.json',
|
|
518
525
|
'package.json',
|
|
519
|
-
|
|
526
|
+
...apiOnly ? [] : [
|
|
527
|
+
'worker/package.json'
|
|
528
|
+
]
|
|
520
529
|
])if (!files.includes(requiredPath)) throw new Error(`[ultramodern-release-envelope] final Cloudflare staging is missing ${requiredPath}.`);
|
|
521
530
|
if (files.some((logicalPath)=>'public/release' === logicalPath || logicalPath.startsWith('public/release/'))) throw new Error('[ultramodern-release-envelope] final Cloudflare envelope must remain private and cannot be staged under public/release.');
|
|
522
531
|
const backendManifestPath = `public/${BACKEND_FEDERATION_MANIFEST_FILE}`;
|
|
523
532
|
const backendContainerPath = `public/${BACKEND_FEDERATION_REMOTE_ENTRY_FILE}`;
|
|
524
|
-
const apiBackendPaths = files.filter(
|
|
525
|
-
|
|
526
|
-
const
|
|
533
|
+
const apiBackendPaths = files.filter(isEffectBffWorkerArtifact);
|
|
534
|
+
if (!files.some((logicalPath)=>EFFECT_BFF_WORKER_PATTERN.test(logicalPath))) throw new Error('[ultramodern-release-envelope] final Cloudflare staging has no actual Effect API/BFF worker artifact.');
|
|
535
|
+
const ssrPaths = files.filter((logicalPath)=>(logicalPath.startsWith('server/') || logicalPath.startsWith('worker/')) && COMPILED_MODULE_PATTERN.test(logicalPath) && !isEffectBffWorkerArtifact(logicalPath));
|
|
536
|
+
const uiClientPaths = files.filter((logicalPath)=>logicalPath.startsWith('public/') && logicalPath !== CRAWLER_POLICY_PATH && !isPublicMetadataPath(logicalPath) && logicalPath !== PUBLIC_BUILD_ARTIFACT_PATH && logicalPath !== backendManifestPath && logicalPath !== backendContainerPath);
|
|
537
|
+
if (apiOnly && (uiClientPaths.length > 0 || ssrPaths.some((path)=>'server/index.mjs' !== path))) throw new Error('[ultramodern-release-envelope] final API-only Cloudflare staging contains an undeclared UI/client or SSR surface.');
|
|
527
538
|
for (const [surface, paths] of [
|
|
528
539
|
[
|
|
529
540
|
'UI/client',
|
|
@@ -531,27 +542,29 @@ const createCloudflareStagedReleaseArtifactInputs = async (outputDirectory, iden
|
|
|
531
542
|
],
|
|
532
543
|
[
|
|
533
544
|
'Cloudflare SSR',
|
|
534
|
-
ssrPaths
|
|
545
|
+
apiOnly ? [] : ssrPaths
|
|
535
546
|
],
|
|
536
547
|
[
|
|
537
548
|
'Cloudflare API/backend',
|
|
538
549
|
apiBackendPaths
|
|
539
550
|
]
|
|
540
|
-
])if (0 === paths.length) throw new Error(`[ultramodern-release-envelope] final Cloudflare staging has no ${surface} artifacts.`);
|
|
551
|
+
])if (0 === paths.length && (!apiOnly || 'Cloudflare API/backend' === surface)) throw new Error(`[ultramodern-release-envelope] final Cloudflare staging has no ${surface} artifacts.`);
|
|
541
552
|
for (const logicalPath of [
|
|
542
553
|
backendManifestPath,
|
|
543
554
|
backendContainerPath
|
|
544
555
|
])if (!files.includes(logicalPath)) throw new Error(`[ultramodern-release-envelope] final Cloudflare staging is missing ${logicalPath}.`);
|
|
545
|
-
const clientExecutionPaths = await manifestReferencedClientModules(outputDirectory, files, 'public/mf-manifest.json');
|
|
546
|
-
const ssrExecutionPaths = await routeReferencedSsrModules(outputDirectory, files, 'cloudflare', 'server/route.json');
|
|
547
|
-
if (0 === clientExecutionPaths.length || 0 === ssrExecutionPaths.length) throw new Error('[ultramodern-release-envelope] final Cloudflare manifests must reference emitted UI/client and SSR execution modules.');
|
|
556
|
+
const clientExecutionPaths = apiOnly ? [] : await manifestReferencedClientModules(outputDirectory, files, 'public/mf-manifest.json');
|
|
557
|
+
const ssrExecutionPaths = apiOnly ? [] : await routeReferencedSsrModules(outputDirectory, files, 'cloudflare', 'server/route.json');
|
|
558
|
+
if (!apiOnly && (0 === clientExecutionPaths.length || 0 === ssrExecutionPaths.length)) throw new Error('[ultramodern-release-envelope] final Cloudflare manifests must reference emitted UI/client and SSR execution modules.');
|
|
548
559
|
const runtimeByPath = new Map();
|
|
549
560
|
for (const logicalPath of files)runtimeByPath.set(logicalPath, 'cloudflare-deployment');
|
|
550
561
|
const add = (paths, runtime)=>{
|
|
551
562
|
for (const logicalPath of paths)runtimeByPath.set(logicalPath, runtime);
|
|
552
563
|
};
|
|
553
564
|
add(uiClientPaths, 'browser');
|
|
554
|
-
|
|
565
|
+
if (files.includes(CRAWLER_POLICY_PATH)) runtimeByPath.set(CRAWLER_POLICY_PATH, 'crawler-policy');
|
|
566
|
+
add(files.filter(isPublicMetadataPath), 'public-metadata');
|
|
567
|
+
add(apiOnly ? [] : ssrPaths, 'workerd');
|
|
555
568
|
add(apiBackendPaths, 'workerd-effect');
|
|
556
569
|
add([
|
|
557
570
|
backendManifestPath
|
|
@@ -565,7 +578,7 @@ const createCloudflareStagedReleaseArtifactInputs = async (outputDirectory, iden
|
|
|
565
578
|
backendManifestPath,
|
|
566
579
|
backendContainerPath
|
|
567
580
|
],
|
|
568
|
-
ssr: [
|
|
581
|
+
ssr: apiOnly ? [] : [
|
|
569
582
|
...new Set([
|
|
570
583
|
...ssrExecutionPaths,
|
|
571
584
|
...ssrPaths.filter((logicalPath)=>logicalPath.startsWith('worker/'))
|
|
@@ -584,7 +597,7 @@ const createCloudflareStagedReleaseArtifactInputs = async (outputDirectory, iden
|
|
|
584
597
|
uiClient: [
|
|
585
598
|
...uiClientPaths
|
|
586
599
|
].sort((left, right)=>left.localeCompare(right)),
|
|
587
|
-
ssr: [
|
|
600
|
+
ssr: apiOnly ? [] : [
|
|
588
601
|
...ssrPaths
|
|
589
602
|
].sort((left, right)=>left.localeCompare(right)),
|
|
590
603
|
apiBackend: [
|
|
@@ -600,7 +613,7 @@ const createCloudflareStagedReleaseArtifactInputs = async (outputDirectory, iden
|
|
|
600
613
|
const emitCloudflareStagedReleaseEnvelope = async ({ distDirectory, outputDirectory })=>{
|
|
601
614
|
const source = await verifyBuildOutputReleaseEnvelope(distDirectory, 'cloudflare');
|
|
602
615
|
if (!source) return;
|
|
603
|
-
const { artifacts, surfaces } = await createCloudflareStagedReleaseArtifactInputs(outputDirectory, source.identity);
|
|
616
|
+
const { artifacts, surfaces } = await createCloudflareStagedReleaseArtifactInputs(outputDirectory, source.identity, 0 === source.surfaces.uiClient.length);
|
|
604
617
|
const staged = await createMicroVerticalReleaseEnvelope({
|
|
605
618
|
artifactRoot: outputDirectory,
|
|
606
619
|
target: 'cloudflare',
|
|
@@ -185,7 +185,7 @@ const assertUniqueSortedArtifacts = (artifacts, location)=>{
|
|
|
185
185
|
if (paths.some((logicalPath, index)=>logicalPath !== sorted[index])) throw new Error(`${location} must be sorted by logicalPath.`);
|
|
186
186
|
};
|
|
187
187
|
const assertSurfacePaths = (value, location)=>{
|
|
188
|
-
if (!Array.isArray(value)
|
|
188
|
+
if (!Array.isArray(value)) throw new Error(`${location} must be an array of artifact paths.`);
|
|
189
189
|
const paths = value.map((item, index)=>assertNormalizedLogicalPath(item, `${location}[${index}]`));
|
|
190
190
|
const sorted = [
|
|
191
191
|
...paths
|
|
@@ -207,10 +207,16 @@ const assertSurfaces = (value)=>{
|
|
|
207
207
|
'manifest',
|
|
208
208
|
'container'
|
|
209
209
|
], 'surfaces.backendFederation');
|
|
210
|
+
const uiClient = assertSurfacePaths(surfaces.uiClient, 'surfaces.uiClient');
|
|
211
|
+
const ssr = assertSurfacePaths(surfaces.ssr, 'surfaces.ssr');
|
|
212
|
+
const apiBackend = assertSurfacePaths(surfaces.apiBackend, 'surfaces.apiBackend');
|
|
213
|
+
if (uiClient.length > 0 && 0 === ssr.length) throw new Error('surfaces.ssr must contain at least one artifact path when UI/client is declared.');
|
|
214
|
+
if (ssr.length > 0 && 0 === uiClient.length) throw new Error('surfaces.uiClient must contain at least one artifact path when SSR is declared.');
|
|
215
|
+
if (0 === apiBackend.length) throw new Error('surfaces.apiBackend must contain at least one artifact path.');
|
|
210
216
|
return {
|
|
211
|
-
uiClient
|
|
212
|
-
ssr
|
|
213
|
-
apiBackend
|
|
217
|
+
uiClient,
|
|
218
|
+
ssr,
|
|
219
|
+
apiBackend,
|
|
214
220
|
backendFederation: {
|
|
215
221
|
manifest: assertNormalizedLogicalPath(backendFederation.manifest, 'surfaces.backendFederation.manifest'),
|
|
216
222
|
container: assertNormalizedLogicalPath(backendFederation.container, 'surfaces.backendFederation.container')
|
|
@@ -53,6 +53,36 @@ export declare const createBackendManifest: (workspaceRoot: string, distDirector
|
|
|
53
53
|
}[];
|
|
54
54
|
shared: never[];
|
|
55
55
|
backendFederation: {
|
|
56
|
+
role: string;
|
|
57
|
+
appId: string;
|
|
58
|
+
name: string;
|
|
59
|
+
runtimeFramework: string;
|
|
60
|
+
strictEffectApproach: boolean;
|
|
61
|
+
contractVersion: string;
|
|
62
|
+
nodeAdapterVersion: string;
|
|
63
|
+
remoteType: string;
|
|
64
|
+
expose: string;
|
|
65
|
+
manifestUrl: string;
|
|
66
|
+
containerEntry: string;
|
|
67
|
+
source: {
|
|
68
|
+
module: string;
|
|
69
|
+
};
|
|
70
|
+
rpcPath: string | undefined;
|
|
71
|
+
rpcSerialization: string;
|
|
72
|
+
deliveryUnit?: import("@modern-js/backend-federation-contracts").DeliveryUnitContractBlock | undefined;
|
|
73
|
+
versionBoundary: {
|
|
74
|
+
invariant: string;
|
|
75
|
+
packageName: string | undefined;
|
|
76
|
+
version: string | undefined;
|
|
77
|
+
buildVersion: string | undefined;
|
|
78
|
+
uiManifestUrl?: string | undefined;
|
|
79
|
+
deliveryUnit?: {
|
|
80
|
+
unitId: string;
|
|
81
|
+
buildMarker: string;
|
|
82
|
+
sourceRevision: string;
|
|
83
|
+
} | undefined;
|
|
84
|
+
};
|
|
85
|
+
} | {
|
|
56
86
|
role: string;
|
|
57
87
|
appId: string;
|
|
58
88
|
name: string;
|
|
@@ -1,13 +1,23 @@
|
|
|
1
1
|
import { type DeliveryUnitContractBlock, type UltramodernBuildArtifact } from '@modern-js/backend-federation-contracts';
|
|
2
|
-
export declare const
|
|
3
|
-
export
|
|
2
|
+
export declare const REFERENCE_TOPOLOGY_PATH = "topology/reference-topology.json";
|
|
3
|
+
export declare const DEVELOPMENT_OVERLAY_PATH = "topology/local-overlays/development.json";
|
|
4
|
+
export type TopologyApp = {
|
|
4
5
|
id?: unknown;
|
|
6
|
+
domain?: unknown;
|
|
5
7
|
kind?: unknown;
|
|
6
8
|
path?: unknown;
|
|
7
9
|
package?: unknown;
|
|
8
|
-
|
|
10
|
+
portEnv?: unknown;
|
|
11
|
+
cloudflare?: {
|
|
12
|
+
publicUrlEnv?: unknown;
|
|
13
|
+
};
|
|
9
14
|
api?: {
|
|
10
|
-
|
|
15
|
+
bff?: {
|
|
16
|
+
prefix?: unknown;
|
|
17
|
+
};
|
|
18
|
+
protocol?: unknown;
|
|
19
|
+
rpcPath?: unknown;
|
|
20
|
+
rpcSerialization?: unknown;
|
|
11
21
|
stem?: unknown;
|
|
12
22
|
};
|
|
13
23
|
moduleFederation?: {
|
|
@@ -37,19 +47,23 @@ export type CompactApp = {
|
|
|
37
47
|
packageName?: unknown;
|
|
38
48
|
version?: unknown;
|
|
39
49
|
};
|
|
40
|
-
|
|
50
|
+
};
|
|
51
|
+
export type DevelopmentOverlay = {
|
|
52
|
+
ports?: Record<string, unknown>;
|
|
53
|
+
manifests?: Record<string, unknown>;
|
|
54
|
+
serverExecution?: Record<string, {
|
|
41
55
|
node?: {
|
|
42
56
|
remoteName?: unknown;
|
|
43
57
|
manifestUrl?: unknown;
|
|
44
58
|
containerEntry?: unknown;
|
|
45
59
|
remoteType?: unknown;
|
|
46
60
|
};
|
|
47
|
-
}
|
|
61
|
+
}>;
|
|
48
62
|
};
|
|
49
|
-
export type
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
63
|
+
export type ReferenceTopology = {
|
|
64
|
+
shell?: TopologyApp;
|
|
65
|
+
shells?: TopologyApp[];
|
|
66
|
+
verticals?: TopologyApp[];
|
|
53
67
|
};
|
|
54
68
|
export type BackendFederationApp = {
|
|
55
69
|
id: string;
|
|
@@ -62,13 +76,15 @@ export type BackendFederationApp = {
|
|
|
62
76
|
deliveryUnit?: DeliveryUnitContractBlock;
|
|
63
77
|
port: number;
|
|
64
78
|
apiPrefix: string;
|
|
79
|
+
apiProtocol: 'rest' | 'rpc';
|
|
80
|
+
rpcPath?: string;
|
|
65
81
|
apiStem: string;
|
|
66
82
|
backendName: string;
|
|
67
83
|
manifestUrl: string;
|
|
68
84
|
containerEntry: string;
|
|
69
85
|
remoteType: string;
|
|
70
86
|
uiManifestUrl?: string;
|
|
71
|
-
|
|
87
|
+
topologyDeliveryUnit?: {
|
|
72
88
|
unitId?: string;
|
|
73
89
|
buildMarker?: string;
|
|
74
90
|
sourceRevision?: string;
|
|
@@ -98,5 +114,8 @@ export declare const createStampedDeliveryUnit: (input: {
|
|
|
98
114
|
version?: string;
|
|
99
115
|
sourceRevision: string;
|
|
100
116
|
}) => DeliveryUnitContractBlock | undefined;
|
|
101
|
-
export declare const
|
|
102
|
-
|
|
117
|
+
export declare const createAppFromTopology: (workspaceRoot: string, appDirectory: string, topologyApp: TopologyApp, overlay: DevelopmentOverlay, packageManifest: {
|
|
118
|
+
name?: unknown;
|
|
119
|
+
version?: unknown;
|
|
120
|
+
}) => BackendFederationApp | undefined;
|
|
121
|
+
export declare const findBackendFederationApp: (workspaceRoot: string, appDirectory: string) => Promise<BackendFederationApp>;
|
|
@@ -11,7 +11,7 @@ export type DeliveryUnitStamp = DeliveryUnitIdentity & {
|
|
|
11
11
|
};
|
|
12
12
|
/**
|
|
13
13
|
* Resolve the delivery-unit record declared for this app by the workspace
|
|
14
|
-
*
|
|
14
|
+
* reference topology. This is the topology source
|
|
15
15
|
* of truth the Cloudflare worker snapshot is verified against.
|
|
16
16
|
*/
|
|
17
17
|
export declare const resolveTopologyDeliveryUnit: (appDirectory: string) => Promise<DeliveryUnitStamp | undefined>;
|
|
@@ -10,6 +10,6 @@ export declare const CLOUDFLARE_RUNTIME_TYPE = "cloudflare-module-worker";
|
|
|
10
10
|
export declare const CLOUDFLARE_OUTPUT_PACKAGE_TYPE = "module";
|
|
11
11
|
export declare const CLOUDFLARE_WORKER_PACKAGE_TYPE = "commonjs";
|
|
12
12
|
export declare const CLOUDFLARE_WORKER_BUNDLE_FORMAT = "commonjs";
|
|
13
|
-
export declare const CLOUDFLARE_WORKER_NODE_BUILTINS: readonly ['assert', 'assert/strict', 'async_hooks', 'buffer', 'child_process', 'crypto', 'dgram', 'dns', 'domain', 'events', 'fs', 'fs/promises', 'http', 'http2', 'inspector', 'module', 'net', 'os', 'path', 'process', 'readline', 'readline/promises', 'repl', 'sqlite', 'stream', 'stream/consumers', 'stream/promises', 'stream/web', 'string_decoder', 'timers', 'timers/promises', 'tls', 'trace_events', 'tty', 'url', 'util', 'util/types', 'v8', 'vm', 'wasi', 'worker_threads', 'zlib'];
|
|
13
|
+
export declare const CLOUDFLARE_WORKER_NODE_BUILTINS: readonly ['assert', 'assert/strict', 'async_hooks', 'buffer', 'child_process', 'crypto', 'dgram', 'dns', 'domain', 'events', 'fs', 'fs/promises', 'http', 'http2', 'https', 'inspector', 'module', 'net', 'os', 'path', 'process', 'readline', 'readline/promises', 'repl', 'sqlite', 'stream', 'stream/consumers', 'stream/promises', 'stream/web', 'string_decoder', 'timers', 'timers/promises', 'tls', 'trace_events', 'tty', 'url', 'util', 'util/types', 'v8', 'vm', 'wasi', 'worker_threads', 'zlib'];
|
|
14
14
|
export declare const CLOUDFLARE_WORKER_PLATFORM_MODULES: readonly ['cloudflare:sockets'];
|
|
15
15
|
export declare const CLOUDFLARE_REQUIRED_COMPATIBILITY_FLAGS: readonly ['nodejs_compat', 'global_fetch_strictly_public'];
|
package/package.json
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"directory": "packages/solutions/app-tools-extensions"
|
|
12
12
|
},
|
|
13
13
|
"license": "MIT",
|
|
14
|
-
"version": "3.9.0-ultramodern.
|
|
14
|
+
"version": "3.9.0-ultramodern.13",
|
|
15
15
|
"files": [
|
|
16
16
|
"dist",
|
|
17
17
|
"src"
|
|
@@ -142,38 +142,38 @@
|
|
|
142
142
|
"node": ">=26.7.0"
|
|
143
143
|
},
|
|
144
144
|
"dependencies": {
|
|
145
|
-
"@babel/parser": "^8.0.
|
|
146
|
-
"@babel/traverse": "^8.0.
|
|
145
|
+
"@babel/parser": "^8.0.6",
|
|
146
|
+
"@babel/traverse": "^8.0.6",
|
|
147
147
|
"@loadable/component": "5.16.7",
|
|
148
|
-
"@modern-js/backend-federation-contracts": "npm:@bleedingdev/modern-js-backend-federation-contracts@3.9.0-ultramodern.
|
|
149
|
-
"@modern-js/builder": "npm:@bleedingdev/modern-js-builder@3.9.0-ultramodern.
|
|
150
|
-
"@modern-js/prod-server": "npm:@bleedingdev/modern-js-prod-server@3.9.0-ultramodern.
|
|
151
|
-
"@modern-js/runtime-renderer-extensions": "npm:@bleedingdev/modern-js-runtime-renderer-extensions@3.9.0-ultramodern.
|
|
152
|
-
"@modern-js/server-core": "npm:@bleedingdev/modern-js-server-core@3.9.0-ultramodern.
|
|
153
|
-
"@modern-js/server-runtime-extensions": "npm:@bleedingdev/modern-js-server-runtime-extensions@3.9.0-ultramodern.
|
|
154
|
-
"@modern-js/surface-resolution": "npm:@bleedingdev/modern-js-surface-resolution@3.9.0-ultramodern.
|
|
155
|
-
"@modern-js/types": "npm:@bleedingdev/modern-js-types@3.9.0-ultramodern.
|
|
156
|
-
"@modern-js/utils": "npm:@bleedingdev/modern-js-utils@3.9.0-ultramodern.
|
|
148
|
+
"@modern-js/backend-federation-contracts": "npm:@bleedingdev/modern-js-backend-federation-contracts@3.9.0-ultramodern.13",
|
|
149
|
+
"@modern-js/builder": "npm:@bleedingdev/modern-js-builder@3.9.0-ultramodern.13",
|
|
150
|
+
"@modern-js/prod-server": "npm:@bleedingdev/modern-js-prod-server@3.9.0-ultramodern.13",
|
|
151
|
+
"@modern-js/runtime-renderer-extensions": "npm:@bleedingdev/modern-js-runtime-renderer-extensions@3.9.0-ultramodern.13",
|
|
152
|
+
"@modern-js/server-core": "npm:@bleedingdev/modern-js-server-core@3.9.0-ultramodern.13",
|
|
153
|
+
"@modern-js/server-runtime-extensions": "npm:@bleedingdev/modern-js-server-runtime-extensions@3.9.0-ultramodern.13",
|
|
154
|
+
"@modern-js/surface-resolution": "npm:@bleedingdev/modern-js-surface-resolution@3.9.0-ultramodern.13",
|
|
155
|
+
"@modern-js/types": "npm:@bleedingdev/modern-js-types@3.9.0-ultramodern.13",
|
|
156
|
+
"@modern-js/utils": "npm:@bleedingdev/modern-js-utils@3.9.0-ultramodern.13",
|
|
157
157
|
"@swc/helpers": "^0.5.23",
|
|
158
158
|
"compression-webpack-plugin": "^12.0.0",
|
|
159
159
|
"esbuild": "^0.28.2",
|
|
160
160
|
"std-env": "4.2.0"
|
|
161
161
|
},
|
|
162
162
|
"peerDependencies": {
|
|
163
|
-
"@rsbuild/core": "2.2.
|
|
163
|
+
"@rsbuild/core": "2.2.9"
|
|
164
164
|
},
|
|
165
165
|
"devDependencies": {
|
|
166
|
-
"@modern-js/plugin": "npm:@bleedingdev/modern-js-plugin@3.9.0-ultramodern.
|
|
167
|
-
"@modern-js/plugin-bff-extensions": "npm:@bleedingdev/modern-js-plugin-bff-extensions@3.9.0-ultramodern.
|
|
168
|
-
"@module-federation/runtime-tools": "2.9.
|
|
169
|
-
"@rsbuild/core": "2.2.
|
|
170
|
-
"@rslib/core": "1.0.
|
|
166
|
+
"@modern-js/plugin": "npm:@bleedingdev/modern-js-plugin@3.9.0-ultramodern.13",
|
|
167
|
+
"@modern-js/plugin-bff-extensions": "npm:@bleedingdev/modern-js-plugin-bff-extensions@3.9.0-ultramodern.13",
|
|
168
|
+
"@module-federation/runtime-tools": "npm:@bleedingdev/mf-runtime-tools@2.9.1",
|
|
169
|
+
"@rsbuild/core": "2.2.9",
|
|
170
|
+
"@rslib/core": "1.0.2",
|
|
171
171
|
"@scripts/rstest-config": "2.66.0",
|
|
172
172
|
"@types/babel__traverse": "7.28.0",
|
|
173
|
-
"@types/node": "^26.
|
|
173
|
+
"@types/node": "^26.6.2",
|
|
174
174
|
"@typescript/native-preview": "7.0.0-dev.20260707.2",
|
|
175
175
|
"core-js": "^3.50.0",
|
|
176
|
-
"effect": "4.0.0-rc.
|
|
176
|
+
"effect": "npm:@bleedingdev/effect@4.0.0-rc.117",
|
|
177
177
|
"ndepe": "^0.1.13"
|
|
178
178
|
},
|
|
179
179
|
"sideEffects": false,
|
|
@@ -204,8 +204,12 @@ export const createBackendManifest = (
|
|
|
204
204
|
source: {
|
|
205
205
|
module: sourceModule,
|
|
206
206
|
},
|
|
207
|
-
|
|
208
|
-
|
|
207
|
+
...(app.apiProtocol === 'rpc'
|
|
208
|
+
? { rpcPath: app.rpcPath, rpcSerialization: 'json' }
|
|
209
|
+
: {
|
|
210
|
+
readinessPath: `${app.apiPrefix}/${app.apiStem}/readiness`,
|
|
211
|
+
openapiPath: `${app.apiPrefix}/openapi.json`,
|
|
212
|
+
}),
|
|
209
213
|
...(app.deliveryUnit ? { deliveryUnit: app.deliveryUnit } : {}),
|
|
210
214
|
versionBoundary: {
|
|
211
215
|
invariant: 'web-and-api-same-build',
|