@rxap/plugin-nestjs 16.1.0-dev.9 → 16.1.1-dev.0

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