@bleedingdev/modern-js-create 3.4.0-ultramodern.0 → 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/README.md +7 -7
- 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
package/README.md
CHANGED
|
@@ -75,13 +75,13 @@ the repo `tsgo:dts` flow. Run `pnpm --filter @modern-js/create test` when
|
|
|
75
75
|
changing generator behavior; it includes a boundary test that scans generator
|
|
76
76
|
sources, templates, and generated workspace output for compiler API imports.
|
|
77
77
|
|
|
78
|
-
Generated app packages
|
|
79
|
-
`@effect/tsgo` plus
|
|
80
|
-
`
|
|
81
|
-
|
|
82
|
-
TypeScript 6 package. If a future AST
|
|
83
|
-
dedicated compatibility module and test it
|
|
84
|
-
native-preview internals.
|
|
78
|
+
Generated app packages keep stable `typescript` for classic compiler consumers
|
|
79
|
+
such as Module Federation DTS generation, and use `@effect/tsgo` plus
|
|
80
|
+
`@typescript/native-preview` as tooling for `pnpm typecheck`. Generated
|
|
81
|
+
app/package source must not depend on compiler API internals. Existing compiler
|
|
82
|
+
API tests in this package use the stable TypeScript 6 package. If a future AST
|
|
83
|
+
utility is needed, keep it behind a dedicated compatibility module and test it
|
|
84
|
+
against stable `typescript`, not native-preview internals.
|
|
85
85
|
|
|
86
86
|
Generated CI does not call the local aggregate. It runs format, lint,
|
|
87
87
|
typecheck, skills, i18n boundary validation, contract validation, and build as
|
|
@@ -143,6 +143,8 @@ function rewriteShellAppFiles(workspaceRoot, scope, packageSource, enableTailwin
|
|
|
143
143
|
const shellHost = (0, external_descriptors_cjs_namespaceObject.createShellHost)(remotes);
|
|
144
144
|
const publicWeb = (0, external_public_surface_cjs_namespaceObject.createPublicWebAppArtifacts)(shellHost);
|
|
145
145
|
(0, external_fs_io_cjs_namespaceObject.writeJsonFile)(external_node_path_default().join(workspaceRoot, `${external_descriptors_cjs_namespaceObject.shellApp.directory}/package.json`), (0, external_package_json_cjs_namespaceObject.createAppPackage)(scope, shellHost, packageSource, enableTailwind, remotes));
|
|
146
|
+
(0, external_fs_io_cjs_namespaceObject.writeJsonFile)(external_node_path_default().join(workspaceRoot, `${external_descriptors_cjs_namespaceObject.shellApp.directory}/tsconfig.json`), (0, external_package_json_cjs_namespaceObject.createAppTsConfig)(shellHost, remotes));
|
|
147
|
+
(0, external_fs_io_cjs_namespaceObject.writeJsonFile)(external_node_path_default().join(workspaceRoot, `${external_descriptors_cjs_namespaceObject.shellApp.directory}/tsconfig.mf-types.json`), (0, external_package_json_cjs_namespaceObject.createAppMfTypesTsConfig)(shellHost));
|
|
146
148
|
(0, external_fs_io_cjs_namespaceObject.writeFileReplacing)(workspaceRoot, `${external_descriptors_cjs_namespaceObject.shellApp.directory}/src/modern-app-env.d.ts`, (0, external_app_files_cjs_namespaceObject.createAppEnvDts)(shellHost, remotes));
|
|
147
149
|
(0, external_fs_io_cjs_namespaceObject.writeFileReplacing)(workspaceRoot, publicWeb.jsonLdHelperFile.path, publicWeb.jsonLdHelperFile.content);
|
|
148
150
|
(0, external_fs_io_cjs_namespaceObject.writeFileReplacing)(workspaceRoot, publicWeb.routeMetadataFile.path, publicWeb.routeMetadataFile.content);
|
|
@@ -483,6 +485,21 @@ function createDryRunJsonMutations(preflight, manifestUrl) {
|
|
|
483
485
|
pointer: '/dependencies',
|
|
484
486
|
description: `Wire shell dependencies for ${vertical.id}`
|
|
485
487
|
},
|
|
488
|
+
{
|
|
489
|
+
path: 'tsconfig.json',
|
|
490
|
+
pointer: '/references',
|
|
491
|
+
description: `Add ${vertical.id} to the root TS-Go build graph`
|
|
492
|
+
},
|
|
493
|
+
{
|
|
494
|
+
path: `${external_descriptors_cjs_namespaceObject.shellApp.directory}/tsconfig.json`,
|
|
495
|
+
pointer: '/references',
|
|
496
|
+
description: `Add ${vertical.id} to the shell TS-Go project references`
|
|
497
|
+
},
|
|
498
|
+
{
|
|
499
|
+
path: `${external_descriptors_cjs_namespaceObject.shellApp.directory}/tsconfig.mf-types.json`,
|
|
500
|
+
pointer: '/include',
|
|
501
|
+
description: 'Keep shell Module Federation DTS compilation scoped'
|
|
502
|
+
},
|
|
486
503
|
{
|
|
487
504
|
path: external_descriptors_cjs_namespaceObject.GENERATED_CONTRACT_PATH,
|
|
488
505
|
pointer: '/apps',
|
|
@@ -546,6 +563,13 @@ function addUltramodernVertical(options) {
|
|
|
546
563
|
addShellZephyrDependency(options.workspaceRoot, scope, vertical);
|
|
547
564
|
addShellWorkspaceDependency(options.workspaceRoot, scope, vertical);
|
|
548
565
|
updateRootWorkspaceScripts(options.workspaceRoot, scope, packageSource, updatedVerticals);
|
|
566
|
+
(0, external_fs_io_cjs_namespaceObject.writeJsonFile)(external_node_path_default().join(options.workspaceRoot, 'tsconfig.json'), (0, external_package_json_cjs_namespaceObject.createRootTsConfig)([
|
|
567
|
+
{
|
|
568
|
+
...external_descriptors_cjs_namespaceObject.shellApp,
|
|
569
|
+
verticalRefs: updatedVerticals.map((vertical)=>vertical.id)
|
|
570
|
+
},
|
|
571
|
+
...updatedVerticals
|
|
572
|
+
]));
|
|
549
573
|
const afterFiles = (0, external_generation_result_cjs_namespaceObject.createFileSnapshot)(options.workspaceRoot);
|
|
550
574
|
const { createdPaths, rewrittenPaths } = (0, external_generation_result_cjs_namespaceObject.diffFileSnapshots)(beforeFiles, afterFiles);
|
|
551
575
|
const result = (0, external_generation_result_cjs_namespaceObject.createGenerationResult)({
|
|
@@ -236,7 +236,7 @@ function createAppConfigContract(app) {
|
|
|
236
236
|
],
|
|
237
237
|
default: '/'
|
|
238
238
|
},
|
|
239
|
-
disableTsChecker:
|
|
239
|
+
disableTsChecker: false,
|
|
240
240
|
distPath: {
|
|
241
241
|
html: './'
|
|
242
242
|
},
|
|
@@ -595,8 +595,9 @@ function createAppGeneratedContract(scope, app, apps, enableTailwind) {
|
|
|
595
595
|
} : {},
|
|
596
596
|
exposes: Object.keys(app.exposes ?? {}),
|
|
597
597
|
dts: {
|
|
598
|
+
compilerInstance: 'tsgo',
|
|
598
599
|
displayErrorInTerminal: true,
|
|
599
|
-
|
|
600
|
+
tsConfigPath: './tsconfig.mf-types.json'
|
|
600
601
|
},
|
|
601
602
|
browserSafeExposesOnly: true,
|
|
602
603
|
zephyrRspackPlugin: external_versions_cjs_namespaceObject.ZEPHYR_RSPACK_PLUGIN_VERSION
|
|
@@ -648,8 +649,8 @@ function createGeneratedContract(scope, apps = [
|
|
|
648
649
|
toolchain: 'mise'
|
|
649
650
|
},
|
|
650
651
|
versions: {
|
|
651
|
-
typescript: external_versions_cjs_namespaceObject.
|
|
652
|
-
|
|
652
|
+
typescript: external_versions_cjs_namespaceObject.TYPESCRIPT_NATIVE_PREVIEW_VERSION,
|
|
653
|
+
typescriptCompatibility: external_versions_cjs_namespaceObject.TYPESCRIPT_VERSION,
|
|
653
654
|
typescriptNativePreview: external_versions_cjs_namespaceObject.TYPESCRIPT_NATIVE_PREVIEW_VERSION,
|
|
654
655
|
moduleFederation: external_versions_cjs_namespaceObject.MODULE_FEDERATION_VERSION,
|
|
655
656
|
tanstackRouter: external_versions_cjs_namespaceObject.TANSTACK_ROUTER_VERSION,
|
|
@@ -716,9 +717,11 @@ function createTemplateManifest(modernVersion, packageSource) {
|
|
|
716
717
|
'package.json',
|
|
717
718
|
'oxfmt.config.ts',
|
|
718
719
|
'oxlint.config.ts',
|
|
720
|
+
'patches/**',
|
|
719
721
|
'pnpm-workspace.yaml',
|
|
720
722
|
"scripts/**",
|
|
721
723
|
'topology/**',
|
|
724
|
+
'tsconfig.json',
|
|
722
725
|
'tsconfig.base.json'
|
|
723
726
|
],
|
|
724
727
|
deniedPaths: [
|
|
@@ -783,6 +786,7 @@ function createTemplateManifest(modernVersion, packageSource) {
|
|
|
783
786
|
expectedCommands: [
|
|
784
787
|
'mise install',
|
|
785
788
|
'pnpm install',
|
|
789
|
+
'pnpm run typecheck',
|
|
786
790
|
'pnpm run i18n:boundaries',
|
|
787
791
|
'pnpm run contract:check',
|
|
788
792
|
'pnpm run performance:readiness'
|
|
@@ -49,8 +49,7 @@ import { VerticalShowcase } from '../vertical-components';
|
|
|
49
49
|
import { ultramodernUiMarker } from '../../ultramodern-build';
|
|
50
50
|
|
|
51
51
|
export default function ShellHome() {
|
|
52
|
-
const {
|
|
53
|
-
const t = i18nInstance['t'].bind(i18nInstance);
|
|
52
|
+
const { t } = useModernI18n();
|
|
54
53
|
|
|
55
54
|
return (
|
|
56
55
|
<ShellFrame>
|
|
@@ -123,13 +122,14 @@ const loadRemoteComponent = (specifier: string) =>
|
|
|
123
122
|
|
|
124
123
|
const createRemoteFallback = (specifier: string) =>
|
|
125
124
|
({ error }: { error: Error }) => {
|
|
126
|
-
const {
|
|
127
|
-
const t = i18nInstance['t'].bind(i18nInstance);
|
|
125
|
+
const { t } = useModernI18n();
|
|
128
126
|
const classification = classifyModuleFederationFallback(error);
|
|
127
|
+
const telemetryEntry =
|
|
128
|
+
typeof window === 'undefined' ? undefined : window.location.href;
|
|
129
129
|
const telemetry = createModuleFederationFallbackTelemetry({
|
|
130
130
|
appName: '${external_descriptors_cjs_namespaceObject.shellApp.id}',
|
|
131
131
|
classification,
|
|
132
|
-
|
|
132
|
+
...(telemetryEntry === undefined ? {} : { entry: telemetryEntry }),
|
|
133
133
|
error,
|
|
134
134
|
eventName: 'mf.client.remote.fallback',
|
|
135
135
|
exportName: 'default',
|
|
@@ -142,7 +142,7 @@ const createRemoteFallback = (specifier: string) =>
|
|
|
142
142
|
void emitModuleFederationFallbackTelemetry({
|
|
143
143
|
appName: telemetry.appName,
|
|
144
144
|
classification,
|
|
145
|
-
entry: telemetry.entry,
|
|
145
|
+
...(telemetry.entry === undefined ? {} : { entry: telemetry.entry }),
|
|
146
146
|
error,
|
|
147
147
|
eventName: telemetry.eventName,
|
|
148
148
|
exportName: 'default',
|
|
@@ -151,7 +151,7 @@ const createRemoteFallback = (specifier: string) =>
|
|
|
151
151
|
remote: specifier,
|
|
152
152
|
status: 'degraded',
|
|
153
153
|
});
|
|
154
|
-
}, [classification, error,
|
|
154
|
+
}, [classification, error, telemetry]);
|
|
155
155
|
|
|
156
156
|
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>;
|
|
157
157
|
};
|
|
@@ -206,8 +206,7 @@ const createHydratedRemote =
|
|
|
206
206
|
${hydratedExports}
|
|
207
207
|
|
|
208
208
|
export const Header = () => {
|
|
209
|
-
const {
|
|
210
|
-
const t = i18nInstance['t'].bind(i18nInstance);
|
|
209
|
+
const { t } = useModernI18n();
|
|
211
210
|
|
|
212
211
|
return (
|
|
213
212
|
<header className="${tw('flex min-w-0 flex-wrap items-center gap-x-8 gap-y-2 md:flex-1')}" data-modern-boundary-id="${external_descriptors_cjs_namespaceObject.shellApp.mfName}" data-modern-mf-expose="shell/Header">
|
|
@@ -217,8 +216,7 @@ const createHydratedRemote =
|
|
|
217
216
|
};
|
|
218
217
|
|
|
219
218
|
export const StatusBadge = () => {
|
|
220
|
-
const {
|
|
221
|
-
const t = i18nInstance['t'].bind(i18nInstance);
|
|
219
|
+
const { t } = useModernI18n();
|
|
222
220
|
|
|
223
221
|
return (
|
|
224
222
|
<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')}">
|
|
@@ -228,8 +226,7 @@ export const StatusBadge = () => {
|
|
|
228
226
|
};
|
|
229
227
|
|
|
230
228
|
export const VerticalShowcase = () => {
|
|
231
|
-
const {
|
|
232
|
-
const t = i18nInstance['t'].bind(i18nInstance);
|
|
229
|
+
const { t } = useModernI18n();
|
|
233
230
|
|
|
234
231
|
if (widgetCount === 0) {
|
|
235
232
|
return (
|
|
@@ -296,8 +293,7 @@ import { ultramodernUiMarker } from '../../ultramodern-build';
|
|
|
296
293
|
` : '';
|
|
297
294
|
return `${effectBffImport}
|
|
298
295
|
export default function ${(0, external_naming_cjs_namespaceObject.toPascalCase)(app.id)}Home() {
|
|
299
|
-
const {
|
|
300
|
-
const t = i18nInstance['t'].bind(i18nInstance);
|
|
296
|
+
const { language, supportedLanguages, t } = useModernI18n();
|
|
301
297
|
${effectBffState} return (
|
|
302
298
|
<main className="${tw('min-h-screen bg-um-canvas px-4 py-6 text-um-foreground sm:px-8')}">
|
|
303
299
|
<UltramodernRouteHead />
|
|
@@ -343,8 +339,7 @@ function createRemoteEntry(app) {
|
|
|
343
339
|
return `import { useModernI18n } from '@modern-js/plugin-i18n/runtime';
|
|
344
340
|
|
|
345
341
|
export default function ${(0, external_naming_cjs_namespaceObject.toPascalCase)(domain)}Route() {
|
|
346
|
-
const {
|
|
347
|
-
const t = i18nInstance['t'].bind(i18nInstance);
|
|
342
|
+
const { t } = useModernI18n();
|
|
348
343
|
|
|
349
344
|
return (
|
|
350
345
|
<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">
|
|
@@ -362,8 +357,7 @@ function createRemoteWidget(app) {
|
|
|
362
357
|
return `import { useModernI18n } from '@modern-js/plugin-i18n/runtime';
|
|
363
358
|
|
|
364
359
|
export default function ${componentName}() {
|
|
365
|
-
const {
|
|
366
|
-
const t = i18nInstance['t'].bind(i18nInstance);
|
|
360
|
+
const { t } = useModernI18n();
|
|
367
361
|
|
|
368
362
|
return (
|
|
369
363
|
<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">
|
|
@@ -382,8 +376,7 @@ function createRemoteExposeComponent(app, expose) {
|
|
|
382
376
|
return `import { useModernI18n } from '@modern-js/plugin-i18n/runtime';
|
|
383
377
|
|
|
384
378
|
export default function ${componentName}() {
|
|
385
|
-
const {
|
|
386
|
-
const t = i18nInstance['t'].bind(i18nInstance);
|
|
379
|
+
const { t } = useModernI18n();
|
|
387
380
|
|
|
388
381
|
return (
|
|
389
382
|
<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}">
|
|
@@ -84,12 +84,12 @@ const sharedPackages = [
|
|
|
84
84
|
{
|
|
85
85
|
id: 'shared-contracts',
|
|
86
86
|
directory: 'packages/shared-contracts',
|
|
87
|
-
description: '
|
|
87
|
+
description: 'Generated route, ownership, and topology contracts.'
|
|
88
88
|
},
|
|
89
89
|
{
|
|
90
90
|
id: 'shared-design-tokens',
|
|
91
91
|
directory: 'packages/shared-design-tokens',
|
|
92
|
-
description: '
|
|
92
|
+
description: 'Generated design tokens consumed by shell and verticals.'
|
|
93
93
|
}
|
|
94
94
|
];
|
|
95
95
|
function createNeutralOwnership(id, tier = 'tier-2-vertical') {
|
|
@@ -88,27 +88,51 @@ function serviceHasCheckoutCartState(service) {
|
|
|
88
88
|
function createCheckoutCartSharedSchemas(service) {
|
|
89
89
|
if (!serviceHasCheckoutCartState(service)) return '';
|
|
90
90
|
return `
|
|
91
|
-
export
|
|
91
|
+
export interface CheckoutCartLine {
|
|
92
|
+
readonly sku: string;
|
|
93
|
+
readonly name: string;
|
|
94
|
+
readonly quantity: number;
|
|
95
|
+
readonly unitPriceCents: number;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export interface CheckoutCart {
|
|
99
|
+
readonly lines: readonly CheckoutCartLine[];
|
|
100
|
+
readonly subtotalCents: number;
|
|
101
|
+
readonly totalQuantity: number;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export interface CheckoutAddCartItemPayload {
|
|
105
|
+
readonly sku: string;
|
|
106
|
+
readonly name?: string;
|
|
107
|
+
readonly quantity: number;
|
|
108
|
+
readonly unitPriceCents?: number;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export interface CheckoutRemoveCartItemPayload {
|
|
112
|
+
readonly sku: string;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export const checkoutCartLineSchema: Schema.Codec<CheckoutCartLine> = Schema.Struct({
|
|
92
116
|
sku: Schema.String,
|
|
93
117
|
name: Schema.String,
|
|
94
118
|
quantity: Schema.Finite,
|
|
95
119
|
unitPriceCents: Schema.Finite,
|
|
96
120
|
});
|
|
97
121
|
|
|
98
|
-
export const checkoutCartSchema = Schema.Struct({
|
|
122
|
+
export const checkoutCartSchema: Schema.Codec<CheckoutCart> = Schema.Struct({
|
|
99
123
|
lines: Schema.Array(checkoutCartLineSchema),
|
|
100
124
|
subtotalCents: Schema.Finite,
|
|
101
125
|
totalQuantity: Schema.Finite,
|
|
102
126
|
});
|
|
103
127
|
|
|
104
|
-
export const checkoutAddCartItemPayloadSchema = Schema.Struct({
|
|
128
|
+
export const checkoutAddCartItemPayloadSchema: Schema.Codec<CheckoutAddCartItemPayload> = Schema.Struct({
|
|
105
129
|
sku: Schema.String,
|
|
106
130
|
name: Schema.optional(Schema.String),
|
|
107
131
|
quantity: Schema.Finite,
|
|
108
132
|
unitPriceCents: Schema.optional(Schema.Finite),
|
|
109
133
|
});
|
|
110
134
|
|
|
111
|
-
export const checkoutRemoveCartItemPayloadSchema = Schema.Struct({
|
|
135
|
+
export const checkoutRemoveCartItemPayloadSchema: Schema.Codec<CheckoutRemoveCartItemPayload> = Schema.Struct({
|
|
112
136
|
sku: Schema.String,
|
|
113
137
|
});
|
|
114
138
|
`;
|
|
@@ -261,6 +285,7 @@ function createCheckoutCartClientExports(service) {
|
|
|
261
285
|
const pascalStem = (0, external_naming_cjs_namespaceObject.toPascalCase)(stem);
|
|
262
286
|
const clientOptionsName = `${pascalStem}ClientOptions`;
|
|
263
287
|
const createClientName = `create${pascalStem}Client`;
|
|
288
|
+
const clientEffectTypeName = `${pascalStem}ClientEffect`;
|
|
264
289
|
return `
|
|
265
290
|
export interface CheckoutCartLine {
|
|
266
291
|
sku: string;
|
|
@@ -284,7 +309,7 @@ export interface CheckoutAddCartItemInput {
|
|
|
284
309
|
|
|
285
310
|
export const getCheckoutCart = (
|
|
286
311
|
options: ${clientOptionsName} = {},
|
|
287
|
-
) =>
|
|
312
|
+
): ${clientEffectTypeName}<CheckoutCart> =>
|
|
288
313
|
${createClientName}({
|
|
289
314
|
...options,
|
|
290
315
|
operationContext:
|
|
@@ -296,7 +321,7 @@ export const getCheckoutCart = (
|
|
|
296
321
|
export const addCheckoutCartItem = (
|
|
297
322
|
payload: CheckoutAddCartItemInput,
|
|
298
323
|
options: ${clientOptionsName} = {},
|
|
299
|
-
) =>
|
|
324
|
+
): ${clientEffectTypeName}<CheckoutCart> =>
|
|
300
325
|
${createClientName}({
|
|
301
326
|
...options,
|
|
302
327
|
operationContext:
|
|
@@ -310,7 +335,7 @@ export const addCheckoutCartItem = (
|
|
|
310
335
|
export const removeCheckoutCartItem = (
|
|
311
336
|
sku: string,
|
|
312
337
|
options: ${clientOptionsName} = {},
|
|
313
|
-
) =>
|
|
338
|
+
): ${clientEffectTypeName}<CheckoutCart> =>
|
|
314
339
|
${createClientName}({
|
|
315
340
|
...options,
|
|
316
341
|
operationContext:
|
|
@@ -323,7 +348,7 @@ export const removeCheckoutCartItem = (
|
|
|
323
348
|
|
|
324
349
|
export const clearCheckoutCart = (
|
|
325
350
|
options: ${clientOptionsName} = {},
|
|
326
|
-
) =>
|
|
351
|
+
): ${clientEffectTypeName}<CheckoutCart> =>
|
|
327
352
|
${createClientName}({
|
|
328
353
|
...options,
|
|
329
354
|
operationContext:
|
|
@@ -354,12 +379,63 @@ function createEffectSharedApiContract(service) {
|
|
|
354
379
|
const apiName = verticalEffectApiName(service);
|
|
355
380
|
const groupName = verticalEffectGroupName(service);
|
|
356
381
|
const stem = (0, external_descriptors_cjs_namespaceObject.effectApiStem)(service);
|
|
382
|
+
const pascalStem = (0, external_naming_cjs_namespaceObject.toPascalCase)(stem);
|
|
383
|
+
const markerType = `${pascalStem}Marker`;
|
|
384
|
+
const itemType = `${pascalStem}Item`;
|
|
385
|
+
const readinessType = `${pascalStem}Readiness`;
|
|
386
|
+
const createPayloadType = `${pascalStem}CreatePayload`;
|
|
387
|
+
const createResponseType = `${pascalStem}CreateResponse`;
|
|
388
|
+
const listResponseType = `${pascalStem}ListResponse`;
|
|
357
389
|
const apiPrefix = (0, external_descriptors_cjs_namespaceObject.effectApiPrefix)(service);
|
|
358
390
|
const checkoutCartSharedSchemas = createCheckoutCartSharedSchemas(service);
|
|
359
391
|
const checkoutCartSharedSchemaSection = '' === checkoutCartSharedSchemas ? '' : `${checkoutCartSharedSchemas}\n`;
|
|
360
392
|
const checkoutCartOperationContexts = createCheckoutCartOperationContexts(service).trimStart();
|
|
361
393
|
const checkoutCartOperationContextEntries = '' === checkoutCartOperationContexts ? '' : `${checkoutCartOperationContexts}\n`;
|
|
362
|
-
return `export
|
|
394
|
+
return `export interface ${markerType} {
|
|
395
|
+
readonly appId: string;
|
|
396
|
+
readonly build: string;
|
|
397
|
+
readonly deployProfile: string;
|
|
398
|
+
readonly packageName: string;
|
|
399
|
+
readonly surface: string;
|
|
400
|
+
readonly version: string;
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
export interface ${itemType} {
|
|
404
|
+
readonly id: string;
|
|
405
|
+
readonly marker: ${markerType};
|
|
406
|
+
readonly title: string;
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
export interface ${readinessType} {
|
|
410
|
+
readonly checks: {
|
|
411
|
+
readonly effectBff: 'ready';
|
|
412
|
+
readonly moduleFederation: 'ready';
|
|
413
|
+
readonly ssr: 'ready';
|
|
414
|
+
readonly translations: 'ready';
|
|
415
|
+
};
|
|
416
|
+
readonly marker: ${markerType};
|
|
417
|
+
readonly status: 'ready';
|
|
418
|
+
readonly versionSkew: 'none';
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
export interface ${createPayloadType} {
|
|
422
|
+
readonly title: string;
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
export interface ${listResponseType} {
|
|
426
|
+
readonly items: readonly ${itemType}[];
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
export interface ${createResponseType} {
|
|
430
|
+
readonly item: ${itemType};
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
export interface ${notFoundErrorExport} {
|
|
434
|
+
readonly _tag: '${notFoundErrorExport}';
|
|
435
|
+
readonly id: string;
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
export const ${markerSchemaExport}: Schema.Codec<${markerType}> = Schema.Struct({
|
|
363
439
|
appId: Schema.String,
|
|
364
440
|
build: Schema.String,
|
|
365
441
|
deployProfile: Schema.String,
|
|
@@ -368,13 +444,13 @@ function createEffectSharedApiContract(service) {
|
|
|
368
444
|
version: Schema.String,
|
|
369
445
|
});
|
|
370
446
|
|
|
371
|
-
export const ${schemaExport} = Schema.Struct({
|
|
447
|
+
export const ${schemaExport}: Schema.Codec<${itemType}> = Schema.Struct({
|
|
372
448
|
id: Schema.String,
|
|
373
449
|
marker: ${markerSchemaExport},
|
|
374
450
|
title: Schema.String,
|
|
375
451
|
});
|
|
376
452
|
|
|
377
|
-
export const ${readinessSchemaExport} = Schema.Struct({
|
|
453
|
+
export const ${readinessSchemaExport}: Schema.Codec<${readinessType}> = Schema.Struct({
|
|
378
454
|
checks: Schema.Struct({
|
|
379
455
|
effectBff: Schema.Literal('ready'),
|
|
380
456
|
moduleFederation: Schema.Literal('ready'),
|
|
@@ -386,18 +462,13 @@ export const ${readinessSchemaExport} = Schema.Struct({
|
|
|
386
462
|
versionSkew: Schema.Literal('none'),
|
|
387
463
|
});
|
|
388
464
|
|
|
389
|
-
export const ${createPayloadSchemaExport} = Schema.Struct({
|
|
465
|
+
export const ${createPayloadSchemaExport}: Schema.Codec<${createPayloadType}> = Schema.Struct({
|
|
390
466
|
title: Schema.String,
|
|
391
467
|
});
|
|
392
468
|
|
|
393
|
-
${checkoutCartSharedSchemaSection}export
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
id: Schema.String,
|
|
397
|
-
},
|
|
398
|
-
) {}
|
|
399
|
-
|
|
400
|
-
export const ${notFoundSchemaExport} = ${notFoundErrorExport}.pipe(
|
|
469
|
+
${checkoutCartSharedSchemaSection}export const ${notFoundSchemaExport}: Schema.Codec<${notFoundErrorExport}> = Schema.TaggedStruct('${notFoundErrorExport}', {
|
|
470
|
+
id: Schema.String,
|
|
471
|
+
}).pipe(
|
|
401
472
|
HttpApiSchema.status(404),
|
|
402
473
|
);
|
|
403
474
|
|
|
@@ -501,13 +572,20 @@ function createEffectServiceEntry(service, contractImportPath) {
|
|
|
501
572
|
HttpApiBuilder,
|
|
502
573
|
Layer,
|
|
503
574
|
} from '@modern-js/plugin-bff/effect-edge';
|
|
504
|
-
import {
|
|
575
|
+
import type {
|
|
576
|
+
EffectBffDefinition,
|
|
577
|
+
EffectBffRuntime,
|
|
578
|
+
EffectRuntimeLayer,
|
|
579
|
+
} from '@modern-js/plugin-bff/effect-edge';
|
|
580
|
+
import { ultramodernApiMarker } from '../../shared/ultramodern-build.ts';
|
|
505
581
|
import {
|
|
506
582
|
${apiExport},
|
|
507
583
|
${groupName}OperationContexts,
|
|
584
|
+
} from '${contractImportPath}';
|
|
585
|
+
import type {
|
|
508
586
|
${notFoundErrorExport},
|
|
587
|
+
OperationContext,
|
|
509
588
|
} from '${contractImportPath}';
|
|
510
|
-
import type { OperationContext } from '${contractImportPath}';
|
|
511
589
|
|
|
512
590
|
const ${groupName}Items = [
|
|
513
591
|
{
|
|
@@ -568,9 +646,13 @@ const ${groupName}Layer = HttpApiBuilder.group(
|
|
|
568
646
|
const matchedItem = ${groupName}Items.find(
|
|
569
647
|
candidate => candidate.id === params.id,
|
|
570
648
|
);
|
|
649
|
+
const notFound: ${notFoundErrorExport} = {
|
|
650
|
+
_tag: '${notFoundErrorExport}',
|
|
651
|
+
id: params.id,
|
|
652
|
+
};
|
|
571
653
|
const result =
|
|
572
654
|
matchedItem === undefined
|
|
573
|
-
? Effect.fail(
|
|
655
|
+
? Effect.fail(notFound)
|
|
574
656
|
: Effect.succeed(matchedItem);
|
|
575
657
|
|
|
576
658
|
return result.pipe(
|
|
@@ -601,12 +683,15 @@ const ${groupName}Layer = HttpApiBuilder.group(
|
|
|
601
683
|
|
|
602
684
|
const layer = HttpApiBuilder.layer(${apiExport}).pipe(
|
|
603
685
|
Layer.provide(${groupName}Layer),
|
|
604
|
-
);
|
|
686
|
+
) satisfies EffectRuntimeLayer;
|
|
605
687
|
|
|
606
|
-
|
|
688
|
+
const effectBff: EffectBffDefinition<typeof ${apiExport}, EffectRuntimeLayer> &
|
|
689
|
+
EffectBffRuntime<typeof ${apiExport}, EffectRuntimeLayer> = defineEffectBff({
|
|
607
690
|
api: ${apiExport},
|
|
608
691
|
layer,
|
|
609
692
|
});
|
|
693
|
+
|
|
694
|
+
export default effectBff;
|
|
610
695
|
`;
|
|
611
696
|
}
|
|
612
697
|
function createEffectClient(service, contractImportPath) {
|
|
@@ -617,25 +702,71 @@ function createEffectClient(service, contractImportPath) {
|
|
|
617
702
|
const singular = verticalEffectErrorStem(service);
|
|
618
703
|
const clientOptionsName = `${(0, external_naming_cjs_namespaceObject.toPascalCase)(stem)}ClientOptions`;
|
|
619
704
|
const createClientName = `create${(0, external_naming_cjs_namespaceObject.toPascalCase)(stem)}Client`;
|
|
705
|
+
const clientTypeName = `${(0, external_naming_cjs_namespaceObject.toPascalCase)(stem)}Client`;
|
|
706
|
+
const clientEffectTypeName = `${(0, external_naming_cjs_namespaceObject.toPascalCase)(stem)}ClientEffect`;
|
|
620
707
|
const listName = `list${(0, external_naming_cjs_namespaceObject.toPascalCase)(stem)}`;
|
|
621
708
|
const readinessName = `get${(0, external_naming_cjs_namespaceObject.toPascalCase)(stem)}Readiness`;
|
|
622
709
|
const getName = `get${(0, external_naming_cjs_namespaceObject.toPascalCase)(singular)}`;
|
|
623
710
|
const createName = `create${(0, external_naming_cjs_namespaceObject.toPascalCase)(singular)}`;
|
|
711
|
+
const notFoundErrorExport = verticalEffectNotFoundErrorExport(service);
|
|
712
|
+
const pascalStem = (0, external_naming_cjs_namespaceObject.toPascalCase)(stem);
|
|
713
|
+
const itemType = `${pascalStem}Item`;
|
|
714
|
+
const readinessType = `${pascalStem}Readiness`;
|
|
715
|
+
const createResponseType = `${pascalStem}CreateResponse`;
|
|
716
|
+
const listResponseType = `${pascalStem}ListResponse`;
|
|
624
717
|
const checkoutCartClientExports = createCheckoutCartClientExports(service);
|
|
625
718
|
return `import {
|
|
626
719
|
Effect,
|
|
627
720
|
makeEffectHttpApiClient,
|
|
628
721
|
runEffectRequest,
|
|
629
722
|
} from '@modern-js/plugin-bff/effect-client';
|
|
723
|
+
import type {
|
|
724
|
+
HttpClientError,
|
|
725
|
+
HttpApi,
|
|
726
|
+
HttpApiClient,
|
|
727
|
+
HttpApiGroup,
|
|
728
|
+
Schema,
|
|
729
|
+
} from '@modern-js/plugin-bff/effect-client';
|
|
630
730
|
import {
|
|
631
731
|
${contractExport}ApiContract,
|
|
632
732
|
${apiExport},
|
|
633
733
|
${groupName}OperationContexts,
|
|
634
734
|
} from '${contractImportPath}';
|
|
635
|
-
import type {
|
|
735
|
+
import type {
|
|
736
|
+
${createResponseType},
|
|
737
|
+
${itemType},
|
|
738
|
+
${listResponseType},
|
|
739
|
+
${notFoundErrorExport},
|
|
740
|
+
OperationContext,
|
|
741
|
+
${readinessType},
|
|
742
|
+
} from '${contractImportPath}';
|
|
636
743
|
|
|
637
744
|
export { Effect, runEffectRequest };
|
|
638
745
|
|
|
746
|
+
type ${pascalStem}EffectGroups = typeof ${apiExport} extends HttpApi.HttpApi<
|
|
747
|
+
infer _ApiId,
|
|
748
|
+
infer Groups
|
|
749
|
+
>
|
|
750
|
+
? Groups
|
|
751
|
+
: never;
|
|
752
|
+
|
|
753
|
+
export type ${clientTypeName} = HttpApiClient.Client<
|
|
754
|
+
Extract<${pascalStem}EffectGroups, HttpApiGroup.Any>,
|
|
755
|
+
never,
|
|
756
|
+
never
|
|
757
|
+
>;
|
|
758
|
+
|
|
759
|
+
export type ${pascalStem}ClientError =
|
|
760
|
+
| ${notFoundErrorExport}
|
|
761
|
+
| HttpClientError.HttpClientError
|
|
762
|
+
| Schema.SchemaError;
|
|
763
|
+
|
|
764
|
+
export type ${clientEffectTypeName}<Success> = Effect.Effect<
|
|
765
|
+
Success,
|
|
766
|
+
${pascalStem}ClientError,
|
|
767
|
+
never
|
|
768
|
+
>;
|
|
769
|
+
|
|
639
770
|
export interface ${clientOptionsName} {
|
|
640
771
|
baseUrl?: string | URL;
|
|
641
772
|
locale?: string;
|
|
@@ -645,7 +776,7 @@ export interface ${clientOptionsName} {
|
|
|
645
776
|
|
|
646
777
|
export const ${createClientName} = (
|
|
647
778
|
options: ${clientOptionsName} = {},
|
|
648
|
-
) =>
|
|
779
|
+
): ${clientEffectTypeName}<${clientTypeName}> =>
|
|
649
780
|
makeEffectHttpApiClient(${apiExport}, {
|
|
650
781
|
baseUrl: options.baseUrl ?? ${contractExport}ApiContract.apiPrefix,
|
|
651
782
|
requestContext: {
|
|
@@ -661,7 +792,7 @@ export const ${createClientName} = (
|
|
|
661
792
|
|
|
662
793
|
export const ${listName} = (
|
|
663
794
|
options: ${clientOptionsName} & { limit?: number } = {},
|
|
664
|
-
) =>
|
|
795
|
+
): ${clientEffectTypeName}<${listResponseType}> =>
|
|
665
796
|
${createClientName}({
|
|
666
797
|
...options,
|
|
667
798
|
operationContext:
|
|
@@ -674,7 +805,7 @@ export const ${listName} = (
|
|
|
674
805
|
|
|
675
806
|
export const ${readinessName} = (
|
|
676
807
|
options: ${clientOptionsName} = {},
|
|
677
|
-
) =>
|
|
808
|
+
): ${clientEffectTypeName}<${readinessType}> =>
|
|
678
809
|
${createClientName}({
|
|
679
810
|
...options,
|
|
680
811
|
operationContext:
|
|
@@ -686,7 +817,7 @@ export const ${readinessName} = (
|
|
|
686
817
|
export const ${getName} = (
|
|
687
818
|
id: string,
|
|
688
819
|
options: ${clientOptionsName} = {},
|
|
689
|
-
) =>
|
|
820
|
+
): ${clientEffectTypeName}<${itemType}> =>
|
|
690
821
|
${createClientName}({
|
|
691
822
|
...options,
|
|
692
823
|
operationContext:
|
|
@@ -698,7 +829,7 @@ export const ${getName} = (
|
|
|
698
829
|
export const ${createName} = (
|
|
699
830
|
title: string,
|
|
700
831
|
options: ${clientOptionsName} = {},
|
|
701
|
-
) =>
|
|
832
|
+
): ${clientEffectTypeName}<${createResponseType}> =>
|
|
702
833
|
${createClientName}({
|
|
703
834
|
...options,
|
|
704
835
|
operationContext:
|