@bleedingdev/modern-js-create 3.5.0-ultramodern.28 → 3.5.0-ultramodern.29
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/ultramodern-tooling/commands.cjs +497 -155
- package/dist/cjs/ultramodern-tooling/config.cjs +149 -8
- package/dist/cjs/ultramodern-workspace/add-vertical.cjs +25 -0
- package/dist/cjs/ultramodern-workspace/api.cjs +44 -0
- package/dist/cjs/ultramodern-workspace/backend-federation.cjs +282 -0
- package/dist/cjs/ultramodern-workspace/contracts.cjs +24 -8
- package/dist/cjs/ultramodern-workspace/delivery-unit-sync.cjs +157 -0
- package/dist/cjs/ultramodern-workspace/delivery-unit.cjs +88 -0
- package/dist/cjs/ultramodern-workspace/descriptors.cjs +24 -0
- package/dist/cjs/ultramodern-workspace/module-federation.cjs +122 -44
- package/dist/cjs/ultramodern-workspace/package-json.cjs +11 -34
- package/dist/cjs/ultramodern-workspace/pnpm-workspace-policy-plan.cjs +166 -0
- package/dist/cjs/ultramodern-workspace/tooling-command-catalog.cjs +153 -0
- package/dist/cjs/ultramodern-workspace/workspace-script-plan.cjs +175 -0
- package/dist/cjs/ultramodern-workspace/workspace-scripts.cjs +43 -62
- package/dist/cjs/ultramodern-workspace/workspace-validation-contract.cjs +97 -0
- package/dist/cjs/ultramodern-workspace/write-workspace.cjs +9 -3
- package/dist/cjs/ultramodern-workspace/zerops.cjs +100 -0
- package/dist/esm/ultramodern-tooling/commands.js +500 -158
- package/dist/esm/ultramodern-tooling/config.js +144 -9
- package/dist/esm/ultramodern-workspace/add-vertical.js +26 -1
- package/dist/esm/ultramodern-workspace/api.js +43 -2
- package/dist/esm/ultramodern-workspace/backend-federation.js +217 -0
- package/dist/esm/ultramodern-workspace/contracts.js +24 -8
- package/dist/esm/ultramodern-workspace/delivery-unit-sync.js +108 -0
- package/dist/esm/ultramodern-workspace/delivery-unit.js +31 -0
- package/dist/esm/ultramodern-workspace/descriptors.js +13 -1
- package/dist/esm/ultramodern-workspace/module-federation.js +121 -36
- package/dist/esm/ultramodern-workspace/package-json.js +11 -31
- package/dist/esm/ultramodern-workspace/pnpm-workspace-policy-plan.js +113 -0
- package/dist/esm/ultramodern-workspace/tooling-command-catalog.js +100 -0
- package/dist/esm/ultramodern-workspace/workspace-script-plan.js +110 -0
- package/dist/esm/ultramodern-workspace/workspace-scripts.js +35 -63
- package/dist/esm/ultramodern-workspace/workspace-validation-contract.js +59 -0
- package/dist/esm/ultramodern-workspace/write-workspace.js +11 -5
- package/dist/esm/ultramodern-workspace/zerops.js +62 -0
- package/dist/esm-node/ultramodern-tooling/commands.js +500 -158
- package/dist/esm-node/ultramodern-tooling/config.js +144 -9
- package/dist/esm-node/ultramodern-workspace/add-vertical.js +26 -1
- package/dist/esm-node/ultramodern-workspace/api.js +43 -2
- package/dist/esm-node/ultramodern-workspace/backend-federation.js +218 -0
- package/dist/esm-node/ultramodern-workspace/contracts.js +24 -8
- package/dist/esm-node/ultramodern-workspace/delivery-unit-sync.js +109 -0
- package/dist/esm-node/ultramodern-workspace/delivery-unit.js +32 -0
- package/dist/esm-node/ultramodern-workspace/descriptors.js +13 -1
- package/dist/esm-node/ultramodern-workspace/module-federation.js +121 -36
- package/dist/esm-node/ultramodern-workspace/package-json.js +11 -31
- package/dist/esm-node/ultramodern-workspace/pnpm-workspace-policy-plan.js +114 -0
- package/dist/esm-node/ultramodern-workspace/tooling-command-catalog.js +101 -0
- package/dist/esm-node/ultramodern-workspace/workspace-script-plan.js +111 -0
- package/dist/esm-node/ultramodern-workspace/workspace-scripts.js +35 -63
- package/dist/esm-node/ultramodern-workspace/workspace-validation-contract.js +60 -0
- package/dist/esm-node/ultramodern-workspace/write-workspace.js +11 -5
- package/dist/esm-node/ultramodern-workspace/zerops.js +63 -0
- package/dist/types/ultramodern-tooling/config.d.ts +6 -0
- package/dist/types/ultramodern-workspace/api.d.ts +1 -0
- package/dist/types/ultramodern-workspace/backend-federation.d.ts +11 -0
- package/dist/types/ultramodern-workspace/contracts.d.ts +1 -1
- package/dist/types/ultramodern-workspace/delivery-unit-sync.d.ts +6 -0
- package/dist/types/ultramodern-workspace/delivery-unit.d.ts +27 -0
- package/dist/types/ultramodern-workspace/descriptors.d.ts +4 -0
- package/dist/types/ultramodern-workspace/module-federation.d.ts +4 -9
- package/dist/types/ultramodern-workspace/package-json.d.ts +0 -1
- package/dist/types/ultramodern-workspace/pnpm-workspace-policy-plan.d.ts +39 -0
- package/dist/types/ultramodern-workspace/tooling-command-catalog.d.ts +18 -0
- package/dist/types/ultramodern-workspace/workspace-script-plan.d.ts +72 -0
- package/dist/types/ultramodern-workspace/workspace-scripts.d.ts +3 -0
- package/dist/types/ultramodern-workspace/workspace-validation-contract.d.ts +42 -0
- package/dist/types/ultramodern-workspace/zerops.d.ts +2 -0
- package/package.json +3 -3
- package/template-workspace/.gitignore.handlebars +1 -0
- package/template-workspace/scripts/bootstrap-agent-skills.mjs +11 -3
- package/templates/workspace-scripts/check-ultramodern-api-boundaries.mts +40 -2
- package/templates/workspace-scripts/generate-node-backend-federation.mjs +270 -0
- package/templates/workspace-scripts/materialize-zerops-runtime.mjs +448 -0
- package/templates/workspace-scripts/proof-cloudflare-version.mjs +234 -8
- package/templates/workspace-scripts/proof-node-backend-federation.mjs +729 -0
- package/templates/workspace-scripts/ultramodern-cloudflare-proof.mjs +188 -2
- package/templates/workspace-scripts/validate-ultramodern-workspace.mjs.handlebars +322 -8
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import "node:module";
|
|
2
|
+
const defineToolingCommand = (command)=>({
|
|
3
|
+
...command,
|
|
4
|
+
wrapperPath: `scripts/${command.wrapperName}.mts`
|
|
5
|
+
});
|
|
6
|
+
const generatedToolingCommands = [
|
|
7
|
+
defineToolingCommand({
|
|
8
|
+
id: 'validate',
|
|
9
|
+
command: 'validate',
|
|
10
|
+
wrapperName: 'validate-ultramodern-workspace',
|
|
11
|
+
contractKey: 'validate',
|
|
12
|
+
rootScript: 'contract:check'
|
|
13
|
+
}),
|
|
14
|
+
defineToolingCommand({
|
|
15
|
+
id: 'typecheck',
|
|
16
|
+
command: 'typecheck',
|
|
17
|
+
wrapperName: 'ultramodern-typecheck',
|
|
18
|
+
contractKey: 'typecheck',
|
|
19
|
+
rootScript: 'typecheck',
|
|
20
|
+
templatePath: "templates/workspace-scripts/ultramodern-typecheck.mjs",
|
|
21
|
+
cwd: 'invocation'
|
|
22
|
+
}),
|
|
23
|
+
defineToolingCommand({
|
|
24
|
+
id: 'mfTypes',
|
|
25
|
+
command: 'mf-types',
|
|
26
|
+
wrapperName: 'assert-mf-types',
|
|
27
|
+
contractKey: 'mfTypes',
|
|
28
|
+
rootScript: 'mf:types'
|
|
29
|
+
}),
|
|
30
|
+
defineToolingCommand({
|
|
31
|
+
id: 'publicSurface',
|
|
32
|
+
command: 'public-surface',
|
|
33
|
+
wrapperName: 'generate-public-surface-assets',
|
|
34
|
+
contractKey: 'publicSurface',
|
|
35
|
+
templatePath: "templates/workspace-scripts/generate-public-surface-assets.mjs"
|
|
36
|
+
}),
|
|
37
|
+
defineToolingCommand({
|
|
38
|
+
id: 'backendFederationGenerate',
|
|
39
|
+
command: 'backend-federation-generate',
|
|
40
|
+
wrapperName: 'generate-node-backend-federation',
|
|
41
|
+
contractKey: 'backendFederationGenerate',
|
|
42
|
+
rootScript: 'node:backend-federation:generate',
|
|
43
|
+
templatePath: "templates/workspace-scripts/generate-node-backend-federation.mjs"
|
|
44
|
+
}),
|
|
45
|
+
defineToolingCommand({
|
|
46
|
+
id: 'backendFederationProof',
|
|
47
|
+
command: 'backend-federation-proof',
|
|
48
|
+
wrapperName: 'proof-node-backend-federation',
|
|
49
|
+
contractKey: 'backendFederationProof',
|
|
50
|
+
rootScript: 'node:proof',
|
|
51
|
+
templatePath: "templates/workspace-scripts/proof-node-backend-federation.mjs"
|
|
52
|
+
}),
|
|
53
|
+
defineToolingCommand({
|
|
54
|
+
id: 'cloudflareProof',
|
|
55
|
+
command: 'cloudflare-proof',
|
|
56
|
+
wrapperName: 'proof-cloudflare-version',
|
|
57
|
+
contractKey: 'cloudflareProof',
|
|
58
|
+
rootScript: 'cloudflare:proof',
|
|
59
|
+
templatePath: "templates/workspace-scripts/proof-cloudflare-version.mjs"
|
|
60
|
+
}),
|
|
61
|
+
defineToolingCommand({
|
|
62
|
+
id: 'cloudflareOutputVerify',
|
|
63
|
+
command: 'cloudflare-output-verify',
|
|
64
|
+
wrapperName: 'verify-cloudflare-output',
|
|
65
|
+
contractKey: 'cloudflareOutputVerify',
|
|
66
|
+
rootScript: 'cloudflare-output:verify'
|
|
67
|
+
}),
|
|
68
|
+
defineToolingCommand({
|
|
69
|
+
id: 'performanceReadiness',
|
|
70
|
+
command: 'performance-readiness',
|
|
71
|
+
wrapperName: 'ultramodern-performance-readiness',
|
|
72
|
+
contractKey: 'performanceReadiness',
|
|
73
|
+
rootScript: 'performance:readiness',
|
|
74
|
+
templatePath: "templates/workspace-scripts/ultramodern-performance-readiness.mjs"
|
|
75
|
+
}),
|
|
76
|
+
defineToolingCommand({
|
|
77
|
+
id: 'migrateStrictEffect',
|
|
78
|
+
command: 'migrate-strict-effect',
|
|
79
|
+
wrapperName: 'migrate-strict-effect',
|
|
80
|
+
contractKey: 'migrateStrictEffect',
|
|
81
|
+
rootScript: 'migrate:strict-effect'
|
|
82
|
+
}),
|
|
83
|
+
defineToolingCommand({
|
|
84
|
+
id: 'routesGenerate',
|
|
85
|
+
command: 'routes-generate',
|
|
86
|
+
wrapperName: 'generate-tanstack-routes',
|
|
87
|
+
contractKey: 'routesGenerate'
|
|
88
|
+
})
|
|
89
|
+
];
|
|
90
|
+
const toolingCommandById = Object.fromEntries(generatedToolingCommands.map((command)=>[
|
|
91
|
+
command.id,
|
|
92
|
+
command
|
|
93
|
+
]));
|
|
94
|
+
const GENERATED_TOOLING_COMMANDS = toolingCommandById;
|
|
95
|
+
const generatedToolingCommandList = ()=>generatedToolingCommands.map((command)=>command.command);
|
|
96
|
+
const createToolingWrapperContract = ()=>Object.fromEntries(generatedToolingCommands.map((command)=>[
|
|
97
|
+
command.contractKey,
|
|
98
|
+
command.wrapperPath
|
|
99
|
+
]));
|
|
100
|
+
const createGeneratedToolingWrapperMap = createToolingWrapperContract;
|
|
101
|
+
export { GENERATED_TOOLING_COMMANDS, createGeneratedToolingWrapperMap, createToolingWrapperContract, generatedToolingCommandList, generatedToolingCommands, toolingCommandById };
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import "node:module";
|
|
2
|
+
import { appHasApi } from "./descriptors.js";
|
|
3
|
+
import { relativeRootFor } from "./naming.js";
|
|
4
|
+
import { createPublicSurfaceGenerationCommand } from "./public-surface.js";
|
|
5
|
+
import { GENERATED_TOOLING_COMMANDS } from "./tooling-command-catalog.js";
|
|
6
|
+
const toolingWrapperPath = (key)=>GENERATED_TOOLING_COMMANDS[key].wrapperPath;
|
|
7
|
+
const rootToolingScriptName = (key)=>{
|
|
8
|
+
const rootScript = GENERATED_TOOLING_COMMANDS[key].rootScript;
|
|
9
|
+
if (!rootScript) throw new Error(`Generated tooling command ${key} does not define a root package script.`);
|
|
10
|
+
return rootScript;
|
|
11
|
+
};
|
|
12
|
+
const rootToolingWrapperCommand = (key)=>`node ./${toolingWrapperPath(key)}`;
|
|
13
|
+
const relativeToolingWrapperPath = (packageDir, key)=>`${relativeRootFor(packageDir)}/${toolingWrapperPath(key)}`;
|
|
14
|
+
const packageToolingWrapperCommand = (packageDir, key)=>`node ${relativeToolingWrapperPath(packageDir, key)}`;
|
|
15
|
+
const workspaceRootPackageScriptNames = {
|
|
16
|
+
build: 'build',
|
|
17
|
+
cloudflareBuild: 'cloudflare:build',
|
|
18
|
+
cloudflareDeploy: 'cloudflare:deploy',
|
|
19
|
+
cloudflareProof: rootToolingScriptName('cloudflareProof'),
|
|
20
|
+
cloudflareOutputVerify: rootToolingScriptName('cloudflareOutputVerify'),
|
|
21
|
+
backendFederationGenerate: rootToolingScriptName('backendFederationGenerate'),
|
|
22
|
+
nodeProof: rootToolingScriptName('backendFederationProof'),
|
|
23
|
+
mfTypes: rootToolingScriptName('mfTypes'),
|
|
24
|
+
performanceReadiness: rootToolingScriptName('performanceReadiness'),
|
|
25
|
+
migrateStrictEffect: rootToolingScriptName('migrateStrictEffect'),
|
|
26
|
+
zeropsMaterialize: 'zerops:materialize',
|
|
27
|
+
contractCheck: rootToolingScriptName('validate'),
|
|
28
|
+
typecheck: 'typecheck',
|
|
29
|
+
check: 'check'
|
|
30
|
+
};
|
|
31
|
+
const workspaceAppPackageScriptNames = {
|
|
32
|
+
dev: 'dev',
|
|
33
|
+
build: 'build',
|
|
34
|
+
cloudflareBuild: 'cloudflare:build',
|
|
35
|
+
cloudflareDeploy: 'cloudflare:deploy',
|
|
36
|
+
cloudflarePreview: 'cloudflare:preview',
|
|
37
|
+
cloudflareProof: 'cloudflare:proof',
|
|
38
|
+
serve: 'serve',
|
|
39
|
+
typecheck: 'typecheck'
|
|
40
|
+
};
|
|
41
|
+
const createStrictTsgoTypecheckCommand = (packageDir)=>`${packageToolingWrapperCommand(packageDir, 'typecheck')} --project tsconfig.json`;
|
|
42
|
+
function createWorkspaceAppScriptPlan(app) {
|
|
43
|
+
const backendFederationBuildCommand = appHasApi(app) ? `${packageToolingWrapperCommand(app.directory, 'backendFederationGenerate')} --app ${app.id}` : void 0;
|
|
44
|
+
const backendFederationCloudflareBuildCommand = backendFederationBuildCommand ? `${backendFederationBuildCommand} --target dist-cloudflare` : void 0;
|
|
45
|
+
const buildSteps = [
|
|
46
|
+
'ULTRAMODERN_ZEPHYR=false modern build',
|
|
47
|
+
backendFederationBuildCommand,
|
|
48
|
+
createPublicSurfaceGenerationCommand(app, 'dist'),
|
|
49
|
+
app.exposes ? packageToolingWrapperCommand(app.directory, 'mfTypes') : void 0
|
|
50
|
+
].filter((step)=>Boolean(step));
|
|
51
|
+
const cloudflareBuildSteps = [
|
|
52
|
+
'ULTRAMODERN_ZEPHYR=false MODERNJS_DEPLOY=cloudflare modern build',
|
|
53
|
+
backendFederationCloudflareBuildCommand,
|
|
54
|
+
'ULTRAMODERN_ZEPHYR=false MODERNJS_DEPLOY=cloudflare modern deploy --skip-build',
|
|
55
|
+
createPublicSurfaceGenerationCommand(app, 'cloudflare'),
|
|
56
|
+
`${packageToolingWrapperCommand(app.directory, 'cloudflareOutputVerify')} --app ${app.id}`
|
|
57
|
+
].filter((step)=>Boolean(step));
|
|
58
|
+
return {
|
|
59
|
+
dev: 'modern dev',
|
|
60
|
+
build: buildSteps.join(' && '),
|
|
61
|
+
cloudflareBuild: cloudflareBuildSteps.join(' && '),
|
|
62
|
+
cloudflareDeploy: 'ULTRAMODERN_CLOUDFLARE_REQUIRE_PUBLIC_URLS=true pnpm run cloudflare:build && wrangler deploy --config .output/wrangler.json',
|
|
63
|
+
cloudflarePreview: 'pnpm run cloudflare:build && wrangler dev --config .output/wrangler.json',
|
|
64
|
+
cloudflareProof: `${packageToolingWrapperCommand(app.directory, 'cloudflareProof')} --app ${app.id}`,
|
|
65
|
+
serve: 'modern serve',
|
|
66
|
+
typecheck: createStrictTsgoTypecheckCommand(app.directory)
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
function createWorkspaceAppPackageScripts(app) {
|
|
70
|
+
const plan = createWorkspaceAppScriptPlan(app);
|
|
71
|
+
return Object.fromEntries(Object.entries(workspaceAppPackageScriptNames).map(([planKey, packageScriptName])=>[
|
|
72
|
+
packageScriptName,
|
|
73
|
+
plan[planKey]
|
|
74
|
+
]));
|
|
75
|
+
}
|
|
76
|
+
function createWorkspaceRootScriptPlan(remotes = [], options = {}) {
|
|
77
|
+
const hasRemotes = remotes.length > 0;
|
|
78
|
+
const mfTypesScript = rootToolingScriptName('mfTypes');
|
|
79
|
+
const performanceReadinessScript = rootToolingScriptName('performanceReadiness');
|
|
80
|
+
const cloudflareOutputVerifyScript = rootToolingScriptName('cloudflareOutputVerify');
|
|
81
|
+
const backendFederationGenerateScript = rootToolingScriptName('backendFederationGenerate');
|
|
82
|
+
const nodeProofScript = rootToolingScriptName('backendFederationProof');
|
|
83
|
+
const bridgeCheck = options.bridgeCheck ?? '';
|
|
84
|
+
const remoteBuildPrefix = hasRemotes ? 'ULTRAMODERN_ZEPHYR=false pnpm -r --filter "./verticals/*" run build && ' : '';
|
|
85
|
+
const remoteCloudflareBuildPrefix = hasRemotes ? 'pnpm -r --filter "./verticals/*" run cloudflare:build && ' : '';
|
|
86
|
+
const remoteCloudflareDeployPrefix = hasRemotes ? 'pnpm -r --filter "./verticals/*" run cloudflare:deploy && ' : '';
|
|
87
|
+
return {
|
|
88
|
+
build: `${remoteBuildPrefix}ULTRAMODERN_ZEPHYR=false pnpm --filter "./apps/shell-super-app" run build && pnpm ${mfTypesScript} && pnpm ${performanceReadinessScript}`,
|
|
89
|
+
cloudflareBuild: `${remoteCloudflareBuildPrefix}pnpm --filter "./apps/shell-super-app" run cloudflare:build && pnpm ${mfTypesScript} && pnpm ${cloudflareOutputVerifyScript}`,
|
|
90
|
+
cloudflareDeploy: `${remoteCloudflareDeployPrefix}pnpm --filter "./apps/shell-super-app" run cloudflare:deploy`,
|
|
91
|
+
cloudflareProof: `${rootToolingWrapperCommand('cloudflareProof')} --out .codex/reports/cloudflare-version-proof/public-url-proof.json`,
|
|
92
|
+
cloudflareOutputVerify: rootToolingWrapperCommand('cloudflareOutputVerify'),
|
|
93
|
+
backendFederationGenerate: rootToolingWrapperCommand('backendFederationGenerate'),
|
|
94
|
+
nodeProof: rootToolingWrapperCommand('backendFederationProof'),
|
|
95
|
+
mfTypes: rootToolingWrapperCommand('mfTypes'),
|
|
96
|
+
performanceReadiness: rootToolingWrapperCommand('performanceReadiness'),
|
|
97
|
+
migrateStrictEffect: rootToolingWrapperCommand('migrateStrictEffect'),
|
|
98
|
+
zeropsMaterialize: "node ./scripts/materialize-zerops-runtime.mjs",
|
|
99
|
+
contractCheck: rootToolingWrapperCommand('validate'),
|
|
100
|
+
typecheck: options.typecheck ?? `${rootToolingWrapperCommand('typecheck')} --project tsconfig.json`,
|
|
101
|
+
check: `pnpm format:check && pnpm lint && pnpm typecheck && pnpm skills:check && pnpm i18n:boundaries && pnpm api:check && pnpm contract:check && pnpm ${backendFederationGenerateScript} && pnpm ${nodeProofScript} && pnpm performance:readiness${bridgeCheck}`
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
function createWorkspaceRootPackageScripts(remotes = [], options = {}) {
|
|
105
|
+
const plan = createWorkspaceRootScriptPlan(remotes, options);
|
|
106
|
+
return Object.fromEntries(Object.entries(workspaceRootPackageScriptNames).map(([planKey, packageScriptName])=>[
|
|
107
|
+
packageScriptName,
|
|
108
|
+
plan[planKey]
|
|
109
|
+
]));
|
|
110
|
+
}
|
|
111
|
+
export { createStrictTsgoTypecheckCommand, createWorkspaceAppPackageScripts, createWorkspaceAppScriptPlan, createWorkspaceRootPackageScripts, createWorkspaceRootScriptPlan, packageToolingWrapperCommand, rootToolingScriptName, rootToolingWrapperCommand, workspaceAppPackageScriptNames, workspaceRootPackageScriptNames };
|
|
@@ -1,15 +1,9 @@
|
|
|
1
1
|
import "node:module";
|
|
2
2
|
import node_fs from "node:fs";
|
|
3
3
|
import node_path from "node:path";
|
|
4
|
-
import { verticalApiGroupName } from "./api.js";
|
|
5
|
-
import { remoteComponentOutputPath } from "./demo-components.js";
|
|
6
|
-
import { appHasApi, appI18nNamespace, remoteDependencyAlias, shellApp } from "./descriptors.js";
|
|
7
4
|
import { readFileTemplate, renderFileTemplate, writeFileReplacing } from "./fs-io.js";
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import { publicSurfaceManagedSourceAssetPaths } from "./public-surface.js";
|
|
11
|
-
import { createLocalisedUrlsMap, createRouteMetaFilePath, createRouteOwnedI18nPaths, createRoutePageFilePath } from "./routes.js";
|
|
12
|
-
import { CLOUDFLARE_COMPATIBILITY_DATE, EFFECT_VERSION, MODULE_FEDERATION_VERSION, NODE_VERSION, PNPM_VERSION } from "./versions.js";
|
|
5
|
+
import { GENERATED_TOOLING_COMMANDS, generatedToolingCommands } from "./tooling-command-catalog.js";
|
|
6
|
+
import { createWorkspaceValidationContract } from "./workspace-validation-contract.js";
|
|
13
7
|
function createToolWrapperScript(command, extraArgs = []) {
|
|
14
8
|
const commandJson = JSON.stringify(command);
|
|
15
9
|
const extraArgsJson = JSON.stringify(extraArgs);
|
|
@@ -43,6 +37,13 @@ if (result.error) {
|
|
|
43
37
|
process.exit(result.status ?? 1);
|
|
44
38
|
`;
|
|
45
39
|
}
|
|
40
|
+
function writeGeneratedToolWrapperScript(targetDir, key) {
|
|
41
|
+
const command = GENERATED_TOOLING_COMMANDS[key];
|
|
42
|
+
writeWorkspaceOwnedMtsScript(targetDir, command.wrapperName, createToolWrapperScript(command.command));
|
|
43
|
+
}
|
|
44
|
+
function writeGeneratedToolWrapperScripts(targetDir) {
|
|
45
|
+
for (const command of generatedToolingCommands)writeGeneratedToolWrapperScript(targetDir, command.id);
|
|
46
|
+
}
|
|
46
47
|
function createSkillsToolWrapperScript() {
|
|
47
48
|
return `#!/usr/bin/env node
|
|
48
49
|
import { spawnSync } from 'node:child_process';
|
|
@@ -97,54 +98,24 @@ function migrateCopiedWorkspaceScriptToMts(targetDir, name) {
|
|
|
97
98
|
node_fs.renameSync(legacyPath, migratedPath);
|
|
98
99
|
}
|
|
99
100
|
function createWorkspaceValidationScript(scope, enableTailwind, remotes = []) {
|
|
100
|
-
const
|
|
101
|
-
id: remote.id,
|
|
102
|
-
domain: remote.domain,
|
|
103
|
-
stem: remote.api.stem,
|
|
104
|
-
group: verticalApiGroupName(remote),
|
|
105
|
-
path: remote.directory,
|
|
106
|
-
port: remote.port,
|
|
107
|
-
mfName: remote.mfName,
|
|
108
|
-
apiPrefix: remote.api.prefix,
|
|
109
|
-
tailwindPrefix: tailwindPrefixForApp(remote),
|
|
110
|
-
zephyrAlias: remoteDependencyAlias(remote),
|
|
111
|
-
packageName: packageName(scope, remote.packageSuffix),
|
|
112
|
-
exposes: Object.keys(remote.exposes ?? {}),
|
|
113
|
-
componentPaths: Object.keys(remote.exposes ?? {}).map((expose)=>remoteComponentOutputPath(remote, expose)).filter((componentPath)=>Boolean(componentPath)),
|
|
114
|
-
namespace: appI18nNamespace(remote),
|
|
115
|
-
routePagePaths: createRouteOwnedI18nPaths(remote).filter((route)=>'/' !== route.canonicalPath).map((route)=>createRoutePageFilePath(remote, route.canonicalPath)),
|
|
116
|
-
routeMetaPaths: createRouteOwnedI18nPaths(remote).map((route)=>createRouteMetaFilePath(remote, route.canonicalPath)),
|
|
117
|
-
localisedUrls: createLocalisedUrlsMap(remote),
|
|
118
|
-
verticalRefs: remote.verticalRefs ?? []
|
|
119
|
-
}));
|
|
120
|
-
const shellRouteMetaPaths = createRouteOwnedI18nPaths(shellApp).map((route)=>createRouteMetaFilePath(shellApp, route.canonicalPath));
|
|
121
|
-
const shellNamespace = appI18nNamespace(shellApp);
|
|
122
|
-
const oldRemotePaths = [
|
|
123
|
-
'apps/remotes'
|
|
124
|
-
];
|
|
125
|
-
const expectedBuildScript = remotes.length > 0 ? 'ULTRAMODERN_ZEPHYR=false pnpm -r --filter "./verticals/*" run build && ULTRAMODERN_ZEPHYR=false pnpm --filter "./apps/shell-super-app" run build && pnpm mf:types && pnpm performance:readiness' : 'ULTRAMODERN_ZEPHYR=false pnpm --filter "./apps/shell-super-app" run build && pnpm mf:types && pnpm performance:readiness';
|
|
126
|
-
const expectedCloudflareBuildScript = remotes.length > 0 ? 'pnpm -r --filter "./verticals/*" run cloudflare:build && pnpm --filter "./apps/shell-super-app" run cloudflare:build && pnpm mf:types' : 'pnpm --filter "./apps/shell-super-app" run cloudflare:build && pnpm mf:types';
|
|
127
|
-
const expectedCloudflareDeployScript = remotes.length > 0 ? 'pnpm -r --filter "./verticals/*" run cloudflare:deploy && pnpm --filter "./apps/shell-super-app" run cloudflare:deploy' : 'pnpm --filter "./apps/shell-super-app" run cloudflare:deploy';
|
|
128
|
-
const expectedCloudflareSecurity = createCloudflareSecurityContract();
|
|
101
|
+
const contract = createWorkspaceValidationContract(scope, enableTailwind, remotes);
|
|
129
102
|
return renderFileTemplate("workspace-scripts/validate-ultramodern-workspace.mjs", {
|
|
130
|
-
packageScope:
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
shellRouteMetaPathsJson: JSON.stringify(shellRouteMetaPaths, null, 2),
|
|
147
|
-
cloudflareCompatibilityDate: CLOUDFLARE_COMPATIBILITY_DATE
|
|
103
|
+
packageScope: contract.packageScope,
|
|
104
|
+
nodeVersion: contract.versions.node,
|
|
105
|
+
tailwindEnabledJson: JSON.stringify(contract.tailwindEnabled),
|
|
106
|
+
fullStackVerticalsJson: JSON.stringify(contract.fullStackVerticals, null, 2),
|
|
107
|
+
shellNamespaceJson: JSON.stringify(contract.shellNamespace),
|
|
108
|
+
oldRemotePathsJson: JSON.stringify(contract.oldRemotePaths),
|
|
109
|
+
expectedBuildScriptJson: JSON.stringify(contract.scripts.build),
|
|
110
|
+
expectedCloudflareBuildScriptJson: JSON.stringify(contract.scripts.cloudflareBuild),
|
|
111
|
+
expectedCloudflareDeployScriptJson: JSON.stringify(contract.scripts.cloudflareDeploy),
|
|
112
|
+
expectedCloudflareSecurityJson: JSON.stringify(contract.cloudflareSecurity, null, 2),
|
|
113
|
+
workspaceValidationContractJson: JSON.stringify(contract, null, 2),
|
|
114
|
+
publicSurfaceManagedSourceAssetPathsJson: JSON.stringify(contract.publicSurfaceManagedSourceAssetPaths, null, 2),
|
|
115
|
+
shellRouteMetaPathsJson: JSON.stringify(contract.shellRouteMetaPaths, null, 2),
|
|
116
|
+
effectVersion: contract.versions.effect,
|
|
117
|
+
moduleFederationVersion: contract.versions.moduleFederation,
|
|
118
|
+
cloudflareCompatibilityDate: contract.versions.cloudflareCompatibilityDate
|
|
148
119
|
});
|
|
149
120
|
}
|
|
150
121
|
function createWorkspaceI18nBoundaryValidationScript() {
|
|
@@ -156,18 +127,19 @@ function createWorkspaceApiBoundaryValidationScript() {
|
|
|
156
127
|
function createPerformanceReadinessConfigScript() {
|
|
157
128
|
return readFileTemplate("workspace-scripts/ultramodern-performance-readiness.config.mjs");
|
|
158
129
|
}
|
|
130
|
+
function createNodeBackendFederationProofScript() {
|
|
131
|
+
return readFileTemplate("workspace-scripts/proof-node-backend-federation.mjs");
|
|
132
|
+
}
|
|
133
|
+
function createZeropsRuntimeMaterializationScript() {
|
|
134
|
+
return readFileTemplate("workspace-scripts/materialize-zerops-runtime.mjs");
|
|
135
|
+
}
|
|
159
136
|
function writeGeneratedWorkspaceScripts(targetDir, _scope, _enableTailwind, _remotes = []) {
|
|
160
|
-
writeWorkspaceOwnedMtsScript(targetDir, 'assert-mf-types', createToolWrapperScript('mf-types'));
|
|
161
|
-
writeWorkspaceOwnedMtsScript(targetDir, 'validate-ultramodern-workspace', createToolWrapperScript('validate'));
|
|
162
137
|
writeWorkspaceOwnedMtsScript(targetDir, 'check-ultramodern-i18n-boundaries', createWorkspaceI18nBoundaryValidationScript());
|
|
163
138
|
writeWorkspaceOwnedMtsScript(targetDir, 'check-ultramodern-api-boundaries', createWorkspaceApiBoundaryValidationScript());
|
|
164
|
-
|
|
165
|
-
writeWorkspaceOwnedMtsScript(targetDir, 'proof-cloudflare-version', createToolWrapperScript('cloudflare-proof'));
|
|
139
|
+
writeFileReplacing(targetDir, "scripts/materialize-zerops-runtime.mjs", createZeropsRuntimeMaterializationScript());
|
|
166
140
|
writeFileReplacing(targetDir, "scripts/ultramodern-performance-readiness.config.mjs", createPerformanceReadinessConfigScript());
|
|
167
|
-
|
|
168
|
-
writeWorkspaceOwnedMtsScript(targetDir, 'migrate-strict-effect', createToolWrapperScript('migrate-strict-effect'));
|
|
169
|
-
writeWorkspaceOwnedMtsScript(targetDir, 'ultramodern-typecheck', createToolWrapperScript('typecheck'));
|
|
141
|
+
writeGeneratedToolWrapperScripts(targetDir);
|
|
170
142
|
writeWorkspaceOwnedMtsScript(targetDir, 'bootstrap-agent-skills', createSkillsToolWrapperScript());
|
|
171
143
|
migrateCopiedWorkspaceScriptToMts(targetDir, 'setup-agent-reference-repos');
|
|
172
144
|
}
|
|
173
|
-
export { createPerformanceReadinessConfigScript, createWorkspaceApiBoundaryValidationScript, createWorkspaceI18nBoundaryValidationScript, createWorkspaceValidationScript, writeGeneratedWorkspaceScripts };
|
|
145
|
+
export { createNodeBackendFederationProofScript, createPerformanceReadinessConfigScript, createWorkspaceApiBoundaryValidationScript, createWorkspaceI18nBoundaryValidationScript, createWorkspaceValidationScript, createZeropsRuntimeMaterializationScript, writeGeneratedToolWrapperScripts, writeGeneratedWorkspaceScripts };
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import "node:module";
|
|
2
|
+
import { verticalApiGroupName } from "./api.js";
|
|
3
|
+
import { createBackendFederationMetadata } from "./backend-federation.js";
|
|
4
|
+
import { createDeliveryUnitRecord } from "./delivery-unit.js";
|
|
5
|
+
import { remoteComponentOutputPath } from "./demo-components.js";
|
|
6
|
+
import { appHasApi, appI18nNamespace, remoteDependencyAlias, shellApp } from "./descriptors.js";
|
|
7
|
+
import { packageName, tailwindPrefixForApp } from "./naming.js";
|
|
8
|
+
import { createCloudflareSecurityContract } from "./policy.js";
|
|
9
|
+
import { publicSurfaceManagedSourceAssetPaths } from "./public-surface.js";
|
|
10
|
+
import { createLocalisedUrlsMap, createRouteMetaFilePath, createRouteOwnedI18nPaths, createRoutePageFilePath } from "./routes.js";
|
|
11
|
+
import { CLOUDFLARE_COMPATIBILITY_DATE, EFFECT_VERSION, MODULE_FEDERATION_VERSION, NODE_VERSION, PNPM_VERSION } from "./versions.js";
|
|
12
|
+
import { createWorkspaceRootPackageScripts, createWorkspaceRootScriptPlan } from "./workspace-script-plan.js";
|
|
13
|
+
function createWorkspaceValidationContract(scope, enableTailwind, remotes = []) {
|
|
14
|
+
const fullStackVerticals = remotes.filter(appHasApi).map((remote)=>({
|
|
15
|
+
id: remote.id,
|
|
16
|
+
domain: remote.domain,
|
|
17
|
+
stem: remote.api.stem,
|
|
18
|
+
group: verticalApiGroupName(remote),
|
|
19
|
+
path: remote.directory,
|
|
20
|
+
port: remote.port,
|
|
21
|
+
mfName: remote.mfName,
|
|
22
|
+
apiPrefix: remote.api.prefix,
|
|
23
|
+
tailwindPrefix: tailwindPrefixForApp(remote),
|
|
24
|
+
zephyrAlias: remoteDependencyAlias(remote),
|
|
25
|
+
packageName: packageName(scope, remote.packageSuffix),
|
|
26
|
+
backendFederation: createBackendFederationMetadata(scope, remote),
|
|
27
|
+
deliveryUnit: createDeliveryUnitRecord(scope, remote),
|
|
28
|
+
exposes: Object.keys(remote.exposes ?? {}),
|
|
29
|
+
componentPaths: Object.keys(remote.exposes ?? {}).map((expose)=>remoteComponentOutputPath(remote, expose)).filter((componentPath)=>Boolean(componentPath)),
|
|
30
|
+
namespace: appI18nNamespace(remote),
|
|
31
|
+
routePagePaths: createRouteOwnedI18nPaths(remote).filter((route)=>'/' !== route.canonicalPath).map((route)=>createRoutePageFilePath(remote, route.canonicalPath)),
|
|
32
|
+
routeMetaPaths: createRouteOwnedI18nPaths(remote).map((route)=>createRouteMetaFilePath(remote, route.canonicalPath)),
|
|
33
|
+
localisedUrls: createLocalisedUrlsMap(remote),
|
|
34
|
+
verticalRefs: remote.verticalRefs ?? []
|
|
35
|
+
}));
|
|
36
|
+
return {
|
|
37
|
+
packageScope: scope,
|
|
38
|
+
versions: {
|
|
39
|
+
cloudflareCompatibilityDate: CLOUDFLARE_COMPATIBILITY_DATE,
|
|
40
|
+
effect: EFFECT_VERSION,
|
|
41
|
+
moduleFederation: MODULE_FEDERATION_VERSION,
|
|
42
|
+
node: NODE_VERSION,
|
|
43
|
+
pnpm: PNPM_VERSION
|
|
44
|
+
},
|
|
45
|
+
tailwindEnabled: enableTailwind,
|
|
46
|
+
fullStackVerticals,
|
|
47
|
+
shellNamespace: appI18nNamespace(shellApp),
|
|
48
|
+
oldRemotePaths: [
|
|
49
|
+
'apps/remotes'
|
|
50
|
+
],
|
|
51
|
+
scripts: createWorkspaceRootScriptPlan(remotes),
|
|
52
|
+
packageScripts: createWorkspaceRootPackageScripts(remotes),
|
|
53
|
+
cloudflareSecurity: createCloudflareSecurityContract(),
|
|
54
|
+
publicSurfaceManagedSourceAssetPaths: [
|
|
55
|
+
...publicSurfaceManagedSourceAssetPaths
|
|
56
|
+
],
|
|
57
|
+
shellRouteMetaPaths: createRouteOwnedI18nPaths(shellApp).map((route)=>createRouteMetaFilePath(shellApp, route.canonicalPath))
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
export { createWorkspaceValidationContract };
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import "node:module";
|
|
2
2
|
import node_fs from "node:fs";
|
|
3
|
-
import { createApiClient, createApiServiceEntry, createSharedApi, createShellApiClient } from "./api.js";
|
|
3
|
+
import { createApiClient, createApiServiceEntry, createBackendEffectApiExpose, createSharedApi, createShellApiClient } from "./api.js";
|
|
4
4
|
import { createAppEnvDts, createAppRuntimeConfig, createAppStyles, createPostcssConfig, createSharedDesignTokensCss, createShellFrameComponent, createTailwindConfig } from "./app-files.js";
|
|
5
|
+
import { createBackendFederationContractFile } from "./backend-federation.js";
|
|
5
6
|
import { normalizeUltramodernBridgeConfig } from "./bridge-config.js";
|
|
6
7
|
import { createDevelopmentOverlay, createOwnership, createTopology, createUltramodernConfig } from "./contracts.js";
|
|
7
8
|
import { createLayout, createRemoteEntry, createRemoteExposeComponent, createRemotePage, createShellPage, createShellRemoteComponents, remoteComponentOutputPath } from "./demo-components.js";
|
|
@@ -9,7 +10,7 @@ import { ULTRAMODERN_CONFIG_PATH, appHasApi, appI18nNamespace, createShellHost,
|
|
|
9
10
|
import { copyRootTemplate, formatGeneratedWorkspaceFiles, writeFile, writeFileReplacing, writeJson } from "./fs-io.js";
|
|
10
11
|
import { createFileSnapshot, createGenerationResult, diffFileSnapshots } from "./generation-result.js";
|
|
11
12
|
import { createAppPublicLocaleMessages } from "./locales.js";
|
|
12
|
-
import { createAppModernConfig, createRemoteModuleFederationConfig, createShellModuleFederationConfig, createUltramodernBuildModule, createUltramodernBuildReexportModule } from "./module-federation.js";
|
|
13
|
+
import { createAppModernConfig, createBackendModuleFederationConfig, createRemoteModuleFederationConfig, createShellModuleFederationConfig, createUltramodernBuildModule, createUltramodernBuildReexportModule } from "./module-federation.js";
|
|
13
14
|
import { assertUniqueTailwindPrefixes, toPackageScope } from "./naming.js";
|
|
14
15
|
import { runCodeSmithOverlays } from "./overlays.js";
|
|
15
16
|
import { createAppMfTypesTsConfig, createAppPackage, createAppTsConfig, createRootPackageJson, createRootTsConfig, createSharedContractsIndex, createSharedPackage, createSharedPackageTsConfig, createTsConfigBase } from "./package-json.js";
|
|
@@ -17,6 +18,7 @@ import { resolvePackageSource } from "./package-source.js";
|
|
|
17
18
|
import { createPublicWebAppArtifacts } from "./public-surface.js";
|
|
18
19
|
import { DRIZZLE_ORM_VERSION, EFFECT_VERSION, EFFECT_VITEST_VERSION, MODULE_FEDERATION_VERSION, NODE_FETCH_VERSION, NODE_VERSION, PNPM_VERSION, TANSTACK_ROUTER_CORE_VERSION, TANSTACK_ROUTER_VERSION, TYPESCRIPT_VERSION } from "./versions.js";
|
|
19
20
|
import { writeGeneratedWorkspaceScripts } from "./workspace-scripts.js";
|
|
21
|
+
import { createZeropsYaml } from "./zerops.js";
|
|
20
22
|
function writeApp(targetDir, scope, app, packageSource, enableTailwind, remotes = [], bridge) {
|
|
21
23
|
const resolvedApp = 'shell' === app.kind ? createShellHost(remotes) : app;
|
|
22
24
|
const publicWeb = createPublicWebAppArtifacts(resolvedApp);
|
|
@@ -32,7 +34,7 @@ function writeApp(targetDir, scope, app, packageSource, enableTailwind, remotes
|
|
|
32
34
|
writeFile(targetDir, publicWeb.jsonLdHelperFile.path, publicWeb.jsonLdHelperFile.content);
|
|
33
35
|
writeFile(targetDir, publicWeb.routeMetadataFile.path, publicWeb.routeMetadataFile.content);
|
|
34
36
|
writeFile(targetDir, publicWeb.routeHeadFile.path, publicWeb.routeHeadFile.content);
|
|
35
|
-
writeFile(targetDir, `${resolvedApp.directory}/modern.config.ts`, createAppModernConfig(scope, resolvedApp));
|
|
37
|
+
writeFile(targetDir, `${resolvedApp.directory}/modern.config.ts`, createAppModernConfig(scope, resolvedApp, remotes));
|
|
36
38
|
writeFile(targetDir, `${resolvedApp.directory}/src/modern.runtime.ts`, createAppRuntimeConfig(resolvedApp, scope, remotes));
|
|
37
39
|
writeJson(targetDir, `${resolvedApp.directory}/locales/en/translation.json`, createAppPublicLocaleMessages(resolvedApp, 'en', remotes));
|
|
38
40
|
writeJson(targetDir, `${resolvedApp.directory}/locales/en/${appI18nNamespace(resolvedApp)}.json`, createAppPublicLocaleMessages(resolvedApp, 'en', remotes));
|
|
@@ -44,6 +46,7 @@ function writeApp(targetDir, scope, app, packageSource, enableTailwind, remotes
|
|
|
44
46
|
writeFile(targetDir, `${resolvedApp.directory}/tailwind.config.ts`, createTailwindConfig());
|
|
45
47
|
}
|
|
46
48
|
writeFile(targetDir, `${resolvedApp.directory}/module-federation.config.ts`, 'shell' === resolvedApp.kind ? createShellModuleFederationConfig(scope, remotes) : createRemoteModuleFederationConfig(scope, resolvedApp, remotes));
|
|
49
|
+
if (appHasApi(resolvedApp)) writeFile(targetDir, `${resolvedApp.directory}/backend-federation.config.ts`, createBackendModuleFederationConfig(resolvedApp));
|
|
47
50
|
writeAppFile('src/routes/layout.tsx', createLayout(resolvedApp.id));
|
|
48
51
|
writeAppFile('src/routes/[lang]/page.tsx', 'shell' === resolvedApp.kind ? createShellPage(remotes) : createRemotePage(resolvedApp));
|
|
49
52
|
for (const generatedFile of publicWeb.routeMetaFiles)writeFile(targetDir, generatedFile.path, generatedFile.content);
|
|
@@ -56,6 +59,8 @@ function writeApp(targetDir, scope, app, packageSource, enableTailwind, remotes
|
|
|
56
59
|
if (appHasApi(resolvedApp)) {
|
|
57
60
|
writeFile(targetDir, `${resolvedApp.directory}/shared/api.ts`, createSharedApi(resolvedApp));
|
|
58
61
|
writeFile(targetDir, `${resolvedApp.directory}/api/index.ts`, createApiServiceEntry(resolvedApp, '../shared/api.ts'));
|
|
62
|
+
writeFile(targetDir, `${resolvedApp.directory}/api/backend-federation.ts`, createBackendFederationContractFile(resolvedApp));
|
|
63
|
+
writeFile(targetDir, `${resolvedApp.directory}/api/effect-api.ts`, createBackendEffectApiExpose(scope, resolvedApp));
|
|
59
64
|
writeFile(targetDir, `${resolvedApp.directory}/src/api/${resolvedApp.api.stem}-client.ts`, createApiClient(resolvedApp, '../../shared/api'));
|
|
60
65
|
}
|
|
61
66
|
if ('vertical' === resolvedApp.kind) {
|
|
@@ -105,7 +110,7 @@ function writePnpmWorkspacePackages(targetDir, bridge) {
|
|
|
105
110
|
...bridge.workspacePackages.map((entry)=>entry.pattern)
|
|
106
111
|
];
|
|
107
112
|
const renderedPackages = packages.map((pattern)=>` - ${pattern}`).join('\n');
|
|
108
|
-
writeFileReplacing(targetDir, 'pnpm-workspace.yaml', pnpmWorkspace.replace(/^packages:\n(?: {2}- .+\n)+/u, `packages:\n${renderedPackages}\n`));
|
|
113
|
+
writeFileReplacing(targetDir, 'pnpm-workspace.yaml', pnpmWorkspace.replace(/^packages:\r?\n(?: {2}- .+\r?\n)+/u, `packages:\n${renderedPackages}\n`));
|
|
109
114
|
}
|
|
110
115
|
function generateUltramodernWorkspace(options) {
|
|
111
116
|
const beforeFiles = createFileSnapshot(options.targetDir);
|
|
@@ -142,11 +147,12 @@ function generateUltramodernWorkspace(options) {
|
|
|
142
147
|
});
|
|
143
148
|
writePnpmWorkspacePackages(options.targetDir, bridge);
|
|
144
149
|
writeJson(options.targetDir, 'package.json', createCompactRootPackageJson(scope, packageSource, initialVerticals, bridge));
|
|
150
|
+
writeFile(options.targetDir, 'zerops.yaml', `${createZeropsYaml(scope, createdApps)}\n`);
|
|
145
151
|
writeJson(options.targetDir, 'tsconfig.base.json', createTsConfigBase());
|
|
146
152
|
writeJson(options.targetDir, 'tsconfig.json', createRootTsConfig(createdApps));
|
|
147
153
|
writeJson(options.targetDir, 'topology/reference-topology.json', createTopology(scope, initialVerticals));
|
|
148
154
|
writeJson(options.targetDir, 'topology/ownership.json', createOwnership(scope, initialVerticals));
|
|
149
|
-
writeJson(options.targetDir, 'topology/local-overlays/development.json', createDevelopmentOverlay(initialVerticals));
|
|
155
|
+
writeJson(options.targetDir, 'topology/local-overlays/development.json', createDevelopmentOverlay(scope, initialVerticals));
|
|
150
156
|
writeJson(options.targetDir, ULTRAMODERN_CONFIG_PATH, createCompactUltramodernConfig(scope, options.modernVersion, packageSource, createdApps, enableTailwind, bridge));
|
|
151
157
|
writeApp(options.targetDir, scope, shellApp, packageSource, enableTailwind, initialVerticals, bridge);
|
|
152
158
|
for (const remote of initialVerticals)writeApp(options.targetDir, scope, remote, packageSource, enableTailwind, initialVerticals, bridge);
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import "node:module";
|
|
2
|
+
import { appHasApi, resolveApiPrefix, resolveApiStem } from "./descriptors.js";
|
|
3
|
+
import { packageName } from "./naming.js";
|
|
4
|
+
import { NODE_VERSION } from "./versions.js";
|
|
5
|
+
const zeropsNodeRuntime = `nodejs@${NODE_VERSION.split('.')[0]}`;
|
|
6
|
+
function quoteYamlString(value) {
|
|
7
|
+
return `'${value.replace(/'/gu, "''")}'`;
|
|
8
|
+
}
|
|
9
|
+
function readinessPath(app) {
|
|
10
|
+
if (!appHasApi(app)) return '/';
|
|
11
|
+
return `${resolveApiPrefix(app)}/${resolveApiStem(app)}/readiness`;
|
|
12
|
+
}
|
|
13
|
+
function createZeropsService(scope, app) {
|
|
14
|
+
const runtimeDirectory = `.zerops/runtime/${app.id}`;
|
|
15
|
+
const appPackageName = packageName(scope, app.packageSuffix);
|
|
16
|
+
const commands = [
|
|
17
|
+
'curl https://mise.run | sh',
|
|
18
|
+
'~/.local/bin/mise install',
|
|
19
|
+
'~/.local/bin/mise exec -- pnpm install --frozen-lockfile',
|
|
20
|
+
`~/.local/bin/mise exec -- pnpm --filter ${appPackageName} run build`,
|
|
21
|
+
`~/.local/bin/mise exec -- pnpm run zerops:materialize -- --app ${app.id} --package ${appPackageName} --package-dir ${app.directory}`,
|
|
22
|
+
`cp topology/reference-topology.json ${runtimeDirectory}/topology.json`,
|
|
23
|
+
`cp topology/local-overlays/development.json ${runtimeDirectory}/local-overlay.json`
|
|
24
|
+
];
|
|
25
|
+
return [
|
|
26
|
+
` - setup: ${app.id}`,
|
|
27
|
+
' build:',
|
|
28
|
+
` base: ${zeropsNodeRuntime}`,
|
|
29
|
+
' buildCommands:',
|
|
30
|
+
' - |',
|
|
31
|
+
...commands.map((command)=>` ${command}`),
|
|
32
|
+
' deployFiles:',
|
|
33
|
+
` - ${runtimeDirectory}`,
|
|
34
|
+
' deploy:',
|
|
35
|
+
' temporaryShutdown: false',
|
|
36
|
+
' readinessCheck:',
|
|
37
|
+
' httpGet:',
|
|
38
|
+
` port: ${app.port}`,
|
|
39
|
+
` path: ${readinessPath(app)}`,
|
|
40
|
+
' failureTimeout: 120',
|
|
41
|
+
' retryPeriod: 10',
|
|
42
|
+
' run:',
|
|
43
|
+
` base: ${zeropsNodeRuntime}`,
|
|
44
|
+
' ports:',
|
|
45
|
+
` - port: ${app.port}`,
|
|
46
|
+
' protocol: TCP',
|
|
47
|
+
' httpSupport: true',
|
|
48
|
+
' envVariables:',
|
|
49
|
+
' NODE_ENV: production',
|
|
50
|
+
` ${app.portEnv}: ${quoteYamlString(String(app.port))}`,
|
|
51
|
+
` ULTRAMODERN_ZEROPS_SERVICE: ${quoteYamlString(app.id)}`,
|
|
52
|
+
` start: cd ${runtimeDirectory} && npm run serve`
|
|
53
|
+
].join('\n');
|
|
54
|
+
}
|
|
55
|
+
function createZeropsYaml(scope, apps) {
|
|
56
|
+
return [
|
|
57
|
+
'# Generated by Modern.js UltraModern workspace tooling.',
|
|
58
|
+
'# Zerops runs each full-stack MicroVertical as a package-owned Node service.',
|
|
59
|
+
'zerops:',
|
|
60
|
+
...apps.map((app)=>createZeropsService(scope, app))
|
|
61
|
+
].join('\n\n');
|
|
62
|
+
}
|
|
63
|
+
export { createZeropsYaml };
|
|
@@ -39,5 +39,11 @@ export type UltramodernToolingConfig = {
|
|
|
39
39
|
apps: UltramodernToolingConfigApp[];
|
|
40
40
|
};
|
|
41
41
|
};
|
|
42
|
+
export declare function normalizeCompactUltramodernConfig(workspaceRoot: string, compact: Record<string, any>): UltramodernToolingConfig;
|
|
43
|
+
export declare function synthesizeCompactUltramodernConfig(workspaceRoot: string): {
|
|
44
|
+
compact: Record<string, any>;
|
|
45
|
+
missing: string[];
|
|
46
|
+
sources: string[];
|
|
47
|
+
} | undefined;
|
|
42
48
|
export declare function readUltramodernConfig(workspaceRoot?: any): UltramodernToolingConfig;
|
|
43
49
|
export declare function workspaceAppsFromToolingConfig(config: UltramodernToolingConfig): WorkspaceApp[];
|
|
@@ -52,6 +52,7 @@ export declare function createApiServiceEntry(service: {
|
|
|
52
52
|
id: string;
|
|
53
53
|
api?: WorkspaceApi;
|
|
54
54
|
}, contractImportPath: string): string;
|
|
55
|
+
export declare function createBackendEffectApiExpose(scope: string, service: WorkspaceApp): string;
|
|
55
56
|
export declare function createApiClient(service: {
|
|
56
57
|
id: string;
|
|
57
58
|
api?: WorkspaceApi;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { JsonValue, WorkspaceApp } from './types';
|
|
2
|
+
export declare const BACKEND_FEDERATION_CONTRACT_VERSION = "microvertical-server-effect-v1";
|
|
3
|
+
export declare const BACKEND_FEDERATION_NODE_ADAPTER_VERSION = "backend-mf-effect-v1";
|
|
4
|
+
export declare function createWorkerBindingName(app: WorkspaceApp): string;
|
|
5
|
+
export declare function createWorkerBindingEnv(app: WorkspaceApp): string;
|
|
6
|
+
export declare function createDispatchWorkerNameEnv(app: WorkspaceApp): string;
|
|
7
|
+
export declare function createServerExecutionOverlay(scope: string, app: WorkspaceApp): JsonValue | undefined;
|
|
8
|
+
export declare function createBackendFederationContract(scope: string, app: WorkspaceApp): JsonValue | undefined;
|
|
9
|
+
export declare function createBackendFederationMetadata(scope: string, app: WorkspaceApp): JsonValue | undefined;
|
|
10
|
+
export declare function createBackendFederationContractFile(app: WorkspaceApp): string;
|
|
11
|
+
export declare function createBackendFederationSummary(scope: string, app: WorkspaceApp): JsonValue | undefined;
|
|
@@ -2,5 +2,5 @@ import type { UltramodernBridgeConfig } from './bridge-config';
|
|
|
2
2
|
import type { JsonValue, ResolvedPackageSource, WorkspaceApp } from './types';
|
|
3
3
|
export declare function createTopology(scope: string, remotes?: WorkspaceApp[]): JsonValue;
|
|
4
4
|
export declare function createOwnership(scope: string, remotes?: WorkspaceApp[]): JsonValue;
|
|
5
|
-
export declare function createDevelopmentOverlay(remotes?: WorkspaceApp[]): JsonValue;
|
|
5
|
+
export declare function createDevelopmentOverlay(scope: string, remotes?: WorkspaceApp[]): JsonValue;
|
|
6
6
|
export declare function createUltramodernConfig(scope: string, modernVersion: string, packageSource: ResolvedPackageSource, apps?: WorkspaceApp[], enableTailwind?: boolean, bridge?: UltramodernBridgeConfig): JsonValue;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { WorkspaceApp } from './types';
|
|
2
|
+
export declare const DELIVERY_UNIT_SCHEMA_VERSION = 1;
|
|
3
|
+
export type DeliveryUnitRecord = {
|
|
4
|
+
schemaVersion: 1;
|
|
5
|
+
kind: 'microvertical-delivery-unit';
|
|
6
|
+
unitId: string;
|
|
7
|
+
appId: string;
|
|
8
|
+
packageName: string;
|
|
9
|
+
version: string;
|
|
10
|
+
sourceRevision: string;
|
|
11
|
+
buildMarker: string;
|
|
12
|
+
deployProfile: 'cloudflare-ssr-mf-effect-v1';
|
|
13
|
+
};
|
|
14
|
+
export declare function createBuildMarker(scope: string, app: {
|
|
15
|
+
id: string;
|
|
16
|
+
packageSuffix: string;
|
|
17
|
+
}): any;
|
|
18
|
+
export declare function deliveryUnitContractBlock(record: DeliveryUnitRecord): {
|
|
19
|
+
schemaVersion: 1;
|
|
20
|
+
kind: "microvertical-delivery-unit";
|
|
21
|
+
unitId: string;
|
|
22
|
+
packageName: string;
|
|
23
|
+
version: string;
|
|
24
|
+
buildMarker: string;
|
|
25
|
+
sourceRevision: string;
|
|
26
|
+
};
|
|
27
|
+
export declare function createDeliveryUnitRecord(scope: string, app: WorkspaceApp): DeliveryUnitRecord;
|