@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.
- package/dist/cjs/ultramodern-tooling/commands/migrate-strict-effect/generated-artifacts-typescript.cjs +1 -0
- package/dist/cjs/ultramodern-tooling/commands/migrate-strict-effect/package-cohort.cjs +2 -0
- package/dist/cjs/ultramodern-tooling/commands/migrate-strict-effect/shared-api-infrastructure.cjs +99 -0
- package/dist/cjs/ultramodern-tooling/commands/migrate-strict-effect/toolchain-pins.cjs +1 -0
- package/dist/cjs/ultramodern-tooling/commands/migrate-strict-effect.cjs +2 -0
- package/dist/cjs/ultramodern-workspace/api/client.cjs +2 -2
- package/dist/cjs/ultramodern-workspace/api/service.cjs +45 -16
- package/dist/cjs/ultramodern-workspace/api/shared.cjs +26 -16
- package/dist/cjs/ultramodern-workspace/mf-validation/inspect.cjs +6 -2
- package/dist/cjs/ultramodern-workspace/module-federation/reexport-module.cjs +0 -5
- package/dist/cjs/ultramodern-workspace/package-json.cjs +12 -1
- package/dist/cjs/ultramodern-workspace/policy.cjs +1 -0
- package/dist/cjs/ultramodern-workspace/tsconfigs.cjs +3 -0
- package/dist/cjs/ultramodern-workspace/workspace-script-plan.cjs +1 -1
- package/dist/cjs/ultramodern-workspace/workspace-scripts.cjs +5 -0
- package/dist/cjs/ultramodern-workspace/write-app.cjs +9 -3
- package/dist/cjs/ultramodern-workspace/write-workspace.cjs +5 -3
- package/dist/esm/ultramodern-tooling/commands/migrate-strict-effect/generated-artifacts-typescript.js +1 -0
- package/dist/esm/ultramodern-tooling/commands/migrate-strict-effect/package-cohort.js +2 -0
- package/dist/esm/ultramodern-tooling/commands/migrate-strict-effect/shared-api-infrastructure.js +50 -0
- package/dist/esm/ultramodern-tooling/commands/migrate-strict-effect/toolchain-pins.js +1 -0
- package/dist/esm/ultramodern-tooling/commands/migrate-strict-effect.js +2 -0
- package/dist/esm/ultramodern-workspace/api/client.js +2 -2
- package/dist/esm/ultramodern-workspace/api/service.js +45 -16
- package/dist/esm/ultramodern-workspace/api/shared.js +27 -17
- package/dist/esm/ultramodern-workspace/mf-validation/inspect.js +6 -2
- package/dist/esm/ultramodern-workspace/module-federation/reexport-module.js +0 -5
- package/dist/esm/ultramodern-workspace/package-json.js +12 -1
- package/dist/esm/ultramodern-workspace/policy.js +1 -0
- package/dist/esm/ultramodern-workspace/tsconfigs.js +3 -0
- package/dist/esm/ultramodern-workspace/workspace-script-plan.js +1 -1
- package/dist/esm/ultramodern-workspace/workspace-scripts.js +5 -0
- package/dist/esm/ultramodern-workspace/write-app.js +9 -3
- package/dist/esm/ultramodern-workspace/write-workspace.js +6 -4
- package/dist/esm-node/ultramodern-tooling/commands/migrate-strict-effect/generated-artifacts-typescript.js +1 -0
- package/dist/esm-node/ultramodern-tooling/commands/migrate-strict-effect/package-cohort.js +2 -0
- package/dist/esm-node/ultramodern-tooling/commands/migrate-strict-effect/shared-api-infrastructure.js +51 -0
- package/dist/esm-node/ultramodern-tooling/commands/migrate-strict-effect/toolchain-pins.js +1 -0
- package/dist/esm-node/ultramodern-tooling/commands/migrate-strict-effect.js +2 -0
- package/dist/esm-node/ultramodern-workspace/api/client.js +2 -2
- package/dist/esm-node/ultramodern-workspace/api/service.js +45 -16
- package/dist/esm-node/ultramodern-workspace/api/shared.js +27 -17
- package/dist/esm-node/ultramodern-workspace/mf-validation/inspect.js +6 -2
- package/dist/esm-node/ultramodern-workspace/module-federation/reexport-module.js +0 -5
- package/dist/esm-node/ultramodern-workspace/package-json.js +12 -1
- package/dist/esm-node/ultramodern-workspace/policy.js +1 -0
- package/dist/esm-node/ultramodern-workspace/tsconfigs.js +3 -0
- package/dist/esm-node/ultramodern-workspace/workspace-script-plan.js +1 -1
- package/dist/esm-node/ultramodern-workspace/workspace-scripts.js +5 -0
- package/dist/esm-node/ultramodern-workspace/write-app.js +9 -3
- package/dist/esm-node/ultramodern-workspace/write-workspace.js +6 -4
- package/dist/types/ultramodern-tooling/commands/migrate-strict-effect/shared-api-infrastructure.d.ts +4 -0
- package/dist/types/ultramodern-workspace/api/client.d.ts +3 -1
- package/dist/types/ultramodern-workspace/api/service.d.ts +3 -1
- package/dist/types/ultramodern-workspace/api/shared.d.ts +2 -0
- package/dist/types/ultramodern-workspace/package-json.d.ts +1 -1
- package/dist/types/ultramodern-workspace/policy.d.ts +2 -0
- package/package.json +4 -4
- package/template-workspace/.modernjs/release-cohort.json +40 -40
- package/templates/packages/effect-bff-runtime.ts +50 -0
- package/templates/packages/microvertical-api-baseline.ts +102 -0
- package/templates/workspace-scripts/check-ultramodern-api-boundaries.mts +49 -28
- package/templates/workspace-scripts/microvertical-api-baseline-boundary.mts +944 -0
- package/templates/workspace-scripts/ultramodern-cloudflare-proof.mjs +25 -7
- package/templates/workspace-scripts/validate-ultramodern-workspace.mjs.handlebars +1 -1
|
@@ -3,7 +3,7 @@ import { resolveApiProtocol, resolveApiStem, verticalApiApps } from "../descript
|
|
|
3
3
|
import { packageName, toPascalCase } from "../naming.js";
|
|
4
4
|
import { createCheckoutCartClientExports, serviceHasCheckoutCartState } from "./checkout-cart.js";
|
|
5
5
|
import { verticalApiErrorStem, verticalApiExport, verticalApiGroupName, verticalApiNotFoundErrorExport } from "./names.js";
|
|
6
|
-
function createApiClient(service, contractImportPath) {
|
|
6
|
+
function createApiClient(service, contractImportPath, options) {
|
|
7
7
|
const apiExport = verticalApiExport(service);
|
|
8
8
|
const contractExport = verticalApiGroupName(service);
|
|
9
9
|
const stem = resolveApiStem(service);
|
|
@@ -119,7 +119,7 @@ export const ${readinessName} = (
|
|
|
119
119
|
operationContext:
|
|
120
120
|
options.operationContext ?? ${groupName}OperationContexts.readiness,
|
|
121
121
|
}).pipe(
|
|
122
|
-
Effect.flatMap(client => client.${groupName}.readiness({})),
|
|
122
|
+
Effect.flatMap(client => client.${options ? 'foundation' : groupName}.readiness({})),
|
|
123
123
|
);
|
|
124
124
|
|
|
125
125
|
export const ${getName} = (
|
|
@@ -5,23 +5,22 @@ import { packageName } from "../naming.js";
|
|
|
5
5
|
import { createCheckoutCartServerHandlers, createCheckoutCartServerState } from "./checkout-cart.js";
|
|
6
6
|
import { verticalApiExport, verticalApiGroupName, verticalApiNotFoundErrorExport } from "./names.js";
|
|
7
7
|
import { createRpcApiServiceEntry, rpcPath, verticalRpcContractExport, verticalRpcGroupExport } from "./rpc.js";
|
|
8
|
-
function createApiServiceEntry(service, contractImportPath) {
|
|
8
|
+
function createApiServiceEntry(service, contractImportPath, options) {
|
|
9
9
|
if ((service.api?.protocol ?? 'rest') === 'rpc') return createRpcApiServiceEntry(service);
|
|
10
10
|
const apiExport = verticalApiExport(service);
|
|
11
11
|
const groupName = verticalApiGroupName(service);
|
|
12
12
|
const notFoundErrorExport = verticalApiNotFoundErrorExport(service);
|
|
13
13
|
const stem = resolveApiStem(service);
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
const assemblyImport = options ? `import { assembleEffectBffRuntime } from '${packageName(options.scope, 'shared-contracts')}/server/effect-bff-runtime';\n` : '';
|
|
15
|
+
return `${assemblyImport}import {
|
|
16
|
+
${options ? '' : 'defineEffectBff,'}
|
|
16
17
|
Effect,
|
|
17
18
|
HttpApiBuilder,
|
|
18
19
|
Layer,
|
|
19
20
|
} from '@modern-js/plugin-bff/effect-edge';
|
|
20
|
-
import type {
|
|
21
|
-
EffectBffDefinition,
|
|
22
|
-
EffectBffRuntime,
|
|
21
|
+
${options ? '' : `import type {
|
|
23
22
|
EffectRuntimeLayer,
|
|
24
|
-
} from '@modern-js/plugin-bff/effect-edge'
|
|
23
|
+
} from '@modern-js/plugin-bff/effect-edge';`}
|
|
25
24
|
import { ultramodernApiMarker } from '../shared/ultramodern-build.ts';
|
|
26
25
|
import {
|
|
27
26
|
${apiExport},
|
|
@@ -51,6 +50,31 @@ const operationAttributes = (operationContext: OperationContext) => ({
|
|
|
51
50
|
: {}),
|
|
52
51
|
});
|
|
53
52
|
|
|
53
|
+
${options ? `const ${groupName}ReadinessLayer = HttpApiBuilder.group(
|
|
54
|
+
${apiExport},
|
|
55
|
+
'foundation',
|
|
56
|
+
handlers => handlers
|
|
57
|
+
.handle('readiness', () =>
|
|
58
|
+
Effect.succeed({
|
|
59
|
+
checks: {
|
|
60
|
+
api: 'ready' as const,
|
|
61
|
+
moduleFederation: 'ready' as const,
|
|
62
|
+
ssr: 'ready' as const,
|
|
63
|
+
translations: 'ready' as const,
|
|
64
|
+
},
|
|
65
|
+
marker: ultramodernApiMarker,
|
|
66
|
+
status: 'ready' as const,
|
|
67
|
+
versionSkew: 'none' as const,
|
|
68
|
+
}).pipe(
|
|
69
|
+
Effect.withSpan('ultramodern.api.${groupName}.readiness', {
|
|
70
|
+
attributes: operationAttributes(${groupName}OperationContexts.readiness),
|
|
71
|
+
kind: 'server',
|
|
72
|
+
}),
|
|
73
|
+
),
|
|
74
|
+
)
|
|
75
|
+
,
|
|
76
|
+
);` : ''}
|
|
77
|
+
|
|
54
78
|
const ${groupName}Layer = HttpApiBuilder.group(
|
|
55
79
|
${apiExport},
|
|
56
80
|
'${groupName}',
|
|
@@ -69,7 +93,7 @@ const ${groupName}Layer = HttpApiBuilder.group(
|
|
|
69
93
|
}),
|
|
70
94
|
),
|
|
71
95
|
)
|
|
72
|
-
.handle('readiness', () =>
|
|
96
|
+
${options ? '' : ` .handle('readiness', () =>
|
|
73
97
|
Effect.succeed({
|
|
74
98
|
checks: {
|
|
75
99
|
api: 'ready' as const,
|
|
@@ -87,6 +111,7 @@ const ${groupName}Layer = HttpApiBuilder.group(
|
|
|
87
111
|
}),
|
|
88
112
|
),
|
|
89
113
|
)
|
|
114
|
+
`}
|
|
90
115
|
.handle('get', ({ params }) => {
|
|
91
116
|
const matchedItem = ${groupName}Items.find(
|
|
92
117
|
candidate => candidate.id === params.id,
|
|
@@ -126,14 +151,18 @@ const ${groupName}Layer = HttpApiBuilder.group(
|
|
|
126
151
|
)${createCheckoutCartServerHandlers(service)},
|
|
127
152
|
);
|
|
128
153
|
|
|
129
|
-
const
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
layer
|
|
136
|
-
})
|
|
154
|
+
${options ? `const apiHandlersLive = Layer.mergeAll(${groupName}Layer, ${groupName}ReadinessLayer);
|
|
155
|
+
export const make${apiExport[0].toUpperCase()}${apiExport.slice(1)}Runtime = () =>
|
|
156
|
+
assembleEffectBffRuntime({
|
|
157
|
+
api: ${apiExport},
|
|
158
|
+
handlers: apiHandlersLive,
|
|
159
|
+
});` : `export const make${apiExport[0].toUpperCase()}${apiExport.slice(1)}Runtime = () => {
|
|
160
|
+
const layer = HttpApiBuilder.layer(${apiExport}).pipe(
|
|
161
|
+
Layer.provide(${groupName}Layer),
|
|
162
|
+
) satisfies EffectRuntimeLayer;
|
|
163
|
+
return defineEffectBff({ api: ${apiExport}, layer });
|
|
164
|
+
};`}
|
|
165
|
+
const apiRuntime = make${apiExport[0].toUpperCase()}${apiExport.slice(1)}Runtime();
|
|
137
166
|
|
|
138
167
|
export default apiRuntime;
|
|
139
168
|
`;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import "node:module";
|
|
2
2
|
import { resolveApiPrefix, resolveApiStem } from "../descriptors.js";
|
|
3
3
|
import { renderTemplate } from "../fs-io.js";
|
|
4
|
-
import { toPascalCase } from "../naming.js";
|
|
4
|
+
import { packageName, toPascalCase } from "../naming.js";
|
|
5
5
|
import { createCheckoutCartApiContractFields, createCheckoutCartEndpointDefinitions, createCheckoutCartOperationContexts, createCheckoutCartSharedSchemas } from "./checkout-cart.js";
|
|
6
6
|
import { verticalApiCreatePayloadSchemaExport, verticalApiExport, verticalApiGroupName, verticalApiMarkerSchemaExport, verticalApiName, verticalApiNotFoundErrorExport, verticalApiNotFoundSchemaExport, verticalApiReadinessSchemaExport, verticalApiSchemaExport } from "./names.js";
|
|
7
7
|
function createSharedApiImports() {
|
|
@@ -14,7 +14,7 @@ function createSharedApiImports() {
|
|
|
14
14
|
} from '@modern-js/plugin-bff/effect-client';
|
|
15
15
|
`;
|
|
16
16
|
}
|
|
17
|
-
function createSharedApiContract(service) {
|
|
17
|
+
function createSharedApiContract(service, shared = false) {
|
|
18
18
|
const schemaExport = verticalApiSchemaExport(service);
|
|
19
19
|
const markerSchemaExport = verticalApiMarkerSchemaExport(service);
|
|
20
20
|
const readinessSchemaExport = verticalApiReadinessSchemaExport(service);
|
|
@@ -71,7 +71,7 @@ function createSharedApiContract(service) {
|
|
|
71
71
|
listOperationContext,
|
|
72
72
|
readinessOperationContext
|
|
73
73
|
}).trim();
|
|
74
|
-
return `export interface ${markerType} {
|
|
74
|
+
return `${shared ? `export type ${markerType} = MicroVerticalBuildMarker;` : `export interface ${markerType} {
|
|
75
75
|
readonly appId: string;
|
|
76
76
|
readonly build: string;
|
|
77
77
|
readonly buildMarker: string;
|
|
@@ -81,7 +81,7 @@ function createSharedApiContract(service) {
|
|
|
81
81
|
readonly surface: string;
|
|
82
82
|
readonly unitId: string;
|
|
83
83
|
readonly version: string;
|
|
84
|
-
}
|
|
84
|
+
}`}
|
|
85
85
|
|
|
86
86
|
export interface ${itemType} {
|
|
87
87
|
readonly id: string;
|
|
@@ -89,7 +89,7 @@ export interface ${itemType} {
|
|
|
89
89
|
readonly title: string;
|
|
90
90
|
}
|
|
91
91
|
|
|
92
|
-
export interface ${readinessType} {
|
|
92
|
+
${shared ? `export type ${readinessType} = MicroVerticalReadiness;` : `export interface ${readinessType} {
|
|
93
93
|
readonly checks: {
|
|
94
94
|
readonly api: 'ready';
|
|
95
95
|
readonly moduleFederation: 'ready';
|
|
@@ -99,7 +99,7 @@ export interface ${readinessType} {
|
|
|
99
99
|
readonly marker: ${markerType};
|
|
100
100
|
readonly status: 'ready';
|
|
101
101
|
readonly versionSkew: 'none';
|
|
102
|
-
}
|
|
102
|
+
}`}
|
|
103
103
|
|
|
104
104
|
export interface ${createPayloadType} {
|
|
105
105
|
readonly title: string;
|
|
@@ -118,7 +118,7 @@ export interface ${notFoundErrorExport} {
|
|
|
118
118
|
readonly id: string;
|
|
119
119
|
}
|
|
120
120
|
|
|
121
|
-
export const ${markerSchemaExport}: Schema.Codec<${markerType}> = Schema.Struct({
|
|
121
|
+
${shared ? `export const ${markerSchemaExport}: Schema.Codec<${markerType}> = MicroVerticalBuildMarkerSchema;` : `export const ${markerSchemaExport}: Schema.Codec<${markerType}> = Schema.Struct({
|
|
122
122
|
appId: Schema.String,
|
|
123
123
|
build: Schema.String,
|
|
124
124
|
buildMarker: Schema.String,
|
|
@@ -128,7 +128,7 @@ export const ${markerSchemaExport}: Schema.Codec<${markerType}> = Schema.Struct(
|
|
|
128
128
|
surface: Schema.String,
|
|
129
129
|
unitId: Schema.String,
|
|
130
130
|
version: Schema.String,
|
|
131
|
-
})
|
|
131
|
+
});`}
|
|
132
132
|
|
|
133
133
|
export const ${schemaExport}: Schema.Codec<${itemType}> = Schema.Struct({
|
|
134
134
|
id: Schema.String,
|
|
@@ -136,7 +136,7 @@ export const ${schemaExport}: Schema.Codec<${itemType}> = Schema.Struct({
|
|
|
136
136
|
title: Schema.String,
|
|
137
137
|
});
|
|
138
138
|
|
|
139
|
-
export const ${readinessSchemaExport}: Schema.Codec<${readinessType}> = Schema.Struct({
|
|
139
|
+
${shared ? `export const ${readinessSchemaExport}: Schema.Codec<${readinessType}> = MicroVerticalReadinessSchema;` : `export const ${readinessSchemaExport}: Schema.Codec<${readinessType}> = Schema.Struct({
|
|
140
140
|
checks: Schema.Struct({
|
|
141
141
|
api: Schema.Literal('ready'),
|
|
142
142
|
moduleFederation: Schema.Literal('ready'),
|
|
@@ -146,7 +146,7 @@ export const ${readinessSchemaExport}: Schema.Codec<${readinessType}> = Schema.S
|
|
|
146
146
|
marker: ${markerSchemaExport},
|
|
147
147
|
status: Schema.Literal('ready'),
|
|
148
148
|
versionSkew: Schema.Literal('none'),
|
|
149
|
-
})
|
|
149
|
+
});`}
|
|
150
150
|
|
|
151
151
|
export const ${createPayloadSchemaExport}: Schema.Codec<${createPayloadType}> = Schema.Struct({
|
|
152
152
|
title: Schema.String,
|
|
@@ -158,7 +158,7 @@ ${checkoutCartSharedSchemaSection}export const ${notFoundSchemaExport}: Schema.C
|
|
|
158
158
|
HttpApiSchema.status(404),
|
|
159
159
|
);
|
|
160
160
|
|
|
161
|
-
export interface OperationContext {
|
|
161
|
+
${shared ? 'export type OperationContext = MicroVerticalOperationContext;' : `export interface OperationContext {
|
|
162
162
|
method: string;
|
|
163
163
|
operationId: string;
|
|
164
164
|
routePath: string;
|
|
@@ -170,9 +170,14 @@ export interface OperationContext {
|
|
|
170
170
|
| 'data-platform'
|
|
171
171
|
| 'unknown';
|
|
172
172
|
traceId?: string;
|
|
173
|
-
}
|
|
173
|
+
}`}
|
|
174
174
|
|
|
175
|
-
export const ${
|
|
175
|
+
${shared ? `export const ${groupName}FoundationApi = HttpApi.make('${apiName}Foundation').add(
|
|
176
|
+
HttpApiGroup.make('foundation').add(
|
|
177
|
+
HttpApiEndpoint.get('readiness', '/${stem}/readiness', { success: ${readinessSchemaExport} }),
|
|
178
|
+
),
|
|
179
|
+
);` : ''}
|
|
180
|
+
export const ${apiExport} = HttpApi.make('${apiName}')${shared ? `.addHttpApi(${groupName}FoundationApi)` : ''}.add(
|
|
176
181
|
HttpApiGroup.make('${groupName}')
|
|
177
182
|
.add(
|
|
178
183
|
HttpApiEndpoint.get('list', '/${stem}', {
|
|
@@ -184,11 +189,12 @@ export const ${apiExport} = HttpApi.make('${apiName}').add(
|
|
|
184
189
|
}),
|
|
185
190
|
}),
|
|
186
191
|
)
|
|
187
|
-
.add(
|
|
192
|
+
${shared ? '' : ` .add(
|
|
188
193
|
HttpApiEndpoint.get('readiness', '/${stem}/readiness', {
|
|
189
194
|
success: ${readinessSchemaExport},
|
|
190
195
|
}),
|
|
191
196
|
)
|
|
197
|
+
`}
|
|
192
198
|
.add(
|
|
193
199
|
HttpApiEndpoint.get('get', '/${stem}/:id', {
|
|
194
200
|
error: ${notFoundSchemaExport},
|
|
@@ -209,7 +215,7 @@ export const ${apiExport} = HttpApi.make('${apiName}').add(
|
|
|
209
215
|
);
|
|
210
216
|
|
|
211
217
|
export const ${groupName}OperationContexts = {
|
|
212
|
-
${operationContextEntries}
|
|
218
|
+
${shared ? operationContextEntries.replaceAll(/(\w+: )\{([\s\S]*?)\},/gu, (_, key, fields)=>`${key}createMicroVerticalOperationContext({${fields.replace(/\n\s*source: 'generated-client',/u, '')}}),`) : operationContextEntries}
|
|
213
219
|
} satisfies Record<string, OperationContext>;
|
|
214
220
|
|
|
215
221
|
export const ${groupName}ApiContract = {
|
|
@@ -220,8 +226,12 @@ ${createCheckoutCartApiContractFields(service)} ownerId: '${service.id}',
|
|
|
220
226
|
} as const;
|
|
221
227
|
`;
|
|
222
228
|
}
|
|
223
|
-
function createSharedApi(service) {
|
|
229
|
+
function createSharedApi(service, options) {
|
|
230
|
+
const imports = options ? `import { MicroVerticalBuildMarkerSchema, MicroVerticalReadinessSchema, createMicroVerticalOperationContext } from '${packageName(options.scope, 'shared-contracts')}/microvertical-api-baseline';
|
|
231
|
+
import type { MicroVerticalBuildMarker, MicroVerticalReadiness, MicroVerticalOperationContext } from '${packageName(options.scope, 'shared-contracts')}/microvertical-api-baseline';
|
|
232
|
+
` : '';
|
|
224
233
|
return `${createSharedApiImports()}
|
|
225
|
-
${
|
|
234
|
+
${imports}
|
|
235
|
+
${createSharedApiContract(service, void 0 !== options)}`;
|
|
226
236
|
}
|
|
227
237
|
export { createSharedApi };
|
|
@@ -12,7 +12,11 @@ function extractExposes(configPath, value) {
|
|
|
12
12
|
if (array) return array.sort();
|
|
13
13
|
throw new Error(`Cannot statically extract Module Federation exposes from ${configPath}; use a literal exposes object or string array.`);
|
|
14
14
|
}
|
|
15
|
-
function extractDtsSettings(configPath, value) {
|
|
15
|
+
function extractDtsSettings(configPath, value, exposes) {
|
|
16
|
+
if ('false' === value) {
|
|
17
|
+
if (exposes.length > 0) throw new Error(`Module Federation DTS cannot be disabled for exposed app ${configPath}.`);
|
|
18
|
+
return {};
|
|
19
|
+
}
|
|
16
20
|
if (void 0 === value) return {};
|
|
17
21
|
const dts = parseObjectLiteral(value);
|
|
18
22
|
if (!dts || dts.hasSpread) throw new Error(`Cannot statically extract Module Federation DTS settings from ${configPath}; use a literal dts object.`);
|
|
@@ -39,7 +43,7 @@ function inspectModuleFederationConfigSource(source, appDir, configPath) {
|
|
|
39
43
|
return {
|
|
40
44
|
appDir,
|
|
41
45
|
configPath,
|
|
42
|
-
dts: extractDtsSettings(configPath, properties.properties.get('dts')),
|
|
46
|
+
dts: extractDtsSettings(configPath, properties.properties.get('dts'), exposes),
|
|
43
47
|
exposes,
|
|
44
48
|
hostOnlyNoExposes
|
|
45
49
|
};
|
|
@@ -46,22 +46,17 @@ const ultramodernBuildArtifact = {
|
|
|
46
46
|
},
|
|
47
47
|
} as const;
|
|
48
48
|
|
|
49
|
-
export { ultramodernBuildArtifact };
|
|
50
|
-
|
|
51
49
|
export const ultramodernDeliveryUnit =
|
|
52
50
|
ultramodernBuildArtifact.deliveryUnit;
|
|
53
|
-
export const ultramodernVerticalIdentity = ultramodernDeliveryUnit;
|
|
54
51
|
export const ultramodernUiMarker = ultramodernBuildArtifact.surfaces.ui;
|
|
55
52
|
export const ultramodernApiMarker = ultramodernBuildArtifact.surfaces.api;
|
|
56
53
|
`;
|
|
57
54
|
}
|
|
58
55
|
function createUltramodernBuildReexportModule() {
|
|
59
56
|
return `export {
|
|
60
|
-
ultramodernBuildArtifact,
|
|
61
57
|
ultramodernApiMarker,
|
|
62
58
|
ultramodernDeliveryUnit,
|
|
63
59
|
ultramodernUiMarker,
|
|
64
|
-
ultramodernVerticalIdentity,
|
|
65
60
|
} from '../shared/ultramodern-build';
|
|
66
61
|
`;
|
|
67
62
|
}
|
|
@@ -172,7 +172,7 @@ function createAppPackage(scope, app, packageSource, enableTailwind, remotes = [
|
|
|
172
172
|
if (Object.keys(packageExports).length > 0) packageJson.exports = packageExports;
|
|
173
173
|
return packageJson;
|
|
174
174
|
}
|
|
175
|
-
function createSharedPackage(scope, id, description) {
|
|
175
|
+
function createSharedPackage(scope, id, description, packageSource) {
|
|
176
176
|
const packageJson = {
|
|
177
177
|
private: true,
|
|
178
178
|
name: packageName(scope, id),
|
|
@@ -189,6 +189,17 @@ function createSharedPackage(scope, id, description) {
|
|
|
189
189
|
'@effect/tsgo': ULTRAMODERN_PACKAGE_PINS.appDevDependencies["@effect/tsgo"]
|
|
190
190
|
}
|
|
191
191
|
};
|
|
192
|
+
if ('shared-contracts' === id) {
|
|
193
|
+
packageJson.exports = {
|
|
194
|
+
'.': './src/index.ts',
|
|
195
|
+
'./microvertical-api-baseline': './src/microvertical-api-baseline.ts',
|
|
196
|
+
'./server/effect-bff-runtime': './src/effect-bff-runtime.ts'
|
|
197
|
+
};
|
|
198
|
+
packageJson.dependencies = {
|
|
199
|
+
...ULTRAMODERN_PACKAGE_PINS.bffEffectDependencies,
|
|
200
|
+
'@modern-js/plugin-bff': packageSource ? modernPackageSpecifier('@modern-js/plugin-bff', packageSource) : WORKSPACE_PACKAGE_VERSION
|
|
201
|
+
};
|
|
202
|
+
}
|
|
192
203
|
if ('shared-design-tokens' === id) packageJson.exports = {
|
|
193
204
|
...packageJson.exports,
|
|
194
205
|
'./tokens.css': './src/tokens.css'
|
|
@@ -250,6 +250,7 @@ const ULTRAMODERN_PACKAGE_PINS = {
|
|
|
250
250
|
rootDevDependencies: {
|
|
251
251
|
'@effect/tsgo': EFFECT_TSGO_VERSION,
|
|
252
252
|
"@typescript/native": `npm:typescript@${TYPESCRIPT_VERSION}`,
|
|
253
|
+
'@types/node': TYPES_NODE_VERSION,
|
|
253
254
|
'cross-env': CROSS_ENV_VERSION,
|
|
254
255
|
lefthook: LEFTHOOK_VERSION,
|
|
255
256
|
miniflare: MINIFLARE_VERSION,
|
|
@@ -140,7 +140,7 @@ function createWorkspaceRootScriptPlan(remotes = [], options = {}) {
|
|
|
140
140
|
migrateStrictEffect: rootToolingWrapperCommand('migrateStrictEffect'),
|
|
141
141
|
zeropsMaterialize: "node ./scripts/materialize-zerops-runtime.mjs",
|
|
142
142
|
contractCheck: rootToolingWrapperCommand('validate'),
|
|
143
|
-
typecheck: options.typecheck ?? `${rootToolingWrapperCommand('typecheck')} --
|
|
143
|
+
typecheck: options.typecheck ?? `${rootToolingWrapperCommand('typecheck')} --build tsconfig.json`,
|
|
144
144
|
check: `pnpm format:check && pnpm lint && pnpm typecheck && pnpm skills:check && pnpm i18n:boundaries && pnpm api:check && pnpm contract:check && pnpm performance:readiness${bridgeCheck}`
|
|
145
145
|
};
|
|
146
146
|
}
|
|
@@ -130,6 +130,7 @@ function writeGeneratedWorkspaceScripts(targetDir, scope, enableTailwind, remote
|
|
|
130
130
|
const hasBackendSurface = remotes.some(appHasApi);
|
|
131
131
|
writeWorkspaceOwnedMtsScript(targetDir, 'check-ultramodern-i18n-boundaries', createWorkspaceI18nBoundaryValidationScript());
|
|
132
132
|
writeWorkspaceOwnedMtsScript(targetDir, 'check-ultramodern-api-boundaries', createWorkspaceApiBoundaryValidationScript());
|
|
133
|
+
writeWorkspaceOwnedMtsScript(targetDir, 'microvertical-api-baseline-boundary', external_fs_io_js_readFileTemplate("workspace-scripts/microvertical-api-baseline-boundary.mts"));
|
|
133
134
|
if (!shellOnly) {
|
|
134
135
|
writeFileReplacing(targetDir, "scripts/materialize-zerops-runtime.mjs", createZeropsRuntimeMaterializationScript());
|
|
135
136
|
writeWorkspaceOwnedMtsScript(targetDir, 'proof-workerd-ssr', createWorkerdSsrProofScript());
|
|
@@ -157,6 +158,10 @@ function migratedWorkspaceScriptArtifacts(options) {
|
|
|
157
158
|
content: createWorkspaceI18nBoundaryValidationScript(),
|
|
158
159
|
legacyPath: "scripts/check-ultramodern-i18n-boundaries.mjs"
|
|
159
160
|
},
|
|
161
|
+
{
|
|
162
|
+
relativePath: "scripts/microvertical-api-baseline-boundary.mts",
|
|
163
|
+
content: external_fs_io_js_readFileTemplate("workspace-scripts/microvertical-api-baseline-boundary.mts")
|
|
164
|
+
},
|
|
160
165
|
{
|
|
161
166
|
relativePath: "scripts/check-ultramodern-api-boundaries.mts",
|
|
162
167
|
content: createWorkspaceApiBoundaryValidationScript(),
|
|
@@ -89,11 +89,17 @@ function writeAppRouteAndShellFiles({ targetDir, scope, resolvedApp, emitsUi, re
|
|
|
89
89
|
function writeAppApiAndRemoteExposeFiles({ targetDir, scope, resolvedApp, emitsUi, writeAppFile }) {
|
|
90
90
|
if (appHasApi(resolvedApp)) {
|
|
91
91
|
const rpcProtocol = 'rpc' === resolveApiProtocol(resolvedApp);
|
|
92
|
-
rpcProtocol ? writeFile(targetDir, `${resolvedApp.directory}/shared/rpc.ts`, createRpcContractFile(resolvedApp)) : writeFile(targetDir, `${resolvedApp.directory}/shared/api.ts`, createSharedApi(resolvedApp
|
|
93
|
-
|
|
92
|
+
rpcProtocol ? writeFile(targetDir, `${resolvedApp.directory}/shared/rpc.ts`, createRpcContractFile(resolvedApp)) : writeFile(targetDir, `${resolvedApp.directory}/shared/api.ts`, createSharedApi(resolvedApp, {
|
|
93
|
+
scope
|
|
94
|
+
}));
|
|
95
|
+
writeFile(targetDir, `${resolvedApp.directory}/api/index.ts`, createApiServiceEntry(resolvedApp, rpcProtocol ? '../shared/rpc.ts' : '../shared/api.ts', {
|
|
96
|
+
scope
|
|
97
|
+
}));
|
|
94
98
|
writeFile(targetDir, `${resolvedApp.directory}/api/backend-federation.ts`, createBackendFederationContractFile(resolvedApp));
|
|
95
99
|
writeFile(targetDir, `${resolvedApp.directory}/api/effect-api.ts`, createBackendEffectApiExpose(scope, resolvedApp));
|
|
96
|
-
rpcProtocol ? writeFile(targetDir, `${resolvedApp.directory}/src/api/${resolvedApp.api.stem}-rpc-client.ts`, createRpcClientFile(resolvedApp)) : writeFile(targetDir, `${resolvedApp.directory}/src/api/${resolvedApp.api.stem}-client.ts`, createApiClient(resolvedApp, '../../shared/api'
|
|
100
|
+
rpcProtocol ? writeFile(targetDir, `${resolvedApp.directory}/src/api/${resolvedApp.api.stem}-rpc-client.ts`, createRpcClientFile(resolvedApp)) : writeFile(targetDir, `${resolvedApp.directory}/src/api/${resolvedApp.api.stem}-client.ts`, createApiClient(resolvedApp, '../../shared/api', {
|
|
101
|
+
scope
|
|
102
|
+
}));
|
|
97
103
|
}
|
|
98
104
|
if ('vertical' === resolvedApp.kind && emitsUi) {
|
|
99
105
|
writeAppFile('src/federation-entry.tsx', createRemoteEntry(resolvedApp));
|
|
@@ -6,7 +6,7 @@ import { createSharedDesignTokensCss } from "./app-files.js";
|
|
|
6
6
|
import { normalizeUltramodernBridgeConfig } from "./bridge-config.js";
|
|
7
7
|
import { createDevelopmentOverlay, createOwnership, createTopology, createUltramodernConfig } from "./contracts.js";
|
|
8
8
|
import { ULTRAMODERN_CONFIG_PATH, createShellHost, sharedPackages, shellApp } from "./descriptors.js";
|
|
9
|
-
import { copyRootTemplate, formatGeneratedWorkspaceFiles, writeFile, writeFileReplacing, writeJson } from "./fs-io.js";
|
|
9
|
+
import { copyRootTemplate, formatGeneratedWorkspaceFiles, readFileTemplate, writeFile, writeFileReplacing, writeJson } from "./fs-io.js";
|
|
10
10
|
import { createFileSnapshot, createGenerationResult, diffFileSnapshots } from "./generation-result.js";
|
|
11
11
|
import { assertUniqueTailwindPrefixes, toPackageScope } from "./naming.js";
|
|
12
12
|
import { runCodeSmithOverlays } from "./overlays.js";
|
|
@@ -20,12 +20,14 @@ import { createZeropsYaml } from "./zerops.js";
|
|
|
20
20
|
function hasExplicitInstallRequest(options) {
|
|
21
21
|
return void 0 !== options.packageSource && 'workspace' !== options.packageSource.strategy;
|
|
22
22
|
}
|
|
23
|
-
function writeSharedPackages(targetDir, scope) {
|
|
23
|
+
function writeSharedPackages(targetDir, scope, packageSource) {
|
|
24
24
|
for (const sharedPackage of sharedPackages){
|
|
25
|
-
writeJson(targetDir, `${sharedPackage.directory}/package.json`, createSharedPackage(scope, sharedPackage.id, sharedPackage.description));
|
|
25
|
+
writeJson(targetDir, `${sharedPackage.directory}/package.json`, createSharedPackage(scope, sharedPackage.id, sharedPackage.description, packageSource));
|
|
26
26
|
writeJson(targetDir, `${sharedPackage.directory}/tsconfig.json`, createSharedPackageTsConfig(sharedPackage.directory));
|
|
27
27
|
}
|
|
28
28
|
writeFile(targetDir, 'packages/shared-contracts/src/index.ts', createSharedContractsIndex());
|
|
29
|
+
writeFile(targetDir, 'packages/shared-contracts/src/microvertical-api-baseline.ts', readFileTemplate('packages/microvertical-api-baseline.ts'));
|
|
30
|
+
writeFile(targetDir, 'packages/shared-contracts/src/effect-bff-runtime.ts', readFileTemplate('packages/effect-bff-runtime.ts'));
|
|
29
31
|
writeFile(targetDir, 'packages/shared-design-tokens/src/index.ts', `export const sharedDesignTokens = {
|
|
30
32
|
color: {
|
|
31
33
|
accent: '#2f8f68',
|
|
@@ -145,7 +147,7 @@ function generateUltramodernWorkspaceInPlace(options, logicalWorkspaceRoot = opt
|
|
|
145
147
|
writeJson(options.targetDir, ULTRAMODERN_CONFIG_PATH, createCompactUltramodernConfig(scope, options.modernVersion, packageSource, createdApps, enableTailwind, bridge));
|
|
146
148
|
writeApp(options.targetDir, scope, shellApp, packageSource, enableTailwind, initialVerticals, bridge);
|
|
147
149
|
for (const remote of initialVerticals)writeApp(options.targetDir, scope, remote, packageSource, enableTailwind, initialVerticals, bridge);
|
|
148
|
-
writeSharedPackages(options.targetDir, scope);
|
|
150
|
+
writeSharedPackages(options.targetDir, scope, packageSource);
|
|
149
151
|
writeGeneratedWorkspaceScripts(options.targetDir, scope, enableTailwind, initialVerticals, releaseCohort);
|
|
150
152
|
const preliminaryAfterFiles = createFileSnapshot(options.targetDir);
|
|
151
153
|
const preliminaryDiff = diffFileSnapshots(beforeFiles, preliminaryAfterFiles);
|
package/dist/types/ultramodern-tooling/commands/migrate-strict-effect/shared-api-infrastructure.d.ts
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { ResolvedPackageSource } from '../../../ultramodern-workspace/types.js';
|
|
2
|
+
import { type MigrationIo } from './io.js';
|
|
3
|
+
/** Add infrastructure only: existing contracts and business handlers stay owned by the consumer. */
|
|
4
|
+
export declare function ensureSharedApiInfrastructure(io: MigrationIo, scope: string, packageSource: ResolvedPackageSource): void;
|
|
@@ -2,5 +2,7 @@ import type { WorkspaceApi, WorkspaceApp } from '../types.js';
|
|
|
2
2
|
export declare function createApiClient(service: {
|
|
3
3
|
id: string;
|
|
4
4
|
api?: WorkspaceApi;
|
|
5
|
-
}, contractImportPath: string
|
|
5
|
+
}, contractImportPath: string, options?: {
|
|
6
|
+
readonly scope: string;
|
|
7
|
+
}): string;
|
|
6
8
|
export declare function createShellApiClient(scope: string, remotes?: WorkspaceApp[]): string;
|
|
@@ -2,5 +2,7 @@ import type { WorkspaceApi, WorkspaceApp } from '../types.js';
|
|
|
2
2
|
export declare function createApiServiceEntry(service: {
|
|
3
3
|
id: string;
|
|
4
4
|
api?: WorkspaceApi;
|
|
5
|
-
}, contractImportPath: string
|
|
5
|
+
}, contractImportPath: string, options?: {
|
|
6
|
+
readonly scope: string;
|
|
7
|
+
}): string;
|
|
6
8
|
export declare function createBackendEffectApiExpose(scope: string, service: WorkspaceApp): string;
|
|
@@ -4,5 +4,5 @@ export declare function appDependencies(scope: string, packageSource: ResolvedPa
|
|
|
4
4
|
export declare function createRootPackageJson(scope: string, packageSource: ResolvedPackageSource, remotes?: WorkspaceApp[], bridge?: UltramodernBridgeConfig, additionalShells?: WorkspaceApp[]): JsonValue;
|
|
5
5
|
export { createAppMfTypesTsConfig, createAppTsConfig, createPackageTsConfig, createRootTsConfig, createSharedPackageTsConfig, createTsConfigBase, } from './tsconfigs.js';
|
|
6
6
|
export declare function createAppPackage(scope: string, app: WorkspaceApp, packageSource: ResolvedPackageSource, enableTailwind: boolean, remotes?: WorkspaceApp[], bridge?: UltramodernBridgeConfig): JsonValue;
|
|
7
|
-
export declare function createSharedPackage(scope: string, id: string, description: string): JsonValue;
|
|
7
|
+
export declare function createSharedPackage(scope: string, id: string, description: string, packageSource?: ResolvedPackageSource): JsonValue;
|
|
8
8
|
export declare function createSharedContractsIndex(): string;
|
|
@@ -82,6 +82,7 @@ export declare const ULTRAMODERN_PACKAGE_PINS: {
|
|
|
82
82
|
readonly rootDevDependencies: {
|
|
83
83
|
readonly '@effect/tsgo': "0.41.0";
|
|
84
84
|
readonly '@typescript/native': "npm:typescript@7.0.2";
|
|
85
|
+
readonly '@types/node': "^26.4.1";
|
|
85
86
|
readonly 'cross-env': "10.1.0";
|
|
86
87
|
readonly lefthook: "^2.1.10";
|
|
87
88
|
readonly miniflare: "4.20260730.0";
|
|
@@ -134,6 +135,7 @@ export declare const ULTRAMODERN_WORKSPACE_POLICY: {
|
|
|
134
135
|
readonly rootDevDependencies: {
|
|
135
136
|
readonly '@effect/tsgo': "0.41.0";
|
|
136
137
|
readonly '@typescript/native': "npm:typescript@7.0.2";
|
|
138
|
+
readonly '@types/node': "^26.4.1";
|
|
137
139
|
readonly 'cross-env': "10.1.0";
|
|
138
140
|
readonly lefthook: "^2.1.10";
|
|
139
141
|
readonly miniflare: "4.20260730.0";
|
package/package.json
CHANGED
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"engines": {
|
|
27
27
|
"node": ">=26.7.0"
|
|
28
28
|
},
|
|
29
|
-
"version": "3.9.0-ultramodern.
|
|
29
|
+
"version": "3.9.0-ultramodern.3",
|
|
30
30
|
"types": "./dist/types/index.d.ts",
|
|
31
31
|
"main": "./dist/esm-node/index.js",
|
|
32
32
|
"bin": {
|
|
@@ -82,8 +82,8 @@
|
|
|
82
82
|
],
|
|
83
83
|
"dependencies": {
|
|
84
84
|
"@modern-js/codesmith": "2.6.9",
|
|
85
|
-
"@modern-js/i18n-utils": "npm:@bleedingdev/modern-js-i18n-utils@3.9.0-ultramodern.
|
|
86
|
-
"@modern-js/utils": "npm:@bleedingdev/modern-js-utils@3.9.0-ultramodern.
|
|
85
|
+
"@modern-js/i18n-utils": "npm:@bleedingdev/modern-js-i18n-utils@3.9.0-ultramodern.3",
|
|
86
|
+
"@modern-js/utils": "npm:@bleedingdev/modern-js-utils@3.9.0-ultramodern.3",
|
|
87
87
|
"esbuild": "^0.28.2",
|
|
88
88
|
"oxfmt": "0.66.0",
|
|
89
89
|
"ultracite": "7.11.0"
|
|
@@ -110,6 +110,6 @@
|
|
|
110
110
|
"type-check": "tsgo --noEmit -p tsconfig.json"
|
|
111
111
|
},
|
|
112
112
|
"ultramodern": {
|
|
113
|
-
"frameworkVersion": "3.9.0-ultramodern.
|
|
113
|
+
"frameworkVersion": "3.9.0-ultramodern.3"
|
|
114
114
|
}
|
|
115
115
|
}
|