@rxap/plugin-nestjs 16.1.0-dev.4 → 16.1.0-dev.40

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 (112) hide show
  1. package/CHANGELOG.md +355 -0
  2. package/README.md +155 -1
  3. package/generators.json +112 -0
  4. package/package.json +59 -41
  5. package/src/generators/feature-microservice/generator.d.ts +4 -0
  6. package/src/generators/feature-microservice/generator.js +17 -0
  7. package/src/generators/feature-microservice/generator.js.map +1 -0
  8. package/src/generators/feature-microservice/index.d.ts +2 -0
  9. package/src/generators/feature-microservice/index.js +7 -0
  10. package/src/generators/feature-microservice/index.js.map +1 -0
  11. package/src/generators/feature-microservice/schema.d.ts +5 -0
  12. package/src/generators/feature-microservice/schema.json +23 -0
  13. package/src/generators/frontend-microservice/generator.d.ts +4 -0
  14. package/src/generators/frontend-microservice/generator.js +17 -0
  15. package/src/generators/frontend-microservice/generator.js.map +1 -0
  16. package/src/generators/frontend-microservice/index.d.ts +2 -0
  17. package/src/generators/frontend-microservice/index.js +7 -0
  18. package/src/generators/frontend-microservice/index.js.map +1 -0
  19. package/src/generators/frontend-microservice/schema.d.ts +6 -0
  20. package/src/generators/frontend-microservice/schema.json +29 -0
  21. package/src/generators/health-indicator/generator.d.ts +4 -0
  22. package/src/generators/health-indicator/generator.js +31 -0
  23. package/src/generators/health-indicator/generator.js.map +1 -0
  24. package/src/generators/health-indicator/index.d.ts +2 -0
  25. package/src/generators/health-indicator/index.js +7 -0
  26. package/src/generators/health-indicator/index.js.map +1 -0
  27. package/src/generators/health-indicator/schema.d.ts +5 -0
  28. package/src/generators/health-indicator/schema.json +32 -0
  29. package/src/generators/health-indicator-init/generator.d.ts +4 -0
  30. package/src/generators/health-indicator-init/generator.js +35 -0
  31. package/src/generators/health-indicator-init/generator.js.map +1 -0
  32. package/src/generators/health-indicator-init/index.d.ts +2 -0
  33. package/src/generators/health-indicator-init/index.js +7 -0
  34. package/src/generators/health-indicator-init/index.js.map +1 -0
  35. package/src/generators/health-indicator-init/schema.d.ts +4 -0
  36. package/src/generators/health-indicator-init/schema.json +22 -0
  37. package/src/generators/init/generator.js +8 -5
  38. package/src/generators/init/generator.js.map +1 -1
  39. package/src/generators/init/index.d.ts +2 -0
  40. package/src/generators/init/index.js +7 -0
  41. package/src/generators/init/index.js.map +1 -0
  42. package/src/generators/init/schema.d.ts +2 -0
  43. package/src/generators/init/schema.json +10 -0
  44. package/src/generators/init-application/extract-existing-config-validation.d.ts +3 -0
  45. package/src/generators/init-application/extract-existing-config-validation.js +47 -0
  46. package/src/generators/init-application/extract-existing-config-validation.js.map +1 -0
  47. package/src/generators/init-application/files/shared/Dockerfile +33 -0
  48. package/src/generators/init-application/generator.js +554 -29
  49. package/src/generators/init-application/generator.js.map +1 -1
  50. package/src/generators/init-application/index.d.ts +2 -0
  51. package/src/generators/init-application/index.js +7 -0
  52. package/src/generators/init-application/index.js.map +1 -0
  53. package/src/generators/init-application/schema.d.ts +5 -2
  54. package/src/generators/init-application/schema.json +36 -21
  55. package/src/generators/init-library/generator.js +36 -7
  56. package/src/generators/init-library/generator.js.map +1 -1
  57. package/src/generators/init-library/index.d.ts +2 -0
  58. package/src/generators/init-library/index.js +7 -0
  59. package/src/generators/init-library/index.js.map +1 -0
  60. package/src/generators/init-library/schema.d.ts +2 -0
  61. package/src/generators/init-library/schema.json +10 -0
  62. package/src/generators/jwt/generator.d.ts +4 -0
  63. package/src/generators/jwt/generator.js +76 -0
  64. package/src/generators/jwt/generator.js.map +1 -0
  65. package/src/generators/jwt/index.d.ts +2 -0
  66. package/src/generators/jwt/index.js +7 -0
  67. package/src/generators/jwt/index.js.map +1 -0
  68. package/src/generators/jwt/schema.d.ts +4 -0
  69. package/src/generators/jwt/schema.json +18 -0
  70. package/src/generators/microservice/generator.d.ts +4 -0
  71. package/src/generators/microservice/generator.js +26 -0
  72. package/src/generators/microservice/generator.js.map +1 -0
  73. package/src/generators/microservice/index.d.ts +2 -0
  74. package/src/generators/microservice/index.js +7 -0
  75. package/src/generators/microservice/index.js.map +1 -0
  76. package/src/generators/microservice/schema.d.ts +6 -0
  77. package/src/generators/microservice/schema.json +27 -0
  78. package/src/generators/open-api/generator.d.ts +4 -0
  79. package/src/generators/open-api/generator.js +74 -0
  80. package/src/generators/open-api/generator.js.map +1 -0
  81. package/src/generators/open-api/index.d.ts +2 -0
  82. package/src/generators/open-api/index.js +7 -0
  83. package/src/generators/open-api/index.js.map +1 -0
  84. package/src/generators/open-api/schema.d.ts +4 -0
  85. package/src/generators/open-api/schema.json +18 -0
  86. package/src/generators/sentry/generator.d.ts +4 -0
  87. package/src/generators/sentry/generator.js +152 -0
  88. package/src/generators/sentry/generator.js.map +1 -0
  89. package/src/generators/sentry/index.d.ts +2 -0
  90. package/src/generators/sentry/index.js +7 -0
  91. package/src/generators/sentry/index.js.map +1 -0
  92. package/src/generators/sentry/schema.d.ts +6 -0
  93. package/src/generators/sentry/schema.json +32 -0
  94. package/src/generators/swagger/files/environments/environment.swagger.ts__tmpl__ +1 -0
  95. package/src/generators/swagger/files/swagger.ts__tmpl__ +17 -15
  96. package/src/generators/swagger/generator.js +10 -17
  97. package/src/generators/swagger/generator.js.map +1 -1
  98. package/src/generators/swagger/index.d.ts +2 -0
  99. package/src/generators/swagger/index.js +7 -0
  100. package/src/generators/swagger/index.js.map +1 -0
  101. package/src/generators/swagger/schema.d.ts +1 -0
  102. package/src/generators/swagger/schema.json +3 -0
  103. package/src/generators/validator/generator.d.ts +4 -0
  104. package/src/generators/validator/generator.js +14 -0
  105. package/src/generators/validator/generator.js.map +1 -0
  106. package/src/generators/validator/index.d.ts +2 -0
  107. package/src/generators/validator/index.js +7 -0
  108. package/src/generators/validator/index.js.map +1 -0
  109. package/src/generators/validator/schema.d.ts +4 -0
  110. package/src/generators/validator/schema.json +22 -0
  111. package/src/lib/skip-non-nest-project.js +3 -3
  112. package/src/lib/skip-non-nest-project.js.map +1 -1
@@ -5,11 +5,109 @@ const tslib_1 = require("tslib");
5
5
  const devkit_1 = require("@nx/devkit");
6
6
  const library_1 = require("@nx/js/src/generators/library/library");
7
7
  const generator_utilities_1 = require("@rxap/generator-utilities");
8
+ const ts_morph_1 = require("@rxap/ts-morph");
9
+ const workspace_ts_morph_1 = require("@rxap/workspace-ts-morph");
8
10
  const workspace_utilities_1 = require("@rxap/workspace-utilities");
9
- const ngcli_adapter_1 = require("nx/src/adapter/ngcli-adapter");
10
11
  const path_1 = require("path");
12
+ const ts_morph_2 = require("ts-morph");
11
13
  const skip_non_nest_project_1 = require("../../lib/skip-non-nest-project");
12
- const generator_1 = require("../swagger/generator");
14
+ const generator_1 = require("../health-indicator-init/generator");
15
+ const generator_2 = require("../health-indicator/generator");
16
+ const generator_3 = require("../jwt/generator");
17
+ const generator_4 = require("../open-api/generator");
18
+ const generator_5 = require("../sentry/generator");
19
+ const generator_6 = require("../swagger/generator");
20
+ const generator_7 = require("../validator/generator");
21
+ const extract_existing_config_validation_1 = require("./extract-existing-config-validation");
22
+ function coerceEnvironmentFiles(tree, options) {
23
+ (0, workspace_ts_morph_1.TsMorphNestProjectTransform)(tree, {
24
+ project: options.project,
25
+ }, (project, [sourceFile, prodSourceFile]) => {
26
+ (0, ts_morph_1.CoerceImports)(sourceFile, {
27
+ moduleSpecifier: '@rxap/nest-utilities',
28
+ namedImports: ['Environment'],
29
+ });
30
+ (0, ts_morph_1.CoerceImports)(prodSourceFile, {
31
+ moduleSpecifier: '@rxap/nest-utilities',
32
+ namedImports: ['Environment'],
33
+ });
34
+ const baseEnvironment = {
35
+ name: w => w.quote('development'),
36
+ production: 'false',
37
+ app: w => w.quote(options.project),
38
+ };
39
+ if (options.sentry) {
40
+ baseEnvironment['sentry'] = ts_morph_2.Writers.object({
41
+ enabled: 'false',
42
+ debug: 'false',
43
+ });
44
+ }
45
+ const normal = (0, ts_morph_1.CoerceVariableDeclaration)(sourceFile, 'environment', {
46
+ type: 'Environment',
47
+ initializer: ts_morph_2.Writers.object(baseEnvironment),
48
+ });
49
+ if (options.overwrite) {
50
+ normal.set({ initializer: ts_morph_2.Writers.object(baseEnvironment) });
51
+ }
52
+ baseEnvironment['name'] = w => w.quote('production');
53
+ baseEnvironment['production'] = 'true';
54
+ if (options.sentry) {
55
+ baseEnvironment['sentry'] = ts_morph_2.Writers.object({
56
+ enabled: 'true',
57
+ debug: 'false',
58
+ });
59
+ }
60
+ const prod = (0, ts_morph_1.CoerceVariableDeclaration)(prodSourceFile, 'environment', {
61
+ type: 'Environment',
62
+ initializer: ts_morph_2.Writers.object(baseEnvironment),
63
+ });
64
+ if (options.overwrite) {
65
+ prod.set({ initializer: ts_morph_2.Writers.object(baseEnvironment) });
66
+ }
67
+ }, [
68
+ '/environments/environment.ts?',
69
+ '/environments/environment.prod.ts?',
70
+ ]);
71
+ }
72
+ function removeAppServiceFile(tree, projectSourceRoot) {
73
+ var _a, _b;
74
+ const appServiceFilePath = (0, path_1.join)(projectSourceRoot, 'app', 'app.service.ts');
75
+ if (tree.exists(appServiceFilePath)) {
76
+ if ((_b = (_a = tree.read(appServiceFilePath)) === null || _a === void 0 ? void 0 : _a.toString('utf-8')) === null || _b === void 0 ? void 0 : _b.includes('return { message: \'Hello API\' };')) {
77
+ console.warn('Remove the app service file');
78
+ tree.delete(appServiceFilePath);
79
+ if (tree.exists((0, path_1.join)(projectSourceRoot, 'app', 'app.service.spec.ts'))) {
80
+ console.warn('Remove the app service spec file');
81
+ tree.delete((0, path_1.join)(projectSourceRoot, 'app', 'app.service.spec.ts'));
82
+ }
83
+ else {
84
+ console.warn('The app service spec file does not exists');
85
+ }
86
+ }
87
+ else {
88
+ console.warn('The app service file does not contains the default method');
89
+ }
90
+ }
91
+ else {
92
+ console.warn('The app service file does not exists');
93
+ }
94
+ }
95
+ function removeAppControllerSpecFile(tree, projectSourceRoot) {
96
+ var _a, _b;
97
+ const appControllerSpecFilePath = (0, path_1.join)(projectSourceRoot, 'app', 'app.controller.spec.ts');
98
+ if (tree.exists(appControllerSpecFilePath)) {
99
+ if ((_b = (_a = tree.read(appControllerSpecFilePath)) === null || _a === void 0 ? void 0 : _a.toString('utf-8')) === null || _b === void 0 ? void 0 : _b.includes('should return "Hello API"')) {
100
+ console.warn('Remove the app controller spec file');
101
+ tree.delete(appControllerSpecFilePath);
102
+ }
103
+ else {
104
+ console.warn('The app controller spec file does not contains the default test');
105
+ }
106
+ }
107
+ else {
108
+ console.warn('The app controller spec file does not exists');
109
+ }
110
+ }
13
111
  function skipProject(tree, options, project, projectName) {
14
112
  if ((0, skip_non_nest_project_1.SkipNonNestProject)(tree, options, project, projectName)) {
15
113
  return true;
@@ -23,10 +121,12 @@ function setGeneralTargetDefaults(tree) {
23
121
  const nxJson = (0, devkit_1.readNxJson)(tree);
24
122
  (0, workspace_utilities_1.CoerceTargetDefaultsDependency)(nxJson, 'build', 'generate-package-json');
25
123
  (0, workspace_utilities_1.CoerceTargetDefaultsDependency)(nxJson, 'generate-open-api', 'swagger-generate');
124
+ (0, workspace_utilities_1.CoerceNxJsonCacheableOperation)(nxJson, 'generate-package-json', 'generate-open-api', 'swagger-generate', 'swagger-build');
26
125
  (0, devkit_1.updateNxJson)(tree, nxJson);
27
126
  }
28
127
  function updateProjectTargets(project) {
29
- var _a, _b, _c;
128
+ var _a, _b, _c, _d, _e;
129
+ var _f, _g;
30
130
  (0, workspace_utilities_1.CoerceTarget)(project, 'generate-package-json', {
31
131
  executor: '@rxap/plugin-nestjs:package-json',
32
132
  configurations: {
@@ -40,7 +140,7 @@ function updateProjectTargets(project) {
40
140
  (0, workspace_utilities_1.CoerceTarget)(project, 'generate-open-api', {
41
141
  executor: '@rxap/plugin-library:run-generator',
42
142
  options: {
43
- generator: '@rxap/schematics-open-api:generate',
143
+ generator: '@rxap/plugin-open-api:generate',
44
144
  options: {
45
145
  project: `open-api-${project.name}`,
46
146
  path: `${outputPath.replace('dist/', 'dist/swagger/')}/openapi.json`,
@@ -48,14 +148,62 @@ function updateProjectTargets(project) {
48
148
  },
49
149
  },
50
150
  });
151
+ (0, workspace_utilities_1.CoerceTarget)(project, 'build', {
152
+ options: {
153
+ generatePackageJson: true,
154
+ },
155
+ configurations: {
156
+ production: {
157
+ fileReplacements: [
158
+ {
159
+ replace: `${project.sourceRoot}/environments/environment.ts`,
160
+ with: `${project.sourceRoot}/environments/environment.prod.ts`,
161
+ },
162
+ ],
163
+ },
164
+ development: {
165
+ progress: true,
166
+ },
167
+ },
168
+ }, workspace_utilities_1.Strategy.OVERWRITE);
169
+ if (project.targets['docker']) {
170
+ (_d = (_f = project.targets['docker']).options) !== null && _d !== void 0 ? _d : (_f.options = {});
171
+ (_e = (_g = project.targets['docker'].options).dockerfile) !== null && _e !== void 0 ? _e : (_g.dockerfile = 'shared/nestjs/Dockerfile');
172
+ }
51
173
  }
52
174
  function updateGitIgnore(tree, project) {
53
175
  (0, generator_utilities_1.CoerceIgnorePattern)(tree, (0, path_1.join)(project.root, '.gitignore'), ['package.json']);
54
176
  }
177
+ function addDependencies(tree, options) {
178
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
179
+ yield (0, workspace_utilities_1.AddPackageJsonDependency)(tree, '@nestjs/throttler', 'latest', { soft: true });
180
+ yield (0, workspace_utilities_1.AddPackageJsonDependency)(tree, 'cookie-parser', 'latest', { soft: true });
181
+ yield (0, workspace_utilities_1.AddPackageJsonDependency)(tree, '@nestjs/config', 'latest', { soft: true });
182
+ yield (0, workspace_utilities_1.AddPackageJsonDependency)(tree, 'joi', 'latest', { soft: true });
183
+ yield (0, workspace_utilities_1.AddPackageJsonDependency)(tree, '@rxap/nest-utilities', 'latest', { soft: true });
184
+ yield (0, workspace_utilities_1.AddPackageJsonDependency)(tree, '@rxap/nest-server', 'latest', { soft: true });
185
+ yield (0, workspace_utilities_1.AddPackageJsonDevDependency)(tree, '@types/cookie-parser', 'latest', { soft: true });
186
+ yield (0, workspace_utilities_1.AddPackageJsonDevDependency)(tree, '@types/csurf', 'latest', { soft: true });
187
+ yield (0, workspace_utilities_1.AddPackageJsonDevDependency)(tree, '@rxap/plugin-application', 'latest', { soft: true });
188
+ yield (0, workspace_utilities_1.AddPackageJsonDevDependency)(tree, '@rxap/plugin-docker', 'latest', { soft: true });
189
+ switch (options.platform) {
190
+ case 'express':
191
+ yield (0, workspace_utilities_1.AddPackageJsonDependency)(tree, '@nestjs/platform-express', 'latest', { soft: true });
192
+ yield (0, workspace_utilities_1.AddPackageJsonDependency)(tree, 'helmet', 'latest', { soft: true });
193
+ break;
194
+ case 'fastify':
195
+ yield (0, workspace_utilities_1.AddPackageJsonDependency)(tree, '@nestjs/platform-fastify', 'latest', { soft: true });
196
+ yield (0, workspace_utilities_1.AddPackageJsonDependency)(tree, '@fastify/helmet', 'latest', { soft: true });
197
+ break;
198
+ }
199
+ });
200
+ }
55
201
  function createOpenApiClientSdkLibrary(tree, project, projects) {
202
+ var _a;
56
203
  return tslib_1.__awaiter(this, void 0, void 0, function* () {
57
204
  const openApiProjectName = `open-api-${project.name}`;
58
205
  if (projects.has(openApiProjectName)) {
206
+ console.log(`Open api client sdk library for project ${project.name} already exists`);
59
207
  return;
60
208
  }
61
209
  const projectRoot = project.root;
@@ -63,14 +211,20 @@ function createOpenApiClientSdkLibrary(tree, project, projects) {
63
211
  const name = fragments.pop();
64
212
  fragments.shift(); // remove the root folder
65
213
  const directory = `open-api/${fragments.join('/')}`;
66
- yield (0, library_1.default)(tree, {
67
- name,
68
- directory,
69
- unitTestRunner: 'none',
70
- tags: 'open-api',
71
- buildable: false,
72
- bundler: 'none',
73
- });
214
+ try {
215
+ yield (0, library_1.default)(tree, {
216
+ name,
217
+ directory,
218
+ unitTestRunner: 'none',
219
+ tags: 'open-api',
220
+ buildable: false,
221
+ bundler: 'none',
222
+ });
223
+ }
224
+ catch (e) {
225
+ console.warn(`Can't create open api client sdk library: ${e.message}`);
226
+ return;
227
+ }
74
228
  let tsConfig;
75
229
  try {
76
230
  tsConfig = JSON.parse(tree.read('tsconfig.base.json').toString('utf-8'));
@@ -82,35 +236,406 @@ function createOpenApiClientSdkLibrary(tree, project, projects) {
82
236
  if (!projects.has(openApiProjectName)) {
83
237
  throw new Error(`Can't find project ${openApiProjectName}`);
84
238
  }
85
- const openApiProjectRoot = projects.get(openApiProjectName).root;
239
+ const openApiProjectConfiguration = projects.get(openApiProjectName);
240
+ const openApiProjectRoot = openApiProjectConfiguration.root;
86
241
  delete tsConfig.compilerOptions.paths[`${directory}/${name}`];
87
242
  tsConfig.compilerOptions.paths[`${openApiProjectName}/*`] = [`${openApiProjectRoot}/src/lib/*`];
88
243
  tree.write('tsconfig.base.json', JSON.stringify(tsConfig, null, 2));
89
244
  tree.write(`${openApiProjectRoot}/src/index.ts`, 'export {};');
90
245
  tree.delete(`${openApiProjectRoot}/src/lib/${openApiProjectName}.ts`);
91
246
  tree.delete(`${openApiProjectRoot}/README.md`);
247
+ (_a = openApiProjectConfiguration.implicitDependencies) !== null && _a !== void 0 ? _a : (openApiProjectConfiguration.implicitDependencies = []);
248
+ openApiProjectConfiguration.implicitDependencies.push(project.name);
249
+ (0, devkit_1.updateProjectConfiguration)(tree, openApiProjectName, openApiProjectConfiguration);
250
+ });
251
+ }
252
+ function getPort(tree, options, projectSourceRoot) {
253
+ if (options.port && options.projects.length === 1) {
254
+ return options.port;
255
+ }
256
+ if (tree.exists((0, path_1.join)(projectSourceRoot, 'app', 'app.config.ts'))) {
257
+ const match = tree.read((0, path_1.join)(projectSourceRoot, 'app', 'app.config.ts'))
258
+ .toString()
259
+ .match(/validationSchema\['PORT'\] = Joi.number\(\).default\((\d+)\);/);
260
+ if (match) {
261
+ return parseInt(match[1]);
262
+ }
263
+ }
264
+ if (tree.exists((0, path_1.join)(projectSourceRoot, 'app', 'app.module.ts'))) {
265
+ const match = tree.read((0, path_1.join)(projectSourceRoot, 'app', 'app.module.ts'))
266
+ .toString()
267
+ .match(/PORT: Joi.number\(\).default\((\d+)\)/);
268
+ if (match) {
269
+ return parseInt(match[1]);
270
+ }
271
+ }
272
+ return Math.floor(Math.random() * 1000) + 3000;
273
+ }
274
+ const MAIN_NEST_APP_OPTIONS_STATEMENT = 'const options: NestApplicationOptions = {};';
275
+ const MAIN_BOOTSTRAP_OPTIONS_STATEMENT = 'const bootstrapOptions: Partial<MonolithicBootstrapOptions> = {};';
276
+ const MAIN_SERVER_STATEMENT = 'const server = new Monolithic<NestApplicationOptions, NestExpressApplication>(AppModule, environment, options, bootstrapOptions);';
277
+ const MAIN_BOOTSTRAP_STATEMENT = 'server.bootstrap().catch((e) => console.error(\'Server bootstrap failed: \' + e.message));';
278
+ const MAIN_SETUP_HELMET_STATEMENT = 'server.after(SetupHelmet());';
279
+ const MAIN_SETUP_COOKIE_STATEMENT = 'server.after(SetupCookieParser());';
280
+ const MAIN_SETUP_CORS_STATEMENT = 'server.after(SetupCors());';
281
+ function assertMainStatements(sourceFile) {
282
+ var _a;
283
+ const statements = [];
284
+ statements.push('const options: NestApplicationOptions = {');
285
+ statements.push('const bootstrapOptions: Partial<MonolithicBootstrapOptions> = {');
286
+ statements.push('const server = new Monolithic<NestApplicationOptions, NestExpressApplication>(AppModule, environment, options, bootstrapOptions);');
287
+ const existingStatements = (_a = sourceFile.getStatements().map(s => s.getText())) !== null && _a !== void 0 ? _a : [];
288
+ for (const statement of statements) {
289
+ if (!existingStatements.includes(statement)) {
290
+ console.error(`Missing statement from main.ts: ${statement}`);
291
+ sourceFile.set({
292
+ statements: [
293
+ MAIN_NEST_APP_OPTIONS_STATEMENT,
294
+ MAIN_BOOTSTRAP_OPTIONS_STATEMENT,
295
+ MAIN_SERVER_STATEMENT,
296
+ MAIN_SETUP_HELMET_STATEMENT,
297
+ MAIN_SETUP_COOKIE_STATEMENT,
298
+ MAIN_SETUP_CORS_STATEMENT,
299
+ MAIN_BOOTSTRAP_STATEMENT,
300
+ ],
301
+ });
302
+ (0, ts_morph_1.CoerceImports)(sourceFile, [
303
+ {
304
+ moduleSpecifier: '@nestjs/common',
305
+ namedImports: ['NestApplicationOptions'],
306
+ },
307
+ {
308
+ moduleSpecifier: '@nestjs/platform-express',
309
+ namedImports: ['NestExpressApplication'],
310
+ },
311
+ {
312
+ moduleSpecifier: '@rxap/nest-server',
313
+ namedImports: [
314
+ 'MonolithicBootstrapOptions',
315
+ 'Monolithic',
316
+ 'SetupHelmet',
317
+ 'SetupCookieParser',
318
+ 'SetupCors',
319
+ ],
320
+ },
321
+ {
322
+ moduleSpecifier: './app/app.module',
323
+ namedImports: ['AppModule'],
324
+ },
325
+ {
326
+ moduleSpecifier: './environments/environment',
327
+ namedImports: ['environment'],
328
+ },
329
+ ]);
330
+ return;
331
+ }
332
+ }
333
+ }
334
+ function updateMainFile(tree, project, projectName, options) {
335
+ (0, workspace_ts_morph_1.TsMorphAngularProjectTransform)(tree, {
336
+ project: project.name,
337
+ // directory: '..' // to move from the apps/demo/src/app folder into the apps/demo/src folder
338
+ }, (project, [sourceFile]) => {
339
+ var _a;
340
+ assertMainStatements(sourceFile);
341
+ const importDeclarations = [];
342
+ const statements = [];
343
+ if (options.sentry) {
344
+ importDeclarations.push({
345
+ moduleSpecifier: '@rxap/nest-sentry',
346
+ namedImports: ['SetupSentryLogger'],
347
+ });
348
+ statements.push('server.after(SetupSentryLogger());');
349
+ }
350
+ else {
351
+ importDeclarations.push({
352
+ moduleSpecifier: '@rxap/nest-logger',
353
+ namedImports: ['RxapLogger'],
354
+ });
355
+ statements.push('server.after(app => app.useLogger(new RxapLogger()));');
356
+ }
357
+ if (options.validator) {
358
+ importDeclarations.push({
359
+ moduleSpecifier: '@rxap/nest-server',
360
+ namedImports: ['ValidationPipeSetup'],
361
+ });
362
+ statements.push('server.after(ValidationPipeSetup());');
363
+ }
364
+ if (options.swaggerLive) {
365
+ importDeclarations.push({
366
+ moduleSpecifier: '@rxap/nest-server',
367
+ namedImports: ['SetupSwagger'],
368
+ });
369
+ statements.push('server.after(SetupSwagger());');
370
+ }
371
+ if (options.statusRegister) {
372
+ importDeclarations.push({
373
+ moduleSpecifier: '@rxap/nest-server',
374
+ namedImports: ['RegisterToStatusService'],
375
+ });
376
+ statements.push('server.ready(RegisterToStatusService());');
377
+ }
378
+ (0, ts_morph_1.CoerceImports)(sourceFile, importDeclarations);
379
+ for (let i = 0; i < statements.length; i++) {
380
+ const statement = statements[i];
381
+ const lastStatement = i > 0 ? statements[i - 1] : null;
382
+ const nestStatement = i < statements.length - 1 ? statements[i + 1] : null;
383
+ const existingStatements = (_a = sourceFile.getStatements().map(s => s.getText())) !== null && _a !== void 0 ? _a : [];
384
+ if (!existingStatements.includes(statement)) {
385
+ let index;
386
+ if (lastStatement) {
387
+ index = existingStatements.findIndex(s => s.includes(lastStatement)) + 1;
388
+ }
389
+ else if (nestStatement) {
390
+ index = existingStatements.findIndex(s => s.includes(nestStatement));
391
+ }
392
+ else {
393
+ index = existingStatements.findIndex(s => s.includes(MAIN_BOOTSTRAP_STATEMENT));
394
+ }
395
+ console.log(`insert statement: ${statement} at index ${index}`);
396
+ sourceFile.insertStatements(index, statement);
397
+ }
398
+ }
399
+ if (projectName === 'service-status') {
400
+ const variableDeclaration = (0, ts_morph_1.CoerceVariableDeclaration)(sourceFile, 'bootstrapOptions', { initializer: '{}' });
401
+ const objectLiteralExpression = variableDeclaration.getInitializerIfKindOrThrow(ts_morph_2.SyntaxKind.ObjectLiteralExpression);
402
+ let objectLiteralElementLike = objectLiteralExpression.getProperty('globalPrefixOptions');
403
+ if (!objectLiteralElementLike) {
404
+ objectLiteralElementLike = objectLiteralExpression.addPropertyAssignment({
405
+ name: 'globalPrefixOptions',
406
+ initializer: '{}',
407
+ });
408
+ }
409
+ const gpoPropertyAssigment = objectLiteralElementLike.asKindOrThrow(ts_morph_2.SyntaxKind.PropertyAssignment);
410
+ const gpoObjectLiteralExpression = gpoPropertyAssigment.getInitializerIfKindOrThrow(ts_morph_2.SyntaxKind.ObjectLiteralExpression);
411
+ let gpoElementLike = gpoObjectLiteralExpression.getProperty('exclude');
412
+ if (!gpoElementLike) {
413
+ gpoElementLike = gpoObjectLiteralExpression.addPropertyAssignment({
414
+ name: 'exclude',
415
+ initializer: `[ '/health(.*)', '/info', '/openapi', '/register' ]`,
416
+ });
417
+ }
418
+ }
419
+ }, ['main.ts']);
420
+ }
421
+ function updateTags(project, options) {
422
+ const tags = ['backend', 'nest', 'service'];
423
+ if (options.sentry) {
424
+ tags.push('sentry');
425
+ }
426
+ if (options.swagger) {
427
+ tags.push('swagger');
428
+ }
429
+ if (options.jwt) {
430
+ tags.push('jwt');
431
+ }
432
+ if (options.healthIndicator) {
433
+ tags.push('health-indicator');
434
+ }
435
+ if (options.openApi) {
436
+ tags.push('openapi');
437
+ }
438
+ if (options.platform) {
439
+ tags.push(options.platform);
440
+ }
441
+ (0, generator_utilities_1.CoerceProjectTags)(project, tags);
442
+ }
443
+ function updateApiConfigurationFile(tree, projectName, apiPrefix, apiConfigurationFile) {
444
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
445
+ if (apiConfigurationFile) {
446
+ yield (0, workspace_utilities_1.UpdateJsonFile)(tree, json => {
447
+ json[projectName] = { baseUrl: `/${apiPrefix}` };
448
+ }, apiConfigurationFile, { create: true });
449
+ }
92
450
  });
93
451
  }
94
452
  function initApplicationGenerator(tree, options) {
453
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r;
95
454
  return tslib_1.__awaiter(this, void 0, void 0, function* () {
455
+ (_a = options.sentry) !== null && _a !== void 0 ? _a : (options.sentry = true);
456
+ (_b = options.swagger) !== null && _b !== void 0 ? _b : (options.swagger = true);
457
+ (_c = options.healthIndicator) !== null && _c !== void 0 ? _c : (options.healthIndicator = true);
458
+ (_d = options.platform) !== null && _d !== void 0 ? _d : (options.platform = 'express');
459
+ (_e = options.validator) !== null && _e !== void 0 ? _e : (options.validator = true);
460
+ (_f = options.healthIndicatorList) !== null && _f !== void 0 ? _f : (options.healthIndicatorList = []);
461
+ (_g = options.port) !== null && _g !== void 0 ? _g : (options.port = undefined);
462
+ (_h = options.apiPrefix) !== null && _h !== void 0 ? _h : (options.apiPrefix = undefined);
463
+ (_j = options.sentryDsn) !== null && _j !== void 0 ? _j : (options.sentryDsn = undefined);
464
+ (_k = options.overwrite) !== null && _k !== void 0 ? _k : (options.overwrite = false);
465
+ (_l = options.openApi) !== null && _l !== void 0 ? _l : (options.openApi = false);
466
+ (_m = options.jwt) !== null && _m !== void 0 ? _m : (options.jwt = false);
467
+ (_o = options.statusRegister) !== null && _o !== void 0 ? _o : (options.statusRegister = true);
468
+ (_p = options.apiConfigurationFile) !== null && _p !== void 0 ? _p : (options.apiConfigurationFile = 'shared/service/configuration/latest/config.api.json');
96
469
  console.log('nestjs application init generator:', options);
470
+ yield (0, workspace_utilities_1.AddPackageJsonDependency)(tree, '@rxap/nest-server', 'latest', { soft: true });
471
+ yield (0, workspace_utilities_1.AddPackageJsonDependency)(tree, '@rxap/nest-utilities', 'latest', { soft: true });
472
+ yield (0, workspace_utilities_1.AddPackageJsonDependency)(tree, '@rxap/nest-logger', 'latest', { soft: true });
473
+ yield (0, workspace_utilities_1.AddPackageJsonDependency)(tree, '@nestjs/terminus', 'latest', { soft: true });
474
+ yield (0, workspace_utilities_1.AddPackageJsonDependency)(tree, '@nestjs/config', 'latest', { soft: true });
475
+ yield (0, workspace_utilities_1.AddPackageJsonDependency)(tree, 'joi', 'latest', { soft: true });
476
+ yield (0, workspace_utilities_1.AddPackageJsonDependency)(tree, '@rxap/plugin-nestjs', 'latest', { soft: true });
477
+ yield (0, workspace_utilities_1.AddPackageJsonDependency)(tree, '@rxap/plugin-library', 'latest', { soft: true });
478
+ yield (0, workspace_utilities_1.AddPackageJsonDependency)(tree, '@rxap/plugin-open-api', 'latest', { soft: true });
479
+ if (options.sentry) {
480
+ yield (0, workspace_utilities_1.AddPackageJsonDependency)(tree, '@rxap/nest-sentry', 'latest', { soft: true });
481
+ }
482
+ if (options.swagger) {
483
+ yield (0, workspace_utilities_1.AddPackageJsonDependency)(tree, '@nestjs/swagger', 'latest', { soft: true });
484
+ yield (0, workspace_utilities_1.AddPackageJsonDependency)(tree, '@rxap/workspace-open-api', 'latest', { soft: true });
485
+ }
486
+ if (options.jwt) {
487
+ yield (0, workspace_utilities_1.AddPackageJsonDependency)(tree, '@rxap/nest-jwt', 'latest', { soft: true });
488
+ }
489
+ if (options.openApi) {
490
+ yield (0, workspace_utilities_1.AddPackageJsonDependency)(tree, '@rxap/nest-open-api', 'latest', { soft: true });
491
+ }
492
+ (0, workspace_utilities_1.CoerceFilesStructure)(tree, {
493
+ srcFolder: (0, path_1.join)(__dirname, 'files', 'shared'),
494
+ target: 'shared/nestjs',
495
+ overwrite: options.overwrite,
496
+ });
97
497
  setGeneralTargetDefaults(tree);
98
- const projects = (0, devkit_1.getProjects)(tree);
99
- for (const [projectName, project] of projects.entries()) {
100
- if (skipProject(tree, options, project, projectName)) {
101
- continue;
102
- }
103
- console.log(`init project: ${projectName}`);
104
- updateProjectTargets(project);
105
- updateGitIgnore(tree, project);
106
- yield createOpenApiClientSdkLibrary(tree, project, projects);
107
- // apply changes to the project configuration
108
- (0, devkit_1.updateProjectConfiguration)(tree, projectName, project);
109
- if (options.swagger) {
110
- yield (0, generator_1.default)(tree, { project: projectName });
111
- }
112
- if (options.legacy) {
113
- yield (0, ngcli_adapter_1.wrapAngularDevkitSchematic)('@rxap/schematic-nestjs', 'init')(tree, Object.assign(Object.assign({}, options), { swagger: false, project: projectName }));
498
+ yield addDependencies(tree, options);
499
+ if (!options.skipProjects) {
500
+ const projects = (0, devkit_1.getProjects)(tree);
501
+ for (const [projectName, project] of projects.entries()) {
502
+ if (skipProject(tree, options, project, projectName)) {
503
+ continue;
504
+ }
505
+ const projectSourceRoot = project.sourceRoot;
506
+ if (!projectSourceRoot) {
507
+ throw new Error(`Can't find project source root for project ${projectName}`);
508
+ }
509
+ const port = getPort(tree, options, projectSourceRoot);
510
+ const globalApiPrefix = (0, workspace_utilities_1.GetNestApiPrefix)(tree, options, projectSourceRoot, projectName);
511
+ console.log(`init project: ${projectName}`);
512
+ updateProjectTargets(project);
513
+ updateGitIgnore(tree, project);
514
+ updateTags(project, options);
515
+ yield updateApiConfigurationFile(tree, projectName, globalApiPrefix, options.apiConfigurationFile);
516
+ yield createOpenApiClientSdkLibrary(tree, project, projects);
517
+ // apply changes to the project configuration
518
+ (0, devkit_1.updateProjectConfiguration)(tree, projectName, project);
519
+ coerceEnvironmentFiles(tree, {
520
+ project: projectName,
521
+ sentry: options.sentry,
522
+ overwrite: options.overwrite,
523
+ });
524
+ (0, workspace_ts_morph_1.TsMorphNestProjectTransform)(tree, { project: projectName }, (project, [moduleSourceFile, controllerSourceFile, configSourceFile]) => {
525
+ (0, ts_morph_1.CoerceNestAppModule)(moduleSourceFile);
526
+ (0, ts_morph_1.CoerceNestAppController)(controllerSourceFile);
527
+ (0, ts_morph_1.CoerceNestThrottlerModuleImport)(moduleSourceFile, { overwrite: options.overwrite });
528
+ (0, ts_morph_1.CoerceNestConfigModuleImport)(moduleSourceFile, { overwrite: options.overwrite });
529
+ (0, ts_morph_1.CoerceAppGuardProvider)(moduleSourceFile);
530
+ (0, ts_morph_1.CoerceNestEnvironmentProvider)(moduleSourceFile);
531
+ (0, ts_morph_1.CoerceNestLoggerProvider)(moduleSourceFile);
532
+ const itemList = (0, extract_existing_config_validation_1.ExtractExistingConfigValidation)(moduleSourceFile);
533
+ for (const item of [
534
+ {
535
+ name: 'PORT',
536
+ type: 'number',
537
+ defaultValue: port.toFixed(0),
538
+ },
539
+ {
540
+ name: 'GLOBAL_API_PREFIX',
541
+ defaultValue: w => w.quote(globalApiPrefix),
542
+ },
543
+ {
544
+ name: 'THROTTLER_TTL',
545
+ defaultValue: '1',
546
+ },
547
+ {
548
+ name: 'THROTTLER_LIMIT',
549
+ defaultValue: '10',
550
+ },
551
+ {
552
+ name: 'COOKIE_SECRET',
553
+ defaultValue: 'GenerateRandomString()',
554
+ },
555
+ ]) {
556
+ if (!itemList.find(i => i.name === item.name)) {
557
+ itemList.push(item);
558
+ }
559
+ }
560
+ if (options.statusRegister && projectName !== 'service-status') {
561
+ if (!itemList.find(i => i.name === 'STATUS_SERVICE_BASE_URL')) {
562
+ itemList.push({
563
+ name: 'STATUS_SERVICE_BASE_URL',
564
+ defaultValue: `environment.production ? 'http://rxap-service-status:3000' : 'http://localhost:5300'`,
565
+ });
566
+ }
567
+ (0, ts_morph_1.CoerceImports)(configSourceFile, {
568
+ namespaceImport: 'process',
569
+ moduleSpecifier: 'process',
570
+ });
571
+ }
572
+ (0, ts_morph_1.CoerceNestAppConfig)(configSourceFile, {
573
+ itemList,
574
+ overwrite: options.overwrite,
575
+ });
576
+ (0, ts_morph_1.CoerceImports)(configSourceFile, {
577
+ namedImports: ['GenerateRandomString'],
578
+ moduleSpecifier: '@rxap/utilities',
579
+ });
580
+ }, [
581
+ '/app/app.module.ts',
582
+ '/app/app.controller.ts',
583
+ '/app/app.config.ts?',
584
+ ]);
585
+ removeAppServiceFile(tree, projectSourceRoot);
586
+ removeAppControllerSpecFile(tree, projectSourceRoot);
587
+ if (options.generateMain) {
588
+ updateMainFile(tree, project, projectName, options);
589
+ }
590
+ if (options.healthIndicator || ((_q = options.healthIndicatorList) === null || _q === void 0 ? void 0 : _q.length)) {
591
+ if ((_r = options.healthIndicatorList) === null || _r === void 0 ? void 0 : _r.length) {
592
+ for (const healthIndicator of options.healthIndicatorList) {
593
+ yield (0, generator_2.default)(tree, {
594
+ name: healthIndicator,
595
+ project: projectName,
596
+ overwrite: options.overwrite,
597
+ });
598
+ }
599
+ }
600
+ else {
601
+ yield (0, generator_1.default)(tree, {
602
+ project: projectName,
603
+ overwrite: options.overwrite,
604
+ });
605
+ }
606
+ }
607
+ if (options.sentry) {
608
+ yield (0, generator_5.default)(tree, {
609
+ project: projectName,
610
+ dsn: options.sentryDsn,
611
+ required: !!options.sentryDsn,
612
+ overwrite: options.overwrite,
613
+ });
614
+ }
615
+ if (options.validator) {
616
+ yield (0, generator_7.default)(tree, {
617
+ project: projectName,
618
+ overwrite: options.overwrite,
619
+ });
620
+ }
621
+ if (options.openApi) {
622
+ yield (0, generator_4.default)(tree, {
623
+ project: projectName,
624
+ overwrite: options.overwrite,
625
+ });
626
+ }
627
+ if (options.jwt) {
628
+ yield (0, generator_3.default)(tree, {
629
+ project: projectName,
630
+ overwrite: options.overwrite,
631
+ });
632
+ }
633
+ if (options.swagger !== false) {
634
+ yield (0, generator_6.default)(tree, {
635
+ project: projectName,
636
+ overwrite: options.overwrite,
637
+ });
638
+ }
114
639
  }
115
640
  }
116
641
  });