stackinit 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.
Files changed (63) hide show
  1. package/.editorconfig +18 -0
  2. package/.env.example +11 -0
  3. package/.eslintrc.json +30 -0
  4. package/.github/workflows/ci.yml +36 -0
  5. package/.prettierignore +11 -0
  6. package/.prettierrc.json +10 -0
  7. package/CONTRIBUTING.md +272 -0
  8. package/Dockerfile +36 -0
  9. package/LICENSE +22 -0
  10. package/README.md +202 -0
  11. package/dist/banner.d.ts +2 -0
  12. package/dist/banner.d.ts.map +1 -0
  13. package/dist/banner.js +16 -0
  14. package/dist/banner.js.map +1 -0
  15. package/dist/ci.d.ts +3 -0
  16. package/dist/ci.d.ts.map +1 -0
  17. package/dist/ci.js +83 -0
  18. package/dist/ci.js.map +1 -0
  19. package/dist/dependencies.d.ts +3 -0
  20. package/dist/dependencies.d.ts.map +1 -0
  21. package/dist/dependencies.js +102 -0
  22. package/dist/dependencies.js.map +1 -0
  23. package/dist/detect.d.ts +3 -0
  24. package/dist/detect.d.ts.map +1 -0
  25. package/dist/detect.js +125 -0
  26. package/dist/detect.js.map +1 -0
  27. package/dist/docker.d.ts +3 -0
  28. package/dist/docker.d.ts.map +1 -0
  29. package/dist/docker.js +100 -0
  30. package/dist/docker.js.map +1 -0
  31. package/dist/generate.d.ts +3 -0
  32. package/dist/generate.d.ts.map +1 -0
  33. package/dist/generate.js +71 -0
  34. package/dist/generate.js.map +1 -0
  35. package/dist/husky.d.ts +3 -0
  36. package/dist/husky.d.ts.map +1 -0
  37. package/dist/husky.js +92 -0
  38. package/dist/husky.js.map +1 -0
  39. package/dist/index.d.ts +3 -0
  40. package/dist/index.d.ts.map +1 -0
  41. package/dist/index.js +128 -0
  42. package/dist/index.js.map +1 -0
  43. package/dist/templates.d.ts +11 -0
  44. package/dist/templates.d.ts.map +1 -0
  45. package/dist/templates.js +209 -0
  46. package/dist/templates.js.map +1 -0
  47. package/dist/types.d.ts +16 -0
  48. package/dist/types.d.ts.map +1 -0
  49. package/dist/types.js +2 -0
  50. package/dist/types.js.map +1 -0
  51. package/docker-compose.yml +15 -0
  52. package/package.json +60 -0
  53. package/src/banner.ts +15 -0
  54. package/src/ci.ts +94 -0
  55. package/src/dependencies.ts +120 -0
  56. package/src/detect.ts +132 -0
  57. package/src/docker.ts +107 -0
  58. package/src/generate.ts +81 -0
  59. package/src/husky.ts +107 -0
  60. package/src/index.ts +145 -0
  61. package/src/templates.ts +244 -0
  62. package/src/types.ts +18 -0
  63. package/tsconfig.json +26 -0
@@ -0,0 +1,244 @@
1
+ import type { ProjectInfo, Options } from './types.js';
2
+
3
+ export interface Templates {
4
+ eslint: string;
5
+ prettier: string;
6
+ prettierIgnore: string;
7
+ gitignore: string;
8
+ editorconfig: string;
9
+ envExample: string;
10
+ }
11
+
12
+ export function getTemplates(projectInfo: ProjectInfo, options: Options): Templates {
13
+ return {
14
+ eslint: getESLintConfig(projectInfo, options),
15
+ prettier: getPrettierConfig(),
16
+ prettierIgnore: getPrettierIgnore(),
17
+ gitignore: getGitignore(projectInfo),
18
+ editorconfig: getEditorConfig(),
19
+ envExample: getEnvExample(projectInfo),
20
+ };
21
+ }
22
+
23
+ function getESLintConfig(projectInfo: ProjectInfo, options: Options): string {
24
+ const isStrict = options.strict ?? false;
25
+ const hasTypeScript = projectInfo.hasTypeScript;
26
+ const isReact = projectInfo.type === 'react' || projectInfo.type === 'nextjs' || projectInfo.type === 'vite';
27
+
28
+ const config: any = {
29
+ root: true,
30
+ env: {
31
+ node: true,
32
+ es2022: true,
33
+ ...(isReact && { browser: true }),
34
+ },
35
+ extends: [],
36
+ parserOptions: {
37
+ ecmaVersion: 2022,
38
+ sourceType: 'module',
39
+ },
40
+ rules: {
41
+ 'no-console': isStrict ? 'error' : 'warn',
42
+ 'no-debugger': isStrict ? 'error' : 'warn',
43
+ 'no-unused-vars': isStrict ? 'error' : 'warn',
44
+ 'prefer-const': 'error',
45
+ 'no-var': 'error',
46
+ },
47
+ };
48
+
49
+ if (hasTypeScript) {
50
+ config.parser = '@typescript-eslint/parser';
51
+ config.plugins = ['@typescript-eslint'];
52
+ config.extends.push(
53
+ 'eslint:recommended',
54
+ 'plugin:@typescript-eslint/recommended',
55
+ ...(isStrict ? ['plugin:@typescript-eslint/recommended-requiring-type-checking'] : [])
56
+ );
57
+ config.parserOptions = {
58
+ ...config.parserOptions,
59
+ project: './tsconfig.json',
60
+ };
61
+ config.rules = {
62
+ ...config.rules,
63
+ '@typescript-eslint/no-unused-vars': isStrict ? 'error' : 'warn',
64
+ '@typescript-eslint/explicit-function-return-type': isStrict ? 'warn' : 'off',
65
+ '@typescript-eslint/no-explicit-any': isStrict ? 'error' : 'warn',
66
+ };
67
+ } else {
68
+ config.extends.push('eslint:recommended');
69
+ }
70
+
71
+ if (isReact) {
72
+ config.extends.push('plugin:react/recommended', 'plugin:react-hooks/recommended');
73
+ config.settings = {
74
+ react: {
75
+ version: 'detect',
76
+ },
77
+ };
78
+ config.rules = {
79
+ ...config.rules,
80
+ 'react/react-in-jsx-scope': 'off', // Not needed in React 17+
81
+ 'react/prop-types': 'off', // TypeScript handles this
82
+ };
83
+ }
84
+
85
+ if (projectInfo.type === 'nextjs') {
86
+ config.extends.push('plugin:@next/next/recommended');
87
+ }
88
+
89
+ return JSON.stringify(config, null, 2);
90
+ }
91
+
92
+ function getPrettierConfig(): string {
93
+ return JSON.stringify(
94
+ {
95
+ semi: true,
96
+ trailingComma: 'es5',
97
+ singleQuote: true,
98
+ printWidth: 80,
99
+ tabWidth: 2,
100
+ useTabs: false,
101
+ arrowParens: 'always',
102
+ endOfLine: 'lf',
103
+ },
104
+ null,
105
+ 2
106
+ );
107
+ }
108
+
109
+ function getPrettierIgnore(): string {
110
+ return `node_modules
111
+ dist
112
+ build
113
+ .next
114
+ .nuxt
115
+ .cache
116
+ coverage
117
+ *.log
118
+ .DS_Store
119
+ .env
120
+ .env.local
121
+ `;
122
+ }
123
+
124
+ function getGitignore(projectInfo: ProjectInfo): string {
125
+ const base = `# Dependencies
126
+ node_modules/
127
+ .pnp
128
+ .pnp.js
129
+
130
+ # Testing
131
+ coverage/
132
+ *.lcov
133
+ .nyc_output
134
+
135
+ # Production
136
+ dist/
137
+ build/
138
+ .next/
139
+ out/
140
+ .nuxt/
141
+ .cache/
142
+
143
+ # Misc
144
+ .DS_Store
145
+ *.pem
146
+ *.log
147
+ npm-debug.log*
148
+ yarn-debug.log*
149
+ yarn-error.log*
150
+ pnpm-debug.log*
151
+ lerna-debug.log*
152
+
153
+ # Local env files
154
+ .env
155
+ .env*.local
156
+ .env.development.local
157
+ .env.test.local
158
+ .env.production.local
159
+
160
+ # IDE
161
+ .vscode/
162
+ .idea/
163
+ *.swp
164
+ *.swo
165
+ *~
166
+
167
+ # OS
168
+ Thumbs.db
169
+ `;
170
+
171
+ if (projectInfo.type === 'nextjs') {
172
+ return base + `
173
+ # Next.js
174
+ .next/
175
+ out/
176
+ `;
177
+ }
178
+
179
+ if (projectInfo.type === 'vite') {
180
+ return base + `
181
+ # Vite
182
+ dist/
183
+ dist-ssr/
184
+ *.local
185
+ `;
186
+ }
187
+
188
+ return base;
189
+ }
190
+
191
+ function getEditorConfig(): string {
192
+ return `root = true
193
+
194
+ [*]
195
+ charset = utf-8
196
+ end_of_line = lf
197
+ indent_style = space
198
+ indent_size = 2
199
+ insert_final_newline = true
200
+ trim_trailing_whitespace = true
201
+
202
+ [*.md]
203
+ trim_trailing_whitespace = false
204
+
205
+ [*.{yml,yaml}]
206
+ indent_size = 2
207
+
208
+ [Makefile]
209
+ indent_style = tab
210
+ `;
211
+ }
212
+
213
+ function getEnvExample(projectInfo: ProjectInfo): string {
214
+ const base = `# Environment variables
215
+ # Copy this file to .env and fill in the values
216
+
217
+ NODE_ENV=development
218
+ PORT=3000
219
+ `;
220
+
221
+ if (projectInfo.type === 'nextjs') {
222
+ return base + `
223
+ # Next.js
224
+ NEXT_PUBLIC_API_URL=http://localhost:3000/api
225
+ `;
226
+ }
227
+
228
+ if (projectInfo.type === 'react' || projectInfo.type === 'vite') {
229
+ return base + `
230
+ # API
231
+ VITE_API_URL=http://localhost:3000/api
232
+ REACT_APP_API_URL=http://localhost:3000/api
233
+ `;
234
+ }
235
+
236
+ return base + `
237
+ # Database (example)
238
+ # DATABASE_URL=postgresql://user:password@localhost:5432/dbname
239
+
240
+ # API Keys (example)
241
+ # API_KEY=your-api-key-here
242
+ `;
243
+ }
244
+
package/src/types.ts ADDED
@@ -0,0 +1,18 @@
1
+ export type ProjectType = 'node' | 'react' | 'nextjs' | 'vite' | 'unknown';
2
+ export type PackageManager = 'npm' | 'yarn' | 'pnpm';
3
+
4
+ export interface ProjectInfo {
5
+ type: ProjectType;
6
+ packageManager: PackageManager;
7
+ hasTypeScript: boolean;
8
+ isMonorepo: boolean;
9
+ rootPath: string;
10
+ }
11
+
12
+ export interface Options {
13
+ strict?: boolean;
14
+ docker?: boolean;
15
+ ciOnly?: boolean;
16
+ dryRun?: boolean;
17
+ }
18
+
package/tsconfig.json ADDED
@@ -0,0 +1,26 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "ES2022",
5
+ "lib": ["ES2022"],
6
+ "moduleResolution": "node",
7
+ "outDir": "./dist",
8
+ "rootDir": "./src",
9
+ "strict": true,
10
+ "esModuleInterop": true,
11
+ "skipLibCheck": true,
12
+ "forceConsistentCasingInFileNames": true,
13
+ "resolveJsonModule": true,
14
+ "declaration": true,
15
+ "declarationMap": true,
16
+ "sourceMap": true,
17
+ "noUnusedLocals": true,
18
+ "noUnusedParameters": true,
19
+ "noImplicitReturns": true,
20
+ "noFallthroughCasesInSwitch": true,
21
+ "types": ["node"]
22
+ },
23
+ "include": ["src/**/*"],
24
+ "exclude": ["node_modules", "dist"]
25
+ }
26
+