create-velox-app 0.6.74 → 0.6.76

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/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # create-velox-app
2
2
 
3
+ ## 0.6.76
4
+
5
+ ### Patch Changes
6
+
7
+ - fix(create): resolve all template type errors for zero-error scaffolding
8
+
9
+ ## 0.6.75
10
+
11
+ ### Patch Changes
12
+
13
+ - feat(create): add --pm flag to skip package manager prompt
14
+
3
15
  ## 0.6.74
4
16
 
5
17
  ### Patch Changes
package/dist/cli.d.ts CHANGED
@@ -6,11 +6,14 @@
6
6
  * Handles command-line arguments and initiates the scaffolding process.
7
7
  */
8
8
  import type { DatabaseType, TemplateType } from './templates/index.js';
9
+ /** Valid package manager types */
10
+ export type PackageManagerType = 'npm' | 'pnpm' | 'yarn';
9
11
  /** @internal Exported for testing */
10
12
  export interface ParsedArgs {
11
13
  projectName?: string;
12
14
  template?: TemplateType;
13
15
  database?: DatabaseType;
16
+ packageManager?: PackageManagerType;
14
17
  help: boolean;
15
18
  version: boolean;
16
19
  }
package/dist/cli.js CHANGED
@@ -39,6 +39,8 @@ Options:
39
39
  Available: ${getTemplateNames()}
40
40
  -d, --database <name> Database to use (default: "sqlite")
41
41
  Available: ${getDatabaseNames()}
42
+ --pm <manager> Package manager to use (npm, pnpm, yarn)
43
+ Skips interactive prompt if specified
42
44
  -h, --help Show this help message
43
45
  -v, --version Show version number
44
46
 
@@ -60,8 +62,11 @@ Examples:
60
62
  npx create-velox-app my-app --auth # Auth template (shortcut)
61
63
  npx create-velox-app my-app --rsc -d postgresql # RSC with PostgreSQL
62
64
  npx create-velox-app my-app --template=spa # SPA + API template
65
+ npx create-velox-app my-app --pm npm # Non-interactive (npm)
63
66
  npx create-velox-app # Prompt for all options
64
67
  `;
68
+ /** Valid package managers */
69
+ const VALID_PACKAGE_MANAGERS = new Set(['npm', 'pnpm', 'yarn']);
65
70
  /** Template shorthand flags (--auth, --spa, etc.) */
66
71
  const TEMPLATE_FLAGS = new Set([
67
72
  '--spa',
@@ -207,6 +212,39 @@ export function parseArgs(args) {
207
212
  }
208
213
  continue;
209
214
  }
215
+ // Handle --pm=<value>
216
+ if (arg.startsWith('--pm=')) {
217
+ const value = arg.split('=')[1];
218
+ if (!value) {
219
+ console.error('Error: --pm requires a value. Available: npm, pnpm, yarn');
220
+ process.exit(1);
221
+ }
222
+ if (VALID_PACKAGE_MANAGERS.has(value)) {
223
+ result.packageManager = value;
224
+ }
225
+ else {
226
+ console.error(`Invalid package manager: ${value}. Available: npm, pnpm, yarn`);
227
+ process.exit(1);
228
+ }
229
+ continue;
230
+ }
231
+ // Handle --pm <value>
232
+ if (arg === '--pm') {
233
+ const value = args[i + 1];
234
+ if (!value || value.startsWith('-')) {
235
+ console.error('Error: --pm requires a value. Available: npm, pnpm, yarn');
236
+ process.exit(1);
237
+ }
238
+ if (VALID_PACKAGE_MANAGERS.has(value)) {
239
+ result.packageManager = value;
240
+ i++; // Skip next arg
241
+ }
242
+ else {
243
+ console.error(`Invalid package manager: ${value}. Available: npm, pnpm, yarn`);
244
+ process.exit(1);
245
+ }
246
+ continue;
247
+ }
210
248
  // Non-flag argument
211
249
  if (!arg.startsWith('-')) {
212
250
  if (!result.projectName) {
@@ -245,7 +283,7 @@ async function main() {
245
283
  process.exit(0);
246
284
  }
247
285
  // Run scaffolder
248
- await createVeloxApp(parsed.projectName, parsed.template, parsed.database);
286
+ await createVeloxApp(parsed.projectName, parsed.template, parsed.database, parsed.packageManager);
249
287
  }
250
288
  catch (error) {
251
289
  // Handle unexpected errors with actionable guidance
package/dist/index.d.ts CHANGED
@@ -19,7 +19,7 @@ export declare function isPathSafe(baseDir: string, targetPath: string): boolean
19
19
  /**
20
20
  * Main scaffolding function that creates a new VeloxTS project
21
21
  */
22
- export declare function createVeloxApp(initialProjectName?: string, initialTemplate?: TemplateType, initialDatabase?: DatabaseType): Promise<void>;
22
+ export declare function createVeloxApp(initialProjectName?: string, initialTemplate?: TemplateType, initialDatabase?: DatabaseType, initialPackageManager?: 'npm' | 'pnpm' | 'yarn'): Promise<void>;
23
23
  /**
24
24
  * Detect which package manager is being used
25
25
  * @internal Exported for testing
package/dist/index.js CHANGED
@@ -59,7 +59,7 @@ export function isPathSafe(baseDir, targetPath) {
59
59
  /**
60
60
  * Main scaffolding function that creates a new VeloxTS project
61
61
  */
62
- export async function createVeloxApp(initialProjectName, initialTemplate, initialDatabase) {
62
+ export async function createVeloxApp(initialProjectName, initialTemplate, initialDatabase, initialPackageManager) {
63
63
  // Print welcome banner
64
64
  console.log('');
65
65
  p.intro(pc.cyan(pc.bold('create-velox-app')));
@@ -67,7 +67,7 @@ export async function createVeloxApp(initialProjectName, initialTemplate, initia
67
67
  let projectCreated = false;
68
68
  try {
69
69
  // Collect project configuration
70
- const config = await promptProjectConfig(initialProjectName, initialTemplate, initialDatabase);
70
+ const config = await promptProjectConfig(initialProjectName, initialTemplate, initialDatabase, initialPackageManager);
71
71
  projectDirectory = config.directory;
72
72
  // Show configuration summary
73
73
  p.log.info(pc.dim('Configuration:'));
@@ -127,7 +127,7 @@ export async function createVeloxApp(initialProjectName, initialTemplate, initia
127
127
  /**
128
128
  * Prompt user for project configuration
129
129
  */
130
- async function promptProjectConfig(initialName, initialTemplate, initialDatabase) {
130
+ async function promptProjectConfig(initialName, initialTemplate, initialDatabase, initialPackageManager) {
131
131
  // Project name
132
132
  const name = initialName
133
133
  ? initialName
@@ -199,10 +199,11 @@ async function promptProjectConfig(initialName, initialTemplate, initialDatabase
199
199
  throw new Error(`Database "${database}" is not yet available. Please choose SQLite for now.`);
200
200
  }
201
201
  }
202
- // Package manager selection (prompt unless running in CI/non-interactive mode)
203
- let packageManager = detectPackageManager();
202
+ // Package manager selection (prompt unless provided via CLI or running in CI/non-interactive mode)
203
+ let packageManager = initialPackageManager ?? detectPackageManager();
204
+ // Only show package manager prompt if not provided via CLI
204
205
  // SKIP_INSTALL is set in smoke tests to skip interactive prompts
205
- if (process.env.SKIP_INSTALL !== 'true') {
206
+ if (!initialPackageManager && process.env.SKIP_INSTALL !== 'true') {
206
207
  const selectedPackageManager = await p.select({
207
208
  message: 'Choose a package manager',
208
209
  initialValue: packageManager,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-velox-app",
3
- "version": "0.6.74",
3
+ "version": "0.6.76",
4
4
  "description": "Project scaffolder for VeloxTS framework",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -2,7 +2,16 @@
2
2
  * Application Configuration
3
3
  */
4
4
 
5
- import type { FastifyLoggerOptions } from 'fastify';
5
+ /**
6
+ * Application configuration type
7
+ */
8
+ export interface AppConfig {
9
+ port: number;
10
+ host: string;
11
+ logger: boolean | { level: string };
12
+ apiPrefix: string;
13
+ env: 'development' | 'production' | 'test';
14
+ }
6
15
 
7
16
  /**
8
17
  * Build logger configuration based on environment.
@@ -11,7 +20,7 @@ import type { FastifyLoggerOptions } from 'fastify';
11
20
  * - LOG_LEVEL=debug: Enable debug-level logging
12
21
  * - Default: Standard info-level logging
13
22
  */
14
- function buildLoggerConfig(): boolean | FastifyLoggerOptions {
23
+ function buildLoggerConfig(): boolean | { level: string } {
15
24
  const logLevel = process.env.LOG_LEVEL;
16
25
 
17
26
  // Silent mode - no logging
@@ -28,12 +37,10 @@ function buildLoggerConfig(): boolean | FastifyLoggerOptions {
28
37
  return true;
29
38
  }
30
39
 
31
- export const config = {
40
+ export const config: AppConfig = {
32
41
  port: Number(process.env.PORT) || __API_PORT__,
33
42
  host: process.env.HOST || '0.0.0.0',
34
43
  logger: buildLoggerConfig(),
35
44
  apiPrefix: process.env.API_PREFIX || '/api',
36
45
  env: (process.env.NODE_ENV || 'development') as 'development' | 'production' | 'test',
37
- } as const;
38
-
39
- export type AppConfig = typeof config;
46
+ };
@@ -39,7 +39,7 @@ const { PrismaClient } = require('@prisma/client') as {
39
39
  declare global {
40
40
  // Allow global `var` declarations for hot reload in development
41
41
  // eslint-disable-next-line no-var
42
- var __db: PrismaClient | undefined;
42
+ var __db: PrismaClientType | undefined;
43
43
  }
44
44
 
45
45
  /* @if sqlite */
@@ -47,7 +47,7 @@ declare global {
47
47
  * Create a Prisma client instance using the SQLite adapter.
48
48
  * Validates that DATABASE_URL is set before creating the client.
49
49
  */
50
- function createPrismaClient(): PrismaClient {
50
+ function createPrismaClient(): PrismaClientType {
51
51
  const databaseUrl = process.env.DATABASE_URL;
52
52
 
53
53
  if (!databaseUrl) {
@@ -70,7 +70,7 @@ function createPrismaClient(): PrismaClient {
70
70
  * - PrismaPg now takes connectionString directly (not a Pool instance)
71
71
  * - Pool management is handled internally by the adapter
72
72
  */
73
- function createPrismaClient(): PrismaClient {
73
+ function createPrismaClient(): PrismaClientType {
74
74
  const connectionString = process.env.DATABASE_URL;
75
75
 
76
76
  if (!connectionString) {
@@ -214,7 +214,8 @@ export const authProcedures = procedures('auth', {
214
214
  .guard(authenticated)
215
215
  .output(LogoutResponse)
216
216
  .mutation(async ({ ctx }) => {
217
- const tokenId = ctx.auth?.token?.jti;
217
+ // Narrow the discriminated union to access native JWT payload
218
+ const tokenId = ctx.auth?.authMode === 'native' ? ctx.auth.payload?.jti : undefined;
218
219
 
219
220
  if (tokenId) {
220
221
  tokenStore.revoke(tokenId, 15 * 60 * 1000);
@@ -239,7 +240,7 @@ export const authProcedures = procedures('auth', {
239
240
 
240
241
  return {
241
242
  id: user.id,
242
- name: (user.name as string) || '',
243
+ name: user.name ?? '',
243
244
  email: user.email,
244
245
  roles: Array.isArray(user.roles) ? user.roles : ['user'],
245
246
  };
@@ -7,7 +7,7 @@
7
7
  * IMPORTANT: Keep this file browser-safe - no Node.js imports or side effects.
8
8
  */
9
9
 
10
- import type { RouteMap } from '@veloxts/router';
10
+ import type { RouteMap } from '@veloxts/velox';
11
11
 
12
12
  /**
13
13
  * Route mappings for the VeloxTS client
@@ -8,27 +8,21 @@
8
8
  import { z } from 'zod';
9
9
 
10
10
  // ============================================================================
11
- // Timestamp Helper
11
+ // User Schema
12
12
  // ============================================================================
13
13
 
14
14
  /**
15
- * Schema that accepts Date or string and outputs ISO string.
16
- * Handles Prisma Date objects JSON-safe strings.
15
+ * User response schema.
16
+ * Uses z.coerce.date() to safely handle both:
17
+ * - Date objects from Prisma (output)
18
+ * - ISO strings from JSON (input validation)
17
19
  */
18
- const dateToString = z
19
- .union([z.date(), z.string()])
20
- .transform((val) => (val instanceof Date ? val.toISOString() : val));
21
-
22
- // ============================================================================
23
- // User Schema
24
- // ============================================================================
25
-
26
20
  export const UserSchema = z.object({
27
21
  id: z.string().uuid(),
28
22
  name: z.string().min(1).max(100),
29
23
  email: z.string().email(),
30
- createdAt: dateToString,
31
- updatedAt: dateToString,
24
+ createdAt: z.coerce.date(),
25
+ updatedAt: z.coerce.date(),
32
26
  });
33
27
 
34
28
  export type User = z.infer<typeof UserSchema>;
@@ -5,10 +5,17 @@
5
5
  * This enables full autocomplete for ctx.db in procedure handlers.
6
6
  */
7
7
 
8
- import type { PrismaClient } from './generated/prisma/client.js';
8
+ import type { PrismaClient } from '@prisma/client';
9
9
 
10
10
  declare module '@veloxts/core' {
11
11
  interface BaseContext {
12
12
  db: PrismaClient;
13
13
  }
14
14
  }
15
+
16
+ // Extend User interface to include name field from Prisma model
17
+ declare module '@veloxts/auth' {
18
+ interface User {
19
+ name?: string;
20
+ }
21
+ }
@@ -238,7 +238,7 @@ export const authProcedures = procedures('auth', {
238
238
 
239
239
  return {
240
240
  id: user.id,
241
- name: (user.name as string) || '',
241
+ name: user.name ?? '',
242
242
  email: user.email,
243
243
  roles: Array.isArray(user.roles) ? user.roles : ['user'],
244
244
  };
@@ -26,7 +26,7 @@ declare module '@tanstack/react-router' {
26
26
 
27
27
  /* @if auth */
28
28
  // Dynamic headers for auth - fetches token on each request
29
- const getAuthHeaders = () => {
29
+ const getAuthHeaders = (): Record<string, string> => {
30
30
  const token = localStorage.getItem('token');
31
31
  return token ? { Authorization: `Bearer ${token}` } : {};
32
32
  };