@rxap/plugin-nestjs 16.1.0-dev.3 → 16.1.0-dev.31

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