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