create-sprint 0.0.1 → 0.0.2

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 (3) hide show
  1. package/bin/cli.js +253 -0
  2. package/bin/cli.ts +103 -103
  3. package/package.json +8 -5
package/bin/cli.js ADDED
@@ -0,0 +1,253 @@
1
+ #!/usr/bin/env node
2
+ import { select, input } from "@inquirer/prompts";
3
+ import { mkdir, writeFile } from "fs/promises";
4
+ import { existsSync } from "fs";
5
+ import { join } from "path";
6
+ const args = process.argv.slice(2);
7
+ const initIndex = args.indexOf("init");
8
+ const isInitCommand = initIndex !== -1;
9
+ if (!isInitCommand) {
10
+ console.log("\nšŸš€ Sprint - Quickly API Framework\n");
11
+ console.log("Usage: sprint init [options]");
12
+ console.log("\nOptions:");
13
+ console.log(" --ts, --typescript Create TypeScript project");
14
+ console.log(" --js, --javascript Create JavaScript project");
15
+ console.log(" --name <name> Project name");
16
+ console.log(" --current Create in current directory");
17
+ console.log("\nExamples:");
18
+ console.log(" sprint init Interactive mode");
19
+ console.log(" sprint init --ts Create TypeScript project");
20
+ console.log(" sprint init --ts --name my-api");
21
+ console.log(" sprint init --js --current\n");
22
+ process.exit(0);
23
+ }
24
+ const hasTs = args.includes("--ts") || args.includes("--typescript");
25
+ const hasJs = args.includes("--js") || args.includes("--javascript");
26
+ const hasName = args.indexOf("--name");
27
+ const projectNameArg = hasName !== -1 ? args[hasName + 1] : null;
28
+ const useCurrentDirArg = args.includes("--current");
29
+ async function main() {
30
+ console.log("\nšŸš€ Welcome to Sprint - Quickly API Framework\n");
31
+ let projectName;
32
+ let language;
33
+ if (projectNameArg) {
34
+ projectName = projectNameArg;
35
+ }
36
+ else if (useCurrentDirArg) {
37
+ projectName = ".";
38
+ }
39
+ else {
40
+ projectName = await getProjectName();
41
+ }
42
+ if (hasTs) {
43
+ language = "typescript";
44
+ }
45
+ else if (hasJs) {
46
+ language = "javascript";
47
+ }
48
+ else {
49
+ language = await selectLanguage();
50
+ }
51
+ console.log(`\nāœ… Creating Sprint project: ${projectName === "." ? "current directory" : projectName} with ${language === "typescript" ? "TypeScript" : "JavaScript"}\n`);
52
+ await createProject(projectName, language);
53
+ console.log("\nāœ… Project created successfully!");
54
+ console.log("\nšŸ“¦ Next steps:");
55
+ const cdCmd = projectName === "." ? "" : `cd ${projectName} && `;
56
+ console.log(` ${cdCmd}npm install`);
57
+ console.log(` ${cdCmd}npm run dev`);
58
+ console.log("\n");
59
+ }
60
+ async function getProjectName() {
61
+ const useCurrentDir = await select({
62
+ message: "Where would you like to create your project?",
63
+ choices: [
64
+ {
65
+ name: "Current directory",
66
+ value: "current",
67
+ },
68
+ {
69
+ name: "New directory",
70
+ value: "new",
71
+ },
72
+ ],
73
+ });
74
+ if (useCurrentDir === "current") {
75
+ return ".";
76
+ }
77
+ const name = await input({
78
+ message: "Enter project name:",
79
+ validate: (value) => {
80
+ if (!value.trim())
81
+ return "Please enter a project name";
82
+ return true;
83
+ },
84
+ });
85
+ return name;
86
+ }
87
+ async function selectLanguage() {
88
+ const language = await select({
89
+ message: "Select your preferred language:",
90
+ choices: [
91
+ {
92
+ name: "TypeScript",
93
+ value: "typescript",
94
+ description: "Recommended - Type safety and better developer experience",
95
+ },
96
+ {
97
+ name: "JavaScript",
98
+ value: "javascript",
99
+ description: "Vanilla JavaScript for simpler projects",
100
+ },
101
+ ],
102
+ });
103
+ return language;
104
+ }
105
+ async function createProject(projectName, language) {
106
+ const isCurrentDir = projectName === ".";
107
+ const targetDir = isCurrentDir ? process.cwd() : join(process.cwd(), projectName);
108
+ if (!isCurrentDir && existsSync(targetDir)) {
109
+ console.error(`Error: Directory ${projectName} already exists`);
110
+ process.exit(1);
111
+ }
112
+ if (!isCurrentDir) {
113
+ await mkdir(targetDir, { recursive: true });
114
+ }
115
+ const pkgJson = language === "typescript"
116
+ ? getTypeScriptPackageJson(projectName)
117
+ : getJavaScriptPackageJson(projectName);
118
+ await writeFile(join(targetDir, "package.json"), JSON.stringify(pkgJson, null, 2));
119
+ if (language === "typescript") {
120
+ await writeFile(join(targetDir, "tsconfig.json"), getTsConfig());
121
+ }
122
+ const srcDir = join(targetDir, "src");
123
+ await mkdir(srcDir, { recursive: true });
124
+ await writeFile(join(srcDir, "index." + (language === "typescript" ? "ts" : "js")), getMainFile(language));
125
+ if (language === "typescript") {
126
+ await writeFile(join(srcDir, "app." + (language === "typescript" ? "ts" : "js")), getAppFile(language));
127
+ }
128
+ await writeFile(join(targetDir, ".env.example"), getEnvExample());
129
+ }
130
+ function getTypeScriptPackageJson(name) {
131
+ return {
132
+ name: name === "." ? "sprint-app" : name,
133
+ version: "0.0.1",
134
+ description: "Sprint API",
135
+ main: "dist/index.js",
136
+ scripts: {
137
+ build: "tsc",
138
+ start: "node dist/index.js",
139
+ dev: "tsx watch src/index.ts",
140
+ },
141
+ dependencies: {
142
+ "sprint-es": "^0.0.24",
143
+ dotenv: "^17.0.0",
144
+ },
145
+ devDependencies: {
146
+ "@types/node": "^22.0.0",
147
+ "tsx": "^4.19.0",
148
+ typescript: "^5.6.0",
149
+ },
150
+ };
151
+ }
152
+ function getJavaScriptPackageJson(name) {
153
+ return {
154
+ name: name === "." ? "sprint-app" : name,
155
+ version: "0.0.1",
156
+ description: "Sprint API",
157
+ main: "src/index.js",
158
+ type: "module",
159
+ scripts: {
160
+ start: "node src/index.js",
161
+ dev: "node --watch src/index.js",
162
+ },
163
+ dependencies: {
164
+ "sprint-es": "^0.0.24",
165
+ dotenv: "^17.0.0",
166
+ },
167
+ };
168
+ }
169
+ function getTsConfig() {
170
+ return JSON.stringify({
171
+ compilerOptions: {
172
+ target: "ES2020",
173
+ module: "ESNext",
174
+ moduleResolution: "bundler",
175
+ lib: ["ES2020"],
176
+ outDir: "./dist",
177
+ rootDir: "./src",
178
+ strict: true,
179
+ esModuleInterop: true,
180
+ skipLibCheck: true,
181
+ forceConsistentCasingInFileNames: true,
182
+ resolveJsonModule: true,
183
+ declaration: true,
184
+ declarationMap: true,
185
+ sourceMap: true,
186
+ },
187
+ include: ["src/**/*"],
188
+ exclude: ["node_modules", "dist"],
189
+ }, null, 2);
190
+ }
191
+ function getMainFile(language) {
192
+ if (language === "typescript") {
193
+ return `import Sprint from 'sprint-es';
194
+ import dotenv from 'dotenv';
195
+
196
+ dotenv.config();
197
+
198
+ const app = new Sprint({
199
+ port: process.env.PORT ? parseInt(process.env.PORT) : 3000,
200
+ favicon: process.env.FAVICON || undefined,
201
+ bodyParser: {
202
+ limit: '10mb'
203
+ }
204
+ });
205
+
206
+ app.get('/', (req, res) => {
207
+ res.send('Hello from Sprint!');
208
+ });
209
+
210
+ app.listen();
211
+ `;
212
+ }
213
+ return `import Sprint from 'sprint-es';
214
+ import dotenv from 'dotenv';
215
+
216
+ dotenv.config();
217
+
218
+ const app = new Sprint({
219
+ port: process.env.PORT ? parseInt(process.env.PORT) : 3000,
220
+ favicon: process.env.FAVICON || undefined,
221
+ bodyParser: {
222
+ limit: '10mb'
223
+ }
224
+ });
225
+
226
+ app.get('/', (req, res) => {
227
+ res.send('Hello from Sprint!');
228
+ });
229
+
230
+ app.listen();
231
+ `;
232
+ }
233
+ function getAppFile(language) {
234
+ if (language === "typescript") {
235
+ return `import type { SprintOptions } from 'sprint-es';
236
+
237
+ export const options: SprintOptions = {
238
+ port: 3000,
239
+ bodyParser: {
240
+ limit: '10mb'
241
+ }
242
+ };
243
+ `;
244
+ }
245
+ return "";
246
+ }
247
+ function getEnvExample() {
248
+ return `PORT=3000
249
+ FAVICON=./public/favicon.ico
250
+ NODE_ENV=development
251
+ `;
252
+ }
253
+ main().catch(console.error);
package/bin/cli.ts CHANGED
@@ -1,93 +1,93 @@
1
- #!/usr/bin/env node
2
-
3
- import { select, input } from '@inquirer/prompts';
4
- import { mkdir, writeFile } from 'fs/promises';
5
- import { existsSync } from 'fs';
6
- import { join } from 'path';
1
+ import { select, input } from "@inquirer/prompts";
2
+ import { mkdir, writeFile } from "fs/promises";
3
+ import { existsSync } from "fs";
4
+ import { join } from "path";
5
+ import { fileURLToPath } from "url";
6
+ import { dirname } from "path";
7
7
 
8
8
  const args = process.argv.slice(2);
9
- const initIndex = args.indexOf('init');
9
+ const initIndex = args.indexOf("init");
10
10
  const isInitCommand = initIndex !== -1;
11
11
 
12
12
  if (!isInitCommand) {
13
- console.log('\nšŸš€ Sprint - Quickly API Framework\n');
14
- console.log('Usage: sprint init [options]');
15
- console.log('\nOptions:');
16
- console.log(' --ts, --typescript Create TypeScript project');
17
- console.log(' --js, --javascript Create JavaScript project');
18
- console.log(' --name <name> Project name');
19
- console.log(' --current Create in current directory');
20
- console.log('\nExamples:');
21
- console.log(' sprint init Interactive mode');
22
- console.log(' sprint init --ts Create TypeScript project');
23
- console.log(' sprint init --ts --name my-api');
24
- console.log(' sprint init --js --current\n');
13
+ console.log("\nšŸš€ Sprint - Quickly API Framework\n");
14
+ console.log("Usage: sprint init [options]");
15
+ console.log("\nOptions:");
16
+ console.log(" --ts, --typescript Create TypeScript project");
17
+ console.log(" --js, --javascript Create JavaScript project");
18
+ console.log(" --name <name> Project name");
19
+ console.log(" --current Create in current directory");
20
+ console.log("\nExamples:");
21
+ console.log(" sprint init Interactive mode");
22
+ console.log(" sprint init --ts Create TypeScript project");
23
+ console.log(" sprint init --ts --name my-api");
24
+ console.log(" sprint init --js --current\n");
25
25
  process.exit(0);
26
26
  }
27
27
 
28
- const hasTs = args.includes('--ts') || args.includes('--typescript');
29
- const hasJs = args.includes('--js') || args.includes('--javascript');
30
- const hasName = args.indexOf('--name');
28
+ const hasTs = args.includes("--ts") || args.includes("--typescript");
29
+ const hasJs = args.includes("--js") || args.includes("--javascript");
30
+ const hasName = args.indexOf("--name");
31
31
  const projectNameArg = hasName !== -1 ? args[hasName + 1] : null;
32
- const useCurrentDirArg = args.includes('--current');
32
+ const useCurrentDirArg = args.includes("--current");
33
33
 
34
34
  async function main() {
35
- console.log('\nšŸš€ Welcome to Sprint - Quickly API Framework\n');
35
+ console.log("\nšŸš€ Welcome to Sprint - Quickly API Framework\n");
36
36
 
37
- let projectName: string;
38
- let language: 'typescript' | 'javascript';
37
+ let projectName;
38
+ let language;
39
39
 
40
40
  if (projectNameArg) {
41
41
  projectName = projectNameArg;
42
42
  } else if (useCurrentDirArg) {
43
- projectName = '.';
43
+ projectName = ".";
44
44
  } else {
45
45
  projectName = await getProjectName();
46
46
  }
47
47
 
48
48
  if (hasTs) {
49
- language = 'typescript';
49
+ language = "typescript";
50
50
  } else if (hasJs) {
51
- language = 'javascript';
51
+ language = "javascript";
52
52
  } else {
53
53
  language = await selectLanguage();
54
54
  }
55
55
 
56
- console.log(`\nāœ… Creating Sprint project: ${projectName === '.' ? 'current directory' : projectName} with ${language === 'typescript' ? 'TypeScript' : 'JavaScript'}\n`);
56
+ console.log(`\nāœ… Creating Sprint project: ${projectName === "." ? "current directory" : projectName} with ${language === "typescript" ? "TypeScript" : "JavaScript"}\n`);
57
57
 
58
58
  await createProject(projectName, language);
59
59
 
60
- console.log('\nāœ… Project created successfully!');
61
- console.log(`\nšŸ“¦ Next steps:`);
62
- console.log(` cd ${projectName === '.' ? '' : projectName}${projectName === '.' ? '' : ' '}(if created new directory)`);
63
- console.log(` npm install`);
64
- console.log(` npm run dev`);
65
- console.log('\n');
60
+ console.log("\nāœ… Project created successfully!");
61
+ console.log("\nšŸ“¦ Next steps:");
62
+ const cdCmd = projectName === "." ? "" : `cd ${projectName} && `;
63
+ console.log(` ${cdCmd}npm install`);
64
+ console.log(` ${cdCmd}npm run dev`);
65
+ console.log("\n");
66
66
  }
67
67
 
68
- async function getProjectName(): Promise<string> {
68
+ async function getProjectName() {
69
69
  const useCurrentDir = await select({
70
- message: 'Where would you like to create your project?',
70
+ message: "Where would you like to create your project?",
71
71
  choices: [
72
72
  {
73
- name: 'Current directory',
74
- value: 'current',
73
+ name: "Current directory",
74
+ value: "current",
75
75
  },
76
76
  {
77
- name: 'New directory',
78
- value: 'new',
77
+ name: "New directory",
78
+ value: "new",
79
79
  },
80
80
  ],
81
81
  });
82
82
 
83
- if (useCurrentDir === 'current') {
84
- return '.';
83
+ if (useCurrentDir === "current") {
84
+ return ".";
85
85
  }
86
86
 
87
87
  const name = await input({
88
- message: 'Enter project name:',
89
- validate: (value: string) => {
90
- if (!value.trim()) return 'Please enter a project name';
88
+ message: "Enter project name:",
89
+ validate: (value) => {
90
+ if (!value.trim()) return "Please enter a project name";
91
91
  return true;
92
92
  },
93
93
  });
@@ -95,19 +95,19 @@ async function getProjectName(): Promise<string> {
95
95
  return name;
96
96
  }
97
97
 
98
- async function selectLanguage(): Promise<'typescript' | 'javascript'> {
99
- const language: 'typescript' | 'javascript' = await select({
100
- message: 'Select your preferred language:',
98
+ async function selectLanguage() {
99
+ const language = await select({
100
+ message: "Select your preferred language:",
101
101
  choices: [
102
102
  {
103
- name: 'TypeScript',
104
- value: 'typescript',
105
- description: 'Recommended - Type safety and better developer experience',
103
+ name: "TypeScript",
104
+ value: "typescript",
105
+ description: "Recommended - Type safety and better developer experience",
106
106
  },
107
107
  {
108
- name: 'JavaScript',
109
- value: 'javascript',
110
- description: 'Vanilla JavaScript for simpler projects',
108
+ name: "JavaScript",
109
+ value: "javascript",
110
+ description: "Vanilla JavaScript for simpler projects",
111
111
  },
112
112
  ],
113
113
  });
@@ -115,8 +115,8 @@ async function selectLanguage(): Promise<'typescript' | 'javascript'> {
115
115
  return language;
116
116
  }
117
117
 
118
- async function createProject(projectName: string, language: 'typescript' | 'javascript') {
119
- const isCurrentDir = projectName === '.';
118
+ async function createProject(projectName, language) {
119
+ const isCurrentDir = projectName === ".";
120
120
  const targetDir = isCurrentDir ? process.cwd() : join(process.cwd(), projectName);
121
121
 
122
122
  if (!isCurrentDir && existsSync(targetDir)) {
@@ -128,65 +128,65 @@ async function createProject(projectName: string, language: 'typescript' | 'java
128
128
  await mkdir(targetDir, { recursive: true });
129
129
  }
130
130
 
131
- const pkgJson = language === 'typescript'
131
+ const pkgJson = language === "typescript"
132
132
  ? getTypeScriptPackageJson(projectName)
133
133
  : getJavaScriptPackageJson(projectName);
134
134
 
135
- await writeFile(join(targetDir, 'package.json'), JSON.stringify(pkgJson, null, 2));
135
+ await writeFile(join(targetDir, "package.json"), JSON.stringify(pkgJson, null, 2));
136
136
 
137
- if (language === 'typescript') {
138
- await writeFile(join(targetDir, 'tsconfig.json'), getTsConfig());
137
+ if (language === "typescript") {
138
+ await writeFile(join(targetDir, "tsconfig.json"), getTsConfig());
139
139
  }
140
140
 
141
- const srcDir = join(targetDir, 'src');
141
+ const srcDir = join(targetDir, "src");
142
142
  await mkdir(srcDir, { recursive: true });
143
143
 
144
- await writeFile(join(srcDir, 'index.' + (language === 'typescript' ? 'ts' : 'js')), getMainFile(language));
144
+ await writeFile(join(srcDir, "index." + (language === "typescript" ? "ts" : "js")), getMainFile(language));
145
145
 
146
- if (language === 'typescript') {
147
- await writeFile(join(srcDir, 'app.' + (language === 'typescript' ? 'ts' : 'js')), getAppFile(language));
146
+ if (language === "typescript") {
147
+ await writeFile(join(srcDir, "app." + (language === "typescript" ? "ts" : "js")), getAppFile(language));
148
148
  }
149
149
 
150
- await writeFile(join(targetDir, '.env.example'), getEnvExample());
150
+ await writeFile(join(targetDir, ".env.example"), getEnvExample());
151
151
  }
152
152
 
153
- function getTypeScriptPackageJson(name: string) {
153
+ function getTypeScriptPackageJson(name) {
154
154
  return {
155
- name: name === '.' ? 'sprint-app' : name,
156
- version: '0.0.1',
157
- description: 'Sprint API',
158
- main: 'dist/index.js',
155
+ name: name === "." ? "sprint-app" : name,
156
+ version: "0.0.1",
157
+ description: "Sprint API",
158
+ main: "dist/index.js",
159
159
  scripts: {
160
- build: 'tsc',
161
- start: 'node dist/index.js',
162
- dev: 'tsx watch src/index.ts',
160
+ build: "tsc",
161
+ start: "node dist/index.js",
162
+ dev: "tsx watch src/index.ts",
163
163
  },
164
164
  dependencies: {
165
- 'sprint-es': '^0.0.23',
166
- dotenv: '^17.0.0',
165
+ "sprint-es": "^0.0.24",
166
+ dotenv: "^17.0.0",
167
167
  },
168
168
  devDependencies: {
169
- '@types/node': '^22.0.0',
170
- 'tsx': '^4.19.0',
171
- typescript: '^5.6.0',
169
+ "@types/node": "^22.0.0",
170
+ "tsx": "^4.19.0",
171
+ typescript: "^5.6.0",
172
172
  },
173
173
  };
174
174
  }
175
175
 
176
- function getJavaScriptPackageJson(name: string) {
176
+ function getJavaScriptPackageJson(name) {
177
177
  return {
178
- name: name === '.' ? 'sprint-app' : name,
179
- version: '0.0.1',
180
- description: 'Sprint API',
181
- main: 'src/index.js',
182
- type: 'module',
178
+ name: name === "." ? "sprint-app" : name,
179
+ version: "0.0.1",
180
+ description: "Sprint API",
181
+ main: "src/index.js",
182
+ type: "module",
183
183
  scripts: {
184
- start: 'node src/index.js',
185
- dev: 'node --watch src/index.js',
184
+ start: "node src/index.js",
185
+ dev: "node --watch src/index.js",
186
186
  },
187
187
  dependencies: {
188
- 'sprint-es': '^0.0.23',
189
- dotenv: '^17.0.0',
188
+ "sprint-es": "^0.0.24",
189
+ dotenv: "^17.0.0",
190
190
  },
191
191
  };
192
192
  }
@@ -194,12 +194,12 @@ function getJavaScriptPackageJson(name: string) {
194
194
  function getTsConfig() {
195
195
  return JSON.stringify({
196
196
  compilerOptions: {
197
- target: 'ES2020',
198
- module: 'ESNext',
199
- moduleResolution: 'bundler',
200
- lib: ['ES2020'],
201
- outDir: './dist',
202
- rootDir: './src',
197
+ target: "ES2020",
198
+ module: "ESNext",
199
+ moduleResolution: "bundler",
200
+ lib: ["ES2020"],
201
+ outDir: "./dist",
202
+ rootDir: "./src",
203
203
  strict: true,
204
204
  esModuleInterop: true,
205
205
  skipLibCheck: true,
@@ -209,13 +209,13 @@ function getTsConfig() {
209
209
  declarationMap: true,
210
210
  sourceMap: true,
211
211
  },
212
- include: ['src/**/*'],
213
- exclude: ['node_modules', 'dist'],
212
+ include: ["src/**/*"],
213
+ exclude: ["node_modules", "dist"],
214
214
  }, null, 2);
215
215
  }
216
216
 
217
- function getMainFile(language: 'typescript' | 'javascript') {
218
- if (language === 'typescript') {
217
+ function getMainFile(language) {
218
+ if (language === "typescript") {
219
219
  return `import Sprint from 'sprint-es';
220
220
  import dotenv from 'dotenv';
221
221
 
@@ -257,8 +257,8 @@ app.listen();
257
257
  `;
258
258
  }
259
259
 
260
- function getAppFile(language: 'typescript' | 'javascript') {
261
- if (language === 'typescript') {
260
+ function getAppFile(language) {
261
+ if (language === "typescript") {
262
262
  return `import type { SprintOptions } from 'sprint-es';
263
263
 
264
264
  export const options: SprintOptions = {
@@ -269,7 +269,7 @@ export const options: SprintOptions = {
269
269
  };
270
270
  `;
271
271
  }
272
- return '';
272
+ return "";
273
273
  }
274
274
 
275
275
  function getEnvExample() {
package/package.json CHANGED
@@ -1,17 +1,19 @@
1
1
  {
2
2
  "name": "create-sprint",
3
- "version": "0.0.1",
3
+ "version": "0.0.2",
4
4
  "description": "Create a new Sprint API project",
5
5
  "type": "module",
6
6
  "bin": {
7
- "create-sprint": "tsx bin/cli.ts",
8
- "sprint": "tsx bin/cli.ts"
7
+ "create-sprint": "./bin/cli.js",
8
+ "sprint": "./bin/cli.js"
9
9
  },
10
10
  "files": [
11
11
  "bin/**/*"
12
12
  ],
13
13
  "scripts": {
14
- "start": "tsx bin/cli.ts"
14
+ "build": "tsc && node -e \"const fs=require('fs');const p='bin/cli.js';const c=fs.readFileSync(p,'utf8');fs.writeFileSync(p,'#!/usr/bin/env node\\n'+c)\"",
15
+ "prepublishOnly": "npm run build",
16
+ "start": "node bin/cli.js"
15
17
  },
16
18
  "keywords": [
17
19
  "sprint",
@@ -26,7 +28,8 @@
26
28
  "@inquirer/prompts": "^7.10.1"
27
29
  },
28
30
  "devDependencies": {
29
- "tsx": "^4.19.0"
31
+ "tsx": "^4.19.0",
32
+ "typescript": "^5.9.3"
30
33
  },
31
34
  "engines": {
32
35
  "node": ">=18.0.0"