@ackee/create-node-app 1.0.1 → 2.0.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 (149) hide show
  1. package/AUTHORS +2 -1
  2. package/README.md +26 -18
  3. package/docs/development.md +42 -0
  4. package/lib/Bootstrap.js +106 -65
  5. package/lib/Bootstrap.js.map +1 -1
  6. package/lib/Builder.js +111 -0
  7. package/lib/Builder.js.map +1 -0
  8. package/lib/Files.js +21 -0
  9. package/lib/Files.js.map +1 -0
  10. package/lib/Logger.js +26 -8
  11. package/lib/Logger.js.map +1 -1
  12. package/lib/Mergers/ConfigMerger.js +22 -0
  13. package/lib/Mergers/ConfigMerger.js.map +1 -0
  14. package/lib/Mergers/ContainerMerger.js +172 -0
  15. package/lib/Mergers/ContainerMerger.js.map +1 -0
  16. package/lib/Mergers/EnvJsoncMerger.js +20 -0
  17. package/lib/Mergers/EnvJsoncMerger.js.map +1 -0
  18. package/lib/Mergers/Merger.js +36 -0
  19. package/lib/Mergers/Merger.js.map +1 -0
  20. package/lib/Mergers/PackageJsonMerger.js +36 -0
  21. package/lib/Mergers/PackageJsonMerger.js.map +1 -0
  22. package/lib/Npm.js +40 -12
  23. package/lib/Npm.js.map +1 -1
  24. package/lib/PackageJson.js +4 -4
  25. package/lib/PackageJson.js.map +1 -1
  26. package/lib/StarterLoader.js +86 -0
  27. package/lib/StarterLoader.js.map +1 -0
  28. package/package.json +8 -5
  29. package/src/Bootstrap.ts +123 -82
  30. package/src/Builder.ts +172 -0
  31. package/src/Files.ts +22 -0
  32. package/src/Logger.ts +26 -7
  33. package/src/Mergers/ConfigMerger.ts +28 -0
  34. package/src/Mergers/ContainerMerger.ts +241 -0
  35. package/src/Mergers/EnvJsoncMerger.ts +24 -0
  36. package/src/Mergers/Merger.ts +51 -0
  37. package/src/Mergers/PackageJsonMerger.ts +45 -0
  38. package/src/Npm.ts +60 -15
  39. package/src/PackageJson.ts +6 -4
  40. package/src/Starter.ts +2 -2
  41. package/src/StarterLoader.ts +148 -0
  42. package/starter/{cloudrun → _base}/.env.jsonc +1 -5
  43. package/starter/{cloudrun → _base}/.eslintrc.cjs +3 -2
  44. package/starter/_base/README.md +53 -0
  45. package/starter/_base/package.json +45 -0
  46. package/starter/{cloudrun → _base}/src/adapters/pino.logger.ts +1 -1
  47. package/starter/_base/src/config.ts +16 -0
  48. package/starter/{cloudrun-graphql → _base}/src/container.ts +3 -1
  49. package/starter/_base/src/index.ts +14 -0
  50. package/starter/{cloudrun → _base}/src/view/cli/README.md +2 -6
  51. package/starter/api/graphql/.env.jsonc +8 -0
  52. package/starter/{cloudrun-graphql → api/graphql}/.eslintrc.cjs +4 -5
  53. package/starter/api/graphql/node-app.jsonc +6 -0
  54. package/starter/api/graphql/package.json +36 -0
  55. package/starter/{cloudrun-graphql → api/graphql}/src/config.ts +0 -4
  56. package/starter/api/graphql/src/index.ts +11 -0
  57. package/starter/{cloudrun-graphql → api/graphql}/src/test/helloWorld.test.ts +14 -3
  58. package/starter/api/graphql/src/view/graphql/context-factory.ts +13 -0
  59. package/starter/{cloudrun-graphql → api/graphql}/src/view/server.ts +16 -6
  60. package/starter/api/rest/.env.jsonc +6 -0
  61. package/starter/api/rest/.eslintrc.cjs +8 -0
  62. package/starter/api/rest/node-app.jsonc +6 -0
  63. package/starter/api/rest/package.json +25 -0
  64. package/starter/{cloudrun → api/rest}/src/config.ts +0 -5
  65. package/starter/api/rest/src/container.ts +13 -0
  66. package/starter/{cloudrun → api/rest}/src/index.ts +4 -4
  67. package/starter/{cloudrun → api/rest}/src/test/health-check.test.ts +3 -5
  68. package/starter/{cloudrun → api/rest}/src/test/util/openapi-test.util.ts +3 -3
  69. package/starter/{cloudrun → api/rest}/src/view/rest/middleware/error-handler.ts +1 -1
  70. package/starter/{cloudrun → api/rest}/src/view/rest/routes.ts +1 -1
  71. package/starter/{cloudrun → api/rest}/src/view/rest/util/openapi.util.ts +19 -19
  72. package/starter/{cloudrun → api/rest}/src/view/server.ts +6 -4
  73. package/starter/infra/postgresql-knex/.env.jsonc +5 -0
  74. package/starter/{shared → infra/postgresql-knex}/docker-compose/docker-compose.yml +1 -1
  75. package/starter/infra/postgresql-knex/knexfile.ts +16 -0
  76. package/starter/infra/postgresql-knex/node-app.jsonc +6 -0
  77. package/starter/infra/postgresql-knex/package.json +13 -0
  78. package/starter/infra/postgresql-knex/src/adapters/knex.database.test.ts +21 -0
  79. package/starter/infra/postgresql-knex/src/adapters/knex.database.ts +14 -0
  80. package/starter/infra/postgresql-knex/src/adapters/repositories/migration.repository.ts +24 -0
  81. package/starter/infra/postgresql-knex/src/config.ts +14 -0
  82. package/starter/infra/postgresql-knex/src/container.ts +23 -0
  83. package/starter/infra/postgresql-knex/src/db/migration.template.ts +4 -0
  84. package/starter/infra/postgresql-knex/src/db/migrations/.gitkeep +0 -0
  85. package/starter/infra/postgresql-knex/src/db/seed.template.ts +3 -0
  86. package/starter/infra/postgresql-knex/src/db/seeds/.gitkeep +0 -0
  87. package/starter/infra/postgresql-knex/src/domain/ports/database.d.ts +4 -0
  88. package/starter/infra/postgresql-knex/src/domain/ports/repositories/migration.repository.d.ts +9 -0
  89. package/starter/infra/postgresql-knex/src/test/setup.ts +16 -0
  90. package/starter/{shared → pipeline/cloudrun-gitlab}/.gitlab-ci.yml +15 -6
  91. package/starter/pipeline/cloudrun-gitlab/node-app.jsonc +6 -0
  92. package/tsconfig.tsbuildinfo +1 -1
  93. package/lib/Toolbelt.js +0 -102
  94. package/lib/Toolbelt.js.map +0 -1
  95. package/lib/cloudrun/CloudRunStarter.js +0 -127
  96. package/lib/cloudrun/CloudRunStarter.js.map +0 -1
  97. package/lib/cloudrun-graphql/GraphQLStarter.js +0 -118
  98. package/lib/cloudrun-graphql/GraphQLStarter.js.map +0 -1
  99. package/src/Toolbelt.ts +0 -132
  100. package/src/cloudrun/CloudRunStarter.ts +0 -182
  101. package/src/cloudrun-graphql/GraphQLStarter.ts +0 -182
  102. package/starter/cloudrun/README.md +0 -69
  103. package/starter/cloudrun/src/container.ts +0 -18
  104. package/starter/cloudrun/src/context.ts +0 -39
  105. package/starter/cloudrun/src/domain/errors/codes.ts +0 -9
  106. package/starter/cloudrun/src/domain/errors/errors.ts +0 -25
  107. package/starter/cloudrun/src/domain/ports/logger.d.ts +0 -21
  108. package/starter/cloudrun-graphql/.env.jsonc +0 -12
  109. package/starter/cloudrun-graphql/README.md +0 -53
  110. package/starter/cloudrun-graphql/src/adapters/pino.logger.ts +0 -44
  111. package/starter/cloudrun-graphql/src/index.ts +0 -11
  112. package/starter/shared/.gitignore_ +0 -5
  113. package/starter/shared/ci-branch-config/common.env +0 -7
  114. package/starter/shared/ci-branch-config/development.env +0 -7
  115. package/starter/shared/ci-branch-config/master.env +0 -7
  116. package/starter/shared/ci-branch-config/stage.env +0 -7
  117. package/starter/shared/docker-compose/docker-compose.override.yml +0 -5
  118. package/starter/shared/jest.config.js +0 -12
  119. /package/starter/{shared → _base}/.dockerignore +0 -0
  120. /package/starter/{cloudrun → _base}/.eslint.tsconfig.json +0 -0
  121. /package/starter/{shared → _base}/.mocha-junit-config.json +0 -0
  122. /package/starter/{shared → _base}/.mocharc.json +0 -0
  123. /package/starter/{shared → _base}/.nvmrc +0 -0
  124. /package/starter/{shared → _base}/Dockerfile +0 -0
  125. /package/starter/{shared → _base}/prettier.config.cjs +0 -0
  126. /package/starter/{cloudrun-graphql → _base}/src/context.ts +0 -0
  127. /package/starter/{cloudrun-graphql → _base}/src/domain/errors/codes.ts +0 -0
  128. /package/starter/{cloudrun-graphql → _base}/src/domain/errors/errors.ts +0 -0
  129. /package/starter/{cloudrun-graphql → _base}/src/domain/ports/logger.d.ts +0 -0
  130. /package/starter/{shared → _base}/src/test/setup.ts +0 -0
  131. /package/starter/{cloudrun → _base}/src/view/cli/cli.ts +0 -0
  132. /package/starter/{shared → _base}/tsconfig.json +0 -0
  133. /package/starter/{cloudrun-graphql → api/graphql}/.eslint.tsconfig.json +0 -0
  134. /package/starter/{cloudrun-graphql → api/graphql}/codegen.yml +0 -0
  135. /package/starter/{cloudrun-graphql → api/graphql}/src/view/controller.ts +0 -0
  136. /package/starter/{cloudrun-graphql → api/graphql}/src/view/graphql/resolvers/greeting.resolver.ts +0 -0
  137. /package/starter/{cloudrun-graphql → api/graphql}/src/view/graphql/resolvers.ts +0 -0
  138. /package/starter/{cloudrun-graphql → api/graphql}/src/view/graphql/schema/schema.graphql +0 -0
  139. /package/starter/{cloudrun-graphql → api/graphql}/src/view/graphql/schema.ts +0 -0
  140. /package/starter/{cloudrun → api/rest}/src/domain/health-check.service.ts +0 -0
  141. /package/starter/{cloudrun → api/rest}/src/view/cli/openapi/generate.ts +0 -0
  142. /package/starter/{cloudrun/src/view/rest/controller → api/rest/src/view/rest/controllers}/health-check.controller.ts +0 -0
  143. /package/starter/{cloudrun → api/rest}/src/view/rest/middleware/context-middleware.ts +0 -0
  144. /package/starter/{cloudrun → api/rest}/src/view/rest/middleware/request-logger.ts +0 -0
  145. /package/starter/{cloudrun → api/rest}/src/view/rest/request.d.ts +0 -0
  146. /package/starter/{cloudrun → api/rest}/src/view/rest/spec/openapi.yml +0 -0
  147. /package/starter/{shared → infra/postgresql-knex}/docker-compose/docker-compose-entrypoint.sh +0 -0
  148. /package/starter/{shared → infra/postgresql-knex}/docker-compose/docker-compose.ci.yml +0 -0
  149. /package/starter/{shared → infra/postgresql-knex}/docker-compose/docker-compose.local.yml +0 -0
package/AUTHORS CHANGED
@@ -1,3 +1,4 @@
1
1
  Jiri Smolik <jiri.smolik@ackee.cz>
2
2
  Patrik Hoffmann <patrik.hoffmann@ackee.cz>
3
- Roman Filatov <roman.filatov@ackee.cz>
3
+ Roman Filatov <roman.filatov@ackee.cz>
4
+ Pavel Švagr <pavel.svagr@ackee.cz>
package/README.md CHANGED
@@ -6,34 +6,42 @@
6
6
 
7
7
  # Create Node App
8
8
 
9
- CLI to help you set up Node.js TypeScript project. Set up project includes
9
+ CLI to help you set up a Node.js TypeScript project. The setup includes:
10
10
 
11
11
  - code style tools (prettier, lint)
12
- - testing (using jest)
13
- - infrastructure files of your choice (Docker, etc.)
14
- - GitLab CI and npm ci-\* scripts (for Ackee CI/CD pipelines)
12
+ - testing (using mocha)
13
+ - infrastructure files of your choice (PostgreSQL etc.)
14
+ - CI pipeline templates (based on Ackee GitLab CI/CD pipelines)
15
15
 
16
16
  ## Usage
17
17
 
18
18
  Run directly from GitHub repo via npx:
19
19
 
20
20
  ```
21
- Usage: npm exec --ignore-scripts -- github:AckeeCZ/create-node-app STARTER [OPTIONS] [DIRECTORY]
22
-
23
- STARTER Which template to setup (required)
21
+ Usage: npm exec --ignore-scripts -- github:AckeeCZ/create-node-app [OPTIONS]
24
22
 
25
23
  Options:
26
- --dir, -d DIR Destination directory (default: ./node-app)
27
- --project-name, -n NAME Google Cloud project name (default: directory basename)
28
- --force, -f Overwrite existing destination directory if it's not empty
29
- --help, -h Show this help message
30
-
31
- Starters available:
32
- cloudrun Cloud Run + express
33
- cloudrun-graphql Cloud Run + graphql
24
+ -d, --dir Destination directory [string] [default: "./node-app"]
25
+ -D, --debug Enables debug logs [boolean] [default: false]
26
+ -n, --project-name Google Cloud project name [string] [default: "node-app"]
27
+ -f, --force Overwrite existing destination if it's not empty
28
+ [boolean] [default: false]
29
+ --api Selects API
30
+ [string] [choices: "graphql", "rest"]
31
+ --database Selects database as database
32
+ [string] [choices: "postgres-knex"]
33
+ --pipeline Selects pipeline
34
+ [string] [choices: "cloudrun-gitlab"]
35
+ --version Show version number [boolean]
36
+ --help Show help [boolean]
34
37
  ```
35
38
 
36
- Supported starter templates:
39
+ ## Setup options
37
40
 
38
- - [Cloud Run](./starter/cloudrun/README.md)
39
- - [GraphQL Cloud Run](./starter/cloudrun-graphql/README.md)
41
+ - API layer
42
+ - [RESTful](starter/api/rest/)
43
+ - [GraphQL](starter/api/graphql/)
44
+ - Database
45
+ - [PostgreSQL](starter/infra/postgresql-knex/) using [Knex](https://github.com/knex/knex)
46
+ - Pipelines
47
+ - [GitLab CloudRun](starter/pipeline/cloudrun-gitlab/)
@@ -0,0 +1,42 @@
1
+ # Development 👷
2
+
3
+ ## Starters
4
+
5
+ Starters are folders containing files and structure that can be optionally added to the final created repository by `create-node-app` (cna). The base folder structure and tooling that should be available in every application created by cna is located in the [\_base](../starter/_base) folder.
6
+
7
+ Each additional starter is an addition to this base. When a user selects a specific starter, all contents are copied into the final directory **except for specific files that require content merging**. Every file that is merged uses its own merger defined in the [Mergers](../src/Mergers/) directory.
8
+
9
+ Each starter directory must contain a `node-app.jsonc` configuration file that defines the starter's metadata for the cna.
10
+
11
+ ### Grouping and sorting
12
+
13
+ Starters are grouped into categories called "modules". These indicate that only one starter should be selected from each group. For example, under the API module there can be GraphQL and RESTful API starters, but the created application can have only one of those.
14
+
15
+ The order for injection into the final repository is alphabetical based on the module fields. The logic for grouping and sorting is as follows:
16
+
17
+ 1. **Base Starter**: The `_base` starter is always built first
18
+ 2. **Selected Starters**: Each selected starter is built in the order of user selection
19
+ 3. **npm install**: Dependencies are installed
20
+ 4. **Prebuild Scripts**: All `prebuild` scripts from selected starters are executed
21
+ 5. **Final Build**: `npm run build` is executed
22
+
23
+ ### Configuration
24
+
25
+ The `node-app.jsonc` file is a JSON with Comments file that configures how a starter behaves during the build process. The structure is as follows (fields with \* are required):
26
+
27
+ - `id`\* (`string`): Unique identifier
28
+ - `name`\* (`string`): Displayed in the CLI in the form of `<name> <module>` e.g. `RESTful API`
29
+ - `module`\* (`string`): The category this starter belongs to (e.g., "API", "database")
30
+ - `prebuild` (`string[]`): Array of npm script names to run before the main build
31
+ - `replace` (`string[]`): Array of file paths (relative to project root) where string replacements should be applied
32
+
33
+ #### Example RESTful API `node-app.jsonc`
34
+
35
+ ```jsonc
36
+ {
37
+ "module": "API",
38
+ "id": "rest",
39
+ "name": "RESTful",
40
+ "prebuild": ["generate:api"],
41
+ }
42
+ ```
package/lib/Bootstrap.js CHANGED
@@ -1,79 +1,120 @@
1
- import { CloudRunStarter } from './cloudrun/CloudRunStarter.js';
2
- import { Npm } from './Npm.js';
3
- import { Toolbelt } from './Toolbelt.js';
1
+ import inquirer from 'inquirer';
4
2
  import * as path from 'path';
5
- import { PackageJson } from './PackageJson.js';
6
- import { GraphQLStarter } from './cloudrun-graphql/GraphQLStarter.js';
3
+ import * as fs from 'fs';
7
4
  import yargs from 'yargs';
8
5
  import { hideBin } from 'yargs/helpers';
9
- import { logger } from './Logger.js';
6
+ import { Builder } from './Builder.js';
7
+ import { Logger } from './Logger.js';
8
+ import { Npm } from './Npm.js';
9
+ import { PackageJson } from './PackageJson.js';
10
+ import { StarterLoader } from './StarterLoader.js';
10
11
  export class Bootstrap {
11
12
  constructor() {
12
- this.starters = [new CloudRunStarter(), new GraphQLStarter()];
13
+ this.starterLoader = new StarterLoader();
14
+ }
15
+ async askMissingOptions(parsedArgs) {
16
+ const starters = [];
17
+ for (const module of this.starterLoader.getOptions()) {
18
+ const moduleOption = parsedArgs[module.name.toLowerCase()];
19
+ if (moduleOption) {
20
+ if (moduleOption !== 'none') {
21
+ starters.push(this.starterLoader.getStarter(moduleOption));
22
+ }
23
+ continue;
24
+ }
25
+ const answer = await inquirer.prompt({
26
+ type: 'list',
27
+ name: 'starter',
28
+ message: `Which ${module.name} would you like to use?`,
29
+ choices: [...module.starters, 'none'],
30
+ });
31
+ if (answer.starter !== 'none') {
32
+ starters.push(this.starterLoader.getStarter(answer.starter));
33
+ }
34
+ }
35
+ return starters;
13
36
  }
14
- runCLI(args) {
15
- const cli = yargs(hideBin(args))
16
- .usage('create-node-app <starter> [options]')
17
- .positional('starter', {
18
- name: 'starter',
19
- type: 'string',
20
- required: true,
21
- description: 'Which template to setup (required)',
22
- choices: this.starters.map(starter => starter.name),
23
- })
24
- .option('dir', {
25
- type: 'string',
26
- alias: 'd',
27
- default: './node-app',
28
- description: 'Destination directory',
29
- })
30
- .option('project-name', {
31
- type: 'string',
32
- alias: 'n',
33
- default: 'node-app',
34
- description: 'Google Cloud project name',
35
- })
36
- .option('force', {
37
- type: 'boolean',
38
- alias: 'f',
39
- default: false,
40
- description: "Overwrite existing destination directory if it's not empty",
41
- })
42
- .version('1.0.0')
43
- .help();
44
- const parsedArgs = cli.parseSync();
45
- const starterArg = parsedArgs._[0];
46
- const starter = this.starters.find(x => x.name === starterArg);
47
- const destination = path.normalize(parsedArgs.dir);
48
- if (!starter) {
49
- logger.info('Invalid starter');
50
- cli.showHelp();
51
- process.exit(1);
37
+ async runCLI(args) {
38
+ try {
39
+ let cli = yargs(hideBin(args))
40
+ .usage('create-node-app [options]')
41
+ .option('dir', {
42
+ type: 'string',
43
+ alias: 'd',
44
+ default: './node-app',
45
+ description: 'Destination directory',
46
+ })
47
+ .option('debug', {
48
+ type: 'boolean',
49
+ alias: 'D',
50
+ default: false,
51
+ description: 'Enables debug logs',
52
+ })
53
+ .option('project-name', {
54
+ type: 'string',
55
+ alias: 'n',
56
+ default: 'node-app',
57
+ description: 'Google Cloud project name',
58
+ })
59
+ .option('force', {
60
+ type: 'boolean',
61
+ alias: 'f',
62
+ default: false,
63
+ description: "Overwrite existing destination directory if it's not empty",
64
+ });
65
+ const starterOptions = this.starterLoader.getOptions();
66
+ for (const module of starterOptions) {
67
+ cli = cli.option(module.name.toLowerCase(), {
68
+ type: 'string',
69
+ choices: ['none', ...module.starters],
70
+ description: `Selects ${module.name}`,
71
+ });
72
+ }
73
+ cli = cli
74
+ .version('1.0.0')
75
+ .help()
76
+ .check(argv => {
77
+ for (const [key, val] of Object.entries(argv)) {
78
+ if (Array.isArray(val) && key !== '_') {
79
+ throw new Error(`Option --${key} specified multiple times`);
80
+ }
81
+ }
82
+ return true;
83
+ });
84
+ const parsedArgs = cli.parseSync();
85
+ const destination = path.normalize(parsedArgs.dir);
86
+ const logger = new Logger(parsedArgs.debug);
87
+ const npm = new Npm({ dir: destination, logger });
88
+ const packageJson = new PackageJson(npm, logger);
89
+ if (fs.existsSync(destination) && !parsedArgs.force) {
90
+ const answer = await inquirer.prompt({
91
+ type: 'confirm',
92
+ name: 'force',
93
+ message: `Destination directory "${destination}" already exists. Do you want to overwrite everything in it?`,
94
+ });
95
+ if (!answer.force) {
96
+ process.exit(0);
97
+ }
98
+ }
99
+ const starters = await this.askMissingOptions(parsedArgs);
100
+ const builder = new Builder({
101
+ npm,
102
+ logger,
103
+ packageJson,
104
+ starters,
105
+ destination: destination,
106
+ projectName: parsedArgs.projectName,
107
+ });
108
+ await builder.build();
52
109
  }
53
- logger.info(`starter=${starter.name}, destination=${destination}`);
54
- const npm = new Npm({ dir: destination });
55
- const packageJson = new PackageJson(npm);
56
- const toolbelt = new Toolbelt({
57
- npm,
58
- packageJson,
59
- assetDirectory: path.join(import.meta.dirname, '..', 'starter', starter.name),
60
- sharedDirectory: path.join(import.meta.dirname, '..', 'starter', 'shared'),
61
- destination: destination,
62
- projectName: parsedArgs.projectName,
63
- });
64
- starter.setToolbelt(toolbelt);
65
- if (!toolbelt.isDirectoryEmpty(destination)) {
66
- if (!parsedArgs.force) {
67
- logger.info(`Directory '${destination}' already exists and is not empty. Use --force or -f flag to overwrite the existing directory.`);
68
- process.exit(1);
110
+ catch (error) {
111
+ if (error instanceof Error && error.name === 'ExitPromptError') {
112
+ process.exit(0);
69
113
  }
70
114
  else {
71
- logger.info(`Overwriting existing directory '${destination}'`);
115
+ throw error;
72
116
  }
73
117
  }
74
- toolbelt.mkdir(destination, { overwrite: parsedArgs.force });
75
- toolbelt.npm.init();
76
- starter.install();
77
118
  }
78
119
  }
79
120
  //# sourceMappingURL=Bootstrap.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Bootstrap.js","sourceRoot":"","sources":["../src/Bootstrap.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Bootstrap.js","sourceRoot":"","sources":["../src/Bootstrap.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,UAAU,CAAA;AAC/B,OAAO,KAAK,IAAI,MAAM,MAAM,CAAA;AAC5B,OAAO,KAAK,EAAE,MAAM,IAAI,CAAA;AACxB,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AACvC,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AACtC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACpC,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAA;AAC9B,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAC9C,OAAO,EAAiB,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAWjE,MAAM,OAAO,SAAS;IAAtB;QACY,kBAAa,GAAG,IAAI,aAAa,EAAE,CAAA;IAsH/C,CAAC;IApHS,KAAK,CAAC,iBAAiB,CAAC,UAAsB;QACpD,MAAM,QAAQ,GAAoB,EAAE,CAAA;QAEpC,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,aAAa,CAAC,UAAU,EAAE,EAAE,CAAC;YACrD,MAAM,YAAY,GAAG,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,CAAW,CAAA;YACpE,IAAI,YAAY,EAAE,CAAC;gBACjB,IAAI,YAAY,KAAK,MAAM,EAAE,CAAC;oBAC5B,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC,CAAA;gBAC5D,CAAC;gBACD,SAAQ;YACV,CAAC;YAED,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAsB;gBACxD,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE,SAAS;gBACf,OAAO,EAAE,SAAS,MAAM,CAAC,IAAI,yBAAyB;gBACtD,OAAO,EAAE,CAAC,GAAG,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC;aACtC,CAAC,CAAA;YAEF,IAAI,MAAM,CAAC,OAAO,KAAK,MAAM,EAAE,CAAC;gBAC9B,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAA;YAC9D,CAAC;QACH,CAAC;QACD,OAAO,QAAQ,CAAA;IACjB,CAAC;IAEM,KAAK,CAAC,MAAM,CAAC,IAAc;QAChC,IAAI,CAAC;YACH,IAAI,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;iBAC3B,KAAK,CAAC,2BAA2B,CAAC;iBAClC,MAAM,CAAC,KAAK,EAAE;gBACb,IAAI,EAAE,QAAQ;gBACd,KAAK,EAAE,GAAG;gBACV,OAAO,EAAE,YAAY;gBACrB,WAAW,EAAE,uBAAuB;aACrC,CAAC;iBACD,MAAM,CAAC,OAAO,EAAE;gBACf,IAAI,EAAE,SAAS;gBACf,KAAK,EAAE,GAAG;gBACV,OAAO,EAAE,KAAK;gBACd,WAAW,EAAE,oBAAoB;aAClC,CAAC;iBACD,MAAM,CAAC,cAAc,EAAE;gBACtB,IAAI,EAAE,QAAQ;gBACd,KAAK,EAAE,GAAG;gBACV,OAAO,EAAE,UAAU;gBACnB,WAAW,EAAE,2BAA2B;aACzC,CAAC;iBACD,MAAM,CAAC,OAAO,EAAE;gBACf,IAAI,EAAE,SAAS;gBACf,KAAK,EAAE,GAAG;gBACV,OAAO,EAAE,KAAK;gBACd,WAAW,EACT,4DAA4D;aAC/D,CAAC,CAAA;YAEJ,MAAM,cAAc,GAAG,IAAI,CAAC,aAAa,CAAC,UAAU,EAAE,CAAA;YACtD,KAAK,MAAM,MAAM,IAAI,cAAc,EAAE,CAAC;gBACpC,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE;oBAC1C,IAAI,EAAE,QAAQ;oBACd,OAAO,EAAE,CAAC,MAAM,EAAE,GAAG,MAAM,CAAC,QAAQ,CAAC;oBACrC,WAAW,EAAE,WAAW,MAAM,CAAC,IAAI,EAAE;iBACtC,CAAC,CAAA;YACJ,CAAC;YAED,GAAG,GAAG,GAAG;iBACN,OAAO,CAAC,OAAO,CAAC;iBAChB,IAAI,EAAE;iBACN,KAAK,CAAC,IAAI,CAAC,EAAE;gBACZ,KAAK,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;oBAC9C,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,GAAG,KAAK,GAAG,EAAE,CAAC;wBACtC,MAAM,IAAI,KAAK,CAAC,YAAY,GAAG,2BAA2B,CAAC,CAAA;oBAC7D,CAAC;gBACH,CAAC;gBACD,OAAO,IAAI,CAAA;YACb,CAAC,CAAC,CAAA;YAEJ,MAAM,UAAU,GAAG,GAAG,CAAC,SAAS,EAAE,CAAA;YAElC,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,GAAG,CAAS,CAAA;YAE1D,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,CAAA;YAC3C,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,EAAE,CAAC,CAAA;YACjD,MAAM,WAAW,GAAG,IAAI,WAAW,CAAC,GAAG,EAAE,MAAM,CAAC,CAAA;YAEhD,IAAI,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;gBACpD,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAqB;oBACvD,IAAI,EAAE,SAAS;oBACf,IAAI,EAAE,OAAO;oBACb,OAAO,EAAE,0BAA0B,WAAW,8DAA8D;iBAC7G,CAAC,CAAA;gBACF,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;oBAClB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;gBACjB,CAAC;YACH,CAAC;YAED,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,iBAAiB,CAAC,UAAU,CAAC,CAAA;YAEzD,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC;gBAC1B,GAAG;gBACH,MAAM;gBACN,WAAW;gBACX,QAAQ;gBACR,WAAW,EAAE,WAAW;gBACxB,WAAW,EAAE,UAAU,CAAC,WAAW;aACpC,CAAC,CAAA;YAEF,MAAM,OAAO,CAAC,KAAK,EAAE,CAAA;QACvB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,KAAK,YAAY,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,iBAAiB,EAAE,CAAC;gBAC/D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;YACjB,CAAC;iBAAM,CAAC;gBACN,MAAM,KAAK,CAAA;YACb,CAAC;QACH,CAAC;IACH,CAAC;CACF"}
package/lib/Builder.js ADDED
@@ -0,0 +1,111 @@
1
+ import glob from 'fast-glob';
2
+ import * as fs from 'fs/promises';
3
+ import * as path from 'path';
4
+ import { PackageJsonMerger } from './Mergers/PackageJsonMerger.js';
5
+ import { EnvJsoncMerger } from './Mergers/EnvJsoncMerger.js';
6
+ import { ConfigMerger } from './Mergers/ConfigMerger.js';
7
+ import { ContainerMerger } from './Mergers/ContainerMerger.js';
8
+ import { Files } from './Files.js';
9
+ export class Builder {
10
+ constructor(params) {
11
+ this.npm = params.npm;
12
+ this.logger = params.logger;
13
+ this.starters = params.starters;
14
+ this.destination = params.destination;
15
+ this.projectName = params.projectName;
16
+ this.replacements = {
17
+ '{{PROJECT_NAME}}': this.projectName,
18
+ };
19
+ this.fileMergers = [
20
+ new PackageJsonMerger(this.projectName, this.destination, 'package.json'),
21
+ new EnvJsoncMerger(this.destination, '.env.jsonc'),
22
+ new ConfigMerger(this.destination, 'src/config.ts'),
23
+ new ContainerMerger(this.destination, 'src/container.ts'),
24
+ ];
25
+ }
26
+ async prepareFolder() {
27
+ if (await Files.existsAndIsDir(this.destination)) {
28
+ await fs.rm(this.destination, { recursive: true });
29
+ }
30
+ await fs.mkdir(this.destination, { recursive: true });
31
+ }
32
+ async build() {
33
+ try {
34
+ await this.logger.loader(`Preparing clean folder`, this.prepareFolder());
35
+ await this.logger.loader(`Preparing folder structure`, this.buildStarter(Builder.BASE_STARTER_DIR));
36
+ for (const starter of this.starters) {
37
+ await this.logger.loader(`Adding ${starter.config.name} ${starter.config.module}`, this.buildStarter(starter.path, starter.config));
38
+ }
39
+ await this.logger.loader(`npm install`, this.npm.run(['install']));
40
+ const prebuildScripts = this.starters
41
+ .map(starter => starter.config.prebuild)
42
+ .filter(script => script !== undefined);
43
+ for (const script of prebuildScripts) {
44
+ await this.logger.loader(`npm run ${script.join(' ')}`, this.npm.run(['run', ...script]));
45
+ }
46
+ await this.logger.loader(`npm run build`, this.npm.run(['run', 'build']));
47
+ this.logger.info(`Your app is ready in ${path.relative(process.cwd(), this.destination)}! 🚀`);
48
+ }
49
+ catch (error) {
50
+ this.logger.error(error);
51
+ process.exit(1);
52
+ }
53
+ }
54
+ async buildStarter(starterDir, config) {
55
+ const destDir = path.normalize(path.resolve(this.destination));
56
+ const files = await glob(`${starterDir}/*`, {
57
+ cwd: starterDir,
58
+ dot: true,
59
+ onlyFiles: false,
60
+ });
61
+ const ignoredFiles = Builder.IGNORED_FILES.map(file => path.join(starterDir, file));
62
+ const mergedFiles = await Promise.all(this.fileMergers.map(async (merger) => {
63
+ return {
64
+ path: merger.getDestPath(),
65
+ content: await merger.merge(starterDir),
66
+ };
67
+ }));
68
+ await Promise.all(files.map(async (filePath) => {
69
+ if (ignoredFiles.includes(filePath)) {
70
+ return;
71
+ }
72
+ const destFilePath = path.join(destDir, path.basename(filePath));
73
+ if (await Files.existsAndIsDir(filePath)) {
74
+ await fs.cp(filePath, destFilePath, { recursive: true });
75
+ return;
76
+ }
77
+ await fs.cp(filePath, destFilePath);
78
+ }));
79
+ await Promise.all(mergedFiles.map(async ({ path, content }) => fs.writeFile(path, content)));
80
+ if (config?.replace) {
81
+ await Promise.all(config.replace.map(async (filePath) => this.replaceInFile(filePath)));
82
+ }
83
+ }
84
+ async replaceInFile(filePath) {
85
+ filePath = path.normalize(path.join(this.destination, filePath));
86
+ let content = await Files.readUtf8File(filePath);
87
+ content = Object.keys(this.replacements).reduce((acc, key) => {
88
+ return acc.replaceAll(key, this.replacements[key]);
89
+ }, content);
90
+ return fs.writeFile(filePath, content);
91
+ }
92
+ async symlink(linkName, linkedFile) {
93
+ linkName = path.normalize(linkName);
94
+ linkedFile = path.normalize(linkedFile);
95
+ this.logger.info(`> ln -s ${linkName} ${linkedFile}`);
96
+ try {
97
+ await fs.symlink(linkedFile, linkName);
98
+ }
99
+ catch (error) {
100
+ if ('code' in error && error.code === 'EEXIST') {
101
+ // OK
102
+ }
103
+ else {
104
+ throw error;
105
+ }
106
+ }
107
+ }
108
+ }
109
+ Builder.BASE_STARTER_DIR = path.normalize(path.join(import.meta.dirname, '..', 'starter', '_base'));
110
+ Builder.IGNORED_FILES = ['node-app.jsonc'];
111
+ //# sourceMappingURL=Builder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Builder.js","sourceRoot":"","sources":["../src/Builder.ts"],"names":[],"mappings":"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"}
package/lib/Files.js ADDED
@@ -0,0 +1,21 @@
1
+ import * as fsp from 'fs/promises';
2
+ import path from 'path';
3
+ export class Files {
4
+ static async exists(filepath) {
5
+ const stat = await fsp.stat(filepath).catch(() => undefined);
6
+ return Boolean(stat);
7
+ }
8
+ static async existsAndIsDir(filepath) {
9
+ const stat = await fsp.stat(filepath).catch(() => undefined);
10
+ return Boolean(stat?.isDirectory());
11
+ }
12
+ static async readUtf8File(filepath) {
13
+ return fsp.readFile(filepath, 'utf8');
14
+ }
15
+ static isInSameTree(tree, filepath) {
16
+ const file = path.normalize(filepath);
17
+ const fileTree = path.normalize(tree);
18
+ return file.startsWith(fileTree);
19
+ }
20
+ }
21
+ //# sourceMappingURL=Files.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Files.js","sourceRoot":"","sources":["../src/Files.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,aAAa,CAAA;AAClC,OAAO,IAAI,MAAM,MAAM,CAAA;AAEvB,MAAM,OAAO,KAAK;IACT,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,QAAgB;QACzC,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAA;QAC5D,OAAO,OAAO,CAAC,IAAI,CAAC,CAAA;IACtB,CAAC;IAEM,MAAM,CAAC,KAAK,CAAC,cAAc,CAAC,QAAgB;QACjD,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAA;QAC5D,OAAO,OAAO,CAAC,IAAI,EAAE,WAAW,EAAE,CAAC,CAAA;IACrC,CAAC;IACM,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,QAAgB;QAC/C,OAAO,GAAG,CAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAA;IACvC,CAAC;IACM,MAAM,CAAC,YAAY,CAAC,IAAY,EAAE,QAAgB;QACvD,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAA;QACrC,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAA;QACrC,OAAO,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAA;IAClC,CAAC;CACF"}
package/lib/Logger.js CHANGED
@@ -1,12 +1,30 @@
1
- export const logger = {
2
- info: (message) => {
1
+ import { oraPromise } from 'ora';
2
+ export class Logger {
3
+ constructor(enableDebug = false) {
4
+ this.enableDebug = enableDebug;
5
+ }
6
+ info(message) {
3
7
  console.log(message);
4
- },
5
- verbose: (message) => {
8
+ }
9
+ verbose(message) {
6
10
  console.log(message);
7
- },
8
- error: (message) => {
11
+ }
12
+ error(message) {
9
13
  console.log(message);
10
- },
11
- };
14
+ }
15
+ debug(message) {
16
+ if (this.enableDebug) {
17
+ console.log(message);
18
+ }
19
+ }
20
+ loader(message, promise) {
21
+ if (this.enableDebug) {
22
+ this.info(message);
23
+ return promise;
24
+ }
25
+ return oraPromise(promise, {
26
+ text: message,
27
+ });
28
+ }
29
+ }
12
30
  //# sourceMappingURL=Logger.js.map
package/lib/Logger.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"Logger.js","sourceRoot":"","sources":["../src/Logger.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,MAAM,GAAG;IACpB,IAAI,EAAE,CAAC,OAAe,EAAE,EAAE;QACxB,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;IACtB,CAAC;IACD,OAAO,EAAE,CAAC,OAAe,EAAE,EAAE;QAC3B,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;IACtB,CAAC;IACD,KAAK,EAAE,CAAC,OAAe,EAAE,EAAE;QACzB,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;IACtB,CAAC;CACF,CAAA"}
1
+ {"version":3,"file":"Logger.js","sourceRoot":"","sources":["../src/Logger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,KAAK,CAAA;AAEhC,MAAM,OAAO,MAAM;IACjB,YAA4B,cAAuB,KAAK;QAA5B,gBAAW,GAAX,WAAW,CAAiB;IAAG,CAAC;IAE5D,IAAI,CAAC,OAAe;QAClB,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;IACtB,CAAC;IACD,OAAO,CAAC,OAAe;QACrB,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;IACtB,CAAC;IACD,KAAK,CAAC,OAAe;QACnB,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;IACtB,CAAC;IACD,KAAK,CAAC,OAAe;QACnB,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YACrB,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;QACtB,CAAC;IACH,CAAC;IACD,MAAM,CAAC,OAAe,EAAE,OAAqB;QAC3C,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YACrB,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;YAClB,OAAO,OAAO,CAAA;QAChB,CAAC;QAED,OAAO,UAAU,CAAC,OAAO,EAAE;YACzB,IAAI,EAAE,OAAO;SACd,CAAC,CAAA;IACJ,CAAC;CACF"}
@@ -0,0 +1,22 @@
1
+ import { Files } from '../Files.js';
2
+ import { Merger } from './Merger.js';
3
+ export class ConfigMerger extends Merger {
4
+ constructor() {
5
+ super(...arguments);
6
+ this.name = 'Config';
7
+ }
8
+ async merge(originDir) {
9
+ const content = await this.getWhichExistsOrNull(originDir);
10
+ if (content) {
11
+ return content;
12
+ }
13
+ const { originPath, destPath } = this.getPaths(originDir);
14
+ const [destTsConfig, originTsConfig] = await Promise.all([
15
+ Files.readUtf8File(destPath),
16
+ Files.readUtf8File(originPath),
17
+ ]);
18
+ const configContent = /configSchema = {\n(.*?)\n}\n/s.exec(originTsConfig)?.[1];
19
+ return destTsConfig.replace('\n}\n', configContent ? `${configContent}\n}\n` : '}\n');
20
+ }
21
+ }
22
+ //# sourceMappingURL=ConfigMerger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConfigMerger.js","sourceRoot":"","sources":["../../src/Mergers/ConfigMerger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAA;AACnC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAEpC,MAAM,OAAO,YAAa,SAAQ,MAAM;IAAxC;;QACE,SAAI,GAAG,QAAQ,CAAA;IAuBjB,CAAC;IArBC,KAAK,CAAC,KAAK,CAAC,SAAiB;QAC3B,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,oBAAoB,CAAC,SAAS,CAAC,CAAA;QAC1D,IAAI,OAAO,EAAE,CAAC;YACZ,OAAO,OAAO,CAAA;QAChB,CAAC;QAED,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAA;QAEzD,MAAM,CAAC,YAAY,EAAE,cAAc,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;YACvD,KAAK,CAAC,YAAY,CAAC,QAAQ,CAAC;YAC5B,KAAK,CAAC,YAAY,CAAC,UAAU,CAAC;SAC/B,CAAC,CAAA;QACF,MAAM,aAAa,GAAG,+BAA+B,CAAC,IAAI,CACxD,cAAc,CACf,EAAE,CAAC,CAAC,CAAC,CAAA;QAEN,OAAO,YAAY,CAAC,OAAO,CACzB,OAAO,EACP,aAAa,CAAC,CAAC,CAAC,GAAG,aAAa,OAAO,CAAC,CAAC,CAAC,KAAK,CAChD,CAAA;IACH,CAAC;CACF"}