@bleedingdev/modern-js-create 3.4.0-ultramodern.3 → 3.4.0-ultramodern.4

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.
@@ -149,7 +149,7 @@ const createRemoteFallback = (specifier: string) =>
149
149
  remote: specifier,
150
150
  status: 'degraded',
151
151
  });
152
- }, [classification, error, specifier, telemetry]);
152
+ }, [classification, error, telemetry]);
153
153
 
154
154
  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>;
155
155
  };
@@ -88,27 +88,51 @@ function serviceHasCheckoutCartState(service) {
88
88
  function createCheckoutCartSharedSchemas(service) {
89
89
  if (!serviceHasCheckoutCartState(service)) return '';
90
90
  return `
91
- export const checkoutCartLineSchema = Schema.Struct({
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: ReadonlyArray<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.Schema<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.Schema<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.Schema<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.Schema<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 const ${markerSchemaExport} = Schema.Struct({
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: ReadonlyArray<${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.Schema<${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.Schema<${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.Schema<${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.Schema<${createPayloadType}> = Schema.Struct({
390
466
  title: Schema.String,
391
467
  });
392
468
 
393
- ${checkoutCartSharedSchemaSection}export class ${notFoundErrorExport} extends Schema.TaggedErrorClass<${notFoundErrorExport}>()(
394
- '${notFoundErrorExport}',
395
- {
396
- id: Schema.String,
397
- },
398
- ) {}
399
-
400
- export const ${notFoundSchemaExport} = ${notFoundErrorExport}.pipe(
469
+ ${checkoutCartSharedSchemaSection}export const ${notFoundSchemaExport}: Schema.Schema<${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';
575
+ import type {
576
+ EffectBffDefinition,
577
+ EffectBffRuntime,
578
+ EffectRuntimeLayer,
579
+ } from '@modern-js/plugin-bff/effect-edge';
504
580
  import { ultramodernApiMarker } from '../../src/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(new ${notFoundErrorExport}({ id: params.id }))
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
- export default defineEffectBff({
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 { OperationContext } from '${contractImportPath}';
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:
@@ -267,12 +267,12 @@ ${bffPluginEntry} moduleFederationPlugin(),
267
267
  }
268
268
  function createSharedModuleFederationConfig() {
269
269
  return ` shared: {
270
- '@modern-js/plugin-i18n/runtime/no-react-i18next': {
270
+ '@modern-js/plugin-i18n/runtime': {
271
271
  requiredVersion: pluginI18nVersion,
272
272
  singleton: true,
273
273
  treeShaking: false,
274
274
  },
275
- '@modern-js/plugin-i18n/runtime': {
275
+ '@modern-js/plugin-i18n/runtime/no-react-i18next': {
276
276
  requiredVersion: pluginI18nVersion,
277
277
  singleton: true,
278
278
  treeShaking: false,
@@ -392,7 +392,9 @@ const reactVersion = (require('react/package.json') as { version: string }).vers
392
392
  const reactDomVersion = (require('react-dom/package.json') as { version: string }).version;
393
393
 
394
394
  ${createModuleFederationRemoteUrlHelpers(shellHost, remotes)}
395
- export default createModuleFederationConfig({
395
+ const moduleFederationConfig: Parameters<
396
+ typeof createModuleFederationConfig
397
+ >[0] = createModuleFederationConfig({
396
398
  bridge: {
397
399
  enableBridgeRouter: false,
398
400
  },
@@ -410,6 +412,8 @@ export default createModuleFederationConfig({
410
412
  ${createModuleFederationRemotesConfig(scope, shellHost, remotes)}${createSharedModuleFederationConfig()},
411
413
  treeShakingSharedExcludePlugins: ['RspackModuleFederationPlugin'],
412
414
  });
415
+
416
+ export default moduleFederationConfig;
413
417
  `;
414
418
  }
415
419
  function createBuildMarker(scope, app) {
@@ -450,7 +454,9 @@ const reactVersion = (require('react/package.json') as { version: string }).vers
450
454
  const reactDomVersion = (require('react-dom/package.json') as { version: string }).version;
451
455
 
452
456
  ${createModuleFederationRemoteUrlHelpers(app, remotes)}
453
- export default createModuleFederationConfig({
457
+ const moduleFederationConfig: Parameters<
458
+ typeof createModuleFederationConfig
459
+ >[0] = createModuleFederationConfig({
454
460
  bridge: {
455
461
  enableBridgeRouter: false,
456
462
  },
@@ -469,6 +475,8 @@ export default createModuleFederationConfig({
469
475
  ${createModuleFederationRemotesConfig(scope, app, remotes)}${createSharedModuleFederationConfig()},
470
476
  treeShakingSharedExcludePlugins: ['RspackModuleFederationPlugin'],
471
477
  });
478
+
479
+ export default moduleFederationConfig;
472
480
  `;
473
481
  }
474
482
  exports.createAppModernConfig = __webpack_exports__.createAppModernConfig;
@@ -300,6 +300,10 @@ function createTsBuildInfoFile(packageDir) {
300
300
  const cacheKey = packageDir.replace(/[^a-zA-Z0-9._-]+/gu, '__');
301
301
  return `${(0, external_naming_cjs_namespaceObject.relativeRootFor)(packageDir)}/node_modules/.cache/tsgo/${cacheKey}.tsbuildinfo`;
302
302
  }
303
+ function createTsDeclarationOutDir(packageDir) {
304
+ const cacheKey = packageDir.replace(/[^a-zA-Z0-9._-]+/gu, '__');
305
+ return `${(0, external_naming_cjs_namespaceObject.relativeRootFor)(packageDir)}/node_modules/.cache/tsgo/declarations/${cacheKey}`;
306
+ }
303
307
  function createReferences(packageDir, references) {
304
308
  return [
305
309
  ...new Set(references)
@@ -313,8 +317,10 @@ function createPackageTsConfig(packageDir, options = {}) {
313
317
  } : options;
314
318
  const include = resolvedOptions.include ?? [
315
319
  'src',
320
+ 'locales/**/*.json',
316
321
  'modern.config.ts',
317
- 'module-federation.config.ts'
322
+ 'module-federation.config.ts',
323
+ 'package.json'
318
324
  ];
319
325
  if (resolvedOptions.includeApi) include.push('api', 'shared');
320
326
  const references = createReferences(packageDir, resolvedOptions.references ?? []);
@@ -322,7 +328,12 @@ function createPackageTsConfig(packageDir, options = {}) {
322
328
  extends: `${(0, external_naming_cjs_namespaceObject.relativeRootFor)(packageDir)}/tsconfig.base.json`,
323
329
  compilerOptions: {
324
330
  composite: true,
331
+ declaration: true,
332
+ declarationMap: false,
333
+ emitDeclarationOnly: true,
325
334
  incremental: true,
335
+ noEmit: false,
336
+ outDir: createTsDeclarationOutDir(packageDir),
326
337
  tsBuildInfoFile: createTsBuildInfoFile(packageDir)
327
338
  },
328
339
  include
@@ -110,7 +110,7 @@ const createRemoteFallback = (specifier: string) =>
110
110
  remote: specifier,
111
111
  status: 'degraded',
112
112
  });
113
- }, [classification, error, specifier, telemetry]);
113
+ }, [classification, error, telemetry]);
114
114
 
115
115
  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>;
116
116
  };