@bleedingdev/modern-js-create 3.4.0-ultramodern.1 → 3.4.0-ultramodern.10
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-workspace/add-vertical.cjs +24 -0
- package/dist/cjs/ultramodern-workspace/contracts.cjs +8 -4
- package/dist/cjs/ultramodern-workspace/demo-components.cjs +14 -21
- package/dist/cjs/ultramodern-workspace/descriptors.cjs +2 -2
- package/dist/cjs/ultramodern-workspace/effect-api.cjs +162 -31
- package/dist/cjs/ultramodern-workspace/module-federation.cjs +29 -10
- package/dist/cjs/ultramodern-workspace/package-json.cjs +102 -14
- package/dist/cjs/ultramodern-workspace/versions.cjs +1 -5
- package/dist/cjs/ultramodern-workspace/workspace-scripts.cjs +7 -0
- package/dist/cjs/ultramodern-workspace/write-workspace.cjs +6 -8
- package/dist/esm/ultramodern-workspace/add-vertical.js +25 -1
- package/dist/esm/ultramodern-workspace/contracts.js +9 -5
- package/dist/esm/ultramodern-workspace/demo-components.js +14 -21
- package/dist/esm/ultramodern-workspace/descriptors.js +2 -2
- package/dist/esm/ultramodern-workspace/effect-api.js +162 -31
- package/dist/esm/ultramodern-workspace/module-federation.js +27 -11
- package/dist/esm/ultramodern-workspace/package-json.js +87 -11
- package/dist/esm/ultramodern-workspace/versions.js +2 -3
- package/dist/esm/ultramodern-workspace/workspace-scripts.js +5 -1
- package/dist/esm/ultramodern-workspace/write-workspace.js +9 -11
- package/dist/esm-node/ultramodern-workspace/add-vertical.js +25 -1
- package/dist/esm-node/ultramodern-workspace/contracts.js +9 -5
- package/dist/esm-node/ultramodern-workspace/demo-components.js +14 -21
- package/dist/esm-node/ultramodern-workspace/descriptors.js +2 -2
- package/dist/esm-node/ultramodern-workspace/effect-api.js +162 -31
- package/dist/esm-node/ultramodern-workspace/module-federation.js +27 -11
- package/dist/esm-node/ultramodern-workspace/package-json.js +87 -11
- package/dist/esm-node/ultramodern-workspace/versions.js +2 -3
- package/dist/esm-node/ultramodern-workspace/workspace-scripts.js +5 -1
- package/dist/esm-node/ultramodern-workspace/write-workspace.js +9 -11
- package/dist/types/ultramodern-workspace/module-federation.d.ts +1 -0
- package/dist/types/ultramodern-workspace/package-json.d.ts +12 -2
- package/dist/types/ultramodern-workspace/versions.d.ts +1 -2
- package/dist/types/ultramodern-workspace/workspace-scripts.d.ts +1 -0
- package/package.json +4 -4
- package/template-workspace/AGENTS.md.handlebars +2 -1
- package/template-workspace/README.md.handlebars +7 -0
- package/template-workspace/oxfmt.config.ts +3 -1
- package/template-workspace/oxlint.config.ts +3 -1
- package/template-workspace/patches/@tanstack__router-core@1.171.13.patch +51 -0
- package/template-workspace/pnpm-workspace.yaml.handlebars +11 -0
- package/template-workspace/scripts/bootstrap-agent-skills.mjs +42 -10
- package/templates/app/shell-frame.tsx +1 -2
- package/templates/app/ultramodern-route-head.tsx.handlebars +22 -11
- package/templates/packages/shared-contracts-index.ts +206 -272
- package/templates/workspace-scripts/assert-mf-types.mjs.handlebars +9 -0
- package/templates/workspace-scripts/ultramodern-typecheck.mjs +197 -0
- package/templates/workspace-scripts/validate-ultramodern-workspace.mjs.handlebars +234 -2
|
@@ -10,8 +10,7 @@ import { VerticalShowcase } from '../vertical-components';
|
|
|
10
10
|
import { ultramodernUiMarker } from '../../ultramodern-build';
|
|
11
11
|
|
|
12
12
|
export default function ShellHome() {
|
|
13
|
-
const {
|
|
14
|
-
const t = i18nInstance['t'].bind(i18nInstance);
|
|
13
|
+
const { t } = useModernI18n();
|
|
15
14
|
|
|
16
15
|
return (
|
|
17
16
|
<ShellFrame>
|
|
@@ -84,13 +83,14 @@ const loadRemoteComponent = (specifier: string) =>
|
|
|
84
83
|
|
|
85
84
|
const createRemoteFallback = (specifier: string) =>
|
|
86
85
|
({ error }: { error: Error }) => {
|
|
87
|
-
const {
|
|
88
|
-
const t = i18nInstance['t'].bind(i18nInstance);
|
|
86
|
+
const { t } = useModernI18n();
|
|
89
87
|
const classification = classifyModuleFederationFallback(error);
|
|
88
|
+
const telemetryEntry =
|
|
89
|
+
typeof window === 'undefined' ? undefined : window.location.href;
|
|
90
90
|
const telemetry = createModuleFederationFallbackTelemetry({
|
|
91
91
|
appName: '${shellApp.id}',
|
|
92
92
|
classification,
|
|
93
|
-
|
|
93
|
+
...(telemetryEntry === undefined ? {} : { entry: telemetryEntry }),
|
|
94
94
|
error,
|
|
95
95
|
eventName: 'mf.client.remote.fallback',
|
|
96
96
|
exportName: 'default',
|
|
@@ -103,7 +103,7 @@ const createRemoteFallback = (specifier: string) =>
|
|
|
103
103
|
void emitModuleFederationFallbackTelemetry({
|
|
104
104
|
appName: telemetry.appName,
|
|
105
105
|
classification,
|
|
106
|
-
entry: telemetry.entry,
|
|
106
|
+
...(telemetry.entry === undefined ? {} : { entry: telemetry.entry }),
|
|
107
107
|
error,
|
|
108
108
|
eventName: telemetry.eventName,
|
|
109
109
|
exportName: 'default',
|
|
@@ -112,7 +112,7 @@ const createRemoteFallback = (specifier: string) =>
|
|
|
112
112
|
remote: specifier,
|
|
113
113
|
status: 'degraded',
|
|
114
114
|
});
|
|
115
|
-
}, [classification, error,
|
|
115
|
+
}, [classification, error, telemetry]);
|
|
116
116
|
|
|
117
117
|
return <div className="${tw('rounded-xl border border-red-900/20 bg-red-50 px-4 py-3 text-sm font-semibold text-red-900')}" data-remote-error={error.name} {...toModuleFederationFallbackAttributes(telemetry)}>{t('shell.remoteUnavailable')}</div>;
|
|
118
118
|
};
|
|
@@ -167,8 +167,7 @@ const createHydratedRemote =
|
|
|
167
167
|
${hydratedExports}
|
|
168
168
|
|
|
169
169
|
export const Header = () => {
|
|
170
|
-
const {
|
|
171
|
-
const t = i18nInstance['t'].bind(i18nInstance);
|
|
170
|
+
const { t } = useModernI18n();
|
|
172
171
|
|
|
173
172
|
return (
|
|
174
173
|
<header className="${tw('flex min-w-0 flex-wrap items-center gap-x-8 gap-y-2 md:flex-1')}" data-modern-boundary-id="${shellApp.mfName}" data-modern-mf-expose="shell/Header">
|
|
@@ -178,8 +177,7 @@ const createHydratedRemote =
|
|
|
178
177
|
};
|
|
179
178
|
|
|
180
179
|
export const StatusBadge = () => {
|
|
181
|
-
const {
|
|
182
|
-
const t = i18nInstance['t'].bind(i18nInstance);
|
|
180
|
+
const { t } = useModernI18n();
|
|
183
181
|
|
|
184
182
|
return (
|
|
185
183
|
<span className="${tw('inline-flex h-10 shrink-0 items-center justify-center rounded-full border border-stone-900/15 bg-white px-4 text-sm font-extrabold text-stone-950 shadow-lg shadow-stone-900/5')}">
|
|
@@ -189,8 +187,7 @@ export const StatusBadge = () => {
|
|
|
189
187
|
};
|
|
190
188
|
|
|
191
189
|
export const VerticalShowcase = () => {
|
|
192
|
-
const {
|
|
193
|
-
const t = i18nInstance['t'].bind(i18nInstance);
|
|
190
|
+
const { t } = useModernI18n();
|
|
194
191
|
|
|
195
192
|
if (widgetCount === 0) {
|
|
196
193
|
return (
|
|
@@ -257,8 +254,7 @@ import { ultramodernUiMarker } from '../../ultramodern-build';
|
|
|
257
254
|
` : '';
|
|
258
255
|
return `${effectBffImport}
|
|
259
256
|
export default function ${toPascalCase(app.id)}Home() {
|
|
260
|
-
const {
|
|
261
|
-
const t = i18nInstance['t'].bind(i18nInstance);
|
|
257
|
+
const { language, supportedLanguages, t } = useModernI18n();
|
|
262
258
|
${effectBffState} return (
|
|
263
259
|
<main className="${tw('min-h-screen bg-um-canvas px-4 py-6 text-um-foreground sm:px-8')}">
|
|
264
260
|
<UltramodernRouteHead />
|
|
@@ -304,8 +300,7 @@ function createRemoteEntry(app) {
|
|
|
304
300
|
return `import { useModernI18n } from '@modern-js/plugin-i18n/runtime';
|
|
305
301
|
|
|
306
302
|
export default function ${toPascalCase(domain)}Route() {
|
|
307
|
-
const {
|
|
308
|
-
const t = i18nInstance['t'].bind(i18nInstance);
|
|
303
|
+
const { t } = useModernI18n();
|
|
309
304
|
|
|
310
305
|
return (
|
|
311
306
|
<section className="${tw('rounded-2xl bg-white/90 p-5 shadow-xl shadow-stone-900/10')}" data-modern-boundary-id="${app.mfName}" data-modern-mf-expose="./Route">
|
|
@@ -323,8 +318,7 @@ function createRemoteWidget(app) {
|
|
|
323
318
|
return `import { useModernI18n } from '@modern-js/plugin-i18n/runtime';
|
|
324
319
|
|
|
325
320
|
export default function ${componentName}() {
|
|
326
|
-
const {
|
|
327
|
-
const t = i18nInstance['t'].bind(i18nInstance);
|
|
321
|
+
const { t } = useModernI18n();
|
|
328
322
|
|
|
329
323
|
return (
|
|
330
324
|
<section className="${tw('rounded-2xl bg-white/90 p-5 shadow-xl shadow-stone-900/10')}" data-modern-boundary-id="${app.mfName}" data-modern-mf-expose="./Widget">
|
|
@@ -343,8 +337,7 @@ function createRemoteExposeComponent(app, expose) {
|
|
|
343
337
|
return `import { useModernI18n } from '@modern-js/plugin-i18n/runtime';
|
|
344
338
|
|
|
345
339
|
export default function ${componentName}() {
|
|
346
|
-
const {
|
|
347
|
-
const t = i18nInstance['t'].bind(i18nInstance);
|
|
340
|
+
const { t } = useModernI18n();
|
|
348
341
|
|
|
349
342
|
return (
|
|
350
343
|
<section className="${tw('rounded-2xl bg-white/90 p-5 shadow-xl shadow-stone-900/10')}" data-modern-boundary-id="${app.mfName}" data-modern-mf-expose="${expose}">
|
|
@@ -35,12 +35,12 @@ const sharedPackages = [
|
|
|
35
35
|
{
|
|
36
36
|
id: 'shared-contracts',
|
|
37
37
|
directory: 'packages/shared-contracts',
|
|
38
|
-
description: '
|
|
38
|
+
description: 'Generated route, ownership, and topology contracts.'
|
|
39
39
|
},
|
|
40
40
|
{
|
|
41
41
|
id: 'shared-design-tokens',
|
|
42
42
|
directory: 'packages/shared-design-tokens',
|
|
43
|
-
description: '
|
|
43
|
+
description: 'Generated design tokens consumed by shell and verticals.'
|
|
44
44
|
}
|
|
45
45
|
];
|
|
46
46
|
function createNeutralOwnership(id, tier = 'tier-2-vertical') {
|
|
@@ -36,27 +36,51 @@ function serviceHasCheckoutCartState(service) {
|
|
|
36
36
|
function createCheckoutCartSharedSchemas(service) {
|
|
37
37
|
if (!serviceHasCheckoutCartState(service)) return '';
|
|
38
38
|
return `
|
|
39
|
-
export
|
|
39
|
+
export interface CheckoutCartLine {
|
|
40
|
+
readonly sku: string;
|
|
41
|
+
readonly name: string;
|
|
42
|
+
readonly quantity: number;
|
|
43
|
+
readonly unitPriceCents: number;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export interface CheckoutCart {
|
|
47
|
+
readonly lines: readonly CheckoutCartLine[];
|
|
48
|
+
readonly subtotalCents: number;
|
|
49
|
+
readonly totalQuantity: number;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export interface CheckoutAddCartItemPayload {
|
|
53
|
+
readonly sku: string;
|
|
54
|
+
readonly name?: string;
|
|
55
|
+
readonly quantity: number;
|
|
56
|
+
readonly unitPriceCents?: number;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export interface CheckoutRemoveCartItemPayload {
|
|
60
|
+
readonly sku: string;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export const checkoutCartLineSchema: Schema.Codec<CheckoutCartLine> = Schema.Struct({
|
|
40
64
|
sku: Schema.String,
|
|
41
65
|
name: Schema.String,
|
|
42
66
|
quantity: Schema.Finite,
|
|
43
67
|
unitPriceCents: Schema.Finite,
|
|
44
68
|
});
|
|
45
69
|
|
|
46
|
-
export const checkoutCartSchema = Schema.Struct({
|
|
70
|
+
export const checkoutCartSchema: Schema.Codec<CheckoutCart> = Schema.Struct({
|
|
47
71
|
lines: Schema.Array(checkoutCartLineSchema),
|
|
48
72
|
subtotalCents: Schema.Finite,
|
|
49
73
|
totalQuantity: Schema.Finite,
|
|
50
74
|
});
|
|
51
75
|
|
|
52
|
-
export const checkoutAddCartItemPayloadSchema = Schema.Struct({
|
|
76
|
+
export const checkoutAddCartItemPayloadSchema: Schema.Codec<CheckoutAddCartItemPayload> = Schema.Struct({
|
|
53
77
|
sku: Schema.String,
|
|
54
78
|
name: Schema.optional(Schema.String),
|
|
55
79
|
quantity: Schema.Finite,
|
|
56
80
|
unitPriceCents: Schema.optional(Schema.Finite),
|
|
57
81
|
});
|
|
58
82
|
|
|
59
|
-
export const checkoutRemoveCartItemPayloadSchema = Schema.Struct({
|
|
83
|
+
export const checkoutRemoveCartItemPayloadSchema: Schema.Codec<CheckoutRemoveCartItemPayload> = Schema.Struct({
|
|
60
84
|
sku: Schema.String,
|
|
61
85
|
});
|
|
62
86
|
`;
|
|
@@ -209,6 +233,7 @@ function createCheckoutCartClientExports(service) {
|
|
|
209
233
|
const pascalStem = toPascalCase(stem);
|
|
210
234
|
const clientOptionsName = `${pascalStem}ClientOptions`;
|
|
211
235
|
const createClientName = `create${pascalStem}Client`;
|
|
236
|
+
const clientEffectTypeName = `${pascalStem}ClientEffect`;
|
|
212
237
|
return `
|
|
213
238
|
export interface CheckoutCartLine {
|
|
214
239
|
sku: string;
|
|
@@ -232,7 +257,7 @@ export interface CheckoutAddCartItemInput {
|
|
|
232
257
|
|
|
233
258
|
export const getCheckoutCart = (
|
|
234
259
|
options: ${clientOptionsName} = {},
|
|
235
|
-
) =>
|
|
260
|
+
): ${clientEffectTypeName}<CheckoutCart> =>
|
|
236
261
|
${createClientName}({
|
|
237
262
|
...options,
|
|
238
263
|
operationContext:
|
|
@@ -244,7 +269,7 @@ export const getCheckoutCart = (
|
|
|
244
269
|
export const addCheckoutCartItem = (
|
|
245
270
|
payload: CheckoutAddCartItemInput,
|
|
246
271
|
options: ${clientOptionsName} = {},
|
|
247
|
-
) =>
|
|
272
|
+
): ${clientEffectTypeName}<CheckoutCart> =>
|
|
248
273
|
${createClientName}({
|
|
249
274
|
...options,
|
|
250
275
|
operationContext:
|
|
@@ -258,7 +283,7 @@ export const addCheckoutCartItem = (
|
|
|
258
283
|
export const removeCheckoutCartItem = (
|
|
259
284
|
sku: string,
|
|
260
285
|
options: ${clientOptionsName} = {},
|
|
261
|
-
) =>
|
|
286
|
+
): ${clientEffectTypeName}<CheckoutCart> =>
|
|
262
287
|
${createClientName}({
|
|
263
288
|
...options,
|
|
264
289
|
operationContext:
|
|
@@ -271,7 +296,7 @@ export const removeCheckoutCartItem = (
|
|
|
271
296
|
|
|
272
297
|
export const clearCheckoutCart = (
|
|
273
298
|
options: ${clientOptionsName} = {},
|
|
274
|
-
) =>
|
|
299
|
+
): ${clientEffectTypeName}<CheckoutCart> =>
|
|
275
300
|
${createClientName}({
|
|
276
301
|
...options,
|
|
277
302
|
operationContext:
|
|
@@ -302,12 +327,63 @@ function createEffectSharedApiContract(service) {
|
|
|
302
327
|
const apiName = verticalEffectApiName(service);
|
|
303
328
|
const groupName = verticalEffectGroupName(service);
|
|
304
329
|
const stem = effectApiStem(service);
|
|
330
|
+
const pascalStem = toPascalCase(stem);
|
|
331
|
+
const markerType = `${pascalStem}Marker`;
|
|
332
|
+
const itemType = `${pascalStem}Item`;
|
|
333
|
+
const readinessType = `${pascalStem}Readiness`;
|
|
334
|
+
const createPayloadType = `${pascalStem}CreatePayload`;
|
|
335
|
+
const createResponseType = `${pascalStem}CreateResponse`;
|
|
336
|
+
const listResponseType = `${pascalStem}ListResponse`;
|
|
305
337
|
const apiPrefix = effectApiPrefix(service);
|
|
306
338
|
const checkoutCartSharedSchemas = createCheckoutCartSharedSchemas(service);
|
|
307
339
|
const checkoutCartSharedSchemaSection = '' === checkoutCartSharedSchemas ? '' : `${checkoutCartSharedSchemas}\n`;
|
|
308
340
|
const checkoutCartOperationContexts = createCheckoutCartOperationContexts(service).trimStart();
|
|
309
341
|
const checkoutCartOperationContextEntries = '' === checkoutCartOperationContexts ? '' : `${checkoutCartOperationContexts}\n`;
|
|
310
|
-
return `export
|
|
342
|
+
return `export interface ${markerType} {
|
|
343
|
+
readonly appId: string;
|
|
344
|
+
readonly build: string;
|
|
345
|
+
readonly deployProfile: string;
|
|
346
|
+
readonly packageName: string;
|
|
347
|
+
readonly surface: string;
|
|
348
|
+
readonly version: string;
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
export interface ${itemType} {
|
|
352
|
+
readonly id: string;
|
|
353
|
+
readonly marker: ${markerType};
|
|
354
|
+
readonly title: string;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
export interface ${readinessType} {
|
|
358
|
+
readonly checks: {
|
|
359
|
+
readonly effectBff: 'ready';
|
|
360
|
+
readonly moduleFederation: 'ready';
|
|
361
|
+
readonly ssr: 'ready';
|
|
362
|
+
readonly translations: 'ready';
|
|
363
|
+
};
|
|
364
|
+
readonly marker: ${markerType};
|
|
365
|
+
readonly status: 'ready';
|
|
366
|
+
readonly versionSkew: 'none';
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
export interface ${createPayloadType} {
|
|
370
|
+
readonly title: string;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
export interface ${listResponseType} {
|
|
374
|
+
readonly items: readonly ${itemType}[];
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
export interface ${createResponseType} {
|
|
378
|
+
readonly item: ${itemType};
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
export interface ${notFoundErrorExport} {
|
|
382
|
+
readonly _tag: '${notFoundErrorExport}';
|
|
383
|
+
readonly id: string;
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
export const ${markerSchemaExport}: Schema.Codec<${markerType}> = Schema.Struct({
|
|
311
387
|
appId: Schema.String,
|
|
312
388
|
build: Schema.String,
|
|
313
389
|
deployProfile: Schema.String,
|
|
@@ -316,13 +392,13 @@ function createEffectSharedApiContract(service) {
|
|
|
316
392
|
version: Schema.String,
|
|
317
393
|
});
|
|
318
394
|
|
|
319
|
-
export const ${schemaExport} = Schema.Struct({
|
|
395
|
+
export const ${schemaExport}: Schema.Codec<${itemType}> = Schema.Struct({
|
|
320
396
|
id: Schema.String,
|
|
321
397
|
marker: ${markerSchemaExport},
|
|
322
398
|
title: Schema.String,
|
|
323
399
|
});
|
|
324
400
|
|
|
325
|
-
export const ${readinessSchemaExport} = Schema.Struct({
|
|
401
|
+
export const ${readinessSchemaExport}: Schema.Codec<${readinessType}> = Schema.Struct({
|
|
326
402
|
checks: Schema.Struct({
|
|
327
403
|
effectBff: Schema.Literal('ready'),
|
|
328
404
|
moduleFederation: Schema.Literal('ready'),
|
|
@@ -334,18 +410,13 @@ export const ${readinessSchemaExport} = Schema.Struct({
|
|
|
334
410
|
versionSkew: Schema.Literal('none'),
|
|
335
411
|
});
|
|
336
412
|
|
|
337
|
-
export const ${createPayloadSchemaExport} = Schema.Struct({
|
|
413
|
+
export const ${createPayloadSchemaExport}: Schema.Codec<${createPayloadType}> = Schema.Struct({
|
|
338
414
|
title: Schema.String,
|
|
339
415
|
});
|
|
340
416
|
|
|
341
|
-
${checkoutCartSharedSchemaSection}export
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
id: Schema.String,
|
|
345
|
-
},
|
|
346
|
-
) {}
|
|
347
|
-
|
|
348
|
-
export const ${notFoundSchemaExport} = ${notFoundErrorExport}.pipe(
|
|
417
|
+
${checkoutCartSharedSchemaSection}export const ${notFoundSchemaExport}: Schema.Codec<${notFoundErrorExport}> = Schema.TaggedStruct('${notFoundErrorExport}', {
|
|
418
|
+
id: Schema.String,
|
|
419
|
+
}).pipe(
|
|
349
420
|
HttpApiSchema.status(404),
|
|
350
421
|
);
|
|
351
422
|
|
|
@@ -449,13 +520,20 @@ function createEffectServiceEntry(service, contractImportPath) {
|
|
|
449
520
|
HttpApiBuilder,
|
|
450
521
|
Layer,
|
|
451
522
|
} from '@modern-js/plugin-bff/effect-edge';
|
|
452
|
-
import {
|
|
523
|
+
import type {
|
|
524
|
+
EffectBffDefinition,
|
|
525
|
+
EffectBffRuntime,
|
|
526
|
+
EffectRuntimeLayer,
|
|
527
|
+
} from '@modern-js/plugin-bff/effect-edge';
|
|
528
|
+
import { ultramodernApiMarker } from '../../shared/ultramodern-build.ts';
|
|
453
529
|
import {
|
|
454
530
|
${apiExport},
|
|
455
531
|
${groupName}OperationContexts,
|
|
532
|
+
} from '${contractImportPath}';
|
|
533
|
+
import type {
|
|
456
534
|
${notFoundErrorExport},
|
|
535
|
+
OperationContext,
|
|
457
536
|
} from '${contractImportPath}';
|
|
458
|
-
import type { OperationContext } from '${contractImportPath}';
|
|
459
537
|
|
|
460
538
|
const ${groupName}Items = [
|
|
461
539
|
{
|
|
@@ -516,9 +594,13 @@ const ${groupName}Layer = HttpApiBuilder.group(
|
|
|
516
594
|
const matchedItem = ${groupName}Items.find(
|
|
517
595
|
candidate => candidate.id === params.id,
|
|
518
596
|
);
|
|
597
|
+
const notFound: ${notFoundErrorExport} = {
|
|
598
|
+
_tag: '${notFoundErrorExport}',
|
|
599
|
+
id: params.id,
|
|
600
|
+
};
|
|
519
601
|
const result =
|
|
520
602
|
matchedItem === undefined
|
|
521
|
-
? Effect.fail(
|
|
603
|
+
? Effect.fail(notFound)
|
|
522
604
|
: Effect.succeed(matchedItem);
|
|
523
605
|
|
|
524
606
|
return result.pipe(
|
|
@@ -549,12 +631,15 @@ const ${groupName}Layer = HttpApiBuilder.group(
|
|
|
549
631
|
|
|
550
632
|
const layer = HttpApiBuilder.layer(${apiExport}).pipe(
|
|
551
633
|
Layer.provide(${groupName}Layer),
|
|
552
|
-
);
|
|
634
|
+
) satisfies EffectRuntimeLayer;
|
|
553
635
|
|
|
554
|
-
|
|
636
|
+
const effectBff: EffectBffDefinition<typeof ${apiExport}, EffectRuntimeLayer> &
|
|
637
|
+
EffectBffRuntime<typeof ${apiExport}, EffectRuntimeLayer> = defineEffectBff({
|
|
555
638
|
api: ${apiExport},
|
|
556
639
|
layer,
|
|
557
640
|
});
|
|
641
|
+
|
|
642
|
+
export default effectBff;
|
|
558
643
|
`;
|
|
559
644
|
}
|
|
560
645
|
function createEffectClient(service, contractImportPath) {
|
|
@@ -565,25 +650,71 @@ function createEffectClient(service, contractImportPath) {
|
|
|
565
650
|
const singular = verticalEffectErrorStem(service);
|
|
566
651
|
const clientOptionsName = `${toPascalCase(stem)}ClientOptions`;
|
|
567
652
|
const createClientName = `create${toPascalCase(stem)}Client`;
|
|
653
|
+
const clientTypeName = `${toPascalCase(stem)}Client`;
|
|
654
|
+
const clientEffectTypeName = `${toPascalCase(stem)}ClientEffect`;
|
|
568
655
|
const listName = `list${toPascalCase(stem)}`;
|
|
569
656
|
const readinessName = `get${toPascalCase(stem)}Readiness`;
|
|
570
657
|
const getName = `get${toPascalCase(singular)}`;
|
|
571
658
|
const createName = `create${toPascalCase(singular)}`;
|
|
659
|
+
const notFoundErrorExport = verticalEffectNotFoundErrorExport(service);
|
|
660
|
+
const pascalStem = toPascalCase(stem);
|
|
661
|
+
const itemType = `${pascalStem}Item`;
|
|
662
|
+
const readinessType = `${pascalStem}Readiness`;
|
|
663
|
+
const createResponseType = `${pascalStem}CreateResponse`;
|
|
664
|
+
const listResponseType = `${pascalStem}ListResponse`;
|
|
572
665
|
const checkoutCartClientExports = createCheckoutCartClientExports(service);
|
|
573
666
|
return `import {
|
|
574
667
|
Effect,
|
|
575
668
|
makeEffectHttpApiClient,
|
|
576
669
|
runEffectRequest,
|
|
577
670
|
} from '@modern-js/plugin-bff/effect-client';
|
|
671
|
+
import type {
|
|
672
|
+
HttpClientError,
|
|
673
|
+
HttpApi,
|
|
674
|
+
HttpApiClient,
|
|
675
|
+
HttpApiGroup,
|
|
676
|
+
Schema,
|
|
677
|
+
} from '@modern-js/plugin-bff/effect-client';
|
|
578
678
|
import {
|
|
579
679
|
${contractExport}ApiContract,
|
|
580
680
|
${apiExport},
|
|
581
681
|
${groupName}OperationContexts,
|
|
582
682
|
} from '${contractImportPath}';
|
|
583
|
-
import type {
|
|
683
|
+
import type {
|
|
684
|
+
${createResponseType},
|
|
685
|
+
${itemType},
|
|
686
|
+
${listResponseType},
|
|
687
|
+
${notFoundErrorExport},
|
|
688
|
+
OperationContext,
|
|
689
|
+
${readinessType},
|
|
690
|
+
} from '${contractImportPath}';
|
|
584
691
|
|
|
585
692
|
export { Effect, runEffectRequest };
|
|
586
693
|
|
|
694
|
+
type ${pascalStem}EffectGroups = typeof ${apiExport} extends HttpApi.HttpApi<
|
|
695
|
+
infer _ApiId,
|
|
696
|
+
infer Groups
|
|
697
|
+
>
|
|
698
|
+
? Groups
|
|
699
|
+
: never;
|
|
700
|
+
|
|
701
|
+
export type ${clientTypeName} = HttpApiClient.Client<
|
|
702
|
+
Extract<${pascalStem}EffectGroups, HttpApiGroup.Any>,
|
|
703
|
+
never,
|
|
704
|
+
never
|
|
705
|
+
>;
|
|
706
|
+
|
|
707
|
+
export type ${pascalStem}ClientError =
|
|
708
|
+
| ${notFoundErrorExport}
|
|
709
|
+
| HttpClientError.HttpClientError
|
|
710
|
+
| Schema.SchemaError;
|
|
711
|
+
|
|
712
|
+
export type ${clientEffectTypeName}<Success> = Effect.Effect<
|
|
713
|
+
Success,
|
|
714
|
+
${pascalStem}ClientError,
|
|
715
|
+
never
|
|
716
|
+
>;
|
|
717
|
+
|
|
587
718
|
export interface ${clientOptionsName} {
|
|
588
719
|
baseUrl?: string | URL;
|
|
589
720
|
locale?: string;
|
|
@@ -593,7 +724,7 @@ export interface ${clientOptionsName} {
|
|
|
593
724
|
|
|
594
725
|
export const ${createClientName} = (
|
|
595
726
|
options: ${clientOptionsName} = {},
|
|
596
|
-
) =>
|
|
727
|
+
): ${clientEffectTypeName}<${clientTypeName}> =>
|
|
597
728
|
makeEffectHttpApiClient(${apiExport}, {
|
|
598
729
|
baseUrl: options.baseUrl ?? ${contractExport}ApiContract.apiPrefix,
|
|
599
730
|
requestContext: {
|
|
@@ -609,7 +740,7 @@ export const ${createClientName} = (
|
|
|
609
740
|
|
|
610
741
|
export const ${listName} = (
|
|
611
742
|
options: ${clientOptionsName} & { limit?: number } = {},
|
|
612
|
-
) =>
|
|
743
|
+
): ${clientEffectTypeName}<${listResponseType}> =>
|
|
613
744
|
${createClientName}({
|
|
614
745
|
...options,
|
|
615
746
|
operationContext:
|
|
@@ -622,7 +753,7 @@ export const ${listName} = (
|
|
|
622
753
|
|
|
623
754
|
export const ${readinessName} = (
|
|
624
755
|
options: ${clientOptionsName} = {},
|
|
625
|
-
) =>
|
|
756
|
+
): ${clientEffectTypeName}<${readinessType}> =>
|
|
626
757
|
${createClientName}({
|
|
627
758
|
...options,
|
|
628
759
|
operationContext:
|
|
@@ -634,7 +765,7 @@ export const ${readinessName} = (
|
|
|
634
765
|
export const ${getName} = (
|
|
635
766
|
id: string,
|
|
636
767
|
options: ${clientOptionsName} = {},
|
|
637
|
-
) =>
|
|
768
|
+
): ${clientEffectTypeName}<${itemType}> =>
|
|
638
769
|
${createClientName}({
|
|
639
770
|
...options,
|
|
640
771
|
operationContext:
|
|
@@ -646,7 +777,7 @@ export const ${getName} = (
|
|
|
646
777
|
export const ${createName} = (
|
|
647
778
|
title: string,
|
|
648
779
|
options: ${clientOptionsName} = {},
|
|
649
|
-
) =>
|
|
780
|
+
): ${clientEffectTypeName}<${createResponseType}> =>
|
|
650
781
|
${createClientName}({
|
|
651
782
|
...options,
|
|
652
783
|
operationContext:
|
|
@@ -122,7 +122,7 @@ ${bffConfig} ...(cloudflareDeployEnabled
|
|
|
122
122
|
},
|
|
123
123
|
output: {
|
|
124
124
|
assetPrefix,
|
|
125
|
-
disableTsChecker:
|
|
125
|
+
disableTsChecker: false,
|
|
126
126
|
distPath: {
|
|
127
127
|
html: './',
|
|
128
128
|
},
|
|
@@ -178,6 +178,10 @@ ${bffPluginEntry} moduleFederationPlugin(),
|
|
|
178
178
|
},
|
|
179
179
|
},
|
|
180
180
|
source: {
|
|
181
|
+
alias: {
|
|
182
|
+
'@modern-js/plugin-i18n/runtime':
|
|
183
|
+
'@modern-js/plugin-i18n/runtime/no-react-i18next',
|
|
184
|
+
},
|
|
181
185
|
globalVars: {
|
|
182
186
|
ULTRAMODERN_SITE_URL: siteUrl,
|
|
183
187
|
},
|
|
@@ -191,12 +195,6 @@ ${bffPluginEntry} moduleFederationPlugin(),
|
|
|
191
195
|
chain.output
|
|
192
196
|
.uniqueName('${createRspackUniqueName(app)}')
|
|
193
197
|
.chunkLoadingGlobal('${createRspackChunkLoadingGlobal(app)}');
|
|
194
|
-
chain.ignoreWarnings([
|
|
195
|
-
{
|
|
196
|
-
message: /the request of a dependency is an expression/u,
|
|
197
|
-
module: /modern-js-plugin-i18n/u,
|
|
198
|
-
},
|
|
199
|
-
]);
|
|
200
198
|
},
|
|
201
199
|
},
|
|
202
200
|
},
|
|
@@ -213,7 +211,7 @@ ${bffPluginEntry} moduleFederationPlugin(),
|
|
|
213
211
|
}
|
|
214
212
|
function createSharedModuleFederationConfig() {
|
|
215
213
|
return ` shared: {
|
|
216
|
-
'@modern-js/plugin-i18n/runtime': {
|
|
214
|
+
'@modern-js/plugin-i18n/runtime/no-react-i18next': {
|
|
217
215
|
requiredVersion: pluginI18nVersion,
|
|
218
216
|
singleton: true,
|
|
219
217
|
treeShaking: false,
|
|
@@ -333,7 +331,9 @@ const reactVersion = (require('react/package.json') as { version: string }).vers
|
|
|
333
331
|
const reactDomVersion = (require('react-dom/package.json') as { version: string }).version;
|
|
334
332
|
|
|
335
333
|
${createModuleFederationRemoteUrlHelpers(shellHost, remotes)}
|
|
336
|
-
|
|
334
|
+
const moduleFederationConfig: Parameters<
|
|
335
|
+
typeof createModuleFederationConfig
|
|
336
|
+
>[0] = createModuleFederationConfig({
|
|
337
337
|
bridge: {
|
|
338
338
|
enableBridgeRouter: false,
|
|
339
339
|
},
|
|
@@ -345,12 +345,15 @@ export default createModuleFederationConfig({
|
|
|
345
345
|
generateTypes: {
|
|
346
346
|
compilerInstance: 'tsgo',
|
|
347
347
|
},
|
|
348
|
+
tsConfigPath: './tsconfig.mf-types.json',
|
|
348
349
|
},
|
|
349
350
|
filename: 'remoteEntry.js',
|
|
350
351
|
name: '${shellApp.mfName}',
|
|
351
352
|
${createModuleFederationRemotesConfig(scope, shellHost, remotes)}${createSharedModuleFederationConfig()},
|
|
352
353
|
treeShakingSharedExcludePlugins: ['RspackModuleFederationPlugin'],
|
|
353
354
|
});
|
|
355
|
+
|
|
356
|
+
export default moduleFederationConfig;
|
|
354
357
|
`;
|
|
355
358
|
}
|
|
356
359
|
function createBuildMarker(scope, app) {
|
|
@@ -376,6 +379,14 @@ export const ultramodernApiMarker = {
|
|
|
376
379
|
} as const;
|
|
377
380
|
`;
|
|
378
381
|
}
|
|
382
|
+
function createUltramodernBuildReexportModule() {
|
|
383
|
+
return `export {
|
|
384
|
+
ultramodernApiMarker,
|
|
385
|
+
ultramodernUiMarker,
|
|
386
|
+
ultramodernVerticalIdentity,
|
|
387
|
+
} from '../shared/ultramodern-build';
|
|
388
|
+
`;
|
|
389
|
+
}
|
|
379
390
|
function createRemoteModuleFederationConfig(scope, app, remotes = []) {
|
|
380
391
|
const exposes = formatTsObjectLiteral(app.exposes ?? {});
|
|
381
392
|
return `// @effect-diagnostics nodeBuiltinImport:off
|
|
@@ -391,7 +402,9 @@ const reactVersion = (require('react/package.json') as { version: string }).vers
|
|
|
391
402
|
const reactDomVersion = (require('react-dom/package.json') as { version: string }).version;
|
|
392
403
|
|
|
393
404
|
${createModuleFederationRemoteUrlHelpers(app, remotes)}
|
|
394
|
-
|
|
405
|
+
const moduleFederationConfig: Parameters<
|
|
406
|
+
typeof createModuleFederationConfig
|
|
407
|
+
>[0] = createModuleFederationConfig({
|
|
395
408
|
bridge: {
|
|
396
409
|
enableBridgeRouter: false,
|
|
397
410
|
},
|
|
@@ -403,6 +416,7 @@ export default createModuleFederationConfig({
|
|
|
403
416
|
generateTypes: {
|
|
404
417
|
compilerInstance: 'tsgo',
|
|
405
418
|
},
|
|
419
|
+
tsConfigPath: './tsconfig.mf-types.json',
|
|
406
420
|
},
|
|
407
421
|
exposes: ${exposes},
|
|
408
422
|
filename: 'remoteEntry.js',
|
|
@@ -410,6 +424,8 @@ export default createModuleFederationConfig({
|
|
|
410
424
|
${createModuleFederationRemotesConfig(scope, app, remotes)}${createSharedModuleFederationConfig()},
|
|
411
425
|
treeShakingSharedExcludePlugins: ['RspackModuleFederationPlugin'],
|
|
412
426
|
});
|
|
427
|
+
|
|
428
|
+
export default moduleFederationConfig;
|
|
413
429
|
`;
|
|
414
430
|
}
|
|
415
|
-
export { createAppModernConfig, createBuildMarker, createModuleFederationRemoteUrlHelpers, createModuleFederationRemotesConfig, createRemoteModuleFederationConfig, createSharedModuleFederationConfig, createShellModuleFederationConfig, createUltramodernBuildModule, formatTsObjectLiteral };
|
|
431
|
+
export { createAppModernConfig, createBuildMarker, createModuleFederationRemoteUrlHelpers, createModuleFederationRemotesConfig, createRemoteModuleFederationConfig, createSharedModuleFederationConfig, createShellModuleFederationConfig, createUltramodernBuildModule, createUltramodernBuildReexportModule, formatTsObjectLiteral };
|