@bleedingdev/modern-js-create 3.4.0-ultramodern.8 → 3.5.0-ultramodern.0
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 +25 -23
- package/dist/cjs/index.cjs +37 -4
- package/dist/cjs/locale/en.cjs +12 -2
- package/dist/cjs/locale/zh.cjs +12 -2
- package/dist/cjs/ultramodern-tooling/commands.cjs +185 -0
- package/dist/cjs/ultramodern-tooling/config.cjs +172 -0
- package/dist/cjs/ultramodern-workspace/add-vertical.cjs +87 -75
- package/dist/cjs/ultramodern-workspace/{effect-api.cjs → api.cjs} +207 -208
- package/dist/cjs/ultramodern-workspace/bridge-config.cjs +327 -0
- package/dist/cjs/ultramodern-workspace/codesmith.cjs +1 -0
- package/dist/cjs/ultramodern-workspace/contracts.cjs +127 -657
- package/dist/cjs/ultramodern-workspace/demo-components.cjs +12 -12
- package/dist/cjs/ultramodern-workspace/descriptors.cjs +25 -25
- package/dist/cjs/ultramodern-workspace/fs-io.cjs +117 -0
- package/dist/cjs/ultramodern-workspace/generation-result.cjs +5 -5
- package/dist/cjs/ultramodern-workspace/index.cjs +4 -0
- package/dist/cjs/ultramodern-workspace/mf-validation.cjs +571 -0
- package/dist/cjs/ultramodern-workspace/module-federation.cjs +33 -18
- package/dist/cjs/ultramodern-workspace/overlays.cjs +2 -2
- package/dist/cjs/ultramodern-workspace/package-json.cjs +57 -41
- package/dist/cjs/ultramodern-workspace/policy.cjs +4 -4
- package/dist/cjs/ultramodern-workspace/public-api.cjs +4 -0
- package/dist/cjs/ultramodern-workspace/public-surface.cjs +2 -2
- package/dist/cjs/ultramodern-workspace/versions.cjs +5 -0
- package/dist/cjs/ultramodern-workspace/workspace-scripts.cjs +119 -50
- package/dist/cjs/ultramodern-workspace/write-workspace.cjs +62 -21
- package/dist/esm/index.js +37 -4
- package/dist/esm/locale/en.js +12 -2
- package/dist/esm/locale/zh.js +12 -2
- package/dist/esm/ultramodern-tooling/commands.js +132 -0
- package/dist/esm/ultramodern-tooling/config.js +120 -0
- package/dist/esm/ultramodern-workspace/add-vertical.js +88 -79
- package/dist/esm/ultramodern-workspace/{effect-api.js → api.js} +146 -147
- package/dist/esm/ultramodern-workspace/bridge-config.js +270 -0
- package/dist/esm/ultramodern-workspace/codesmith.js +1 -0
- package/dist/esm/ultramodern-workspace/contracts.js +129 -611
- package/dist/esm/ultramodern-workspace/demo-components.js +13 -13
- package/dist/esm/ultramodern-workspace/descriptors.js +11 -11
- package/dist/esm/ultramodern-workspace/fs-io.js +116 -2
- package/dist/esm/ultramodern-workspace/generation-result.js +6 -6
- package/dist/esm/ultramodern-workspace/index.js +1 -0
- package/dist/esm/ultramodern-workspace/mf-validation.js +516 -0
- package/dist/esm/ultramodern-workspace/module-federation.js +34 -19
- package/dist/esm/ultramodern-workspace/overlays.js +2 -2
- package/dist/esm/ultramodern-workspace/package-json.js +56 -40
- package/dist/esm/ultramodern-workspace/policy.js +5 -5
- package/dist/esm/ultramodern-workspace/public-api.js +1 -0
- package/dist/esm/ultramodern-workspace/public-surface.js +2 -2
- package/dist/esm/ultramodern-workspace/versions.js +3 -1
- package/dist/esm/ultramodern-workspace/workspace-scripts.js +107 -34
- package/dist/esm/ultramodern-workspace/write-workspace.js +64 -26
- package/dist/esm-node/index.js +37 -4
- package/dist/esm-node/locale/en.js +12 -2
- package/dist/esm-node/locale/zh.js +12 -2
- package/dist/esm-node/ultramodern-tooling/commands.js +133 -0
- package/dist/esm-node/ultramodern-tooling/config.js +121 -0
- package/dist/esm-node/ultramodern-workspace/add-vertical.js +88 -79
- package/dist/esm-node/ultramodern-workspace/{effect-api.js → api.js} +146 -147
- package/dist/esm-node/ultramodern-workspace/bridge-config.js +271 -0
- package/dist/esm-node/ultramodern-workspace/codesmith.js +1 -0
- package/dist/esm-node/ultramodern-workspace/contracts.js +129 -611
- package/dist/esm-node/ultramodern-workspace/demo-components.js +13 -13
- package/dist/esm-node/ultramodern-workspace/descriptors.js +11 -11
- package/dist/esm-node/ultramodern-workspace/fs-io.js +116 -2
- package/dist/esm-node/ultramodern-workspace/generation-result.js +6 -6
- package/dist/esm-node/ultramodern-workspace/index.js +1 -0
- package/dist/esm-node/ultramodern-workspace/mf-validation.js +517 -0
- package/dist/esm-node/ultramodern-workspace/module-federation.js +34 -19
- package/dist/esm-node/ultramodern-workspace/overlays.js +2 -2
- package/dist/esm-node/ultramodern-workspace/package-json.js +56 -40
- package/dist/esm-node/ultramodern-workspace/policy.js +5 -5
- package/dist/esm-node/ultramodern-workspace/public-api.js +1 -0
- package/dist/esm-node/ultramodern-workspace/public-surface.js +2 -2
- package/dist/esm-node/ultramodern-workspace/versions.js +3 -1
- package/dist/esm-node/ultramodern-workspace/workspace-scripts.js +107 -34
- package/dist/esm-node/ultramodern-workspace/write-workspace.js +64 -26
- package/dist/types/locale/en.d.ts +10 -0
- package/dist/types/locale/index.d.ts +20 -0
- package/dist/types/locale/zh.d.ts +10 -0
- package/dist/types/ultramodern-tooling/commands.d.ts +1 -0
- package/dist/types/ultramodern-tooling/config.d.ts +43 -0
- package/dist/types/ultramodern-workspace/add-vertical.d.ts +5 -2
- package/dist/types/ultramodern-workspace/api.d.ts +73 -0
- package/dist/types/ultramodern-workspace/bridge-config.d.ts +64 -0
- package/dist/types/ultramodern-workspace/codesmith.d.ts +1 -0
- package/dist/types/ultramodern-workspace/contracts.d.ts +2 -17
- package/dist/types/ultramodern-workspace/descriptors.d.ts +10 -10
- package/dist/types/ultramodern-workspace/fs-io.d.ts +1 -0
- package/dist/types/ultramodern-workspace/index.d.ts +2 -0
- package/dist/types/ultramodern-workspace/mf-validation.d.ts +27 -0
- package/dist/types/ultramodern-workspace/package-json.d.ts +5 -4
- package/dist/types/ultramodern-workspace/public-api.d.ts +2 -0
- package/dist/types/ultramodern-workspace/types.d.ts +9 -7
- package/dist/types/ultramodern-workspace/versions.d.ts +2 -0
- package/dist/types/ultramodern-workspace/workspace-scripts.d.ts +2 -7
- package/dist/types/ultramodern-workspace/write-workspace.d.ts +4 -2
- package/package.json +5 -3
- package/template-workspace/{.agents → .codex}/skills-lock.json +12 -12
- package/template-workspace/.github/workflows/ultramodern-workspace-gates.yml.handlebars +2 -0
- package/template-workspace/.gitignore.handlebars +3 -0
- package/template-workspace/AGENTS.md.handlebars +11 -5
- package/template-workspace/README.md.handlebars +15 -12
- package/template-workspace/oxfmt.config.ts +1 -0
- package/template-workspace/oxlint.config.ts +1 -0
- package/template-workspace/patches/@tanstack__router-core@1.171.13.patch +51 -0
- package/template-workspace/pnpm-workspace.yaml.handlebars +4 -0
- package/template-workspace/scripts/bootstrap-agent-skills.mjs +77 -67
- package/templates/workspace-scripts/assert-mf-types.mjs.handlebars +51 -8
- package/templates/workspace-scripts/check-ultramodern-api-boundaries.mts +344 -0
- package/templates/workspace-scripts/{check-ultramodern-i18n-boundaries.mjs → check-ultramodern-i18n-boundaries.mts} +1 -1
- package/templates/workspace-scripts/generate-public-surface-assets.mjs +246 -9
- package/templates/workspace-scripts/proof-cloudflare-version.mjs +277 -9
- package/templates/workspace-scripts/ultramodern-cloudflare-proof.mjs +35 -10
- package/templates/workspace-scripts/ultramodern-performance-readiness.mjs +165 -2
- package/templates/workspace-scripts/ultramodern-typecheck.mjs +4 -2
- package/templates/workspace-scripts/validate-ultramodern-workspace.mjs.handlebars +840 -84
- package/dist/types/ultramodern-workspace/effect-api.d.ts +0 -73
- /package/template-workspace/{.agents → .codex}/rstackjs-agent-skills-LICENSE +0 -0
- /package/template-workspace/{.agents → .codex}/skills/rsbuild-best-practices/SKILL.md +0 -0
- /package/template-workspace/{.agents → .codex}/skills/rsdoctor-analysis/SKILL.md +0 -0
- /package/template-workspace/{.agents → .codex}/skills/rsdoctor-analysis/references/command-map.md +0 -0
- /package/template-workspace/{.agents → .codex}/skills/rsdoctor-analysis/references/common-analysis-patterns.md +0 -0
- /package/template-workspace/{.agents → .codex}/skills/rsdoctor-analysis/references/install-rsdoctor-common.md +0 -0
- /package/template-workspace/{.agents → .codex}/skills/rsdoctor-analysis/references/install-rsdoctor-rspack.md +0 -0
- /package/template-workspace/{.agents → .codex}/skills/rsdoctor-analysis/references/install-rsdoctor-webpack.md +0 -0
- /package/template-workspace/{.agents → .codex}/skills/rsdoctor-analysis/references/install-rsdoctor.md +0 -0
- /package/template-workspace/{.agents → .codex}/skills/rsdoctor-analysis/references/rsdoctor-data-types.md +0 -0
- /package/template-workspace/{.agents → .codex}/skills/rslib-best-practices/SKILL.md +0 -0
- /package/template-workspace/{.agents → .codex}/skills/rslib-modern-package/SKILL.md +0 -0
- /package/template-workspace/{.agents → .codex}/skills/rspack-best-practices/SKILL.md +0 -0
- /package/template-workspace/{.agents → .codex}/skills/rspack-tracing/SKILL.md +0 -0
- /package/template-workspace/{.agents → .codex}/skills/rspack-tracing/references/bottlenecks.md +0 -0
- /package/template-workspace/{.agents → .codex}/skills/rspack-tracing/references/tracing-guide.md +0 -0
- /package/template-workspace/{.agents → .codex}/skills/rspack-tracing/scripts/analyze_trace.js +0 -0
- /package/template-workspace/{.agents → .codex}/skills/rstest-best-practices/SKILL.md +0 -0
|
@@ -1,38 +1,38 @@
|
|
|
1
1
|
import "node:module";
|
|
2
|
-
import {
|
|
2
|
+
import { appHasApi, resolveApiPrefix, resolveApiStem, verticalApiApps } from "./descriptors.js";
|
|
3
3
|
import { packageName, toCamelCase, toPascalCase } from "./naming.js";
|
|
4
|
-
function
|
|
5
|
-
return `${toCamelCase(
|
|
4
|
+
function verticalApiExport(service) {
|
|
5
|
+
return `${toCamelCase(resolveApiStem(service))}Api`;
|
|
6
6
|
}
|
|
7
|
-
function
|
|
8
|
-
return toCamelCase(
|
|
7
|
+
function verticalApiGroupName(service) {
|
|
8
|
+
return toCamelCase(resolveApiStem(service));
|
|
9
9
|
}
|
|
10
|
-
function
|
|
11
|
-
return `${toPascalCase(
|
|
10
|
+
function verticalApiName(service) {
|
|
11
|
+
return `${toPascalCase(resolveApiStem(service))}Api`;
|
|
12
12
|
}
|
|
13
|
-
function
|
|
14
|
-
return `${toCamelCase(
|
|
13
|
+
function verticalApiSchemaExport(service) {
|
|
14
|
+
return `${toCamelCase(resolveApiStem(service))}ItemSchema`;
|
|
15
15
|
}
|
|
16
|
-
function
|
|
17
|
-
return `${toCamelCase(
|
|
16
|
+
function verticalApiMarkerSchemaExport(service) {
|
|
17
|
+
return `${toCamelCase(resolveApiStem(service))}MarkerSchema`;
|
|
18
18
|
}
|
|
19
|
-
function
|
|
20
|
-
return `${toCamelCase(
|
|
19
|
+
function verticalApiReadinessSchemaExport(service) {
|
|
20
|
+
return `${toCamelCase(resolveApiStem(service))}ReadinessSchema`;
|
|
21
21
|
}
|
|
22
|
-
function
|
|
23
|
-
return
|
|
22
|
+
function verticalApiErrorStem(service) {
|
|
23
|
+
return resolveApiStem(service);
|
|
24
24
|
}
|
|
25
|
-
function
|
|
26
|
-
return `${toCamelCase(
|
|
25
|
+
function verticalApiCreatePayloadSchemaExport(service) {
|
|
26
|
+
return `${toCamelCase(resolveApiStem(service))}CreatePayloadSchema`;
|
|
27
27
|
}
|
|
28
|
-
function
|
|
29
|
-
return `${toPascalCase(
|
|
28
|
+
function verticalApiNotFoundErrorExport(service) {
|
|
29
|
+
return `${toPascalCase(verticalApiErrorStem(service))}NotFound`;
|
|
30
30
|
}
|
|
31
|
-
function
|
|
32
|
-
return `${toCamelCase(
|
|
31
|
+
function verticalApiNotFoundSchemaExport(service) {
|
|
32
|
+
return `${toCamelCase(verticalApiErrorStem(service))}NotFoundSchema`;
|
|
33
33
|
}
|
|
34
34
|
function serviceHasCheckoutCartState(service) {
|
|
35
|
-
return 'checkout' ===
|
|
35
|
+
return 'checkout' === resolveApiStem(service);
|
|
36
36
|
}
|
|
37
37
|
function createCheckoutCartSharedSchemas(service) {
|
|
38
38
|
if (!serviceHasCheckoutCartState(service)) return '';
|
|
@@ -90,61 +90,61 @@ function createCheckoutCartEndpointDefinitions(service) {
|
|
|
90
90
|
if (!serviceHasCheckoutCartState(service)) return '';
|
|
91
91
|
return `
|
|
92
92
|
.add(
|
|
93
|
-
HttpApiEndpoint.get('getCart', '/
|
|
93
|
+
HttpApiEndpoint.get('getCart', '/checkout/cart', {
|
|
94
94
|
success: checkoutCartSchema,
|
|
95
95
|
}),
|
|
96
96
|
)
|
|
97
97
|
.add(
|
|
98
|
-
HttpApiEndpoint.post('addCartItem', '/
|
|
98
|
+
HttpApiEndpoint.post('addCartItem', '/checkout/cart/items', {
|
|
99
99
|
payload: checkoutAddCartItemPayloadSchema,
|
|
100
100
|
success: checkoutCartSchema,
|
|
101
101
|
}),
|
|
102
102
|
)
|
|
103
103
|
.add(
|
|
104
|
-
HttpApiEndpoint.post('removeCartItem', '/
|
|
104
|
+
HttpApiEndpoint.post('removeCartItem', '/checkout/cart/remove', {
|
|
105
105
|
payload: checkoutRemoveCartItemPayloadSchema,
|
|
106
106
|
success: checkoutCartSchema,
|
|
107
107
|
}),
|
|
108
108
|
)
|
|
109
109
|
.add(
|
|
110
|
-
HttpApiEndpoint.post('clearCart', '/
|
|
110
|
+
HttpApiEndpoint.post('clearCart', '/checkout/cart/clear', {
|
|
111
111
|
success: checkoutCartSchema,
|
|
112
112
|
}),
|
|
113
113
|
)`;
|
|
114
114
|
}
|
|
115
115
|
function createCheckoutCartOperationContexts(service) {
|
|
116
|
-
const apiName =
|
|
117
|
-
const groupName =
|
|
116
|
+
const apiName = verticalApiName(service);
|
|
117
|
+
const groupName = verticalApiGroupName(service);
|
|
118
118
|
if (!serviceHasCheckoutCartState(service)) return '';
|
|
119
119
|
return `
|
|
120
120
|
addCartItem: {
|
|
121
121
|
method: 'POST',
|
|
122
122
|
operationId: '${apiName}:${groupName}:addCartItem',
|
|
123
|
-
routePath: '/
|
|
123
|
+
routePath: '/checkout/cart/items',
|
|
124
124
|
source: 'generated-client',
|
|
125
125
|
},
|
|
126
126
|
clearCart: {
|
|
127
127
|
method: 'POST',
|
|
128
128
|
operationId: '${apiName}:${groupName}:clearCart',
|
|
129
|
-
routePath: '/
|
|
129
|
+
routePath: '/checkout/cart/clear',
|
|
130
130
|
source: 'generated-client',
|
|
131
131
|
},
|
|
132
132
|
getCart: {
|
|
133
133
|
method: 'GET',
|
|
134
134
|
operationId: '${apiName}:${groupName}:getCart',
|
|
135
|
-
routePath: '/
|
|
135
|
+
routePath: '/checkout/cart',
|
|
136
136
|
source: 'generated-client',
|
|
137
137
|
},
|
|
138
138
|
removeCartItem: {
|
|
139
139
|
method: 'POST',
|
|
140
140
|
operationId: '${apiName}:${groupName}:removeCartItem',
|
|
141
|
-
routePath: '/
|
|
141
|
+
routePath: '/checkout/cart/remove',
|
|
142
142
|
source: 'generated-client',
|
|
143
143
|
},`;
|
|
144
144
|
}
|
|
145
145
|
function createCheckoutCartApiContractFields(service) {
|
|
146
146
|
if (!serviceHasCheckoutCartState(service)) return '';
|
|
147
|
-
return ` checkoutCartPath: '${
|
|
147
|
+
return ` checkoutCartPath: '${resolveApiPrefix(service)}/checkout/cart',
|
|
148
148
|
`;
|
|
149
149
|
}
|
|
150
150
|
function createCheckoutCartServerState(service) {
|
|
@@ -175,12 +175,12 @@ const createCheckoutCartSnapshot = () => {
|
|
|
175
175
|
`;
|
|
176
176
|
}
|
|
177
177
|
function createCheckoutCartServerHandlers(service) {
|
|
178
|
-
const groupName =
|
|
178
|
+
const groupName = verticalApiGroupName(service);
|
|
179
179
|
if (!serviceHasCheckoutCartState(service)) return '';
|
|
180
180
|
return `
|
|
181
181
|
.handle('getCart', () =>
|
|
182
182
|
Effect.sync(() => createCheckoutCartSnapshot()).pipe(
|
|
183
|
-
Effect.withSpan('ultramodern.
|
|
183
|
+
Effect.withSpan('ultramodern.api.${groupName}.checkout.getCart', {
|
|
184
184
|
attributes: operationAttributes(${groupName}OperationContexts.getCart),
|
|
185
185
|
kind: 'server',
|
|
186
186
|
}),
|
|
@@ -198,7 +198,7 @@ function createCheckoutCartServerHandlers(service) {
|
|
|
198
198
|
});
|
|
199
199
|
return createCheckoutCartSnapshot();
|
|
200
200
|
}).pipe(
|
|
201
|
-
Effect.withSpan('ultramodern.
|
|
201
|
+
Effect.withSpan('ultramodern.api.${groupName}.checkout.addCartItem', {
|
|
202
202
|
attributes: operationAttributes(${groupName}OperationContexts.addCartItem),
|
|
203
203
|
kind: 'server',
|
|
204
204
|
}),
|
|
@@ -209,7 +209,7 @@ function createCheckoutCartServerHandlers(service) {
|
|
|
209
209
|
checkoutCartLines.delete(payload.sku);
|
|
210
210
|
return createCheckoutCartSnapshot();
|
|
211
211
|
}).pipe(
|
|
212
|
-
Effect.withSpan('ultramodern.
|
|
212
|
+
Effect.withSpan('ultramodern.api.${groupName}.checkout.removeCartItem', {
|
|
213
213
|
attributes: operationAttributes(${groupName}OperationContexts.removeCartItem),
|
|
214
214
|
kind: 'server',
|
|
215
215
|
}),
|
|
@@ -220,7 +220,7 @@ function createCheckoutCartServerHandlers(service) {
|
|
|
220
220
|
checkoutCartLines.clear();
|
|
221
221
|
return createCheckoutCartSnapshot();
|
|
222
222
|
}).pipe(
|
|
223
|
-
Effect.withSpan('ultramodern.
|
|
223
|
+
Effect.withSpan('ultramodern.api.${groupName}.checkout.clearCart', {
|
|
224
224
|
attributes: operationAttributes(${groupName}OperationContexts.clearCart),
|
|
225
225
|
kind: 'server',
|
|
226
226
|
}),
|
|
@@ -229,8 +229,8 @@ function createCheckoutCartServerHandlers(service) {
|
|
|
229
229
|
}
|
|
230
230
|
function createCheckoutCartClientExports(service) {
|
|
231
231
|
if (!serviceHasCheckoutCartState(service)) return '';
|
|
232
|
-
const stem =
|
|
233
|
-
const groupName =
|
|
232
|
+
const stem = resolveApiStem(service);
|
|
233
|
+
const groupName = verticalApiGroupName(service);
|
|
234
234
|
const pascalStem = toPascalCase(stem);
|
|
235
235
|
const clientOptionsName = `${pascalStem}ClientOptions`;
|
|
236
236
|
const createClientName = `create${pascalStem}Client`;
|
|
@@ -307,7 +307,7 @@ export const clearCheckoutCart = (
|
|
|
307
307
|
);
|
|
308
308
|
`;
|
|
309
309
|
}
|
|
310
|
-
function
|
|
310
|
+
function createSharedApiImports() {
|
|
311
311
|
return `import {
|
|
312
312
|
HttpApi,
|
|
313
313
|
HttpApiEndpoint,
|
|
@@ -317,17 +317,17 @@ function createEffectSharedApiImports() {
|
|
|
317
317
|
} from '@modern-js/plugin-bff/effect-client';
|
|
318
318
|
`;
|
|
319
319
|
}
|
|
320
|
-
function
|
|
321
|
-
const schemaExport =
|
|
322
|
-
const markerSchemaExport =
|
|
323
|
-
const readinessSchemaExport =
|
|
324
|
-
const createPayloadSchemaExport =
|
|
325
|
-
const notFoundErrorExport =
|
|
326
|
-
const notFoundSchemaExport =
|
|
327
|
-
const apiExport =
|
|
328
|
-
const apiName =
|
|
329
|
-
const groupName =
|
|
330
|
-
const stem =
|
|
320
|
+
function createSharedApiContract(service) {
|
|
321
|
+
const schemaExport = verticalApiSchemaExport(service);
|
|
322
|
+
const markerSchemaExport = verticalApiMarkerSchemaExport(service);
|
|
323
|
+
const readinessSchemaExport = verticalApiReadinessSchemaExport(service);
|
|
324
|
+
const createPayloadSchemaExport = verticalApiCreatePayloadSchemaExport(service);
|
|
325
|
+
const notFoundErrorExport = verticalApiNotFoundErrorExport(service);
|
|
326
|
+
const notFoundSchemaExport = verticalApiNotFoundSchemaExport(service);
|
|
327
|
+
const apiExport = verticalApiExport(service);
|
|
328
|
+
const apiName = verticalApiName(service);
|
|
329
|
+
const groupName = verticalApiGroupName(service);
|
|
330
|
+
const stem = resolveApiStem(service);
|
|
331
331
|
const pascalStem = toPascalCase(stem);
|
|
332
332
|
const markerType = `${pascalStem}Marker`;
|
|
333
333
|
const itemType = `${pascalStem}Item`;
|
|
@@ -335,7 +335,7 @@ function createEffectSharedApiContract(service) {
|
|
|
335
335
|
const createPayloadType = `${pascalStem}CreatePayload`;
|
|
336
336
|
const createResponseType = `${pascalStem}CreateResponse`;
|
|
337
337
|
const listResponseType = `${pascalStem}ListResponse`;
|
|
338
|
-
const apiPrefix =
|
|
338
|
+
const apiPrefix = resolveApiPrefix(service);
|
|
339
339
|
const checkoutCartSharedSchemas = createCheckoutCartSharedSchemas(service);
|
|
340
340
|
const checkoutCartSharedSchemaSection = '' === checkoutCartSharedSchemas ? '' : `${checkoutCartSharedSchemas}\n`;
|
|
341
341
|
const checkoutCartOperationContexts = createCheckoutCartOperationContexts(service).trimStart();
|
|
@@ -357,7 +357,7 @@ export interface ${itemType} {
|
|
|
357
357
|
|
|
358
358
|
export interface ${readinessType} {
|
|
359
359
|
readonly checks: {
|
|
360
|
-
readonly
|
|
360
|
+
readonly api: 'ready';
|
|
361
361
|
readonly moduleFederation: 'ready';
|
|
362
362
|
readonly ssr: 'ready';
|
|
363
363
|
readonly translations: 'ready';
|
|
@@ -401,7 +401,7 @@ export const ${schemaExport}: Schema.Codec<${itemType}> = Schema.Struct({
|
|
|
401
401
|
|
|
402
402
|
export const ${readinessSchemaExport}: Schema.Codec<${readinessType}> = Schema.Struct({
|
|
403
403
|
checks: Schema.Struct({
|
|
404
|
-
|
|
404
|
+
api: Schema.Literal('ready'),
|
|
405
405
|
moduleFederation: Schema.Literal('ready'),
|
|
406
406
|
ssr: Schema.Literal('ready'),
|
|
407
407
|
translations: Schema.Literal('ready'),
|
|
@@ -438,7 +438,7 @@ export interface OperationContext {
|
|
|
438
438
|
export const ${apiExport} = HttpApi.make('${apiName}').add(
|
|
439
439
|
HttpApiGroup.make('${groupName}')
|
|
440
440
|
.add(
|
|
441
|
-
HttpApiEndpoint.get('list', '
|
|
441
|
+
HttpApiEndpoint.get('list', '/${stem}', {
|
|
442
442
|
query: {
|
|
443
443
|
limit: Schema.optional(Schema.FiniteFromString),
|
|
444
444
|
},
|
|
@@ -448,12 +448,12 @@ export const ${apiExport} = HttpApi.make('${apiName}').add(
|
|
|
448
448
|
}),
|
|
449
449
|
)
|
|
450
450
|
.add(
|
|
451
|
-
HttpApiEndpoint.get('readiness', '
|
|
451
|
+
HttpApiEndpoint.get('readiness', '/${stem}/readiness', {
|
|
452
452
|
success: ${readinessSchemaExport},
|
|
453
453
|
}),
|
|
454
454
|
)
|
|
455
455
|
.add(
|
|
456
|
-
HttpApiEndpoint.get('get', '
|
|
456
|
+
HttpApiEndpoint.get('get', '/${stem}/:id', {
|
|
457
457
|
error: ${notFoundSchemaExport},
|
|
458
458
|
params: {
|
|
459
459
|
id: Schema.String,
|
|
@@ -462,7 +462,7 @@ export const ${apiExport} = HttpApi.make('${apiName}').add(
|
|
|
462
462
|
}),
|
|
463
463
|
)
|
|
464
464
|
.add(
|
|
465
|
-
HttpApiEndpoint.post('create', '
|
|
465
|
+
HttpApiEndpoint.post('create', '/${stem}', {
|
|
466
466
|
payload: ${createPayloadSchemaExport},
|
|
467
467
|
success: Schema.Struct({
|
|
468
468
|
item: ${schemaExport},
|
|
@@ -475,46 +475,46 @@ export const ${groupName}OperationContexts = {
|
|
|
475
475
|
${checkoutCartOperationContextEntries} create: {
|
|
476
476
|
method: 'POST',
|
|
477
477
|
operationId: '${apiName}:${groupName}:create',
|
|
478
|
-
routePath: '
|
|
478
|
+
routePath: '/${stem}',
|
|
479
479
|
source: 'generated-client',
|
|
480
480
|
},
|
|
481
481
|
get: {
|
|
482
482
|
method: 'GET',
|
|
483
483
|
operationId: '${apiName}:${groupName}:get',
|
|
484
|
-
routePath: '
|
|
484
|
+
routePath: '/${stem}/:id',
|
|
485
485
|
source: 'generated-client',
|
|
486
486
|
},
|
|
487
487
|
list: {
|
|
488
488
|
method: 'GET',
|
|
489
489
|
operationId: '${apiName}:${groupName}:list',
|
|
490
|
-
routePath: '
|
|
490
|
+
routePath: '/${stem}',
|
|
491
491
|
source: 'generated-client',
|
|
492
492
|
},
|
|
493
493
|
readiness: {
|
|
494
494
|
method: 'GET',
|
|
495
495
|
operationId: '${apiName}:${groupName}:readiness',
|
|
496
|
-
routePath: '
|
|
496
|
+
routePath: '/${stem}/readiness',
|
|
497
497
|
source: 'generated-client',
|
|
498
498
|
},
|
|
499
499
|
} satisfies Record<string, OperationContext>;
|
|
500
500
|
|
|
501
501
|
export const ${groupName}ApiContract = {
|
|
502
502
|
apiPrefix: '${apiPrefix}',
|
|
503
|
-
basePath: '${apiPrefix}
|
|
503
|
+
basePath: '${apiPrefix}/${stem}',
|
|
504
504
|
${createCheckoutCartApiContractFields(service)} ownerId: '${service.id}',
|
|
505
|
-
readinessPath: '${apiPrefix}
|
|
505
|
+
readinessPath: '${apiPrefix}/${stem}/readiness',
|
|
506
506
|
} as const;
|
|
507
507
|
`;
|
|
508
508
|
}
|
|
509
|
-
function
|
|
510
|
-
return `${
|
|
511
|
-
${
|
|
509
|
+
function createSharedApi(service) {
|
|
510
|
+
return `${createSharedApiImports()}
|
|
511
|
+
${createSharedApiContract(service)}`;
|
|
512
512
|
}
|
|
513
|
-
function
|
|
514
|
-
const apiExport =
|
|
515
|
-
const groupName =
|
|
516
|
-
const notFoundErrorExport =
|
|
517
|
-
const stem =
|
|
513
|
+
function createApiServiceEntry(service, contractImportPath) {
|
|
514
|
+
const apiExport = verticalApiExport(service);
|
|
515
|
+
const groupName = verticalApiGroupName(service);
|
|
516
|
+
const notFoundErrorExport = verticalApiNotFoundErrorExport(service);
|
|
517
|
+
const stem = resolveApiStem(service);
|
|
518
518
|
return `import {
|
|
519
519
|
defineEffectBff,
|
|
520
520
|
Effect,
|
|
@@ -526,7 +526,7 @@ import type {
|
|
|
526
526
|
EffectBffRuntime,
|
|
527
527
|
EffectRuntimeLayer,
|
|
528
528
|
} from '@modern-js/plugin-bff/effect-edge';
|
|
529
|
-
import { ultramodernApiMarker } from '
|
|
529
|
+
import { ultramodernApiMarker } from '../shared/ultramodern-build.ts';
|
|
530
530
|
import {
|
|
531
531
|
${apiExport},
|
|
532
532
|
${groupName}OperationContexts,
|
|
@@ -567,7 +567,7 @@ const ${groupName}Layer = HttpApiBuilder.group(
|
|
|
567
567
|
? ${groupName}Items.slice(0, query.limit)
|
|
568
568
|
: ${groupName}Items,
|
|
569
569
|
}).pipe(
|
|
570
|
-
Effect.withSpan('ultramodern.
|
|
570
|
+
Effect.withSpan('ultramodern.api.${groupName}.list', {
|
|
571
571
|
attributes: operationAttributes(${groupName}OperationContexts.list),
|
|
572
572
|
kind: 'server',
|
|
573
573
|
}),
|
|
@@ -576,7 +576,7 @@ const ${groupName}Layer = HttpApiBuilder.group(
|
|
|
576
576
|
.handle('readiness', () =>
|
|
577
577
|
Effect.succeed({
|
|
578
578
|
checks: {
|
|
579
|
-
|
|
579
|
+
api: 'ready' as const,
|
|
580
580
|
moduleFederation: 'ready' as const,
|
|
581
581
|
ssr: 'ready' as const,
|
|
582
582
|
translations: 'ready' as const,
|
|
@@ -585,7 +585,7 @@ const ${groupName}Layer = HttpApiBuilder.group(
|
|
|
585
585
|
status: 'ready' as const,
|
|
586
586
|
versionSkew: 'none' as const,
|
|
587
587
|
}).pipe(
|
|
588
|
-
Effect.withSpan('ultramodern.
|
|
588
|
+
Effect.withSpan('ultramodern.api.${groupName}.readiness', {
|
|
589
589
|
attributes: operationAttributes(${groupName}OperationContexts.readiness),
|
|
590
590
|
kind: 'server',
|
|
591
591
|
}),
|
|
@@ -605,7 +605,7 @@ const ${groupName}Layer = HttpApiBuilder.group(
|
|
|
605
605
|
: Effect.succeed(matchedItem);
|
|
606
606
|
|
|
607
607
|
return result.pipe(
|
|
608
|
-
Effect.withSpan('ultramodern.
|
|
608
|
+
Effect.withSpan('ultramodern.api.${groupName}.get', {
|
|
609
609
|
attributes: operationAttributes(${groupName}OperationContexts.get),
|
|
610
610
|
kind: 'server',
|
|
611
611
|
}),
|
|
@@ -622,7 +622,7 @@ const ${groupName}Layer = HttpApiBuilder.group(
|
|
|
622
622
|
title: payload.title,
|
|
623
623
|
},
|
|
624
624
|
}).pipe(
|
|
625
|
-
Effect.withSpan('ultramodern.
|
|
625
|
+
Effect.withSpan('ultramodern.api.${groupName}.create', {
|
|
626
626
|
attributes: operationAttributes(${groupName}OperationContexts.create),
|
|
627
627
|
kind: 'server',
|
|
628
628
|
}),
|
|
@@ -634,21 +634,21 @@ const layer = HttpApiBuilder.layer(${apiExport}).pipe(
|
|
|
634
634
|
Layer.provide(${groupName}Layer),
|
|
635
635
|
) satisfies EffectRuntimeLayer;
|
|
636
636
|
|
|
637
|
-
const
|
|
637
|
+
const apiRuntime: EffectBffDefinition<typeof ${apiExport}, EffectRuntimeLayer> &
|
|
638
638
|
EffectBffRuntime<typeof ${apiExport}, EffectRuntimeLayer> = defineEffectBff({
|
|
639
639
|
api: ${apiExport},
|
|
640
640
|
layer,
|
|
641
641
|
});
|
|
642
642
|
|
|
643
|
-
export default
|
|
643
|
+
export default apiRuntime;
|
|
644
644
|
`;
|
|
645
645
|
}
|
|
646
|
-
function
|
|
647
|
-
const apiExport =
|
|
648
|
-
const contractExport =
|
|
649
|
-
const stem =
|
|
650
|
-
const groupName =
|
|
651
|
-
const singular =
|
|
646
|
+
function createApiClient(service, contractImportPath) {
|
|
647
|
+
const apiExport = verticalApiExport(service);
|
|
648
|
+
const contractExport = verticalApiGroupName(service);
|
|
649
|
+
const stem = resolveApiStem(service);
|
|
650
|
+
const groupName = verticalApiGroupName(service);
|
|
651
|
+
const singular = verticalApiErrorStem(service);
|
|
652
652
|
const clientOptionsName = `${toPascalCase(stem)}ClientOptions`;
|
|
653
653
|
const createClientName = `create${toPascalCase(stem)}Client`;
|
|
654
654
|
const clientTypeName = `${toPascalCase(stem)}Client`;
|
|
@@ -657,7 +657,7 @@ function createEffectClient(service, contractImportPath) {
|
|
|
657
657
|
const readinessName = `get${toPascalCase(stem)}Readiness`;
|
|
658
658
|
const getName = `get${toPascalCase(singular)}`;
|
|
659
659
|
const createName = `create${toPascalCase(singular)}`;
|
|
660
|
-
const notFoundErrorExport =
|
|
660
|
+
const notFoundErrorExport = verticalApiNotFoundErrorExport(service);
|
|
661
661
|
const pascalStem = toPascalCase(stem);
|
|
662
662
|
const itemType = `${pascalStem}Item`;
|
|
663
663
|
const readinessType = `${pascalStem}Readiness`;
|
|
@@ -692,7 +692,7 @@ import type {
|
|
|
692
692
|
|
|
693
693
|
export { Effect, runEffectRequest };
|
|
694
694
|
|
|
695
|
-
type ${pascalStem}
|
|
695
|
+
type ${pascalStem}ApiGroups = typeof ${apiExport} extends HttpApi.HttpApi<
|
|
696
696
|
infer _ApiId,
|
|
697
697
|
infer Groups
|
|
698
698
|
>
|
|
@@ -700,7 +700,7 @@ type ${pascalStem}EffectGroups = typeof ${apiExport} extends HttpApi.HttpApi<
|
|
|
700
700
|
: never;
|
|
701
701
|
|
|
702
702
|
export type ${clientTypeName} = HttpApiClient.Client<
|
|
703
|
-
Extract<${pascalStem}
|
|
703
|
+
Extract<${pascalStem}ApiGroups, HttpApiGroup.Any>,
|
|
704
704
|
never,
|
|
705
705
|
never
|
|
706
706
|
>;
|
|
@@ -790,11 +790,11 @@ export const ${createName} = (
|
|
|
790
790
|
);${checkoutCartClientExports}
|
|
791
791
|
`;
|
|
792
792
|
}
|
|
793
|
-
function
|
|
794
|
-
const exports =
|
|
795
|
-
const stem =
|
|
793
|
+
function createShellApiClient(scope, remotes = []) {
|
|
794
|
+
const exports = verticalApiApps(remotes).map((remote)=>{
|
|
795
|
+
const stem = resolveApiStem(remote);
|
|
796
796
|
const pascalStem = toPascalCase(stem);
|
|
797
|
-
const pascalSingular = toPascalCase(
|
|
797
|
+
const pascalSingular = toPascalCase(verticalApiErrorStem(remote));
|
|
798
798
|
const checkoutCartExports = serviceHasCheckoutCartState(remote) ? ` addCheckoutCartItem,
|
|
799
799
|
clearCheckoutCart,
|
|
800
800
|
getCheckoutCart,
|
|
@@ -810,15 +810,15 @@ ${checkoutCartExports} create${pascalSingular},
|
|
|
810
810
|
get${pascalStem}Readiness,
|
|
811
811
|
list${pascalStem},
|
|
812
812
|
type ${pascalStem}ClientOptions,
|
|
813
|
-
} from '${packageName(scope, remote.packageSuffix)}/
|
|
813
|
+
} from '${packageName(scope, remote.packageSuffix)}/api/client';`;
|
|
814
814
|
}).join('\n\n');
|
|
815
815
|
return exports ? `${exports}\n` : `export const ultramodernVerticalClients = [] as const;
|
|
816
816
|
`;
|
|
817
817
|
}
|
|
818
|
-
function
|
|
819
|
-
const stem =
|
|
818
|
+
function createApiReadinessContract(app) {
|
|
819
|
+
const stem = resolveApiStem(app);
|
|
820
820
|
return {
|
|
821
|
-
endpoint:
|
|
821
|
+
endpoint: `/${stem}/readiness`,
|
|
822
822
|
marker: {
|
|
823
823
|
ui: 'ultramodernUiMarker',
|
|
824
824
|
api: 'ultramodernApiMarker',
|
|
@@ -828,11 +828,11 @@ function createEffectReadinessContract(app) {
|
|
|
828
828
|
'moduleFederation',
|
|
829
829
|
'ssr',
|
|
830
830
|
'translations',
|
|
831
|
-
'
|
|
831
|
+
'api'
|
|
832
832
|
]
|
|
833
833
|
};
|
|
834
834
|
}
|
|
835
|
-
function
|
|
835
|
+
function createApiRequestContextContract() {
|
|
836
836
|
return {
|
|
837
837
|
propagatedHeaders: [
|
|
838
838
|
'accept-language',
|
|
@@ -843,39 +843,39 @@ function createEffectRequestContextContract() {
|
|
|
843
843
|
'x-ultramodern-env',
|
|
844
844
|
'x-vertical-version-id'
|
|
845
845
|
],
|
|
846
|
-
source: 'shell-to-vertical-
|
|
846
|
+
source: 'shell-to-vertical-api-client'
|
|
847
847
|
};
|
|
848
848
|
}
|
|
849
|
-
function
|
|
850
|
-
const stem =
|
|
851
|
-
const group =
|
|
852
|
-
const basePath =
|
|
849
|
+
function createApiDomainOperations(app) {
|
|
850
|
+
const stem = resolveApiStem(app);
|
|
851
|
+
const group = verticalApiGroupName(app);
|
|
852
|
+
const basePath = `/${stem}`;
|
|
853
853
|
const checkoutCartOperations = serviceHasCheckoutCartState(app) ? {
|
|
854
854
|
checkoutCartAddItem: {
|
|
855
855
|
client: 'addCheckoutCartItem',
|
|
856
856
|
method: 'POST',
|
|
857
|
-
path: '/
|
|
857
|
+
path: '/checkout/cart/items',
|
|
858
858
|
resource: 'checkout-cart',
|
|
859
859
|
owner: app.id
|
|
860
860
|
},
|
|
861
861
|
checkoutCartClear: {
|
|
862
862
|
client: 'clearCheckoutCart',
|
|
863
863
|
method: 'POST',
|
|
864
|
-
path: '/
|
|
864
|
+
path: '/checkout/cart/clear',
|
|
865
865
|
resource: 'checkout-cart',
|
|
866
866
|
owner: app.id
|
|
867
867
|
},
|
|
868
868
|
checkoutCartRead: {
|
|
869
869
|
client: 'getCheckoutCart',
|
|
870
870
|
method: 'GET',
|
|
871
|
-
path: '/
|
|
871
|
+
path: '/checkout/cart',
|
|
872
872
|
resource: 'checkout-cart',
|
|
873
873
|
owner: app.id
|
|
874
874
|
},
|
|
875
875
|
checkoutCartRemoveItem: {
|
|
876
876
|
client: 'removeCheckoutCartItem',
|
|
877
877
|
method: 'POST',
|
|
878
|
-
path: '/
|
|
878
|
+
path: '/checkout/cart/remove',
|
|
879
879
|
resource: 'checkout-cart',
|
|
880
880
|
owner: app.id
|
|
881
881
|
}
|
|
@@ -890,14 +890,14 @@ function createEffectDomainOperations(app) {
|
|
|
890
890
|
owner: app.id
|
|
891
891
|
},
|
|
892
892
|
workspaceDetail: {
|
|
893
|
-
client: `get${toPascalCase(
|
|
893
|
+
client: `get${toPascalCase(verticalApiErrorStem(app))}`,
|
|
894
894
|
method: 'GET',
|
|
895
895
|
path: `${basePath}/:id`,
|
|
896
896
|
resource: 'workspace-item',
|
|
897
897
|
owner: app.id
|
|
898
898
|
},
|
|
899
899
|
workspaceCreate: {
|
|
900
|
-
client: `create${toPascalCase(
|
|
900
|
+
client: `create${toPascalCase(verticalApiErrorStem(app))}`,
|
|
901
901
|
method: 'POST',
|
|
902
902
|
path: basePath,
|
|
903
903
|
resource: group,
|
|
@@ -905,82 +905,81 @@ function createEffectDomainOperations(app) {
|
|
|
905
905
|
}
|
|
906
906
|
};
|
|
907
907
|
}
|
|
908
|
-
function
|
|
909
|
-
if (!
|
|
908
|
+
function apiTopologyMetadata(app) {
|
|
909
|
+
if (!appHasApi(app)) return;
|
|
910
910
|
return {
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
}
|
|
911
|
+
runtime: 'effect',
|
|
912
|
+
bff: {
|
|
913
|
+
prefix: app.api.prefix,
|
|
914
|
+
openapi: '/openapi.json',
|
|
915
|
+
strictEffectApproach: true
|
|
916
|
+
},
|
|
917
|
+
contract: {
|
|
918
|
+
export: './api',
|
|
919
|
+
path: `${app.directory}/shared/api.ts`
|
|
920
|
+
},
|
|
921
|
+
client: {
|
|
922
|
+
export: './api/client',
|
|
923
|
+
path: `${app.directory}/src/api/${app.api.stem}-client.ts`
|
|
924
|
+
},
|
|
925
|
+
serverEntry: `${app.directory}/api/index.ts`,
|
|
926
|
+
basePath: `${app.api.prefix}/${app.api.stem}`,
|
|
927
|
+
consumedBy: app.api.consumedBy,
|
|
928
|
+
readiness: createApiReadinessContract(app),
|
|
929
|
+
requestContext: createApiRequestContextContract(),
|
|
930
|
+
domainOperations: createApiDomainOperations(app)
|
|
932
931
|
};
|
|
933
932
|
}
|
|
934
|
-
function
|
|
935
|
-
const stem =
|
|
933
|
+
function createApiOperationContract(target) {
|
|
934
|
+
const stem = resolveApiStem(target);
|
|
936
935
|
const checkoutCartOperations = serviceHasCheckoutCartState(target) ? {
|
|
937
936
|
addCartItem: {
|
|
938
937
|
method: 'POST',
|
|
939
|
-
path: '/
|
|
938
|
+
path: '/checkout/cart/items',
|
|
940
939
|
source: 'generated-client'
|
|
941
940
|
},
|
|
942
941
|
clearCart: {
|
|
943
942
|
method: 'POST',
|
|
944
|
-
path: '/
|
|
943
|
+
path: '/checkout/cart/clear',
|
|
945
944
|
source: 'generated-client'
|
|
946
945
|
},
|
|
947
946
|
getCart: {
|
|
948
947
|
method: 'GET',
|
|
949
|
-
path: '/
|
|
948
|
+
path: '/checkout/cart',
|
|
950
949
|
source: 'generated-client'
|
|
951
950
|
},
|
|
952
951
|
removeCartItem: {
|
|
953
952
|
method: 'POST',
|
|
954
|
-
path: '/
|
|
953
|
+
path: '/checkout/cart/remove',
|
|
955
954
|
source: 'generated-client'
|
|
956
955
|
}
|
|
957
956
|
} : {};
|
|
958
957
|
return {
|
|
959
|
-
group:
|
|
960
|
-
notFound:
|
|
958
|
+
group: verticalApiGroupName(target),
|
|
959
|
+
notFound: verticalApiNotFoundErrorExport(target),
|
|
961
960
|
operations: {
|
|
962
961
|
...checkoutCartOperations,
|
|
963
962
|
list: {
|
|
964
963
|
method: 'GET',
|
|
965
|
-
path:
|
|
964
|
+
path: `/${stem}`,
|
|
966
965
|
source: 'generated-client'
|
|
967
966
|
},
|
|
968
967
|
readiness: {
|
|
969
968
|
method: 'GET',
|
|
970
|
-
path:
|
|
969
|
+
path: `/${stem}/readiness`,
|
|
971
970
|
source: 'generated-client'
|
|
972
971
|
},
|
|
973
972
|
get: {
|
|
974
973
|
method: 'GET',
|
|
975
|
-
path:
|
|
974
|
+
path: `/${stem}/:id`,
|
|
976
975
|
source: 'generated-client'
|
|
977
976
|
},
|
|
978
977
|
create: {
|
|
979
978
|
method: 'POST',
|
|
980
|
-
path:
|
|
979
|
+
path: `/${stem}`,
|
|
981
980
|
source: 'generated-client'
|
|
982
981
|
}
|
|
983
982
|
}
|
|
984
983
|
};
|
|
985
984
|
}
|
|
986
|
-
export {
|
|
985
|
+
export { apiTopologyMetadata, createApiClient, createApiDomainOperations, createApiOperationContract, createApiReadinessContract, createApiRequestContextContract, createApiServiceEntry, createSharedApi, createSharedApiContract, createSharedApiImports, createShellApiClient, verticalApiCreatePayloadSchemaExport, verticalApiErrorStem, verticalApiExport, verticalApiGroupName, verticalApiMarkerSchemaExport, verticalApiName, verticalApiNotFoundErrorExport, verticalApiNotFoundSchemaExport, verticalApiReadinessSchemaExport, verticalApiSchemaExport };
|