@bleedingdev/modern-js-create 3.4.0-ultramodern.19 → 3.4.0-ultramodern.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/dist/cjs/index.cjs +1 -1
  2. package/dist/cjs/locale/en.cjs +2 -2
  3. package/dist/cjs/locale/zh.cjs +2 -2
  4. package/dist/cjs/ultramodern-tooling/config.cjs +9 -91
  5. package/dist/cjs/ultramodern-workspace/add-vertical.cjs +13 -40
  6. package/dist/cjs/ultramodern-workspace/contracts.cjs +2 -0
  7. package/dist/cjs/ultramodern-workspace/demo-components.cjs +12 -12
  8. package/dist/cjs/ultramodern-workspace/descriptors.cjs +0 -4
  9. package/dist/cjs/ultramodern-workspace/effect-api.cjs +74 -75
  10. package/dist/cjs/ultramodern-workspace/mf-validation.cjs +1 -2
  11. package/dist/cjs/ultramodern-workspace/module-federation.cjs +3 -2
  12. package/dist/cjs/ultramodern-workspace/package-json.cjs +6 -5
  13. package/dist/cjs/ultramodern-workspace/policy.cjs +1 -1
  14. package/dist/cjs/ultramodern-workspace/workspace-scripts.cjs +7 -0
  15. package/dist/cjs/ultramodern-workspace/write-workspace.cjs +4 -4
  16. package/dist/esm/index.js +1 -1
  17. package/dist/esm/locale/en.js +2 -2
  18. package/dist/esm/locale/zh.js +2 -2
  19. package/dist/esm/ultramodern-tooling/config.js +10 -92
  20. package/dist/esm/ultramodern-workspace/add-vertical.js +14 -41
  21. package/dist/esm/ultramodern-workspace/contracts.js +2 -0
  22. package/dist/esm/ultramodern-workspace/demo-components.js +12 -12
  23. package/dist/esm/ultramodern-workspace/descriptors.js +1 -2
  24. package/dist/esm/ultramodern-workspace/effect-api.js +74 -75
  25. package/dist/esm/ultramodern-workspace/mf-validation.js +1 -2
  26. package/dist/esm/ultramodern-workspace/module-federation.js +3 -2
  27. package/dist/esm/ultramodern-workspace/package-json.js +6 -5
  28. package/dist/esm/ultramodern-workspace/policy.js +1 -1
  29. package/dist/esm/ultramodern-workspace/workspace-scripts.js +5 -1
  30. package/dist/esm/ultramodern-workspace/write-workspace.js +4 -4
  31. package/dist/esm-node/index.js +1 -1
  32. package/dist/esm-node/locale/en.js +2 -2
  33. package/dist/esm-node/locale/zh.js +2 -2
  34. package/dist/esm-node/ultramodern-tooling/config.js +10 -92
  35. package/dist/esm-node/ultramodern-workspace/add-vertical.js +14 -41
  36. package/dist/esm-node/ultramodern-workspace/contracts.js +2 -0
  37. package/dist/esm-node/ultramodern-workspace/demo-components.js +12 -12
  38. package/dist/esm-node/ultramodern-workspace/descriptors.js +1 -2
  39. package/dist/esm-node/ultramodern-workspace/effect-api.js +74 -75
  40. package/dist/esm-node/ultramodern-workspace/mf-validation.js +1 -2
  41. package/dist/esm-node/ultramodern-workspace/module-federation.js +3 -2
  42. package/dist/esm-node/ultramodern-workspace/package-json.js +6 -5
  43. package/dist/esm-node/ultramodern-workspace/policy.js +1 -1
  44. package/dist/esm-node/ultramodern-workspace/workspace-scripts.js +5 -1
  45. package/dist/esm-node/ultramodern-workspace/write-workspace.js +4 -4
  46. package/dist/types/ultramodern-tooling/config.d.ts +1 -2
  47. package/dist/types/ultramodern-workspace/descriptors.d.ts +0 -1
  48. package/dist/types/ultramodern-workspace/workspace-scripts.d.ts +1 -0
  49. package/package.json +3 -3
  50. package/templates/workspace-scripts/assert-mf-types.mjs.handlebars +1 -11
  51. package/templates/workspace-scripts/check-ultramodern-api-boundaries.mjs +339 -0
  52. package/templates/workspace-scripts/generate-public-surface-assets.mjs +14 -12
  53. package/templates/workspace-scripts/proof-cloudflare-version.mjs +3 -13
  54. package/templates/workspace-scripts/ultramodern-cloudflare-proof.mjs +3 -3
  55. package/templates/workspace-scripts/ultramodern-performance-readiness.mjs +1 -9
  56. package/templates/workspace-scripts/validate-ultramodern-workspace.mjs.handlebars +82 -86
@@ -53,13 +53,13 @@ __webpack_require__.d(__webpack_exports__, {
53
53
  const external_descriptors_cjs_namespaceObject = require("./descriptors.cjs");
54
54
  const external_naming_cjs_namespaceObject = require("./naming.cjs");
55
55
  function verticalEffectApiExport(service) {
56
- return `${(0, external_naming_cjs_namespaceObject.toCamelCase)((0, external_descriptors_cjs_namespaceObject.effectApiStem)(service))}EffectApi`;
56
+ return `${(0, external_naming_cjs_namespaceObject.toCamelCase)((0, external_descriptors_cjs_namespaceObject.effectApiStem)(service))}Api`;
57
57
  }
58
58
  function verticalEffectGroupName(service) {
59
59
  return (0, external_naming_cjs_namespaceObject.toCamelCase)((0, external_descriptors_cjs_namespaceObject.effectApiStem)(service));
60
60
  }
61
61
  function verticalEffectApiName(service) {
62
- return `${(0, external_naming_cjs_namespaceObject.toPascalCase)((0, external_descriptors_cjs_namespaceObject.effectApiStem)(service))}EffectApi`;
62
+ return `${(0, external_naming_cjs_namespaceObject.toPascalCase)((0, external_descriptors_cjs_namespaceObject.effectApiStem)(service))}Api`;
63
63
  }
64
64
  function verticalEffectSchemaExport(service) {
65
65
  return `${(0, external_naming_cjs_namespaceObject.toCamelCase)((0, external_descriptors_cjs_namespaceObject.effectApiStem)(service))}ItemSchema`;
@@ -141,24 +141,24 @@ function createCheckoutCartEndpointDefinitions(service) {
141
141
  if (!serviceHasCheckoutCartState(service)) return '';
142
142
  return `
143
143
  .add(
144
- HttpApiEndpoint.get('getCart', '/effect/checkout/cart', {
144
+ HttpApiEndpoint.get('getCart', '/checkout/cart', {
145
145
  success: checkoutCartSchema,
146
146
  }),
147
147
  )
148
148
  .add(
149
- HttpApiEndpoint.post('addCartItem', '/effect/checkout/cart/items', {
149
+ HttpApiEndpoint.post('addCartItem', '/checkout/cart/items', {
150
150
  payload: checkoutAddCartItemPayloadSchema,
151
151
  success: checkoutCartSchema,
152
152
  }),
153
153
  )
154
154
  .add(
155
- HttpApiEndpoint.post('removeCartItem', '/effect/checkout/cart/remove', {
155
+ HttpApiEndpoint.post('removeCartItem', '/checkout/cart/remove', {
156
156
  payload: checkoutRemoveCartItemPayloadSchema,
157
157
  success: checkoutCartSchema,
158
158
  }),
159
159
  )
160
160
  .add(
161
- HttpApiEndpoint.post('clearCart', '/effect/checkout/cart/clear', {
161
+ HttpApiEndpoint.post('clearCart', '/checkout/cart/clear', {
162
162
  success: checkoutCartSchema,
163
163
  }),
164
164
  )`;
@@ -171,31 +171,31 @@ function createCheckoutCartOperationContexts(service) {
171
171
  addCartItem: {
172
172
  method: 'POST',
173
173
  operationId: '${apiName}:${groupName}:addCartItem',
174
- routePath: '/effect/checkout/cart/items',
174
+ routePath: '/checkout/cart/items',
175
175
  source: 'generated-client',
176
176
  },
177
177
  clearCart: {
178
178
  method: 'POST',
179
179
  operationId: '${apiName}:${groupName}:clearCart',
180
- routePath: '/effect/checkout/cart/clear',
180
+ routePath: '/checkout/cart/clear',
181
181
  source: 'generated-client',
182
182
  },
183
183
  getCart: {
184
184
  method: 'GET',
185
185
  operationId: '${apiName}:${groupName}:getCart',
186
- routePath: '/effect/checkout/cart',
186
+ routePath: '/checkout/cart',
187
187
  source: 'generated-client',
188
188
  },
189
189
  removeCartItem: {
190
190
  method: 'POST',
191
191
  operationId: '${apiName}:${groupName}:removeCartItem',
192
- routePath: '/effect/checkout/cart/remove',
192
+ routePath: '/checkout/cart/remove',
193
193
  source: 'generated-client',
194
194
  },`;
195
195
  }
196
196
  function createCheckoutCartApiContractFields(service) {
197
197
  if (!serviceHasCheckoutCartState(service)) return '';
198
- return ` checkoutCartPath: '${(0, external_descriptors_cjs_namespaceObject.effectApiPrefix)(service)}/effect/checkout/cart',
198
+ return ` checkoutCartPath: '${(0, external_descriptors_cjs_namespaceObject.effectApiPrefix)(service)}/checkout/cart',
199
199
  `;
200
200
  }
201
201
  function createCheckoutCartServerState(service) {
@@ -231,7 +231,7 @@ function createCheckoutCartServerHandlers(service) {
231
231
  return `
232
232
  .handle('getCart', () =>
233
233
  Effect.sync(() => createCheckoutCartSnapshot()).pipe(
234
- Effect.withSpan('ultramodern.effect.${groupName}.checkout.getCart', {
234
+ Effect.withSpan('ultramodern.api.${groupName}.checkout.getCart', {
235
235
  attributes: operationAttributes(${groupName}OperationContexts.getCart),
236
236
  kind: 'server',
237
237
  }),
@@ -249,7 +249,7 @@ function createCheckoutCartServerHandlers(service) {
249
249
  });
250
250
  return createCheckoutCartSnapshot();
251
251
  }).pipe(
252
- Effect.withSpan('ultramodern.effect.${groupName}.checkout.addCartItem', {
252
+ Effect.withSpan('ultramodern.api.${groupName}.checkout.addCartItem', {
253
253
  attributes: operationAttributes(${groupName}OperationContexts.addCartItem),
254
254
  kind: 'server',
255
255
  }),
@@ -260,7 +260,7 @@ function createCheckoutCartServerHandlers(service) {
260
260
  checkoutCartLines.delete(payload.sku);
261
261
  return createCheckoutCartSnapshot();
262
262
  }).pipe(
263
- Effect.withSpan('ultramodern.effect.${groupName}.checkout.removeCartItem', {
263
+ Effect.withSpan('ultramodern.api.${groupName}.checkout.removeCartItem', {
264
264
  attributes: operationAttributes(${groupName}OperationContexts.removeCartItem),
265
265
  kind: 'server',
266
266
  }),
@@ -271,7 +271,7 @@ function createCheckoutCartServerHandlers(service) {
271
271
  checkoutCartLines.clear();
272
272
  return createCheckoutCartSnapshot();
273
273
  }).pipe(
274
- Effect.withSpan('ultramodern.effect.${groupName}.checkout.clearCart', {
274
+ Effect.withSpan('ultramodern.api.${groupName}.checkout.clearCart', {
275
275
  attributes: operationAttributes(${groupName}OperationContexts.clearCart),
276
276
  kind: 'server',
277
277
  }),
@@ -408,7 +408,7 @@ export interface ${itemType} {
408
408
 
409
409
  export interface ${readinessType} {
410
410
  readonly checks: {
411
- readonly effectBff: 'ready';
411
+ readonly api: 'ready';
412
412
  readonly moduleFederation: 'ready';
413
413
  readonly ssr: 'ready';
414
414
  readonly translations: 'ready';
@@ -452,7 +452,7 @@ export const ${schemaExport}: Schema.Codec<${itemType}> = Schema.Struct({
452
452
 
453
453
  export const ${readinessSchemaExport}: Schema.Codec<${readinessType}> = Schema.Struct({
454
454
  checks: Schema.Struct({
455
- effectBff: Schema.Literal('ready'),
455
+ api: Schema.Literal('ready'),
456
456
  moduleFederation: Schema.Literal('ready'),
457
457
  ssr: Schema.Literal('ready'),
458
458
  translations: Schema.Literal('ready'),
@@ -489,7 +489,7 @@ export interface OperationContext {
489
489
  export const ${apiExport} = HttpApi.make('${apiName}').add(
490
490
  HttpApiGroup.make('${groupName}')
491
491
  .add(
492
- HttpApiEndpoint.get('list', '/effect/${stem}', {
492
+ HttpApiEndpoint.get('list', '/${stem}', {
493
493
  query: {
494
494
  limit: Schema.optional(Schema.FiniteFromString),
495
495
  },
@@ -499,12 +499,12 @@ export const ${apiExport} = HttpApi.make('${apiName}').add(
499
499
  }),
500
500
  )
501
501
  .add(
502
- HttpApiEndpoint.get('readiness', '/effect/${stem}/readiness', {
502
+ HttpApiEndpoint.get('readiness', '/${stem}/readiness', {
503
503
  success: ${readinessSchemaExport},
504
504
  }),
505
505
  )
506
506
  .add(
507
- HttpApiEndpoint.get('get', '/effect/${stem}/:id', {
507
+ HttpApiEndpoint.get('get', '/${stem}/:id', {
508
508
  error: ${notFoundSchemaExport},
509
509
  params: {
510
510
  id: Schema.String,
@@ -513,7 +513,7 @@ export const ${apiExport} = HttpApi.make('${apiName}').add(
513
513
  }),
514
514
  )
515
515
  .add(
516
- HttpApiEndpoint.post('create', '/effect/${stem}', {
516
+ HttpApiEndpoint.post('create', '/${stem}', {
517
517
  payload: ${createPayloadSchemaExport},
518
518
  success: Schema.Struct({
519
519
  item: ${schemaExport},
@@ -526,34 +526,34 @@ export const ${groupName}OperationContexts = {
526
526
  ${checkoutCartOperationContextEntries} create: {
527
527
  method: 'POST',
528
528
  operationId: '${apiName}:${groupName}:create',
529
- routePath: '/effect/${stem}',
529
+ routePath: '/${stem}',
530
530
  source: 'generated-client',
531
531
  },
532
532
  get: {
533
533
  method: 'GET',
534
534
  operationId: '${apiName}:${groupName}:get',
535
- routePath: '/effect/${stem}/:id',
535
+ routePath: '/${stem}/:id',
536
536
  source: 'generated-client',
537
537
  },
538
538
  list: {
539
539
  method: 'GET',
540
540
  operationId: '${apiName}:${groupName}:list',
541
- routePath: '/effect/${stem}',
541
+ routePath: '/${stem}',
542
542
  source: 'generated-client',
543
543
  },
544
544
  readiness: {
545
545
  method: 'GET',
546
546
  operationId: '${apiName}:${groupName}:readiness',
547
- routePath: '/effect/${stem}/readiness',
547
+ routePath: '/${stem}/readiness',
548
548
  source: 'generated-client',
549
549
  },
550
550
  } satisfies Record<string, OperationContext>;
551
551
 
552
552
  export const ${groupName}ApiContract = {
553
553
  apiPrefix: '${apiPrefix}',
554
- basePath: '${apiPrefix}/effect/${stem}',
554
+ basePath: '${apiPrefix}/${stem}',
555
555
  ${createCheckoutCartApiContractFields(service)} ownerId: '${service.id}',
556
- readinessPath: '${apiPrefix}/effect/${stem}/readiness',
556
+ readinessPath: '${apiPrefix}/${stem}/readiness',
557
557
  } as const;
558
558
  `;
559
559
  }
@@ -577,7 +577,7 @@ import type {
577
577
  EffectBffRuntime,
578
578
  EffectRuntimeLayer,
579
579
  } from '@modern-js/plugin-bff/effect-edge';
580
- import { ultramodernApiMarker } from '../../shared/ultramodern-build.ts';
580
+ import { ultramodernApiMarker } from '../shared/ultramodern-build.ts';
581
581
  import {
582
582
  ${apiExport},
583
583
  ${groupName}OperationContexts,
@@ -618,7 +618,7 @@ const ${groupName}Layer = HttpApiBuilder.group(
618
618
  ? ${groupName}Items.slice(0, query.limit)
619
619
  : ${groupName}Items,
620
620
  }).pipe(
621
- Effect.withSpan('ultramodern.effect.${groupName}.list', {
621
+ Effect.withSpan('ultramodern.api.${groupName}.list', {
622
622
  attributes: operationAttributes(${groupName}OperationContexts.list),
623
623
  kind: 'server',
624
624
  }),
@@ -627,7 +627,7 @@ const ${groupName}Layer = HttpApiBuilder.group(
627
627
  .handle('readiness', () =>
628
628
  Effect.succeed({
629
629
  checks: {
630
- effectBff: 'ready' as const,
630
+ api: 'ready' as const,
631
631
  moduleFederation: 'ready' as const,
632
632
  ssr: 'ready' as const,
633
633
  translations: 'ready' as const,
@@ -636,7 +636,7 @@ const ${groupName}Layer = HttpApiBuilder.group(
636
636
  status: 'ready' as const,
637
637
  versionSkew: 'none' as const,
638
638
  }).pipe(
639
- Effect.withSpan('ultramodern.effect.${groupName}.readiness', {
639
+ Effect.withSpan('ultramodern.api.${groupName}.readiness', {
640
640
  attributes: operationAttributes(${groupName}OperationContexts.readiness),
641
641
  kind: 'server',
642
642
  }),
@@ -656,7 +656,7 @@ const ${groupName}Layer = HttpApiBuilder.group(
656
656
  : Effect.succeed(matchedItem);
657
657
 
658
658
  return result.pipe(
659
- Effect.withSpan('ultramodern.effect.${groupName}.get', {
659
+ Effect.withSpan('ultramodern.api.${groupName}.get', {
660
660
  attributes: operationAttributes(${groupName}OperationContexts.get),
661
661
  kind: 'server',
662
662
  }),
@@ -673,7 +673,7 @@ const ${groupName}Layer = HttpApiBuilder.group(
673
673
  title: payload.title,
674
674
  },
675
675
  }).pipe(
676
- Effect.withSpan('ultramodern.effect.${groupName}.create', {
676
+ Effect.withSpan('ultramodern.api.${groupName}.create', {
677
677
  attributes: operationAttributes(${groupName}OperationContexts.create),
678
678
  kind: 'server',
679
679
  }),
@@ -685,13 +685,13 @@ const layer = HttpApiBuilder.layer(${apiExport}).pipe(
685
685
  Layer.provide(${groupName}Layer),
686
686
  ) satisfies EffectRuntimeLayer;
687
687
 
688
- const effectBff: EffectBffDefinition<typeof ${apiExport}, EffectRuntimeLayer> &
688
+ const apiRuntime: EffectBffDefinition<typeof ${apiExport}, EffectRuntimeLayer> &
689
689
  EffectBffRuntime<typeof ${apiExport}, EffectRuntimeLayer> = defineEffectBff({
690
690
  api: ${apiExport},
691
691
  layer,
692
692
  });
693
693
 
694
- export default effectBff;
694
+ export default apiRuntime;
695
695
  `;
696
696
  }
697
697
  function createEffectClient(service, contractImportPath) {
@@ -743,7 +743,7 @@ import type {
743
743
 
744
744
  export { Effect, runEffectRequest };
745
745
 
746
- type ${pascalStem}EffectGroups = typeof ${apiExport} extends HttpApi.HttpApi<
746
+ type ${pascalStem}ApiGroups = typeof ${apiExport} extends HttpApi.HttpApi<
747
747
  infer _ApiId,
748
748
  infer Groups
749
749
  >
@@ -751,7 +751,7 @@ type ${pascalStem}EffectGroups = typeof ${apiExport} extends HttpApi.HttpApi<
751
751
  : never;
752
752
 
753
753
  export type ${clientTypeName} = HttpApiClient.Client<
754
- Extract<${pascalStem}EffectGroups, HttpApiGroup.Any>,
754
+ Extract<${pascalStem}ApiGroups, HttpApiGroup.Any>,
755
755
  never,
756
756
  never
757
757
  >;
@@ -861,7 +861,7 @@ ${checkoutCartExports} create${pascalSingular},
861
861
  get${pascalStem}Readiness,
862
862
  list${pascalStem},
863
863
  type ${pascalStem}ClientOptions,
864
- } from '${(0, external_naming_cjs_namespaceObject.packageName)(scope, remote.packageSuffix)}/effect/client';`;
864
+ } from '${(0, external_naming_cjs_namespaceObject.packageName)(scope, remote.packageSuffix)}/api/client';`;
865
865
  }).join('\n\n');
866
866
  return exports1 ? `${exports1}\n` : `export const ultramodernVerticalClients = [] as const;
867
867
  `;
@@ -869,7 +869,7 @@ ${checkoutCartExports} create${pascalSingular},
869
869
  function createEffectReadinessContract(app) {
870
870
  const stem = (0, external_descriptors_cjs_namespaceObject.effectApiStem)(app);
871
871
  return {
872
- endpoint: `/effect/${stem}/readiness`,
872
+ endpoint: `/${stem}/readiness`,
873
873
  marker: {
874
874
  ui: 'ultramodernUiMarker',
875
875
  api: 'ultramodernApiMarker',
@@ -879,7 +879,7 @@ function createEffectReadinessContract(app) {
879
879
  'moduleFederation',
880
880
  'ssr',
881
881
  'translations',
882
- 'effectBff'
882
+ 'api'
883
883
  ]
884
884
  };
885
885
  }
@@ -894,39 +894,39 @@ function createEffectRequestContextContract() {
894
894
  'x-ultramodern-env',
895
895
  'x-vertical-version-id'
896
896
  ],
897
- source: 'shell-to-vertical-effect-client'
897
+ source: 'shell-to-vertical-api-client'
898
898
  };
899
899
  }
900
900
  function createEffectDomainOperations(app) {
901
901
  const stem = (0, external_descriptors_cjs_namespaceObject.effectApiStem)(app);
902
902
  const group = verticalEffectGroupName(app);
903
- const basePath = `/effect/${stem}`;
903
+ const basePath = `/${stem}`;
904
904
  const checkoutCartOperations = serviceHasCheckoutCartState(app) ? {
905
905
  checkoutCartAddItem: {
906
906
  client: 'addCheckoutCartItem',
907
907
  method: 'POST',
908
- path: '/effect/checkout/cart/items',
908
+ path: '/checkout/cart/items',
909
909
  resource: 'checkout-cart',
910
910
  owner: app.id
911
911
  },
912
912
  checkoutCartClear: {
913
913
  client: 'clearCheckoutCart',
914
914
  method: 'POST',
915
- path: '/effect/checkout/cart/clear',
915
+ path: '/checkout/cart/clear',
916
916
  resource: 'checkout-cart',
917
917
  owner: app.id
918
918
  },
919
919
  checkoutCartRead: {
920
920
  client: 'getCheckoutCart',
921
921
  method: 'GET',
922
- path: '/effect/checkout/cart',
922
+ path: '/checkout/cart',
923
923
  resource: 'checkout-cart',
924
924
  owner: app.id
925
925
  },
926
926
  checkoutCartRemoveItem: {
927
927
  client: 'removeCheckoutCartItem',
928
928
  method: 'POST',
929
- path: '/effect/checkout/cart/remove',
929
+ path: '/checkout/cart/remove',
930
930
  resource: 'checkout-cart',
931
931
  owner: app.id
932
932
  }
@@ -959,27 +959,26 @@ function createEffectDomainOperations(app) {
959
959
  function effectApiTopologyMetadata(app) {
960
960
  if (!(0, external_descriptors_cjs_namespaceObject.appHasEffectApi)(app)) return;
961
961
  return {
962
- effect: {
963
- runtime: 'effect',
964
- bff: {
965
- prefix: app.effectApi.prefix,
966
- openapi: '/openapi.json'
967
- },
968
- contract: {
969
- export: './shared/effect/api',
970
- path: `${app.directory}/shared/effect/api.ts`
971
- },
972
- client: {
973
- export: './effect/client',
974
- path: `${app.directory}/src/effect/${app.effectApi.stem}-client.ts`
975
- },
976
- serverEntry: `${app.directory}/api/effect/index.ts`,
977
- basePath: `${app.effectApi.prefix}/effect/${app.effectApi.stem}`,
978
- consumedBy: app.effectApi.consumedBy,
979
- readiness: createEffectReadinessContract(app),
980
- requestContext: createEffectRequestContextContract(),
981
- domainOperations: createEffectDomainOperations(app)
982
- }
962
+ runtime: 'effect',
963
+ bff: {
964
+ prefix: app.effectApi.prefix,
965
+ openapi: '/openapi.json',
966
+ strictEffectApproach: true
967
+ },
968
+ contract: {
969
+ export: './api',
970
+ path: `${app.directory}/shared/api.ts`
971
+ },
972
+ client: {
973
+ export: './api/client',
974
+ path: `${app.directory}/src/api/${app.effectApi.stem}-client.ts`
975
+ },
976
+ serverEntry: `${app.directory}/api/index.ts`,
977
+ basePath: `${app.effectApi.prefix}/${app.effectApi.stem}`,
978
+ consumedBy: app.effectApi.consumedBy,
979
+ readiness: createEffectReadinessContract(app),
980
+ requestContext: createEffectRequestContextContract(),
981
+ domainOperations: createEffectDomainOperations(app)
983
982
  };
984
983
  }
985
984
  function createEffectOperationContract(target) {
@@ -987,22 +986,22 @@ function createEffectOperationContract(target) {
987
986
  const checkoutCartOperations = serviceHasCheckoutCartState(target) ? {
988
987
  addCartItem: {
989
988
  method: 'POST',
990
- path: '/effect/checkout/cart/items',
989
+ path: '/checkout/cart/items',
991
990
  source: 'generated-client'
992
991
  },
993
992
  clearCart: {
994
993
  method: 'POST',
995
- path: '/effect/checkout/cart/clear',
994
+ path: '/checkout/cart/clear',
996
995
  source: 'generated-client'
997
996
  },
998
997
  getCart: {
999
998
  method: 'GET',
1000
- path: '/effect/checkout/cart',
999
+ path: '/checkout/cart',
1001
1000
  source: 'generated-client'
1002
1001
  },
1003
1002
  removeCartItem: {
1004
1003
  method: 'POST',
1005
- path: '/effect/checkout/cart/remove',
1004
+ path: '/checkout/cart/remove',
1006
1005
  source: 'generated-client'
1007
1006
  }
1008
1007
  } : {};
@@ -1013,22 +1012,22 @@ function createEffectOperationContract(target) {
1013
1012
  ...checkoutCartOperations,
1014
1013
  list: {
1015
1014
  method: 'GET',
1016
- path: `/effect/${stem}`,
1015
+ path: `/${stem}`,
1017
1016
  source: 'generated-client'
1018
1017
  },
1019
1018
  readiness: {
1020
1019
  method: 'GET',
1021
- path: `/effect/${stem}/readiness`,
1020
+ path: `/${stem}/readiness`,
1022
1021
  source: 'generated-client'
1023
1022
  },
1024
1023
  get: {
1025
1024
  method: 'GET',
1026
- path: `/effect/${stem}/:id`,
1025
+ path: `/${stem}/:id`,
1027
1026
  source: 'generated-client'
1028
1027
  },
1029
1028
  create: {
1030
1029
  method: 'POST',
1031
- path: `/effect/${stem}`,
1030
+ path: `/${stem}`,
1032
1031
  source: 'generated-client'
1033
1032
  }
1034
1033
  }
@@ -48,8 +48,7 @@ var external_node_path_default = /*#__PURE__*/ __webpack_require__.n(external_no
48
48
  const moduleFederationConfigFile = 'module-federation.config.ts';
49
49
  const mfTypesArchive = 'dist/@mf-types.zip';
50
50
  const generatedMetadataPaths = [
51
- '.modernjs/ultramodern.json',
52
- '.modernjs/ultramodern-generated-contract.json'
51
+ '.modernjs/ultramodern.json'
53
52
  ];
54
53
  const defaultAppRootDirs = [
55
54
  'apps',
@@ -59,10 +59,11 @@ function createAppModernConfig(scope, app) {
59
59
  const bffImport = (0, external_descriptors_cjs_namespaceObject.appHasEffectApi)(app) ? "import { bffPlugin } from '@modern-js/plugin-bff';\n" : '';
60
60
  const bffConfig = (0, external_descriptors_cjs_namespaceObject.appHasEffectApi)(app) ? ` bff: {
61
61
  effect: {
62
- entry: './api/effect/index',
62
+ entry: './api/index',
63
63
  openapi: {
64
64
  path: '/openapi.json',
65
65
  },
66
+ strictEffectApproach: true,
66
67
  },
67
68
  prefix: '${(0, external_descriptors_cjs_namespaceObject.effectApiPrefix)(app)}',
68
69
  runtimeFramework: 'effect',
@@ -446,7 +447,7 @@ export const ultramodernUiMarker = {
446
447
 
447
448
  export const ultramodernApiMarker = {
448
449
  ...ultramodernVerticalIdentity,
449
- surface: 'effect-bff',
450
+ surface: 'api',
450
451
  } as const;
451
452
  `;
452
453
  }
@@ -225,10 +225,11 @@ function createRootPackageJson(scope, packageSource, remotes = [], bridge) {
225
225
  'mf:types': "node ./scripts/assert-mf-types.mjs",
226
226
  'performance:readiness': "node ./scripts/ultramodern-performance-readiness.mjs",
227
227
  'contract:check': "node ./scripts/validate-ultramodern-workspace.mjs",
228
+ 'api:check': "node ./scripts/check-ultramodern-api-boundaries.mjs",
228
229
  'i18n:boundaries': "node ./scripts/check-ultramodern-i18n-boundaries.mjs",
229
230
  ...bridgeScripts,
230
231
  postinstall: "oxfmt . '!repos/**' && node ./scripts/bootstrap-agent-skills.mjs --postinstall",
231
- check: `pnpm format:check && pnpm lint && pnpm typecheck && pnpm skills:check && pnpm i18n:boundaries && pnpm contract:check && pnpm performance:readiness${bridgeCheck}`
232
+ check: `pnpm format:check && pnpm lint && pnpm typecheck && pnpm skills:check && pnpm i18n:boundaries && pnpm api:check && pnpm contract:check && pnpm performance:readiness${bridgeCheck}`
232
233
  },
233
234
  engines: {
234
235
  node: '>=26',
@@ -428,7 +429,7 @@ function createAppPackage(scope, app, packageSource, enableTailwind, remotes = [
428
429
  appId: app.id,
429
430
  topology: `${(0, external_naming_cjs_namespaceObject.relativeRootFor)(app.directory)}/topology/reference-topology.json`,
430
431
  ...(0, external_descriptors_cjs_namespaceObject.appHasEffectApi)(app) ? {
431
- apiRuntime: 'effect-bff'
432
+ apiRuntime: 'effect'
432
433
  } : {}
433
434
  },
434
435
  'zephyr:dependencies': createZephyrDependencies(scope, app, remotes),
@@ -436,11 +437,11 @@ function createAppPackage(scope, app, packageSource, enableTailwind, remotes = [
436
437
  devDependencies: appDevDependencies(packageSource, enableTailwind)
437
438
  };
438
439
  if ((0, external_descriptors_cjs_namespaceObject.appHasEffectApi)(app)) Object.assign(packageExports, {
439
- './effect/client': `./src/effect/${app.effectApi.stem}-client.ts`,
440
- './shared/effect/api': './shared/effect/api.ts'
440
+ './api': './shared/api.ts',
441
+ './api/client': `./src/api/${app.effectApi.stem}-client.ts`
441
442
  });
442
443
  else if ('shell' === app.kind) Object.assign(packageExports, {
443
- './effect/clients': './src/effect/vertical-clients.ts'
444
+ './api/clients': './src/api/vertical-clients.ts'
444
445
  });
445
446
  if (Object.keys(packageExports).length > 0) packageJson.exports = packageExports;
446
447
  return packageJson;
@@ -57,7 +57,7 @@ function createCloudflareProofRoute(app) {
57
57
  mfManifest: '/mf-manifest.json',
58
58
  locale: `/locales/en/${(0, external_descriptors_cjs_namespaceObject.appI18nNamespace)(app)}.json`,
59
59
  ...(0, external_descriptors_cjs_namespaceObject.appHasEffectApi)(app) ? {
60
- effectReadiness: `${(0, external_descriptors_cjs_namespaceObject.effectApiPrefix)(app)}/effect/${(0, external_descriptors_cjs_namespaceObject.effectApiStem)(app)}/readiness`
60
+ apiReadiness: `${(0, external_descriptors_cjs_namespaceObject.effectApiPrefix)(app)}/${(0, external_descriptors_cjs_namespaceObject.effectApiStem)(app)}/readiness`
61
61
  } : {}
62
62
  };
63
63
  }
@@ -29,6 +29,7 @@ var __webpack_exports__ = {};
29
29
  __webpack_require__.r(__webpack_exports__);
30
30
  __webpack_require__.d(__webpack_exports__, {
31
31
  createPerformanceReadinessConfigScript: ()=>createPerformanceReadinessConfigScript,
32
+ createWorkspaceApiBoundaryValidationScript: ()=>createWorkspaceApiBoundaryValidationScript,
32
33
  createWorkspaceI18nBoundaryValidationScript: ()=>createWorkspaceI18nBoundaryValidationScript,
33
34
  createWorkspaceValidationScript: ()=>createWorkspaceValidationScript,
34
35
  writeGeneratedWorkspaceScripts: ()=>writeGeneratedWorkspaceScripts
@@ -162,6 +163,9 @@ function createWorkspaceValidationScript(scope, enableTailwind, remotes = []) {
162
163
  function createWorkspaceI18nBoundaryValidationScript() {
163
164
  return (0, external_fs_io_cjs_namespaceObject.readFileTemplate)("workspace-scripts/check-ultramodern-i18n-boundaries.mjs");
164
165
  }
166
+ function createWorkspaceApiBoundaryValidationScript() {
167
+ return (0, external_fs_io_cjs_namespaceObject.readFileTemplate)("workspace-scripts/check-ultramodern-api-boundaries.mjs");
168
+ }
165
169
  function createPerformanceReadinessConfigScript() {
166
170
  return (0, external_fs_io_cjs_namespaceObject.readFileTemplate)("workspace-scripts/ultramodern-performance-readiness.config.mjs");
167
171
  }
@@ -169,6 +173,7 @@ function writeGeneratedWorkspaceScripts(targetDir, _scope, _enableTailwind, _rem
169
173
  (0, external_fs_io_cjs_namespaceObject.writeFileReplacing)(targetDir, "scripts/assert-mf-types.mjs", createToolWrapperScript('mf-types'));
170
174
  (0, external_fs_io_cjs_namespaceObject.writeFileReplacing)(targetDir, "scripts/validate-ultramodern-workspace.mjs", createToolWrapperScript('validate'));
171
175
  (0, external_fs_io_cjs_namespaceObject.writeFileReplacing)(targetDir, "scripts/check-ultramodern-i18n-boundaries.mjs", createWorkspaceI18nBoundaryValidationScript());
176
+ (0, external_fs_io_cjs_namespaceObject.writeFileReplacing)(targetDir, "scripts/check-ultramodern-api-boundaries.mjs", createWorkspaceApiBoundaryValidationScript());
172
177
  (0, external_fs_io_cjs_namespaceObject.writeFileReplacing)(targetDir, "scripts/generate-public-surface-assets.mjs", createToolWrapperScript('public-surface'));
173
178
  (0, external_fs_io_cjs_namespaceObject.writeFileReplacing)(targetDir, "scripts/proof-cloudflare-version.mjs", createToolWrapperScript('cloudflare-proof'));
174
179
  (0, external_fs_io_cjs_namespaceObject.writeFileReplacing)(targetDir, "scripts/ultramodern-performance-readiness.config.mjs", createPerformanceReadinessConfigScript());
@@ -177,11 +182,13 @@ function writeGeneratedWorkspaceScripts(targetDir, _scope, _enableTailwind, _rem
177
182
  (0, external_fs_io_cjs_namespaceObject.writeFileReplacing)(targetDir, "scripts/bootstrap-agent-skills.mjs", createSkillsToolWrapperScript());
178
183
  }
179
184
  exports.createPerformanceReadinessConfigScript = __webpack_exports__.createPerformanceReadinessConfigScript;
185
+ exports.createWorkspaceApiBoundaryValidationScript = __webpack_exports__.createWorkspaceApiBoundaryValidationScript;
180
186
  exports.createWorkspaceI18nBoundaryValidationScript = __webpack_exports__.createWorkspaceI18nBoundaryValidationScript;
181
187
  exports.createWorkspaceValidationScript = __webpack_exports__.createWorkspaceValidationScript;
182
188
  exports.writeGeneratedWorkspaceScripts = __webpack_exports__.writeGeneratedWorkspaceScripts;
183
189
  for(var __rspack_i in __webpack_exports__)if (-1 === [
184
190
  "createPerformanceReadinessConfigScript",
191
+ "createWorkspaceApiBoundaryValidationScript",
185
192
  "createWorkspaceI18nBoundaryValidationScript",
186
193
  "createWorkspaceValidationScript",
187
194
  "writeGeneratedWorkspaceScripts"
@@ -95,12 +95,12 @@ function writeApp(targetDir, scope, app, packageSource, enableTailwind, remotes
95
95
  if ('shell' === resolvedApp.kind) {
96
96
  writeAppFile('src/routes/vertical-components.tsx', (0, external_demo_components_cjs_namespaceObject.createShellRemoteComponents)(scope, remotes));
97
97
  writeAppFile('src/routes/shell-frame.tsx', (0, external_app_files_cjs_namespaceObject.createShellFrameComponent)());
98
- (0, external_fs_io_cjs_namespaceObject.writeFile)(targetDir, `${resolvedApp.directory}/src/effect/vertical-clients.ts`, (0, external_effect_api_cjs_namespaceObject.createShellEffectClient)(scope, remotes));
98
+ (0, external_fs_io_cjs_namespaceObject.writeFile)(targetDir, `${resolvedApp.directory}/src/api/vertical-clients.ts`, (0, external_effect_api_cjs_namespaceObject.createShellEffectClient)(scope, remotes));
99
99
  }
100
100
  if ((0, external_descriptors_cjs_namespaceObject.appHasEffectApi)(resolvedApp)) {
101
- (0, external_fs_io_cjs_namespaceObject.writeFile)(targetDir, `${resolvedApp.directory}/shared/effect/api.ts`, (0, external_effect_api_cjs_namespaceObject.createEffectSharedApi)(resolvedApp));
102
- (0, external_fs_io_cjs_namespaceObject.writeFile)(targetDir, `${resolvedApp.directory}/api/effect/index.ts`, (0, external_effect_api_cjs_namespaceObject.createEffectServiceEntry)(resolvedApp, '../../shared/effect/api.ts'));
103
- (0, external_fs_io_cjs_namespaceObject.writeFile)(targetDir, `${resolvedApp.directory}/src/effect/${resolvedApp.effectApi.stem}-client.ts`, (0, external_effect_api_cjs_namespaceObject.createEffectClient)(resolvedApp, '../../shared/effect/api'));
101
+ (0, external_fs_io_cjs_namespaceObject.writeFile)(targetDir, `${resolvedApp.directory}/shared/api.ts`, (0, external_effect_api_cjs_namespaceObject.createEffectSharedApi)(resolvedApp));
102
+ (0, external_fs_io_cjs_namespaceObject.writeFile)(targetDir, `${resolvedApp.directory}/api/index.ts`, (0, external_effect_api_cjs_namespaceObject.createEffectServiceEntry)(resolvedApp, '../shared/api.ts'));
103
+ (0, external_fs_io_cjs_namespaceObject.writeFile)(targetDir, `${resolvedApp.directory}/src/api/${resolvedApp.effectApi.stem}-client.ts`, (0, external_effect_api_cjs_namespaceObject.createEffectClient)(resolvedApp, '../../shared/api'));
104
104
  }
105
105
  if ('vertical' === resolvedApp.kind) {
106
106
  writeAppFile('src/federation-entry.tsx', (0, external_demo_components_cjs_namespaceObject.createRemoteEntry)(resolvedApp));
package/dist/esm/index.js CHANGED
@@ -184,7 +184,7 @@ function detectBffRuntime(args) {
184
184
  process.exit(1);
185
185
  }
186
186
  if (!SUPPORTED_BFF_RUNTIMES.includes(runtime)) {
187
- console.error(`Unsupported BFF runtime "${runtime}". UltraModern workspaces scaffold an Effect BFF for every MicroVertical (supported: ${SUPPORTED_BFF_RUNTIMES.join(', ')}).`);
187
+ console.error(`Unsupported BFF runtime "${runtime}". UltraModern workspaces scaffold a strict Effect API runtime for every MicroVertical (supported: ${SUPPORTED_BFF_RUNTIMES.join(', ')}).`);
188
188
  process.exit(1);
189
189
  }
190
190
  return runtime;
@@ -18,7 +18,7 @@ const EN_LOCALE = {
18
18
  step1: 'cd {projectName}',
19
19
  step2: 'pnpm install',
20
20
  step3: 'pnpm dev',
21
- legacyModernJsWarning: "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\nBRUTAL WARNING: YOU ARE OPTING OUT OF ULTRAMODERN.JS DEFAULTS.\nThe unattended default is the best UltraModern.js configuration:\na structured SuperApp workspace, presetUltramodern, TanStack Router,\nEffect BFF, Tailwind CSS v4, and the BleedingDev package cohort.\nThe original Modern.js setup is a dangerous opt-in path.\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
21
+ legacyModernJsWarning: "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\nBRUTAL WARNING: YOU ARE OPTING OUT OF ULTRAMODERN.JS DEFAULTS.\nThe unattended default is the best UltraModern.js configuration:\na structured SuperApp workspace, presetUltramodern, TanStack Router,\na strict Effect API runtime, Tailwind CSS v4, and the BleedingDev package cohort.\nThe original Modern.js setup is a dangerous opt-in path.\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
22
22
  },
23
23
  help: {
24
24
  title: '🚀 UltraModern.js Project Creator',
@@ -30,7 +30,7 @@ const EN_LOCALE = {
30
30
  optionVersion: ' -v, --version Display version information',
31
31
  optionLang: ' -l, --lang Set the language (en default; zh opt-in)',
32
32
  optionTailwind: ' --no-tailwind Disable default Tailwind CSS v4 workspace styling',
33
- optionBff: ' --bff Keep the default Effect BFF scaffolding (every MicroVertical ships an Effect BFF)',
33
+ optionBff: ' --bff Keep the default strict Effect API runtime (every MicroVertical ships one)',
34
34
  optionBffRuntime: ' --bff-runtime Select the BFF runtime for scaffolded MicroVerticals (supported: effect; default: effect)',
35
35
  optionWorkspace: ' --workspace Use workspace protocol for @modern-js dependencies (for local monorepo testing)',
36
36
  optionUltramodernPackageSource: ' --ultramodern-package-source Select UltraModern package source (workspace or install; BleedingDev defaults to install aliases)',