@bleedingdev/modern-js-app-tools-extensions 3.9.0-ultramodern.8 → 3.9.3-ultramodern.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +23 -0
- package/dist/cjs/backend-federation-build/codegen.js +29 -18
- package/dist/cjs/backend-federation-build/config.js +84 -45
- package/dist/cjs/backend-federation-build/emit.js +63 -22
- package/dist/cjs/build-config/build-environment.js +25 -162
- package/dist/cjs/build-config/internal-effect-discovery.js +143 -0
- package/dist/cjs/build-config/public.js +2 -5
- package/dist/cjs/build-config/remote-address.js +58 -0
- package/dist/cjs/cloudflare/artifacts.js +8 -19
- package/dist/cjs/cloudflare/delivery-unit.js +125 -43
- package/dist/cjs/cloudflare/index.js +14 -4
- package/dist/cjs/cloudflare/native-renderer.js +100 -0
- package/dist/cjs/cloudflare/renderer-identity.js +106 -0
- package/dist/cjs/cloudflare/worker-manifest.js +54 -13
- package/dist/cjs/cloudflare/worker-options.js +48 -0
- package/dist/cjs/cloudflare/wrangler-config.js +210 -13
- package/dist/cjs/cloudflare-builder.js +307 -89
- package/dist/cjs/cloudflare-output-contract.js +36 -4
- package/dist/cjs/cloudflare-output-verifier/identity.js +112 -23
- 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/config.js +10 -5
- package/dist/cjs/deploy-output/npmAliases.js +92 -6
- package/dist/cjs/deploy-output/plugin.js +27 -6
- package/dist/cjs/deploy-output/public-assets.js +146 -0
- package/dist/cjs/deploy-output/target.js +57 -1
- package/dist/cjs/deploy-output/trace-files.js +99 -0
- package/dist/cjs/module-federation-config/exposes.js +70 -0
- package/dist/cjs/module-federation-config/index.js +73 -0
- package/dist/cjs/module-federation-config/inspect.js +103 -0
- package/dist/cjs/module-federation-config/object-literal.js +87 -0
- package/dist/cjs/module-federation-config/syntax.js +151 -0
- package/dist/cjs/module-federation-config/types.js +18 -0
- package/dist/cjs/native-type-checker.js +164 -18
- package/dist/cjs/policy-defaults.js +110 -0
- package/dist/cjs/release-envelope/canonical.js +2 -9
- package/dist/cjs/release-envelope/contract.js +68 -0
- package/dist/cjs/release-envelope/framework-output.js +296 -105
- package/dist/cjs/release-envelope/index.js +150 -36
- package/dist/cjs/release-envelope/plugin.js +24 -15
- package/dist/cjs/release-envelope/renderer-output-stamp.js +170 -0
- package/dist/cjs/release-envelope/types.js +10 -8
- package/dist/cjs/release-identity.js +8 -5
- package/dist/cjs/renderer-build-identity.js +134 -0
- package/dist/cjs/runtime-package-resolution.js +118 -0
- package/dist/cjs/templates/cloudflare-entry.001-bootstrap-security.mjs +14 -6
- package/dist/cjs/templates/cloudflare-entry.002-assets-routes.mjs +10 -2
- package/dist/cjs/templates/cloudflare-entry.004-rendering-css.mjs +403 -96
- package/dist/cjs/templates/cloudflare-entry.005-worker-dispatch.mjs +530 -103
- package/dist/cjs/templates/cloudflare-entry.006-fetch-handler.mjs +26 -7
- package/dist/cjs/templates/cloudflare-worker-route-data.mjs +1069 -0
- package/dist/cjs/workspace-topology.js +84 -0
- package/dist/esm/backend-federation-build/codegen.mjs +29 -18
- package/dist/esm/backend-federation-build/config.mjs +74 -38
- package/dist/esm/backend-federation-build/emit.mjs +64 -23
- package/dist/esm/build-config/build-environment.mjs +26 -160
- package/dist/esm/build-config/internal-effect-discovery.mjs +102 -0
- package/dist/esm/build-config/public.mjs +1 -1
- package/dist/esm/build-config/remote-address.mjs +20 -0
- package/dist/esm/cloudflare/artifacts.mjs +8 -19
- package/dist/esm/cloudflare/delivery-unit.mjs +124 -45
- package/dist/esm/cloudflare/index.mjs +15 -5
- package/dist/esm/cloudflare/native-renderer.mjs +48 -0
- package/dist/esm/cloudflare/renderer-identity.mjs +57 -0
- package/dist/esm/cloudflare/worker-manifest.mjs +55 -14
- package/dist/esm/cloudflare/worker-options.mjs +10 -0
- package/dist/esm/cloudflare/wrangler-config.mjs +203 -12
- package/dist/esm/cloudflare-builder.mjs +301 -89
- package/dist/esm/cloudflare-output-contract.mjs +29 -3
- package/dist/esm/cloudflare-output-verifier/identity.mjs +113 -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/config.mjs +3 -1
- package/dist/esm/deploy-output/npmAliases.mjs +92 -6
- package/dist/esm/deploy-output/plugin.mjs +24 -6
- package/dist/esm/deploy-output/public-assets.mjs +82 -0
- package/dist/esm/deploy-output/target.mjs +50 -3
- package/dist/esm/deploy-output/trace-files.mjs +47 -0
- package/dist/esm/module-federation-config/exposes.mjs +18 -0
- package/dist/esm/module-federation-config/index.mjs +4 -0
- package/dist/esm/module-federation-config/inspect.mjs +65 -0
- package/dist/esm/module-federation-config/object-literal.mjs +43 -0
- package/dist/esm/module-federation-config/syntax.mjs +101 -0
- package/dist/esm/module-federation-config/types.mjs +0 -0
- package/dist/esm/native-type-checker.mjs +158 -18
- package/dist/esm/policy-defaults.mjs +51 -0
- package/dist/esm/release-envelope/canonical.mjs +2 -9
- package/dist/esm/release-envelope/contract.mjs +21 -0
- package/dist/esm/release-envelope/framework-output.mjs +297 -106
- package/dist/esm/release-envelope/index.mjs +149 -38
- package/dist/esm/release-envelope/plugin.mjs +24 -15
- package/dist/esm/release-envelope/renderer-output-stamp.mjs +112 -0
- package/dist/esm/release-envelope/types.mjs +2 -3
- package/dist/esm/release-identity.mjs +8 -5
- package/dist/esm/renderer-build-identity.mjs +82 -0
- package/dist/esm/runtime-package-resolution.mjs +60 -0
- package/dist/esm/templates/cloudflare-entry.001-bootstrap-security.mjs +14 -6
- package/dist/esm/templates/cloudflare-entry.002-assets-routes.mjs +10 -2
- package/dist/esm/templates/cloudflare-entry.004-rendering-css.mjs +403 -96
- package/dist/esm/templates/cloudflare-entry.005-worker-dispatch.mjs +530 -103
- package/dist/esm/templates/cloudflare-entry.006-fetch-handler.mjs +26 -7
- package/dist/esm/templates/cloudflare-worker-route-data.mjs +1069 -0
- package/dist/esm/workspace-topology.mjs +21 -0
- package/dist/esm-node/backend-federation-build/codegen.mjs +29 -18
- package/dist/esm-node/backend-federation-build/config.mjs +74 -38
- package/dist/esm-node/backend-federation-build/emit.mjs +64 -23
- package/dist/esm-node/build-config/build-environment.mjs +26 -160
- package/dist/esm-node/build-config/internal-effect-discovery.mjs +103 -0
- package/dist/esm-node/build-config/public.mjs +1 -1
- package/dist/esm-node/build-config/remote-address.mjs +21 -0
- package/dist/esm-node/cloudflare/artifacts.mjs +8 -19
- package/dist/esm-node/cloudflare/delivery-unit.mjs +124 -45
- package/dist/esm-node/cloudflare/index.mjs +15 -5
- package/dist/esm-node/cloudflare/native-renderer.mjs +49 -0
- package/dist/esm-node/cloudflare/renderer-identity.mjs +58 -0
- package/dist/esm-node/cloudflare/worker-manifest.mjs +55 -14
- package/dist/esm-node/cloudflare/worker-options.mjs +11 -0
- package/dist/esm-node/cloudflare/wrangler-config.mjs +203 -12
- package/dist/esm-node/cloudflare-builder.mjs +301 -89
- package/dist/esm-node/cloudflare-output-contract.mjs +29 -3
- package/dist/esm-node/cloudflare-output-verifier/identity.mjs +113 -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/config.mjs +3 -1
- package/dist/esm-node/deploy-output/npmAliases.mjs +92 -6
- package/dist/esm-node/deploy-output/plugin.mjs +24 -6
- package/dist/esm-node/deploy-output/public-assets.mjs +83 -0
- package/dist/esm-node/deploy-output/target.mjs +50 -3
- package/dist/esm-node/deploy-output/trace-files.mjs +48 -0
- package/dist/esm-node/module-federation-config/exposes.mjs +19 -0
- package/dist/esm-node/module-federation-config/index.mjs +5 -0
- package/dist/esm-node/module-federation-config/inspect.mjs +66 -0
- package/dist/esm-node/module-federation-config/object-literal.mjs +44 -0
- package/dist/esm-node/module-federation-config/syntax.mjs +102 -0
- package/dist/esm-node/module-federation-config/types.mjs +1 -0
- package/dist/esm-node/native-type-checker.mjs +158 -18
- package/dist/esm-node/policy-defaults.mjs +52 -0
- package/dist/esm-node/release-envelope/canonical.mjs +2 -9
- package/dist/esm-node/release-envelope/contract.mjs +22 -0
- package/dist/esm-node/release-envelope/framework-output.mjs +297 -106
- package/dist/esm-node/release-envelope/index.mjs +149 -38
- package/dist/esm-node/release-envelope/plugin.mjs +24 -15
- package/dist/esm-node/release-envelope/renderer-output-stamp.mjs +113 -0
- package/dist/esm-node/release-envelope/types.mjs +2 -3
- package/dist/esm-node/release-identity.mjs +8 -5
- package/dist/esm-node/renderer-build-identity.mjs +83 -0
- package/dist/esm-node/runtime-package-resolution.mjs +61 -0
- package/dist/esm-node/templates/cloudflare-entry.001-bootstrap-security.mjs +14 -6
- package/dist/esm-node/templates/cloudflare-entry.002-assets-routes.mjs +10 -2
- package/dist/esm-node/templates/cloudflare-entry.004-rendering-css.mjs +403 -96
- package/dist/esm-node/templates/cloudflare-entry.005-worker-dispatch.mjs +530 -103
- package/dist/esm-node/templates/cloudflare-entry.006-fetch-handler.mjs +26 -7
- package/dist/esm-node/templates/cloudflare-worker-route-data.mjs +1069 -0
- package/dist/esm-node/workspace-topology.mjs +22 -0
- package/dist/types/backend-federation-build/codegen.d.ts +30 -0
- package/dist/types/backend-federation-build/config.d.ts +10 -57
- package/dist/types/backend-federation-build/emit.d.ts +12 -2
- package/dist/types/backend-federation-build/index.d.ts +1 -1
- package/dist/types/build-config/build-environment.d.ts +1 -9
- package/dist/types/build-config/internal-effect-discovery.d.ts +4 -0
- package/dist/types/build-config/public.d.ts +1 -1
- package/dist/types/build-config/remote-address.d.ts +3 -0
- package/dist/types/cloudflare/artifacts.d.ts +7 -6
- package/dist/types/cloudflare/constants.d.ts +1 -1
- package/dist/types/cloudflare/delivery-unit.d.ts +38 -7
- package/dist/types/cloudflare/native-renderer.d.ts +30 -0
- package/dist/types/cloudflare/renderer-identity.d.ts +25 -0
- package/dist/types/cloudflare/worker-manifest.d.ts +17 -2
- package/dist/types/cloudflare/worker-options.d.ts +20 -0
- package/dist/types/cloudflare/wrangler-config.d.ts +55 -2
- package/dist/types/cloudflare-builder.d.ts +51 -8
- package/dist/types/cloudflare-output-contract.d.ts +5 -3
- package/dist/types/cloudflare-output-verifier/identity.d.ts +7 -3
- package/dist/types/cloudflare-output-verifier/worker-bundles.d.ts +2 -2
- package/dist/types/config.d.ts +98 -13
- package/dist/types/deploy-output/plugin.d.ts +29 -9
- package/dist/types/deploy-output/public-assets.d.ts +51 -0
- package/dist/types/deploy-output/target.d.ts +28 -5
- package/dist/types/deploy-output/trace-files.d.ts +17 -0
- package/dist/types/module-federation-config/exposes.d.ts +11 -0
- package/dist/types/module-federation-config/index.d.ts +5 -0
- package/dist/types/module-federation-config/inspect.d.ts +2 -0
- package/dist/types/module-federation-config/object-literal.d.ts +4 -0
- package/dist/types/module-federation-config/syntax.d.ts +7 -0
- package/dist/types/module-federation-config/types.d.ts +20 -0
- package/dist/types/native-type-checker.d.ts +26 -3
- package/dist/types/policy-defaults.d.ts +56 -0
- package/dist/types/release-envelope/canonical.d.ts +5 -5
- package/dist/types/release-envelope/contract.d.mts +8 -0
- package/dist/types/release-envelope/framework-output.d.ts +23 -13
- package/dist/types/release-envelope/index.d.ts +17 -5
- package/dist/types/release-envelope/plugin.d.ts +10 -6
- package/dist/types/release-envelope/renderer-output-stamp.d.ts +34 -0
- package/dist/types/release-envelope/types.d.ts +42 -4
- package/dist/types/release-identity.d.ts +3 -2
- package/dist/types/renderer-build-identity.d.ts +30 -0
- package/dist/types/runtime-package-resolution.d.ts +28 -0
- package/dist/types/templates/cloudflare-worker-route-data.d.mts +14 -0
- package/dist/types/workspace-topology.d.ts +91 -0
- package/package.json +97 -26
- package/src/backend-federation-build/codegen.ts +28 -19
- package/src/backend-federation-build/config.ts +189 -123
- package/src/backend-federation-build/emit.ts +119 -38
- package/src/backend-federation-build/index.ts +4 -1
- package/src/build-config/build-environment.ts +59 -285
- package/src/build-config/internal-effect-discovery.ts +239 -0
- package/src/build-config/public.ts +0 -1
- package/src/build-config/remote-address.ts +33 -0
- package/src/cloudflare/artifacts.ts +22 -43
- package/src/cloudflare/delivery-unit.ts +283 -60
- package/src/cloudflare/index.ts +35 -19
- package/src/cloudflare/native-renderer.ts +117 -0
- package/src/cloudflare/renderer-identity.ts +171 -0
- package/src/cloudflare/worker-manifest.ts +108 -10
- package/src/cloudflare/worker-options.ts +60 -0
- package/src/cloudflare/wrangler-config.ts +390 -14
- package/src/cloudflare-builder.ts +543 -170
- package/src/cloudflare-output-contract.ts +45 -2
- package/src/cloudflare-output-verifier/identity.ts +138 -7
- 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/config.ts +101 -19
- package/src/deploy-output/npmAliases.ts +141 -4
- package/src/deploy-output/plugin.ts +55 -18
- package/src/deploy-output/public-assets.ts +224 -0
- package/src/deploy-output/target.ts +97 -14
- package/src/deploy-output/trace-files.ts +80 -0
- package/src/module-federation-config/exposes.ts +46 -0
- package/src/module-federation-config/index.ts +22 -0
- package/src/module-federation-config/inspect.ts +157 -0
- package/src/module-federation-config/object-literal.ts +76 -0
- package/src/module-federation-config/syntax.ts +212 -0
- package/src/module-federation-config/types.ts +22 -0
- package/src/native-type-checker.ts +281 -26
- package/src/policy-defaults.ts +157 -0
- package/src/release-envelope/canonical.ts +6 -18
- package/src/release-envelope/contract.mjs +28 -0
- package/src/release-envelope/framework-output.ts +681 -156
- package/src/release-envelope/index.ts +315 -60
- package/src/release-envelope/plugin.ts +54 -38
- package/src/release-envelope/renderer-output-stamp.ts +210 -0
- package/src/release-envelope/types.ts +75 -6
- package/src/release-identity.ts +19 -2
- package/src/renderer-build-identity.ts +168 -0
- package/src/runtime-package-resolution.ts +115 -0
- package/src/templates/cloudflare-entry.001-bootstrap-security.mjs +14 -6
- package/src/templates/cloudflare-entry.002-assets-routes.mjs +10 -2
- package/src/templates/cloudflare-entry.004-rendering-css.mjs +403 -96
- package/src/templates/cloudflare-entry.005-worker-dispatch.mjs +530 -103
- package/src/templates/cloudflare-entry.006-fetch-handler.mjs +26 -7
- package/src/templates/cloudflare-worker-route-data.mjs +1069 -0
- package/src/workspace-topology.ts +125 -0
- package/dist/cjs/templates/cloudflare-worker-fs-promises.mjs +0 -11
- package/dist/cjs/templates/cloudflare-worker-loadable-server.mjs +0 -281
- package/dist/cjs/templates/cloudflare-worker-mf-ssr-runtime-plugin.mjs +0 -14
- package/dist/cjs/templates/cloudflare-worker-path.mjs +0 -98
- package/dist/esm/templates/cloudflare-worker-fs-promises.mjs +0 -11
- package/dist/esm/templates/cloudflare-worker-loadable-server.mjs +0 -281
- package/dist/esm/templates/cloudflare-worker-mf-ssr-runtime-plugin.mjs +0 -14
- package/dist/esm/templates/cloudflare-worker-path.mjs +0 -98
- package/dist/esm-node/templates/cloudflare-worker-fs-promises.mjs +0 -11
- package/dist/esm-node/templates/cloudflare-worker-loadable-server.mjs +0 -281
- package/dist/esm-node/templates/cloudflare-worker-mf-ssr-runtime-plugin.mjs +0 -14
- package/dist/esm-node/templates/cloudflare-worker-path.mjs +0 -98
- package/dist/types/templates/cloudflare-worker-fs-promises.d.mts +0 -5
- package/dist/types/templates/cloudflare-worker-loadable-server.d.mts +0 -48
- package/dist/types/templates/cloudflare-worker-mf-ssr-runtime-plugin.d.mts +0 -13
- package/dist/types/templates/cloudflare-worker-path.d.mts +0 -21
- package/src/templates/cloudflare-worker-fs-promises.mjs +0 -11
- package/src/templates/cloudflare-worker-loadable-server.mjs +0 -281
- package/src/templates/cloudflare-worker-mf-ssr-runtime-plugin.mjs +0 -14
- package/src/templates/cloudflare-worker-path.mjs +0 -98
|
@@ -53,14 +53,34 @@ const promises_namespaceObject = require("node:fs/promises");
|
|
|
53
53
|
var promises_default = /*#__PURE__*/ __webpack_require__.n(promises_namespaceObject);
|
|
54
54
|
const external_node_path_namespaceObject = require("node:path");
|
|
55
55
|
var external_node_path_default = /*#__PURE__*/ __webpack_require__.n(external_node_path_namespaceObject);
|
|
56
|
+
const external_node_util_namespaceObject = require("node:util");
|
|
56
57
|
const backend_federation_contracts_namespaceObject = require("@modern-js/backend-federation-contracts");
|
|
58
|
+
const config_js_namespaceObject = require("../backend-federation-build/config.js");
|
|
59
|
+
const delivery_unit_js_namespaceObject = require("../cloudflare/delivery-unit.js");
|
|
57
60
|
const external_index_js_namespaceObject = require("./index.js");
|
|
61
|
+
const external_types_js_namespaceObject = require("./types.js");
|
|
58
62
|
const MICROVERTICAL_RELEASE_ENVELOPE_PATH = 'release/microvertical-release-envelope.json';
|
|
59
63
|
const MICROVERTICAL_RELEASE_IDENTITY_CARRIERS_PATH = 'release/microvertical-release-identity-carriers.json';
|
|
60
64
|
const MICROVERTICAL_RELEASE_IDENTITY_CARRIERS_KIND = 'ultramodern-release-identity-carriers';
|
|
61
65
|
const MICROVERTICAL_RELEASE_IDENTITY_CARRIERS_SCHEMA_VERSION = 1;
|
|
62
66
|
const COMPILED_MODULE_PATTERN = /\.(?:c|m)?js$/u;
|
|
63
67
|
const EFFECT_BFF_WORKER_PATTERN = /^worker\/__modern_bff_effect\.(?:c|m)?js$/u;
|
|
68
|
+
const EFFECT_BFF_WORKER_SUPPORT_PATTERN = /^worker\/__modern_worker_(?:runtime|shared)_*\.(?:c|m)?js$/u;
|
|
69
|
+
const isEffectBffWorkerArtifact = (logicalPath)=>EFFECT_BFF_WORKER_PATTERN.test(logicalPath) || EFFECT_BFF_WORKER_SUPPORT_PATTERN.test(logicalPath);
|
|
70
|
+
const effectBffWorkerArtifacts = (files)=>files.some((logicalPath)=>EFFECT_BFF_WORKER_PATTERN.test(logicalPath)) ? files.filter(isEffectBffWorkerArtifact) : [];
|
|
71
|
+
const CRAWLER_POLICY_PATH = 'public/robots.txt';
|
|
72
|
+
const isPublicMetadataPath = (logicalPath)=>'public/_headers' === logicalPath || /^public\/\.well-known\/[^/]+\.json$/u.test(logicalPath);
|
|
73
|
+
const PUBLIC_BUILD_ARTIFACT_PATH = `public/${backend_federation_contracts_namespaceObject.ULTRAMODERN_BUILD_ARTIFACT_FILE}`;
|
|
74
|
+
const DECLARED_PUBLIC_ASSET_RUNTIME = 'public-asset';
|
|
75
|
+
const resolveDeclaredPublicAssets = (files, declaredPublicAssets, target)=>{
|
|
76
|
+
const staged = new Set(files);
|
|
77
|
+
const declared = new Set();
|
|
78
|
+
for (const logicalPath of declaredPublicAssets){
|
|
79
|
+
if (!logicalPath.startsWith('public/') || !staged.has(logicalPath)) throw new Error(`[ultramodern-release-envelope] final ${target} staging has no declared public asset file ${JSON.stringify(logicalPath)}.`);
|
|
80
|
+
declared.add(logicalPath);
|
|
81
|
+
}
|
|
82
|
+
return declared;
|
|
83
|
+
};
|
|
64
84
|
const isRecord = (value)=>'object' == typeof value && null !== value && !Array.isArray(value);
|
|
65
85
|
const flattenStrings = (value)=>'string' == typeof value ? [
|
|
66
86
|
value
|
|
@@ -74,7 +94,12 @@ const collectNestedStrings = (value, key)=>{
|
|
|
74
94
|
]);
|
|
75
95
|
};
|
|
76
96
|
const emptyProducerRouteModules = async (distDirectory, files, manifest, manifestLogicalPath)=>{
|
|
77
|
-
if (!isRecord(manifest) || !Array.isArray(manifest.exposes) || 0 !== manifest.exposes.length || !Array.isArray(manifest.remotes) ||
|
|
97
|
+
if (!isRecord(manifest) || !Array.isArray(manifest.exposes) || 0 !== manifest.exposes.length || !Array.isArray(manifest.remotes) || manifest.remotes.some((remote)=>!isRecord(remote) || [
|
|
98
|
+
'federationContainerName',
|
|
99
|
+
'moduleName',
|
|
100
|
+
'alias',
|
|
101
|
+
'entry'
|
|
102
|
+
].some((key)=>'string' != typeof remote[key] || 0 === remote[key].trim().length)) || !isRecord(manifest.metaData) || !isRecord(manifest.metaData.remoteEntry) || '' !== manifest.metaData.remoteEntry.name || '' !== manifest.metaData.remoteEntry.path || 'global' !== manifest.metaData.remoteEntry.type) return [];
|
|
78
103
|
const publicPath = manifest.metaData.publicPath;
|
|
79
104
|
const safeReference = (value)=>'string' == typeof value && value.length > 0 && !/[\\\\%?#\s]/u.test(value) && !value.split('/').some((segment)=>'.' === segment || '..' === segment);
|
|
80
105
|
if (!safeReference(publicPath)) return [];
|
|
@@ -175,11 +200,14 @@ const writeReleaseEnvelope = async (artifactRoot, envelope)=>{
|
|
|
175
200
|
if (!envelopePath) throw new Error('[ultramodern-release-envelope] could not resolve release envelope path.');
|
|
176
201
|
await promises_default().writeFile(envelopePath, `${(0, external_index_js_namespaceObject.canonicalSerializeMicroVerticalReleaseEnvelope)(envelope)}\n`);
|
|
177
202
|
};
|
|
178
|
-
const readBuildArtifact = async (distDirectory)=>{
|
|
203
|
+
const readBuildArtifact = async (distDirectory, requirePromotable = true)=>{
|
|
179
204
|
const artifactPath = external_node_path_default().join(distDirectory, backend_federation_contracts_namespaceObject.ULTRAMODERN_BUILD_ARTIFACT_FILE);
|
|
180
205
|
const artifact = await readJson(artifactPath);
|
|
181
206
|
if (!(0, backend_federation_contracts_namespaceObject.isUltramodernBuildArtifact)(artifact)) throw new Error(`[ultramodern-release-envelope] ${backend_federation_contracts_namespaceObject.ULTRAMODERN_BUILD_ARTIFACT_FILE} is missing or invalid.`);
|
|
182
|
-
if ('workspace' === artifact.deliveryUnit.sourceRevision)
|
|
207
|
+
if ('workspace' === artifact.deliveryUnit.sourceRevision) {
|
|
208
|
+
if (!requirePromotable) return;
|
|
209
|
+
throw new Error('[ultramodern-release-envelope] sourceRevision "workspace" cannot produce a promotable envelope.');
|
|
210
|
+
}
|
|
183
211
|
return artifact;
|
|
184
212
|
};
|
|
185
213
|
const assertIdentityBlock = (value, identity, location, includeReleaseVersion)=>{
|
|
@@ -248,7 +276,7 @@ const releaseArtifact = (logicalPath, runtime)=>({
|
|
|
248
276
|
const writeReleaseIdentityCarrierMetadata = async (artifactRoot, identity, carrierPaths)=>{
|
|
249
277
|
const surfacesByPath = new Map();
|
|
250
278
|
for (const [surface, logicalPaths] of Object.entries(carrierPaths)){
|
|
251
|
-
if (0 === logicalPaths.length) throw new Error(`[ultramodern-release-envelope] ${surface} has no declared release-identity carrier artifact.`);
|
|
279
|
+
if (0 === logicalPaths.length && 'ssr' !== surface && 'uiClient' !== surface) throw new Error(`[ultramodern-release-envelope] ${surface} has no declared release-identity carrier artifact.`);
|
|
252
280
|
for (const logicalPath of logicalPaths){
|
|
253
281
|
const surfaces = surfacesByPath.get(logicalPath) ?? new Set();
|
|
254
282
|
surfaces.add(surface);
|
|
@@ -288,12 +316,14 @@ const writeReleaseIdentityCarrierMetadata = async (artifactRoot, identity, carri
|
|
|
288
316
|
}, null, 2)}\n`);
|
|
289
317
|
return releaseArtifact(MICROVERTICAL_RELEASE_IDENTITY_CARRIERS_PATH, 'release-identity-metadata');
|
|
290
318
|
};
|
|
291
|
-
const createReleaseArtifactInputs = async (distDirectory, identity, target)=>{
|
|
319
|
+
const createReleaseArtifactInputs = async (distDirectory, identity, target, apiOnly, uiOnly, shellConsumer)=>{
|
|
320
|
+
const backendProducer = !uiOnly && !shellConsumer;
|
|
292
321
|
const files = await collectFiles(distDirectory);
|
|
293
|
-
|
|
322
|
+
const effectWorkerPaths = effectBffWorkerArtifacts(files);
|
|
323
|
+
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.');
|
|
294
324
|
const uiClientPaths = files.filter((logicalPath)=>{
|
|
295
325
|
const topLevel = logicalPath.split('/')[0];
|
|
296
|
-
return 'static' === topLevel || 'html' === topLevel || 'public' === topLevel || [
|
|
326
|
+
return 'static' === topLevel || 'html' === topLevel || 'public' === topLevel && logicalPath !== CRAWLER_POLICY_PATH && logicalPath !== PUBLIC_BUILD_ARTIFACT_PATH && !isPublicMetadataPath(logicalPath) || [
|
|
297
327
|
'index.html',
|
|
298
328
|
'mf-manifest.json',
|
|
299
329
|
'mf-stats.json',
|
|
@@ -302,16 +332,19 @@ const createReleaseArtifactInputs = async (distDirectory, identity, target)=>{
|
|
|
302
332
|
'loadable-stats.json'
|
|
303
333
|
].includes(logicalPath);
|
|
304
334
|
});
|
|
305
|
-
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) && !
|
|
335
|
+
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) && !effectWorkerPaths.includes(logicalPath));
|
|
306
336
|
const nodeApiEntryPaths = files.filter((logicalPath)=>logicalPath.startsWith('api/') && COMPILED_MODULE_PATTERN.test(logicalPath));
|
|
307
|
-
const apiBackendPaths = 'node' === target ? files.filter((logicalPath)=>(logicalPath.startsWith('api/') || logicalPath.startsWith('shared/')) && COMPILED_MODULE_PATTERN.test(logicalPath)) :
|
|
308
|
-
if (0 ===
|
|
309
|
-
if (0
|
|
310
|
-
if (
|
|
311
|
-
|
|
312
|
-
if (0
|
|
313
|
-
|
|
314
|
-
|
|
337
|
+
const apiBackendPaths = 'node' === target ? files.filter((logicalPath)=>(logicalPath.startsWith('api/') || logicalPath.startsWith('shared/')) && COMPILED_MODULE_PATTERN.test(logicalPath)) : effectWorkerPaths;
|
|
338
|
+
if (backendProducer && 'cloudflare' === target && 0 === effectWorkerPaths.length) throw new Error('[ultramodern-release-envelope] cloudflare MicroVertical has no actual Effect API/BFF worker artifact.');
|
|
339
|
+
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.');
|
|
340
|
+
if (!apiOnly && 0 === uiClientPaths.length) throw new Error(`[ultramodern-release-envelope] ${target} full-stack MicroVertical has no UI/client artifacts.`);
|
|
341
|
+
if (!apiOnly && 0 === ssrPaths.length) throw new Error(`[ultramodern-release-envelope] ${target} full-stack MicroVertical has no ${'node' === target ? 'Node' : 'workerd'} SSR artifacts.`);
|
|
342
|
+
if (uiOnly && (apiBackendPaths.length > 0 || nodeApiEntryPaths.length > 0)) throw new Error('[ultramodern-release-envelope] UI-only application emitted an undeclared API/backend artifact.');
|
|
343
|
+
if (backendProducer && ('node' === target && 0 === nodeApiEntryPaths.length || 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'}.`);
|
|
344
|
+
const clientExecutionPaths = apiOnly ? [] : await manifestReferencedClientModules(distDirectory, files);
|
|
345
|
+
if (!apiOnly && 0 === clientExecutionPaths.length) throw new Error('[ultramodern-release-envelope] UI/client manifest references no compiled execution module.');
|
|
346
|
+
const ssrExecutionPaths = apiOnly ? [] : await routeReferencedSsrModules(distDirectory, files, target);
|
|
347
|
+
if (!apiOnly && 0 === ssrExecutionPaths.length) throw new Error(`[ultramodern-release-envelope] route manifest references no emitted ${'node' === target ? 'Node' : 'Cloudflare'} SSR execution module.`);
|
|
315
348
|
const runtimeByPath = new Map();
|
|
316
349
|
const add = (paths, runtime)=>{
|
|
317
350
|
for (const logicalPath of paths){
|
|
@@ -321,14 +354,25 @@ const createReleaseArtifactInputs = async (distDirectory, identity, target)=>{
|
|
|
321
354
|
}
|
|
322
355
|
};
|
|
323
356
|
add(uiClientPaths, 'browser');
|
|
357
|
+
add(files.filter((logicalPath)=>logicalPath === CRAWLER_POLICY_PATH), 'crawler-policy');
|
|
358
|
+
add(files.filter(isPublicMetadataPath), 'public-metadata');
|
|
324
359
|
add(ssrPaths, 'node' === target ? 'nodejs' : 'workerd');
|
|
325
360
|
add(apiBackendPaths, 'node' === target ? 'nodejs' : 'workerd-effect');
|
|
326
361
|
add([
|
|
327
|
-
backend_federation_contracts_namespaceObject.
|
|
328
|
-
], '
|
|
329
|
-
add(
|
|
330
|
-
|
|
331
|
-
|
|
362
|
+
backend_federation_contracts_namespaceObject.ULTRAMODERN_BUILD_ARTIFACT_FILE
|
|
363
|
+
], 'release-identity-metadata');
|
|
364
|
+
add(files.filter((logicalPath)=>logicalPath === PUBLIC_BUILD_ARTIFACT_PATH), 'release-identity-metadata');
|
|
365
|
+
if (backendProducer) {
|
|
366
|
+
add([
|
|
367
|
+
backend_federation_contracts_namespaceObject.BACKEND_FEDERATION_MANIFEST_FILE
|
|
368
|
+
], 'module-federation-manifest');
|
|
369
|
+
add([
|
|
370
|
+
backend_federation_contracts_namespaceObject.BACKEND_FEDERATION_REMOTE_ENTRY_FILE
|
|
371
|
+
], 'node' === target ? 'nodejs' : 'commonjs-module');
|
|
372
|
+
}
|
|
373
|
+
if (shellConsumer) {
|
|
374
|
+
for (const logicalPath of files)if (!runtimeByPath.has(logicalPath)) runtimeByPath.set(logicalPath, `${target}-deployment`);
|
|
375
|
+
}
|
|
332
376
|
const surfaces = {
|
|
333
377
|
uiClient: [
|
|
334
378
|
...uiClientPaths
|
|
@@ -339,20 +383,26 @@ const createReleaseArtifactInputs = async (distDirectory, identity, target)=>{
|
|
|
339
383
|
apiBackend: [
|
|
340
384
|
...apiBackendPaths
|
|
341
385
|
].sort((left, right)=>left.localeCompare(right)),
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
386
|
+
...backendProducer ? {
|
|
387
|
+
backendFederation: {
|
|
388
|
+
manifest: backend_federation_contracts_namespaceObject.BACKEND_FEDERATION_MANIFEST_FILE,
|
|
389
|
+
container: backend_federation_contracts_namespaceObject.BACKEND_FEDERATION_REMOTE_ENTRY_FILE
|
|
390
|
+
}
|
|
391
|
+
} : {}
|
|
346
392
|
};
|
|
347
393
|
const artifacts = [
|
|
348
394
|
...runtimeByPath
|
|
349
395
|
].map(([logicalPath, runtime])=>releaseArtifact(logicalPath, runtime)).sort((left, right)=>left.logicalPath.localeCompare(right.logicalPath));
|
|
350
396
|
const identityCarrierMetadata = await writeReleaseIdentityCarrierMetadata(distDirectory, identity, {
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
397
|
+
...apiBackendPaths.length > 0 ? {
|
|
398
|
+
apiBackend: apiBackendPaths
|
|
399
|
+
} : {},
|
|
400
|
+
...backendProducer ? {
|
|
401
|
+
backendFederation: [
|
|
402
|
+
backend_federation_contracts_namespaceObject.BACKEND_FEDERATION_MANIFEST_FILE,
|
|
403
|
+
backend_federation_contracts_namespaceObject.BACKEND_FEDERATION_REMOTE_ENTRY_FILE
|
|
404
|
+
]
|
|
405
|
+
} : {},
|
|
356
406
|
ssr: [
|
|
357
407
|
...new Set([
|
|
358
408
|
...ssrExecutionPaths,
|
|
@@ -369,6 +419,25 @@ const createReleaseArtifactInputs = async (distDirectory, identity, target)=>{
|
|
|
369
419
|
surfaces
|
|
370
420
|
};
|
|
371
421
|
};
|
|
422
|
+
const releaseEnvelopeSurfaces = (surfaces, shellConsumer)=>{
|
|
423
|
+
if (!shellConsumer) return {
|
|
424
|
+
surfaces
|
|
425
|
+
};
|
|
426
|
+
const { uiClient, ssr, apiBackend } = surfaces;
|
|
427
|
+
return {
|
|
428
|
+
kind: external_types_js_namespaceObject.SHELL_RELEASE_ENVELOPE_KIND,
|
|
429
|
+
surfaces: {
|
|
430
|
+
uiClient,
|
|
431
|
+
ssr,
|
|
432
|
+
apiBackend
|
|
433
|
+
}
|
|
434
|
+
};
|
|
435
|
+
};
|
|
436
|
+
const assertShellBuildIdentity = async (appDirectory, distDirectory)=>{
|
|
437
|
+
const source = await (0, config_js_namespaceObject.readBuildIdentity)(appDirectory);
|
|
438
|
+
const finalized = await pathExists(external_node_path_default().join(distDirectory, backend_federation_contracts_namespaceObject.ULTRAMODERN_BUILD_ARTIFACT_FILE)) ? await (0, delivery_unit_js_namespaceObject.resolveWorkerDeliveryUnitStamp)(appDirectory, distDirectory) : void 0;
|
|
439
|
+
if (!source.artifact || !finalized || finalized.unitId !== source.unitId) throw new Error('[ultramodern-release-envelope] Shell is missing its native compiled delivery-unit identity.');
|
|
440
|
+
};
|
|
372
441
|
const pathExists = async (filePath)=>{
|
|
373
442
|
try {
|
|
374
443
|
await promises_default().access(filePath);
|
|
@@ -377,36 +446,79 @@ const pathExists = async (filePath)=>{
|
|
|
377
446
|
return false;
|
|
378
447
|
}
|
|
379
448
|
};
|
|
380
|
-
const emitFrameworkMicroVerticalReleaseEnvelope = async ({ apiOnly, distDirectory, target })=>{
|
|
381
|
-
|
|
449
|
+
const emitFrameworkMicroVerticalReleaseEnvelope = async ({ apiOnly, appDirectory, distDirectory, requirePromotable = true, expectedRendererProfile, role, target })=>{
|
|
450
|
+
const declaredRole = appDirectory ? await (0, delivery_unit_js_namespaceObject.resolveTopologyReleaseRole)(appDirectory) : void 0;
|
|
451
|
+
if (void 0 !== role && void 0 !== declaredRole && role !== declaredRole) throw new Error('[ultramodern-release-envelope] Configured release role disagrees with the declared topology app.');
|
|
452
|
+
const shellConsumer = (declaredRole ?? role ?? 'microvertical') === 'shell';
|
|
382
453
|
const backendManifestPath = external_node_path_default().join(distDirectory, backend_federation_contracts_namespaceObject.BACKEND_FEDERATION_MANIFEST_FILE);
|
|
383
454
|
const backendContainerPath = external_node_path_default().join(distDirectory, backend_federation_contracts_namespaceObject.BACKEND_FEDERATION_REMOTE_ENTRY_FILE);
|
|
384
455
|
const [hasBackendManifest, hasBackendContainer] = await Promise.all([
|
|
385
456
|
pathExists(backendManifestPath),
|
|
386
457
|
pathExists(backendContainerPath)
|
|
387
458
|
]);
|
|
388
|
-
if (
|
|
389
|
-
|
|
390
|
-
|
|
459
|
+
if (shellConsumer) {
|
|
460
|
+
if (apiOnly || hasBackendManifest || hasBackendContainer || !appDirectory) throw new Error('[ultramodern-release-envelope] Shell requires a full-stack application source and cannot declare a backend federation producer.');
|
|
461
|
+
await assertShellBuildIdentity(appDirectory, distDirectory);
|
|
462
|
+
} else if (!apiOnly && !hasBackendManifest && !hasBackendContainer) {
|
|
463
|
+
const source = appDirectory ? external_node_path_default().join(appDirectory, backend_federation_contracts_namespaceObject.ULTRAMODERN_BUILD_ARTIFACT_PATH) : void 0;
|
|
464
|
+
const participationPaths = [
|
|
465
|
+
external_node_path_default().join(distDirectory, backend_federation_contracts_namespaceObject.ULTRAMODERN_BUILD_ARTIFACT_FILE),
|
|
466
|
+
backendManifestPath,
|
|
467
|
+
backendContainerPath,
|
|
468
|
+
...source ? [
|
|
469
|
+
source,
|
|
470
|
+
source.replace(/\.json$/u, '.ts')
|
|
471
|
+
] : []
|
|
472
|
+
];
|
|
473
|
+
const hasParticipationEntry = (await Promise.all(participationPaths.map(async (filePath)=>{
|
|
474
|
+
try {
|
|
475
|
+
await promises_default().lstat(filePath);
|
|
476
|
+
return true;
|
|
477
|
+
} catch (error) {
|
|
478
|
+
if (isMissingPathError(error)) return false;
|
|
479
|
+
throw error;
|
|
480
|
+
}
|
|
481
|
+
}))).some(Boolean);
|
|
482
|
+
if (!hasParticipationEntry && (!appDirectory || !await (0, delivery_unit_js_namespaceObject.resolveTopologyDeliveryUnit)(appDirectory))) return;
|
|
483
|
+
}
|
|
484
|
+
const buildArtifact = await readBuildArtifact(distDirectory, requirePromotable);
|
|
485
|
+
const declared = appDirectory && buildArtifact ? await (0, delivery_unit_js_namespaceObject.resolveWorkerDeliveryUnitStamp)(appDirectory, distDirectory) : void 0;
|
|
486
|
+
const uiOnly = Boolean(declared?.surfaces.ui && !declared.surfaces.api);
|
|
487
|
+
if (uiOnly && (apiOnly || hasBackendManifest || hasBackendContainer)) throw new Error('[ultramodern-release-envelope] UI-only application cannot declare API-only configuration or backend federation output.');
|
|
488
|
+
if (!hasBackendManifest && !hasBackendContainer && !apiOnly && !buildArtifact) return;
|
|
489
|
+
if (!shellConsumer && !uiOnly && (!hasBackendManifest || !hasBackendContainer)) throw new Error('[ultramodern-release-envelope] MicroVertical backend federation manifest and container must be emitted together.');
|
|
490
|
+
if (!buildArtifact) return;
|
|
491
|
+
const builtUi = buildArtifact.surfaces.ui;
|
|
492
|
+
if (Boolean(builtUi) === apiOnly) throw new Error('[ultramodern-release-envelope] build artifact UI surface must match the configured application surface.');
|
|
493
|
+
if (void 0 !== expectedRendererProfile) (0, backend_federation_contracts_namespaceObject.assertRendererProfileCompatibility)(expectedRendererProfile, builtUi?.rendererProfile);
|
|
494
|
+
const ui = builtUi ? {
|
|
495
|
+
rendererIdentity: builtUi.rendererIdentity,
|
|
496
|
+
rendererProfile: builtUi.rendererProfile,
|
|
497
|
+
routerBindings: builtUi.routerBindings
|
|
498
|
+
} : void 0;
|
|
391
499
|
const identity = {
|
|
392
500
|
unitId: buildArtifact.deliveryUnit.unitId,
|
|
393
501
|
buildMarker: buildArtifact.deliveryUnit.buildMarker,
|
|
394
502
|
sourceRevision: buildArtifact.deliveryUnit.sourceRevision,
|
|
395
503
|
releaseVersion: buildArtifact.deliveryUnit.version
|
|
396
504
|
};
|
|
397
|
-
await readBackendManifest(distDirectory, identity);
|
|
398
|
-
const { artifacts, surfaces } = await createReleaseArtifactInputs(distDirectory, identity, target);
|
|
505
|
+
if (!shellConsumer && !uiOnly) await readBackendManifest(distDirectory, identity);
|
|
506
|
+
const { artifacts, surfaces } = await createReleaseArtifactInputs(distDirectory, identity, target, apiOnly, uiOnly, shellConsumer);
|
|
399
507
|
const envelope = await (0, external_index_js_namespaceObject.createMicroVerticalReleaseEnvelope)({
|
|
400
508
|
artifactRoot: distDirectory,
|
|
401
509
|
target,
|
|
402
510
|
identity,
|
|
511
|
+
...ui ? {
|
|
512
|
+
ui
|
|
513
|
+
} : {},
|
|
403
514
|
artifacts,
|
|
404
|
-
surfaces
|
|
515
|
+
...releaseEnvelopeSurfaces(surfaces, shellConsumer)
|
|
405
516
|
});
|
|
517
|
+
await verifyBuildArtifactCarriers(distDirectory, envelope);
|
|
406
518
|
await writeReleaseEnvelope(distDirectory, envelope);
|
|
407
519
|
return envelope;
|
|
408
520
|
};
|
|
409
|
-
const readFrameworkMicroVerticalReleaseEnvelope = async ({ artifactRoot, expectedTarget, logicalPathForArtifact, required = false })=>{
|
|
521
|
+
const readFrameworkMicroVerticalReleaseEnvelope = async ({ artifactRoot, expectedTarget, logicalPathForArtifact, expectedRendererProfile, required = false })=>{
|
|
410
522
|
const envelopePath = await resolveSafeReleaseEnvelopePath({
|
|
411
523
|
artifactRoot,
|
|
412
524
|
createDirectory: false
|
|
@@ -415,30 +527,55 @@ const readFrameworkMicroVerticalReleaseEnvelope = async ({ artifactRoot, expecte
|
|
|
415
527
|
if (required) throw new Error(`[ultramodern-release-envelope] required envelope is missing at ${MICROVERTICAL_RELEASE_ENVELOPE_PATH}.`);
|
|
416
528
|
return;
|
|
417
529
|
}
|
|
418
|
-
|
|
530
|
+
const envelope = await (0, external_index_js_namespaceObject.verifyMicroVerticalReleaseEnvelope)(await readJson(envelopePath), {
|
|
419
531
|
artifactRoot,
|
|
420
532
|
...expectedTarget ? {
|
|
421
533
|
expectedTarget
|
|
422
534
|
} : {},
|
|
423
535
|
...logicalPathForArtifact ? {
|
|
424
536
|
logicalPathForArtifact
|
|
537
|
+
} : {},
|
|
538
|
+
...expectedRendererProfile ? {
|
|
539
|
+
expectedRendererProfile
|
|
425
540
|
} : {}
|
|
426
541
|
});
|
|
542
|
+
await verifyBuildArtifactCarriers(artifactRoot, envelope, logicalPathForArtifact);
|
|
543
|
+
return envelope;
|
|
544
|
+
};
|
|
545
|
+
const verifyBuildArtifactCarriers = async (artifactRoot, envelope, logicalPathForArtifact)=>{
|
|
546
|
+
const carriers = envelope.artifacts.filter((artifact)=>artifact.logicalPath === backend_federation_contracts_namespaceObject.ULTRAMODERN_BUILD_ARTIFACT_FILE || artifact.logicalPath === PUBLIC_BUILD_ARTIFACT_PATH);
|
|
547
|
+
if (0 === carriers.length) throw new Error('[ultramodern-release-envelope] immutable build artifact must be bound to the release envelope.');
|
|
548
|
+
for (const artifact of carriers){
|
|
549
|
+
if ('file' !== artifact.kind || 'release-identity-metadata' !== artifact.runtime) throw new Error('[ultramodern-release-envelope] immutable build artifact must be a real file with runtime "release-identity-metadata".');
|
|
550
|
+
const logicalPath = logicalPathForArtifact?.(artifact) ?? artifact.logicalPath;
|
|
551
|
+
const built = await readJson(external_node_path_default().join(artifactRoot, logicalPath));
|
|
552
|
+
if (!(0, backend_federation_contracts_namespaceObject.isUltramodernBuildArtifact)(built)) throw new Error('[ultramodern-release-envelope] bound build artifact is invalid.');
|
|
553
|
+
assertIdentityBlock(built.deliveryUnit, envelope.identity, 'buildArtifact.deliveryUnit', true);
|
|
554
|
+
if (Boolean(built.surfaces.ui) !== Boolean(envelope.ui)) throw new Error('[ultramodern-release-envelope] bound build artifact UI surface differs from the release envelope.');
|
|
555
|
+
if (envelope.ui && built.surfaces.ui) {
|
|
556
|
+
if (!(0, external_node_util_namespaceObject.isDeepStrictEqual)(envelope.ui.routerBindings, built.surfaces.ui.routerBindings)) throw new Error('[ultramodern-release-envelope] buildArtifact.ui.routerBindings differ from the release envelope.');
|
|
557
|
+
(0, backend_federation_contracts_namespaceObject.assertRendererProfileCompatibility)(envelope.ui.rendererProfile, built.surfaces.ui.rendererProfile);
|
|
558
|
+
for (const field of [
|
|
559
|
+
'renderer',
|
|
560
|
+
'protocolVersion',
|
|
561
|
+
'appId',
|
|
562
|
+
'entryName',
|
|
563
|
+
'buildId'
|
|
564
|
+
])if (envelope.ui.rendererIdentity[field] !== built.surfaces.ui.rendererIdentity[field]) throw new Error(`[ultramodern-release-envelope] buildArtifact.ui.rendererIdentity.${field} differs from the release envelope.`);
|
|
565
|
+
}
|
|
566
|
+
}
|
|
427
567
|
};
|
|
428
568
|
const verifyBuildOutputReleaseEnvelope = async (distDirectory, expectedTarget)=>{
|
|
429
|
-
const [hasEnvelope, hasBuildArtifact
|
|
569
|
+
const [hasEnvelope, hasBuildArtifact] = await Promise.all([
|
|
430
570
|
pathExists(external_node_path_default().join(distDirectory, MICROVERTICAL_RELEASE_ENVELOPE_PATH)),
|
|
431
|
-
pathExists(external_node_path_default().join(distDirectory, backend_federation_contracts_namespaceObject.ULTRAMODERN_BUILD_ARTIFACT_FILE))
|
|
432
|
-
pathExists(external_node_path_default().join(distDirectory, backend_federation_contracts_namespaceObject.BACKEND_FEDERATION_MANIFEST_FILE)),
|
|
433
|
-
pathExists(external_node_path_default().join(distDirectory, backend_federation_contracts_namespaceObject.BACKEND_FEDERATION_REMOTE_ENTRY_FILE))
|
|
571
|
+
pathExists(external_node_path_default().join(distDirectory, backend_federation_contracts_namespaceObject.ULTRAMODERN_BUILD_ARTIFACT_FILE))
|
|
434
572
|
]);
|
|
435
|
-
const isFullStackMicroVertical = hasBuildArtifact && (hasBackendManifest || hasBackendEntry);
|
|
436
573
|
return readFrameworkMicroVerticalReleaseEnvelope({
|
|
437
574
|
artifactRoot: distDirectory,
|
|
438
575
|
...expectedTarget ? {
|
|
439
576
|
expectedTarget
|
|
440
577
|
} : {},
|
|
441
|
-
required: hasEnvelope ||
|
|
578
|
+
required: hasEnvelope || hasBuildArtifact
|
|
442
579
|
});
|
|
443
580
|
};
|
|
444
581
|
const verifyNodeReleaseEnvelopeStaging = async ({ outputDirectory })=>readFrameworkMicroVerticalReleaseEnvelope({
|
|
@@ -446,21 +583,26 @@ const verifyNodeReleaseEnvelopeStaging = async ({ outputDirectory })=>readFramew
|
|
|
446
583
|
expectedTarget: 'node',
|
|
447
584
|
required: true
|
|
448
585
|
});
|
|
449
|
-
const createNodeStagedReleaseArtifactInputs = async (outputDirectory, identity)=>{
|
|
586
|
+
const createNodeStagedReleaseArtifactInputs = async (outputDirectory, identity, apiOnly, uiOnly, declaredPublicAssets, shellConsumer)=>{
|
|
587
|
+
const backendProducer = !uiOnly && !shellConsumer;
|
|
450
588
|
const files = await collectFiles(outputDirectory);
|
|
589
|
+
const declaredPublicAssetPaths = resolveDeclaredPublicAssets(files, declaredPublicAssets, 'Node');
|
|
451
590
|
for (const requiredPath of [
|
|
452
591
|
'index.js',
|
|
453
592
|
'package.json',
|
|
454
|
-
|
|
455
|
-
|
|
593
|
+
...backendProducer ? [
|
|
594
|
+
backend_federation_contracts_namespaceObject.BACKEND_FEDERATION_MANIFEST_FILE,
|
|
595
|
+
backend_federation_contracts_namespaceObject.BACKEND_FEDERATION_REMOTE_ENTRY_FILE
|
|
596
|
+
] : []
|
|
456
597
|
])if (!files.includes(requiredPath)) throw new Error(`[ultramodern-release-envelope] final Node staging is missing ${requiredPath}.`);
|
|
457
598
|
const backendFederationPaths = new Set([
|
|
458
599
|
backend_federation_contracts_namespaceObject.BACKEND_FEDERATION_MANIFEST_FILE,
|
|
459
600
|
backend_federation_contracts_namespaceObject.BACKEND_FEDERATION_REMOTE_ENTRY_FILE
|
|
460
601
|
]);
|
|
602
|
+
if (shellConsumer && files.some((logicalPath)=>backendFederationPaths.has(logicalPath))) throw new Error('[ultramodern-release-envelope] final Shell Node staging cannot contain a backend federation producer artifact.');
|
|
461
603
|
const uiClientPaths = files.filter((logicalPath)=>{
|
|
462
604
|
const topLevel = logicalPath.split('/')[0];
|
|
463
|
-
return 'static' === topLevel || 'html' === topLevel || 'public' === topLevel || [
|
|
605
|
+
return 'static' === topLevel || 'html' === topLevel || 'public' === topLevel && logicalPath !== CRAWLER_POLICY_PATH && logicalPath !== PUBLIC_BUILD_ARTIFACT_PATH && !isPublicMetadataPath(logicalPath) && !declaredPublicAssetPaths.has(logicalPath) || [
|
|
464
606
|
'index.html',
|
|
465
607
|
'mf-manifest.json',
|
|
466
608
|
'mf-stats.json',
|
|
@@ -471,6 +613,8 @@ const createNodeStagedReleaseArtifactInputs = async (outputDirectory, identity)=
|
|
|
471
613
|
});
|
|
472
614
|
const ssrPaths = files.filter((logicalPath)=>'index.js' === logicalPath || logicalPath.startsWith('bundles/') && COMPILED_MODULE_PATTERN.test(logicalPath));
|
|
473
615
|
const apiBackendPaths = files.filter((logicalPath)=>(logicalPath.startsWith('api/') || logicalPath.startsWith('shared/')) && COMPILED_MODULE_PATTERN.test(logicalPath));
|
|
616
|
+
if (uiOnly && (apiBackendPaths.length > 0 || files.some((logicalPath)=>backendFederationPaths.has(logicalPath)))) throw new Error('[ultramodern-release-envelope] final UI-only Node staging contains an undeclared API/backend or backend federation artifact.');
|
|
617
|
+
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.');
|
|
474
618
|
for (const [surface, paths] of [
|
|
475
619
|
[
|
|
476
620
|
'UI/client',
|
|
@@ -478,32 +622,45 @@ const createNodeStagedReleaseArtifactInputs = async (outputDirectory, identity)=
|
|
|
478
622
|
],
|
|
479
623
|
[
|
|
480
624
|
'Node SSR',
|
|
481
|
-
ssrPaths
|
|
625
|
+
apiOnly ? [] : ssrPaths
|
|
482
626
|
],
|
|
483
627
|
[
|
|
484
628
|
'Node API/backend',
|
|
485
629
|
apiBackendPaths
|
|
486
630
|
]
|
|
487
|
-
])if (0 === paths.length) throw new Error(`[ultramodern-release-envelope] final Node staging has no ${surface} artifacts.`);
|
|
488
|
-
const clientExecutionPaths = await manifestReferencedClientModules(outputDirectory, files);
|
|
489
|
-
const ssrExecutionPaths = await routeReferencedSsrModules(outputDirectory, files, 'node');
|
|
490
|
-
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.');
|
|
631
|
+
])if (0 === paths.length && ('Node API/backend' === surface ? backendProducer : !apiOnly)) throw new Error(`[ultramodern-release-envelope] final Node staging has no ${surface} artifacts.`);
|
|
632
|
+
const clientExecutionPaths = apiOnly ? [] : await manifestReferencedClientModules(outputDirectory, files);
|
|
633
|
+
const ssrExecutionPaths = apiOnly ? [] : await routeReferencedSsrModules(outputDirectory, files, 'node');
|
|
634
|
+
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.');
|
|
491
635
|
const runtimeByPath = new Map(files.filter((logicalPath)=>!backendFederationPaths.has(logicalPath)).map((logicalPath)=>[
|
|
492
636
|
logicalPath,
|
|
493
637
|
'nodejs-deployment'
|
|
494
638
|
]));
|
|
495
639
|
for (const logicalPath of uiClientPaths)runtimeByPath.set(logicalPath, 'browser');
|
|
496
|
-
for (const logicalPath of
|
|
640
|
+
for (const logicalPath of declaredPublicAssetPaths)runtimeByPath.set(logicalPath, DECLARED_PUBLIC_ASSET_RUNTIME);
|
|
641
|
+
if (files.includes(CRAWLER_POLICY_PATH)) runtimeByPath.set(CRAWLER_POLICY_PATH, 'crawler-policy');
|
|
642
|
+
for (const logicalPath of files.filter(isPublicMetadataPath))runtimeByPath.set(logicalPath, 'public-metadata');
|
|
643
|
+
for (const logicalPath of apiOnly ? [] : ssrPaths)runtimeByPath.set(logicalPath, 'nodejs');
|
|
497
644
|
for (const logicalPath of apiBackendPaths)runtimeByPath.set(logicalPath, 'nodejs');
|
|
498
|
-
|
|
499
|
-
|
|
645
|
+
if (backendProducer) {
|
|
646
|
+
runtimeByPath.set(backend_federation_contracts_namespaceObject.BACKEND_FEDERATION_MANIFEST_FILE, 'module-federation-manifest');
|
|
647
|
+
runtimeByPath.set(backend_federation_contracts_namespaceObject.BACKEND_FEDERATION_REMOTE_ENTRY_FILE, 'nodejs');
|
|
648
|
+
}
|
|
649
|
+
for (const logicalPath of [
|
|
650
|
+
backend_federation_contracts_namespaceObject.ULTRAMODERN_BUILD_ARTIFACT_FILE,
|
|
651
|
+
PUBLIC_BUILD_ARTIFACT_PATH
|
|
652
|
+
])if (files.includes(logicalPath)) runtimeByPath.set(logicalPath, 'release-identity-metadata');
|
|
500
653
|
const identityCarrierMetadata = await writeReleaseIdentityCarrierMetadata(outputDirectory, identity, {
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
654
|
+
...apiBackendPaths.length > 0 ? {
|
|
655
|
+
apiBackend: apiBackendPaths
|
|
656
|
+
} : {},
|
|
657
|
+
...backendProducer ? {
|
|
658
|
+
backendFederation: [
|
|
659
|
+
backend_federation_contracts_namespaceObject.BACKEND_FEDERATION_MANIFEST_FILE,
|
|
660
|
+
backend_federation_contracts_namespaceObject.BACKEND_FEDERATION_REMOTE_ENTRY_FILE
|
|
661
|
+
]
|
|
662
|
+
} : {},
|
|
663
|
+
ssr: apiOnly ? [] : [
|
|
507
664
|
...new Set([
|
|
508
665
|
...ssrExecutionPaths,
|
|
509
666
|
...ssrPaths.filter((logicalPath)=>'index.js' !== logicalPath)
|
|
@@ -522,30 +679,37 @@ const createNodeStagedReleaseArtifactInputs = async (outputDirectory, identity)=
|
|
|
522
679
|
uiClient: [
|
|
523
680
|
...uiClientPaths
|
|
524
681
|
].sort((left, right)=>left.localeCompare(right)),
|
|
525
|
-
ssr: [
|
|
682
|
+
ssr: apiOnly ? [] : [
|
|
526
683
|
...ssrPaths
|
|
527
684
|
].sort((left, right)=>left.localeCompare(right)),
|
|
528
685
|
apiBackend: [
|
|
529
686
|
...apiBackendPaths
|
|
530
687
|
].sort((left, right)=>left.localeCompare(right)),
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
688
|
+
...backendProducer ? {
|
|
689
|
+
backendFederation: {
|
|
690
|
+
manifest: backend_federation_contracts_namespaceObject.BACKEND_FEDERATION_MANIFEST_FILE,
|
|
691
|
+
container: backend_federation_contracts_namespaceObject.BACKEND_FEDERATION_REMOTE_ENTRY_FILE
|
|
692
|
+
}
|
|
693
|
+
} : {}
|
|
535
694
|
}
|
|
536
695
|
};
|
|
537
696
|
};
|
|
538
|
-
const emitNodeStagedReleaseEnvelope = async ({ distDirectory, outputDirectory })=>{
|
|
697
|
+
const emitNodeStagedReleaseEnvelope = async ({ declaredPublicAssets = [], distDirectory, outputDirectory })=>{
|
|
539
698
|
const source = await verifyBuildOutputReleaseEnvelope(distDirectory, 'node');
|
|
540
699
|
if (!source) return;
|
|
541
|
-
const
|
|
700
|
+
const shellConsumer = source.kind === external_types_js_namespaceObject.SHELL_RELEASE_ENVELOPE_KIND;
|
|
701
|
+
const { artifacts, surfaces } = await createNodeStagedReleaseArtifactInputs(outputDirectory, source.identity, 0 === source.surfaces.uiClient.length, 0 === source.surfaces.apiBackend.length, declaredPublicAssets, shellConsumer);
|
|
542
702
|
const staged = await (0, external_index_js_namespaceObject.createMicroVerticalReleaseEnvelope)({
|
|
543
703
|
artifactRoot: outputDirectory,
|
|
544
704
|
target: 'node',
|
|
545
705
|
identity: source.identity,
|
|
706
|
+
...source.ui ? {
|
|
707
|
+
ui: source.ui
|
|
708
|
+
} : {},
|
|
546
709
|
artifacts,
|
|
547
|
-
surfaces
|
|
710
|
+
...releaseEnvelopeSurfaces(surfaces, shellConsumer)
|
|
548
711
|
});
|
|
712
|
+
await verifyBuildArtifactCarriers(outputDirectory, staged);
|
|
549
713
|
await writeReleaseEnvelope(outputDirectory, staged);
|
|
550
714
|
return staged;
|
|
551
715
|
};
|
|
@@ -556,21 +720,29 @@ const stageCloudflareReleaseEnvelope = async ({ distDirectory, outputDirectory }
|
|
|
556
720
|
if (await pathExists(stagedEnvelopePath)) throw new Error('[ultramodern-release-envelope] Cloudflare staging contains a stale envelope before final output generation.');
|
|
557
721
|
return source;
|
|
558
722
|
};
|
|
559
|
-
const createCloudflareStagedReleaseArtifactInputs = async (outputDirectory, identity)=>{
|
|
723
|
+
const createCloudflareStagedReleaseArtifactInputs = async (outputDirectory, identity, apiOnly, uiOnly, declaredPublicAssets, shellConsumer)=>{
|
|
724
|
+
const backendProducer = !uiOnly && !shellConsumer;
|
|
560
725
|
const files = await collectFiles(outputDirectory);
|
|
726
|
+
const declaredPublicAssetPaths = resolveDeclaredPublicAssets(files, declaredPublicAssets, 'Cloudflare');
|
|
561
727
|
for (const requiredPath of [
|
|
562
728
|
'server/index.mjs',
|
|
563
729
|
'server/modern-worker-manifest.json',
|
|
564
730
|
'wrangler.json',
|
|
565
731
|
'package.json',
|
|
566
|
-
|
|
732
|
+
...apiOnly ? [] : [
|
|
733
|
+
'worker/package.json'
|
|
734
|
+
]
|
|
567
735
|
])if (!files.includes(requiredPath)) throw new Error(`[ultramodern-release-envelope] final Cloudflare staging is missing ${requiredPath}.`);
|
|
568
736
|
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.');
|
|
569
737
|
const backendManifestPath = `public/${backend_federation_contracts_namespaceObject.BACKEND_FEDERATION_MANIFEST_FILE}`;
|
|
570
738
|
const backendContainerPath = `public/${backend_federation_contracts_namespaceObject.BACKEND_FEDERATION_REMOTE_ENTRY_FILE}`;
|
|
571
|
-
const apiBackendPaths = files
|
|
572
|
-
|
|
573
|
-
const
|
|
739
|
+
const apiBackendPaths = effectBffWorkerArtifacts(files);
|
|
740
|
+
if (backendProducer && !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.');
|
|
741
|
+
const ssrPaths = files.filter((logicalPath)=>(logicalPath.startsWith('server/') || logicalPath.startsWith('worker/')) && COMPILED_MODULE_PATTERN.test(logicalPath) && !apiBackendPaths.includes(logicalPath));
|
|
742
|
+
const uiClientPaths = files.filter((logicalPath)=>logicalPath.startsWith('public/') && logicalPath !== CRAWLER_POLICY_PATH && !isPublicMetadataPath(logicalPath) && !declaredPublicAssetPaths.has(logicalPath) && logicalPath !== PUBLIC_BUILD_ARTIFACT_PATH && logicalPath !== backendManifestPath && logicalPath !== backendContainerPath);
|
|
743
|
+
if (shellConsumer && files.some((logicalPath)=>logicalPath === backendManifestPath || logicalPath === backendContainerPath)) throw new Error('[ultramodern-release-envelope] final Shell Cloudflare staging cannot contain a backend federation producer artifact.');
|
|
744
|
+
if (uiOnly && (apiBackendPaths.length > 0 || files.some((logicalPath)=>logicalPath === backendManifestPath || logicalPath === backendContainerPath || logicalPath.startsWith('api/') && COMPILED_MODULE_PATTERN.test(logicalPath)))) throw new Error('[ultramodern-release-envelope] final UI-only Cloudflare staging contains an undeclared API/backend or backend federation artifact.');
|
|
745
|
+
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.');
|
|
574
746
|
for (const [surface, paths] of [
|
|
575
747
|
[
|
|
576
748
|
'UI/client',
|
|
@@ -578,41 +750,53 @@ const createCloudflareStagedReleaseArtifactInputs = async (outputDirectory, iden
|
|
|
578
750
|
],
|
|
579
751
|
[
|
|
580
752
|
'Cloudflare SSR',
|
|
581
|
-
ssrPaths
|
|
753
|
+
apiOnly ? [] : ssrPaths
|
|
582
754
|
],
|
|
583
755
|
[
|
|
584
756
|
'Cloudflare API/backend',
|
|
585
757
|
apiBackendPaths
|
|
586
758
|
]
|
|
587
|
-
])if (0 === paths.length) throw new Error(`[ultramodern-release-envelope] final Cloudflare staging has no ${surface} artifacts.`);
|
|
588
|
-
for (const logicalPath of [
|
|
759
|
+
])if (0 === paths.length && ('Cloudflare API/backend' === surface ? backendProducer : !apiOnly)) throw new Error(`[ultramodern-release-envelope] final Cloudflare staging has no ${surface} artifacts.`);
|
|
760
|
+
for (const logicalPath of backendProducer ? [
|
|
589
761
|
backendManifestPath,
|
|
590
762
|
backendContainerPath
|
|
591
|
-
])if (!files.includes(logicalPath)) throw new Error(`[ultramodern-release-envelope] final Cloudflare staging is missing ${logicalPath}.`);
|
|
592
|
-
const clientExecutionPaths = await manifestReferencedClientModules(outputDirectory, files, 'public/mf-manifest.json');
|
|
593
|
-
const ssrExecutionPaths = await routeReferencedSsrModules(outputDirectory, files, 'cloudflare', 'server/route.json');
|
|
594
|
-
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.');
|
|
763
|
+
] : [])if (!files.includes(logicalPath)) throw new Error(`[ultramodern-release-envelope] final Cloudflare staging is missing ${logicalPath}.`);
|
|
764
|
+
const clientExecutionPaths = apiOnly ? [] : await manifestReferencedClientModules(outputDirectory, files, 'public/mf-manifest.json');
|
|
765
|
+
const ssrExecutionPaths = apiOnly ? [] : await routeReferencedSsrModules(outputDirectory, files, 'cloudflare', 'server/route.json');
|
|
766
|
+
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.');
|
|
595
767
|
const runtimeByPath = new Map();
|
|
596
768
|
for (const logicalPath of files)runtimeByPath.set(logicalPath, 'cloudflare-deployment');
|
|
597
769
|
const add = (paths, runtime)=>{
|
|
598
770
|
for (const logicalPath of paths)runtimeByPath.set(logicalPath, runtime);
|
|
599
771
|
};
|
|
600
772
|
add(uiClientPaths, 'browser');
|
|
601
|
-
add(ssrPaths, 'workerd');
|
|
602
|
-
add(apiBackendPaths, 'workerd-effect');
|
|
603
773
|
add([
|
|
604
|
-
|
|
605
|
-
],
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
], '
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
backendManifestPath
|
|
774
|
+
...declaredPublicAssetPaths
|
|
775
|
+
], DECLARED_PUBLIC_ASSET_RUNTIME);
|
|
776
|
+
if (files.includes(CRAWLER_POLICY_PATH)) runtimeByPath.set(CRAWLER_POLICY_PATH, 'crawler-policy');
|
|
777
|
+
add(files.filter(isPublicMetadataPath), 'public-metadata');
|
|
778
|
+
add(apiOnly ? [] : ssrPaths, 'workerd');
|
|
779
|
+
add(apiBackendPaths, 'workerd-effect');
|
|
780
|
+
if (backendProducer) {
|
|
781
|
+
add([
|
|
782
|
+
backendManifestPath
|
|
783
|
+
], 'module-federation-manifest');
|
|
784
|
+
add([
|
|
613
785
|
backendContainerPath
|
|
614
|
-
],
|
|
615
|
-
|
|
786
|
+
], 'commonjs-module');
|
|
787
|
+
}
|
|
788
|
+
add(files.filter((logicalPath)=>logicalPath === backend_federation_contracts_namespaceObject.ULTRAMODERN_BUILD_ARTIFACT_FILE || logicalPath === PUBLIC_BUILD_ARTIFACT_PATH), 'release-identity-metadata');
|
|
789
|
+
const identityCarrierMetadata = await writeReleaseIdentityCarrierMetadata(outputDirectory, identity, {
|
|
790
|
+
...apiBackendPaths.length > 0 ? {
|
|
791
|
+
apiBackend: apiBackendPaths
|
|
792
|
+
} : {},
|
|
793
|
+
...backendProducer ? {
|
|
794
|
+
backendFederation: [
|
|
795
|
+
backendManifestPath,
|
|
796
|
+
backendContainerPath
|
|
797
|
+
]
|
|
798
|
+
} : {},
|
|
799
|
+
ssr: apiOnly ? [] : [
|
|
616
800
|
...new Set([
|
|
617
801
|
...ssrExecutionPaths,
|
|
618
802
|
...ssrPaths.filter((logicalPath)=>logicalPath.startsWith('worker/'))
|
|
@@ -631,30 +815,37 @@ const createCloudflareStagedReleaseArtifactInputs = async (outputDirectory, iden
|
|
|
631
815
|
uiClient: [
|
|
632
816
|
...uiClientPaths
|
|
633
817
|
].sort((left, right)=>left.localeCompare(right)),
|
|
634
|
-
ssr: [
|
|
818
|
+
ssr: apiOnly ? [] : [
|
|
635
819
|
...ssrPaths
|
|
636
820
|
].sort((left, right)=>left.localeCompare(right)),
|
|
637
821
|
apiBackend: [
|
|
638
822
|
...apiBackendPaths
|
|
639
823
|
].sort((left, right)=>left.localeCompare(right)),
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
824
|
+
...backendProducer ? {
|
|
825
|
+
backendFederation: {
|
|
826
|
+
manifest: backendManifestPath,
|
|
827
|
+
container: backendContainerPath
|
|
828
|
+
}
|
|
829
|
+
} : {}
|
|
644
830
|
}
|
|
645
831
|
};
|
|
646
832
|
};
|
|
647
|
-
const emitCloudflareStagedReleaseEnvelope = async ({ distDirectory, outputDirectory })=>{
|
|
833
|
+
const emitCloudflareStagedReleaseEnvelope = async ({ declaredPublicAssets = [], distDirectory, outputDirectory })=>{
|
|
648
834
|
const source = await verifyBuildOutputReleaseEnvelope(distDirectory, 'cloudflare');
|
|
649
835
|
if (!source) return;
|
|
650
|
-
const
|
|
836
|
+
const shellConsumer = source.kind === external_types_js_namespaceObject.SHELL_RELEASE_ENVELOPE_KIND;
|
|
837
|
+
const { artifacts, surfaces } = await createCloudflareStagedReleaseArtifactInputs(outputDirectory, source.identity, 0 === source.surfaces.uiClient.length, 0 === source.surfaces.apiBackend.length, declaredPublicAssets, shellConsumer);
|
|
651
838
|
const staged = await (0, external_index_js_namespaceObject.createMicroVerticalReleaseEnvelope)({
|
|
652
839
|
artifactRoot: outputDirectory,
|
|
653
840
|
target: 'cloudflare',
|
|
654
841
|
identity: source.identity,
|
|
842
|
+
...source.ui ? {
|
|
843
|
+
ui: source.ui
|
|
844
|
+
} : {},
|
|
655
845
|
artifacts,
|
|
656
|
-
surfaces
|
|
846
|
+
...releaseEnvelopeSurfaces(surfaces, shellConsumer)
|
|
657
847
|
});
|
|
848
|
+
await verifyBuildArtifactCarriers(outputDirectory, staged);
|
|
658
849
|
await writeReleaseEnvelope(outputDirectory, staged);
|
|
659
850
|
return staged;
|
|
660
851
|
};
|