create-time2ship 1.0.0 โ†’ 1.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.
@@ -0,0 +1,10 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "Skill(systematic-debugging)",
5
+ "Skill(systematic-debugging:*)",
6
+ "Bash(npm link)",
7
+ "Bash(node:*)"
8
+ ]
9
+ }
10
+ }
package/README.md CHANGED
@@ -1,90 +1,38 @@
1
1
  # create-time2ship
2
2
 
3
- Create a new Time2Ship full-stack application in seconds.
4
-
5
- ## Quick Start
3
+ Create a new Time2Ship full-stack app in seconds.
6
4
 
7
5
  ```bash
8
6
  npx create-time2ship my-app
7
+ cd my-app
8
+ docker-compose up
9
9
  ```
10
10
 
11
- ## Usage
11
+ ## What's Included
12
12
 
13
- ### With npx (recommended)
13
+ - **Next.js 16** + React 19
14
+ - **Express API** + TypeScript
15
+ - **PostgreSQL** + Drizzle ORM
16
+ - **Docker** ready
17
+ - **JWT auth** built-in
18
+ - **Tailwind CSS 4**
19
+
20
+ ## Usage
14
21
 
15
22
  ```bash
23
+ # With npx
16
24
  npx create-time2ship my-app
17
- ```
18
25
 
19
- ### With npm
20
-
21
- ```bash
26
+ # With npm/yarn/pnpm
22
27
  npm create time2ship my-app
23
- ```
24
-
25
- ### With yarn
26
-
27
- ```bash
28
28
  yarn create time2ship my-app
29
- ```
30
-
31
- ### With pnpm
32
-
33
- ```bash
34
29
  pnpm create time2ship my-app
35
30
  ```
36
31
 
37
- ## What You Get
38
-
39
- Time2Ship is a production-ready full-stack monorepo featuring:
40
-
41
- - โšก **Next.js 16** with React 19
42
- - ๐Ÿ›ก๏ธ **Express API** with TypeScript
43
- - ๐Ÿ—„๏ธ **PostgreSQL** with Drizzle ORM
44
- - ๐Ÿณ **Docker** ready
45
- - ๐Ÿ” **JWT Authentication** out of the box
46
- - ๐Ÿงช **Comprehensive testing** setup
47
- - ๐Ÿ“ง **Email service** with templates
48
- - ๐ŸŽจ **Tailwind CSS 4**
49
-
50
- ## Interactive Setup
51
-
52
- The CLI will guide you through:
53
-
54
- 1. **Project Name** - Choose your project name
55
- 2. **Description** - Optional project description
56
- 3. **Package Manager** - npm, yarn, or pnpm
57
- 4. **Dependencies** - Install now or later
58
- 5. **Git** - Initialize git repository
59
- 6. **Environment** - Auto-generate .env files
60
-
61
- ## After Creation
62
-
63
- ```bash
64
- cd my-app
65
-
66
- # Start with Docker (recommended)
67
- docker-compose up
68
-
69
- # Or run individually
70
- docker-compose up db # Database
71
- cd apps/api && npm run dev # API
72
- cd apps/client && npm run dev # Client
73
- ```
74
-
75
- Your app will be available at:
76
- - Frontend: http://localhost:3000
77
- - API: http://localhost:3001
78
-
79
- ## Documentation
80
-
81
- Full documentation available in your project's README.md
82
-
83
- ## Support
32
+ ## Links
84
33
 
85
- - ๐Ÿ“– [Documentation](https://github.com/time2build-ai/time2ship)
86
- - ๐Ÿ› [Report Issues](https://github.com/time2build-ai/time2ship/issues)
87
- - ๐Ÿ’ฌ [Discussions](https://github.com/time2build-ai/time2ship/discussions)
34
+ - [Time2Ship Repo](https://github.com/time2build-ai/time2ship)
35
+ - [Report Issues](https://github.com/time2build-ai/time2ship/issues)
88
36
 
89
37
  ## License
90
38
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-time2ship",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "Create a new Time2Ship full-stack application in seconds",
5
5
  "main": "src/index.js",
6
6
  "bin": {
package/src/index.js CHANGED
@@ -9,8 +9,12 @@ async function run() {
9
9
  // Print welcome message
10
10
  printWelcome();
11
11
 
12
+ // Get project name from CLI argument if provided
13
+ const args = process.argv.slice(2);
14
+ const projectNameArg = args[0];
15
+
12
16
  // Get user input
13
- const config = await runPrompts();
17
+ const config = await runPrompts(projectNameArg);
14
18
 
15
19
  if (!config) {
16
20
  console.log(chalk.yellow('\nSetup cancelled.'));
package/src/prompts.js CHANGED
@@ -30,60 +30,98 @@ function validateProjectName(name) {
30
30
  /**
31
31
  * Run interactive prompts
32
32
  */
33
- async function runPrompts() {
33
+ async function runPrompts(projectNameArg) {
34
+ const chalk = require('chalk');
35
+
36
+ console.log(chalk.cyan('Step 1/5: Project Setup'));
34
37
  const questions = [
35
38
  {
36
39
  type: 'text',
37
40
  name: 'projectName',
38
- message: 'What is your project name?',
39
- initial: 'my-time2ship-app',
41
+ message: 'โ†’ Project name:',
42
+ initial: projectNameArg || 'my-time2ship-app',
40
43
  validate: validateProjectName
41
44
  },
42
45
  {
43
46
  type: 'text',
44
47
  name: 'description',
45
- message: 'Project description (optional):',
48
+ message: 'โ†’ Description (optional):',
46
49
  initial: 'A Time2Ship application'
47
- },
48
- {
49
- type: 'select',
50
- name: 'packageManager',
51
- message: 'Which package manager do you want to use?',
52
- choices: [
53
- { title: 'npm', value: 'npm' },
54
- { title: 'yarn', value: 'yarn' },
55
- { title: 'pnpm', value: 'pnpm' }
56
- ],
57
- initial: 0
58
- },
59
- {
60
- type: 'confirm',
61
- name: 'installDeps',
62
- message: 'Install dependencies now?',
63
- initial: true
64
- },
50
+ }
51
+ ];
52
+
53
+ const response = await prompts(questions, {
54
+ onCancel: () => {
55
+ console.log(chalk.red('\nโœ— Setup cancelled'));
56
+ process.exit(0);
57
+ }
58
+ });
59
+
60
+ console.log();
61
+ console.log(chalk.cyan('Step 2/5: Package Manager'));
62
+ const pmQuestion = await prompts({
63
+ type: 'select',
64
+ name: 'packageManager',
65
+ message: 'โ†’ Choose package manager:',
66
+ choices: [
67
+ { title: 'npm', value: 'npm' },
68
+ { title: 'yarn', value: 'yarn' },
69
+ { title: 'pnpm', value: 'pnpm' }
70
+ ],
71
+ initial: 0
72
+ }, {
73
+ onCancel: () => {
74
+ console.log(chalk.red('\nโœ— Setup cancelled'));
75
+ process.exit(0);
76
+ }
77
+ });
78
+
79
+ console.log();
80
+ console.log(chalk.cyan('Step 3/5: Clone & Setup'));
81
+ console.log(chalk.gray(' (This will clone the time2ship boilerplate)'));
82
+
83
+ console.log();
84
+ console.log(chalk.cyan('Step 4/5: Dependencies'));
85
+ const depsQuestion = await prompts({
86
+ type: 'confirm',
87
+ name: 'installDeps',
88
+ message: 'โ†’ Install dependencies now?',
89
+ initial: true
90
+ }, {
91
+ onCancel: () => {
92
+ console.log(chalk.red('\nโœ— Setup cancelled'));
93
+ process.exit(0);
94
+ }
95
+ });
96
+
97
+ console.log();
98
+ console.log(chalk.cyan('Step 5/5: Finalize'));
99
+ const finalQuestions = await prompts([
65
100
  {
66
101
  type: 'confirm',
67
102
  name: 'initGit',
68
- message: 'Initialize a git repository?',
103
+ message: 'โ†’ Initialize git repository?',
69
104
  initial: true
70
105
  },
71
106
  {
72
107
  type: 'confirm',
73
108
  name: 'setupEnv',
74
- message: 'Create environment files (.env)?',
109
+ message: 'โ†’ Create .env files?',
75
110
  initial: true
76
111
  }
77
- ];
78
-
79
- const response = await prompts(questions, {
112
+ ], {
80
113
  onCancel: () => {
81
114
  console.log(chalk.red('\nโœ— Setup cancelled'));
82
115
  process.exit(0);
83
116
  }
84
117
  });
85
118
 
86
- return response;
119
+ return {
120
+ ...response,
121
+ ...pmQuestion,
122
+ ...depsQuestion,
123
+ ...finalQuestions
124
+ };
87
125
  }
88
126
 
89
127
  module.exports = {
package/src/setup.js CHANGED
@@ -10,7 +10,7 @@ const { generateEnvFiles } = require('./templates');
10
10
  * Clone the Time2Ship repository
11
11
  */
12
12
  async function cloneRepository(targetDir) {
13
- const spinner = ora('Cloning Time2Ship boilerplate...').start();
13
+ const spinner = ora('Cloning time2ship boilerplate...').start();
14
14
 
15
15
  try {
16
16
  // Clone from GitHub
@@ -22,9 +22,9 @@ async function cloneRepository(targetDir) {
22
22
  // Remove .git directory
23
23
  await fs.remove(path.join(targetDir, '.git'));
24
24
 
25
- spinner.succeed('Boilerplate cloned successfully');
25
+ spinner.succeed(chalk.green('โœ“ Cloned boilerplate'));
26
26
  } catch (error) {
27
- spinner.fail('Failed to clone repository');
27
+ spinner.fail(chalk.red('โœ— Failed to clone repository'));
28
28
  throw new Error(`Git clone failed: ${error.message}`);
29
29
  }
30
30
  }
@@ -41,12 +41,11 @@ async function installDependencies(projectPath, packageManager) {
41
41
  stdio: 'pipe'
42
42
  });
43
43
 
44
- spinner.succeed('Dependencies installed');
44
+ spinner.succeed(chalk.green('โœ“ Dependencies installed'));
45
45
  } catch (error) {
46
- spinner.fail('Failed to install dependencies');
47
- console.log(chalk.yellow('\nYou can install dependencies manually later by running:'));
48
- console.log(chalk.cyan(` cd ${path.basename(projectPath)}`));
49
- console.log(chalk.cyan(` ${packageManager} install\n`));
46
+ spinner.fail(chalk.red('โœ— Failed to install dependencies'));
47
+ console.log(chalk.yellow(' You can install manually later:'));
48
+ console.log(chalk.gray(` cd ${path.basename(projectPath)} && ${packageManager} install`));
50
49
  }
51
50
  }
52
51
 
@@ -64,10 +63,10 @@ async function initializeGit(projectPath) {
64
63
  stdio: 'pipe'
65
64
  });
66
65
 
67
- spinner.succeed('Git repository initialized');
66
+ spinner.succeed(chalk.green('โœ“ Git initialized'));
68
67
  } catch (error) {
69
- spinner.fail('Failed to initialize git');
70
- console.log(chalk.yellow('You can initialize git manually later.'));
68
+ spinner.fail(chalk.red('โœ— Failed to initialize git'));
69
+ console.log(chalk.gray(' You can initialize git manually later'));
71
70
  }
72
71
  }
73
72
 
@@ -88,12 +87,10 @@ async function setupEnvironmentFiles(projectPath, config) {
88
87
  const clientEnvPath = path.join(projectPath, 'apps', 'client', '.env.local');
89
88
  await fs.writeFile(clientEnvPath, clientEnv);
90
89
 
91
- spinner.succeed('Environment files created');
90
+ spinner.succeed(chalk.green('โœ“ Environment files created'));
92
91
  } catch (error) {
93
- spinner.fail('Failed to create environment files');
94
- console.log(chalk.yellow('\nYou can create environment files manually:'));
95
- console.log(chalk.cyan(' cp apps/api/.env.example apps/api/.env'));
96
- console.log(chalk.cyan(' cp apps/client/.env.example apps/client/.env.local\n'));
92
+ spinner.fail(chalk.red('โœ— Failed to create environment files'));
93
+ console.log(chalk.gray(' You can create .env files manually later'));
97
94
  }
98
95
  }
99
96
 
@@ -101,7 +98,7 @@ async function setupEnvironmentFiles(projectPath, config) {
101
98
  * Update package.json with project details
102
99
  */
103
100
  async function updateProjectPackageJson(projectPath, config) {
104
- const spinner = ora('Updating package.json...').start();
101
+ const spinner = ora('Updating package.json files...').start();
105
102
 
106
103
  try {
107
104
  // Update root package.json
@@ -132,9 +129,9 @@ async function updateProjectPackageJson(projectPath, config) {
132
129
 
133
130
  await fs.writeJson(apiPkgPath, apiPkg, { spaces: 2 });
134
131
 
135
- spinner.succeed('package.json files updated');
132
+ spinner.succeed(chalk.green('โœ“ Updated package.json files'));
136
133
  } catch (error) {
137
- spinner.warn('Could not update package.json files');
134
+ spinner.warn(chalk.yellow('โš  Could not update package.json files'));
138
135
  }
139
136
  }
140
137
 
package/src/utils.js CHANGED
@@ -5,13 +5,7 @@ const chalk = require('chalk');
5
5
  */
6
6
  function printWelcome() {
7
7
  console.log();
8
- console.log(chalk.blue.bold(' โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•—'));
9
- console.log(chalk.blue.bold(' โ•‘ โ•‘'));
10
- console.log(chalk.blue.bold(' โ•‘ ๐Ÿš€ Welcome to Time2Ship ๐Ÿš€ โ•‘'));
11
- console.log(chalk.blue.bold(' โ•‘ โ•‘'));
12
- console.log(chalk.blue.bold(' โ•‘ Ship your ideas faster! โ•‘'));
13
- console.log(chalk.blue.bold(' โ•‘ โ•‘'));
14
- console.log(chalk.blue.bold(' โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•'));
8
+ console.log(chalk.cyan.bold('๐Ÿš€ create-time2ship'));
15
9
  console.log();
16
10
  }
17
11
 
@@ -20,7 +14,7 @@ function printWelcome() {
20
14
  */
21
15
  function printSuccess(projectName) {
22
16
  console.log();
23
- console.log(chalk.green.bold(' โœ“ Success!'), `Your project "${projectName}" is ready!`);
17
+ console.log(chalk.green.bold('โœ“ Success!'), chalk.white(`Your project "${projectName}" is ready!`));
24
18
  console.log();
25
19
  }
26
20
 
@@ -30,59 +24,33 @@ function printSuccess(projectName) {
30
24
  function printNextSteps(config) {
31
25
  const { projectName, installDeps, setupEnv, packageManager } = config;
32
26
 
33
- console.log(chalk.cyan.bold('๐Ÿ“‹ Next Steps:\n'));
27
+ console.log(chalk.cyan.bold('Next steps:'));
34
28
 
35
- // Step 1: Navigate to directory
36
- console.log(chalk.white(' 1. Navigate to your project:'));
37
- console.log(chalk.gray(` cd ${projectName}\n`));
29
+ // Navigate to directory
30
+ console.log(chalk.gray(' cd ' + projectName));
38
31
 
39
- // Step 2: Install dependencies (if not done)
32
+ // Install dependencies (if not done)
40
33
  if (!installDeps) {
41
- console.log(chalk.white(' 2. Install dependencies:'));
42
- console.log(chalk.gray(` ${packageManager} install\n`));
34
+ console.log(chalk.gray(` ${packageManager} install`));
43
35
  }
44
36
 
45
- // Step 3: Configure environment (if not done)
37
+ // Configure environment (if not done)
46
38
  if (!setupEnv) {
47
- console.log(chalk.white(` ${installDeps ? '2' : '3'}. Set up environment variables:`));
48
- console.log(chalk.gray(' cp apps/api/.env.example apps/api/.env'));
49
- console.log(chalk.gray(' cp apps/client/.env.example apps/client/.env.local'));
50
- console.log(chalk.yellow(' โš ๏ธ Update the .env files with your configuration\n'));
51
- } else {
52
- console.log(chalk.white(` ${installDeps ? '2' : '3'}. Review and update environment variables:`));
53
- console.log(chalk.gray(' apps/api/.env'));
54
- console.log(chalk.gray(' apps/client/.env.local'));
55
- console.log(chalk.yellow(' โš ๏ธ JWT secrets have been auto-generated\n'));
39
+ console.log(chalk.gray(' # Copy and configure .env files'));
56
40
  }
57
41
 
58
- // Step 4: Start development
59
- const stepNum = installDeps && setupEnv ? '3' : installDeps || setupEnv ? '4' : '5';
60
- console.log(chalk.white(` ${stepNum}. Start development with Docker:`));
61
- console.log(chalk.gray(' docker-compose up\n'));
62
-
63
- console.log(chalk.white(' Or run services individually:'));
64
- console.log(chalk.gray(' # Terminal 1 - Database'));
65
- console.log(chalk.gray(' docker-compose up db\n'));
66
- console.log(chalk.gray(' # Terminal 2 - API'));
67
- console.log(chalk.gray(' cd apps/api && npm run dev\n'));
68
- console.log(chalk.gray(' # Terminal 3 - Client'));
69
- console.log(chalk.gray(' cd apps/client && npm run dev\n'));
42
+ // Start development
43
+ console.log(chalk.gray(' docker-compose up'));
44
+ console.log();
70
45
 
71
46
  // URLs
72
- console.log(chalk.cyan.bold('๐ŸŒ Your app will be available at:\n'));
73
- console.log(chalk.white(' Frontend:'), chalk.blue.underline('http://localhost:3000'));
74
- console.log(chalk.white(' API: '), chalk.blue.underline('http://localhost:3001'));
75
- console.log(chalk.white(' Database:'), chalk.gray('localhost:5432\n'));
76
-
77
- // Documentation
78
- console.log(chalk.cyan.bold('๐Ÿ“š Documentation:\n'));
79
- console.log(chalk.gray(` Check out the README.md in your project for detailed docs\n`));
80
-
81
- // Happy coding
82
- console.log(chalk.green.bold(' Happy shipping! ๐Ÿš€\n'));
47
+ console.log(chalk.cyan('Your app:'));
48
+ console.log(chalk.white(' Frontend โ†’'), chalk.blue('http://localhost:3000'));
49
+ console.log(chalk.white(' API โ†’'), chalk.blue('http://localhost:3001'));
50
+ console.log();
83
51
 
84
- // Support
85
- console.log(chalk.gray(' Need help? Visit: ') + chalk.blue.underline('https://github.com/time2build-ai/time2ship'));
52
+ // Happy shipping
53
+ console.log(chalk.green('Happy shipping! ๐Ÿš€'));
86
54
  console.log();
87
55
  }
88
56