@bleedingdev/modern-js-ultramodern-create 3.9.0-ultramodern.2 → 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 (65) hide show
  1. package/dist/cjs/ultramodern-tooling/commands/migrate-strict-effect/generated-artifacts-typescript.cjs +1 -0
  2. package/dist/cjs/ultramodern-tooling/commands/migrate-strict-effect/package-cohort.cjs +2 -0
  3. package/dist/cjs/ultramodern-tooling/commands/migrate-strict-effect/shared-api-infrastructure.cjs +99 -0
  4. package/dist/cjs/ultramodern-tooling/commands/migrate-strict-effect/toolchain-pins.cjs +1 -0
  5. package/dist/cjs/ultramodern-tooling/commands/migrate-strict-effect.cjs +2 -0
  6. package/dist/cjs/ultramodern-workspace/api/client.cjs +2 -2
  7. package/dist/cjs/ultramodern-workspace/api/service.cjs +45 -16
  8. package/dist/cjs/ultramodern-workspace/api/shared.cjs +26 -16
  9. package/dist/cjs/ultramodern-workspace/mf-validation/inspect.cjs +6 -2
  10. package/dist/cjs/ultramodern-workspace/module-federation/reexport-module.cjs +0 -5
  11. package/dist/cjs/ultramodern-workspace/package-json.cjs +12 -1
  12. package/dist/cjs/ultramodern-workspace/policy.cjs +1 -0
  13. package/dist/cjs/ultramodern-workspace/tsconfigs.cjs +3 -0
  14. package/dist/cjs/ultramodern-workspace/workspace-script-plan.cjs +1 -1
  15. package/dist/cjs/ultramodern-workspace/workspace-scripts.cjs +5 -0
  16. package/dist/cjs/ultramodern-workspace/write-app.cjs +9 -3
  17. package/dist/cjs/ultramodern-workspace/write-workspace.cjs +5 -3
  18. package/dist/esm/ultramodern-tooling/commands/migrate-strict-effect/generated-artifacts-typescript.js +1 -0
  19. package/dist/esm/ultramodern-tooling/commands/migrate-strict-effect/package-cohort.js +2 -0
  20. package/dist/esm/ultramodern-tooling/commands/migrate-strict-effect/shared-api-infrastructure.js +50 -0
  21. package/dist/esm/ultramodern-tooling/commands/migrate-strict-effect/toolchain-pins.js +1 -0
  22. package/dist/esm/ultramodern-tooling/commands/migrate-strict-effect.js +2 -0
  23. package/dist/esm/ultramodern-workspace/api/client.js +2 -2
  24. package/dist/esm/ultramodern-workspace/api/service.js +45 -16
  25. package/dist/esm/ultramodern-workspace/api/shared.js +27 -17
  26. package/dist/esm/ultramodern-workspace/mf-validation/inspect.js +6 -2
  27. package/dist/esm/ultramodern-workspace/module-federation/reexport-module.js +0 -5
  28. package/dist/esm/ultramodern-workspace/package-json.js +12 -1
  29. package/dist/esm/ultramodern-workspace/policy.js +1 -0
  30. package/dist/esm/ultramodern-workspace/tsconfigs.js +3 -0
  31. package/dist/esm/ultramodern-workspace/workspace-script-plan.js +1 -1
  32. package/dist/esm/ultramodern-workspace/workspace-scripts.js +5 -0
  33. package/dist/esm/ultramodern-workspace/write-app.js +9 -3
  34. package/dist/esm/ultramodern-workspace/write-workspace.js +6 -4
  35. package/dist/esm-node/ultramodern-tooling/commands/migrate-strict-effect/generated-artifacts-typescript.js +1 -0
  36. package/dist/esm-node/ultramodern-tooling/commands/migrate-strict-effect/package-cohort.js +2 -0
  37. package/dist/esm-node/ultramodern-tooling/commands/migrate-strict-effect/shared-api-infrastructure.js +51 -0
  38. package/dist/esm-node/ultramodern-tooling/commands/migrate-strict-effect/toolchain-pins.js +1 -0
  39. package/dist/esm-node/ultramodern-tooling/commands/migrate-strict-effect.js +2 -0
  40. package/dist/esm-node/ultramodern-workspace/api/client.js +2 -2
  41. package/dist/esm-node/ultramodern-workspace/api/service.js +45 -16
  42. package/dist/esm-node/ultramodern-workspace/api/shared.js +27 -17
  43. package/dist/esm-node/ultramodern-workspace/mf-validation/inspect.js +6 -2
  44. package/dist/esm-node/ultramodern-workspace/module-federation/reexport-module.js +0 -5
  45. package/dist/esm-node/ultramodern-workspace/package-json.js +12 -1
  46. package/dist/esm-node/ultramodern-workspace/policy.js +1 -0
  47. package/dist/esm-node/ultramodern-workspace/tsconfigs.js +3 -0
  48. package/dist/esm-node/ultramodern-workspace/workspace-script-plan.js +1 -1
  49. package/dist/esm-node/ultramodern-workspace/workspace-scripts.js +5 -0
  50. package/dist/esm-node/ultramodern-workspace/write-app.js +9 -3
  51. package/dist/esm-node/ultramodern-workspace/write-workspace.js +6 -4
  52. package/dist/types/ultramodern-tooling/commands/migrate-strict-effect/shared-api-infrastructure.d.ts +4 -0
  53. package/dist/types/ultramodern-workspace/api/client.d.ts +3 -1
  54. package/dist/types/ultramodern-workspace/api/service.d.ts +3 -1
  55. package/dist/types/ultramodern-workspace/api/shared.d.ts +2 -0
  56. package/dist/types/ultramodern-workspace/package-json.d.ts +1 -1
  57. package/dist/types/ultramodern-workspace/policy.d.ts +2 -0
  58. package/package.json +4 -4
  59. package/template-workspace/.modernjs/release-cohort.json +40 -40
  60. package/templates/packages/effect-bff-runtime.ts +50 -0
  61. package/templates/packages/microvertical-api-baseline.ts +102 -0
  62. package/templates/workspace-scripts/check-ultramodern-api-boundaries.mts +49 -28
  63. package/templates/workspace-scripts/microvertical-api-baseline-boundary.mts +944 -0
  64. package/templates/workspace-scripts/ultramodern-cloudflare-proof.mjs +25 -7
  65. package/templates/workspace-scripts/validate-ultramodern-workspace.mjs.handlebars +1 -1
@@ -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, '');
@@ -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'
@@ -290,6 +290,7 @@ const ULTRAMODERN_PACKAGE_PINS = {
290
290
  rootDevDependencies: {
291
291
  '@effect/tsgo': external_versions_cjs_namespaceObject.EFFECT_TSGO_VERSION,
292
292
  "@typescript/native": `npm:typescript@${external_versions_cjs_namespaceObject.TYPESCRIPT_VERSION}`,
293
+ '@types/node': external_versions_cjs_namespaceObject.TYPES_NODE_VERSION,
293
294
  'cross-env': external_versions_cjs_namespaceObject.CROSS_ENV_VERSION,
294
295
  lefthook: external_versions_cjs_namespaceObject.LEFTHOOK_VERSION,
295
296
  miniflare: external_versions_cjs_namespaceObject.MINIFLARE_VERSION,
@@ -53,6 +53,9 @@ function createTsConfigBase() {
53
53
  return {
54
54
  compilerOptions: {
55
55
  target: 'ESNext',
56
+ types: [
57
+ 'node'
58
+ ],
56
59
  lib: [
57
60
  'ESNext',
58
61
  'DOM',
@@ -175,7 +175,7 @@ function createWorkspaceRootScriptPlan(remotes = [], options = {}) {
175
175
  migrateStrictEffect: rootToolingWrapperCommand('migrateStrictEffect'),
176
176
  zeropsMaterialize: "node ./scripts/materialize-zerops-runtime.mjs",
177
177
  contractCheck: rootToolingWrapperCommand('validate'),
178
- typecheck: options.typecheck ?? `${rootToolingWrapperCommand('typecheck')} --project tsconfig.json`,
178
+ typecheck: options.typecheck ?? `${rootToolingWrapperCommand('typecheck')} --build tsconfig.json`,
179
179
  check: `pnpm format:check && pnpm lint && pnpm typecheck && pnpm skills:check && pnpm i18n:boundaries && pnpm api:check && pnpm contract:check && pnpm performance:readiness${bridgeCheck}`
180
180
  };
181
181
  }
@@ -176,6 +176,7 @@ function writeGeneratedWorkspaceScripts(targetDir, scope, enableTailwind, remote
176
176
  const hasBackendSurface = remotes.some(external_descriptors_cjs_namespaceObject.appHasApi);
177
177
  writeWorkspaceOwnedMtsScript(targetDir, 'check-ultramodern-i18n-boundaries', createWorkspaceI18nBoundaryValidationScript());
178
178
  writeWorkspaceOwnedMtsScript(targetDir, 'check-ultramodern-api-boundaries', createWorkspaceApiBoundaryValidationScript());
179
+ writeWorkspaceOwnedMtsScript(targetDir, 'microvertical-api-baseline-boundary', (0, external_fs_io_cjs_namespaceObject.readFileTemplate)("workspace-scripts/microvertical-api-baseline-boundary.mts"));
179
180
  if (!shellOnly) {
180
181
  (0, external_fs_io_cjs_namespaceObject.writeFileReplacing)(targetDir, "scripts/materialize-zerops-runtime.mjs", createZeropsRuntimeMaterializationScript());
181
182
  writeWorkspaceOwnedMtsScript(targetDir, 'proof-workerd-ssr', createWorkerdSsrProofScript());
@@ -203,6 +204,10 @@ function migratedWorkspaceScriptArtifacts(options) {
203
204
  content: createWorkspaceI18nBoundaryValidationScript(),
204
205
  legacyPath: "scripts/check-ultramodern-i18n-boundaries.mjs"
205
206
  },
207
+ {
208
+ relativePath: "scripts/microvertical-api-baseline-boundary.mts",
209
+ content: (0, external_fs_io_cjs_namespaceObject.readFileTemplate)("workspace-scripts/microvertical-api-baseline-boundary.mts")
210
+ },
206
211
  {
207
212
  relativePath: "scripts/check-ultramodern-api-boundaries.mts",
208
213
  content: createWorkspaceApiBoundaryValidationScript(),
@@ -122,12 +122,18 @@ function writeAppApiAndRemoteExposeFiles({ targetDir, scope, resolvedApp, emitsU
122
122
  if ((0, external_descriptors_cjs_namespaceObject.appHasApi)(resolvedApp)) {
123
123
  const rpcProtocol = 'rpc' === (0, external_descriptors_cjs_namespaceObject.resolveApiProtocol)(resolvedApp);
124
124
  if (rpcProtocol) (0, external_fs_io_cjs_namespaceObject.writeFile)(targetDir, `${resolvedApp.directory}/shared/rpc.ts`, (0, rpc_cjs_namespaceObject.createRpcContractFile)(resolvedApp));
125
- else (0, external_fs_io_cjs_namespaceObject.writeFile)(targetDir, `${resolvedApp.directory}/shared/api.ts`, (0, external_api_cjs_namespaceObject.createSharedApi)(resolvedApp));
126
- (0, external_fs_io_cjs_namespaceObject.writeFile)(targetDir, `${resolvedApp.directory}/api/index.ts`, (0, external_api_cjs_namespaceObject.createApiServiceEntry)(resolvedApp, rpcProtocol ? '../shared/rpc.ts' : '../shared/api.ts'));
125
+ else (0, external_fs_io_cjs_namespaceObject.writeFile)(targetDir, `${resolvedApp.directory}/shared/api.ts`, (0, external_api_cjs_namespaceObject.createSharedApi)(resolvedApp, {
126
+ scope
127
+ }));
128
+ (0, external_fs_io_cjs_namespaceObject.writeFile)(targetDir, `${resolvedApp.directory}/api/index.ts`, (0, external_api_cjs_namespaceObject.createApiServiceEntry)(resolvedApp, rpcProtocol ? '../shared/rpc.ts' : '../shared/api.ts', {
129
+ scope
130
+ }));
127
131
  (0, external_fs_io_cjs_namespaceObject.writeFile)(targetDir, `${resolvedApp.directory}/api/backend-federation.ts`, (0, external_backend_federation_cjs_namespaceObject.createBackendFederationContractFile)(resolvedApp));
128
132
  (0, external_fs_io_cjs_namespaceObject.writeFile)(targetDir, `${resolvedApp.directory}/api/effect-api.ts`, (0, external_api_cjs_namespaceObject.createBackendEffectApiExpose)(scope, resolvedApp));
129
133
  if (rpcProtocol) (0, external_fs_io_cjs_namespaceObject.writeFile)(targetDir, `${resolvedApp.directory}/src/api/${resolvedApp.api.stem}-rpc-client.ts`, (0, rpc_cjs_namespaceObject.createRpcClientFile)(resolvedApp));
130
- else (0, external_fs_io_cjs_namespaceObject.writeFile)(targetDir, `${resolvedApp.directory}/src/api/${resolvedApp.api.stem}-client.ts`, (0, external_api_cjs_namespaceObject.createApiClient)(resolvedApp, '../../shared/api'));
134
+ else (0, external_fs_io_cjs_namespaceObject.writeFile)(targetDir, `${resolvedApp.directory}/src/api/${resolvedApp.api.stem}-client.ts`, (0, external_api_cjs_namespaceObject.createApiClient)(resolvedApp, '../../shared/api', {
135
+ scope
136
+ }));
131
137
  }
132
138
  if ('vertical' === resolvedApp.kind && emitsUi) {
133
139
  writeAppFile('src/federation-entry.tsx', (0, external_demo_components_cjs_namespaceObject.createRemoteEntry)(resolvedApp));
@@ -63,12 +63,14 @@ const external_zerops_cjs_namespaceObject = require("./zerops.cjs");
63
63
  function hasExplicitInstallRequest(options) {
64
64
  return void 0 !== options.packageSource && 'workspace' !== options.packageSource.strategy;
65
65
  }
66
- function writeSharedPackages(targetDir, scope) {
66
+ function writeSharedPackages(targetDir, scope, packageSource) {
67
67
  for (const sharedPackage of external_descriptors_cjs_namespaceObject.sharedPackages){
68
- (0, external_fs_io_cjs_namespaceObject.writeJson)(targetDir, `${sharedPackage.directory}/package.json`, (0, external_package_json_cjs_namespaceObject.createSharedPackage)(scope, sharedPackage.id, sharedPackage.description));
68
+ (0, external_fs_io_cjs_namespaceObject.writeJson)(targetDir, `${sharedPackage.directory}/package.json`, (0, external_package_json_cjs_namespaceObject.createSharedPackage)(scope, sharedPackage.id, sharedPackage.description, packageSource));
69
69
  (0, external_fs_io_cjs_namespaceObject.writeJson)(targetDir, `${sharedPackage.directory}/tsconfig.json`, (0, external_package_json_cjs_namespaceObject.createSharedPackageTsConfig)(sharedPackage.directory));
70
70
  }
71
71
  (0, external_fs_io_cjs_namespaceObject.writeFile)(targetDir, 'packages/shared-contracts/src/index.ts', (0, external_package_json_cjs_namespaceObject.createSharedContractsIndex)());
72
+ (0, external_fs_io_cjs_namespaceObject.writeFile)(targetDir, 'packages/shared-contracts/src/microvertical-api-baseline.ts', (0, external_fs_io_cjs_namespaceObject.readFileTemplate)('packages/microvertical-api-baseline.ts'));
73
+ (0, external_fs_io_cjs_namespaceObject.writeFile)(targetDir, 'packages/shared-contracts/src/effect-bff-runtime.ts', (0, external_fs_io_cjs_namespaceObject.readFileTemplate)('packages/effect-bff-runtime.ts'));
72
74
  (0, external_fs_io_cjs_namespaceObject.writeFile)(targetDir, 'packages/shared-design-tokens/src/index.ts', `export const sharedDesignTokens = {
73
75
  color: {
74
76
  accent: '#2f8f68',
@@ -188,7 +190,7 @@ function generateUltramodernWorkspaceInPlace(options, logicalWorkspaceRoot = opt
188
190
  (0, external_fs_io_cjs_namespaceObject.writeJson)(options.targetDir, external_descriptors_cjs_namespaceObject.ULTRAMODERN_CONFIG_PATH, createCompactUltramodernConfig(scope, options.modernVersion, packageSource, createdApps, enableTailwind, bridge));
189
191
  (0, external_write_app_cjs_namespaceObject.writeApp)(options.targetDir, scope, external_descriptors_cjs_namespaceObject.shellApp, packageSource, enableTailwind, initialVerticals, bridge);
190
192
  for (const remote of initialVerticals)(0, external_write_app_cjs_namespaceObject.writeApp)(options.targetDir, scope, remote, packageSource, enableTailwind, initialVerticals, bridge);
191
- writeSharedPackages(options.targetDir, scope);
193
+ writeSharedPackages(options.targetDir, scope, packageSource);
192
194
  (0, external_workspace_scripts_cjs_namespaceObject.writeGeneratedWorkspaceScripts)(options.targetDir, scope, enableTailwind, initialVerticals, releaseCohort);
193
195
  const preliminaryAfterFiles = (0, external_generation_result_cjs_namespaceObject.createFileSnapshot)(options.targetDir);
194
196
  const preliminaryDiff = (0, external_generation_result_cjs_namespaceObject.diffFileSnapshots)(beforeFiles, preliminaryAfterFiles);
@@ -70,6 +70,7 @@ function mergeTypeScriptConfig(generated, existing) {
70
70
  ...existingCompilerOptions,
71
71
  ...generatedCompilerOptions
72
72
  };
73
+ if (Array.isArray(generatedCompilerOptions.types)) compilerOptions.types = mergeUniqueJsonValues(generatedCompilerOptions.types, existingCompilerOptions.types);
73
74
  if (Array.isArray(generatedCompilerOptions.plugins) || Array.isArray(existingCompilerOptions.plugins)) compilerOptions.plugins = mergeTypeScriptPlugins(generatedCompilerOptions.plugins, existingCompilerOptions.plugins);
74
75
  const merged = {
75
76
  ...existingConfig,
@@ -135,6 +135,8 @@ function mergeGeneratedScript(consumer, framework, canRetireLegacyOxfmtCliExclus
135
135
  const frameworkSegmentSet = new Set(frameworkSegments);
136
136
  const canonicalFrameworkSegment = (segment)=>{
137
137
  if (frameworkSegmentSet.has(segment)) return segment;
138
+ const referenceBuild = segment.replace('--project tsconfig.json', '--build tsconfig.json');
139
+ if (frameworkSegmentSet.has(referenceBuild)) return referenceBuild;
138
140
  const portableEnvironmentSegment = `cross-env ${segment}`;
139
141
  if (frameworkSegmentSet.has(portableEnvironmentSegment)) return portableEnvironmentSegment;
140
142
  const portableOxfmtSegment = segment.replace(/ '!repos\/\*\*'$/u, '');