@rxap/plugin-angular 20.0.1-dev.1 → 20.0.1-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 (274) hide show
  1. package/.eslintignore +6 -0
  2. package/.eslintrc.json +44 -0
  3. package/CHANGELOG.md +43 -0
  4. package/LICENSE +621 -0
  5. package/README.md.handlebars +115 -0
  6. package/jest.config.ts +11 -0
  7. package/package.json +11 -24
  8. package/project.json +68 -0
  9. package/schematics.yaml +6 -0
  10. package/src/application.ts +124 -0
  11. package/src/executors/check-ng-package/executor.ts +33 -0
  12. package/src/executors/config/executor.ts +74 -0
  13. package/src/executors/i18n/executor.ts +198 -0
  14. package/src/executors/tailwind/executor.ts +34 -0
  15. package/src/generators/convert-to-buildable-library/generator.ts +110 -0
  16. package/src/generators/fix-schematic/generator.ts +103 -0
  17. package/src/generators/fix-schematic/index.ts +5 -0
  18. package/src/generators/init/coerce-nx-json.ts +72 -0
  19. package/src/generators/init/generator.ts +28 -0
  20. package/src/generators/init/index.ts +5 -0
  21. package/src/generators/init/init-workspace.ts +84 -0
  22. package/src/generators/init-application/assert-main-statements.ts +74 -0
  23. package/src/generators/init-application/cleanup.ts +127 -0
  24. package/src/generators/init-application/coerce-app-config.ts +147 -0
  25. package/src/generators/init-application/coerce-environment-files.ts +105 -0
  26. package/src/generators/init-application/coerce-localazy-config-file.ts +26 -0
  27. package/src/generators/init-application/coerce-project.ts +128 -0
  28. package/src/generators/init-application/generate-authentication.ts +122 -0
  29. package/src/generators/init-application/generate-monolithic.spec.ts +45 -0
  30. package/src/generators/init-application/generate-monolithic.ts +57 -0
  31. package/src/generators/init-application/generator.ts +356 -0
  32. package/src/generators/init-application/index.ts +5 -0
  33. package/src/generators/init-application/link-mfe-remote-with-host.ts +60 -0
  34. package/src/generators/init-application/project-i18n-configuration.ts +4 -0
  35. package/src/generators/init-application/update-git-ignore.ts +22 -0
  36. package/src/generators/init-application/update-main-file.ts +118 -0
  37. package/src/generators/init-application/update-project-targets.ts +229 -0
  38. package/src/generators/init-application/update-tags.ts +30 -0
  39. package/src/generators/init-application/update-target-defaults.ts +43 -0
  40. package/src/generators/init-application/update-ts-config.ts +31 -0
  41. package/src/generators/init-component/generator.ts +147 -0
  42. package/src/generators/init-component/index.ts +5 -0
  43. package/src/generators/init-feature/generator.ts +77 -0
  44. package/src/generators/init-feature/index.ts +5 -0
  45. package/src/generators/init-feature-library/generator.ts +82 -0
  46. package/src/generators/init-feature-library/index.ts +5 -0
  47. package/src/generators/init-feature-library/init-project.ts +53 -0
  48. package/src/generators/init-feature-library/init-workspace.ts +10 -0
  49. package/src/generators/init-library/check-if-secondary-entrypoint-include-in-the-ts-config.ts +46 -0
  50. package/src/generators/init-library/cleanup.ts +22 -0
  51. package/src/generators/init-library/coerce-projects.ts +118 -0
  52. package/src/generators/init-library/coerce-tailwind-theme-scss.ts +27 -0
  53. package/src/generators/init-library/extend-angular-specific-eslint.ts +37 -0
  54. package/src/generators/init-library/generator.ts +87 -0
  55. package/src/generators/init-library/has-index-scss.ts +14 -0
  56. package/src/generators/init-library/has-tailwind-config.ts +9 -0
  57. package/src/generators/init-library/index.ts +5 -0
  58. package/src/generators/init-library/init-project.ts +46 -0
  59. package/src/generators/init-library/init-workspace.ts +26 -0
  60. package/src/generators/init-library/is-ng-packagr-project.ts +9 -0
  61. package/src/generators/init-library/ng-package-json.ts +23 -0
  62. package/src/generators/init-library/set-general-target-defaults.ts +36 -0
  63. package/src/generators/init-library/update-package-json.ts +26 -0
  64. package/src/generators/init-library/update-project-ng-package-configuration.ts +51 -0
  65. package/src/generators/init-library/update-ts-config.ts +24 -0
  66. package/src/generators/schematic/generator.ts +179 -0
  67. package/src/generators/schematic/index.ts +5 -0
  68. package/src/i18n.ts +130 -0
  69. package/src/lib/angular-version.ts +1 -0
  70. package/src/lib/coerce-cypress-component-testing.ts +113 -0
  71. package/src/lib/coerce-test-setup.ts +60 -0
  72. package/src/library.ts +153 -0
  73. package/src/migrations/update-19-0-0/add-m2-prefix-to-material-scss-functions.ts +32 -0
  74. package/src/migrations/update-19-0-0/migration.ts +283 -0
  75. package/src/test-setup.ts +24 -0
  76. package/tsconfig.json +20 -0
  77. package/tsconfig.lib.json +10 -0
  78. package/tsconfig.spec.json +15 -0
  79. package/tsconfig.typedoc.json +5 -0
  80. package/src/application.d.ts +0 -6
  81. package/src/application.js +0 -77
  82. package/src/application.js.map +0 -1
  83. package/src/executors/check-ng-package/executor.d.ts +0 -5
  84. package/src/executors/check-ng-package/executor.js +0 -30
  85. package/src/executors/check-ng-package/executor.js.map +0 -1
  86. package/src/executors/config/executor.d.ts +0 -10
  87. package/src/executors/config/executor.js +0 -65
  88. package/src/executors/config/executor.js.map +0 -1
  89. package/src/executors/i18n/executor.d.ts +0 -9
  90. package/src/executors/i18n/executor.js +0 -158
  91. package/src/executors/i18n/executor.js.map +0 -1
  92. package/src/executors/tailwind/executor.d.ts +0 -5
  93. package/src/executors/tailwind/executor.js +0 -31
  94. package/src/executors/tailwind/executor.js.map +0 -1
  95. package/src/generators/convert-to-buildable-library/generator.d.ts +0 -4
  96. package/src/generators/convert-to-buildable-library/generator.js +0 -88
  97. package/src/generators/convert-to-buildable-library/generator.js.map +0 -1
  98. package/src/generators/fix-schematic/generator.d.ts +0 -4
  99. package/src/generators/fix-schematic/generator.js +0 -72
  100. package/src/generators/fix-schematic/generator.js.map +0 -1
  101. package/src/generators/fix-schematic/index.d.ts +0 -2
  102. package/src/generators/fix-schematic/index.js +0 -7
  103. package/src/generators/fix-schematic/index.js.map +0 -1
  104. package/src/generators/init/coerce-nx-json.d.ts +0 -3
  105. package/src/generators/init/coerce-nx-json.js +0 -74
  106. package/src/generators/init/coerce-nx-json.js.map +0 -1
  107. package/src/generators/init/generator.d.ts +0 -4
  108. package/src/generators/init/generator.js +0 -19
  109. package/src/generators/init/generator.js.map +0 -1
  110. package/src/generators/init/index.d.ts +0 -2
  111. package/src/generators/init/index.js +0 -7
  112. package/src/generators/init/index.js.map +0 -1
  113. package/src/generators/init/init-workspace.d.ts +0 -3
  114. package/src/generators/init/init-workspace.js +0 -73
  115. package/src/generators/init/init-workspace.js.map +0 -1
  116. package/src/generators/init-application/assert-main-statements.d.ts +0 -4
  117. package/src/generators/init-application/assert-main-statements.js +0 -76
  118. package/src/generators/init-application/assert-main-statements.js.map +0 -1
  119. package/src/generators/init-application/cleanup.d.ts +0 -3
  120. package/src/generators/init-application/cleanup.js +0 -108
  121. package/src/generators/init-application/cleanup.js.map +0 -1
  122. package/src/generators/init-application/coerce-app-config.d.ts +0 -3
  123. package/src/generators/init-application/coerce-app-config.js +0 -143
  124. package/src/generators/init-application/coerce-app-config.js.map +0 -1
  125. package/src/generators/init-application/coerce-environment-files.d.ts +0 -5
  126. package/src/generators/init-application/coerce-environment-files.js +0 -75
  127. package/src/generators/init-application/coerce-environment-files.js.map +0 -1
  128. package/src/generators/init-application/coerce-localazy-config-file.d.ts +0 -2
  129. package/src/generators/init-application/coerce-localazy-config-file.js +0 -25
  130. package/src/generators/init-application/coerce-localazy-config-file.js.map +0 -1
  131. package/src/generators/init-application/coerce-project.d.ts +0 -4
  132. package/src/generators/init-application/coerce-project.js +0 -56
  133. package/src/generators/init-application/coerce-project.js.map +0 -1
  134. package/src/generators/init-application/generate-authentication.d.ts +0 -3
  135. package/src/generators/init-application/generate-authentication.js +0 -97
  136. package/src/generators/init-application/generate-authentication.js.map +0 -1
  137. package/src/generators/init-application/generate-monolithic.d.ts +0 -3
  138. package/src/generators/init-application/generate-monolithic.js +0 -45
  139. package/src/generators/init-application/generate-monolithic.js.map +0 -1
  140. package/src/generators/init-application/generator.d.ts +0 -4
  141. package/src/generators/init-application/generator.js +0 -257
  142. package/src/generators/init-application/generator.js.map +0 -1
  143. package/src/generators/init-application/index.d.ts +0 -2
  144. package/src/generators/init-application/index.js +0 -7
  145. package/src/generators/init-application/index.js.map +0 -1
  146. package/src/generators/init-application/link-mfe-remote-with-host.d.ts +0 -3
  147. package/src/generators/init-application/link-mfe-remote-with-host.js +0 -54
  148. package/src/generators/init-application/link-mfe-remote-with-host.js.map +0 -1
  149. package/src/generators/init-application/project-i18n-configuration.d.ts +0 -7
  150. package/src/generators/init-application/project-i18n-configuration.js +0 -3
  151. package/src/generators/init-application/project-i18n-configuration.js.map +0 -1
  152. package/src/generators/init-application/update-git-ignore.d.ts +0 -3
  153. package/src/generators/init-application/update-git-ignore.js +0 -17
  154. package/src/generators/init-application/update-git-ignore.js.map +0 -1
  155. package/src/generators/init-application/update-main-file.d.ts +0 -3
  156. package/src/generators/init-application/update-main-file.js +0 -106
  157. package/src/generators/init-application/update-main-file.js.map +0 -1
  158. package/src/generators/init-application/update-project-targets.d.ts +0 -6
  159. package/src/generators/init-application/update-project-targets.js +0 -210
  160. package/src/generators/init-application/update-project-targets.js.map +0 -1
  161. package/src/generators/init-application/update-tags.d.ts +0 -3
  162. package/src/generators/init-application/update-tags.js +0 -25
  163. package/src/generators/init-application/update-tags.js.map +0 -1
  164. package/src/generators/init-application/update-target-defaults.d.ts +0 -3
  165. package/src/generators/init-application/update-target-defaults.js +0 -30
  166. package/src/generators/init-application/update-target-defaults.js.map +0 -1
  167. package/src/generators/init-application/update-ts-config.d.ts +0 -2
  168. package/src/generators/init-application/update-ts-config.js +0 -30
  169. package/src/generators/init-application/update-ts-config.js.map +0 -1
  170. package/src/generators/init-component/generator.d.ts +0 -5
  171. package/src/generators/init-component/generator.js +0 -106
  172. package/src/generators/init-component/generator.js.map +0 -1
  173. package/src/generators/init-component/index.d.ts +0 -2
  174. package/src/generators/init-component/index.js +0 -7
  175. package/src/generators/init-component/index.js.map +0 -1
  176. package/src/generators/init-feature/generator.d.ts +0 -4
  177. package/src/generators/init-feature/generator.js +0 -53
  178. package/src/generators/init-feature/generator.js.map +0 -1
  179. package/src/generators/init-feature/index.d.ts +0 -2
  180. package/src/generators/init-feature/index.js +0 -7
  181. package/src/generators/init-feature/index.js.map +0 -1
  182. package/src/generators/init-feature-library/generator.d.ts +0 -4
  183. package/src/generators/init-feature-library/generator.js +0 -51
  184. package/src/generators/init-feature-library/generator.js.map +0 -1
  185. package/src/generators/init-feature-library/index.d.ts +0 -2
  186. package/src/generators/init-feature-library/index.js +0 -7
  187. package/src/generators/init-feature-library/index.js.map +0 -1
  188. package/src/generators/init-feature-library/init-project.d.ts +0 -3
  189. package/src/generators/init-feature-library/init-project.js +0 -41
  190. package/src/generators/init-feature-library/init-project.js.map +0 -1
  191. package/src/generators/init-feature-library/init-workspace.d.ts +0 -3
  192. package/src/generators/init-feature-library/init-workspace.js +0 -12
  193. package/src/generators/init-feature-library/init-workspace.js.map +0 -1
  194. package/src/generators/init-library/check-if-secondary-entrypoint-include-in-the-ts-config.d.ts +0 -2
  195. package/src/generators/init-library/check-if-secondary-entrypoint-include-in-the-ts-config.js +0 -39
  196. package/src/generators/init-library/check-if-secondary-entrypoint-include-in-the-ts-config.js.map +0 -1
  197. package/src/generators/init-library/cleanup.d.ts +0 -2
  198. package/src/generators/init-library/cleanup.js +0 -16
  199. package/src/generators/init-library/cleanup.js.map +0 -1
  200. package/src/generators/init-library/coerce-projects.d.ts +0 -3
  201. package/src/generators/init-library/coerce-projects.js +0 -92
  202. package/src/generators/init-library/coerce-projects.js.map +0 -1
  203. package/src/generators/init-library/coerce-tailwind-theme-scss.d.ts +0 -2
  204. package/src/generators/init-library/coerce-tailwind-theme-scss.js +0 -22
  205. package/src/generators/init-library/coerce-tailwind-theme-scss.js.map +0 -1
  206. package/src/generators/init-library/extend-angular-specific-eslint.d.ts +0 -2
  207. package/src/generators/init-library/extend-angular-specific-eslint.js +0 -25
  208. package/src/generators/init-library/extend-angular-specific-eslint.js.map +0 -1
  209. package/src/generators/init-library/generator.d.ts +0 -4
  210. package/src/generators/init-library/generator.js +0 -56
  211. package/src/generators/init-library/generator.js.map +0 -1
  212. package/src/generators/init-library/has-index-scss.d.ts +0 -2
  213. package/src/generators/init-library/has-index-scss.js +0 -11
  214. package/src/generators/init-library/has-index-scss.js.map +0 -1
  215. package/src/generators/init-library/has-tailwind-config.d.ts +0 -2
  216. package/src/generators/init-library/has-tailwind-config.js +0 -8
  217. package/src/generators/init-library/has-tailwind-config.js.map +0 -1
  218. package/src/generators/init-library/index.d.ts +0 -2
  219. package/src/generators/init-library/index.js +0 -7
  220. package/src/generators/init-library/index.js.map +0 -1
  221. package/src/generators/init-library/init-project.d.ts +0 -3
  222. package/src/generators/init-library/init-project.js +0 -37
  223. package/src/generators/init-library/init-project.js.map +0 -1
  224. package/src/generators/init-library/init-workspace.d.ts +0 -3
  225. package/src/generators/init-library/init-workspace.js +0 -21
  226. package/src/generators/init-library/init-workspace.js.map +0 -1
  227. package/src/generators/init-library/is-ng-packagr-project.d.ts +0 -2
  228. package/src/generators/init-library/is-ng-packagr-project.js +0 -8
  229. package/src/generators/init-library/is-ng-packagr-project.js.map +0 -1
  230. package/src/generators/init-library/ng-package-json.d.ts +0 -8
  231. package/src/generators/init-library/ng-package-json.js +0 -16
  232. package/src/generators/init-library/ng-package-json.js.map +0 -1
  233. package/src/generators/init-library/set-general-target-defaults.d.ts +0 -2
  234. package/src/generators/init-library/set-general-target-defaults.js +0 -27
  235. package/src/generators/init-library/set-general-target-defaults.js.map +0 -1
  236. package/src/generators/init-library/update-package-json.d.ts +0 -2
  237. package/src/generators/init-library/update-package-json.js +0 -17
  238. package/src/generators/init-library/update-package-json.js.map +0 -1
  239. package/src/generators/init-library/update-project-ng-package-configuration.d.ts +0 -2
  240. package/src/generators/init-library/update-project-ng-package-configuration.js +0 -37
  241. package/src/generators/init-library/update-project-ng-package-configuration.js.map +0 -1
  242. package/src/generators/init-library/update-ts-config.d.ts +0 -2
  243. package/src/generators/init-library/update-ts-config.js +0 -22
  244. package/src/generators/init-library/update-ts-config.js.map +0 -1
  245. package/src/generators/schematic/generator.d.ts +0 -6
  246. package/src/generators/schematic/generator.js +0 -127
  247. package/src/generators/schematic/generator.js.map +0 -1
  248. package/src/generators/schematic/index.d.ts +0 -2
  249. package/src/generators/schematic/index.js +0 -7
  250. package/src/generators/schematic/index.js.map +0 -1
  251. package/src/i18n.d.ts +0 -6
  252. package/src/i18n.js +0 -83
  253. package/src/i18n.js.map +0 -1
  254. package/src/index.js +0 -10
  255. package/src/index.js.map +0 -1
  256. package/src/lib/angular-version.d.ts +0 -1
  257. package/src/lib/angular-version.js +0 -5
  258. package/src/lib/angular-version.js.map +0 -1
  259. package/src/lib/coerce-cypress-component-testing.d.ts +0 -2
  260. package/src/lib/coerce-cypress-component-testing.js +0 -78
  261. package/src/lib/coerce-cypress-component-testing.js.map +0 -1
  262. package/src/lib/coerce-test-setup.d.ts +0 -2
  263. package/src/lib/coerce-test-setup.js +0 -47
  264. package/src/lib/coerce-test-setup.js.map +0 -1
  265. package/src/library.d.ts +0 -6
  266. package/src/library.js +0 -100
  267. package/src/library.js.map +0 -1
  268. package/src/migrations/update-19-0-0/add-m2-prefix-to-material-scss-functions.d.ts +0 -2
  269. package/src/migrations/update-19-0-0/add-m2-prefix-to-material-scss-functions.js +0 -29
  270. package/src/migrations/update-19-0-0/add-m2-prefix-to-material-scss-functions.js.map +0 -1
  271. package/src/migrations/update-19-0-0/migration.d.ts +0 -9
  272. package/src/migrations/update-19-0-0/migration.js +0 -220
  273. package/src/migrations/update-19-0-0/migration.js.map +0 -1
  274. /package/src/{index.d.ts → index.ts} +0 -0
@@ -0,0 +1,24 @@
1
+ import { Tree } from '@nx/devkit';
2
+ import {
3
+ GetProjectRoot,
4
+ UpdateTsConfigJson,
5
+ } from '@rxap/workspace-utilities';
6
+
7
+ export function updateTsConfig(tree: Tree, projectName: string) {
8
+
9
+ const projectRoot = GetProjectRoot(tree, projectName);
10
+
11
+ for (const infix of [ 'lib', 'spec' ]) {
12
+ UpdateTsConfigJson(tree, tsConfig => {
13
+ tsConfig.compilerOptions ??= {};
14
+ tsConfig.compilerOptions.types ??= [];
15
+ if (!tsConfig.compilerOptions.types.includes('@angular/localize')) {
16
+ tsConfig.compilerOptions.types.push('@angular/localize');
17
+ }
18
+ }, {
19
+ basePath: projectRoot,
20
+ infix,
21
+ });
22
+ }
23
+
24
+ }
@@ -0,0 +1,179 @@
1
+ import {
2
+ formatFiles,
3
+ generateFiles,
4
+ GeneratorsJson,
5
+ joinPathFragments,
6
+ names,
7
+ readJson,
8
+ readProjectConfiguration,
9
+ Tree,
10
+ updateJson,
11
+ updateProjectConfiguration,
12
+ writeJson,
13
+ } from '@nx/devkit';
14
+ import {
15
+ CoerceAssets,
16
+ GetWorkspaceScope,
17
+ PackageJson,
18
+ } from '@rxap/workspace-utilities';
19
+ import * as path from 'path';
20
+ import { SchematicGeneratorSchema } from './schema';
21
+
22
+ type NormalizedSchema = SchematicGeneratorSchema & ReturnType<typeof names> & {
23
+ fileName: string;
24
+ className: string;
25
+ projectRoot: string;
26
+ projectSourceRoot: string;
27
+ npmScope: string;
28
+ npmPackageName: string;
29
+ };
30
+
31
+ function normalizeOptions(host: Tree, options: SchematicGeneratorSchema): NormalizedSchema {
32
+ const npmScope = GetWorkspaceScope(host);
33
+
34
+ const {
35
+ root: projectRoot,
36
+ sourceRoot: projectSourceRoot,
37
+ } = readProjectConfiguration(host, options.project);
38
+
39
+ const npmPackageName = readJson<{ name: string }>(host, path.join(projectRoot, 'package.json')).name;
40
+
41
+ let description: string;
42
+ if (options.description) {
43
+ description = options.description;
44
+ } else {
45
+ description = `${ options.name } schematic`;
46
+ }
47
+
48
+ if (!projectSourceRoot) {
49
+ throw new Error(`Project source root not found for project ${ options.project }`);
50
+ }
51
+
52
+ return {
53
+ ...options, ...names(options.name),
54
+ description,
55
+ projectRoot,
56
+ projectSourceRoot,
57
+ npmScope,
58
+ npmPackageName,
59
+ };
60
+ }
61
+
62
+ function addFiles(host: Tree, options: NormalizedSchema) {
63
+ generateFiles(host, path.join(__dirname, './files/schematic'), `${ options.projectSourceRoot }/schematics`, {
64
+ ...options,
65
+ schematicFnName: `${ options.propertyName }Schematic`,
66
+ schemaInterfaceName: `${ options.className }SchematicSchema`,
67
+ });
68
+ }
69
+
70
+ export async function createCollectionJson(host: Tree, projectRoot: string) {
71
+ updateJson<PackageJson>(host, joinPathFragments(projectRoot, 'package.json'), (json) => {
72
+ json.schematics ??= './collection.json';
73
+ return json;
74
+ });
75
+ writeJson<GeneratorsJson>(host, joinPathFragments(projectRoot, 'collection.json'), {
76
+ schematics: {},
77
+ });
78
+ }
79
+
80
+ async function updateCollectionJson(host: Tree, options: NormalizedSchema) {
81
+ const packageJson = readJson<PackageJson>(host, joinPathFragments(options.projectRoot, 'package.json'));
82
+ const packageJsonSchematics = packageJson.schematics;
83
+ let schematicsPath = packageJsonSchematics ? joinPathFragments(options.projectRoot, packageJsonSchematics) : null;
84
+
85
+ if (!schematicsPath) {
86
+ schematicsPath = joinPathFragments(options.projectRoot, 'collection.json');
87
+ }
88
+ if (!host.exists(schematicsPath)) {
89
+ await createCollectionJson(host, options.projectRoot);
90
+ }
91
+
92
+ updateJson<GeneratorsJson>(host, schematicsPath, (json) => {
93
+ let schematics = json.schematics;
94
+ schematics ??= {};
95
+ schematics[options.name] = {
96
+ factory: `./src/schematics/${ options.fileName }/index`,
97
+ schema: `./src/schematics/${ options.fileName }/schema.json`,
98
+ description: options.description,
99
+ };
100
+ json.schematics = schematics;
101
+ return json;
102
+ });
103
+ }
104
+
105
+ export function hasSchematic(tree: Tree, projectName: string, schematicName: string): boolean {
106
+ const project = readProjectConfiguration(tree, projectName);
107
+ const packageJson = readJson<PackageJson>(tree, joinPathFragments(project.root, 'package.json'));
108
+ if (!packageJson.schematics) {
109
+ return false;
110
+ }
111
+ const schematicsPath = joinPathFragments(project.root, packageJson.schematics);
112
+ const collectionJson = readJson<GeneratorsJson>(tree, schematicsPath);
113
+ return (
114
+ collectionJson.schematics?.[schematicName] !== undefined
115
+ );
116
+ }
117
+
118
+ function coerceBuildTarget(
119
+ tree: Tree,
120
+ {
121
+ projectRoot,
122
+ project,
123
+ }: NormalizedSchema,
124
+ ) {
125
+
126
+ const projectConfiguration = readProjectConfiguration(tree, project);
127
+
128
+ projectConfiguration.targets ??= {};
129
+ projectConfiguration.targets['build'] ??= {};
130
+ const buildTarget = projectConfiguration.targets['build'];
131
+
132
+ buildTarget.executor = '@nx/js:tsc';
133
+ buildTarget.outputs ??= [ '{options.outputPath}' ];
134
+ buildTarget.options ??= {};
135
+ buildTarget.options.outputPath = `dist/${ projectRoot }`;
136
+ buildTarget.options.main = `${ projectRoot }/src/index.ts`;
137
+ buildTarget.options.tsConfig = `${ projectRoot }/tsconfig.lib.json`;
138
+ buildTarget.options.assets ??= [];
139
+
140
+ const assets = [
141
+ `${ projectRoot }/*.md`, {
142
+ 'input': `./${ projectRoot }/src`,
143
+ 'glob': '**/!(*.ts)',
144
+ 'output': './src',
145
+ }, {
146
+ 'input': `./${ projectRoot }/src`,
147
+ 'glob': '**/*.d.ts',
148
+ 'output': './src',
149
+ }, {
150
+ 'input': `./${ projectRoot }`,
151
+ 'glob': 'collection.json',
152
+ 'output': '.',
153
+ },
154
+ ];
155
+
156
+ CoerceAssets(buildTarget.options.assets, assets);
157
+
158
+ updateProjectConfiguration(tree, project, projectConfiguration);
159
+ }
160
+
161
+ export async function schematicGenerator(host: Tree, _options: SchematicGeneratorSchema) {
162
+ const options = normalizeOptions(host, _options);
163
+ if (hasSchematic(host, options.project, options.name)) {
164
+ throw new Error(`Generator ${ options.name } already exists.`);
165
+ }
166
+
167
+ addFiles(host, options);
168
+
169
+ await updateCollectionJson(host, options);
170
+
171
+ if (!options.skipFormat) {
172
+ await formatFiles(host);
173
+ }
174
+
175
+ coerceBuildTarget(host, options);
176
+
177
+ }
178
+
179
+ export default schematicGenerator;
@@ -0,0 +1,5 @@
1
+ import { convertNxGenerator } from '@nx/devkit';
2
+ import generator from './generator';
3
+
4
+ const schematic = convertNxGenerator(generator);
5
+ export default schematic;
package/src/i18n.ts ADDED
@@ -0,0 +1,130 @@
1
+ import {
2
+ CreateNodesContextV2,
3
+ CreateNodesV2,
4
+ ProjectConfiguration,
5
+ TargetConfiguration,
6
+ } from '@nx/devkit';
7
+ import {
8
+ FindProjectByPath,
9
+ FsTree,
10
+ } from '@rxap/workspace-utilities';
11
+ import { Optional } from 'nx/src/project-graph/plugins';
12
+ import { combineGlobPatterns } from 'nx/src/utils/globs';
13
+ import { dirname } from 'path';
14
+ import 'colors';
15
+
16
+ // eslint-disable-next-line @typescript-eslint/no-empty-interface
17
+ export interface PluginOptions {}
18
+
19
+ export function normalizeOptions(
20
+ options: PluginOptions | undefined,
21
+ ): PluginOptions {
22
+ return options ?? {};
23
+ }
24
+
25
+ export const createNodesV2: CreateNodesV2<PluginOptions> = [
26
+ combineGlobPatterns([
27
+ '**/tsconfig.app.json',
28
+ '**/src/main.ts',
29
+ '**/src/app/app.module.ts',
30
+ '**/src/app/app.component.ts',
31
+ '**/src/index.html',
32
+ '**/src/i18n.index.html.hbs'
33
+ ]),
34
+ async (configFilePaths, options, context) => {
35
+ const normalizedOptions = normalizeOptions(options);
36
+
37
+ const includedConfigFilePaths = await Promise.all(
38
+ configFilePaths.map(async (configFilePath) => {
39
+ if (
40
+ await shouldHaveProjectConfiguration(
41
+ configFilePath,
42
+ normalizedOptions,
43
+ context,
44
+ )
45
+ ) {
46
+ return configFilePath;
47
+ }
48
+ return undefined;
49
+ }),
50
+ ).then((configFilePathOrUndefinedList) =>
51
+ configFilePathOrUndefinedList.filter((value) => value !== undefined),
52
+ );
53
+
54
+ const results = await Promise.all(
55
+ includedConfigFilePaths.map(async (configFilePath) => {
56
+ const [ projectPath, projectConfiguration ] =
57
+ await createProjectConfiguration(
58
+ configFilePath,
59
+ normalizedOptions,
60
+ context,
61
+ );
62
+ return [ configFilePath, projectPath, projectConfiguration ] as [
63
+ string,
64
+ string,
65
+ Optional<ProjectConfiguration, 'root'>
66
+ ];
67
+ }),
68
+ );
69
+
70
+ return results.map(
71
+ ([ configFilePath, projectPath, projectConfiguration ]) => [
72
+ configFilePath,
73
+ {
74
+ projects: {
75
+ [projectPath]: projectConfiguration,
76
+ },
77
+ },
78
+ ],
79
+ );
80
+ },
81
+ ];
82
+
83
+ async function shouldHaveProjectConfiguration(
84
+ configFilePath: string,
85
+ options: PluginOptions,
86
+ context: CreateNodesContextV2,
87
+ ): Promise<boolean> {
88
+ const projectPath = dirname(configFilePath);
89
+ const tree = new FsTree(context.workspaceRoot);
90
+ if (!FindProjectByPath(tree, projectPath)) {
91
+ // console.log(`The folder of the file '${ configFilePath }' is not the root of a project. Skipping`.yellow);
92
+ return false;
93
+ }
94
+ return true;
95
+ }
96
+
97
+ async function createProjectConfiguration(
98
+ configFilePath: string,
99
+ options: PluginOptions,
100
+ context: CreateNodesContextV2,
101
+ ): Promise<[ string, Optional<ProjectConfiguration, 'root'> ]> {
102
+ const projectPath = dirname(configFilePath);
103
+ const targets: Record<string, TargetConfiguration> = {};
104
+ const tree = new FsTree(context.workspaceRoot);
105
+ const projectConfiguration = FindProjectByPath(tree, projectPath);
106
+
107
+ if (!projectConfiguration) {
108
+ throw new Error(`Could not find project in '${ projectPath }'`);
109
+ }
110
+
111
+ targets['i18n-index-html'] = createI18nIndexHtmlTarget();
112
+
113
+ return [
114
+ projectPath, {
115
+ targets,
116
+ },
117
+ ];
118
+ }
119
+
120
+ function createI18nIndexHtmlTarget(): TargetConfiguration {
121
+ return {
122
+ dependsOn: [ "build"],
123
+ executor: "@rxap/plugin-application:i18n",
124
+ outputs: [ "{workspaceRoot}/dist/{projectRoot}/index.html"],
125
+ inputs: [
126
+ "{projectRoot}/i18n.index.html.hbs"
127
+ ],
128
+ cache: true
129
+ };
130
+ }
@@ -0,0 +1 @@
1
+ export const ANGULAR_VERSION = '~19.1.0';
@@ -0,0 +1,113 @@
1
+ import { cypressComponentConfiguration } from '@nx/angular/generators';
2
+ import {
3
+ getProjects,
4
+ ProjectConfiguration,
5
+ readProjectConfiguration,
6
+ Tree,
7
+ updateProjectConfiguration,
8
+ } from '@nx/devkit';
9
+ import {
10
+ CoerceFile,
11
+ IsAngularProject,
12
+ IsApplicationProject,
13
+ IsRxapRepository,
14
+ } from '@rxap/workspace-utilities';
15
+ import { join } from 'path';
16
+
17
+ function determineCypressBuildTargetProject(tree: Tree, project: ProjectConfiguration, projectName: string): string {
18
+
19
+ if (IsApplicationProject(project)) {
20
+ return projectName;
21
+ }
22
+
23
+ const projects = getProjects(tree);
24
+
25
+ const angularApplicationProjects = Array.from(projects.entries())
26
+ .filter(([ , project ]) => IsApplicationProject(project) && IsAngularProject(project));
27
+
28
+ const cypressProject = angularApplicationProjects.find(([ projectName ]) => projectName.endsWith('cypress'));
29
+
30
+ if (cypressProject) {
31
+ return cypressProject[0];
32
+ }
33
+
34
+ if (angularApplicationProjects.length) {
35
+ return angularApplicationProjects[0][0];
36
+ } else {
37
+ throw new Error('No angular application project found. Can not determine the cypress build target project.');
38
+ }
39
+
40
+ }
41
+
42
+ export async function CoerceCypressComponentTesting(tree: Tree, project: ProjectConfiguration, projectName: string) {
43
+
44
+ project.targets ??= {};
45
+
46
+ if (!project.targets['component-test']) {
47
+ const buildTargetProjectName = determineCypressBuildTargetProject(tree, project, projectName);
48
+ await cypressComponentConfiguration(tree, {
49
+ project: projectName,
50
+ generateTests: true,
51
+ skipFormat: false,
52
+ buildTarget: `${ buildTargetProjectName }:build:development`,
53
+ });
54
+ if (buildTargetProjectName !== projectName) {
55
+ const buildTargetProject = readProjectConfiguration(tree, buildTargetProjectName);
56
+ buildTargetProject.implicitDependencies ??= [];
57
+ if (!buildTargetProject.implicitDependencies.includes(projectName)) {
58
+ buildTargetProject.implicitDependencies.push(projectName);
59
+ updateProjectConfiguration(
60
+ tree,
61
+ buildTargetProjectName,
62
+ buildTargetProject,
63
+ );
64
+ }
65
+ }
66
+ const _project = readProjectConfiguration(tree, projectName);
67
+ _project.targets ??= {};
68
+ _project.targets['component-test'].configurations ??= {};
69
+ _project.targets['component-test'].configurations['open'] ??= {};
70
+ _project.targets['component-test'].configurations['open'].watch = true;
71
+ updateProjectConfiguration(
72
+ tree,
73
+ projectName,
74
+ _project,
75
+ );
76
+ if (IsRxapRepository(tree)) {
77
+ CoerceFile(tree, join(
78
+ project.root,
79
+ 'cypress.config.ts',
80
+ ),
81
+ `import { componentTestingPreset } from 'workspace';
82
+ import { defineConfig } from 'cypress';
83
+
84
+ export default defineConfig({
85
+ component: componentTestingPreset(__filename),
86
+ });`, true);
87
+ }
88
+ }
89
+
90
+ const _project = readProjectConfiguration(
91
+ tree,
92
+ projectName,
93
+ );
94
+ _project.targets ??= {};
95
+ if (_project.targets['component-test'].options.devServerTarget) {
96
+ const cypressProjectName = _project.targets['component-test'].options.devServerTarget.split(':').shift();
97
+ if (cypressProjectName !== projectName) {
98
+ const cypressProject = readProjectConfiguration(
99
+ tree,
100
+ cypressProjectName,
101
+ );
102
+ cypressProject.implicitDependencies ??= [];
103
+ if (!cypressProject.implicitDependencies.includes(projectName)) {
104
+ cypressProject.implicitDependencies.push(projectName);
105
+ updateProjectConfiguration(
106
+ tree,
107
+ cypressProjectName,
108
+ cypressProject,
109
+ );
110
+ }
111
+ }
112
+ }
113
+ }
@@ -0,0 +1,60 @@
1
+ import { Tree } from '@nx/devkit';
2
+ import { CoerceImports } from '@rxap/ts-morph';
3
+ import { TsMorphAngularProjectTransform } from '@rxap/workspace-ts-morph';
4
+ import {
5
+ CoerceFile,
6
+ GetProjectSourceRoot,
7
+ } from '@rxap/workspace-utilities';
8
+
9
+ export function coerceTestSetup(tree: Tree, projectName: string) {
10
+ const projectSourceRoot = GetProjectSourceRoot(tree, projectName);
11
+
12
+ const testSetupPath = `${projectSourceRoot}/test-setup.ts`;
13
+ CoerceFile(tree, testSetupPath, `// @ts-expect-error https://thymikee.github.io/jest-preset-angular/docs/getting-started/test-environment
14
+ globalThis.ngJest = {
15
+ testEnvironmentOptions: {
16
+ errorOnUnknownElements: true,
17
+ errorOnUnknownProperties: true,
18
+ },
19
+ };
20
+ import 'jest-preset-angular/setup-jest';
21
+ `);
22
+
23
+ TsMorphAngularProjectTransform(tree, { project: projectName, basePath: projectSourceRoot }, (_, [ sourceFile ]) => {
24
+
25
+ CoerceImports(sourceFile, [
26
+ {
27
+ moduleSpecifier: 'util',
28
+ namedImports: [ 'TextDecoder', 'TextEncoder' ],
29
+ },
30
+ {
31
+ moduleSpecifier: '@angular/localize/init',
32
+ },
33
+ ]);
34
+
35
+ const hasTextEncoderStatement = !!sourceFile.getStatement(
36
+ statement => statement.getText().includes('global.TextEncoder ??= TextEncoder as any;'));
37
+ const hasTextDecoderStatement = !!sourceFile.getStatement(
38
+ statement => statement.getText().includes('global.TextDecoder ??= TextDecoder as any;'));
39
+ const hasLocalizeInitStatement = !!sourceFile.getStatement(
40
+ statement => statement.getText().includes('jest.spyOn(global as any, \'$localize\')'));
41
+
42
+ if (!hasTextEncoderStatement) {
43
+ sourceFile.addStatements(`global.TextEncoder ??= TextEncoder as any;`);
44
+ }
45
+
46
+ if (!hasTextDecoderStatement) {
47
+ sourceFile.addStatements(`global.TextDecoder ??= TextDecoder as any;`);
48
+ }
49
+
50
+ if (!hasLocalizeInitStatement) {
51
+ sourceFile.addStatements(`jest.spyOn(global as any, '$localize').mockImplementation((...args: any[]) => {
52
+ // This template tag function just returns the first argument with no transformations.
53
+ // Change this to fit your unit test needs.
54
+ return args[0];
55
+ });`);
56
+ }
57
+
58
+ }, [ 'test-setup.ts' ]);
59
+
60
+ }
package/src/library.ts ADDED
@@ -0,0 +1,153 @@
1
+ import {
2
+ CreateNodesContextV2,
3
+ CreateNodesV2,
4
+ ProjectConfiguration,
5
+ TargetConfiguration,
6
+ } from '@nx/devkit';
7
+ import {
8
+ FindProjectByPath,
9
+ FsTree,
10
+ IsRxapRepository,
11
+ } from '@rxap/workspace-utilities';
12
+ import { existsSync } from 'fs';
13
+ import { Optional } from 'nx/src/project-graph/plugins';
14
+ import {
15
+ dirname,
16
+ join,
17
+ } from 'path';
18
+ import 'colors';
19
+
20
+ // eslint-disable-next-line @typescript-eslint/no-empty-interface
21
+ export interface PluginOptions {}
22
+
23
+ export function normalizeOptions(
24
+ options: PluginOptions | undefined,
25
+ ): PluginOptions {
26
+ return options ?? {};
27
+ }
28
+
29
+ export const createNodesV2: CreateNodesV2<PluginOptions> = [
30
+ '**/ng-package.json',
31
+ async (configFilePaths, options, context) => {
32
+ const normalizedOptions = normalizeOptions(options);
33
+
34
+ const includedConfigFilePaths = await Promise.all(
35
+ configFilePaths.map(async (configFilePath) => {
36
+ if (
37
+ await shouldHaveProjectConfiguration(
38
+ configFilePath,
39
+ normalizedOptions,
40
+ context,
41
+ )
42
+ ) {
43
+ return configFilePath;
44
+ }
45
+ return undefined;
46
+ }),
47
+ ).then((configFilePathOrUndefinedList) =>
48
+ configFilePathOrUndefinedList.filter((value) => value !== undefined),
49
+ );
50
+
51
+ const results = await Promise.all(
52
+ includedConfigFilePaths.map(async (configFilePath) => {
53
+ const [ projectPath, projectConfiguration ] =
54
+ await createProjectConfiguration(
55
+ configFilePath,
56
+ normalizedOptions,
57
+ context,
58
+ );
59
+ return [ configFilePath, projectPath, projectConfiguration ] as [
60
+ string,
61
+ string,
62
+ Optional<ProjectConfiguration, 'root'>
63
+ ];
64
+ }),
65
+ );
66
+
67
+ return results.map(
68
+ ([ configFilePath, projectPath, projectConfiguration ]) => [
69
+ configFilePath,
70
+ {
71
+ projects: {
72
+ [projectPath]: projectConfiguration,
73
+ },
74
+ },
75
+ ],
76
+ );
77
+ },
78
+ ];
79
+
80
+ async function shouldHaveProjectConfiguration(
81
+ configFilePath: string,
82
+ options: PluginOptions,
83
+ context: CreateNodesContextV2,
84
+ ): Promise<boolean> {
85
+ const projectPath = dirname(configFilePath);
86
+ const tree = new FsTree(context.workspaceRoot);
87
+ if (!FindProjectByPath(tree, projectPath)) {
88
+ // console.log(`The folder of the file '${ configFilePath }' is not the root of a project. Skipping`.yellow);
89
+ return false;
90
+ }
91
+ return true;
92
+ }
93
+
94
+ async function createProjectConfiguration(
95
+ configFilePath: string,
96
+ options: PluginOptions,
97
+ context: CreateNodesContextV2,
98
+ ): Promise<[ string, Optional<ProjectConfiguration, 'root'> ]> {
99
+ const projectPath = dirname(configFilePath);
100
+ const targets: Record<string, TargetConfiguration> = {};
101
+ const tree = new FsTree(context.workspaceRoot);
102
+ const projectConfiguration = FindProjectByPath(tree, projectPath);
103
+
104
+ if (!projectConfiguration) {
105
+ throw new Error(`Could not find project in '${ projectPath }'`);
106
+ }
107
+
108
+ targets['check-ng-package'] = createCheckNgPackageTarget();
109
+
110
+ if (existsSync(join(projectPath, 'tailwind.config.js'))) {
111
+ targets['build-tailwind'] = createBuildTailwindTarget(IsRxapRepository(context.workspaceRoot));
112
+ }
113
+
114
+ return [
115
+ projectPath, {
116
+ targets,
117
+ },
118
+ ];
119
+ }
120
+
121
+ function createBuildTailwindTarget(isRxapRepository: boolean): TargetConfiguration {
122
+ const dependsOn: TargetConfiguration['dependsOn'] = [];
123
+ if (isRxapRepository) {
124
+ dependsOn.push({
125
+ target: 'build',
126
+ projects: [ 'browser-tailwind' ],
127
+ });
128
+ }
129
+ return {
130
+ executor: '@rxap/plugin-angular:tailwind',
131
+ configurations: {
132
+ production: {
133
+ minify: true,
134
+ },
135
+ },
136
+ dependsOn,
137
+ inputs: [
138
+ '{projectRoot}/**/*.html',
139
+ '{projectRoot}/**/*.scss',
140
+ '{projectRoot}/**/*.css',
141
+ ],
142
+ outputs: [ '{projectRoot}/theme.css' ],
143
+ cache: true,
144
+ };
145
+ }
146
+
147
+ function createCheckNgPackageTarget(): TargetConfiguration {
148
+ return {
149
+ executor: '@rxap/plugin-angular:check-ng-package',
150
+ inputs: [ '{projectRoot}/ng-package.json', '{projectRoot}/package.json' ],
151
+ cache: true,
152
+ };
153
+ }
@@ -0,0 +1,32 @@
1
+ import { Tree } from '@nx/devkit';
2
+ import { VisitTree } from '@rxap/workspace-utilities';
3
+ import { migrateM2ThemingApiUsages } from './migration';
4
+
5
+ export default async function (tree: Tree) {
6
+
7
+ const potentialThemes: Array<{ path: string, content: string }> = [];
8
+
9
+ for (const {
10
+ path,
11
+ isFile
12
+ } of VisitTree(tree, '/')) {
13
+ if (isFile && path.endsWith('.scss')) {
14
+ const content = tree.read(path)!.toString('utf-8');
15
+ if (content.includes('@angular/material')) {
16
+ potentialThemes.push({
17
+ path,
18
+ content,
19
+ });
20
+ }
21
+ }
22
+ }
23
+
24
+ for (const theme of potentialThemes) {
25
+ const migrated = migrateM2ThemingApiUsages(theme.content);
26
+
27
+ if (migrated !== theme.content) {
28
+ tree.write(theme.path, migrated);
29
+ }
30
+ }
31
+
32
+ }