Skip to content

Commit b14c564

Browse files
Merge pull request #40 from Shivansh-Khunger/version-1
🍬 Enhancement: Multiple Package Manager
2 parents 016abf3 + 83b00e5 commit b14c564

8 files changed

Lines changed: 179 additions & 47 deletions

File tree

README.md

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
1-
# create-node-nitro <a href="https://www.npmjs.com/package/create-node-nitro"><img src="https://img.shields.io/npm/v/create-node-nitro" alt="npm package"></a>
1+
# create-nitro <a href="https://www.npmjs.com/package/create-node-nitro"><img src="https://img.shields.io/npm/v/create-nitro" alt="npm package"></a>
2+
3+
<div align="center">
4+
<img src="https://i.ibb.co/YBfq0GH/nitro-logo.png" alt="nitro-logo" width="256" >
5+
</div>
26

37
## Scaffolding Your Node API's
48

59
> **Compatibility Note:**
6-
> Vite requires [Node.js](https://nodejs.org/en/) version 18+, 20+. However, some templates require a higher Node.js version to work, please upgrade if your package manager warns about it.
10+
> Nitro requires [Node.js](https://nodejs.org/en/) version 18+, 20+. However, some templates require a higher Node.js version to work, please upgrade if your package manager warns about it.
711
812
### Features
913

@@ -15,7 +19,19 @@
1519
With NPM:
1620

1721
```bash
18-
$ npm create node-nitro@latest
22+
npm create nitro@latest
23+
```
24+
25+
With Yarn:
26+
27+
```bash
28+
yarn create nitro
29+
```
30+
31+
With PNPM:
32+
33+
```bash
34+
pnpm create nitro
1935
```
2036

2137
Then follow the prompts!
@@ -24,7 +40,13 @@ You can also directly specify the project name and the template you want to use
2440

2541
```bash
2642
# npm 7+, extra double-dash is needed:
27-
npm create node-nitro@latest -- -t <template name> -d <directory name>
43+
npm create nitro@latest -- -t <template name> -d <directory name>
44+
45+
# yarn
46+
yarn create nitro -t <template name> -d <directory name>
47+
48+
# pnpm
49+
pnpm create nitro -t <template name> -d <directory name>
2850
```
2951

3052
Currently supported template presets include:

package.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
{
2-
"name": "create-node-nitro",
3-
"version": "0.1.0-beta.7",
2+
"name": "create-nitro",
3+
"version": "1.0.0",
44
"description": "",
55
"main": "index.js",
6+
"license": "MIT",
67
"scripts": {
78
"build": "tspc",
89
"dev": "tspc --watch",
910
"test": "echo \"Error: no test specified\" && exit 1",
10-
"start": "node ./index.js",
1111
"pub": "npm run build && npm publish"
1212
},
1313
"bin": {
14-
"create-node-nitro": "index.js"
14+
"create-nitro": "index.js"
1515
},
1616
"files": [
1717
"dist/**",

src/helpers/handleOptions.ts

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
// Import necessary external Module(s)
2-
import { bgCyan, yellow } from "kolorist";
3-
41
// Import necessary Type(s)
52
import type { T_UserInputCli } from "../types/prompt";
63

@@ -10,14 +7,14 @@ function handleAdditionalOptions(
107
tempDevDependency: string,
118
) {
129
let dependency = tempDependency;
13-
let devDependency = `${tempDevDependency} prettier`;
10+
let devDependency = tempDevDependency;
1411

1512
if (userInput.formatterAndLinter === "biome-prettier") {
1613
devDependency = `${devDependency} @biomejs/biome`;
1714
} else {
1815
devDependency = `${devDependency} eslint`;
1916
if (userInput.template === "express/ts") {
20-
devDependency = `${devDependency} @typescript-eslint/parser @typescript-eslint/eslint-plugin eslint-plugin-prettier`;
17+
devDependency = `${devDependency} @eslint/js @types/eslint__js typescript typescript-eslint eslint-plugin-prettier`;
2118
}
2219
}
2320

@@ -29,15 +26,10 @@ function handleAdditionalOptions(
2926
}
3027
}
3128

32-
const installCmd = `${dependency} && ${devDependency}`;
33-
34-
console.log(
35-
`${yellow("Installling dependencies...\ncommand ->")} ${bgCyan(
36-
` ${installCmd} `,
37-
)}`,
38-
);
39-
40-
return installCmd;
29+
return {
30+
updtDependencyCmd: dependency,
31+
updtDevDependencyCmd: devDependency,
32+
};
4133
}
4234

4335
export default handleAdditionalOptions;

src/helpers/pkgManager.ts

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
function pkgFromUserAgent(userAgent: string | undefined) {
2+
if (!userAgent) return undefined;
3+
const pkgSpec = userAgent.split(" ")[0];
4+
const pkgSpecArr = pkgSpec.split("/");
5+
return {
6+
name: pkgSpecArr[0],
7+
version: pkgSpecArr[1],
8+
};
9+
}
10+
11+
export type T_PkgManagerInfo = {
12+
pkgManager: string;
13+
prefix: string;
14+
devPrefix: string;
15+
};
16+
17+
const pkgInfo = pkgFromUserAgent(process.env.npm_config_user_agent);
18+
const pkgManager = pkgInfo ? pkgInfo.name : "npm";
19+
20+
function selectPkgManager(): T_PkgManagerInfo {
21+
let pkgManagerInfo: T_PkgManagerInfo = {
22+
pkgManager: pkgManager,
23+
prefix: "npm i",
24+
devPrefix: "npm i --save-dev",
25+
};
26+
27+
if (pkgManager === "yarn") {
28+
pkgManagerInfo = {
29+
...pkgManagerInfo,
30+
prefix: "yarn add",
31+
devPrefix: "yarn add --dev",
32+
};
33+
34+
return pkgManagerInfo;
35+
}
36+
if (pkgManager === "pnpm") {
37+
pkgManagerInfo = {
38+
...pkgManagerInfo,
39+
prefix: "pnpm add",
40+
devPrefix: "pnpm add --save-dev",
41+
};
42+
43+
return pkgManagerInfo;
44+
}
45+
46+
return pkgManagerInfo;
47+
}
48+
49+
export default selectPkgManager;

src/helpers/printDependencies.ts

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import { gray } from "kolorist";
2+
3+
import type { T_PkgManagerInfo } from "./pkgManager";
4+
5+
function printDependencies(
6+
dependencyCmd: string,
7+
devDependencyCmd: string,
8+
pkgManagerInfo: T_PkgManagerInfo,
9+
) {
10+
if (pkgManagerInfo.pkgManager === "pnpm") {
11+
// pnpm does this by default
12+
return;
13+
}
14+
15+
const dependencies = dependencyCmd.replace(pkgManagerInfo.prefix, "");
16+
const devDependencies = devDependencyCmd.replace(
17+
pkgManagerInfo.devPrefix,
18+
"",
19+
);
20+
21+
const dependenciesArr = dependencies.split(" ");
22+
const devDependenciesArr = devDependencies.split(" ");
23+
24+
console.log(
25+
`\nDownloading dependencies... (${pkgManagerInfo.pkgManager})\n`,
26+
);
27+
28+
console.log("Dependencies -:");
29+
dependenciesArr.map((d: string) => {
30+
console.log(`${gray(d)}`);
31+
});
32+
33+
console.log("\nDev-Dependencies -:");
34+
devDependenciesArr.map((d: string) => {
35+
console.log(`${gray(d)}`);
36+
});
37+
38+
if (pkgManagerInfo.pkgManager !== "npm") {
39+
console.log("\n");
40+
}
41+
}
42+
43+
export default printDependencies;

src/index.ts

Lines changed: 47 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -7,29 +7,26 @@ import addDbAndOrm from "@helpers/db&Orms";
77
import { makeDevEnv, makeProdEnv } from "@helpers/envMaker";
88
import addFmtAndLinterConfig from "@helpers/fmt&Linters";
99
import handleAdditionalOptions from "@helpers/handleOptions";
10+
import selectPkgManager from "@helpers/pkgManager";
11+
import printDependencies from "@helpers/printDependencies";
1012
import { parseArgs, startUserInteraction } from "@utils/cli";
1113
import handleError, { makeTargetPath } from "@utils/errorHandler";
12-
1314
import { renameFile } from "@utils/fileSystem";
15+
16+
// Import external Module(s)
17+
import { gray, lightBlue, red } from "kolorist";
18+
1419
// Import necessary Type(s)
1520
import type {
1621
T_Arg_HandleArgs,
1722
T_Arg_HandleCli,
1823
} from "./types/dependencyInstallers";
1924
import type { T_UserInput } from "./types/prompt";
2025

21-
let filePathArr: string[];
22-
export let projectDirPath: string;
23-
24-
if (process.platform === "win32") {
25-
filePathArr = __dirname.split("\\");
26-
filePathArr.pop();
27-
projectDirPath = filePathArr.join("\\");
28-
} else {
29-
filePathArr = __dirname.split("/");
30-
filePathArr.pop();
31-
projectDirPath = filePathArr.join("/");
32-
}
26+
const sysPathDisapator = process.platform === "win32" ? "\\" : "/";
27+
const filePathArr = __dirname.split(sysPathDisapator);
28+
filePathArr.pop();
29+
export const projectDirPath = filePathArr.join(sysPathDisapator);
3330

3431
(async () => {
3532
const parsedArgs = parseArgs();
@@ -46,6 +43,16 @@ if (process.platform === "win32") {
4643
function copyTemplate(targetPath: string, targetTemplate: string) {
4744
try {
4845
const templatePath = `${projectDirPath}/templates/${targetTemplate}`;
46+
const exists = fs.existsSync(targetPath);
47+
48+
if (exists) {
49+
console.log(
50+
`\n${red(
51+
"Program stopped",
52+
)}\nReason -: A directory with the same name exists.`,
53+
);
54+
process.exit(1);
55+
}
4956

5057
fs.cpSync(templatePath, targetPath, { recursive: true });
5158
} catch (err) {
@@ -74,18 +81,24 @@ function performRenames(targetPath: string) {
7481
}
7582

7683
function installDependecies(targetPath: string, userInput: T_UserInput) {
77-
const dependencyCmd = "npm i express pino pino-http pino-pretty";
78-
let devDependencyCmd: string;
84+
const pkgManagerInfo = selectPkgManager();
85+
86+
const dependencyCmd = `${pkgManagerInfo.prefix} express pino pino-http pino-pretty`;
87+
let devDependencyCmd = "prettier";
7988

8089
function handleArgs({
8190
dependencyCmd,
8291
devDependencyCmd,
8392
targetPath,
8493
}: T_Arg_HandleArgs) {
8594
const installCmd = `${dependencyCmd} && ${devDependencyCmd}`;
95+
96+
printDependencies(dependencyCmd, devDependencyCmd, pkgManagerInfo);
97+
8698
try {
8799
execSync(installCmd, {
88100
cwd: targetPath,
101+
stdio: "inherit",
89102
});
90103
} catch (err) {
91104
handleError(err);
@@ -98,18 +111,24 @@ function installDependecies(targetPath: string, userInput: T_UserInput) {
98111
devDependencyCmd,
99112
targetPath,
100113
}: T_Arg_HandleCli) {
101-
const installCmd = handleAdditionalOptions(
102-
userInput,
103-
dependencyCmd,
104-
devDependencyCmd,
105-
);
114+
// these are updated dependency and devDependecy commands which include all the extra options
115+
const { updtDependencyCmd, updtDevDependencyCmd } =
116+
handleAdditionalOptions(userInput, dependencyCmd, devDependencyCmd);
106117

107118
addFmtAndLinterConfig(
108119
userInput.formatterAndLinter,
109120
targetPath,
110121
projectDirPath,
111122
);
112123

124+
const installCmd = `${updtDependencyCmd} && ${updtDevDependencyCmd}`;
125+
126+
printDependencies(
127+
updtDependencyCmd,
128+
updtDevDependencyCmd,
129+
pkgManagerInfo,
130+
);
131+
113132
try {
114133
execSync(installCmd, {
115134
cwd: targetPath,
@@ -127,7 +146,7 @@ function installDependecies(targetPath: string, userInput: T_UserInput) {
127146
switch (userInput.template) {
128147
case "express/js":
129148
{
130-
devDependencyCmd = "npm i --save-dev @dotenvx/dotenvx nodemon";
149+
devDependencyCmd = `${pkgManagerInfo.devPrefix} ${devDependencyCmd} @dotenvx/dotenvx nodemon`;
131150

132151
if (userInput.type === "args") {
133152
handleArgs({ dependencyCmd, devDependencyCmd, targetPath });
@@ -143,8 +162,7 @@ function installDependecies(targetPath: string, userInput: T_UserInput) {
143162
break;
144163
case "express/ts":
145164
{
146-
devDependencyCmd =
147-
"npm i --save-dev tsx typescript @dotenvx/dotenvx @types/express @types/node";
165+
devDependencyCmd = `${pkgManagerInfo.devPrefix} ${devDependencyCmd} tsx typescript @dotenvx/dotenvx @types/express @types/node`;
148166

149167
if (userInput.type === "args") {
150168
handleArgs({ dependencyCmd, devDependencyCmd, targetPath });
@@ -174,4 +192,10 @@ function handleLogic(userInput: T_UserInput) {
174192
performRenames(targetPath);
175193
intialiseGitRepo(targetPath);
176194
installDependecies(targetPath, userInput);
195+
196+
console.log(
197+
`\n${lightBlue("Project made at -:")} ${gray(
198+
`${targetPath},`,
199+
)} Hope you finish this one ;)`,
200+
);
177201
}

src/utils/cli.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ export async function startUserInteraction() {
209209
],
210210
{
211211
onCancel() {
212-
console.log(red("program stopped keyboard interupt"));
212+
console.log(`\n${red("Program stopped")}\nReason -: Keyboard interupt.`);
213213
process.exit(1);
214214
},
215215
},

src/utils/errorHandler.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ import { bold, green, lightRed } from "kolorist";
66
const cwd = process.cwd();
77
let targetPath: string;
88
export function makeTargetPath(userInputDirName: string) {
9-
targetPath = `${cwd}/${userInputDirName}`;
9+
targetPath = `${cwd}${
10+
process.platform === "win32" ? "\\" : "/"
11+
}${userInputDirName}`;
1012

1113
return targetPath;
1214
}

0 commit comments

Comments
 (0)