create-laju-app 1.0.14 → 1.0.15

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/README.md +309 -309
  2. package/bin/cli.js +120 -120
  3. package/package.json +28 -28
package/README.md CHANGED
@@ -1,309 +1,309 @@
1
- # Laju
2
-
3
- A high-performance TypeScript web framework combining HyperExpress, Svelte 5, and Inertia.js for building modern full-stack applications. Features server-side rendering, real-time capabilities, and seamless client-server state management.
4
-
5
- Visit [laju.dev](https://laju.dev)
6
-
7
- ## Features
8
-
9
- - Fast server-side rendering with HyperExpress
10
- - Modern frontend with Svelte 5
11
- - TypeScript support for better type safety
12
- - Inertia.js integration for seamless client-server communication
13
- - Built-in authentication system
14
- - SQLite database with Knex query builder
15
- - Email support with Nodemailer
16
- - Google APIs integration
17
- - Redis caching support
18
- - Asset bundling with Vite
19
- - TailwindCSS for styling
20
-
21
- ## Prerequisites
22
-
23
- - Node.js (Latest LTS version recommended)
24
- - npm or yarn
25
- - Redis server (optional, for caching)
26
-
27
- ## Installation
28
-
29
- Run the following command
30
- ```bash
31
- npx create-laju-app project-name
32
- ```
33
- ## Development
34
-
35
- To start the development server:
36
-
37
- ```bash
38
- npm run dev
39
- ```
40
-
41
- This will:
42
- - Start the Vite development server for frontend assets
43
- - Run the backend server with nodemon for auto-reloading
44
-
45
- ## Building for Production
46
-
47
- To build the application for production:
48
-
49
- ```bash
50
- npm run build
51
- ```
52
-
53
- This command will:
54
- - Clean the build directory
55
- - Build frontend assets with Vite
56
- - Compile TypeScript files
57
- - Copy necessary files to the build directory
58
-
59
- ## Project Structure
60
-
61
- - `/app` - Core application files
62
- - `/middlewares` - Custom middleware functions
63
- - `/services` - Service layer implementations
64
- - `/controllers` - Application controllers
65
- - `/resources` - Frontend resources
66
- - `/views` - Svelte components and views
67
- - `/js` - JavaScript assets and modules
68
- - `/routes` - Route definitions
69
- - `/migrations` - Database migrations
70
- - `/public` - Static files
71
- - `/dist` - Compiled assets (generated)
72
- - `/build` - Production build output
73
-
74
- ## Key Dependencies
75
-
76
- ### Backend
77
- - HyperExpress - High-performance web server
78
- - Knex - SQL query builder
79
- - SQLite3 - Database
80
- - Nodemailer - Email sending
81
- - Redis - Caching (optional)
82
-
83
- ### Frontend
84
- - Svelte 5 - UI framework
85
- - Inertia.js - Client-server communication
86
- - TailwindCSS - Utility-first CSS framework
87
- - Vite - Build tool and dev server
88
-
89
- ## Scripts
90
-
91
- - `npm run dev` - Start development server
92
- - `npm run build` - Build for production
93
-
94
- ## Contributing
95
-
96
- 1. Fork the repository
97
- 2. Create your feature branch
98
- 3. Commit your changes
99
- 4. Push to the branch
100
- 5. Create a new Pull Request
101
-
102
- ## License
103
-
104
- ISC License
105
-
106
- ## Tutorial: Building Your First App
107
-
108
- This tutorial will guide you through building a simple application using this framework.
109
-
110
- ### 1. Setting Up a New Route and Controller
111
-
112
- First, let's create a new route and controller for a blog post feature.
113
-
114
- 1. Create a new controller file `app/controllers/PostController.ts`:
115
-
116
- ```typescript
117
- import { Request, Response } from "../../type";
118
- import DB from "../services/DB";
119
-
120
- class Controller {
121
- public async index(request: Request, response: Response) {
122
- const posts = await DB.from("posts");
123
- return response.inertia("posts/index", { posts });
124
- }
125
-
126
- public async create(request: Request, response: Response) {
127
- return response.inertia("posts/create");
128
- }
129
-
130
- public async store(request: Request, response: Response) {
131
- const { title, content } = request.body;
132
-
133
- await DB.table("posts").insert({
134
- title,
135
- content,
136
- created_at: Date.now(),
137
- updated_at: Date.now()
138
- });
139
-
140
- return response.redirect("/posts");
141
- }
142
- }
143
-
144
- export default new Controller();
145
- ```
146
-
147
- 2. Add routes in `routes/web.ts`:
148
-
149
- ```typescript
150
- import PostController from "../app/controllers/PostController";
151
-
152
- // Add these routes with your existing routes
153
- Route.get("/posts", PostController.index);
154
- Route.get("/posts/create", PostController.create);
155
- Route.post("/posts", PostController.store);
156
- ```
157
-
158
- ### 2. Creating the Database Migration
159
-
160
- Create a migration for the posts table:
161
-
162
- ```bash
163
- npx knex migrate:make create_posts_table
164
- ```
165
-
166
- In the generated migration file:
167
-
168
- ```typescript
169
- import { Knex } from "knex";
170
-
171
- export async function up(knex: Knex): Promise<void> {
172
- await knex.schema.createTable('posts', function (table) {
173
- table.increments('id').primary();
174
- table.string('title').notNullable();
175
- table.text('content').notNullable();
176
- table.bigInteger('created_at');
177
- table.bigInteger('updated_at');
178
- });
179
- }
180
-
181
- export async function down(knex: Knex): Promise<void> {
182
- await knex.schema.dropTable('posts');
183
- }
184
- ```
185
-
186
- Run the migration:
187
-
188
- ```bash
189
- npx knex migrate:latest
190
- ```
191
-
192
- ### 3. Creating Svelte Components
193
-
194
- 1. Create `resources/views/posts/index.svelte`:
195
-
196
- ```svelte
197
- <script>
198
- export let posts = [];
199
- </script>
200
-
201
- <div class="max-w-4xl mx-auto p-4">
202
- <div class="flex justify-between items-center mb-6">
203
- <h1 class="text-2xl font-bold">Blog Posts</h1>
204
- <a
205
- href="/posts/create"
206
- class="bg-blue-500 text-white px-4 py-2 rounded hover:bg-blue-600"
207
- >
208
- Create Post
209
- </a>
210
- </div>
211
-
212
- <div class="space-y-4">
213
- {#each posts as post}
214
- <div class="border p-4 rounded">
215
- <h2 class="text-xl font-semibold">{post.title}</h2>
216
- <p class="mt-2 text-gray-600">{post.content}</p>
217
- </div>
218
- {/each}
219
- </div>
220
- </div>
221
- ```
222
-
223
- 2. Create `resources/views/posts/create.svelte`:
224
-
225
- ```svelte
226
- <script>
227
- import { router } from '@inertiajs/svelte';
228
-
229
- let form = {
230
- title: '',
231
- content: ''
232
- };
233
-
234
- function handleSubmit() {
235
- router.post('/posts', form);
236
- }
237
- </script>
238
-
239
- <div class="max-w-4xl mx-auto p-4">
240
- <h1 class="text-2xl font-bold mb-6">Create New Post</h1>
241
-
242
- <form on:submit|preventDefault={handleSubmit} class="space-y-4">
243
- <div>
244
- <label class="block text-sm font-medium mb-1">Title</label>
245
- <input
246
- type="text"
247
- bind:value={form.title}
248
- class="w-full px-3 py-2 border rounded"
249
- />
250
- </div>
251
-
252
- <div>
253
- <label class="block text-sm font-medium mb-1">Content</label>
254
- <textarea
255
- bind:value={form.content}
256
- class="w-full px-3 py-2 border rounded h-32"
257
- ></textarea>
258
- </div>
259
-
260
- <div>
261
- <button
262
- type="submit"
263
- class="bg-blue-500 text-white px-4 py-2 rounded hover:bg-blue-600"
264
- >
265
- Create Post
266
- </button>
267
- </div>
268
- </form>
269
- </div>
270
- ```
271
-
272
- ### 4. Testing Your Application
273
-
274
- 1. Start the development server:
275
- ```bash
276
- npm run dev
277
- ```
278
-
279
- 2. Visit `http://localhost:5555/posts` in your browser
280
- 3. Try creating a new post using the form
281
- 4. View the list of posts on the index page
282
-
283
- ### Key Concepts
284
-
285
- 1. **Routing**: Routes are defined in `routes/web.ts` using the HyperExpress router
286
- 2. **Controllers**: Handle business logic and return Inertia responses
287
- 3. **Database**: Use Knex.js for database operations and migrations
288
- 4. **Frontend**: Svelte components with Inertia.js for seamless page transitions
289
- 5. **Styling**: TailwindCSS for utility-first styling
290
-
291
- ### Best Practices
292
-
293
- 1. **File Organization**
294
- - Keep controllers in `app/controllers`
295
- - Place Svelte components in `resources/views`
296
- - Database migrations in `migrations`
297
-
298
- 2. **Code Structure**
299
- - Use TypeScript types for better type safety
300
- - Keep controllers focused on single responsibilities
301
- - Use Inertia.js for state management between server and client
302
-
303
- 3. **Database**
304
- - Always use migrations for database changes
305
- - Use the Query Builder for complex queries
306
- - Include timestamps for tracking record changes
307
-
308
- Need help with anything specific? Feel free to ask!
309
-
1
+ # Laju
2
+
3
+ A high-performance TypeScript web framework combining HyperExpress, Svelte 5, and Inertia.js for building modern full-stack applications. Features server-side rendering, real-time capabilities, and seamless client-server state management.
4
+
5
+ Visit [laju.dev](https://laju.dev)
6
+
7
+ ## Features
8
+
9
+ - Fast server-side rendering with HyperExpress
10
+ - Modern frontend with Svelte 5
11
+ - TypeScript support for better type safety
12
+ - Inertia.js integration for seamless client-server communication
13
+ - Built-in authentication system
14
+ - SQLite database with Knex query builder
15
+ - Email support with Nodemailer
16
+ - Google APIs integration
17
+ - Redis caching support
18
+ - Asset bundling with Vite
19
+ - TailwindCSS for styling
20
+
21
+ ## Prerequisites
22
+
23
+ - Node.js (Latest LTS version recommended)
24
+ - npm or yarn
25
+ - Redis server (optional, for caching)
26
+
27
+ ## Installation
28
+
29
+ Run the following command
30
+ ```bash
31
+ npx create-laju-app project-name
32
+ ```
33
+ ## Development
34
+
35
+ To start the development server:
36
+
37
+ ```bash
38
+ npm run dev
39
+ ```
40
+
41
+ This will:
42
+ - Start the Vite development server for frontend assets
43
+ - Run the backend server with nodemon for auto-reloading
44
+
45
+ ## Building for Production
46
+
47
+ To build the application for production:
48
+
49
+ ```bash
50
+ npm run build
51
+ ```
52
+
53
+ This command will:
54
+ - Clean the build directory
55
+ - Build frontend assets with Vite
56
+ - Compile TypeScript files
57
+ - Copy necessary files to the build directory
58
+
59
+ ## Project Structure
60
+
61
+ - `/app` - Core application files
62
+ - `/middlewares` - Custom middleware functions
63
+ - `/services` - Service layer implementations
64
+ - `/controllers` - Application controllers
65
+ - `/resources` - Frontend resources
66
+ - `/views` - Svelte components and views
67
+ - `/js` - JavaScript assets and modules
68
+ - `/routes` - Route definitions
69
+ - `/migrations` - Database migrations
70
+ - `/public` - Static files
71
+ - `/dist` - Compiled assets (generated)
72
+ - `/build` - Production build output
73
+
74
+ ## Key Dependencies
75
+
76
+ ### Backend
77
+ - HyperExpress - High-performance web server
78
+ - Knex - SQL query builder
79
+ - SQLite3 - Database
80
+ - Nodemailer - Email sending
81
+ - Redis - Caching (optional)
82
+
83
+ ### Frontend
84
+ - Svelte 5 - UI framework
85
+ - Inertia.js - Client-server communication
86
+ - TailwindCSS - Utility-first CSS framework
87
+ - Vite - Build tool and dev server
88
+
89
+ ## Scripts
90
+
91
+ - `npm run dev` - Start development server
92
+ - `npm run build` - Build for production
93
+
94
+ ## Contributing
95
+
96
+ 1. Fork the repository
97
+ 2. Create your feature branch
98
+ 3. Commit your changes
99
+ 4. Push to the branch
100
+ 5. Create a new Pull Request
101
+
102
+ ## License
103
+
104
+ ISC License
105
+
106
+ ## Tutorial: Building Your First App
107
+
108
+ This tutorial will guide you through building a simple application using this framework.
109
+
110
+ ### 1. Setting Up a New Route and Controller
111
+
112
+ First, let's create a new route and controller for a blog post feature.
113
+
114
+ 1. Create a new controller file `app/controllers/PostController.ts`:
115
+
116
+ ```typescript
117
+ import { Request, Response } from "../../type";
118
+ import DB from "../services/DB";
119
+
120
+ class Controller {
121
+ public async index(request: Request, response: Response) {
122
+ const posts = await DB.from("posts");
123
+ return response.inertia("posts/index", { posts });
124
+ }
125
+
126
+ public async create(request: Request, response: Response) {
127
+ return response.inertia("posts/create");
128
+ }
129
+
130
+ public async store(request: Request, response: Response) {
131
+ const { title, content } = request.body;
132
+
133
+ await DB.table("posts").insert({
134
+ title,
135
+ content,
136
+ created_at: Date.now(),
137
+ updated_at: Date.now()
138
+ });
139
+
140
+ return response.redirect("/posts");
141
+ }
142
+ }
143
+
144
+ export default new Controller();
145
+ ```
146
+
147
+ 2. Add routes in `routes/web.ts`:
148
+
149
+ ```typescript
150
+ import PostController from "../app/controllers/PostController";
151
+
152
+ // Add these routes with your existing routes
153
+ Route.get("/posts", PostController.index);
154
+ Route.get("/posts/create", PostController.create);
155
+ Route.post("/posts", PostController.store);
156
+ ```
157
+
158
+ ### 2. Creating the Database Migration
159
+
160
+ Create a migration for the posts table:
161
+
162
+ ```bash
163
+ npx knex migrate:make create_posts_table
164
+ ```
165
+
166
+ In the generated migration file:
167
+
168
+ ```typescript
169
+ import { Knex } from "knex";
170
+
171
+ export async function up(knex: Knex): Promise<void> {
172
+ await knex.schema.createTable('posts', function (table) {
173
+ table.increments('id').primary();
174
+ table.string('title').notNullable();
175
+ table.text('content').notNullable();
176
+ table.bigInteger('created_at');
177
+ table.bigInteger('updated_at');
178
+ });
179
+ }
180
+
181
+ export async function down(knex: Knex): Promise<void> {
182
+ await knex.schema.dropTable('posts');
183
+ }
184
+ ```
185
+
186
+ Run the migration:
187
+
188
+ ```bash
189
+ npx knex migrate:latest
190
+ ```
191
+
192
+ ### 3. Creating Svelte Components
193
+
194
+ 1. Create `resources/views/posts/index.svelte`:
195
+
196
+ ```svelte
197
+ <script>
198
+ export let posts = [];
199
+ </script>
200
+
201
+ <div class="max-w-4xl mx-auto p-4">
202
+ <div class="flex justify-between items-center mb-6">
203
+ <h1 class="text-2xl font-bold">Blog Posts</h1>
204
+ <a
205
+ href="/posts/create"
206
+ class="bg-blue-500 text-white px-4 py-2 rounded hover:bg-blue-600"
207
+ >
208
+ Create Post
209
+ </a>
210
+ </div>
211
+
212
+ <div class="space-y-4">
213
+ {#each posts as post}
214
+ <div class="border p-4 rounded">
215
+ <h2 class="text-xl font-semibold">{post.title}</h2>
216
+ <p class="mt-2 text-gray-600">{post.content}</p>
217
+ </div>
218
+ {/each}
219
+ </div>
220
+ </div>
221
+ ```
222
+
223
+ 2. Create `resources/views/posts/create.svelte`:
224
+
225
+ ```svelte
226
+ <script>
227
+ import { router } from '@inertiajs/svelte';
228
+
229
+ let form = {
230
+ title: '',
231
+ content: ''
232
+ };
233
+
234
+ function handleSubmit() {
235
+ router.post('/posts', form);
236
+ }
237
+ </script>
238
+
239
+ <div class="max-w-4xl mx-auto p-4">
240
+ <h1 class="text-2xl font-bold mb-6">Create New Post</h1>
241
+
242
+ <form on:submit|preventDefault={handleSubmit} class="space-y-4">
243
+ <div>
244
+ <label class="block text-sm font-medium mb-1">Title</label>
245
+ <input
246
+ type="text"
247
+ bind:value={form.title}
248
+ class="w-full px-3 py-2 border rounded"
249
+ />
250
+ </div>
251
+
252
+ <div>
253
+ <label class="block text-sm font-medium mb-1">Content</label>
254
+ <textarea
255
+ bind:value={form.content}
256
+ class="w-full px-3 py-2 border rounded h-32"
257
+ ></textarea>
258
+ </div>
259
+
260
+ <div>
261
+ <button
262
+ type="submit"
263
+ class="bg-blue-500 text-white px-4 py-2 rounded hover:bg-blue-600"
264
+ >
265
+ Create Post
266
+ </button>
267
+ </div>
268
+ </form>
269
+ </div>
270
+ ```
271
+
272
+ ### 4. Testing Your Application
273
+
274
+ 1. Start the development server:
275
+ ```bash
276
+ npm run dev
277
+ ```
278
+
279
+ 2. Visit `http://localhost:5555/posts` in your browser
280
+ 3. Try creating a new post using the form
281
+ 4. View the list of posts on the index page
282
+
283
+ ### Key Concepts
284
+
285
+ 1. **Routing**: Routes are defined in `routes/web.ts` using the HyperExpress router
286
+ 2. **Controllers**: Handle business logic and return Inertia responses
287
+ 3. **Database**: Use Knex.js for database operations and migrations
288
+ 4. **Frontend**: Svelte components with Inertia.js for seamless page transitions
289
+ 5. **Styling**: TailwindCSS for utility-first styling
290
+
291
+ ### Best Practices
292
+
293
+ 1. **File Organization**
294
+ - Keep controllers in `app/controllers`
295
+ - Place Svelte components in `resources/views`
296
+ - Database migrations in `migrations`
297
+
298
+ 2. **Code Structure**
299
+ - Use TypeScript types for better type safety
300
+ - Keep controllers focused on single responsibilities
301
+ - Use Inertia.js for state management between server and client
302
+
303
+ 3. **Database**
304
+ - Always use migrations for database changes
305
+ - Use the Query Builder for complex queries
306
+ - Include timestamps for tracking record changes
307
+
308
+ Need help with anything specific? Feel free to ask!
309
+
package/bin/cli.js CHANGED
@@ -1,121 +1,121 @@
1
- #!/usr/bin/env node
2
-
3
- const { program } = require('commander');
4
- const prompts = require('prompts');
5
- const degit = require('degit');
6
- const path = require('path');
7
- const fs = require('fs');
8
- const { execSync } = require('child_process');
9
-
10
- const ASCII_ART = ` -
11
- :+===+ =+
12
- ++++++++++++++
13
- =++++= =+++
14
- +++= +++=
15
- ++= +++++
16
- ++ ++++++ +
17
- == =++++++++++++ -=
18
- = =++++++++++++ ++
19
- = ++++++ ++
20
- - =++++ =+=
21
- =++++ +++
22
- =++= -+++=
23
- ++++++++++++++=
24
- ++=+++++++++=
25
- == `;
26
-
27
- program
28
- .name('create-laju-app')
29
- .description('CLI to create a new project from template')
30
- .version('1.0.0');
31
-
32
- program
33
- .argument('[project-directory]', 'Project directory name')
34
- .action(async (projectDirectory) => {
35
- try {
36
- console.log(ASCII_ART); // Tambahkan ini
37
- console.log('\n'); // Tambah baris kosong setelah ASCII art
38
- // If no project name, ask user
39
- if (!projectDirectory) {
40
- const response = await prompts({
41
- type: 'text',
42
- name: 'projectDirectory',
43
- message: 'Enter project name:'
44
- });
45
- projectDirectory = response.projectDirectory;
46
- }
47
-
48
- if (!projectDirectory) {
49
- console.log('Project name is required to continue.');
50
- process.exit(1);
51
- }
52
-
53
- const targetPath = path.resolve(projectDirectory);
54
-
55
- // Check if directory exists
56
- if (fs.existsSync(targetPath)) {
57
- console.log(`Directory ${projectDirectory} already exists. Choose another name.`);
58
- process.exit(1);
59
- }
60
-
61
- console.log(`Creating a new project in ${targetPath}...`);
62
-
63
- // Clone template from GitHub
64
- const emitter = degit('maulanashalihin/laju');
65
-
66
- await emitter.clone(targetPath);
67
-
68
- // Read package.json from template
69
- const packageJsonPath = path.join(targetPath, 'package.json');
70
- const packageJson = require(packageJsonPath);
71
-
72
- // Update project name in package.json
73
- packageJson.name = projectDirectory;
74
-
75
- // Write back package.json
76
- fs.writeFileSync(
77
- packageJsonPath,
78
- JSON.stringify(packageJson, null, 2)
79
- );
80
-
81
- // Change directory and run setup commands
82
- process.chdir(targetPath);
83
- console.log('📦 Installing dependencies...');
84
- execSync('npm install', { stdio: 'inherit' });
85
- console.log('📝 Copying environment file...');
86
-
87
- execSync(process.platform === 'win32' ? 'copy .env.example .env' : 'cp .env.example .env', { stdio: 'inherit' });
88
- console.log('🔄 Running migrations...');
89
- execSync('npx knex migrate:latest', { stdio: 'inherit' });
90
- // Update scripts in package.json for Windows
91
- if (process.platform === 'win32') {
92
- packageJson.scripts = {
93
- "dev": "cls && npx concurrently \"vite\" \"npx nodemon\"",
94
- "build": "if exist build rmdir /s /q build && vite build && tsc && xcopy /s /e /i dist build && xcopy /s /e /i public build"
95
- };
96
-
97
- // Write updated package.json
98
- fs.writeFileSync(
99
- packageJsonPath,
100
- JSON.stringify(packageJson, null, 2)
101
- );
102
- }
103
-
104
- console.log('🎉 Project created successfully!');
105
- console.log('');
106
- console.log('🚀 Your project is ready! You can now start developing.');
107
-
108
- console.log('');
109
- console.log('👉 Next steps:');
110
- console.log('1. 📁 cd ' + projectDirectory);
111
- console.log('2. 🔥 npm run dev => to start the development server.');
112
- console.log('3. 📦 npm run build => to build the production files.');
113
- console.log('');
114
-
115
- } catch (error) {
116
- console.error('Error:', error.message);
117
- process.exit(1);
118
- }
119
- });
120
-
1
+ #!/usr/bin/env node
2
+
3
+ const { program } = require('commander');
4
+ const prompts = require('prompts');
5
+ const degit = require('degit');
6
+ const path = require('path');
7
+ const fs = require('fs');
8
+ const { execSync } = require('child_process');
9
+
10
+ const ASCII_ART = ` -
11
+ :+===+ =+
12
+ ++++++++++++++
13
+ =++++= =+++
14
+ +++= +++=
15
+ ++= +++++
16
+ ++ ++++++ +
17
+ == =++++++++++++ -=
18
+ = =++++++++++++ ++
19
+ = ++++++ ++
20
+ - =++++ =+=
21
+ =++++ +++
22
+ =++= -+++=
23
+ ++++++++++++++=
24
+ ++=+++++++++=
25
+ == `;
26
+
27
+ program
28
+ .name('create-laju-app')
29
+ .description('CLI to create a new project from template')
30
+ .version('1.0.0');
31
+
32
+ program
33
+ .argument('[project-directory]', 'Project directory name')
34
+ .action(async (projectDirectory) => {
35
+ try {
36
+ console.log(ASCII_ART); // Tambahkan ini
37
+ console.log('\n'); // Tambah baris kosong setelah ASCII art
38
+ // If no project name, ask user
39
+ if (!projectDirectory) {
40
+ const response = await prompts({
41
+ type: 'text',
42
+ name: 'projectDirectory',
43
+ message: 'Enter project name:'
44
+ });
45
+ projectDirectory = response.projectDirectory;
46
+ }
47
+
48
+ if (!projectDirectory) {
49
+ console.log('Project name is required to continue.');
50
+ process.exit(1);
51
+ }
52
+
53
+ const targetPath = path.resolve(projectDirectory);
54
+
55
+ // Check if directory exists
56
+ if (fs.existsSync(targetPath)) {
57
+ console.log(`Directory ${projectDirectory} already exists. Choose another name.`);
58
+ process.exit(1);
59
+ }
60
+
61
+ console.log(`Creating a new project in ${targetPath}...`);
62
+
63
+ // Clone template from GitHub
64
+ const emitter = degit('maulanashalihin/laju');
65
+
66
+ await emitter.clone(targetPath);
67
+
68
+ // Read package.json from template
69
+ const packageJsonPath = path.join(targetPath, 'package.json');
70
+ const packageJson = require(packageJsonPath);
71
+
72
+ // Update project name in package.json
73
+ packageJson.name = projectDirectory;
74
+
75
+ // Write back package.json
76
+ fs.writeFileSync(
77
+ packageJsonPath,
78
+ JSON.stringify(packageJson, null, 2)
79
+ );
80
+
81
+ // Change directory and run setup commands
82
+ process.chdir(targetPath);
83
+ console.log('📦 Installing dependencies...');
84
+ execSync('npm install', { stdio: 'inherit' });
85
+ console.log('📝 Copying environment file...');
86
+
87
+ execSync(process.platform === 'win32' ? 'copy .env.example .env' : 'cp .env.example .env', { stdio: 'inherit' });
88
+ console.log('🔄 Running migrations...');
89
+ execSync('npx knex migrate:latest', { stdio: 'inherit' });
90
+ // Update scripts in package.json for Windows
91
+ if (process.platform === 'win32') {
92
+ packageJson.scripts = {
93
+ "dev": "cls && npx concurrently \"vite\" \"npx nodemon\"",
94
+ "build": "if exist build rmdir /s /q build && vite build && tsc && xcopy /s /e /i dist build && xcopy /s /e /i public build"
95
+ };
96
+
97
+ // Write updated package.json
98
+ fs.writeFileSync(
99
+ packageJsonPath,
100
+ JSON.stringify(packageJson, null, 2)
101
+ );
102
+ }
103
+
104
+ console.log('🎉 Project created successfully!');
105
+ console.log('');
106
+ console.log('🚀 Your project is ready! You can now start developing.');
107
+
108
+ console.log('');
109
+ console.log('👉 Next steps:');
110
+ console.log('1. 📁 cd ' + projectDirectory);
111
+ console.log('2. 🔥 run "npm run dev" to start the development server.');
112
+ console.log('3. 💻 enjoy coding !!!.');
113
+ console.log('');
114
+
115
+ } catch (error) {
116
+ console.error('Error:', error.message);
117
+ process.exit(1);
118
+ }
119
+ });
120
+
121
121
  program.parse();
package/package.json CHANGED
@@ -1,28 +1,28 @@
1
- {
2
- "name": "create-laju-app",
3
- "version": "1.0.14",
4
- "keywords": [
5
- "laju",
6
- "svelte",
7
- "tailwindcss",
8
- "hyper-express",
9
- "sqlite",
10
- "boilerplate",
11
- "template",
12
- "generator"
13
- ],
14
- "bin": {
15
- "create-laju-app": "./bin/cli.js"
16
- },
17
- "dependencies": {
18
- "child_process": "^1.0.2",
19
- "commander": "^11.0.0",
20
- "degit": "^2.8.4",
21
- "prompts": "^2.4.2"
22
- },
23
- "homepage": "https://laju.dev",
24
- "repository": {
25
- "type": "git",
26
- "url": "git+https://github.com/maulanashalihin/laju.git"
27
- }
28
- }
1
+ {
2
+ "name": "create-laju-app",
3
+ "version": "1.0.15",
4
+ "keywords": [
5
+ "laju",
6
+ "svelte",
7
+ "tailwindcss",
8
+ "hyper-express",
9
+ "sqlite",
10
+ "boilerplate",
11
+ "template",
12
+ "generator"
13
+ ],
14
+ "bin": {
15
+ "create-laju-app": "./bin/cli.js"
16
+ },
17
+ "dependencies": {
18
+ "child_process": "^1.0.2",
19
+ "commander": "^11.0.0",
20
+ "degit": "^2.8.4",
21
+ "prompts": "^2.4.2"
22
+ },
23
+ "homepage": "https://laju.dev",
24
+ "repository": {
25
+ "type": "git",
26
+ "url": "git+https://github.com/maulanashalihin/laju.git"
27
+ }
28
+ }