@rxap/plugin-angular 16.2.0-dev.1 → 16.2.0-dev.11

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 (40) hide show
  1. package/CHANGELOG.md +95 -0
  2. package/README.md +1 -1
  3. package/package.json +27 -28
  4. package/src/generators/fix-schematic/generator.js +3 -4
  5. package/src/generators/fix-schematic/generator.js.map +1 -1
  6. package/src/generators/init/generator.js +34 -32
  7. package/src/generators/init/generator.js.map +1 -1
  8. package/src/generators/init-application/coerce-project.d.ts +4 -0
  9. package/src/generators/init-application/coerce-project.js +54 -0
  10. package/src/generators/init-application/coerce-project.js.map +1 -0
  11. package/src/generators/init-application/files/mfe-remote/Dockerfile +29 -0
  12. package/src/generators/init-application/files/mfe-remote/index.html.template +165 -0
  13. package/src/generators/init-application/files/root/favicon.ico +0 -0
  14. package/src/generators/init-application/files/root/styles.scss.template +3 -0
  15. package/src/generators/init-application/files/shared/Dockerfile +1 -1
  16. package/src/generators/init-application/files/shared/ngsw-config.json +11 -1
  17. package/src/generators/init-application/files/styles/_fonts.scss +2 -0
  18. package/src/generators/init-application/generate-authentication.js +5 -0
  19. package/src/generators/init-application/generate-authentication.js.map +1 -1
  20. package/src/generators/init-application/generate-monolithic.js +1 -7
  21. package/src/generators/init-application/generate-monolithic.js.map +1 -1
  22. package/src/generators/init-application/generator.js +319 -93
  23. package/src/generators/init-application/generator.js.map +1 -1
  24. package/src/generators/init-application/schema.d.ts +7 -0
  25. package/src/generators/init-application/schema.json +26 -0
  26. package/src/generators/init-feature/generator.js +18 -4
  27. package/src/generators/init-feature/generator.js.map +1 -1
  28. package/src/generators/init-feature/schema.d.ts +7 -0
  29. package/src/generators/init-feature/schema.json +54 -0
  30. package/src/generators/init-library/generator.js +102 -31
  31. package/src/generators/init-library/generator.js.map +1 -1
  32. package/src/generators/init-library/schema.d.ts +6 -1
  33. package/src/generators/init-library/schema.json +170 -5
  34. package/src/generators/schematic/generator.js +1 -2
  35. package/src/generators/schematic/generator.js.map +1 -1
  36. package/src/lib/skip-project.d.ts +0 -3
  37. package/src/lib/skip-project.js +0 -19
  38. package/src/lib/skip-project.js.map +0 -1
  39. /package/src/generators/init-application/files/{monolithic → mfe-remote}/styles.scss.template +0 -0
  40. /package/src/generators/init-application/files/{monolithic → root}/index.html.template +0 -0
@@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.initApplicationGenerator = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const devkit_1 = require("@nx/devkit");
6
- const generator_utilities_1 = require("@rxap/generator-utilities");
7
6
  const plugin_application_1 = require("@rxap/plugin-application");
8
7
  const plugin_docker_1 = require("@rxap/plugin-docker");
9
8
  const plugin_localazy_1 = require("@rxap/plugin-localazy");
@@ -13,14 +12,14 @@ const workspace_ts_morph_1 = require("@rxap/workspace-ts-morph");
13
12
  const workspace_utilities_1 = require("@rxap/workspace-utilities");
14
13
  const path_1 = require("path");
15
14
  const ts_morph_2 = require("ts-morph");
16
- const skip_project_1 = require("../../lib/skip-project");
15
+ const coerce_project_1 = require("./coerce-project");
17
16
  const generate_authentication_1 = require("./generate-authentication");
18
17
  const generate_monolithic_1 = require("./generate-monolithic");
19
18
  function skipProject(tree, options, project, projectName) {
20
- if ((0, skip_project_1.SkipNonAngularProject)(tree, options, project, projectName)) {
19
+ if ((0, workspace_utilities_1.SkipNonAngularProject)(tree, options, project, projectName)) {
21
20
  return true;
22
21
  }
23
- if ((0, generator_utilities_1.SkipNonApplicationProject)(tree, options, project, projectName)) {
22
+ if ((0, workspace_utilities_1.SkipNonApplicationProject)(tree, options, project, projectName)) {
24
23
  return true;
25
24
  }
26
25
  return false;
@@ -34,7 +33,7 @@ function updateProjectTargets(project, options) {
34
33
  }
35
34
  if (project.targets['docker']) {
36
35
  (_b = (_z = project.targets['docker']).options) !== null && _b !== void 0 ? _b : (_z.options = {});
37
- (_c = (_0 = project.targets['docker'].options).dockerfile) !== null && _c !== void 0 ? _c : (_0.dockerfile = 'shared/angular/Dockerfile');
36
+ (_c = (_0 = project.targets['docker'].options).dockerfile) !== null && _c !== void 0 ? _c : (_0.dockerfile = options.moduleFederation === 'remote' ? (0, path_1.join)(project.sourceRoot, 'Dockerfile') : 'shared/angular/Dockerfile');
38
37
  }
39
38
  (0, workspace_utilities_1.CoerceTarget)(project, 'serve', {
40
39
  options: {
@@ -108,10 +107,12 @@ function updateProjectTargets(project, options) {
108
107
  project.targets['build'].options.sourceMap = true;
109
108
  (_q = (_10 = project.targets['build'].options).assets) !== null && _q !== void 0 ? _q : (_10.assets = []);
110
109
  (_r = (_11 = project.targets['build'].options).scripts) !== null && _r !== void 0 ? _r : (_11.scripts = []);
111
- if (!project.targets['build'].options.scripts.includes('node_modules/marked/marked.min.js')) {
112
- project.targets['build'].options.scripts.push('node_modules/marked/marked.min.js');
110
+ if (options.moduleFederation !== 'remote') {
111
+ if (!project.targets['build'].options.scripts.includes('node_modules/marked/marked.min.js')) {
112
+ project.targets['build'].options.scripts.push('node_modules/marked/marked.min.js');
113
+ }
113
114
  }
114
- (0, generator_utilities_1.CoerceAssets)(project.targets['build'].options.assets, [
115
+ (0, workspace_utilities_1.CoerceAssets)(project.targets['build'].options.assets, [
115
116
  {
116
117
  glob: '*',
117
118
  input: 'shared/angular/assets/',
@@ -130,12 +131,12 @@ function updateProjectTargets(project, options) {
130
131
  project.targets['build'].options.polyfills = ['zone.js'];
131
132
  }
132
133
  // always add the localize init polyfill as some rxap components use the i18n directive
133
- (0, generator_utilities_1.CoerceAssets)(project.targets['build'].options.polyfills, ['@angular/localize/init']);
134
+ (0, workspace_utilities_1.CoerceAssets)(project.targets['build'].options.polyfills, ['@angular/localize/init']);
134
135
  if (options.serviceWorker) {
135
136
  if (!project.sourceRoot) {
136
137
  throw new Error(`The project ${project.name} has no source root`);
137
138
  }
138
- (0, generator_utilities_1.CoerceAssets)(project.targets['build'].options.assets, [
139
+ (0, workspace_utilities_1.CoerceAssets)(project.targets['build'].options.assets, [
139
140
  (0, path_1.join)(project.sourceRoot, 'manifest.webmanifest'),
140
141
  ]);
141
142
  (_t = (_13 = project.targets['build']).configurations) !== null && _t !== void 0 ? _t : (_13.configurations = {});
@@ -238,7 +239,7 @@ function updateGitIgnore(project, tree, options) {
238
239
  throw new Error(`The project ${project.name} has no source root`);
239
240
  }
240
241
  const gitIgnorePath = (0, path_1.join)(project.sourceRoot, '.gitignore');
241
- (0, generator_utilities_1.CoerceIgnorePattern)(tree, gitIgnorePath, [
242
+ (0, workspace_utilities_1.CoerceIgnorePattern)(tree, gitIgnorePath, [
242
243
  '/i18n',
243
244
  ]);
244
245
  }
@@ -257,7 +258,7 @@ function updateTags(project, options) {
257
258
  if (options.sentry) {
258
259
  tags.push('sentry');
259
260
  }
260
- (0, generator_utilities_1.CoerceProjectTags)(project, tags);
261
+ (0, workspace_utilities_1.CoerceProjectTags)(project, tags);
261
262
  }
262
263
  const MAIN_BOOTSTRAP_STATEMENT = `application.bootstrap().catch((err) => console.error(err));`;
263
264
  const MAIN_LOGGER_STATEMENT = `application.importProvidersFrom(LoggerModule.forRoot({
@@ -270,7 +271,12 @@ const MAIN_APP_CREATION_STATEMENT = `const application = new StandaloneApplicati
270
271
  AppComponent,
271
272
  appConfig,
272
273
  );`;
273
- function assertMainStatements(sourceFile) {
274
+ const REMOTE_MAIN_APP_CREATION_STATEMENT = `const application = new StandaloneApplication(
275
+ environment,
276
+ RemoteEntryComponent,
277
+ appConfig,
278
+ );`;
279
+ function assertMainStatements(sourceFile, options) {
274
280
  var _a;
275
281
  const statements = [];
276
282
  statements.push('const application = new StandaloneApplication(');
@@ -281,16 +287,12 @@ function assertMainStatements(sourceFile) {
281
287
  console.error(`Missing statement from angular main.ts: ${statement}`);
282
288
  sourceFile.set({
283
289
  statements: [
284
- MAIN_APP_CREATION_STATEMENT,
290
+ options.moduleFederation === 'remote' ? REMOTE_MAIN_APP_CREATION_STATEMENT : MAIN_APP_CREATION_STATEMENT,
285
291
  MAIN_LOGGER_STATEMENT,
286
292
  MAIN_BOOTSTRAP_STATEMENT,
287
293
  ],
288
294
  });
289
295
  (0, ts_morph_1.CoerceImports)(sourceFile, [
290
- {
291
- moduleSpecifier: './app/app.component',
292
- namedImports: ['AppComponent'],
293
- },
294
296
  {
295
297
  moduleSpecifier: './app/app.config',
296
298
  namedImports: ['appConfig'],
@@ -308,37 +310,119 @@ function assertMainStatements(sourceFile) {
308
310
  namedImports: ['StandaloneApplication'],
309
311
  },
310
312
  ]);
313
+ if (options.moduleFederation === 'remote') {
314
+ (0, ts_morph_1.CoerceImports)(sourceFile, [
315
+ {
316
+ moduleSpecifier: './app/remote-entry/entry.component',
317
+ namedImports: ['RemoteEntryComponent'],
318
+ },
319
+ ]);
320
+ }
321
+ else {
322
+ (0, ts_morph_1.CoerceImports)(sourceFile, [
323
+ {
324
+ moduleSpecifier: './app/app.component',
325
+ namedImports: ['AppComponent'],
326
+ },
327
+ ]);
328
+ }
311
329
  return;
312
330
  }
313
331
  }
314
332
  }
315
- function cleanup(tree, projectSourceRoot) {
333
+ function cleanup(tree, projectName, options) {
334
+ const sourceRoot = (0, workspace_utilities_1.GetProjectSourceRoot)(tree, projectName);
316
335
  const deleteFiles = [
317
336
  'app/app.component.spec.ts',
318
337
  'app/nx-welcome.component.ts',
338
+ 'app/remote-entry/nx-welcome.component.ts',
319
339
  'app/nx-welcome.component.cy.ts',
320
340
  ];
321
341
  for (const file of deleteFiles) {
322
- if (tree.exists((0, path_1.join)(projectSourceRoot, file))) {
323
- tree.delete((0, path_1.join)(projectSourceRoot, file));
324
- }
325
- }
326
- let content = tree.read((0, path_1.join)(projectSourceRoot, 'app/app.component.ts'), 'utf-8')
327
- .replace('title = \'domain-product\';', '')
328
- .replace('import { NxWelcomeComponent } from \'./nx-welcome.component\';', '')
329
- .replace('NxWelcomeComponent, ', '');
330
- tree.write((0, path_1.join)(projectSourceRoot, 'app/app.component.ts'), content);
331
- content = tree.read((0, path_1.join)(projectSourceRoot, 'app/app.component.html'), 'utf-8')
332
- .replace(/<.+-nx-welcome><\/.+-nx-welcome> /, '');
333
- tree.write((0, path_1.join)(projectSourceRoot, 'app/app.component.html'), content);
342
+ if (tree.exists((0, path_1.join)(sourceRoot, file))) {
343
+ tree.delete((0, path_1.join)(sourceRoot, file));
344
+ }
345
+ }
346
+ if (tree.exists((0, path_1.join)(sourceRoot, 'app/app.component.html'))) {
347
+ const content = tree.read((0, path_1.join)(sourceRoot, 'app/app.component.html'), 'utf-8')
348
+ .replace(/<.+-nx-welcome><\/.+-nx-welcome> /, '')
349
+ .replace(/<ul class="remote-menu">[\s\S]*<\/ul>/, '');
350
+ tree.write((0, path_1.join)(sourceRoot, 'app/app.component.html'), content);
351
+ }
352
+ if (options.moduleFederation !== 'remote') {
353
+ (0, workspace_ts_morph_1.TsMorphAngularProjectTransform)(tree, {
354
+ project: projectName,
355
+ }, (_, [appRoutes, appComponent]) => {
356
+ var _a, _b, _c;
357
+ (0, ts_morph_1.RemoveRoute)(appRoutes, {
358
+ component: 'NxWelcomeComponent',
359
+ name: 'appRoutes'
360
+ });
361
+ (_a = appRoutes.getImportDeclaration('./nx-welcome.component')) === null || _a === void 0 ? void 0 : _a.remove();
362
+ (_c = (_b = appComponent.getClass('AppComponent')) === null || _b === void 0 ? void 0 : _b.getProperty('title')) === null || _c === void 0 ? void 0 : _c.remove();
363
+ (0, ts_morph_1.RemoveComponentImport)(appComponent, 'NxWelcomeComponent');
364
+ }, ['app/app.routes.ts', 'app/app.component.ts']);
365
+ }
366
+ if (options.moduleFederation === 'remote') {
367
+ // region module-federation config
368
+ const projectRoot = (0, workspace_utilities_1.GetProjectRoot)(tree, projectName);
369
+ let content = tree.read((0, path_1.join)(projectRoot, 'module-federation.config.js'), 'utf-8');
370
+ content = content.replace('./Routes', './routes');
371
+ tree.write((0, path_1.join)(projectRoot, 'module-federation.config.js'), content);
372
+ // endregion
373
+ // region tsconfig.base.json
374
+ (0, workspace_utilities_1.UpdateTsConfigJson)(tree, tsConfig => {
375
+ var _a, _b;
376
+ var _c;
377
+ (_a = tsConfig.compilerOptions) !== null && _a !== void 0 ? _a : (tsConfig.compilerOptions = {});
378
+ (_b = (_c = tsConfig.compilerOptions).paths) !== null && _b !== void 0 ? _b : (_c.paths = {});
379
+ if (tsConfig.compilerOptions.paths[`${projectName}/Routes`]) {
380
+ delete tsConfig.compilerOptions.paths[`${projectName}/Routes`];
381
+ }
382
+ }, { infix: 'base' });
383
+ // endregion
384
+ (0, workspace_ts_morph_1.TsMorphAngularProjectTransform)(tree, {
385
+ project: projectName,
386
+ }, (_, [entryComponent, entryRoutes]) => {
387
+ var _a, _b;
388
+ (_a = entryComponent.getImportDeclaration('./nx-welcome.component')) === null || _a === void 0 ? void 0 : _a.remove();
389
+ (0, ts_morph_1.RemoveComponentImport)(entryComponent, 'NxWelcomeComponent');
390
+ (0, ts_morph_1.RemoveComponentImport)(entryComponent, 'CommonModule');
391
+ const componentOptions = (0, ts_morph_1.GetComponentDecoratorObject)(entryComponent);
392
+ const templateProp = componentOptions.getProperty('template');
393
+ if (templateProp && ((_b = templateProp.asKindOrThrow(ts_morph_2.SyntaxKind.PropertyAssignment).getInitializer()) === null || _b === void 0 ? void 0 : _b.getText().match(/<.+nx-welcome><\/.+nx-welcome>/))) {
394
+ templateProp.remove();
395
+ componentOptions.addPropertyAssignment({
396
+ name: 'template',
397
+ initializer: w => w.quote('<router-outlet></router-outlet>'),
398
+ });
399
+ (0, ts_morph_1.CoerceComponentImport)(entryComponent, { name: 'RouterModule', moduleSpecifier: '@angular/router' });
400
+ }
401
+ (0, ts_morph_1.CoerceDefaultExport)(entryRoutes.getVariableStatement('remoteRoutes').getDeclarations()[0]);
402
+ }, [
403
+ 'app/remote-entry/entry.component.ts',
404
+ 'app/remote-entry/entry.routes.ts',
405
+ ]);
406
+ if (options.host) {
407
+ (0, workspace_ts_morph_1.TsMorphAngularProjectTransform)(tree, {
408
+ project: options.host,
409
+ }, (_, [appRoutes]) => {
410
+ (0, ts_morph_1.RemoveRoute)(appRoutes, {
411
+ loadRemoteModule: projectName,
412
+ name: 'appRoutes'
413
+ });
414
+ appRoutes.organizeImports();
415
+ }, ['app/app.routes.ts']);
416
+ }
417
+ }
334
418
  }
335
419
  function updateMainFile(tree, projectName, project, options) {
336
420
  (0, workspace_ts_morph_1.TsMorphAngularProjectTransform)(tree, {
337
421
  project: projectName,
338
422
  // directory: '..' // to move from the apps/demo/src/app folder into the apps/demo/src folder
339
- }, (project, [sourceFile]) => {
423
+ }, (project, [sourceFile, mainSourceFile]) => {
340
424
  var _a;
341
- assertMainStatements(sourceFile);
425
+ assertMainStatements(sourceFile, options);
342
426
  const importDeclarations = [];
343
427
  const statements = [];
344
428
  if (options.serviceWorker) {
@@ -388,10 +472,51 @@ function updateMainFile(tree, projectName, project, options) {
388
472
  sourceFile.insertStatements(index, statement);
389
473
  }
390
474
  }
391
- }, ['main.ts']);
475
+ if (options.moduleFederation === 'host') {
476
+ mainSourceFile.set({
477
+ statements: [
478
+ `import {
479
+ setRemoteDefinitions,
480
+ setRemoteUrlResolver
481
+ } from '@nx/angular/mf';
482
+ import type { Environment } from '@rxap/environment';
483
+ import { environment } from './environments/environment';
484
+
485
+ export async function SetupDynamicMfe(environment: Environment) {
486
+
487
+ const manifest = environment.moduleFederation?.manifest;
488
+
489
+ if (!manifest) {
490
+ const release = environment.tag || environment.branch || 'latest';
491
+ setRemoteUrlResolver((remoteName: string) => \`\${ location.origin }/__mfe/\${ release }/\${ remoteName }\`);
492
+ } else {
493
+
494
+ let definitions: Record<string, string>;
495
+
496
+ if (typeof manifest === 'object') {
497
+ definitions = manifest;
498
+ } else {
499
+ definitions = await fetch(manifest).then((res) => res.json());
500
+ }
501
+
502
+ setRemoteDefinitions(definitions);
503
+
504
+ }
505
+
506
+ }
507
+
508
+ SetupDynamicMfe(environment).then(() => import('./bootstrap').catch((err) => console.error(err)));
509
+ `,
510
+ ]
511
+ });
512
+ }
513
+ }, [
514
+ options.moduleFederation ? 'bootstrap.ts' : 'main.ts',
515
+ 'main.ts'
516
+ ]);
392
517
  }
393
518
  function coerceEnvironmentFiles(tree, options) {
394
- (0, workspace_ts_morph_1.TsMorphNestProjectTransform)(tree, {
519
+ (0, workspace_ts_morph_1.TsMorphAngularProjectTransform)(tree, {
395
520
  project: options.project,
396
521
  }, (project, [sourceFile, prodSourceFile]) => {
397
522
  (0, ts_morph_1.CoerceImports)(sourceFile, {
@@ -406,14 +531,22 @@ function coerceEnvironmentFiles(tree, options) {
406
531
  name: w => w.quote('development'),
407
532
  production: 'false',
408
533
  app: w => w.quote(options.project),
409
- serviceWorker: 'false',
410
534
  };
535
+ // region dev environment
536
+ if (options.serviceWorker) {
537
+ baseEnvironment['serviceWorker'] = 'false';
538
+ }
411
539
  if (options.sentry) {
412
540
  baseEnvironment['sentry'] = ts_morph_2.Writers.object({
413
541
  enabled: 'false',
414
542
  debug: 'false',
415
543
  });
416
544
  }
545
+ if (options.moduleFederation === 'host') {
546
+ baseEnvironment['moduleFederation'] = ts_morph_2.Writers.object({
547
+ manifest: w => w.quote('/assets/module-federation.manifest.json'),
548
+ });
549
+ }
417
550
  const normal = (0, ts_morph_1.CoerceVariableDeclaration)(sourceFile, 'environment', {
418
551
  type: 'Environment',
419
552
  initializer: ts_morph_2.Writers.object(baseEnvironment),
@@ -421,15 +554,22 @@ function coerceEnvironmentFiles(tree, options) {
421
554
  if (options.overwrite) {
422
555
  normal.set({ initializer: ts_morph_2.Writers.object(baseEnvironment) });
423
556
  }
424
- baseEnvironment['name'] = w => w.quote('production');
425
- baseEnvironment['production'] = 'true';
426
- baseEnvironment['serviceWorker'] = 'true';
557
+ // region
558
+ // region prod environment
559
+ if (options.moduleFederation === 'host') {
560
+ delete baseEnvironment['moduleFederation'];
561
+ }
562
+ if (options.serviceWorker) {
563
+ baseEnvironment['serviceWorker'] = 'true';
564
+ }
427
565
  if (options.sentry) {
428
566
  baseEnvironment['sentry'] = ts_morph_2.Writers.object({
429
567
  enabled: 'true',
430
568
  debug: 'false',
431
569
  });
432
570
  }
571
+ baseEnvironment['name'] = w => w.quote('production');
572
+ baseEnvironment['production'] = 'true';
433
573
  const prod = (0, ts_morph_1.CoerceVariableDeclaration)(prodSourceFile, 'environment', {
434
574
  type: 'Environment',
435
575
  initializer: ts_morph_2.Writers.object(baseEnvironment),
@@ -437,6 +577,7 @@ function coerceEnvironmentFiles(tree, options) {
437
577
  if (options.overwrite) {
438
578
  prod.set({ initializer: ts_morph_2.Writers.object(baseEnvironment) });
439
579
  }
580
+ // endregion
440
581
  }, [
441
582
  '/environments/environment.ts?',
442
583
  '/environments/environment.prod.ts?',
@@ -462,48 +603,99 @@ function coerceLocalazyConfigFile(tree, project) {
462
603
  }, null, 2));
463
604
  }
464
605
  }
465
- function updateTsConfig(tree, project, options) {
466
- return tslib_1.__awaiter(this, void 0, void 0, function* () {
467
- const projectRoot = project.root;
468
- if (options.i18n) {
469
- for (const tsConfigName of ['app', 'editor', 'spec']) {
470
- yield (0, workspace_utilities_1.UpdateJsonFile)(tree, tsConfig => {
471
- var _a, _b;
472
- var _c;
473
- (_a = tsConfig.compilerOptions) !== null && _a !== void 0 ? _a : (tsConfig.compilerOptions = {});
474
- (_b = (_c = tsConfig.compilerOptions).types) !== null && _b !== void 0 ? _b : (_c.types = []);
475
- if (!tsConfig.compilerOptions.types.includes('@angular/localize')) {
476
- tsConfig.compilerOptions.types.push('@angular/localize');
477
- }
478
- }, (0, path_1.join)(projectRoot, `tsconfig.${tsConfigName}.json`));
606
+ function updateTsConfig(tree, projectName) {
607
+ const projectRoot = (0, workspace_utilities_1.GetProjectRoot)(tree, projectName);
608
+ for (const tsConfigName of ['app', 'editor', 'spec']) {
609
+ (0, workspace_utilities_1.UpdateTsConfigJson)(tree, tsConfig => {
610
+ var _a, _b;
611
+ var _c;
612
+ (_a = tsConfig.compilerOptions) !== null && _a !== void 0 ? _a : (tsConfig.compilerOptions = {});
613
+ (_b = (_c = tsConfig.compilerOptions).types) !== null && _b !== void 0 ? _b : (_c.types = []);
614
+ if (!tsConfig.compilerOptions.types.includes('@angular/localize')) {
615
+ tsConfig.compilerOptions.types.push('@angular/localize');
479
616
  }
480
- }
481
- });
617
+ }, { infix: tsConfigName, basePath: projectRoot });
618
+ }
619
+ }
620
+ function linkMfeRemoteWithHost(tree, projectName, options) {
621
+ if (!options.host) {
622
+ throw new Error('The host project must be defined');
623
+ }
624
+ const hostSourceRoot = (0, workspace_utilities_1.GetProjectSourceRoot)(tree, options.host);
625
+ const isHostMonolithic = tree.exists((0, path_1.join)(hostSourceRoot, 'app/layout.routes.ts'));
626
+ const path = projectName.replace('user-interface-', '').replace('feature-', '');
627
+ if (isHostMonolithic) {
628
+ (0, workspace_ts_morph_1.TsMorphAngularProjectTransform)(tree, {
629
+ project: options.host,
630
+ }, (project, [layoutSourceFile]) => {
631
+ (0, ts_morph_1.CoerceLayoutRoutes)(layoutSourceFile, {
632
+ itemList: [
633
+ {
634
+ route: {
635
+ path,
636
+ loadRemoteModule: projectName
637
+ },
638
+ path: ['']
639
+ }
640
+ ]
641
+ });
642
+ }, ['app/layout.routes.ts']);
643
+ }
644
+ else {
645
+ (0, workspace_ts_morph_1.TsMorphAngularProjectTransform)(tree, {
646
+ project: options.host,
647
+ }, (project, [appRoutes]) => {
648
+ (0, ts_morph_1.CoerceAppRoutes)(appRoutes, {
649
+ itemList: [
650
+ {
651
+ route: {
652
+ path,
653
+ loadRemoteModule: projectName
654
+ },
655
+ },
656
+ ],
657
+ });
658
+ }, ['app/app.routes.ts']);
659
+ }
482
660
  }
483
661
  function initApplicationGenerator(tree, options) {
484
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r;
662
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u;
485
663
  return tslib_1.__awaiter(this, void 0, void 0, function* () {
486
- (_a = options.sentry) !== null && _a !== void 0 ? _a : (options.sentry = true);
487
- (_b = options.openApi) !== null && _b !== void 0 ? _b : (options.openApi = false);
488
- (_c = options.config) !== null && _c !== void 0 ? _c : (options.config = true);
489
- (_d = options.localazy) !== null && _d !== void 0 ? _d : (options.localazy = false);
490
- (_e = options.i18n) !== null && _e !== void 0 ? _e : (options.i18n = false);
491
- (_f = options.serviceWorker) !== null && _f !== void 0 ? _f : (options.serviceWorker = false);
492
- (_g = options.languages) !== null && _g !== void 0 ? _g : (options.languages = options.i18n ? ['en'] : []);
493
- (_h = options.material) !== null && _h !== void 0 ? _h : (options.material = true);
494
- (_j = options.generateMain) !== null && _j !== void 0 ? _j : (options.generateMain = false);
495
- (_k = options.overwrite) !== null && _k !== void 0 ? _k : (options.overwrite = false);
496
- (_l = options.monolithic) !== null && _l !== void 0 ? _l : (options.monolithic = false);
664
+ (_a = options.moduleFederation) !== null && _a !== void 0 ? _a : (options.moduleFederation = undefined);
665
+ (_b = options.sentry) !== null && _b !== void 0 ? _b : (options.sentry = true);
666
+ (_c = options.openApi) !== null && _c !== void 0 ? _c : (options.openApi = false);
667
+ (_d = options.config) !== null && _d !== void 0 ? _d : (options.config = true);
668
+ (_e = options.localazy) !== null && _e !== void 0 ? _e : (options.localazy = false);
669
+ (_f = options.i18n) !== null && _f !== void 0 ? _f : (options.i18n = false);
670
+ (_g = options.serviceWorker) !== null && _g !== void 0 ? _g : (options.serviceWorker = false);
671
+ (_h = options.languages) !== null && _h !== void 0 ? _h : (options.languages = options.i18n ? ['en'] : []);
672
+ (_j = options.material) !== null && _j !== void 0 ? _j : (options.material = true);
673
+ (_k = options.generateMain) !== null && _k !== void 0 ? _k : (options.generateMain = false);
674
+ (_l = options.overwrite) !== null && _l !== void 0 ? _l : (options.overwrite = false);
675
+ (_m = options.monolithic) !== null && _m !== void 0 ? _m : (options.monolithic = false);
497
676
  options.openApi = options.openApi || options.monolithic;
498
- (_m = options.authentik) !== null && _m !== void 0 ? _m : (options.authentik = false);
499
- (_o = options.oauth) !== null && _o !== void 0 ? _o : (options.oauth = false);
500
- (_p = options.authentication) !== null && _p !== void 0 ? _p : (options.authentication = false);
677
+ (_o = options.authentik) !== null && _o !== void 0 ? _o : (options.authentik = false);
678
+ (_p = options.oauth) !== null && _p !== void 0 ? _p : (options.oauth = false);
679
+ (_q = options.authentication) !== null && _q !== void 0 ? _q : (options.authentication = false);
501
680
  options.oauth = options.oauth || options.authentik;
502
- (_q = options.project) !== null && _q !== void 0 ? _q : (options.project = undefined);
503
- (_r = options.projects) !== null && _r !== void 0 ? _r : (options.projects = []);
681
+ (_r = options.project) !== null && _r !== void 0 ? _r : (options.project = undefined);
682
+ (_s = options.projects) !== null && _s !== void 0 ? _s : (options.projects = []);
683
+ (_t = options.cleanup) !== null && _t !== void 0 ? _t : (options.cleanup = true);
684
+ (_u = options.host) !== null && _u !== void 0 ? _u : (options.host = undefined);
504
685
  if (options.project) {
505
686
  (0, utilities_1.CoerceArrayItems)(options.projects, [options.project]);
506
687
  }
688
+ if (options.host) {
689
+ options.moduleFederation = 'remote';
690
+ }
691
+ if (options.moduleFederation === 'remote') {
692
+ options.authentication = false;
693
+ options.oauth = false;
694
+ options.authentik = false;
695
+ options.serviceWorker = false;
696
+ options.sentry = false;
697
+ options.monolithic = false;
698
+ }
507
699
  console.log('angular application init generator:', options);
508
700
  yield (0, plugin_application_1.ApplicationInitWorkspace)(tree, options);
509
701
  yield (0, workspace_utilities_1.AddPackageJsonDependency)(tree, '@mdi/angular-material', 'latest', { soft: true });
@@ -526,17 +718,24 @@ function initApplicationGenerator(tree, options) {
526
718
  yield (0, workspace_utilities_1.AddPackageJsonDependency)(tree, '@rxap/pipes', 'latest', { soft: true });
527
719
  yield (0, workspace_utilities_1.AddPackageJsonDependency)(tree, '@rxap/mixin', 'latest', { soft: true });
528
720
  yield (0, workspace_utilities_1.AddPackageJsonDependency)(tree, '@rxap/reflect-metadata', 'latest', { soft: true });
721
+ const angularVersion = '~16.2.0';
722
+ // must always be added as some rxap components use the i18n tag
723
+ yield (0, workspace_utilities_1.AddPackageJsonDependency)(tree, '@angular/localize', angularVersion, { soft: true });
724
+ // must always be added as some rxap components use interfaces from the package
725
+ // TODO : refactor the @rxap/ngx-error and @rxap/ngx-status-check to be independent from the @sentry/angular-ivy package
726
+ yield (0, workspace_utilities_1.AddPackageJsonDependency)(tree, '@sentry/angular-ivy', 'latest', { soft: true });
529
727
  if (options.oauth) {
530
728
  yield (0, workspace_utilities_1.AddPackageJsonDependency)(tree, 'angular-oauth2-oidc', 'latest', { soft: true });
531
729
  yield (0, workspace_utilities_1.AddPackageJsonDependency)(tree, 'angular-oauth2-oidc-jwks', 'latest', { soft: true });
532
730
  yield (0, workspace_utilities_1.AddPackageJsonDependency)(tree, '@rxap/oauth', 'latest', { soft: true });
533
731
  }
534
732
  if (options.material) {
535
- yield (0, workspace_utilities_1.AddPackageJsonDependency)(tree, '@angular/material', 'latest', { soft: true });
536
- yield (0, workspace_utilities_1.AddPackageJsonDependency)(tree, '@angular/cdk', 'latest', { soft: true });
733
+ yield (0, workspace_utilities_1.AddPackageJsonDependency)(tree, '@angular/material', angularVersion, { soft: true });
734
+ yield (0, workspace_utilities_1.AddPackageJsonDependency)(tree, '@angular/cdk', angularVersion, { soft: true });
537
735
  }
538
736
  if (options.serviceWorker) {
539
737
  yield (0, workspace_utilities_1.AddPackageJsonDependency)(tree, '@rxap/service-worker', 'latest', { soft: true });
738
+ yield (0, workspace_utilities_1.AddPackageJsonDependency)(tree, '@angular/service-worker', angularVersion, { soft: true });
540
739
  }
541
740
  if (options.monolithic) {
542
741
  yield (0, workspace_utilities_1.AddPackageJsonDependency)(tree, '@rxap/layout', 'latest', { soft: true });
@@ -561,12 +760,10 @@ function initApplicationGenerator(tree, options) {
561
760
  }
562
761
  if (options.sentry) {
563
762
  yield (0, workspace_utilities_1.AddPackageJsonDependency)(tree, '@rxap/ngx-sentry', 'latest', { soft: true });
564
- yield (0, workspace_utilities_1.AddPackageJsonDependency)(tree, '@sentry/angular-ivy', 'latest', { soft: true });
565
763
  yield (0, workspace_utilities_1.AddPackageJsonDependency)(tree, '@sentry/browser', 'latest', { soft: true });
566
764
  yield (0, workspace_utilities_1.AddPackageJsonDependency)(tree, '@sentry/integrations', 'latest', { soft: true });
567
765
  }
568
766
  if (options.i18n) {
569
- yield (0, workspace_utilities_1.AddPackageJsonDependency)(tree, '@angular/localize', 'latest', { soft: true });
570
767
  yield (0, workspace_utilities_1.AddPackageJsonDependency)(tree, '@rxap/ngx-localize', 'latest', { soft: true });
571
768
  yield (0, workspace_utilities_1.AddPackageJsonDependency)(tree, '@rxap/ngx-user', 'latest', { soft: true });
572
769
  }
@@ -589,6 +786,14 @@ function initApplicationGenerator(tree, options) {
589
786
  target: 'shared/angular',
590
787
  overwrite: options.overwrite,
591
788
  });
789
+ if (!tree.exists('shared/angular/assets/custom.svg')) {
790
+ tree.write('shared/angular/assets/custom.svg', '<svg></svg>');
791
+ }
792
+ if (options.i18n) {
793
+ let dockerfileContent = tree.read('shared/angular/Dockerfile', 'utf-8');
794
+ dockerfileContent = dockerfileContent.replace('registry.gitlab.com/rxap/docker/nginx:', 'registry.gitlab.com/rxap/docker/i18n-nginx:');
795
+ tree.write('shared/angular/Dockerfile', dockerfileContent);
796
+ }
592
797
  (0, workspace_utilities_1.CoerceFilesStructure)(tree, {
593
798
  srcFolder: (0, path_1.join)(__dirname, 'files', 'styles'),
594
799
  target: 'shared/angular/styles',
@@ -602,23 +807,28 @@ function initApplicationGenerator(tree, options) {
602
807
  });
603
808
  }
604
809
  updateTargetDefaults(tree, options);
810
+ yield (0, coerce_project_1.CoerceProjects)(tree, options);
605
811
  if (!options.skipProjects) {
606
812
  for (const [projectName, project] of (0, devkit_1.getProjects)(tree).entries()) {
607
813
  if (skipProject(tree, options, project, projectName)) {
608
814
  continue;
609
815
  }
816
+ (0, workspace_utilities_1.GenerateSerializedSchematicFile)(tree, (0, workspace_utilities_1.GetProjectRoot)(tree, projectName), '@rxap/plugin-angular', 'init-application', (0, utilities_1.DeleteProperties)(options, ['project', 'projects', 'overwrite', 'skipProjects']));
610
817
  console.log(`init angular application project: ${projectName}`);
818
+ const sourceRoot = (0, workspace_utilities_1.GetProjectSourceRoot)(tree, projectName);
611
819
  (0, plugin_application_1.ApplicationInitProject)(tree, projectName, project, options);
820
+ if (options.overwrite) {
821
+ (0, devkit_1.generateFiles)(tree, (0, path_1.join)(__dirname, 'files', 'root'), sourceRoot, Object.assign(Object.assign({}, options), { relativePathToWorkspaceRoot: (0, path_1.relative)(sourceRoot, ''), name: projectName.replace(/^user-interface-/, ''), classify: utilities_1.classify, prefix: (0, workspace_utilities_1.GetProjectPrefix)(tree, projectName, 'rxap') }));
822
+ }
612
823
  updateProjectTargets(project, options);
613
824
  updateTags(project, options);
614
825
  updateGitIgnore(project, tree, options);
615
- yield updateTsConfig(tree, project, options);
616
- coerceEnvironmentFiles(tree, {
617
- project: projectName,
618
- sentry: options.sentry,
619
- overwrite: options.overwrite,
620
- });
621
- (0, workspace_ts_morph_1.TsMorphNestProjectTransform)(tree, {
826
+ updateTsConfig(tree, projectName);
827
+ if (options.cleanup) {
828
+ cleanup(tree, projectName, options);
829
+ }
830
+ coerceEnvironmentFiles(tree, Object.assign(Object.assign({}, options), { project: projectName }));
831
+ (0, workspace_ts_morph_1.TsMorphAngularProjectTransform)(tree, {
622
832
  project: projectName,
623
833
  }, (_, [sourceFile]) => {
624
834
  const providers = [
@@ -718,6 +928,15 @@ function initApplicationGenerator(tree, options) {
718
928
  },
719
929
  ]);
720
930
  }
931
+ if (options.material) {
932
+ providers.push('ProvideIconAssetPath()');
933
+ (0, ts_morph_1.CoerceImports)(sourceFile, [
934
+ {
935
+ moduleSpecifier: '@rxap/icon',
936
+ namedImports: ['ProvideIconAssetPath'],
937
+ },
938
+ ]);
939
+ }
721
940
  (0, ts_morph_1.CoerceAppConfigProvider)(sourceFile, {
722
941
  overwrite: options.overwrite,
723
942
  providers,
@@ -728,12 +947,6 @@ function initApplicationGenerator(tree, options) {
728
947
  if (options.generateMain) {
729
948
  updateMainFile(tree, projectName, project, options);
730
949
  }
731
- if (!project.sourceRoot) {
732
- throw new Error(`Project source root not found for project ${projectName}`);
733
- }
734
- if (options.cleanup) {
735
- cleanup(tree, project.sourceRoot);
736
- }
737
950
  if (options.localazy) {
738
951
  coerceLocalazyConfigFile(tree, project);
739
952
  }
@@ -743,22 +956,35 @@ function initApplicationGenerator(tree, options) {
743
956
  if (options.monolithic) {
744
957
  (0, generate_monolithic_1.generateMonolithic)(tree, projectName, project, options);
745
958
  }
959
+ if (options.moduleFederation === 'remote') {
960
+ if (options.overwrite) {
961
+ (0, devkit_1.generateFiles)(tree, (0, path_1.join)(__dirname, 'files', 'mfe-remote'), sourceRoot, Object.assign(Object.assign({}, options), { relativePathToWorkspaceRoot: (0, path_1.relative)(sourceRoot, ''), name: projectName
962
+ .replace(/^user-interface-/, '')
963
+ .replace(/^feature-/, ''), classify: utilities_1.classify,
964
+ dasherize: utilities_1.dasherize, prefix: (0, workspace_utilities_1.GetProjectPrefix)(tree, projectName, 'rxap') }));
965
+ }
966
+ if (options.host) {
967
+ linkMfeRemoteWithHost(tree, projectName, options);
968
+ }
969
+ }
746
970
  if (options.serviceWorker) {
747
- if (options.overwrite || !tree.exists((0, path_1.join)(project.sourceRoot, 'manifest.webmanifest'))) {
748
- (0, devkit_1.generateFiles)(tree, (0, path_1.join)(__dirname, 'files', 'service-worker'), project.sourceRoot, Object.assign(Object.assign({}, options), { name: projectName.replace(/^user-interface-/, ''), classify: utilities_1.classify,
971
+ if (options.overwrite || !tree.exists((0, path_1.join)(sourceRoot, 'manifest.webmanifest'))) {
972
+ (0, devkit_1.generateFiles)(tree, (0, path_1.join)(__dirname, 'files', 'service-worker'), sourceRoot, Object.assign(Object.assign({}, options), { name: projectName.replace(/^user-interface-/, ''), classify: utilities_1.classify,
749
973
  dasherize: utilities_1.dasherize }));
750
974
  }
751
975
  }
752
976
  (0, workspace_utilities_1.CoerceFilesStructure)(tree, {
753
977
  srcFolder: (0, path_1.join)(__dirname, 'files', 'assets'),
754
- target: (0, path_1.join)(project.sourceRoot, 'assets'),
978
+ target: (0, path_1.join)(sourceRoot, 'assets'),
755
979
  overwrite: options.overwrite,
756
980
  });
757
981
  // apply changes to the project configuration
758
982
  (0, devkit_1.updateProjectConfiguration)(tree, projectName, project);
759
983
  }
760
984
  }
761
- yield (0, plugin_localazy_1.LocalazyGitlabCiGenerator)(tree, {});
985
+ if (options.localazy) {
986
+ yield (0, plugin_localazy_1.LocalazyGitlabCiGenerator)(tree, {});
987
+ }
762
988
  yield (0, plugin_docker_1.DockerGitlabCiGenerator)(tree, {});
763
989
  });
764
990
  }