create-velox-app 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.
- package/LICENSE +21 -0
- package/README.md +366 -0
- package/dist/cli.d.ts +9 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +65 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +263 -0
- package/dist/index.js.map +1 -0
- package/dist/templates.d.ts +29 -0
- package/dist/templates.d.ts.map +1 -0
- package/dist/templates.js +597 -0
- package/dist/templates.js.map +1 -0
- package/package.json +55 -0
|
@@ -0,0 +1,597 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Template Generation Functions
|
|
3
|
+
*
|
|
4
|
+
* Generates all files needed for a new VeloxTS project.
|
|
5
|
+
* Templates are based on the playground app structure.
|
|
6
|
+
*/
|
|
7
|
+
// ============================================================================
|
|
8
|
+
// Package.json Template
|
|
9
|
+
// ============================================================================
|
|
10
|
+
export function generatePackageJson(template) {
|
|
11
|
+
return JSON.stringify({
|
|
12
|
+
name: template.projectName,
|
|
13
|
+
version: '0.1.0',
|
|
14
|
+
description: 'A VeloxTS application',
|
|
15
|
+
type: 'module',
|
|
16
|
+
main: 'dist/index.js',
|
|
17
|
+
scripts: {
|
|
18
|
+
build: 'tsup',
|
|
19
|
+
start: 'node dist/index.js',
|
|
20
|
+
dev: 'tsx watch src/index.ts',
|
|
21
|
+
'type-check': 'tsc --noEmit',
|
|
22
|
+
clean: 'rm -rf dist tsconfig.tsbuildinfo',
|
|
23
|
+
'db:generate': 'prisma generate',
|
|
24
|
+
'db:push': 'prisma db push',
|
|
25
|
+
'db:studio': 'prisma studio',
|
|
26
|
+
},
|
|
27
|
+
dependencies: {
|
|
28
|
+
'@fastify/static': '^8.3.0',
|
|
29
|
+
'@prisma/adapter-better-sqlite3': '^7.1.0',
|
|
30
|
+
'@prisma/client': '^7.1.0',
|
|
31
|
+
'@veloxts/core': '^0.1.0',
|
|
32
|
+
'@veloxts/orm': '^0.1.0',
|
|
33
|
+
'@veloxts/router': '^0.1.0',
|
|
34
|
+
'@veloxts/validation': '^0.1.0',
|
|
35
|
+
dotenv: '^17.2.3',
|
|
36
|
+
zod: '^3.24.4',
|
|
37
|
+
},
|
|
38
|
+
devDependencies: {
|
|
39
|
+
prisma: '^7.1.0',
|
|
40
|
+
tsup: '^8.5.1',
|
|
41
|
+
tsx: '^4.21.0',
|
|
42
|
+
typescript: '^5.9.3',
|
|
43
|
+
},
|
|
44
|
+
}, null, 2);
|
|
45
|
+
}
|
|
46
|
+
// ============================================================================
|
|
47
|
+
// TypeScript Config
|
|
48
|
+
// ============================================================================
|
|
49
|
+
export function generateTsConfig() {
|
|
50
|
+
return JSON.stringify({
|
|
51
|
+
$schema: 'https://json.schemastore.org/tsconfig',
|
|
52
|
+
compilerOptions: {
|
|
53
|
+
target: 'ES2022',
|
|
54
|
+
module: 'ES2022',
|
|
55
|
+
moduleResolution: 'bundler',
|
|
56
|
+
lib: ['ES2022'],
|
|
57
|
+
strict: true,
|
|
58
|
+
esModuleInterop: true,
|
|
59
|
+
skipLibCheck: true,
|
|
60
|
+
resolveJsonModule: true,
|
|
61
|
+
allowSyntheticDefaultImports: true,
|
|
62
|
+
forceConsistentCasingInFileNames: true,
|
|
63
|
+
isolatedModules: true,
|
|
64
|
+
noUnusedLocals: true,
|
|
65
|
+
noUnusedParameters: true,
|
|
66
|
+
noFallthroughCasesInSwitch: true,
|
|
67
|
+
declaration: false,
|
|
68
|
+
declarationMap: false,
|
|
69
|
+
rootDir: './src',
|
|
70
|
+
outDir: './dist',
|
|
71
|
+
},
|
|
72
|
+
include: ['src/**/*'],
|
|
73
|
+
exclude: ['node_modules', 'dist', '**/*.test.ts', '**/*.spec.ts'],
|
|
74
|
+
}, null, 2);
|
|
75
|
+
}
|
|
76
|
+
// ============================================================================
|
|
77
|
+
// tsup Config
|
|
78
|
+
// ============================================================================
|
|
79
|
+
export function generateTsupConfig() {
|
|
80
|
+
return `import { defineConfig } from 'tsup';
|
|
81
|
+
|
|
82
|
+
export default defineConfig({
|
|
83
|
+
entry: ['src/index.ts'],
|
|
84
|
+
format: ['esm'],
|
|
85
|
+
target: 'node18',
|
|
86
|
+
clean: true,
|
|
87
|
+
dts: false,
|
|
88
|
+
sourcemap: true,
|
|
89
|
+
});
|
|
90
|
+
`;
|
|
91
|
+
}
|
|
92
|
+
// ============================================================================
|
|
93
|
+
// Environment Files
|
|
94
|
+
// ============================================================================
|
|
95
|
+
export function generateEnvExample() {
|
|
96
|
+
return `# Database URL
|
|
97
|
+
# SQLite (local development):
|
|
98
|
+
DATABASE_URL="file:./dev.db"
|
|
99
|
+
# PostgreSQL (production):
|
|
100
|
+
# DATABASE_URL="postgresql://user:password@localhost:5432/myapp"
|
|
101
|
+
|
|
102
|
+
# Server Configuration
|
|
103
|
+
PORT=3000
|
|
104
|
+
HOST=0.0.0.0
|
|
105
|
+
NODE_ENV=development
|
|
106
|
+
|
|
107
|
+
# API Configuration
|
|
108
|
+
API_PREFIX=/api
|
|
109
|
+
`;
|
|
110
|
+
}
|
|
111
|
+
export function generateGitignore() {
|
|
112
|
+
return `# Dependencies
|
|
113
|
+
node_modules/
|
|
114
|
+
|
|
115
|
+
# Build output
|
|
116
|
+
dist/
|
|
117
|
+
*.tsbuildinfo
|
|
118
|
+
|
|
119
|
+
# Environment variables
|
|
120
|
+
.env
|
|
121
|
+
.env.local
|
|
122
|
+
|
|
123
|
+
# Database
|
|
124
|
+
*.db
|
|
125
|
+
*.db-journal
|
|
126
|
+
|
|
127
|
+
# Generated Prisma client
|
|
128
|
+
src/generated/
|
|
129
|
+
|
|
130
|
+
# Logs
|
|
131
|
+
logs/
|
|
132
|
+
*.log
|
|
133
|
+
|
|
134
|
+
# OS
|
|
135
|
+
.DS_Store
|
|
136
|
+
Thumbs.db
|
|
137
|
+
|
|
138
|
+
# IDE
|
|
139
|
+
.vscode/
|
|
140
|
+
.idea/
|
|
141
|
+
*.swp
|
|
142
|
+
*.swo
|
|
143
|
+
|
|
144
|
+
# Turbo
|
|
145
|
+
.turbo/
|
|
146
|
+
`;
|
|
147
|
+
}
|
|
148
|
+
// ============================================================================
|
|
149
|
+
// Prisma Schema
|
|
150
|
+
// ============================================================================
|
|
151
|
+
export function generatePrismaSchema() {
|
|
152
|
+
return `// Prisma Schema
|
|
153
|
+
//
|
|
154
|
+
// This schema defines the database structure.
|
|
155
|
+
// Using SQLite for simplicity - easily swap to PostgreSQL for production.
|
|
156
|
+
|
|
157
|
+
generator client {
|
|
158
|
+
provider = "prisma-client"
|
|
159
|
+
output = "../src/generated/prisma"
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
datasource db {
|
|
163
|
+
provider = "sqlite"
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// ============================================================================
|
|
167
|
+
// User Model
|
|
168
|
+
// ============================================================================
|
|
169
|
+
|
|
170
|
+
/// User model for basic CRUD demonstration
|
|
171
|
+
model User {
|
|
172
|
+
id String @id @default(uuid())
|
|
173
|
+
name String
|
|
174
|
+
email String @unique
|
|
175
|
+
createdAt DateTime @default(now())
|
|
176
|
+
updatedAt DateTime @updatedAt
|
|
177
|
+
|
|
178
|
+
@@map("users")
|
|
179
|
+
}
|
|
180
|
+
`;
|
|
181
|
+
}
|
|
182
|
+
// ============================================================================
|
|
183
|
+
// Prisma Config (Prisma 7.x)
|
|
184
|
+
// ============================================================================
|
|
185
|
+
export function generatePrismaConfig() {
|
|
186
|
+
return `/**
|
|
187
|
+
* Prisma Configuration (Prisma 7.x)
|
|
188
|
+
*
|
|
189
|
+
* Database URL is now configured here instead of schema.prisma.
|
|
190
|
+
* See: https://www.prisma.io/docs/orm/more/upgrade-guides/upgrading-versions/upgrading-to-prisma-7
|
|
191
|
+
*/
|
|
192
|
+
|
|
193
|
+
import 'dotenv/config';
|
|
194
|
+
import { defineConfig } from 'prisma/config';
|
|
195
|
+
|
|
196
|
+
export default defineConfig({
|
|
197
|
+
earlyAccess: true,
|
|
198
|
+
schema: './prisma/schema.prisma',
|
|
199
|
+
datasource: {
|
|
200
|
+
url: process.env.DATABASE_URL!,
|
|
201
|
+
},
|
|
202
|
+
});
|
|
203
|
+
`;
|
|
204
|
+
}
|
|
205
|
+
// ============================================================================
|
|
206
|
+
// Source Files
|
|
207
|
+
// ============================================================================
|
|
208
|
+
export function generateIndexTs() {
|
|
209
|
+
return `/**
|
|
210
|
+
* Application Entry Point
|
|
211
|
+
*/
|
|
212
|
+
|
|
213
|
+
import 'dotenv/config';
|
|
214
|
+
|
|
215
|
+
import fastifyStatic from '@fastify/static';
|
|
216
|
+
import { createVeloxApp, VELOX_VERSION } from '@veloxts/core';
|
|
217
|
+
import { createDatabasePlugin } from '@veloxts/orm';
|
|
218
|
+
import { createRoutesRegistrar, getRouteSummary } from '@veloxts/router';
|
|
219
|
+
import path from 'node:path';
|
|
220
|
+
|
|
221
|
+
import { config } from './config/index.js';
|
|
222
|
+
import { prisma } from './database/index.js';
|
|
223
|
+
import { healthProcedures, userProcedures } from './procedures/index.js';
|
|
224
|
+
|
|
225
|
+
// ============================================================================
|
|
226
|
+
// Application Bootstrap
|
|
227
|
+
// ============================================================================
|
|
228
|
+
|
|
229
|
+
async function createApp() {
|
|
230
|
+
const app = await createVeloxApp({
|
|
231
|
+
port: config.port,
|
|
232
|
+
host: config.host,
|
|
233
|
+
logger: config.logger,
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
// Register database plugin
|
|
237
|
+
await app.use(createDatabasePlugin({ client: prisma }));
|
|
238
|
+
|
|
239
|
+
// Register static file serving for frontend
|
|
240
|
+
await app.server.register(fastifyStatic, {
|
|
241
|
+
root: path.join(process.cwd(), 'public'),
|
|
242
|
+
prefix: '/',
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
// Register REST API routes
|
|
246
|
+
const collections = [userProcedures, healthProcedures];
|
|
247
|
+
app.routes(createRoutesRegistrar(collections, { prefix: config.apiPrefix }));
|
|
248
|
+
|
|
249
|
+
return { app, collections };
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
function printBanner(collections: Parameters<typeof getRouteSummary>[0]) {
|
|
253
|
+
const divider = '═'.repeat(50);
|
|
254
|
+
|
|
255
|
+
console.log(\`\\n\${divider}\`);
|
|
256
|
+
console.log(\` VeloxTS Application v\${VELOX_VERSION}\`);
|
|
257
|
+
console.log(\` Environment: \${config.env}\`);
|
|
258
|
+
console.log(divider);
|
|
259
|
+
|
|
260
|
+
// Print registered routes
|
|
261
|
+
const routes = getRouteSummary(collections);
|
|
262
|
+
console.log('\\n📍 Registered Routes:\\n');
|
|
263
|
+
|
|
264
|
+
for (const route of routes) {
|
|
265
|
+
const method = route.method.padEnd(6);
|
|
266
|
+
const path = route.path.padEnd(25);
|
|
267
|
+
console.log(\` \${method} \${path} → \${route.namespace}.\${route.procedure}\`);
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
console.log(\`\\n\${divider}\`);
|
|
271
|
+
console.log(\` Frontend: http://localhost:\${config.port}\`);
|
|
272
|
+
console.log(\` REST API: http://localhost:\${config.port}\${config.apiPrefix}\`);
|
|
273
|
+
console.log(\`\${divider}\\n\`);
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
async function main() {
|
|
277
|
+
try {
|
|
278
|
+
const { app, collections } = await createApp();
|
|
279
|
+
await app.start();
|
|
280
|
+
printBanner(collections);
|
|
281
|
+
} catch (error) {
|
|
282
|
+
console.error('Failed to start application:', error);
|
|
283
|
+
process.exit(1);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
main();
|
|
288
|
+
`;
|
|
289
|
+
}
|
|
290
|
+
export function generateConfigIndex() {
|
|
291
|
+
return `/**
|
|
292
|
+
* Configuration Exports
|
|
293
|
+
*/
|
|
294
|
+
|
|
295
|
+
export * from './app.js';
|
|
296
|
+
`;
|
|
297
|
+
}
|
|
298
|
+
export function generateConfigApp() {
|
|
299
|
+
return `/**
|
|
300
|
+
* Application Configuration
|
|
301
|
+
*/
|
|
302
|
+
|
|
303
|
+
export interface AppConfig {
|
|
304
|
+
port: number;
|
|
305
|
+
host: string;
|
|
306
|
+
logger: boolean;
|
|
307
|
+
apiPrefix: string;
|
|
308
|
+
env: 'development' | 'production' | 'test';
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
export function createConfig(): AppConfig {
|
|
312
|
+
return {
|
|
313
|
+
port: Number(process.env.PORT) || 3000,
|
|
314
|
+
host: process.env.HOST || '0.0.0.0',
|
|
315
|
+
logger: process.env.LOG_LEVEL !== 'silent',
|
|
316
|
+
apiPrefix: process.env.API_PREFIX || '/api',
|
|
317
|
+
env: (process.env.NODE_ENV as AppConfig['env']) || 'development',
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
export const config = createConfig();
|
|
322
|
+
`;
|
|
323
|
+
}
|
|
324
|
+
export function generateDatabaseIndex() {
|
|
325
|
+
return `/**
|
|
326
|
+
* Database Client (Prisma 7.x)
|
|
327
|
+
*
|
|
328
|
+
* Prisma 7 requires:
|
|
329
|
+
* - Generated client from custom output path
|
|
330
|
+
* - Driver adapter for database connections
|
|
331
|
+
*/
|
|
332
|
+
|
|
333
|
+
import { PrismaClient } from '../generated/prisma/client.js';
|
|
334
|
+
import { PrismaBetterSqlite3 } from '@prisma/adapter-better-sqlite3';
|
|
335
|
+
|
|
336
|
+
// Create SQLite adapter with database URL from environment
|
|
337
|
+
const adapter = new PrismaBetterSqlite3({ url: process.env.DATABASE_URL! });
|
|
338
|
+
|
|
339
|
+
// Export configured Prisma client
|
|
340
|
+
export const prisma = new PrismaClient({ adapter });
|
|
341
|
+
`;
|
|
342
|
+
}
|
|
343
|
+
export function generateProceduresIndex() {
|
|
344
|
+
return `/**
|
|
345
|
+
* Procedure Exports
|
|
346
|
+
*/
|
|
347
|
+
|
|
348
|
+
export * from './health.js';
|
|
349
|
+
export * from './users.js';
|
|
350
|
+
`;
|
|
351
|
+
}
|
|
352
|
+
export function generateHealthProcedures() {
|
|
353
|
+
return `/**
|
|
354
|
+
* Health Check Procedures
|
|
355
|
+
*/
|
|
356
|
+
|
|
357
|
+
import { VELOX_VERSION } from '@veloxts/core';
|
|
358
|
+
import { defineProcedures, procedure } from '@veloxts/router';
|
|
359
|
+
import { z } from 'zod';
|
|
360
|
+
|
|
361
|
+
export const healthProcedures = defineProcedures('health', {
|
|
362
|
+
getHealth: procedure()
|
|
363
|
+
.rest({ method: 'GET', path: '/health' })
|
|
364
|
+
.output(
|
|
365
|
+
z.object({
|
|
366
|
+
status: z.literal('ok'),
|
|
367
|
+
version: z.string(),
|
|
368
|
+
timestamp: z.string().datetime(),
|
|
369
|
+
uptime: z.number(),
|
|
370
|
+
})
|
|
371
|
+
)
|
|
372
|
+
.query(async () => ({
|
|
373
|
+
status: 'ok' as const,
|
|
374
|
+
version: VELOX_VERSION,
|
|
375
|
+
timestamp: new Date().toISOString(),
|
|
376
|
+
uptime: process.uptime(),
|
|
377
|
+
})),
|
|
378
|
+
});
|
|
379
|
+
`;
|
|
380
|
+
}
|
|
381
|
+
export function generateUserProcedures() {
|
|
382
|
+
return `/**
|
|
383
|
+
* User Procedures
|
|
384
|
+
*/
|
|
385
|
+
|
|
386
|
+
import { defineProcedures, procedure } from '@veloxts/router';
|
|
387
|
+
import { paginationInputSchema } from '@veloxts/validation';
|
|
388
|
+
import { z } from 'zod';
|
|
389
|
+
|
|
390
|
+
import { CreateUserInput, UserSchema } from '../schemas/user.js';
|
|
391
|
+
|
|
392
|
+
// Database types
|
|
393
|
+
interface DbUser {
|
|
394
|
+
id: string;
|
|
395
|
+
name: string;
|
|
396
|
+
email: string;
|
|
397
|
+
createdAt: Date;
|
|
398
|
+
updatedAt: Date;
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
interface DbClient {
|
|
402
|
+
user: {
|
|
403
|
+
findUnique: (args: { where: { id: string } }) => Promise<DbUser | null>;
|
|
404
|
+
findMany: (args?: { skip?: number; take?: number }) => Promise<DbUser[]>;
|
|
405
|
+
create: (args: { data: { name: string; email: string } }) => Promise<DbUser>;
|
|
406
|
+
count: () => Promise<number>;
|
|
407
|
+
};
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
function getDb(ctx: { db: unknown }): DbClient {
|
|
411
|
+
return ctx.db as DbClient;
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
function toUserResponse(dbUser: DbUser) {
|
|
415
|
+
return {
|
|
416
|
+
id: dbUser.id,
|
|
417
|
+
name: dbUser.name,
|
|
418
|
+
email: dbUser.email,
|
|
419
|
+
createdAt: dbUser.createdAt.toISOString(),
|
|
420
|
+
updatedAt: dbUser.updatedAt.toISOString(),
|
|
421
|
+
};
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
export const userProcedures = defineProcedures('users', {
|
|
425
|
+
getUser: procedure()
|
|
426
|
+
.input(z.object({ id: z.string().uuid() }))
|
|
427
|
+
.output(UserSchema.nullable())
|
|
428
|
+
.query(async ({ input, ctx }) => {
|
|
429
|
+
const db = getDb(ctx);
|
|
430
|
+
const user = await db.user.findUnique({ where: { id: input.id } });
|
|
431
|
+
return user ? toUserResponse(user) : null;
|
|
432
|
+
}),
|
|
433
|
+
|
|
434
|
+
listUsers: procedure()
|
|
435
|
+
.input(paginationInputSchema.optional())
|
|
436
|
+
.output(
|
|
437
|
+
z.object({
|
|
438
|
+
data: z.array(UserSchema),
|
|
439
|
+
meta: z.object({
|
|
440
|
+
page: z.number(),
|
|
441
|
+
limit: z.number(),
|
|
442
|
+
total: z.number(),
|
|
443
|
+
}),
|
|
444
|
+
})
|
|
445
|
+
)
|
|
446
|
+
.query(async ({ input, ctx }) => {
|
|
447
|
+
const db = getDb(ctx);
|
|
448
|
+
const page = input?.page ?? 1;
|
|
449
|
+
const limit = input?.limit ?? 10;
|
|
450
|
+
const skip = (page - 1) * limit;
|
|
451
|
+
|
|
452
|
+
const [dbUsers, total] = await Promise.all([
|
|
453
|
+
db.user.findMany({ skip, take: limit }),
|
|
454
|
+
db.user.count(),
|
|
455
|
+
]);
|
|
456
|
+
|
|
457
|
+
return {
|
|
458
|
+
data: dbUsers.map(toUserResponse),
|
|
459
|
+
meta: { page, limit, total },
|
|
460
|
+
};
|
|
461
|
+
}),
|
|
462
|
+
|
|
463
|
+
createUser: procedure()
|
|
464
|
+
.input(CreateUserInput)
|
|
465
|
+
.output(UserSchema)
|
|
466
|
+
.mutation(async ({ input, ctx }) => {
|
|
467
|
+
const db = getDb(ctx);
|
|
468
|
+
const user = await db.user.create({ data: input });
|
|
469
|
+
return toUserResponse(user);
|
|
470
|
+
}),
|
|
471
|
+
});
|
|
472
|
+
`;
|
|
473
|
+
}
|
|
474
|
+
export function generateSchemasIndex() {
|
|
475
|
+
return `/**
|
|
476
|
+
* Schema Exports
|
|
477
|
+
*/
|
|
478
|
+
|
|
479
|
+
export * from './user.js';
|
|
480
|
+
`;
|
|
481
|
+
}
|
|
482
|
+
export function generateUserSchema() {
|
|
483
|
+
return `/**
|
|
484
|
+
* User Schemas
|
|
485
|
+
*/
|
|
486
|
+
|
|
487
|
+
import { createIdSchema, emailSchema } from '@veloxts/validation';
|
|
488
|
+
import { z } from 'zod';
|
|
489
|
+
|
|
490
|
+
export const UserSchema = z.object({
|
|
491
|
+
id: createIdSchema('uuid'),
|
|
492
|
+
name: z.string().min(1).max(100),
|
|
493
|
+
email: emailSchema,
|
|
494
|
+
createdAt: z.coerce.date().transform((d) => d.toISOString()),
|
|
495
|
+
updatedAt: z.coerce.date().transform((d) => d.toISOString()),
|
|
496
|
+
});
|
|
497
|
+
|
|
498
|
+
export type User = z.infer<typeof UserSchema>;
|
|
499
|
+
|
|
500
|
+
export const CreateUserInput = z.object({
|
|
501
|
+
name: z.string().min(1).max(100),
|
|
502
|
+
email: emailSchema,
|
|
503
|
+
});
|
|
504
|
+
|
|
505
|
+
export type CreateUserData = z.infer<typeof CreateUserInput>;
|
|
506
|
+
`;
|
|
507
|
+
}
|
|
508
|
+
export function generateIndexHtml() {
|
|
509
|
+
return `<!DOCTYPE html>
|
|
510
|
+
<html lang="en">
|
|
511
|
+
<head>
|
|
512
|
+
<meta charset="UTF-8">
|
|
513
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
514
|
+
<title>VeloxTS App</title>
|
|
515
|
+
<style>
|
|
516
|
+
* { box-sizing: border-box; margin: 0; padding: 0; }
|
|
517
|
+
body { font-family: system-ui, sans-serif; background: #f5f5f5; padding: 20px; }
|
|
518
|
+
.container { max-width: 800px; margin: 0 auto; }
|
|
519
|
+
h1 { margin-bottom: 20px; color: #333; }
|
|
520
|
+
.card { background: white; border-radius: 8px; padding: 20px; margin-bottom: 20px; box-shadow: 0 1px 3px rgba(0,0,0,0.1); }
|
|
521
|
+
.card h2 { margin-bottom: 15px; color: #555; font-size: 1.1rem; }
|
|
522
|
+
button { background: #007bff; color: white; border: none; padding: 8px 16px; border-radius: 4px; cursor: pointer; }
|
|
523
|
+
button:hover { background: #0056b3; }
|
|
524
|
+
</style>
|
|
525
|
+
</head>
|
|
526
|
+
<body>
|
|
527
|
+
<div class="container">
|
|
528
|
+
<h1>Welcome to VeloxTS</h1>
|
|
529
|
+
<div class="card">
|
|
530
|
+
<h2>Your app is running!</h2>
|
|
531
|
+
<p>Visit <code>/api/health</code> to check the API status.</p>
|
|
532
|
+
<p>Visit <code>/api/users</code> to see the users endpoint.</p>
|
|
533
|
+
</div>
|
|
534
|
+
</div>
|
|
535
|
+
</body>
|
|
536
|
+
</html>
|
|
537
|
+
`;
|
|
538
|
+
}
|
|
539
|
+
export function generateReadme(projectName) {
|
|
540
|
+
return `# ${projectName}
|
|
541
|
+
|
|
542
|
+
A VeloxTS application - Laravel-inspired TypeScript full-stack framework.
|
|
543
|
+
|
|
544
|
+
## Getting Started
|
|
545
|
+
|
|
546
|
+
### Install Dependencies
|
|
547
|
+
|
|
548
|
+
\`\`\`bash
|
|
549
|
+
pnpm install
|
|
550
|
+
\`\`\`
|
|
551
|
+
|
|
552
|
+
### Setup Database
|
|
553
|
+
|
|
554
|
+
\`\`\`bash
|
|
555
|
+
pnpm db:push
|
|
556
|
+
\`\`\`
|
|
557
|
+
|
|
558
|
+
### Start Development Server
|
|
559
|
+
|
|
560
|
+
\`\`\`bash
|
|
561
|
+
pnpm dev
|
|
562
|
+
\`\`\`
|
|
563
|
+
|
|
564
|
+
The app will start at http://localhost:3210
|
|
565
|
+
|
|
566
|
+
## Project Structure
|
|
567
|
+
|
|
568
|
+
\`\`\`
|
|
569
|
+
src/
|
|
570
|
+
├── config/ # Application configuration
|
|
571
|
+
├── database/ # Database client
|
|
572
|
+
├── procedures/ # API procedures (business logic)
|
|
573
|
+
├── schemas/ # Zod validation schemas
|
|
574
|
+
└── index.ts # Application entry point
|
|
575
|
+
\`\`\`
|
|
576
|
+
|
|
577
|
+
## Available Scripts
|
|
578
|
+
|
|
579
|
+
- \`pnpm dev\` - Start development server with hot reload
|
|
580
|
+
- \`pnpm build\` - Build for production
|
|
581
|
+
- \`pnpm start\` - Start production server
|
|
582
|
+
- \`pnpm db:push\` - Sync database schema
|
|
583
|
+
- \`pnpm db:studio\` - Open Prisma Studio
|
|
584
|
+
|
|
585
|
+
## Learn More
|
|
586
|
+
|
|
587
|
+
- [VeloxTS Documentation](https://veloxts.dev)
|
|
588
|
+
- [TypeScript](https://www.typescriptlang.org/)
|
|
589
|
+
- [Fastify](https://fastify.dev/)
|
|
590
|
+
- [Prisma](https://www.prisma.io/)
|
|
591
|
+
|
|
592
|
+
## License
|
|
593
|
+
|
|
594
|
+
MIT
|
|
595
|
+
`;
|
|
596
|
+
}
|
|
597
|
+
//# sourceMappingURL=templates.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"templates.js","sourceRoot":"","sources":["../src/templates.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "create-velox-app",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Project scaffolder for VeloxTS framework",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"bin": {
|
|
15
|
+
"create-velox-app": "dist/cli.js"
|
|
16
|
+
},
|
|
17
|
+
"files": [
|
|
18
|
+
"dist",
|
|
19
|
+
"README.md"
|
|
20
|
+
],
|
|
21
|
+
"dependencies": {
|
|
22
|
+
"@clack/prompts": "0.11.0",
|
|
23
|
+
"picocolors": "1.1.1"
|
|
24
|
+
},
|
|
25
|
+
"devDependencies": {
|
|
26
|
+
"@types/node": "24.10.1",
|
|
27
|
+
"typescript": "5.9.3"
|
|
28
|
+
},
|
|
29
|
+
"keywords": [
|
|
30
|
+
"velox",
|
|
31
|
+
"create",
|
|
32
|
+
"scaffold",
|
|
33
|
+
"cli",
|
|
34
|
+
"typescript"
|
|
35
|
+
],
|
|
36
|
+
"license": "MIT",
|
|
37
|
+
"repository": {
|
|
38
|
+
"type": "git",
|
|
39
|
+
"url": "https://github.com/veloxts/velox-ts-framework",
|
|
40
|
+
"directory": "packages/create"
|
|
41
|
+
},
|
|
42
|
+
"engines": {
|
|
43
|
+
"node": ">=20.0.0"
|
|
44
|
+
},
|
|
45
|
+
"publishConfig": {
|
|
46
|
+
"access": "public"
|
|
47
|
+
},
|
|
48
|
+
"scripts": {
|
|
49
|
+
"build": "tsc",
|
|
50
|
+
"dev": "tsc --watch",
|
|
51
|
+
"type-check": "tsc --noEmit",
|
|
52
|
+
"clean": "rm -rf dist tsconfig.tsbuildinfo",
|
|
53
|
+
"smoke-test": "./scripts/smoke-test.sh"
|
|
54
|
+
}
|
|
55
|
+
}
|