@marcuth/create-package 0.1.2 → 0.2.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,44 @@
1
+ # @marcuth/create-package
2
+
3
+ A personalized CLI tool to quickly bootstrap a new TypeScript package with a predefined set of best practices and tools.
4
+
5
+ ## ✨ Features
6
+
7
+ - **TypeScript Ready**: Pre-configured `tsconfig.json` for modern Node.js development.
8
+ - **ESLint & Prettier**: Full linting setup including `eslint-plugin-unused-imports` and automatic code formatting.
9
+ - **Git Integration**: Automatically initializes a git repository, prompts for a remote origin, and sets up `.gitignore` and `.gitattributes`.
10
+ - **Package Metadata**: Infers `homepage` and `bugs` URLs from your repository link (GitHub/GitLab).
11
+ - **Package Manager Detection**: Intelligently detects whether you are using `npm`, `pnpm`, or `yarn`.
12
+
13
+ ## 🚀 Usage
14
+
15
+ You can run it directly npm:
16
+
17
+ ```bash
18
+ npm create @marcuth/package@latest my-package # or npm init @marcuth/package@latest my-package
19
+ ```
20
+
21
+ Or for scoped packages:
22
+
23
+ ```bash
24
+ npm create @marcuth/package@latest @scope/my-package # or npm init @marcuth/package@latest @scope/my-package
25
+ ```
26
+
27
+ ## 🛠️ What's Inside the Generated Project?
28
+
29
+ - **Standard Directory Structure**: `src/` directory for your TypeScript source code.
30
+ - **Pre-configured Scripts**:
31
+ - `npm run build`: Compiles TypeScript to `dist/`.
32
+ - `npm run dev`: Runs the project using `ts-node`.
33
+ - `npm run format`: Formats code using Prettier.
34
+ - `npm run lint`: Checks for linting errors and removes unused imports.
35
+ - **Standard Files**: `.gitignore`, `.gitattributes`, `LICENSE` (MIT), `README.md`, and `.npmignore`.
36
+
37
+ ## 📦 Requirements
38
+
39
+ - Node.js installed.
40
+ - Git (optional, but recommended for repository initialization).
41
+
42
+ ## 📄 License
43
+
44
+ MIT © [Marcuth](https://github.com/marcuth)
package/bin/index.js CHANGED
@@ -1,457 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- import fs from "fs"
4
- import path from "path"
5
- import { spawnSync } from "child_process"
3
+ import { main } from "../src/index.js"
6
4
 
7
- function getInputName() {
8
- return process.argv[2] || "my-package"
9
- }
10
-
11
- function parsePackageName(inputName) {
12
- if (inputName.startsWith("@")) {
13
- if (!inputName.includes("/")) {
14
- console.error("❌ Invalid scope. Use @scope/name")
15
- process.exit(1)
16
- }
17
-
18
- const [, name] = inputName.split("/")
19
- return {
20
- packageName: inputName,
21
- projectDir: name
22
- }
23
- }
24
-
25
- return {
26
- packageName: inputName,
27
- projectDir: inputName
28
- }
29
- }
30
-
31
- function createDirectories(root) {
32
- fs.mkdirSync(root, { recursive: true })
33
- fs.mkdirSync(path.join(root, "src"))
34
- }
35
-
36
- function writePackageJson(root, packageName) {
37
- const content = {
38
- name: packageName,
39
- version: "0.1.0",
40
- type: "commonjs",
41
- main: "./dist/index.js",
42
- module: "./dist/index.js",
43
- types: "./dist/index.d.ts",
44
- files: [
45
- "dist/*",
46
- "!/**/__tests__"
47
- ],
48
- scripts: {
49
- build: "tsc",
50
- dev: "ts-node ./src/index.ts",
51
- format: "prettier --write \"src/**/*.ts\""
52
- },
53
- keywords: [
54
- "marcuth"
55
- ],
56
- author: "Marcuth",
57
- license: "MIT"
58
- }
59
-
60
- fs.writeFileSync(
61
- path.join(root, "package.json"),
62
- JSON.stringify(content, null, 2)
63
- )
64
- }
65
-
66
- function writeTsConfig(root) {
67
- const content = {
68
- "compilerOptions": {
69
- "target": "es2019",
70
- "lib": ["ES2015"],
71
- "module": "NodeNext",
72
- "esModuleInterop": true,
73
- "forceConsistentCasingInFileNames": true,
74
- "strict": true,
75
- "skipLibCheck": true,
76
- "outDir": "./dist",
77
- "rootDir": "./src",
78
- "declaration": true,
79
- "declarationMap": false,
80
- },
81
- "include": ["src"],
82
- "exclude": ["node_modules", "dist"]
83
- }
84
-
85
-
86
- fs.writeFileSync(
87
- path.join(root, "tsconfig.json"),
88
- JSON.stringify(content, null, 2)
89
- )
90
- }
91
-
92
- function writeSourceFile(root, projectDir) {
93
- const content = `function main() {
94
- console.log("Hello from ${projectDir}")
95
- }
96
-
97
- main()
98
- `
99
-
100
- fs.writeFileSync(
101
- path.join(root, "src/index.ts"),
102
- content
103
- )
104
- }
105
-
106
- function writeLicenseFile(root) {
107
- const currentYear = new Date().getFullYear()
108
-
109
- const content = `MIT License
110
-
111
- Copyright (c) ${currentYear} Marcuth
112
-
113
- Permission is hereby granted, free of charge, to any person obtaining a copy
114
- of this software and associated documentation files (the "Software"), to deal
115
- in the Software without restriction, including without limitation the rights
116
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
117
- copies of the Software, and to permit persons to whom the Software is
118
- furnished to do so, subject to the following conditions:
119
-
120
- The above copyright notice and this permission notice shall be included in all
121
- copies or substantial portions of the Software.
122
-
123
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
124
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
125
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
126
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
127
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
128
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
129
- SOFTWARE.`
130
-
131
- fs.writeFileSync(
132
- path.join(root, "LICENSE"),
133
- content
134
- )
135
- }
136
-
137
- function writeGitignoreFile(root) {
138
- const content = `# Created by https://www.toptal.com/developers/gitignore/api/node
139
- # Edit at https://www.toptal.com/developers/gitignore?templates=node
140
-
141
- ### Node ###
142
- # Logs
143
- dist/
144
- logs
145
- *.log
146
- npm-debug.log*
147
- yarn-debug.log*
148
- yarn-error.log*
149
- lerna-debug.log*
150
- .pnpm-debug.log*
151
-
152
- # Diagnostic reports (https://nodejs.org/api/report.html)
153
- report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
154
-
155
- # Runtime data
156
- pids
157
- *.pid
158
- *.seed
159
- *.pid.lock
160
-
161
- # Directory for instrumented libs generated by jscoverage/JSCover
162
- lib-cov
163
-
164
- # Coverage directory used by tools like istanbul
165
- coverage
166
- *.lcov
167
-
168
- # nyc test coverage
169
- .nyc_output
170
-
171
- # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
172
- .grunt
173
-
174
- # Bower dependency directory (https://bower.io/)
175
- bower_components
176
-
177
- # node-waf configuration
178
- .lock-wscript
179
-
180
- # Compiled binary addons (https://nodejs.org/api/addons.html)
181
- build/Release
182
-
183
- # Dependency directories
184
- node_modules/
185
- jspm_packages/
186
-
187
- # Snowpack dependency directory (https://snowpack.dev/)
188
- web_modules/
189
-
190
- # TypeScript cache
191
- *.tsbuildinfo
192
-
193
- # Optional npm cache directory
194
- .npm
195
-
196
- # Optional eslint cache
197
- .eslintcache
198
-
199
- # Optional stylelint cache
200
- .stylelintcache
201
-
202
- # Microbundle cache
203
- .rpt2_cache/
204
- .rts2_cache_cjs/
205
- .rts2_cache_es/
206
- .rts2_cache_umd/
207
-
208
- # Optional REPL history
209
- .node_repl_history
210
-
211
- # Output of 'npm pack'
212
- *.tgz
213
-
214
- # Yarn Integrity file
215
- .yarn-integrity
216
-
217
- # dotenv environment variable files
218
- .env
219
- .env.development.local
220
- .env.test.local
221
- .env.production.local
222
- .env.local
223
-
224
- # parcel-bundler cache (https://parceljs.org/)
225
- .cache
226
- .parcel-cache
227
-
228
- # Next.js build output
229
- .next
230
- out
231
-
232
- # Nuxt.js build / generate output
233
- .nuxt
234
- dist
235
-
236
- # Gatsby files
237
- .cache/
238
- # Comment in the public line in if your project uses Gatsby and not Next.js
239
- # https://nextjs.org/blog/next-9-1#public-directory-support
240
- # public
241
-
242
- # vuepress build output
243
- .vuepress/dist
244
-
245
- # vuepress v2.x temp and cache directory
246
- .temp
247
-
248
- # Docusaurus cache and generated files
249
- .docusaurus
250
-
251
- # Serverless directories
252
- .serverless/
253
-
254
- # FuseBox cache
255
- .fusebox/
256
-
257
- # DynamoDB Local files
258
- .dynamodb/
259
-
260
- # TernJS port file
261
- .tern-port
262
-
263
- # Stores VSCode versions used for testing VSCode extensions
264
- .vscode-test
265
-
266
- # yarn v2
267
- .yarn/cache
268
- .yarn/unplugged
269
- .yarn/build-state.yml
270
- .yarn/install-state.gz
271
- .pnp.*
272
-
273
- ### Node Patch ###
274
- # Serverless Webpack directories
275
- .webpack/
276
-
277
- # Optional stylelint cache
278
-
279
- # SvelteKit build / generate output
280
- .svelte-kit
281
-
282
- # End of https://www.toptal.com/developers/gitignore/api/node`
283
-
284
- fs.writeFileSync(
285
- path.join(root, ".gitignore"),
286
- content
287
- )
288
- }
289
-
290
- function createNpmIgnore(root) {
291
- const content = `src/
292
- tsconfig.json`
293
-
294
- fs.writeFileSync(
295
- path.join(root, ".npmignore"),
296
- content
297
- )
298
- }
299
-
300
- function createReadme(root, packageName) {
301
- const content = `# ${packageName}`
302
-
303
- fs.writeFileSync(
304
- path.join(root, "README.md"),
305
- content
306
- )
307
- }
308
-
309
- function createEsLintRcConfig(root) {
310
- const content = {
311
- "extends": [
312
- "plugin:prettier/recommended"
313
- ],
314
- "plugins": [
315
- "prettier"
316
- ],
317
- "rules": {
318
- "prettier/prettier": "error"
319
- }
320
- }
321
-
322
- fs.writeFileSync(
323
- path.join(root, ".eslintrc.json"),
324
- JSON.stringify(content, null, 4)
325
- )
326
- }
327
-
328
- function createPrettierConfig(root) {
329
- const content = `module.exports = {
330
- "semi": false,
331
- "singleQuote": false,
332
- "tabWidth": 4,
333
- "useTabs": false,
334
- "importTypeOrder": ["NPMPackages", "localImports"],
335
- "newlineBetweenTypes": true,
336
- "sortingMethod": "lineLength",
337
- "plugins": ["./node_modules/prettier-plugin-sort-imports/dist/index.js"],
338
- "endOfLine": "auto",
339
- "printWidth": 120
340
- }`
341
-
342
- fs.writeFileSync(
343
- path.join(root, ".prettierrc.js"),
344
- content
345
- )
346
- }
347
-
348
- function detectPackageManager() {
349
- const userAgent = process.env.npm_config_user_agent || ""
350
-
351
- if (userAgent.includes("pnpm")) return "pnpm"
352
- if (userAgent.includes("yarn")) return "yarn"
353
-
354
- return "npm"
355
- }
356
-
357
- function installDevDependencies(root, deps) {
358
- const pm = detectPackageManager()
359
-
360
- const commands = {
361
- npm: ["install", "--save-dev", ...deps],
362
- pnpm: ["add", "-D", ...deps],
363
- yarn: ["add", "-D", ...deps]
364
- }
365
-
366
- console.log("📦 Installing dev dependencies using", pm)
367
- console.log("📦 Command:", pm, commands[pm].join(" "))
368
-
369
- const result = spawnSync(pm, commands[pm], {
370
- cwd: root,
371
- stdio: "inherit",
372
- shell: true
373
- })
374
-
375
- if (result.error) {
376
- console.error("❌ Spawn error:", result.error)
377
- process.exit(1)
378
- }
379
-
380
- if (result.status !== 0) {
381
- console.error("❌ Failed to install dev dependencies")
382
- process.exit(1)
383
- }
384
- }
385
-
386
- function hasGit() {
387
- const result = spawnSync("git", ["--version"], { stdio: "ignore" })
388
- return result.status === 0
389
- }
390
-
391
- function initGitRepo(root) {
392
- if (!hasGit()) {
393
- console.log("⚠️ Git not found, skipping git init")
394
- return
395
- }
396
-
397
- console.log("🌱 Initializing git repository")
398
-
399
- const result = spawnSync(
400
- "git",
401
- ["init"],
402
- {
403
- cwd: root,
404
- stdio: "inherit"
405
- }
406
- )
407
-
408
- if (result.status !== 0) {
409
- console.error("❌ Falha ao inicializar git")
410
- process.exit(1)
411
- }
412
- }
413
-
414
- function createInitialCommit(root) {
415
- console.log("📸 Creating initial commit")
416
-
417
- spawnSync("git", ["add", "."], {
418
- cwd: root,
419
- stdio: "inherit"
420
- })
421
-
422
- spawnSync(
423
- "git",
424
- ["commit", "-m", "chore: initial commit"],
425
- {
426
- cwd: root,
427
- stdio: "inherit"
428
- }
429
- )
430
- }
431
-
432
- function main() {
433
- const inputName = getInputName()
434
- const { packageName, projectDir } = parsePackageName(inputName)
435
- const root = path.resolve(process.cwd(), projectDir)
436
- const devDependencies = ["@types/node", "ts-node", "typescript", "prettier", "prettier-plugin-sort-imports", "eslint", "eslint-config-prettier", "eslint-plugin-prettier"]
437
-
438
- createDirectories(root)
439
- writePackageJson(root, packageName)
440
- writeTsConfig(root)
441
- writeSourceFile(root, projectDir)
442
- writeLicenseFile(root)
443
- writeGitignoreFile(root)
444
- installDevDependencies(root, devDependencies)
445
- initGitRepo(root)
446
- createNpmIgnore(root)
447
- createReadme(root, packageName)
448
- createEsLintRcConfig(root)
449
- createPrettierConfig(root)
450
- createInitialCommit(root)
451
-
452
- console.log("✅ Creeated project")
453
- console.log("📦 Package:", packageName)
454
- console.log("📁 Folder:", projectDir)
455
- }
456
-
457
- main()
5
+ main().catch(err => {
6
+ console.error("❌ Unexpected error:", err)
7
+ process.exit(1)
8
+ })
package/package.json CHANGED
@@ -1,9 +1,13 @@
1
1
  {
2
2
  "name": "@marcuth/create-package",
3
- "version": "0.1.2",
3
+ "version": "0.2.0",
4
4
  "description": "Create a new package",
5
- "main": "index.js",
5
+ "main": "bin/index.js",
6
6
  "type": "module",
7
+ "files": [
8
+ "bin",
9
+ "src"
10
+ ],
7
11
  "bin": {
8
12
  "create-package": "./bin/index.js"
9
13
  },
@@ -15,4 +19,4 @@
15
19
  ],
16
20
  "author": "Marcuth",
17
21
  "license": "MIT"
18
- }
22
+ }
package/src/index.js ADDED
@@ -0,0 +1,63 @@
1
+ import path from "node:path"
2
+ import readline from "node:readline/promises"
3
+ import { getInputName, parsePackageName } from "./input.js"
4
+ import {
5
+ createDirectories,
6
+ writePackageJson,
7
+ writeTsConfig,
8
+ writeSourceFile,
9
+ writeLicenseFile,
10
+ writeGitignoreFile,
11
+ writeGitAttributes,
12
+ createNpmIgnore,
13
+ createReadme,
14
+ createEsLintRcConfig,
15
+ createPrettierConfig
16
+ } from "./writers.js"
17
+ import { installDevDependencies, initGitRepo, createInitialCommit } from "./system.js"
18
+
19
+ export async function main() {
20
+ const inputName = getInputName()
21
+ const { packageName, projectDir } = parsePackageName(inputName)
22
+ const root = path.resolve(process.cwd(), projectDir)
23
+
24
+ const rl = readline.createInterface({
25
+ input: process.stdin,
26
+ output: process.stdout
27
+ })
28
+
29
+ const repoUrl = await rl.question("🔗 Repository URL (optional): ")
30
+
31
+ rl.close()
32
+
33
+ const devDependencies = [
34
+ "@types/node",
35
+ "ts-node",
36
+ "typescript",
37
+ "prettier",
38
+ "prettier-plugin-sort-imports",
39
+ "eslint",
40
+ "eslint-config-prettier",
41
+ "eslint-plugin-prettier",
42
+ "eslint-plugin-unused-imports"
43
+ ]
44
+
45
+ createDirectories(root)
46
+ writePackageJson(root, packageName, repoUrl)
47
+ writeTsConfig(root)
48
+ writeSourceFile(root, projectDir)
49
+ writeLicenseFile(root)
50
+ writeGitignoreFile(root)
51
+ writeGitAttributes(root)
52
+ installDevDependencies(root, devDependencies)
53
+ initGitRepo(root, repoUrl)
54
+ createNpmIgnore(root)
55
+ createReadme(root, packageName)
56
+ createEsLintRcConfig(root)
57
+ createPrettierConfig(root)
58
+ createInitialCommit(root)
59
+
60
+ console.log("✅ Creeated project")
61
+ console.log("📦 Package:", packageName)
62
+ console.log("📁 Folder:", projectDir)
63
+ }
package/src/input.js ADDED
@@ -0,0 +1,24 @@
1
+ export function getInputName() {
2
+ return process.argv[2] || "my-package"
3
+ }
4
+
5
+ export function parsePackageName(inputName) {
6
+ if (inputName.startsWith("@")) {
7
+ if (!inputName.includes("/")) {
8
+ console.error("❌ Invalid scope. Use @scope/name")
9
+ process.exit(1)
10
+ }
11
+
12
+ const [, name] = inputName.split("/")
13
+
14
+ return {
15
+ packageName: inputName,
16
+ projectDir: name
17
+ }
18
+ }
19
+
20
+ return {
21
+ packageName: inputName,
22
+ projectDir: inputName
23
+ }
24
+ }
package/src/system.js ADDED
@@ -0,0 +1,92 @@
1
+ import { spawnSync } from "node:child_process"
2
+
3
+ export function detectPackageManager() {
4
+ const userAgent = process.env.npm_config_user_agent || ""
5
+
6
+ if (userAgent.includes("pnpm")) return "pnpm"
7
+ if (userAgent.includes("yarn")) return "yarn"
8
+
9
+ return "npm"
10
+ }
11
+
12
+ export function installDevDependencies(root, deps) {
13
+ const pm = detectPackageManager()
14
+
15
+ const commands = {
16
+ npm: ["install", "--save-dev", ...deps],
17
+ pnpm: ["add", "-D", ...deps],
18
+ yarn: ["add", "-D", ...deps]
19
+ }
20
+
21
+ console.log("📦 Installing dev dependencies using", pm)
22
+ console.log("📦 Command:", pm, commands[pm].join(" "))
23
+
24
+ const result = spawnSync(pm, commands[pm], {
25
+ cwd: root,
26
+ stdio: "inherit",
27
+ shell: true
28
+ })
29
+
30
+ if (result.error) {
31
+ console.error("❌ Spawn error:", result.error)
32
+ process.exit(1)
33
+ }
34
+
35
+ if (result.status !== 0) {
36
+ console.error("❌ Failed to install dev dependencies")
37
+ process.exit(1)
38
+ }
39
+ }
40
+
41
+ export function hasGit() {
42
+ const result = spawnSync("git", ["--version"], { stdio: "ignore" })
43
+ return result.status === 0
44
+ }
45
+
46
+ export function initGitRepo(root, repoUrl = "") {
47
+ if (!hasGit()) {
48
+ console.log("⚠️ Git not found, skipping git init")
49
+ return
50
+ }
51
+
52
+ console.log("🌱 Initializing git repository")
53
+
54
+ spawnSync(
55
+ "git",
56
+ ["init"],
57
+ {
58
+ cwd: root,
59
+ stdio: "inherit"
60
+ }
61
+ )
62
+
63
+ if (repoUrl) {
64
+ console.log("🔗 Setting remote origin:", repoUrl)
65
+ spawnSync(
66
+ "git",
67
+ ["remote", "add", "origin", repoUrl],
68
+ {
69
+ cwd: root,
70
+ stdio: "inherit"
71
+ }
72
+ )
73
+ }
74
+ }
75
+
76
+ export function createInitialCommit(root) {
77
+ console.log("📸 Creating initial commit")
78
+
79
+ spawnSync("git", ["add", "."], {
80
+ cwd: root,
81
+ stdio: "inherit"
82
+ })
83
+
84
+ spawnSync(
85
+ "git",
86
+ ["commit", "-m", "chore: initial commit"],
87
+ {
88
+ cwd: root,
89
+ stdio: "inherit"
90
+ }
91
+ )
92
+ }
package/src/writers.js ADDED
@@ -0,0 +1,359 @@
1
+ import fs from "node:fs"
2
+ import path from "node:path"
3
+
4
+ export function createDirectories(root) {
5
+ fs.mkdirSync(root, { recursive: true })
6
+ fs.mkdirSync(path.join(root, "src"))
7
+ }
8
+
9
+ export function writePackageJson(root, packageName, repoUrl = "") {
10
+ let homepage = undefined
11
+ let bugs = undefined
12
+
13
+ if (repoUrl) {
14
+ const baseUrl = repoUrl.replace(/\.git$/, "")
15
+
16
+ if (repoUrl.includes("github.com") || repoUrl.includes("gitlab.com")) {
17
+ homepage = `${baseUrl}#readme`
18
+ bugs = {
19
+ url: `${baseUrl}/issues`
20
+ }
21
+ }
22
+ }
23
+
24
+ const content = {
25
+ name: packageName,
26
+ version: "0.1.0",
27
+ type: "commonjs",
28
+ repository: repoUrl ? {
29
+ type: "git",
30
+ url: repoUrl
31
+ } : undefined,
32
+ homepage,
33
+ bugs,
34
+ main: "./dist/index.js",
35
+ module: "./dist/index.js",
36
+ types: "./dist/index.d.ts",
37
+ files: [
38
+ "dist/*",
39
+ "!/**/__tests__"
40
+ ],
41
+ scripts: {
42
+ build: "tsc",
43
+ dev: "ts-node ./src/index.ts",
44
+ format: "prettier --write \"src/**/*.ts\"",
45
+ lint: "eslint \"src/**/*.ts\" --fix"
46
+ },
47
+ publishConfig: {
48
+ access: "public"
49
+ },
50
+ keywords: [
51
+ "marcuth"
52
+ ],
53
+ author: "Marcuth",
54
+ license: "MIT"
55
+ }
56
+
57
+ fs.writeFileSync(
58
+ path.join(root, "package.json"),
59
+ JSON.stringify(content, null, 2)
60
+ )
61
+ }
62
+
63
+ export function writeTsConfig(root) {
64
+ const content = {
65
+ "compilerOptions": {
66
+ "target": "es2019",
67
+ "lib": ["ES2015"],
68
+ "module": "NodeNext",
69
+ "esModuleInterop": true,
70
+ "forceConsistentCasingInFileNames": true,
71
+ "strict": true,
72
+ "skipLibCheck": true,
73
+ "outDir": "./dist",
74
+ "rootDir": "./src",
75
+ "declaration": true,
76
+ "declarationMap": false,
77
+ },
78
+ "include": ["src"],
79
+ "exclude": ["node_modules", "dist"]
80
+ }
81
+
82
+ fs.writeFileSync(
83
+ path.join(root, "tsconfig.json"),
84
+ JSON.stringify(content, null, 2)
85
+ )
86
+ }
87
+
88
+ export function writeSourceFile(root, projectDir) {
89
+ const content = `function main() {
90
+ console.log("Hello from ${projectDir}")
91
+ }
92
+
93
+ main()
94
+ `
95
+
96
+ fs.writeFileSync(
97
+ path.join(root, "src/index.ts"),
98
+ content
99
+ )
100
+ }
101
+
102
+ export function writeLicenseFile(root) {
103
+ const currentYear = new Date().getFullYear()
104
+
105
+ const content = `MIT License
106
+
107
+ Copyright (c) ${currentYear} Marcuth
108
+
109
+ Permission is hereby granted, free of charge, to any person obtaining a copy
110
+ of this software and associated documentation files (the "Software"), to deal
111
+ in the Software without restriction, including without limitation the rights
112
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
113
+ copies of the Software, and to permit persons to whom the Software is
114
+ furnished to do so, subject to the following conditions:
115
+
116
+ The above copyright notice and this permission notice shall be included in all
117
+ copies or substantial portions of the Software.
118
+
119
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
120
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
121
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
122
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
123
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
124
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
125
+ SOFTWARE.`
126
+
127
+ fs.writeFileSync(
128
+ path.join(root, "LICENSE"),
129
+ content
130
+ )
131
+ }
132
+
133
+ export function writeGitignoreFile(root) {
134
+ const content = `# Created by https://www.toptal.com/developers/gitignore/api/node
135
+ # Edit at https://www.toptal.com/developers/gitignore?templates=node
136
+
137
+ ### Node ###
138
+ # Logs
139
+ dist/
140
+ logs
141
+ *.log
142
+ npm-debug.log*
143
+ yarn-debug.log*
144
+ yarn-error.log*
145
+ lerna-debug.log*
146
+ .pnpm-debug.log*
147
+
148
+ # Diagnostic reports (https://nodejs.org/api/report.html)
149
+ report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
150
+
151
+ # Runtime data
152
+ pids
153
+ *.pid
154
+ *.seed
155
+ *.pid.lock
156
+
157
+ # Directory for instrumented libs generated by jscoverage/JSCover
158
+ lib-cov
159
+
160
+ # Coverage directory used by tools like istanbul
161
+ coverage
162
+ *.lcov
163
+
164
+ # nyc test coverage
165
+ .nyc_output
166
+
167
+ # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
168
+ .grunt
169
+
170
+ # Bower dependency directory (https://bower.io/)
171
+ bower_components
172
+
173
+ # node-waf configuration
174
+ .lock-wscript
175
+
176
+ # Compiled binary addons (https://nodejs.org/api/addons.html)
177
+ build/Release
178
+
179
+ # Dependency directories
180
+ node_modules/
181
+ jspm_packages/
182
+
183
+ # Snowpack dependency directory (https://snowpack.dev/)
184
+ web_modules/
185
+
186
+ # TypeScript cache
187
+ *.tsbuildinfo
188
+
189
+ # Optional npm cache directory
190
+ .npm
191
+
192
+ # Optional eslint cache
193
+ .eslintcache
194
+
195
+ # Optional stylelint cache
196
+ .stylelintcache
197
+
198
+ # Microbundle cache
199
+ .rpt2_cache/
200
+ .rts2_cache_cjs/
201
+ .rts2_cache_es/
202
+ .rts2_cache_umd/
203
+
204
+ # Optional REPL history
205
+ .node_repl_history
206
+
207
+ # Output of 'npm pack'
208
+ *.tgz
209
+
210
+ # Yarn Integrity file
211
+ .yarn-integrity
212
+
213
+ # dotenv environment variable files
214
+ .env
215
+ .env.development.local
216
+ .env.test.local
217
+ .env.production.local
218
+ .env.local
219
+
220
+ # parcel-bundler cache (https://parceljs.org/)
221
+ .cache
222
+ .parcel-cache
223
+
224
+ # Next.js build output
225
+ .next
226
+ out
227
+
228
+ # Nuxt.js build / generate output
229
+ .nuxt
230
+ dist
231
+
232
+ # Gatsby files
233
+ .cache/
234
+ # Comment in the public line in if your project uses Gatsby and not Next.js
235
+ # https://nextjs.org/blog/next-9-1#public-directory-support
236
+ # public
237
+
238
+ # vuepress build output
239
+ .vuepress/dist
240
+
241
+ # vuepress v2.x temp and cache directory
242
+ .temp
243
+
244
+ # Docusaurus cache and generated files
245
+ .docusaurus
246
+
247
+ # Serverless directories
248
+ .serverless/
249
+
250
+ # FuseBox cache
251
+ .fusebox/
252
+
253
+ # DynamoDB Local files
254
+ .dynamodb/
255
+
256
+ # TernJS port file
257
+ .tern-port
258
+
259
+ # Stores VSCode versions used for testing VSCode extensions
260
+ .vscode-test
261
+
262
+ # yarn v2
263
+ .yarn/cache
264
+ .yarn/unplugged
265
+ .yarn/build-state.yml
266
+ .yarn/install-state.gz
267
+ .pnp.*
268
+
269
+ ### Node Patch ###
270
+ # Serverless Webpack directories
271
+ .webpack/
272
+
273
+ # Optional stylelint cache
274
+
275
+ # SvelteKit build / generate output
276
+ .svelte-kit
277
+
278
+ # End of https://www.toptal.com/developers/gitignore/api/node`
279
+
280
+ fs.writeFileSync(
281
+ path.join(root, ".gitignore"),
282
+ content
283
+ )
284
+ }
285
+
286
+ export function writeGitAttributes(root) {
287
+ const content = `*.js linguist-generated=true
288
+ *.d.ts linguist-generated=true`
289
+
290
+ fs.writeFileSync(
291
+ path.join(root, ".gitattributes"),
292
+ content
293
+ )
294
+ }
295
+
296
+ export function createNpmIgnore(root) {
297
+ const content = `src/
298
+ tsconfig.json`
299
+
300
+ fs.writeFileSync(
301
+ path.join(root, ".npmignore"),
302
+ content
303
+ )
304
+ }
305
+
306
+ export function createReadme(root, packageName) {
307
+ const content = `# ${packageName}`
308
+
309
+ fs.writeFileSync(
310
+ path.join(root, "README.md"),
311
+ content
312
+ )
313
+ }
314
+
315
+ export function createEsLintRcConfig(root) {
316
+ const content = {
317
+ "extends": [
318
+ "plugin:prettier/recommended"
319
+ ],
320
+ "plugins": [
321
+ "prettier",
322
+ "unused-imports"
323
+ ],
324
+ "rules": {
325
+ "prettier/prettier": "error",
326
+ "no-unused-vars": "off",
327
+ "unused-imports/no-unused-imports": "error",
328
+ "unused-imports/no-unused-vars": [
329
+ "warn",
330
+ { "vars": "all", "varsIgnorePattern": "^_", "args": "after-used", "argsIgnorePattern": "^_" }
331
+ ]
332
+ }
333
+ }
334
+
335
+ fs.writeFileSync(
336
+ path.join(root, ".eslintrc.json"),
337
+ JSON.stringify(content, null, 4)
338
+ )
339
+ }
340
+
341
+ export function createPrettierConfig(root) {
342
+ const content = `module.exports = {
343
+ "semi": false,
344
+ "singleQuote": false,
345
+ "tabWidth": 4,
346
+ "useTabs": false,
347
+ "importTypeOrder": ["NPMPackages", "localImports"],
348
+ "newlineBetweenTypes": true,
349
+ "sortingMethod": "lineLength",
350
+ "plugins": ["./node_modules/prettier-plugin-sort-imports/dist/index.js"],
351
+ "endOfLine": "auto",
352
+ "printWidth": 120
353
+ }`
354
+
355
+ fs.writeFileSync(
356
+ path.join(root, ".prettierrc.js"),
357
+ content
358
+ )
359
+ }