ts-package-init 0.1.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/README.md +147 -0
- package/dist/cli.js +149 -0
- package/dist/index.js +4 -0
- package/package.json +49 -0
- package/templates/backend/src/index.ts +1 -0
- package/templates/backend/tsconfig.json +10 -0
- package/templates/base/src/index.ts +3 -0
- package/templates/base/tsconfig.json +12 -0
- package/templates/cli/src/index.ts +3 -0
- package/templates/cli/tsconfig.json +10 -0
- package/templates/eslint/.prettierrc.json +6 -0
- package/templates/eslint/eslint.config.js +12 -0
- package/templates/eslint/eslint.prettier.config.js +14 -0
- package/templates/library/src/index.ts +3 -0
- package/templates/library/tsconfig.json +11 -0
package/README.md
ADDED
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
# ts-package-init
|
|
2
|
+
|
|
3
|
+
A fast, minimal, and modern TypeScript project initializer.
|
|
4
|
+
|
|
5
|
+
Create a TypeScript project with sensible defaults in seconds โ no frameworks, no boilerplate overload.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## โจ Features
|
|
10
|
+
|
|
11
|
+
- Zero-config TypeScript setup
|
|
12
|
+
- Presets: `base`, `library`, `backend`, `cli`
|
|
13
|
+
- CommonJS or ESM (`--esm`)
|
|
14
|
+
- Optional ESLint & Prettier
|
|
15
|
+
- Uses `tsx` for fast dev experience
|
|
16
|
+
- Works with Node.js 18+
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## ๐ Usage
|
|
21
|
+
|
|
22
|
+
### Quick start
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npx ts-package-init my-app
|
|
26
|
+
cd my-app
|
|
27
|
+
npm run dev
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### Using npm init
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
npm init ts-package my-app
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## ๐ฆ Presets
|
|
39
|
+
|
|
40
|
+
### Base (default)
|
|
41
|
+
|
|
42
|
+
Minimal runnable TypeScript project.
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
npx ts-package-init my-app
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Scripts:
|
|
49
|
+
```json
|
|
50
|
+
{
|
|
51
|
+
"build": "tsc",
|
|
52
|
+
"dev": "tsx watch src/index.ts"
|
|
53
|
+
}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
### Library
|
|
59
|
+
|
|
60
|
+
For reusable npm packages.
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
npx ts-package-init my-lib --preset library
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Includes:
|
|
67
|
+
- type declarations
|
|
68
|
+
- clean build output
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
### Backend
|
|
73
|
+
|
|
74
|
+
For APIs, workers, and services.
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
npx ts-package-init api --preset backend
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Includes:
|
|
81
|
+
- `dev`, `build`, `start` scripts
|
|
82
|
+
- long-running process defaults
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
### CLI
|
|
87
|
+
|
|
88
|
+
For command-line tools.
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
npx ts-package-init my-cli --preset cli
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Includes:
|
|
95
|
+
- executable binary
|
|
96
|
+
- Node shebang support
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
## ๐ ESM Support
|
|
101
|
+
|
|
102
|
+
Enable ESM with:
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
npx ts-package-init my-app --esm
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
This will:
|
|
109
|
+
- set `"type": "module"`
|
|
110
|
+
- adjust TypeScript config automatically
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
## ๐งน ESLint & Prettier (optional)
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
npx ts-package-init my-app --eslint
|
|
118
|
+
npx ts-package-init my-app --prettier
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Prettier automatically enables ESLint integration.
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
## ๐งช Examples
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
npx ts-package-init demo
|
|
129
|
+
npx ts-package-init my-lib --preset library --esm
|
|
130
|
+
npx ts-package-init api --preset backend --eslint --prettier
|
|
131
|
+
npx ts-package-init tool --preset cli
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
## ๐ฃ Roadmap
|
|
137
|
+
|
|
138
|
+
- Preset-aware ESLint rules
|
|
139
|
+
- Interactive mode
|
|
140
|
+
- Monorepo preset
|
|
141
|
+
- Framework presets (NestJS, Moleculer)
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
## ๐ License
|
|
146
|
+
|
|
147
|
+
MIT
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import fs from "fs-extra";
|
|
4
|
+
import minimist from "minimist";
|
|
5
|
+
import { execa } from "execa";
|
|
6
|
+
import { fileURLToPath } from "node:url";
|
|
7
|
+
const VALID_PRESETS = ["base", "cli", "library", "backend"];
|
|
8
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
9
|
+
const __dirname = path.dirname(__filename);
|
|
10
|
+
function die(msg) {
|
|
11
|
+
console.error(`โ ${msg}`);
|
|
12
|
+
process.exit(1);
|
|
13
|
+
}
|
|
14
|
+
async function run(cmd, args, cwd) {
|
|
15
|
+
try {
|
|
16
|
+
await execa(cmd, args, { cwd, stdio: "inherit" });
|
|
17
|
+
}
|
|
18
|
+
catch (error) {
|
|
19
|
+
die(error?.message);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
function getTemplateDir(preset) {
|
|
23
|
+
return path.resolve(__dirname, `../templates/${preset}`);
|
|
24
|
+
}
|
|
25
|
+
async function patchTsConfig(targetDir, isESM) {
|
|
26
|
+
const tsConfigPath = path.join(targetDir, "tsconfig.json");
|
|
27
|
+
const tsconfig = await fs.readJson(tsConfigPath);
|
|
28
|
+
if (isESM) {
|
|
29
|
+
tsconfig.compilerOptions.module = "ES2022";
|
|
30
|
+
tsconfig.compilerOptions.moduleResolution = "Bundler";
|
|
31
|
+
}
|
|
32
|
+
await fs.writeJson(tsConfigPath, tsconfig, { spaces: 2 });
|
|
33
|
+
}
|
|
34
|
+
function getEslintTemplate(withPrettier) {
|
|
35
|
+
return withPrettier
|
|
36
|
+
? "eslint.prettier.config.js"
|
|
37
|
+
: "eslint.config.js";
|
|
38
|
+
}
|
|
39
|
+
async function copyEslintConfig(targetDir, withPrettier) {
|
|
40
|
+
const filename = getEslintTemplate(withPrettier);
|
|
41
|
+
await fs.copy(path.resolve(__dirname, `../templates/eslint/${filename}`), path.join(targetDir, "eslint.config.js"));
|
|
42
|
+
}
|
|
43
|
+
async function copyPrettierConfig(targetDir) {
|
|
44
|
+
await fs.copy(path.resolve(__dirname, "../templates/eslint/.prettierrc.json"), path.join(targetDir, ".prettierrc.json"));
|
|
45
|
+
}
|
|
46
|
+
async function main() {
|
|
47
|
+
const args = minimist(process.argv.slice(2), {
|
|
48
|
+
default: {
|
|
49
|
+
preset: "base",
|
|
50
|
+
esm: false,
|
|
51
|
+
eslint: false,
|
|
52
|
+
prettier: false
|
|
53
|
+
},
|
|
54
|
+
});
|
|
55
|
+
const name = args._[0];
|
|
56
|
+
const preset = args.preset;
|
|
57
|
+
const isESM = Boolean(args.esm);
|
|
58
|
+
const useEslint = Boolean(args.eslint);
|
|
59
|
+
const usePrettier = Boolean(args.prettier);
|
|
60
|
+
const enableEslint = useEslint || usePrettier;
|
|
61
|
+
const enablePrettier = usePrettier;
|
|
62
|
+
const options = {
|
|
63
|
+
yes: args.yes,
|
|
64
|
+
};
|
|
65
|
+
if (!name)
|
|
66
|
+
die("Please provide a package name");
|
|
67
|
+
// Check valid preset
|
|
68
|
+
if (!VALID_PRESETS.includes(preset))
|
|
69
|
+
die(`Invalid preset: ${preset}`);
|
|
70
|
+
const targetDir = path.join(process.cwd(), name);
|
|
71
|
+
if (await fs.pathExists(targetDir))
|
|
72
|
+
die("A directory already exists");
|
|
73
|
+
// 1) create directory
|
|
74
|
+
await fs.mkdirp(targetDir);
|
|
75
|
+
// 2) copy base template
|
|
76
|
+
const templateDir = getTemplateDir(preset);
|
|
77
|
+
if (!await fs.pathExists(templateDir))
|
|
78
|
+
die(`Template not found for preset: ${preset}`);
|
|
79
|
+
await fs.copy(templateDir, targetDir);
|
|
80
|
+
await patchTsConfig(targetDir, isESM);
|
|
81
|
+
if (enableEslint) {
|
|
82
|
+
await copyEslintConfig(targetDir, enablePrettier);
|
|
83
|
+
}
|
|
84
|
+
if (enablePrettier) {
|
|
85
|
+
await copyPrettierConfig(targetDir);
|
|
86
|
+
}
|
|
87
|
+
// 3) npm init -y
|
|
88
|
+
await run("npm", ["init", "-y"], targetDir);
|
|
89
|
+
// 4) install deps
|
|
90
|
+
await run("npm", ["i", "-D", "typescript", "ts-node", "@types/node"], targetDir);
|
|
91
|
+
if (enableEslint) {
|
|
92
|
+
await run("npm", [
|
|
93
|
+
"i",
|
|
94
|
+
"-D",
|
|
95
|
+
"eslint",
|
|
96
|
+
"@typescript-eslint/parser",
|
|
97
|
+
"@typescript-eslint/eslint-plugin"
|
|
98
|
+
], targetDir);
|
|
99
|
+
}
|
|
100
|
+
if (enablePrettier) {
|
|
101
|
+
await run("npm", [
|
|
102
|
+
"i",
|
|
103
|
+
"-D",
|
|
104
|
+
"prettier",
|
|
105
|
+
"eslint-config-prettier"
|
|
106
|
+
], targetDir);
|
|
107
|
+
}
|
|
108
|
+
// 5) patch package.json
|
|
109
|
+
const pkgPath = path.join(targetDir, "package.json");
|
|
110
|
+
const pkg = await fs.readJson(pkgPath);
|
|
111
|
+
pkg.scripts = pkg.scripts || {};
|
|
112
|
+
if (isESM) {
|
|
113
|
+
pkg.type = "module";
|
|
114
|
+
}
|
|
115
|
+
switch (preset) {
|
|
116
|
+
case "base":
|
|
117
|
+
pkg.scripts.build = "tsc";
|
|
118
|
+
pkg.scripts.dev = "tsx watch src/index.ts";
|
|
119
|
+
break;
|
|
120
|
+
case "library":
|
|
121
|
+
pkg.main = "dist/index.js";
|
|
122
|
+
pkg.types = "dist/index.d.ts";
|
|
123
|
+
pkg.scripts.build = "tsc";
|
|
124
|
+
break;
|
|
125
|
+
case "backend":
|
|
126
|
+
pkg.scripts.build = "tsc";
|
|
127
|
+
pkg.scripts.dev = "tsx watch src/index.ts";
|
|
128
|
+
pkg.scripts.start = "node dist/index.js";
|
|
129
|
+
break;
|
|
130
|
+
case "cli":
|
|
131
|
+
pkg.bin = {
|
|
132
|
+
...(pkg.bin || {}),
|
|
133
|
+
[name]: "dist/index.js"
|
|
134
|
+
};
|
|
135
|
+
pkg.scripts.build = "tsc";
|
|
136
|
+
break;
|
|
137
|
+
}
|
|
138
|
+
if (enableEslint) {
|
|
139
|
+
pkg.scripts.lint = "eslint .";
|
|
140
|
+
}
|
|
141
|
+
if (enablePrettier) {
|
|
142
|
+
pkg.scripts.format = "prettier --write .";
|
|
143
|
+
}
|
|
144
|
+
await fs.writeJson(pkgPath, pkg, { spaces: 2 });
|
|
145
|
+
console.log("\nโ
Done!");
|
|
146
|
+
console.log(`๐ cd ${name}`);
|
|
147
|
+
console.log("๐ npm run build");
|
|
148
|
+
}
|
|
149
|
+
main().catch((e) => die(e?.message || String(e)));
|
package/dist/index.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "ts-package-init",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "Fast, minimal, and modern TypeScript project initializer",
|
|
6
|
+
"author": "Mostafa Hanafy",
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"bin": {
|
|
9
|
+
"ts-package-init": "dist/cli.js"
|
|
10
|
+
},
|
|
11
|
+
"scripts": {
|
|
12
|
+
"dev": "tsx ./src/cli.ts",
|
|
13
|
+
"build": "tsc -p tsconfig.json"
|
|
14
|
+
},
|
|
15
|
+
"keywords": [
|
|
16
|
+
"typescript",
|
|
17
|
+
"cli",
|
|
18
|
+
"scaffold",
|
|
19
|
+
"generator",
|
|
20
|
+
"init",
|
|
21
|
+
"create-ts",
|
|
22
|
+
"typescript-cli"
|
|
23
|
+
],
|
|
24
|
+
"repository": {
|
|
25
|
+
"type": "git",
|
|
26
|
+
"url": "https://github.com/mostafasayed/ts-package-init"
|
|
27
|
+
},
|
|
28
|
+
"homepage": "https://github.com/mostafasayed/ts-package-init",
|
|
29
|
+
"dependencies": {
|
|
30
|
+
"execa": "^9.6.1",
|
|
31
|
+
"fs-extra": "^11.3.3",
|
|
32
|
+
"minimist": "^1.2.8"
|
|
33
|
+
},
|
|
34
|
+
"devDependencies": {
|
|
35
|
+
"@types/fs-extra": "^11.0.4",
|
|
36
|
+
"@types/minimist": "^1.2.5",
|
|
37
|
+
"@types/node": "^25.0.5",
|
|
38
|
+
"tsx": "^4.21.0",
|
|
39
|
+
"typescript": "^5.9.3"
|
|
40
|
+
},
|
|
41
|
+
"files": [
|
|
42
|
+
"dist",
|
|
43
|
+
"templates",
|
|
44
|
+
"README.md"
|
|
45
|
+
],
|
|
46
|
+
"engines": {
|
|
47
|
+
"node": ">=18"
|
|
48
|
+
}
|
|
49
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
console.log("Backend service started");
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import js from "@eslint/js";
|
|
2
|
+
import tseslint from "typescript-eslint";
|
|
3
|
+
import prettier from "eslint-config-prettier";
|
|
4
|
+
|
|
5
|
+
export default [
|
|
6
|
+
js.configs.recommended,
|
|
7
|
+
...tseslint.configs.recommended,
|
|
8
|
+
prettier,
|
|
9
|
+
{
|
|
10
|
+
rules: {
|
|
11
|
+
"no-console": "off"
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
];
|