@bleedingdev/modern-js-app-tools-extensions 3.9.0-ultramodern.9 → 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 +130 -13
- package/dist/cjs/policy-defaults.js +38 -29
- 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/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 +124 -13
- package/dist/esm/policy-defaults.mjs +36 -30
- 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/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 +124 -13
- package/dist/esm-node/policy-defaults.mjs +36 -30
- 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/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 +12 -2
- 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/templates/cloudflare-worker-route-data.d.mts +14 -0
- package/dist/types/workspace-topology.d.ts +91 -0
- package/package.json +87 -27
- 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 +233 -20
- package/src/policy-defaults.ts +47 -17
- 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/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
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
2
|
import { fs as fse } from '@modern-js/utils';
|
|
3
|
-
import type {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
import type { CloudflareWorkerArtifactConfig } from '../config';
|
|
4
|
+
import {
|
|
5
|
+
CLOUDFLARE_PUBLIC_ASSET_SCOPE,
|
|
6
|
+
normalizeDeclaredPublicAssets,
|
|
7
|
+
stageDeclaredPublicAssets,
|
|
8
|
+
} from '../deploy-output/public-assets';
|
|
7
9
|
import {
|
|
8
10
|
RESERVED_ARTIFACT_DESTINATION_DIRECTORIES,
|
|
9
11
|
RESERVED_ARTIFACT_DESTINATION_FILES,
|
|
@@ -54,34 +56,12 @@ export const getCloudflareArtifacts = (modernConfig: CloudflareModernConfig) =>
|
|
|
54
56
|
normalizeCloudflareArtifact,
|
|
55
57
|
);
|
|
56
58
|
|
|
57
|
-
const normalizeCloudflarePublicAsset = (
|
|
58
|
-
asset: CloudflareWorkerPublicAssetConfig,
|
|
59
|
-
index: number,
|
|
60
|
-
) => {
|
|
61
|
-
const from = normalizeRelativePath(
|
|
62
|
-
asset.from,
|
|
63
|
-
`deploy.worker.publicAssets[${index}].from`,
|
|
64
|
-
'app root',
|
|
65
|
-
);
|
|
66
|
-
const to = normalizeRelativePath(
|
|
67
|
-
asset.to,
|
|
68
|
-
`deploy.worker.publicAssets[${index}].to`,
|
|
69
|
-
'Cloudflare public output',
|
|
70
|
-
{ allowRoot: true },
|
|
71
|
-
);
|
|
72
|
-
|
|
73
|
-
return {
|
|
74
|
-
from,
|
|
75
|
-
to,
|
|
76
|
-
index,
|
|
77
|
-
};
|
|
78
|
-
};
|
|
79
|
-
|
|
80
59
|
export const getCloudflarePublicAssets = (
|
|
81
60
|
modernConfig: CloudflareModernConfig,
|
|
82
61
|
) =>
|
|
83
|
-
(
|
|
84
|
-
|
|
62
|
+
normalizeDeclaredPublicAssets(
|
|
63
|
+
modernConfig.deploy?.worker?.publicAssets,
|
|
64
|
+
CLOUDFLARE_PUBLIC_ASSET_SCOPE,
|
|
85
65
|
);
|
|
86
66
|
|
|
87
67
|
export const copyCloudflareArtifacts = async (
|
|
@@ -102,23 +82,22 @@ export const copyCloudflareArtifacts = async (
|
|
|
102
82
|
}
|
|
103
83
|
};
|
|
104
84
|
|
|
85
|
+
/**
|
|
86
|
+
* Stage `deploy.worker.publicAssets` into Worker Static Assets.
|
|
87
|
+
*
|
|
88
|
+
* @returns the staged files relative to the Cloudflare output root.
|
|
89
|
+
*/
|
|
105
90
|
export const copyCloudflarePublicAssets = async (
|
|
106
91
|
appDirectory: string,
|
|
107
|
-
|
|
92
|
+
outputDirectory: string,
|
|
108
93
|
publicAssets: ReturnType<typeof getCloudflarePublicAssets>,
|
|
109
|
-
) =>
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
);
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
await fse.copy(sourcePath, path.join(publicDirectory, asset.to));
|
|
120
|
-
}
|
|
121
|
-
};
|
|
94
|
+
) =>
|
|
95
|
+
stageDeclaredPublicAssets({
|
|
96
|
+
appDirectory,
|
|
97
|
+
outputDirectory,
|
|
98
|
+
assets: publicAssets,
|
|
99
|
+
scope: CLOUDFLARE_PUBLIC_ASSET_SCOPE,
|
|
100
|
+
});
|
|
122
101
|
|
|
123
102
|
export const copyCloudflareD1Migrations = async (
|
|
124
103
|
appDirectory: string,
|
|
@@ -1,26 +1,79 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
|
+
import { isDeepStrictEqual } from 'node:util';
|
|
2
3
|
import {
|
|
4
|
+
assertRendererProfileCompatibility,
|
|
5
|
+
assertUltramodernBuildArtifact,
|
|
3
6
|
type DeliveryUnitIdentity,
|
|
4
|
-
|
|
7
|
+
formatBackendFederationValidationErrors,
|
|
8
|
+
immutableRendererRouterBindings,
|
|
5
9
|
nonEmptyString,
|
|
10
|
+
type RendererIdentity,
|
|
11
|
+
type RendererProfile,
|
|
12
|
+
type RendererRouterBindings,
|
|
6
13
|
toDeliveryUnitIdentity,
|
|
14
|
+
ULTRAMODERN_BUILD_ARTIFACT_FILE,
|
|
7
15
|
ULTRAMODERN_BUILD_ARTIFACT_PATH,
|
|
16
|
+
validateRendererIdentity,
|
|
17
|
+
validateRendererProfile,
|
|
18
|
+
validateRendererRouterBindings,
|
|
8
19
|
} from '@modern-js/backend-federation-contracts';
|
|
9
20
|
import { fs as fse } from '@modern-js/utils';
|
|
10
21
|
import { resolveUltramodernReleaseIdentity } from '../release-identity';
|
|
11
22
|
import { isRecord } from './utils';
|
|
12
23
|
|
|
13
|
-
const
|
|
24
|
+
const TOPOLOGY_PATH = 'topology/reference-topology.json';
|
|
14
25
|
|
|
15
26
|
export type DeliveryUnitStamp = DeliveryUnitIdentity & {
|
|
16
27
|
surfaces: {
|
|
17
|
-
ui?: DeliveryUnitIdentity & {
|
|
28
|
+
ui?: DeliveryUnitIdentity & {
|
|
29
|
+
surface: 'ui';
|
|
30
|
+
rendererIdentity: RendererIdentity;
|
|
31
|
+
rendererProfile: RendererProfile;
|
|
32
|
+
routerBindings: RendererRouterBindings;
|
|
33
|
+
};
|
|
18
34
|
api?: DeliveryUnitIdentity & { surface: 'api' };
|
|
19
35
|
};
|
|
20
36
|
};
|
|
21
37
|
|
|
22
|
-
|
|
38
|
+
/**
|
|
39
|
+
* The topology's declaration of one delivery unit. A UI surface may omit the
|
|
40
|
+
* renderer projection entirely (a React workspace authored before renderer
|
|
41
|
+
* selection); the build then resolves its renderer identity from the app
|
|
42
|
+
* config alone, and there is no declared projection to verify it against.
|
|
43
|
+
*/
|
|
44
|
+
export type TopologyUiSurface = DeliveryUnitIdentity & { surface: 'ui' } & (
|
|
45
|
+
| {
|
|
46
|
+
rendererIdentity: RendererIdentity;
|
|
47
|
+
rendererProfile: RendererProfile;
|
|
48
|
+
routerBindings: RendererRouterBindings;
|
|
49
|
+
}
|
|
50
|
+
| {
|
|
51
|
+
rendererIdentity?: undefined;
|
|
52
|
+
rendererProfile?: undefined;
|
|
53
|
+
routerBindings?: undefined;
|
|
54
|
+
}
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
export type TopologyDeliveryUnit = DeliveryUnitIdentity & {
|
|
58
|
+
/** The declaring topology app. */
|
|
59
|
+
appId: string;
|
|
60
|
+
surfaces: {
|
|
61
|
+
ui?: TopologyUiSurface;
|
|
62
|
+
api?: DeliveryUnitIdentity & { surface: 'api' };
|
|
63
|
+
};
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
const RENDERER_PROJECTION_FIELDS = [
|
|
67
|
+
'renderer',
|
|
68
|
+
'rendererIdentity',
|
|
69
|
+
'rendererIdentities',
|
|
70
|
+
'rendererProfile',
|
|
71
|
+
'routerBindings',
|
|
72
|
+
] as const;
|
|
73
|
+
|
|
74
|
+
type TopologyAppResolution = {
|
|
23
75
|
app?: Record<string, unknown>;
|
|
76
|
+
role: 'microvertical' | 'shell';
|
|
24
77
|
workspaceRoot: string;
|
|
25
78
|
};
|
|
26
79
|
|
|
@@ -30,7 +83,7 @@ const findWorkspaceRoot = async (
|
|
|
30
83
|
let current = path.resolve(appDirectory);
|
|
31
84
|
|
|
32
85
|
for (;;) {
|
|
33
|
-
if (await fse.pathExists(path.join(current,
|
|
86
|
+
if (await fse.pathExists(path.join(current, TOPOLOGY_PATH))) {
|
|
34
87
|
return current;
|
|
35
88
|
}
|
|
36
89
|
|
|
@@ -60,34 +113,32 @@ const stampReleaseIdentity = (
|
|
|
60
113
|
};
|
|
61
114
|
};
|
|
62
115
|
|
|
63
|
-
const
|
|
116
|
+
const resolveTopologyApp = async (
|
|
64
117
|
appDirectory: string,
|
|
65
|
-
): Promise<
|
|
118
|
+
): Promise<TopologyAppResolution | undefined> => {
|
|
66
119
|
const workspaceRoot = await findWorkspaceRoot(appDirectory);
|
|
67
120
|
if (!workspaceRoot) {
|
|
68
121
|
return undefined;
|
|
69
122
|
}
|
|
70
123
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
124
|
+
const topology: unknown = await fse.readJSON(
|
|
125
|
+
path.join(workspaceRoot, TOPOLOGY_PATH),
|
|
126
|
+
);
|
|
127
|
+
if (
|
|
128
|
+
!isRecord(topology) ||
|
|
129
|
+
!isRecord(topology.shell) ||
|
|
130
|
+
!Array.isArray(topology.verticals) ||
|
|
131
|
+
(topology.shells !== undefined && !Array.isArray(topology.shells))
|
|
132
|
+
) {
|
|
133
|
+
throw new Error(
|
|
134
|
+
'[cloudflare-delivery-unit] Invalid declared reference topology.',
|
|
75
135
|
);
|
|
76
|
-
} catch {
|
|
77
|
-
return { workspaceRoot };
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
if (!isRecord(compactConfig)) {
|
|
81
|
-
return { workspaceRoot };
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
const topology = isRecord(compactConfig.topology)
|
|
85
|
-
? compactConfig.topology
|
|
86
|
-
: undefined;
|
|
87
|
-
const apps = Array.isArray(topology?.apps) ? topology.apps : undefined;
|
|
88
|
-
if (!apps) {
|
|
89
|
-
return { app: compactConfig, workspaceRoot };
|
|
90
136
|
}
|
|
137
|
+
const apps = [
|
|
138
|
+
topology.shell,
|
|
139
|
+
...topology.verticals,
|
|
140
|
+
...(Array.isArray(topology.shells) ? topology.shells : []),
|
|
141
|
+
];
|
|
91
142
|
|
|
92
143
|
const resolvedAppDirectory = path.resolve(appDirectory);
|
|
93
144
|
const app = apps.find(candidate => {
|
|
@@ -101,24 +152,122 @@ const resolveCompactApp = async (
|
|
|
101
152
|
resolvedAppDirectory
|
|
102
153
|
);
|
|
103
154
|
});
|
|
155
|
+
if (!isRecord(app)) {
|
|
156
|
+
throw new Error(
|
|
157
|
+
`[cloudflare-delivery-unit] ${appDirectory} is missing from the declared reference topology.`,
|
|
158
|
+
);
|
|
159
|
+
}
|
|
104
160
|
return {
|
|
105
|
-
|
|
161
|
+
app,
|
|
162
|
+
role:
|
|
163
|
+
app === topology.shell ||
|
|
164
|
+
(Array.isArray(topology.shells) && topology.shells.includes(app))
|
|
165
|
+
? 'shell'
|
|
166
|
+
: 'microvertical',
|
|
106
167
|
workspaceRoot,
|
|
107
168
|
};
|
|
108
169
|
};
|
|
109
170
|
|
|
110
|
-
|
|
171
|
+
/** Resolve the producer role from this app's authoritative topology membership. */
|
|
172
|
+
export const resolveTopologyReleaseRole = async (
|
|
173
|
+
appDirectory: string,
|
|
174
|
+
): Promise<'microvertical' | 'shell' | undefined> => {
|
|
175
|
+
const resolved = await resolveTopologyApp(appDirectory);
|
|
176
|
+
if (!resolved?.app) return undefined;
|
|
177
|
+
const kind = resolved.role === 'shell' ? 'shell' : 'vertical';
|
|
178
|
+
if (resolved.app.kind !== kind) {
|
|
179
|
+
throw new Error(
|
|
180
|
+
'[cloudflare-delivery-unit] Declared app kind disagrees with its topology membership.',
|
|
181
|
+
);
|
|
182
|
+
}
|
|
183
|
+
return resolved.role;
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
const createTopologyDeliveryUnitStamp = (
|
|
111
187
|
identity: DeliveryUnitIdentity,
|
|
112
|
-
app
|
|
113
|
-
):
|
|
114
|
-
const surfaceProfile = nonEmptyString(app
|
|
188
|
+
app: Record<string, unknown>,
|
|
189
|
+
): TopologyDeliveryUnit => {
|
|
190
|
+
const surfaceProfile = nonEmptyString(app.surfaceProfile);
|
|
191
|
+
if (
|
|
192
|
+
surfaceProfile !== undefined &&
|
|
193
|
+
!['api-only', 'ui-only', 'full-stack'].includes(surfaceProfile)
|
|
194
|
+
) {
|
|
195
|
+
throw new Error(
|
|
196
|
+
'[cloudflare-delivery-unit] Declared app has an invalid surface profile.',
|
|
197
|
+
);
|
|
198
|
+
}
|
|
115
199
|
const emitsUi = surfaceProfile !== 'api-only';
|
|
116
200
|
const emitsApi = surfaceProfile !== 'ui-only';
|
|
201
|
+
const appId = nonEmptyString(app.id);
|
|
202
|
+
if (!appId)
|
|
203
|
+
throw new Error('[cloudflare-delivery-unit] Declared app requires an id.');
|
|
204
|
+
let ui: TopologyUiSurface | undefined;
|
|
205
|
+
if (emitsUi) {
|
|
206
|
+
if (RENDERER_PROJECTION_FIELDS.every(field => !Object.hasOwn(app, field))) {
|
|
207
|
+
ui = { ...identity, surface: 'ui' };
|
|
208
|
+
} else {
|
|
209
|
+
const routerBindings = isRecord(app.routerBindings)
|
|
210
|
+
? app.routerBindings
|
|
211
|
+
: {};
|
|
212
|
+
const errors = [
|
|
213
|
+
...validateRendererIdentity(app.rendererIdentity).errors,
|
|
214
|
+
...validateRendererProfile(app.rendererProfile).errors,
|
|
215
|
+
...validateRendererRouterBindings(
|
|
216
|
+
app.routerBindings,
|
|
217
|
+
Object.keys(routerBindings),
|
|
218
|
+
'routerBindings',
|
|
219
|
+
).errors,
|
|
220
|
+
];
|
|
221
|
+
if (errors.length) {
|
|
222
|
+
throw new Error(
|
|
223
|
+
`[cloudflare-delivery-unit] ${formatBackendFederationValidationErrors(errors)}`,
|
|
224
|
+
);
|
|
225
|
+
}
|
|
226
|
+
const rendererIdentity = app.rendererIdentity as RendererIdentity;
|
|
227
|
+
const rendererProfile = app.rendererProfile as RendererProfile;
|
|
228
|
+
if (!Object.hasOwn(routerBindings, rendererIdentity.entryName))
|
|
229
|
+
throw new Error(
|
|
230
|
+
'[cloudflare-delivery-unit] Topology routerBindings must include the primary renderer identity entry.',
|
|
231
|
+
);
|
|
232
|
+
const declaredIdentity = toDeliveryUnitIdentity(app.deliveryUnit);
|
|
233
|
+
if (
|
|
234
|
+
rendererIdentity.renderer !== app.renderer ||
|
|
235
|
+
rendererIdentity.renderer !== rendererProfile.renderer ||
|
|
236
|
+
rendererIdentity.appId !== app.id ||
|
|
237
|
+
rendererIdentity.buildId !== declaredIdentity?.buildMarker
|
|
238
|
+
) {
|
|
239
|
+
throw new Error(
|
|
240
|
+
'[cloudflare-delivery-unit] Topology UI renderer metadata must match its app and delivery-unit identity.',
|
|
241
|
+
);
|
|
242
|
+
}
|
|
243
|
+
ui = {
|
|
244
|
+
...identity,
|
|
245
|
+
surface: 'ui',
|
|
246
|
+
rendererIdentity: {
|
|
247
|
+
...rendererIdentity,
|
|
248
|
+
buildId: identity.buildMarker,
|
|
249
|
+
},
|
|
250
|
+
rendererProfile,
|
|
251
|
+
routerBindings: immutableRendererRouterBindings(
|
|
252
|
+
routerBindings as RendererRouterBindings,
|
|
253
|
+
),
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
} else if (
|
|
257
|
+
app.rendererIdentity !== undefined ||
|
|
258
|
+
app.rendererProfile !== undefined ||
|
|
259
|
+
app.routerBindings !== undefined
|
|
260
|
+
) {
|
|
261
|
+
throw new Error(
|
|
262
|
+
'[cloudflare-delivery-unit] API-only topology must not declare a UI renderer identity or profile.',
|
|
263
|
+
);
|
|
264
|
+
}
|
|
117
265
|
|
|
118
266
|
return {
|
|
119
267
|
...identity,
|
|
268
|
+
appId,
|
|
120
269
|
surfaces: {
|
|
121
|
-
...(
|
|
270
|
+
...(ui ? { ui } : {}),
|
|
122
271
|
...(emitsApi ? { api: { ...identity, surface: 'api' as const } } : {}),
|
|
123
272
|
},
|
|
124
273
|
};
|
|
@@ -126,53 +275,127 @@ const createDeliveryUnitStamp = (
|
|
|
126
275
|
|
|
127
276
|
/**
|
|
128
277
|
* Resolve the delivery-unit record declared for this app by the workspace
|
|
129
|
-
*
|
|
278
|
+
* reference topology. This is the topology source
|
|
130
279
|
* of truth the Cloudflare worker snapshot is verified against.
|
|
131
280
|
*/
|
|
132
281
|
export const resolveTopologyDeliveryUnit = async (
|
|
133
282
|
appDirectory: string,
|
|
134
|
-
): Promise<
|
|
135
|
-
const resolved = await
|
|
283
|
+
): Promise<TopologyDeliveryUnit | undefined> => {
|
|
284
|
+
const resolved = await resolveTopologyApp(appDirectory);
|
|
136
285
|
if (!resolved?.app) {
|
|
137
286
|
return undefined;
|
|
138
287
|
}
|
|
139
288
|
const identity = toDeliveryUnitIdentity(resolved.app.deliveryUnit);
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
289
|
+
if (!identity) {
|
|
290
|
+
throw new Error(
|
|
291
|
+
'[cloudflare-delivery-unit] Declared app is missing a valid delivery-unit identity.',
|
|
292
|
+
);
|
|
293
|
+
}
|
|
294
|
+
return createTopologyDeliveryUnitStamp(
|
|
295
|
+
stampReleaseIdentity(identity, resolved.workspaceRoot),
|
|
296
|
+
resolved.app,
|
|
297
|
+
);
|
|
146
298
|
};
|
|
147
299
|
|
|
148
300
|
/**
|
|
149
|
-
*
|
|
150
|
-
*
|
|
151
|
-
* worker snapshot / declared surface source that gets stamped into the manifest.
|
|
301
|
+
* Preserve the finalized build artifact already stamped from renderer-build.json.
|
|
302
|
+
* The generation artifact cannot attest the compiled application.
|
|
152
303
|
*/
|
|
153
304
|
export const resolveWorkerDeliveryUnitStamp = async (
|
|
154
305
|
appDirectory: string,
|
|
306
|
+
distDirectory: string,
|
|
155
307
|
): Promise<DeliveryUnitStamp | undefined> => {
|
|
156
308
|
const buildArtifactPath = path.join(
|
|
157
|
-
|
|
158
|
-
|
|
309
|
+
distDirectory,
|
|
310
|
+
ULTRAMODERN_BUILD_ARTIFACT_FILE,
|
|
159
311
|
);
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
if (!identity) {
|
|
312
|
+
if (!(await fse.pathExists(buildArtifactPath))) {
|
|
313
|
+
if (
|
|
314
|
+
await fse.pathExists(
|
|
315
|
+
path.join(appDirectory, ULTRAMODERN_BUILD_ARTIFACT_PATH),
|
|
316
|
+
)
|
|
317
|
+
)
|
|
318
|
+
throw new Error(
|
|
319
|
+
'[cloudflare-delivery-unit] Finalized build artifact is required before worker output stamping.',
|
|
320
|
+
);
|
|
171
321
|
return undefined;
|
|
172
322
|
}
|
|
173
|
-
const
|
|
174
|
-
|
|
175
|
-
|
|
323
|
+
const artifact: unknown = await fse.readJSON(buildArtifactPath);
|
|
324
|
+
assertUltramodernBuildArtifact(artifact);
|
|
325
|
+
const identity: DeliveryUnitIdentity = {
|
|
326
|
+
unitId: artifact.deliveryUnit.unitId,
|
|
327
|
+
buildMarker: artifact.deliveryUnit.buildMarker,
|
|
328
|
+
sourceRevision: artifact.deliveryUnit.sourceRevision,
|
|
329
|
+
};
|
|
330
|
+
const resolved = await resolveTopologyApp(appDirectory);
|
|
331
|
+
const stampedArtifact = artifact;
|
|
332
|
+
let emitsApi = true;
|
|
333
|
+
if (resolved?.app) {
|
|
334
|
+
if (stampedArtifact.deliveryUnit.appId !== resolved.app.id) {
|
|
335
|
+
throw new Error(
|
|
336
|
+
'[cloudflare-delivery-unit] Build artifact appId must match the declared topology app.',
|
|
337
|
+
);
|
|
338
|
+
}
|
|
339
|
+
const declaredIdentity = toDeliveryUnitIdentity(resolved.app.deliveryUnit);
|
|
340
|
+
if (!declaredIdentity) {
|
|
341
|
+
throw new Error(
|
|
342
|
+
'[cloudflare-delivery-unit] Declared app is missing a valid delivery-unit identity.',
|
|
343
|
+
);
|
|
344
|
+
}
|
|
345
|
+
const expected = createTopologyDeliveryUnitStamp(identity, resolved.app);
|
|
346
|
+
for (const field of ['unitId'] as const) {
|
|
347
|
+
if (declaredIdentity[field] !== identity[field]) {
|
|
348
|
+
throw new Error(
|
|
349
|
+
`[cloudflare-delivery-unit] Build artifact ${field} must match the declared topology delivery-unit identity.`,
|
|
350
|
+
);
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
const ui = stampedArtifact.surfaces.ui;
|
|
354
|
+
if (Boolean(expected.surfaces.ui) !== Boolean(ui)) {
|
|
355
|
+
throw new Error(
|
|
356
|
+
'[cloudflare-delivery-unit] Build artifact UI surface must match the declared topology surface profile.',
|
|
357
|
+
);
|
|
358
|
+
}
|
|
359
|
+
if (expected.surfaces.ui?.rendererIdentity && ui) {
|
|
360
|
+
if (
|
|
361
|
+
!isDeepStrictEqual(
|
|
362
|
+
expected.surfaces.ui.routerBindings,
|
|
363
|
+
ui.routerBindings,
|
|
364
|
+
)
|
|
365
|
+
)
|
|
366
|
+
throw new Error(
|
|
367
|
+
'[cloudflare-delivery-unit] Finalized build routerBindings must match the declared topology router bindings.',
|
|
368
|
+
);
|
|
369
|
+
for (const field of [
|
|
370
|
+
'renderer',
|
|
371
|
+
'appId',
|
|
372
|
+
'entryName',
|
|
373
|
+
'protocolVersion',
|
|
374
|
+
'buildId',
|
|
375
|
+
] as const) {
|
|
376
|
+
if (
|
|
377
|
+
expected.surfaces.ui.rendererIdentity[field] !==
|
|
378
|
+
ui.rendererIdentity[field]
|
|
379
|
+
) {
|
|
380
|
+
throw new Error(
|
|
381
|
+
`[cloudflare-delivery-unit] Build artifact UI rendererIdentity.${field} must match the declared topology renderer identity.`,
|
|
382
|
+
);
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
assertRendererProfileCompatibility(
|
|
386
|
+
expected.surfaces.ui.rendererProfile,
|
|
387
|
+
ui.rendererProfile,
|
|
388
|
+
);
|
|
389
|
+
}
|
|
390
|
+
emitsApi = expected.surfaces.api !== undefined;
|
|
176
391
|
}
|
|
177
|
-
return
|
|
392
|
+
return {
|
|
393
|
+
...stampedArtifact.deliveryUnit,
|
|
394
|
+
surfaces: {
|
|
395
|
+
...(emitsApi ? { api: stampedArtifact.surfaces.api } : {}),
|
|
396
|
+
...(stampedArtifact.surfaces.ui
|
|
397
|
+
? { ui: stampedArtifact.surfaces.ui }
|
|
398
|
+
: {}),
|
|
399
|
+
},
|
|
400
|
+
};
|
|
178
401
|
};
|
package/src/cloudflare/index.ts
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
|
+
import {
|
|
3
|
+
BACKEND_FEDERATION_MANIFEST_FILE,
|
|
4
|
+
BACKEND_FEDERATION_REMOTE_ENTRY_FILE,
|
|
5
|
+
ULTRAMODERN_BUILD_ARTIFACT_FILE,
|
|
6
|
+
} from '@modern-js/backend-federation-contracts';
|
|
2
7
|
import { fs as fse } from '@modern-js/utils';
|
|
3
8
|
import { createCloudflareOutputPlan } from '../cloudflare-output-plan';
|
|
4
9
|
import { assertCloudflareOutput } from '../cloudflare-output-verifier/index';
|
|
@@ -22,14 +27,8 @@ import {
|
|
|
22
27
|
ROUTE_SPEC_FILE,
|
|
23
28
|
ROUTE_SPEC_OUTPUT,
|
|
24
29
|
WORKER_BUNDLE_DIRECTORY,
|
|
25
|
-
WORKER_ENTRY,
|
|
26
|
-
WORKER_MANIFEST,
|
|
27
|
-
WRANGLER_CONFIG_FILE,
|
|
28
30
|
} from './constants';
|
|
29
|
-
import {
|
|
30
|
-
resolveTopologyDeliveryUnit,
|
|
31
|
-
resolveWorkerDeliveryUnitStamp,
|
|
32
|
-
} from './delivery-unit';
|
|
31
|
+
import { resolveWorkerDeliveryUnitStamp } from './delivery-unit';
|
|
33
32
|
import type { CreateCloudflarePreset } from './types';
|
|
34
33
|
import {
|
|
35
34
|
createWorkerManifest,
|
|
@@ -87,21 +86,19 @@ export const createCloudflarePreset: CreateCloudflarePreset = ({
|
|
|
87
86
|
'@modern-js/ultramodern-release-envelope',
|
|
88
87
|
);
|
|
89
88
|
let hasReleaseEnvelope = false;
|
|
89
|
+
let declaredPublicAssets: string[] = [];
|
|
90
90
|
|
|
91
91
|
return {
|
|
92
92
|
async prepare() {
|
|
93
93
|
await fse.remove(outputDirectory);
|
|
94
94
|
},
|
|
95
95
|
async writeOutput() {
|
|
96
|
-
if (
|
|
97
|
-
releaseEnvelopeEnabled &&
|
|
98
|
-
(await fse.pathExists(
|
|
99
|
-
path.join(distDirectory, MICROVERTICAL_RELEASE_ENVELOPE_PATH),
|
|
100
|
-
))
|
|
101
|
-
) {
|
|
96
|
+
if (releaseEnvelopeEnabled) {
|
|
102
97
|
await emitFrameworkMicroVerticalReleaseEnvelope({
|
|
103
98
|
apiOnly,
|
|
99
|
+
appDirectory,
|
|
104
100
|
distDirectory,
|
|
101
|
+
role: modernConfig.deploy?.releaseEnvelopeRole,
|
|
105
102
|
target: 'cloudflare',
|
|
106
103
|
});
|
|
107
104
|
}
|
|
@@ -113,6 +110,20 @@ export const createCloudflarePreset: CreateCloudflarePreset = ({
|
|
|
113
110
|
const relativePath = path
|
|
114
111
|
.relative(distDirectory, src)
|
|
115
112
|
.replace(/\\/gu, '/');
|
|
113
|
+
// API-only builds emit server modules at arbitrary paths under dist,
|
|
114
|
+
// including transitive imports outside api/. Only the framework's
|
|
115
|
+
// published backend contract belongs beside the explicit public tree.
|
|
116
|
+
if (
|
|
117
|
+
apiOnly &&
|
|
118
|
+
relativePath !== '' &&
|
|
119
|
+
![
|
|
120
|
+
BACKEND_FEDERATION_MANIFEST_FILE,
|
|
121
|
+
BACKEND_FEDERATION_REMOTE_ENTRY_FILE,
|
|
122
|
+
ULTRAMODERN_BUILD_ARTIFACT_FILE,
|
|
123
|
+
].includes(relativePath)
|
|
124
|
+
) {
|
|
125
|
+
return false;
|
|
126
|
+
}
|
|
116
127
|
return (
|
|
117
128
|
relativePath !== 'release' &&
|
|
118
129
|
!relativePath.startsWith('release/') &&
|
|
@@ -173,9 +184,9 @@ export const createCloudflarePreset: CreateCloudflarePreset = ({
|
|
|
173
184
|
outputDirectory,
|
|
174
185
|
cloudflareArtifacts,
|
|
175
186
|
);
|
|
176
|
-
await copyCloudflarePublicAssets(
|
|
187
|
+
declaredPublicAssets = await copyCloudflarePublicAssets(
|
|
177
188
|
appDirectory,
|
|
178
|
-
|
|
189
|
+
outputDirectory,
|
|
179
190
|
getCloudflarePublicAssets(modernConfig),
|
|
180
191
|
);
|
|
181
192
|
await copyCloudflareD1Migrations(
|
|
@@ -192,8 +203,10 @@ export const createCloudflarePreset: CreateCloudflarePreset = ({
|
|
|
192
203
|
},
|
|
193
204
|
);
|
|
194
205
|
|
|
195
|
-
const deliveryUnitStamp =
|
|
196
|
-
|
|
206
|
+
const deliveryUnitStamp = await resolveWorkerDeliveryUnitStamp(
|
|
207
|
+
appDirectory,
|
|
208
|
+
distDirectory,
|
|
209
|
+
);
|
|
197
210
|
await fse.writeJSON(
|
|
198
211
|
workerManifestPath,
|
|
199
212
|
await createWorkerManifest(
|
|
@@ -232,8 +245,10 @@ export const createCloudflarePreset: CreateCloudflarePreset = ({
|
|
|
232
245
|
createWorkerModuleLoaders(manifest),
|
|
233
246
|
),
|
|
234
247
|
);
|
|
235
|
-
const topologyDeliveryUnit =
|
|
236
|
-
|
|
248
|
+
const topologyDeliveryUnit = await resolveWorkerDeliveryUnitStamp(
|
|
249
|
+
appDirectory,
|
|
250
|
+
distDirectory,
|
|
251
|
+
);
|
|
237
252
|
await assertCloudflareOutput({
|
|
238
253
|
outputDirectory,
|
|
239
254
|
importWorker: false,
|
|
@@ -241,6 +256,7 @@ export const createCloudflarePreset: CreateCloudflarePreset = ({
|
|
|
241
256
|
});
|
|
242
257
|
if (hasReleaseEnvelope) {
|
|
243
258
|
await emitCloudflareStagedReleaseEnvelope({
|
|
259
|
+
declaredPublicAssets,
|
|
244
260
|
distDirectory,
|
|
245
261
|
outputDirectory,
|
|
246
262
|
});
|