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 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
@@ -0,0 +1,4 @@
1
+ // Entry point for your TypeScript package
2
+ export function hello(name) {
3
+ return `Hello, ${name}!`;
4
+ }
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,10 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "CommonJS",
5
+ "rootDir": "src",
6
+ "outDir": "dist",
7
+ "strict": true,
8
+ "esModuleInterop": true
9
+ }
10
+ }
@@ -0,0 +1,3 @@
1
+ export function hello(name: string) {
2
+ console.log(`Hello, ${name}`);
3
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2020",
4
+ "module": "CommonJS",
5
+ "rootDir": "src",
6
+ "outDir": "dist",
7
+ "strict": true,
8
+ "esModuleInterop": true,
9
+ "skipLibCheck": true,
10
+ "forceConsistentCasingInFileNames": true
11
+ }
12
+ }
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+
3
+ console.log("CLI tool running");
@@ -0,0 +1,10 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "CommonJS",
5
+ "rootDir": "src",
6
+ "outDir": "dist",
7
+ "strict": true,
8
+ "esModuleInterop": true
9
+ }
10
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "semi": true,
3
+ "singleQuote": true,
4
+ "trailingComma": "all",
5
+ "printWidth": 100
6
+ }
@@ -0,0 +1,12 @@
1
+ import js from "@eslint/js";
2
+ import tseslint from "typescript-eslint";
3
+
4
+ export default [
5
+ js.configs.recommended,
6
+ ...tseslint.configs.recommended,
7
+ {
8
+ rules: {
9
+ "no-console": "off"
10
+ }
11
+ }
12
+ ];
@@ -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
+ ];
@@ -0,0 +1,3 @@
1
+ export function hello() {
2
+ return "Hello from library";
3
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2020",
4
+ "module": "CommonJS",
5
+ "rootDir": "src",
6
+ "outDir": "dist",
7
+ "declaration": true,
8
+ "strict": true,
9
+ "esModuleInterop": true
10
+ }
11
+ }