@bleedingdev/modern-js-ultramodern-create 3.9.0-ultramodern.1 → 3.9.0-ultramodern.3

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.
Files changed (77) hide show
  1. package/README.md +4 -4
  2. package/dist/cjs/ultramodern-tooling/commands/migrate-strict-effect/generated-artifacts-typescript.cjs +1 -0
  3. package/dist/cjs/ultramodern-tooling/commands/migrate-strict-effect/package-cohort.cjs +2 -0
  4. package/dist/cjs/ultramodern-tooling/commands/migrate-strict-effect/pnpm-policy.cjs +20 -0
  5. package/dist/cjs/ultramodern-tooling/commands/migrate-strict-effect/shared-api-infrastructure.cjs +99 -0
  6. package/dist/cjs/ultramodern-tooling/commands/migrate-strict-effect/toolchain-pins.cjs +1 -0
  7. package/dist/cjs/ultramodern-tooling/commands/migrate-strict-effect.cjs +2 -0
  8. package/dist/cjs/ultramodern-workspace/api/client.cjs +2 -2
  9. package/dist/cjs/ultramodern-workspace/api/service.cjs +45 -16
  10. package/dist/cjs/ultramodern-workspace/api/shared.cjs +26 -16
  11. package/dist/cjs/ultramodern-workspace/mf-validation/inspect.cjs +6 -2
  12. package/dist/cjs/ultramodern-workspace/module-federation/reexport-module.cjs +0 -5
  13. package/dist/cjs/ultramodern-workspace/package-json.cjs +12 -1
  14. package/dist/cjs/ultramodern-workspace/policy.cjs +20 -154
  15. package/dist/cjs/ultramodern-workspace/tsconfigs.cjs +3 -0
  16. package/dist/cjs/ultramodern-workspace/versions.cjs +15 -15
  17. package/dist/cjs/ultramodern-workspace/workspace-script-plan.cjs +1 -1
  18. package/dist/cjs/ultramodern-workspace/workspace-scripts.cjs +5 -0
  19. package/dist/cjs/ultramodern-workspace/write-app.cjs +9 -3
  20. package/dist/cjs/ultramodern-workspace/write-workspace.cjs +5 -3
  21. package/dist/esm/ultramodern-tooling/commands/migrate-strict-effect/generated-artifacts-typescript.js +1 -0
  22. package/dist/esm/ultramodern-tooling/commands/migrate-strict-effect/package-cohort.js +2 -0
  23. package/dist/esm/ultramodern-tooling/commands/migrate-strict-effect/pnpm-policy.js +20 -0
  24. package/dist/esm/ultramodern-tooling/commands/migrate-strict-effect/shared-api-infrastructure.js +50 -0
  25. package/dist/esm/ultramodern-tooling/commands/migrate-strict-effect/toolchain-pins.js +1 -0
  26. package/dist/esm/ultramodern-tooling/commands/migrate-strict-effect.js +2 -0
  27. package/dist/esm/ultramodern-workspace/api/client.js +2 -2
  28. package/dist/esm/ultramodern-workspace/api/service.js +45 -16
  29. package/dist/esm/ultramodern-workspace/api/shared.js +27 -17
  30. package/dist/esm/ultramodern-workspace/mf-validation/inspect.js +6 -2
  31. package/dist/esm/ultramodern-workspace/module-federation/reexport-module.js +0 -5
  32. package/dist/esm/ultramodern-workspace/package-json.js +12 -1
  33. package/dist/esm/ultramodern-workspace/policy.js +20 -154
  34. package/dist/esm/ultramodern-workspace/tsconfigs.js +3 -0
  35. package/dist/esm/ultramodern-workspace/versions.js +15 -15
  36. package/dist/esm/ultramodern-workspace/workspace-script-plan.js +1 -1
  37. package/dist/esm/ultramodern-workspace/workspace-scripts.js +5 -0
  38. package/dist/esm/ultramodern-workspace/write-app.js +9 -3
  39. package/dist/esm/ultramodern-workspace/write-workspace.js +6 -4
  40. package/dist/esm-node/ultramodern-tooling/commands/migrate-strict-effect/generated-artifacts-typescript.js +1 -0
  41. package/dist/esm-node/ultramodern-tooling/commands/migrate-strict-effect/package-cohort.js +2 -0
  42. package/dist/esm-node/ultramodern-tooling/commands/migrate-strict-effect/pnpm-policy.js +20 -0
  43. package/dist/esm-node/ultramodern-tooling/commands/migrate-strict-effect/shared-api-infrastructure.js +51 -0
  44. package/dist/esm-node/ultramodern-tooling/commands/migrate-strict-effect/toolchain-pins.js +1 -0
  45. package/dist/esm-node/ultramodern-tooling/commands/migrate-strict-effect.js +2 -0
  46. package/dist/esm-node/ultramodern-workspace/api/client.js +2 -2
  47. package/dist/esm-node/ultramodern-workspace/api/service.js +45 -16
  48. package/dist/esm-node/ultramodern-workspace/api/shared.js +27 -17
  49. package/dist/esm-node/ultramodern-workspace/mf-validation/inspect.js +6 -2
  50. package/dist/esm-node/ultramodern-workspace/module-federation/reexport-module.js +0 -5
  51. package/dist/esm-node/ultramodern-workspace/package-json.js +12 -1
  52. package/dist/esm-node/ultramodern-workspace/policy.js +20 -154
  53. package/dist/esm-node/ultramodern-workspace/tsconfigs.js +3 -0
  54. package/dist/esm-node/ultramodern-workspace/versions.js +15 -15
  55. package/dist/esm-node/ultramodern-workspace/workspace-script-plan.js +1 -1
  56. package/dist/esm-node/ultramodern-workspace/workspace-scripts.js +5 -0
  57. package/dist/esm-node/ultramodern-workspace/write-app.js +9 -3
  58. package/dist/esm-node/ultramodern-workspace/write-workspace.js +6 -4
  59. package/dist/types/ultramodern-tooling/commands/migrate-strict-effect/shared-api-infrastructure.d.ts +4 -0
  60. package/dist/types/ultramodern-workspace/api/client.d.ts +3 -1
  61. package/dist/types/ultramodern-workspace/api/service.d.ts +3 -1
  62. package/dist/types/ultramodern-workspace/api/shared.d.ts +2 -0
  63. package/dist/types/ultramodern-workspace/package-json.d.ts +1 -1
  64. package/dist/types/ultramodern-workspace/policy.d.ts +35 -33
  65. package/dist/types/ultramodern-workspace/versions.d.ts +15 -15
  66. package/package.json +9 -9
  67. package/template-workspace/.modernjs/release-cohort.json +40 -40
  68. package/template-workspace/patches/{msgpackr@2.0.6.patch → msgpackr@2.1.0.patch} +3 -2
  69. package/template-workspace/patches/{zod@4.4.3.patch → zod@4.5.4.patch} +8 -6
  70. package/template-workspace/pnpm-workspace.yaml.handlebars +0 -1
  71. package/templates/packages/effect-bff-runtime.ts +50 -0
  72. package/templates/packages/microvertical-api-baseline.ts +102 -0
  73. package/templates/workspace-scripts/check-ultramodern-api-boundaries.mts +49 -28
  74. package/templates/workspace-scripts/microvertical-api-baseline-boundary.mts +944 -0
  75. package/templates/workspace-scripts/ultramodern-cloudflare-proof.mjs +25 -7
  76. package/templates/workspace-scripts/validate-ultramodern-workspace.mjs.handlebars +1 -1
  77. package/template-workspace/patches/@tanstack__router-core@1.171.27.patch +0 -28
package/README.md CHANGED
@@ -52,13 +52,13 @@ pnpm build
52
52
  ```
53
53
 
54
54
  The generated toolchain pins Node `26.7.0`, pnpm `11.24.0`, and
55
- `@types/node@^26.2.0`; its engine baseline remains Node `>=26` with pnpm `11+`.
55
+ `@types/node@^26.4.1`; its engine baseline remains Node `>=26` with pnpm `11+`.
56
56
  `packageManager`, `.mise.toml`, generated validation, and CI should all agree
57
57
  on those values; do not reintroduce Corepack or older pnpm aliases.
58
58
 
59
- The current generated dependency cohort also pins `@effect/tsgo@0.37.0`,
60
- `@tanstack/react-router@1.170.32`, `@tanstack/router-core@1.171.27`,
61
- `@tanstack/history@1.162.1`, and the Module Federation integration `2.9.0`
59
+ The current generated dependency cohort also pins `@effect/tsgo@0.41.0`,
60
+ `@tanstack/react-router@1.170.33`, `@tanstack/router-core@1.171.28`,
61
+ `@tanstack/history@1.162.2`, and the Module Federation integration `2.9.0`
62
62
  cohort, `@module-federation/node@2.7.50`. Move these only through the
63
63
  generator-owned version policy so templates, validation, and the published
64
64
  workspace contract stay aligned.
@@ -113,6 +113,7 @@ function mergeTypeScriptConfig(generated, existing) {
113
113
  ...existingCompilerOptions,
114
114
  ...generatedCompilerOptions
115
115
  };
116
+ if (Array.isArray(generatedCompilerOptions.types)) compilerOptions.types = mergeUniqueJsonValues(generatedCompilerOptions.types, existingCompilerOptions.types);
116
117
  if (Array.isArray(generatedCompilerOptions.plugins) || Array.isArray(existingCompilerOptions.plugins)) compilerOptions.plugins = mergeTypeScriptPlugins(generatedCompilerOptions.plugins, existingCompilerOptions.plugins);
117
118
  const merged = {
118
119
  ...existingConfig,
@@ -170,6 +170,8 @@ function mergeGeneratedScript(consumer, framework, canRetireLegacyOxfmtCliExclus
170
170
  const frameworkSegmentSet = new Set(frameworkSegments);
171
171
  const canonicalFrameworkSegment = (segment)=>{
172
172
  if (frameworkSegmentSet.has(segment)) return segment;
173
+ const referenceBuild = segment.replace('--project tsconfig.json', '--build tsconfig.json');
174
+ if (frameworkSegmentSet.has(referenceBuild)) return referenceBuild;
173
175
  const portableEnvironmentSegment = `cross-env ${segment}`;
174
176
  if (frameworkSegmentSet.has(portableEnvironmentSegment)) return portableEnvironmentSegment;
175
177
  const portableOxfmtSegment = segment.replace(/ '!repos\/\*\*'$/u, '');
@@ -126,6 +126,25 @@ const reviewedAugust24And25StaleReleaseAgeEntries = [
126
126
  'caniuse-lite@1.0.30001810',
127
127
  'electron-to-chromium@1.5.414'
128
128
  ];
129
+ const reviewedAugust26StaleReleaseAgeEntries = [
130
+ '@rsbuild/core@2.2.0',
131
+ '@rspack/binding-darwin-arm64@2.2.0',
132
+ '@rspack/binding-darwin-x64@2.2.0',
133
+ '@rspack/binding-linux-arm64-gnu@2.2.0',
134
+ '@rspack/binding-linux-arm64-musl@2.2.0',
135
+ '@rspack/binding-linux-ppc64-gnu@2.2.0',
136
+ '@rspack/binding-linux-riscv64-gnu@2.2.0',
137
+ '@rspack/binding-linux-riscv64-musl@2.2.0',
138
+ '@rspack/binding-linux-s390x-gnu@2.2.0',
139
+ '@rspack/binding-linux-x64-gnu@2.2.0',
140
+ '@rspack/binding-linux-x64-musl@2.2.0',
141
+ '@rspack/binding-wasm32-wasi@2.2.0',
142
+ '@rspack/binding-win32-arm64-msvc@2.2.0',
143
+ '@rspack/binding-win32-ia32-msvc@2.2.0',
144
+ '@rspack/binding-win32-x64-msvc@2.2.0',
145
+ '@rspack/binding@2.2.0',
146
+ '@rspack/core@2.2.0'
147
+ ];
129
148
  const knownStaleReleaseAgeEntries = new Set([
130
149
  '@effect/opentelemetry@4.0.0-beta.92',
131
150
  '@effect/opentelemetry@4.0.0-beta.94',
@@ -149,6 +168,7 @@ const knownStaleReleaseAgeEntries = new Set([
149
168
  ...staleOxcBindingTargets.map((target)=>`@oxlint/binding-${target}@1.79.0`),
150
169
  ...reviewedAugust10StaleReleaseAgeEntries,
151
170
  ...reviewedAugust24And25StaleReleaseAgeEntries,
171
+ ...reviewedAugust26StaleReleaseAgeEntries,
152
172
  ...policy_cjs_namespaceObject.ULTRAMODERN_WORKSPACE_POLICY.pnpm.releaseAge.approvals.filter((approval)=>approval.packageName.startsWith('@module-federation/')).map((approval)=>`${approval.packageName}@2.6.0`)
153
173
  ]);
154
174
  const canonicalReleaseAgeEntries = new Set(policy_cjs_namespaceObject.ULTRAMODERN_WORKSPACE_POLICY.pnpm.releaseAge.approvals.map((approval)=>`${approval.packageName}@${approval.version}`));
@@ -0,0 +1,99 @@
1
+ "use strict";
2
+ var __webpack_require__ = {};
3
+ (()=>{
4
+ __webpack_require__.n = (module)=>{
5
+ var getter = module && module.__esModule ? ()=>module['default'] : ()=>module;
6
+ __webpack_require__.d(getter, {
7
+ a: getter
8
+ });
9
+ return getter;
10
+ };
11
+ })();
12
+ (()=>{
13
+ __webpack_require__.d = (exports1, getters, values)=>{
14
+ var define = (defs, kind)=>{
15
+ for(var key in defs)if (__webpack_require__.o(defs, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
16
+ enumerable: true,
17
+ [kind]: defs[key]
18
+ });
19
+ };
20
+ define(getters, "get");
21
+ define(values, "value");
22
+ };
23
+ })();
24
+ (()=>{
25
+ __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
26
+ })();
27
+ (()=>{
28
+ __webpack_require__.r = (exports1)=>{
29
+ if ("u" > typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
30
+ value: 'Module'
31
+ });
32
+ Object.defineProperty(exports1, '__esModule', {
33
+ value: true
34
+ });
35
+ };
36
+ })();
37
+ var __webpack_exports__ = {};
38
+ __webpack_require__.r(__webpack_exports__);
39
+ __webpack_require__.d(__webpack_exports__, {
40
+ ensureSharedApiInfrastructure: ()=>ensureSharedApiInfrastructure
41
+ });
42
+ const external_node_fs_namespaceObject = require("node:fs");
43
+ var external_node_fs_default = /*#__PURE__*/ __webpack_require__.n(external_node_fs_namespaceObject);
44
+ const external_node_path_namespaceObject = require("node:path");
45
+ var external_node_path_default = /*#__PURE__*/ __webpack_require__.n(external_node_path_namespaceObject);
46
+ const fs_io_cjs_namespaceObject = require("../../../ultramodern-workspace/fs-io.cjs");
47
+ const package_json_cjs_namespaceObject = require("../../../ultramodern-workspace/package-json.cjs");
48
+ const external_io_cjs_namespaceObject = require("./io.cjs");
49
+ const directory = 'packages/shared-contracts';
50
+ function record(value, label) {
51
+ if (null === value || 'object' != typeof value || Array.isArray(value)) throw new Error(`${label} must be an object; resolve it before migration.`);
52
+ return value;
53
+ }
54
+ function ensureSharedApiInfrastructure(io, scope, packageSource) {
55
+ for (const relativePath of [
56
+ 'packages',
57
+ directory,
58
+ `${directory}/package.json`,
59
+ `${directory}/src`,
60
+ `${directory}/src/index.ts`
61
+ ])if (external_node_fs_default().lstatSync(external_node_path_default().join(io.workspaceRoot, relativePath), {
62
+ throwIfNoEntry: false
63
+ })?.isSymbolicLink()) throw new Error(`Shared API migration cannot write through a symbolic link: ${relativePath}`);
64
+ const manifestPath = external_node_path_default().join(io.workspaceRoot, directory, 'package.json');
65
+ const defaults = (0, package_json_cjs_namespaceObject.createSharedPackage)(scope, 'shared-contracts', 'Shared workspace contracts', packageSource);
66
+ const manifest = external_node_fs_default().existsSync(manifestPath) ? record((0, external_io_cjs_namespaceObject.readJsonFile)(manifestPath), `${directory}/package.json`) : defaults;
67
+ const exports1 = void 0 === manifest.exports ? {} : 'string' == typeof manifest.exports ? {
68
+ '.': manifest.exports
69
+ } : record(manifest.exports, `${directory}/package.json exports`);
70
+ if (Object.keys(exports1).some((key)=>!key.startsWith('.')) || void 0 !== exports1['.'] && './src/index.ts' !== exports1['.']) throw new Error(`${directory}/package.json exports must expose ./src/index.ts at "." before adding shared API infrastructure; consumer exports were not overwritten.`);
71
+ for (const [subpath, target] of Object.entries(record(defaults.exports, 'Shared contract exports')))if (void 0 !== exports1[subpath] && exports1[subpath] !== target) throw new Error(`${directory}/package.json ${subpath} must expose ${String(target)}; consumer exports were not overwritten.`);
72
+ const dependencies = record(manifest.dependencies ?? {}, `${directory}/package.json dependencies`);
73
+ manifest.exports = {
74
+ ...record(defaults.exports, 'Shared contract exports'),
75
+ ...exports1
76
+ };
77
+ manifest.dependencies = {
78
+ ...record(defaults.dependencies, 'Shared contract dependencies'),
79
+ ...dependencies
80
+ };
81
+ const writeMissing = (relativePath, content)=>{
82
+ const filePath = external_node_path_default().join(io.workspaceRoot, directory, relativePath);
83
+ if (void 0 === external_node_fs_default().lstatSync(filePath, {
84
+ throwIfNoEntry: false
85
+ })) io.writeGenerated(filePath, content);
86
+ };
87
+ writeMissing('src/effect-bff-runtime.ts', (0, fs_io_cjs_namespaceObject.readFileTemplate)('packages/effect-bff-runtime.ts'));
88
+ writeMissing('src/microvertical-api-baseline.ts', (0, fs_io_cjs_namespaceObject.readFileTemplate)('packages/microvertical-api-baseline.ts'));
89
+ writeMissing('tsconfig.json', `${JSON.stringify((0, package_json_cjs_namespaceObject.createSharedPackageTsConfig)(directory), null, 2)}\n`);
90
+ writeMissing('src/index.ts', (0, fs_io_cjs_namespaceObject.readFileTemplate)('packages/shared-contracts-index.ts'));
91
+ (0, external_io_cjs_namespaceObject.writeJsonFile)(io, manifestPath, manifest);
92
+ }
93
+ exports.ensureSharedApiInfrastructure = __webpack_exports__.ensureSharedApiInfrastructure;
94
+ for(var __rspack_i in __webpack_exports__)if (-1 === [
95
+ "ensureSharedApiInfrastructure"
96
+ ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
97
+ Object.defineProperty(exports, '__esModule', {
98
+ value: true
99
+ });
@@ -80,6 +80,7 @@ function updateRootPackageToolchain(packageJson) {
80
80
  const devDependencies = ensureRecord(packageJson, 'devDependencies', 'package.json devDependencies');
81
81
  for (const packageName of retiredRootToolingDependencies)delete devDependencies[packageName];
82
82
  devDependencies["@typescript/native"] = policy_cjs_namespaceObject.ULTRAMODERN_PACKAGE_PINS.rootDevDependencies["@typescript/native"];
83
+ devDependencies['@types/node'] = policy_cjs_namespaceObject.ULTRAMODERN_PACKAGE_PINS.rootDevDependencies["@types/node"];
83
84
  devDependencies.miniflare = policy_cjs_namespaceObject.ULTRAMODERN_PACKAGE_PINS.rootDevDependencies.miniflare;
84
85
  }
85
86
  function updateMiseTools(content) {
@@ -61,6 +61,7 @@ const package_cohort_cjs_namespaceObject = require("./migrate-strict-effect/pack
61
61
  const package_source_cjs_namespaceObject = require("./migrate-strict-effect/package-source.cjs");
62
62
  const pnpm_policy_cjs_namespaceObject = require("./migrate-strict-effect/pnpm-policy.cjs");
63
63
  const react_router_retirement_cjs_namespaceObject = require("./migrate-strict-effect/react-router-retirement.cjs");
64
+ const shared_api_infrastructure_cjs_namespaceObject = require("./migrate-strict-effect/shared-api-infrastructure.cjs");
64
65
  const toolchain_pins_cjs_namespaceObject = require("./migrate-strict-effect/toolchain-pins.cjs");
65
66
  const external_options_cjs_namespaceObject = require("./options.cjs");
66
67
  const retiredMetadataPaths = [
@@ -325,6 +326,7 @@ function migrateStrictEffect(args, context, io, dryRun, skipInstall) {
325
326
  const verticalApps = migrated.topology.apps.filter((app)=>'shell' !== app.kind);
326
327
  const hasBackendSurface = verticalApps.some((app)=>app.api);
327
328
  const shellOnly = 0 === verticalApps.length;
329
+ if (hasBackendSurface) (0, shared_api_infrastructure_cjs_namespaceObject.ensureSharedApiInfrastructure)(io, migrated.workspace.packageScope, packageSource);
328
330
  if (shellOnly) {
329
331
  io.log('Shell-only workspace: skipping backend-federation and Zerops runtime stages.');
330
332
  for (const relativePath of [
@@ -35,7 +35,7 @@ const external_descriptors_cjs_namespaceObject = require("../descriptors.cjs");
35
35
  const external_naming_cjs_namespaceObject = require("../naming.cjs");
36
36
  const external_checkout_cart_cjs_namespaceObject = require("./checkout-cart.cjs");
37
37
  const external_names_cjs_namespaceObject = require("./names.cjs");
38
- function createApiClient(service, contractImportPath) {
38
+ function createApiClient(service, contractImportPath, options) {
39
39
  const apiExport = (0, external_names_cjs_namespaceObject.verticalApiExport)(service);
40
40
  const contractExport = (0, external_names_cjs_namespaceObject.verticalApiGroupName)(service);
41
41
  const stem = (0, external_descriptors_cjs_namespaceObject.resolveApiStem)(service);
@@ -151,7 +151,7 @@ export const ${readinessName} = (
151
151
  operationContext:
152
152
  options.operationContext ?? ${groupName}OperationContexts.readiness,
153
153
  }).pipe(
154
- Effect.flatMap(client => client.${groupName}.readiness({})),
154
+ Effect.flatMap(client => client.${options ? 'foundation' : groupName}.readiness({})),
155
155
  );
156
156
 
157
157
  export const ${getName} = (
@@ -37,23 +37,22 @@ const external_naming_cjs_namespaceObject = require("../naming.cjs");
37
37
  const external_checkout_cart_cjs_namespaceObject = require("./checkout-cart.cjs");
38
38
  const external_names_cjs_namespaceObject = require("./names.cjs");
39
39
  const external_rpc_cjs_namespaceObject = require("./rpc.cjs");
40
- function createApiServiceEntry(service, contractImportPath) {
40
+ function createApiServiceEntry(service, contractImportPath, options) {
41
41
  if ((service.api?.protocol ?? 'rest') === 'rpc') return (0, external_rpc_cjs_namespaceObject.createRpcApiServiceEntry)(service);
42
42
  const apiExport = (0, external_names_cjs_namespaceObject.verticalApiExport)(service);
43
43
  const groupName = (0, external_names_cjs_namespaceObject.verticalApiGroupName)(service);
44
44
  const notFoundErrorExport = (0, external_names_cjs_namespaceObject.verticalApiNotFoundErrorExport)(service);
45
45
  const stem = (0, external_descriptors_cjs_namespaceObject.resolveApiStem)(service);
46
- return `import {
47
- defineEffectBff,
46
+ const assemblyImport = options ? `import { assembleEffectBffRuntime } from '${(0, external_naming_cjs_namespaceObject.packageName)(options.scope, 'shared-contracts')}/server/effect-bff-runtime';\n` : '';
47
+ return `${assemblyImport}import {
48
+ ${options ? '' : 'defineEffectBff,'}
48
49
  Effect,
49
50
  HttpApiBuilder,
50
51
  Layer,
51
52
  } from '@modern-js/plugin-bff/effect-edge';
52
- import type {
53
- EffectBffDefinition,
54
- EffectBffRuntime,
53
+ ${options ? '' : `import type {
55
54
  EffectRuntimeLayer,
56
- } from '@modern-js/plugin-bff/effect-edge';
55
+ } from '@modern-js/plugin-bff/effect-edge';`}
57
56
  import { ultramodernApiMarker } from '../shared/ultramodern-build.ts';
58
57
  import {
59
58
  ${apiExport},
@@ -83,6 +82,31 @@ const operationAttributes = (operationContext: OperationContext) => ({
83
82
  : {}),
84
83
  });
85
84
 
85
+ ${options ? `const ${groupName}ReadinessLayer = HttpApiBuilder.group(
86
+ ${apiExport},
87
+ 'foundation',
88
+ handlers => handlers
89
+ .handle('readiness', () =>
90
+ Effect.succeed({
91
+ checks: {
92
+ api: 'ready' as const,
93
+ moduleFederation: 'ready' as const,
94
+ ssr: 'ready' as const,
95
+ translations: 'ready' as const,
96
+ },
97
+ marker: ultramodernApiMarker,
98
+ status: 'ready' as const,
99
+ versionSkew: 'none' as const,
100
+ }).pipe(
101
+ Effect.withSpan('ultramodern.api.${groupName}.readiness', {
102
+ attributes: operationAttributes(${groupName}OperationContexts.readiness),
103
+ kind: 'server',
104
+ }),
105
+ ),
106
+ )
107
+ ,
108
+ );` : ''}
109
+
86
110
  const ${groupName}Layer = HttpApiBuilder.group(
87
111
  ${apiExport},
88
112
  '${groupName}',
@@ -101,7 +125,7 @@ const ${groupName}Layer = HttpApiBuilder.group(
101
125
  }),
102
126
  ),
103
127
  )
104
- .handle('readiness', () =>
128
+ ${options ? '' : ` .handle('readiness', () =>
105
129
  Effect.succeed({
106
130
  checks: {
107
131
  api: 'ready' as const,
@@ -119,6 +143,7 @@ const ${groupName}Layer = HttpApiBuilder.group(
119
143
  }),
120
144
  ),
121
145
  )
146
+ `}
122
147
  .handle('get', ({ params }) => {
123
148
  const matchedItem = ${groupName}Items.find(
124
149
  candidate => candidate.id === params.id,
@@ -158,14 +183,18 @@ const ${groupName}Layer = HttpApiBuilder.group(
158
183
  )${(0, external_checkout_cart_cjs_namespaceObject.createCheckoutCartServerHandlers)(service)},
159
184
  );
160
185
 
161
- const layer = HttpApiBuilder.layer(${apiExport}).pipe(
162
- Layer.provide(${groupName}Layer),
163
- ) satisfies EffectRuntimeLayer;
164
- const apiRuntime: EffectBffDefinition<typeof ${apiExport}, EffectRuntimeLayer> &
165
- EffectBffRuntime<typeof ${apiExport}, EffectRuntimeLayer> = defineEffectBff({
166
- api: ${apiExport},
167
- layer,
168
- });
186
+ ${options ? `const apiHandlersLive = Layer.mergeAll(${groupName}Layer, ${groupName}ReadinessLayer);
187
+ export const make${apiExport[0].toUpperCase()}${apiExport.slice(1)}Runtime = () =>
188
+ assembleEffectBffRuntime({
189
+ api: ${apiExport},
190
+ handlers: apiHandlersLive,
191
+ });` : `export const make${apiExport[0].toUpperCase()}${apiExport.slice(1)}Runtime = () => {
192
+ const layer = HttpApiBuilder.layer(${apiExport}).pipe(
193
+ Layer.provide(${groupName}Layer),
194
+ ) satisfies EffectRuntimeLayer;
195
+ return defineEffectBff({ api: ${apiExport}, layer });
196
+ };`}
197
+ const apiRuntime = make${apiExport[0].toUpperCase()}${apiExport.slice(1)}Runtime();
169
198
 
170
199
  export default apiRuntime;
171
200
  `;
@@ -45,7 +45,7 @@ function createSharedApiImports() {
45
45
  } from '@modern-js/plugin-bff/effect-client';
46
46
  `;
47
47
  }
48
- function createSharedApiContract(service) {
48
+ function createSharedApiContract(service, shared = false) {
49
49
  const schemaExport = (0, external_names_cjs_namespaceObject.verticalApiSchemaExport)(service);
50
50
  const markerSchemaExport = (0, external_names_cjs_namespaceObject.verticalApiMarkerSchemaExport)(service);
51
51
  const readinessSchemaExport = (0, external_names_cjs_namespaceObject.verticalApiReadinessSchemaExport)(service);
@@ -102,7 +102,7 @@ function createSharedApiContract(service) {
102
102
  listOperationContext,
103
103
  readinessOperationContext
104
104
  }).trim();
105
- return `export interface ${markerType} {
105
+ return `${shared ? `export type ${markerType} = MicroVerticalBuildMarker;` : `export interface ${markerType} {
106
106
  readonly appId: string;
107
107
  readonly build: string;
108
108
  readonly buildMarker: string;
@@ -112,7 +112,7 @@ function createSharedApiContract(service) {
112
112
  readonly surface: string;
113
113
  readonly unitId: string;
114
114
  readonly version: string;
115
- }
115
+ }`}
116
116
 
117
117
  export interface ${itemType} {
118
118
  readonly id: string;
@@ -120,7 +120,7 @@ export interface ${itemType} {
120
120
  readonly title: string;
121
121
  }
122
122
 
123
- export interface ${readinessType} {
123
+ ${shared ? `export type ${readinessType} = MicroVerticalReadiness;` : `export interface ${readinessType} {
124
124
  readonly checks: {
125
125
  readonly api: 'ready';
126
126
  readonly moduleFederation: 'ready';
@@ -130,7 +130,7 @@ export interface ${readinessType} {
130
130
  readonly marker: ${markerType};
131
131
  readonly status: 'ready';
132
132
  readonly versionSkew: 'none';
133
- }
133
+ }`}
134
134
 
135
135
  export interface ${createPayloadType} {
136
136
  readonly title: string;
@@ -149,7 +149,7 @@ export interface ${notFoundErrorExport} {
149
149
  readonly id: string;
150
150
  }
151
151
 
152
- export const ${markerSchemaExport}: Schema.Codec<${markerType}> = Schema.Struct({
152
+ ${shared ? `export const ${markerSchemaExport}: Schema.Codec<${markerType}> = MicroVerticalBuildMarkerSchema;` : `export const ${markerSchemaExport}: Schema.Codec<${markerType}> = Schema.Struct({
153
153
  appId: Schema.String,
154
154
  build: Schema.String,
155
155
  buildMarker: Schema.String,
@@ -159,7 +159,7 @@ export const ${markerSchemaExport}: Schema.Codec<${markerType}> = Schema.Struct(
159
159
  surface: Schema.String,
160
160
  unitId: Schema.String,
161
161
  version: Schema.String,
162
- });
162
+ });`}
163
163
 
164
164
  export const ${schemaExport}: Schema.Codec<${itemType}> = Schema.Struct({
165
165
  id: Schema.String,
@@ -167,7 +167,7 @@ export const ${schemaExport}: Schema.Codec<${itemType}> = Schema.Struct({
167
167
  title: Schema.String,
168
168
  });
169
169
 
170
- export const ${readinessSchemaExport}: Schema.Codec<${readinessType}> = Schema.Struct({
170
+ ${shared ? `export const ${readinessSchemaExport}: Schema.Codec<${readinessType}> = MicroVerticalReadinessSchema;` : `export const ${readinessSchemaExport}: Schema.Codec<${readinessType}> = Schema.Struct({
171
171
  checks: Schema.Struct({
172
172
  api: Schema.Literal('ready'),
173
173
  moduleFederation: Schema.Literal('ready'),
@@ -177,7 +177,7 @@ export const ${readinessSchemaExport}: Schema.Codec<${readinessType}> = Schema.S
177
177
  marker: ${markerSchemaExport},
178
178
  status: Schema.Literal('ready'),
179
179
  versionSkew: Schema.Literal('none'),
180
- });
180
+ });`}
181
181
 
182
182
  export const ${createPayloadSchemaExport}: Schema.Codec<${createPayloadType}> = Schema.Struct({
183
183
  title: Schema.String,
@@ -189,7 +189,7 @@ ${checkoutCartSharedSchemaSection}export const ${notFoundSchemaExport}: Schema.C
189
189
  HttpApiSchema.status(404),
190
190
  );
191
191
 
192
- export interface OperationContext {
192
+ ${shared ? 'export type OperationContext = MicroVerticalOperationContext;' : `export interface OperationContext {
193
193
  method: string;
194
194
  operationId: string;
195
195
  routePath: string;
@@ -201,9 +201,14 @@ export interface OperationContext {
201
201
  | 'data-platform'
202
202
  | 'unknown';
203
203
  traceId?: string;
204
- }
204
+ }`}
205
205
 
206
- export const ${apiExport} = HttpApi.make('${apiName}').add(
206
+ ${shared ? `export const ${groupName}FoundationApi = HttpApi.make('${apiName}Foundation').add(
207
+ HttpApiGroup.make('foundation').add(
208
+ HttpApiEndpoint.get('readiness', '/${stem}/readiness', { success: ${readinessSchemaExport} }),
209
+ ),
210
+ );` : ''}
211
+ export const ${apiExport} = HttpApi.make('${apiName}')${shared ? `.addHttpApi(${groupName}FoundationApi)` : ''}.add(
207
212
  HttpApiGroup.make('${groupName}')
208
213
  .add(
209
214
  HttpApiEndpoint.get('list', '/${stem}', {
@@ -215,11 +220,12 @@ export const ${apiExport} = HttpApi.make('${apiName}').add(
215
220
  }),
216
221
  }),
217
222
  )
218
- .add(
223
+ ${shared ? '' : ` .add(
219
224
  HttpApiEndpoint.get('readiness', '/${stem}/readiness', {
220
225
  success: ${readinessSchemaExport},
221
226
  }),
222
227
  )
228
+ `}
223
229
  .add(
224
230
  HttpApiEndpoint.get('get', '/${stem}/:id', {
225
231
  error: ${notFoundSchemaExport},
@@ -240,7 +246,7 @@ export const ${apiExport} = HttpApi.make('${apiName}').add(
240
246
  );
241
247
 
242
248
  export const ${groupName}OperationContexts = {
243
- ${operationContextEntries}
249
+ ${shared ? operationContextEntries.replaceAll(/(\w+: )\{([\s\S]*?)\},/gu, (_, key, fields)=>`${key}createMicroVerticalOperationContext({${fields.replace(/\n\s*source: 'generated-client',/u, '')}}),`) : operationContextEntries}
244
250
  } satisfies Record<string, OperationContext>;
245
251
 
246
252
  export const ${groupName}ApiContract = {
@@ -251,9 +257,13 @@ ${(0, external_checkout_cart_cjs_namespaceObject.createCheckoutCartApiContractFi
251
257
  } as const;
252
258
  `;
253
259
  }
254
- function createSharedApi(service) {
260
+ function createSharedApi(service, options) {
261
+ const imports = options ? `import { MicroVerticalBuildMarkerSchema, MicroVerticalReadinessSchema, createMicroVerticalOperationContext } from '${(0, external_naming_cjs_namespaceObject.packageName)(options.scope, 'shared-contracts')}/microvertical-api-baseline';
262
+ import type { MicroVerticalBuildMarker, MicroVerticalReadiness, MicroVerticalOperationContext } from '${(0, external_naming_cjs_namespaceObject.packageName)(options.scope, 'shared-contracts')}/microvertical-api-baseline';
263
+ ` : '';
255
264
  return `${createSharedApiImports()}
256
- ${createSharedApiContract(service)}`;
265
+ ${imports}
266
+ ${createSharedApiContract(service, void 0 !== options)}`;
257
267
  }
258
268
  exports.createSharedApi = __webpack_exports__.createSharedApi;
259
269
  for(var __rspack_i in __webpack_exports__)if (-1 === [
@@ -43,7 +43,11 @@ function extractExposes(configPath, value) {
43
43
  if (array) return array.sort();
44
44
  throw new Error(`Cannot statically extract Module Federation exposes from ${configPath}; use a literal exposes object or string array.`);
45
45
  }
46
- function extractDtsSettings(configPath, value) {
46
+ function extractDtsSettings(configPath, value, exposes) {
47
+ if ('false' === value) {
48
+ if (exposes.length > 0) throw new Error(`Module Federation DTS cannot be disabled for exposed app ${configPath}.`);
49
+ return {};
50
+ }
47
51
  if (void 0 === value) return {};
48
52
  const dts = (0, external_object_literal_cjs_namespaceObject.parseObjectLiteral)(value);
49
53
  if (!dts || dts.hasSpread) throw new Error(`Cannot statically extract Module Federation DTS settings from ${configPath}; use a literal dts object.`);
@@ -70,7 +74,7 @@ function inspectModuleFederationConfigSource(source, appDir, configPath) {
70
74
  return {
71
75
  appDir,
72
76
  configPath,
73
- dts: extractDtsSettings(configPath, properties.properties.get('dts')),
77
+ dts: extractDtsSettings(configPath, properties.properties.get('dts'), exposes),
74
78
  exposes,
75
79
  hostOnlyNoExposes
76
80
  };
@@ -79,22 +79,17 @@ const ultramodernBuildArtifact = {
79
79
  },
80
80
  } as const;
81
81
 
82
- export { ultramodernBuildArtifact };
83
-
84
82
  export const ultramodernDeliveryUnit =
85
83
  ultramodernBuildArtifact.deliveryUnit;
86
- export const ultramodernVerticalIdentity = ultramodernDeliveryUnit;
87
84
  export const ultramodernUiMarker = ultramodernBuildArtifact.surfaces.ui;
88
85
  export const ultramodernApiMarker = ultramodernBuildArtifact.surfaces.api;
89
86
  `;
90
87
  }
91
88
  function createUltramodernBuildReexportModule() {
92
89
  return `export {
93
- ultramodernBuildArtifact,
94
90
  ultramodernApiMarker,
95
91
  ultramodernDeliveryUnit,
96
92
  ultramodernUiMarker,
97
- ultramodernVerticalIdentity,
98
93
  } from '../shared/ultramodern-build';
99
94
  `;
100
95
  }
@@ -214,7 +214,7 @@ function createAppPackage(scope, app, packageSource, enableTailwind, remotes = [
214
214
  if (Object.keys(packageExports).length > 0) packageJson.exports = packageExports;
215
215
  return packageJson;
216
216
  }
217
- function createSharedPackage(scope, id, description) {
217
+ function createSharedPackage(scope, id, description, packageSource) {
218
218
  const packageJson = {
219
219
  private: true,
220
220
  name: (0, external_naming_cjs_namespaceObject.packageName)(scope, id),
@@ -231,6 +231,17 @@ function createSharedPackage(scope, id, description) {
231
231
  '@effect/tsgo': external_policy_cjs_namespaceObject.ULTRAMODERN_PACKAGE_PINS.appDevDependencies["@effect/tsgo"]
232
232
  }
233
233
  };
234
+ if ('shared-contracts' === id) {
235
+ packageJson.exports = {
236
+ '.': './src/index.ts',
237
+ './microvertical-api-baseline': './src/microvertical-api-baseline.ts',
238
+ './server/effect-bff-runtime': './src/effect-bff-runtime.ts'
239
+ };
240
+ packageJson.dependencies = {
241
+ ...external_policy_cjs_namespaceObject.ULTRAMODERN_PACKAGE_PINS.bffEffectDependencies,
242
+ '@modern-js/plugin-bff': packageSource ? (0, external_ultramodern_package_source_cjs_namespaceObject.modernPackageSpecifier)('@modern-js/plugin-bff', packageSource) : external_ultramodern_package_source_cjs_namespaceObject.WORKSPACE_PACKAGE_VERSION
243
+ };
244
+ }
234
245
  if ('shared-design-tokens' === id) packageJson.exports = {
235
246
  ...packageJson.exports,
236
247
  './tokens.css': './src/tokens.css'