@comet/create-app 1.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.
package/LICENSE ADDED
@@ -0,0 +1,24 @@
1
+ BSD 2-Clause License
2
+
3
+ Copyright (c) 2023, Vivid Planet Software GmbH
4
+
5
+ Redistribution and use in source and binary forms, with or without
6
+ modification, are permitted provided that the following conditions are met:
7
+
8
+ 1. Redistributions of source code must retain the above copyright notice, this
9
+ list of conditions and the following disclaimer.
10
+
11
+ 2. Redistributions in binary form must reproduce the above copyright notice,
12
+ this list of conditions and the following disclaimer in the documentation
13
+ and/or other materials provided with the distribution.
14
+
15
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
19
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
22
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
23
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package/README.md ADDED
@@ -0,0 +1,47 @@
1
+ # @comet/create-app
2
+
3
+ This is a command-line interface to create a new Comet application.
4
+ It sets up a project with the necessary configuration and files to get started quickly.
5
+
6
+ ## Usage
7
+
8
+ To create a new Comet app, run the following command:
9
+
10
+ ```bash
11
+ npx @comet/create-app <project-name>
12
+ ```
13
+
14
+ ### Arguments
15
+
16
+ The following arguments can be passed to customize the project setup:
17
+
18
+ - `project-name` (required): Specifies the name of the project. It will be used as the directory name for the project.
19
+ - `-v` or `--verbose`: Enables extra console logs for verbose output.
20
+ - `-V` or `--version`: Outputs the version number.
21
+ - `-h` or `--help`: Display help for the command.
22
+
23
+ Example usage with arguments:
24
+
25
+ ```bash
26
+ npx @comet/create-app my-project -v
27
+ ```
28
+
29
+
30
+ This command will create a new Comet app with the name "my-project" and enable verbose logging.
31
+
32
+ ## For developers
33
+
34
+ ### Development
35
+
36
+ To test the script locally, run the following commands:
37
+
38
+ 1. Start the development process:
39
+ ```bash
40
+ npm start
41
+ ```
42
+ 2. Run the script:
43
+ ```bash
44
+ node ./bin/index.js
45
+ ```
46
+
47
+ Testing a close to production usage of the CLI can be done by calling `npm link` in the create-app/ directory. Then `npx @comet/create-app` can be used.
package/bin/index.js ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+
3
+ require("../lib/createApp");
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const commander_1 = require("commander");
7
+ const kleur_1 = __importDefault(require("kleur"));
8
+ const process_1 = __importDefault(require("process"));
9
+ const cleanupWorkingDirectory_1 = require("./util/cleanupWorkingDirectory");
10
+ const createInitialGitCommit_1 = require("./util/createInitialGitCommit");
11
+ const createWorkingDirectoryCopy_1 = require("./util/createWorkingDirectoryCopy");
12
+ const isValidNodeVersion_1 = require("./util/isValidNodeVersion");
13
+ const replacePlaceholder_1 = require("./util/replacePlaceholder");
14
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
15
+ const { name, version } = require("../package.json");
16
+ function isValidProjectName(value) {
17
+ const allowedFormat = /^[A-Za-z0-9][A-Za-z0-9-]*$/;
18
+ return allowedFormat.test(value);
19
+ }
20
+ void (async () => {
21
+ const program = new commander_1.Command();
22
+ if (!(0, isValidNodeVersion_1.isValidNodeVersion)()) {
23
+ console.log(kleur_1.default.bgRed("Invalid Node Version (your Node.js version is prior to v18)."));
24
+ return;
25
+ }
26
+ program.name(name).description("CLI to create a comet app").version(version);
27
+ program
28
+ .argument("<projectName>", "Sets the name of the project.")
29
+ .option("-v, --verbose", "Enables extra console logs for verbose output.")
30
+ .action((projectName, options) => {
31
+ if (isValidProjectName(projectName)) {
32
+ createApp({ projectName, verbose: options.verbose });
33
+ }
34
+ else {
35
+ console.log(kleur_1.default.bgRed("Please provide a valid project name."));
36
+ }
37
+ });
38
+ program.parse();
39
+ })();
40
+ async function createApp(projectConfiguration) {
41
+ console.log(kleur_1.default.white(`Creating a new Comet app in `) + kleur_1.default.yellow(`${process_1.default.cwd()}\n`));
42
+ if (!(0, createWorkingDirectoryCopy_1.createWorkingDirectoryCopy)(projectConfiguration.projectName, projectConfiguration.verbose)) {
43
+ return;
44
+ }
45
+ (0, cleanupWorkingDirectory_1.cleanupWorkingDirectory)(projectConfiguration.verbose);
46
+ (0, replacePlaceholder_1.replacePlaceholder)(projectConfiguration.projectName, projectConfiguration.verbose);
47
+ (0, createInitialGitCommit_1.createInitialGitCommit)();
48
+ console.log(`\n${kleur_1.default.white(`Success! Created '${projectConfiguration.projectName}' at '${process_1.default.cwd()}'.`)}`);
49
+ console.log(kleur_1.default.white(`Inside that directory, you can run several commands:\n`));
50
+ console.log(kleur_1.default.white(`nvm use\n`));
51
+ console.log(kleur_1.default.cyan(`sh ./install.sh\n`));
52
+ console.log(kleur_1.default.white(`Installs dependencies.\n`));
53
+ console.log(kleur_1.default.cyan(`npm run dev`));
54
+ console.log(kleur_1.default.white(`Starts all services.\n`));
55
+ console.log(kleur_1.default.cyan(`npx dev-pm status [--interval]`));
56
+ console.log(kleur_1.default.white(`Checks the status of services.\n`));
57
+ console.log(kleur_1.default.cyan(`npx dev-pm logs <service>`));
58
+ console.log(kleur_1.default.white(`Shows the logs of a service.\n`));
59
+ console.log(kleur_1.default.cyan(`npx dev-pm restart <service>`));
60
+ console.log(kleur_1.default.white(`Restarts a service.\n`));
61
+ console.log(kleur_1.default.cyan(`npx dev-pm shutdown`));
62
+ console.log(kleur_1.default.white(`Shutdown all services.\n`));
63
+ console.log(kleur_1.default.cyan(`npm run --prefix api fixtures`));
64
+ console.log(kleur_1.default.white(`Imports fixtures.\n`));
65
+ console.log(kleur_1.default.green(`\n☄️ Successfully created Comet app: ${projectConfiguration.projectName}`));
66
+ }
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.cleanupWorkingDirectory = void 0;
4
+ const deleteFilesAndFolders_1 = require("./deleteFilesAndFolders");
5
+ function cleanupWorkingDirectory(verbose) {
6
+ const cleanupFilesDirectories = ["create-app", ".git", ".github"];
7
+ (0, deleteFilesAndFolders_1.deleteFilesAndFolders)(cleanupFilesDirectories, verbose);
8
+ }
9
+ exports.cleanupWorkingDirectory = cleanupWorkingDirectory;
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.createInitialGitCommit = void 0;
7
+ const child_process_1 = require("child_process");
8
+ const kleur_1 = __importDefault(require("kleur"));
9
+ function createInitialGitCommit() {
10
+ try {
11
+ (0, child_process_1.execSync)("git init");
12
+ (0, child_process_1.execSync)("git add .");
13
+ const basedOnCommit = (0, child_process_1.execSync)('git ls-remote https://github.com/vivid-planet/comet-starter.git | head -1 | sed "s/HEAD//"');
14
+ (0, child_process_1.execSync)("git checkout -b setup-project");
15
+ (0, child_process_1.execSync)(`git commit -m "Initial commit from Starter" -m "Based on ${basedOnCommit}"`);
16
+ console.log(kleur_1.default.white("Created git commit."));
17
+ }
18
+ catch (e) {
19
+ console.log(kleur_1.default.yellow("Could not create git commit."));
20
+ }
21
+ }
22
+ exports.createInitialGitCommit = createInitialGitCommit;
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.createWorkingDirectoryCopy = void 0;
7
+ const child_process_1 = require("child_process");
8
+ const kleur_1 = __importDefault(require("kleur"));
9
+ const process_1 = __importDefault(require("process"));
10
+ function createWorkingDirectoryCopy(projectName, verbose) {
11
+ const clone = `git clone --depth 1 https://github.com/vivid-planet/comet-starter.git ./${projectName}`;
12
+ try {
13
+ (0, child_process_1.execSync)(clone);
14
+ process_1.default.chdir(`./${projectName}`);
15
+ if (verbose) {
16
+ console.log(kleur_1.default.white("Cloned git repository."));
17
+ }
18
+ }
19
+ catch (e) {
20
+ console.log(kleur_1.default.bgRed(`Error while cloning working directory to ${projectName}`));
21
+ return false;
22
+ }
23
+ return true;
24
+ }
25
+ exports.createWorkingDirectoryCopy = createWorkingDirectoryCopy;
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule) ? mod : { "default": mod };
27
+ };
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ exports.deleteFilesAndFolders = void 0;
30
+ const kleur_1 = __importDefault(require("kleur"));
31
+ const deleteFileOrFolder = __importStar(require("rimraf"));
32
+ function deleteFilesAndFolders(files, verbose) {
33
+ for (const toDelete of files) {
34
+ try {
35
+ deleteFileOrFolder.sync(`./${toDelete}`, {
36
+ maxRetries: 5,
37
+ retryDelay: 1000,
38
+ });
39
+ if (verbose) {
40
+ console.log(kleur_1.default.grey(`Info: Deleted ${toDelete}`));
41
+ }
42
+ }
43
+ catch (e) {
44
+ if (verbose) {
45
+ console.log(e);
46
+ }
47
+ console.log(kleur_1.default.yellow(`Could not delete ${toDelete}`));
48
+ }
49
+ }
50
+ }
51
+ exports.deleteFilesAndFolders = deleteFilesAndFolders;
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isValidNodeVersion = void 0;
4
+ function isNodeVersionGreaterThan18() {
5
+ const [major] = process.versions.node.split(".").map(Number);
6
+ return major >= 18;
7
+ }
8
+ function isValidNodeVersion() {
9
+ return isNodeVersionGreaterThan18();
10
+ }
11
+ exports.isValidNodeVersion = isValidNodeVersion;
@@ -0,0 +1,68 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule) ? mod : { "default": mod };
27
+ };
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ exports.replacePlaceholder = void 0;
30
+ const fs = __importStar(require("fs"));
31
+ const glob_1 = require("glob");
32
+ const kleur_1 = __importDefault(require("kleur"));
33
+ function replacePlaceholder(projectName, verbose) {
34
+ const files = glob_1.glob.sync([`./**`, `./.*`, `./.**/**`, `./**/.**/**`], {
35
+ maxDepth: 5,
36
+ ignore: `./.git/**`,
37
+ });
38
+ const placeholder = /[Ss]tarter/g;
39
+ let changedFiles = 0;
40
+ files.forEach((file) => {
41
+ try {
42
+ if (!fs.lstatSync(file).isFile()) {
43
+ return;
44
+ }
45
+ const contents = fs.readFileSync(file, "utf8").toString();
46
+ if (placeholder.test(contents)) {
47
+ if (file.endsWith("intl-update.sh"))
48
+ fs.writeFileSync(file, contents.replaceAll("lang/starter-lang", `lang/${projectName}-lang`));
49
+ else if (file.endsWith("lint-staged.config.js"))
50
+ fs.writeFileSync(file, contents.replaceAll(/"create.*lint:tsc",\n/gs, ""));
51
+ else
52
+ fs.writeFileSync(file, contents.replaceAll(placeholder, projectName));
53
+ changedFiles++;
54
+ if (verbose) {
55
+ console.log(kleur_1.default.grey(`Info: Replaced content in ${file}`));
56
+ }
57
+ }
58
+ }
59
+ catch (e) {
60
+ console.log(e);
61
+ console.log(kleur_1.default.yellow(`Could not replace placeholder in ${file}`));
62
+ }
63
+ });
64
+ if (verbose) {
65
+ console.log(kleur_1.default.green(`Successfully replaced content in ${changedFiles} files`));
66
+ }
67
+ }
68
+ exports.replacePlaceholder = replacePlaceholder;
package/package.json ADDED
@@ -0,0 +1,50 @@
1
+ {
2
+ "name": "@comet/create-app",
3
+ "version": "1.0.0",
4
+ "description": "Command-line interface to create a new Comet application",
5
+ "homepage": "https://github.com/vivid-planet/comet-starter/create-app#readme",
6
+ "bugs": {
7
+ "url": "https://github.com/vivid-planet/comet-starter/issues"
8
+ },
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "https://github.com/vivid-planet/comet-starter",
12
+ "directory": "create-app"
13
+ },
14
+ "license": "BSD-2-Clause",
15
+ "author": "Vivid Planet Software GmbH <office@vivid-planet.com> (https://www.vivid-planet.com/)",
16
+ "bin": "./bin/index.js",
17
+ "files": [
18
+ "bin/index.js",
19
+ "lib/**/*.js"
20
+ ],
21
+ "scripts": {
22
+ "prebuild": "npm run clean",
23
+ "build": "tsc --project tsconfig.json",
24
+ "clean": "rimraf lib",
25
+ "lint": "npm run lint:eslint && npm run lint:tsc",
26
+ "lint:eslint": "eslint --ext .ts,.tsx,.js,.jsx,.json --max-warnings 0 src/ package.json",
27
+ "lint:tsc": "tsc --project ./tsconfig.json",
28
+ "prepublishOnly": "npm run lint && npm run build",
29
+ "prestart": "npm run clean",
30
+ "start": "tsc --watch --project tsconfig.json"
31
+ },
32
+ "dependencies": {
33
+ "commander": "^11.0.0",
34
+ "eslint": "^8.0.0",
35
+ "glob": "^10.3.3",
36
+ "kleur": "^4.1.5",
37
+ "rimraf": "^5.0.1"
38
+ },
39
+ "devDependencies": {
40
+ "@comet/eslint-config": "^4.3.0",
41
+ "@tsconfig/node18": "^18.2.2",
42
+ "@types/prompts": "^2.4.4",
43
+ "prettier": "^2.1.2",
44
+ "typescript": "^5.2.2"
45
+ },
46
+ "publishConfig": {
47
+ "access": "public",
48
+ "registry": "https://registry.npmjs.org"
49
+ }
50
+ }