create-velox-app 0.4.6 → 0.4.7

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.
@@ -58,6 +58,10 @@ export declare const CONDITIONALS: {
58
58
  readonly AUTH_END: "/* @endif auth */";
59
59
  readonly DEFAULT_START: "/* @if default */";
60
60
  readonly DEFAULT_END: "/* @endif default */";
61
+ readonly JSX_AUTH_START: "{/* @if auth */}";
62
+ readonly JSX_AUTH_END: "{/* @endif auth */}";
63
+ readonly JSX_DEFAULT_START: "{/* @if default */}";
64
+ readonly JSX_DEFAULT_END: "{/* @endif default */}";
61
65
  };
62
66
  /**
63
67
  * Process conditional blocks in template content.
@@ -1 +1 @@
1
- {"version":3,"file":"placeholders.d.ts","sourceRoot":"","sources":["../../src/templates/placeholders.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAMjD;;;GAGG;AACH,eAAO,MAAM,YAAY;IACvB,kDAAkD;;IAElD,+CAA+C;;IAE/C,wCAAwC;;IAExC,wDAAwD;;IAExD,sCAAsC;;IAEtC,0CAA0C;;CAElC,CAAC;AAEX;;;;GAIG;AACH,eAAO,MAAM,cAAc,EAAE,cAK5B,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,WAAW,EAAE,cAKzB,CAAC;AAaF;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,GAAG,MAAM,CAgBjF;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,MAAM,EAAE,cAAc,GACrB,MAAM,CAGR;AAaD;;;GAGG;AACH,eAAO,MAAM,YAAY;;;;;CAKf,CAAC;AAcX;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,cAAc,CAAC,UAAU,CAAC,GACnC,MAAM,CAwBR"}
1
+ {"version":3,"file":"placeholders.d.ts","sourceRoot":"","sources":["../../src/templates/placeholders.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAMjD;;;GAGG;AACH,eAAO,MAAM,YAAY;IACvB,kDAAkD;;IAElD,+CAA+C;;IAE/C,wCAAwC;;IAExC,wDAAwD;;IAExD,sCAAsC;;IAEtC,0CAA0C;;CAElC,CAAC;AAEX;;;;GAIG;AACH,eAAO,MAAM,cAAc,EAAE,cAK5B,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,WAAW,EAAE,cAKzB,CAAC;AAaF;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,GAAG,MAAM,CAgBjF;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,MAAM,EAAE,cAAc,GACrB,MAAM,CAGR;AAaD;;;GAGG;AACH,eAAO,MAAM,YAAY;;;;;;;;;CAUf,CAAC;AA0BX;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,cAAc,CAAC,UAAU,CAAC,GACnC,MAAM,CA8BR"}
@@ -106,11 +106,20 @@ export const CONDITIONALS = {
106
106
  AUTH_END: '/* @endif auth */',
107
107
  DEFAULT_START: '/* @if default */',
108
108
  DEFAULT_END: '/* @endif default */',
109
+ // JSX-style conditionals (wrapped in braces)
110
+ JSX_AUTH_START: '{/* @if auth */}',
111
+ JSX_AUTH_END: '{/* @endif auth */}',
112
+ JSX_DEFAULT_START: '{/* @if default */}',
113
+ JSX_DEFAULT_END: '{/* @endif default */}',
109
114
  };
110
115
  /** Pre-compiled regex for auth conditional blocks (performance optimization) */
111
116
  const AUTH_BLOCK_PATTERN = new RegExp(`${escapeRegex(CONDITIONALS.AUTH_START)}[\\s\\S]*?${escapeRegex(CONDITIONALS.AUTH_END)}`, 'g');
112
117
  /** Pre-compiled regex for default conditional blocks (performance optimization) */
113
118
  const DEFAULT_BLOCK_PATTERN = new RegExp(`${escapeRegex(CONDITIONALS.DEFAULT_START)}[\\s\\S]*?${escapeRegex(CONDITIONALS.DEFAULT_END)}`, 'g');
119
+ /** Pre-compiled regex for JSX auth conditional blocks */
120
+ const JSX_AUTH_BLOCK_PATTERN = new RegExp(`${escapeRegex(CONDITIONALS.JSX_AUTH_START)}[\\s\\S]*?${escapeRegex(CONDITIONALS.JSX_AUTH_END)}`, 'g');
121
+ /** Pre-compiled regex for JSX default conditional blocks */
122
+ const JSX_DEFAULT_BLOCK_PATTERN = new RegExp(`${escapeRegex(CONDITIONALS.JSX_DEFAULT_START)}[\\s\\S]*?${escapeRegex(CONDITIONALS.JSX_DEFAULT_END)}`, 'g');
114
123
  /**
115
124
  * Process conditional blocks in template content.
116
125
  *
@@ -120,25 +129,31 @@ const DEFAULT_BLOCK_PATTERN = new RegExp(`${escapeRegex(CONDITIONALS.DEFAULT_STA
120
129
  */
121
130
  export function processConditionals(content, template) {
122
131
  let result = content;
123
- // Process auth conditionals
132
+ // Process auth conditionals (both JS and JSX style)
124
133
  if (template === 'auth') {
125
134
  // Keep auth content but remove markers
126
135
  result = result.replaceAll(CONDITIONALS.AUTH_START, '');
127
136
  result = result.replaceAll(CONDITIONALS.AUTH_END, '');
137
+ result = result.replaceAll(CONDITIONALS.JSX_AUTH_START, '');
138
+ result = result.replaceAll(CONDITIONALS.JSX_AUTH_END, '');
128
139
  }
129
140
  else {
130
141
  // Remove entire auth blocks
131
142
  result = result.replace(AUTH_BLOCK_PATTERN, '');
143
+ result = result.replace(JSX_AUTH_BLOCK_PATTERN, '');
132
144
  }
133
- // Process default conditionals
145
+ // Process default conditionals (both JS and JSX style)
134
146
  if (template === 'default') {
135
147
  // Keep default content but remove markers
136
148
  result = result.replaceAll(CONDITIONALS.DEFAULT_START, '');
137
149
  result = result.replaceAll(CONDITIONALS.DEFAULT_END, '');
150
+ result = result.replaceAll(CONDITIONALS.JSX_DEFAULT_START, '');
151
+ result = result.replaceAll(CONDITIONALS.JSX_DEFAULT_END, '');
138
152
  }
139
153
  else {
140
154
  // Remove entire default blocks
141
155
  result = result.replace(DEFAULT_BLOCK_PATTERN, '');
156
+ result = result.replace(JSX_DEFAULT_BLOCK_PATTERN, '');
142
157
  }
143
158
  return result;
144
159
  }
@@ -1 +1 @@
1
- {"version":3,"file":"placeholders.js","sourceRoot":"","sources":["../../src/templates/placeholders.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"placeholders.js","sourceRoot":"","sources":["../../src/templates/placeholders.ts"],"names":[],"mappings":"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"}
@@ -9,10 +9,11 @@ export declare function generateWebTsConfig(): string;
9
9
  export declare function generateViteConfig(config: TemplateConfig): string;
10
10
  export declare function generateWebIndexHtml(config: TemplateConfig): string;
11
11
  export declare function generateFavicon(): string;
12
- export declare function generateMainTsx(): string;
13
- export declare function generateRootRoute(): string;
12
+ export declare function generateMainTsx(config: TemplateConfig): string;
13
+ export declare function generateRootRoute(config: TemplateConfig): string;
14
14
  export declare function generateDefaultIndexRoute(): string;
15
15
  export declare function generateAuthIndexRoute(): string;
16
16
  export declare function generateAboutRoute(): string;
17
+ export declare function generateUsersRoute(config: TemplateConfig): string;
17
18
  export declare function generateWebBaseFiles(config: TemplateConfig, isAuthTemplate: boolean): TemplateFile[];
18
19
  //# sourceMappingURL=web-base.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"web-base.d.ts","sourceRoot":"","sources":["../../../src/templates/shared/web-base.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAMhE,wBAAgB,sBAAsB,IAAI,MAAM,CAE/C;AAED,wBAAgB,mBAAmB,IAAI,MAAM,CAE5C;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CAEjE;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CAEnE;AAED,wBAAgB,eAAe,IAAI,MAAM,CAExC;AAED,wBAAgB,eAAe,IAAI,MAAM,CAExC;AAED,wBAAgB,iBAAiB,IAAI,MAAM,CAE1C;AAED,wBAAgB,yBAAyB,IAAI,MAAM,CAElD;AAED,wBAAgB,sBAAsB,IAAI,MAAM,CAE/C;AAED,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C;AAMD,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,cAAc,EACtB,cAAc,EAAE,OAAO,GACtB,YAAY,EAAE,CAoBhB"}
1
+ {"version":3,"file":"web-base.d.ts","sourceRoot":"","sources":["../../../src/templates/shared/web-base.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAMhE,wBAAgB,sBAAsB,IAAI,MAAM,CAE/C;AAED,wBAAgB,mBAAmB,IAAI,MAAM,CAE5C;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CAEjE;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CAEnE;AAED,wBAAgB,eAAe,IAAI,MAAM,CAExC;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CAE9D;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CAEhE;AAED,wBAAgB,yBAAyB,IAAI,MAAM,CAElD;AAED,wBAAgB,sBAAsB,IAAI,MAAM,CAE/C;AAED,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CAEjE;AAMD,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,cAAc,EACtB,cAAc,EAAE,OAAO,GACtB,YAAY,EAAE,CAqBhB"}
@@ -23,11 +23,11 @@ export function generateWebIndexHtml(config) {
23
23
  export function generateFavicon() {
24
24
  return compileTemplate('web/favicon.svg', DEFAULT_CONFIG);
25
25
  }
26
- export function generateMainTsx() {
27
- return compileTemplate('web/main.tsx', DEFAULT_CONFIG);
26
+ export function generateMainTsx(config) {
27
+ return compileTemplate('web/main.tsx', config);
28
28
  }
29
- export function generateRootRoute() {
30
- return compileTemplate('web/routes/__root.tsx', DEFAULT_CONFIG);
29
+ export function generateRootRoute(config) {
30
+ return compileTemplate('web/routes/__root.tsx', config);
31
31
  }
32
32
  export function generateDefaultIndexRoute() {
33
33
  return compileTemplate('web/routes/index.default.tsx', DEFAULT_CONFIG);
@@ -38,6 +38,9 @@ export function generateAuthIndexRoute() {
38
38
  export function generateAboutRoute() {
39
39
  return compileTemplate('web/routes/about.tsx', DEFAULT_CONFIG);
40
40
  }
41
+ export function generateUsersRoute(config) {
42
+ return compileTemplate('web/routes/users.tsx', config);
43
+ }
41
44
  // ============================================================================
42
45
  // Generate All Web Base Files
43
46
  // ============================================================================
@@ -50,13 +53,14 @@ export function generateWebBaseFiles(config, isAuthTemplate) {
50
53
  { path: 'apps/web/index.html', content: generateWebIndexHtml(config) },
51
54
  { path: 'apps/web/public/favicon.svg', content: generateFavicon() },
52
55
  // Entry point
53
- { path: 'apps/web/src/main.tsx', content: generateMainTsx() },
56
+ { path: 'apps/web/src/main.tsx', content: generateMainTsx(config) },
54
57
  // Routes
55
- { path: 'apps/web/src/routes/__root.tsx', content: generateRootRoute() },
58
+ { path: 'apps/web/src/routes/__root.tsx', content: generateRootRoute(config) },
56
59
  {
57
60
  path: 'apps/web/src/routes/index.tsx',
58
61
  content: isAuthTemplate ? generateAuthIndexRoute() : generateDefaultIndexRoute(),
59
62
  },
63
+ { path: 'apps/web/src/routes/users.tsx', content: generateUsersRoute(config) },
60
64
  { path: 'apps/web/src/routes/about.tsx', content: generateAboutRoute() },
61
65
  ];
62
66
  }
@@ -1 +1 @@
1
- {"version":3,"file":"web-base.js","sourceRoot":"","sources":["../../../src/templates/shared/web-base.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAGjE,+EAA+E;AAC/E,2BAA2B;AAC3B,+EAA+E;AAE/E,MAAM,UAAU,sBAAsB;IACpC,OAAO,eAAe,CAAC,kBAAkB,EAAE,cAAc,CAAC,CAAC;AAC7D,CAAC;AAED,MAAM,UAAU,mBAAmB;IACjC,OAAO,eAAe,CAAC,mBAAmB,EAAE,cAAc,CAAC,CAAC;AAC9D,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,MAAsB;IACvD,OAAO,eAAe,CAAC,oBAAoB,EAAE,MAAM,CAAC,CAAC;AACvD,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,MAAsB;IACzD,OAAO,eAAe,CAAC,gBAAgB,EAAE,MAAM,CAAC,CAAC;AACnD,CAAC;AAED,MAAM,UAAU,eAAe;IAC7B,OAAO,eAAe,CAAC,iBAAiB,EAAE,cAAc,CAAC,CAAC;AAC5D,CAAC;AAED,MAAM,UAAU,eAAe;IAC7B,OAAO,eAAe,CAAC,cAAc,EAAE,cAAc,CAAC,CAAC;AACzD,CAAC;AAED,MAAM,UAAU,iBAAiB;IAC/B,OAAO,eAAe,CAAC,uBAAuB,EAAE,cAAc,CAAC,CAAC;AAClE,CAAC;AAED,MAAM,UAAU,yBAAyB;IACvC,OAAO,eAAe,CAAC,8BAA8B,EAAE,cAAc,CAAC,CAAC;AACzE,CAAC;AAED,MAAM,UAAU,sBAAsB;IACpC,OAAO,eAAe,CAAC,2BAA2B,EAAE,WAAW,CAAC,CAAC;AACnE,CAAC;AAED,MAAM,UAAU,kBAAkB;IAChC,OAAO,eAAe,CAAC,sBAAsB,EAAE,cAAc,CAAC,CAAC;AACjE,CAAC;AAED,+EAA+E;AAC/E,8BAA8B;AAC9B,+EAA+E;AAE/E,MAAM,UAAU,oBAAoB,CAClC,MAAsB,EACtB,cAAuB;IAEvB,OAAO;QACL,eAAe;QACf,EAAE,IAAI,EAAE,uBAAuB,EAAE,OAAO,EAAE,sBAAsB,EAAE,EAAE;QACpE,EAAE,IAAI,EAAE,wBAAwB,EAAE,OAAO,EAAE,mBAAmB,EAAE,EAAE;QAClE,EAAE,IAAI,EAAE,yBAAyB,EAAE,OAAO,EAAE,kBAAkB,CAAC,MAAM,CAAC,EAAE;QACxE,EAAE,IAAI,EAAE,qBAAqB,EAAE,OAAO,EAAE,oBAAoB,CAAC,MAAM,CAAC,EAAE;QACtE,EAAE,IAAI,EAAE,6BAA6B,EAAE,OAAO,EAAE,eAAe,EAAE,EAAE;QAEnE,cAAc;QACd,EAAE,IAAI,EAAE,uBAAuB,EAAE,OAAO,EAAE,eAAe,EAAE,EAAE;QAE7D,SAAS;QACT,EAAE,IAAI,EAAE,gCAAgC,EAAE,OAAO,EAAE,iBAAiB,EAAE,EAAE;QACxE;YACE,IAAI,EAAE,+BAA+B;YACrC,OAAO,EAAE,cAAc,CAAC,CAAC,CAAC,sBAAsB,EAAE,CAAC,CAAC,CAAC,yBAAyB,EAAE;SACjF;QACD,EAAE,IAAI,EAAE,+BAA+B,EAAE,OAAO,EAAE,kBAAkB,EAAE,EAAE;KACzE,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"web-base.js","sourceRoot":"","sources":["../../../src/templates/shared/web-base.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAGjE,+EAA+E;AAC/E,2BAA2B;AAC3B,+EAA+E;AAE/E,MAAM,UAAU,sBAAsB;IACpC,OAAO,eAAe,CAAC,kBAAkB,EAAE,cAAc,CAAC,CAAC;AAC7D,CAAC;AAED,MAAM,UAAU,mBAAmB;IACjC,OAAO,eAAe,CAAC,mBAAmB,EAAE,cAAc,CAAC,CAAC;AAC9D,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,MAAsB;IACvD,OAAO,eAAe,CAAC,oBAAoB,EAAE,MAAM,CAAC,CAAC;AACvD,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,MAAsB;IACzD,OAAO,eAAe,CAAC,gBAAgB,EAAE,MAAM,CAAC,CAAC;AACnD,CAAC;AAED,MAAM,UAAU,eAAe;IAC7B,OAAO,eAAe,CAAC,iBAAiB,EAAE,cAAc,CAAC,CAAC;AAC5D,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,MAAsB;IACpD,OAAO,eAAe,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC;AACjD,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,MAAsB;IACtD,OAAO,eAAe,CAAC,uBAAuB,EAAE,MAAM,CAAC,CAAC;AAC1D,CAAC;AAED,MAAM,UAAU,yBAAyB;IACvC,OAAO,eAAe,CAAC,8BAA8B,EAAE,cAAc,CAAC,CAAC;AACzE,CAAC;AAED,MAAM,UAAU,sBAAsB;IACpC,OAAO,eAAe,CAAC,2BAA2B,EAAE,WAAW,CAAC,CAAC;AACnE,CAAC;AAED,MAAM,UAAU,kBAAkB;IAChC,OAAO,eAAe,CAAC,sBAAsB,EAAE,cAAc,CAAC,CAAC;AACjE,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,MAAsB;IACvD,OAAO,eAAe,CAAC,sBAAsB,EAAE,MAAM,CAAC,CAAC;AACzD,CAAC;AAED,+EAA+E;AAC/E,8BAA8B;AAC9B,+EAA+E;AAE/E,MAAM,UAAU,oBAAoB,CAClC,MAAsB,EACtB,cAAuB;IAEvB,OAAO;QACL,eAAe;QACf,EAAE,IAAI,EAAE,uBAAuB,EAAE,OAAO,EAAE,sBAAsB,EAAE,EAAE;QACpE,EAAE,IAAI,EAAE,wBAAwB,EAAE,OAAO,EAAE,mBAAmB,EAAE,EAAE;QAClE,EAAE,IAAI,EAAE,yBAAyB,EAAE,OAAO,EAAE,kBAAkB,CAAC,MAAM,CAAC,EAAE;QACxE,EAAE,IAAI,EAAE,qBAAqB,EAAE,OAAO,EAAE,oBAAoB,CAAC,MAAM,CAAC,EAAE;QACtE,EAAE,IAAI,EAAE,6BAA6B,EAAE,OAAO,EAAE,eAAe,EAAE,EAAE;QAEnE,cAAc;QACd,EAAE,IAAI,EAAE,uBAAuB,EAAE,OAAO,EAAE,eAAe,CAAC,MAAM,CAAC,EAAE;QAEnE,SAAS;QACT,EAAE,IAAI,EAAE,gCAAgC,EAAE,OAAO,EAAE,iBAAiB,CAAC,MAAM,CAAC,EAAE;QAC9E;YACE,IAAI,EAAE,+BAA+B;YACrC,OAAO,EAAE,cAAc,CAAC,CAAC,CAAC,sBAAsB,EAAE,CAAC,CAAC,CAAC,yBAAyB,EAAE;SACjF;QACD,EAAE,IAAI,EAAE,+BAA+B,EAAE,OAAO,EAAE,kBAAkB,CAAC,MAAM,CAAC,EAAE;QAC9E,EAAE,IAAI,EAAE,+BAA+B,EAAE,OAAO,EAAE,kBAAkB,EAAE,EAAE;KACzE,CAAC;AACJ,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-velox-app",
3
- "version": "0.4.6",
3
+ "version": "0.4.7",
4
4
  "description": "Project scaffolder for VeloxTS framework",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -25,7 +25,7 @@
25
25
  "picocolors": "1.1.1"
26
26
  },
27
27
  "devDependencies": {
28
- "@types/node": "24.10.1",
28
+ "@types/node": "25.0.0",
29
29
  "typescript": "5.9.3"
30
30
  },
31
31
  "keywords": [
@@ -12,6 +12,10 @@ import { authProcedures } from './procedures/auth.js';
12
12
  import { healthProcedures } from './procedures/health.js';
13
13
  import { userProcedures } from './procedures/users.js';
14
14
 
15
+ // Router type for frontend type safety
16
+ const router = { auth: authProcedures, health: healthProcedures, users: userProcedures };
17
+ export type AppRouter = typeof router;
18
+
15
19
  const app = await veloxApp({
16
20
  port: config.port,
17
21
  host: config.host,
@@ -10,6 +10,10 @@ import { prisma } from './config/database.js';
10
10
  import { healthProcedures } from './procedures/health.js';
11
11
  import { userProcedures } from './procedures/users.js';
12
12
 
13
+ // Router type for frontend type safety
14
+ const router = { health: healthProcedures, users: userProcedures };
15
+ export type AppRouter = typeof router;
16
+
13
17
  const app = await veloxApp({
14
18
  port: config.port,
15
19
  host: config.host,
@@ -23,6 +23,7 @@
23
23
  "bcrypt": "5.1.1",
24
24
  "better-sqlite3": "12.5.0",
25
25
  "dotenv": "17.2.3",
26
+ "file-uri-to-path": "2.0.0",
26
27
  "zod": "3.24.4"
27
28
  },
28
29
  "devDependencies": {
@@ -22,6 +22,7 @@
22
22
  "@veloxts/velox": "__VELOXTS_VERSION__",
23
23
  "better-sqlite3": "12.5.0",
24
24
  "dotenv": "17.2.3",
25
+ "file-uri-to-path": "2.0.0",
25
26
  "zod": "3.24.4"
26
27
  },
27
28
  "devDependencies": {
@@ -127,7 +127,7 @@ const DUMMY_HASH = '$2b$12$LQv3c1yqBWVHxkd0LHAkCOYz6TtxMQJqhN8/X4.uy7dPSSXB5G6Uy
127
127
  // ============================================================================
128
128
 
129
129
  export const authProcedures = defineProcedures('auth', {
130
- register: procedure()
130
+ createAccount: procedure()
131
131
  .rest({ method: 'POST', path: '/auth/register' })
132
132
  .use(rateLimiter.register())
133
133
  .input(RegisterInput)
@@ -165,7 +165,7 @@ export const authProcedures = defineProcedures('auth', {
165
165
  });
166
166
  }),
167
167
 
168
- login: procedure()
168
+ createSession: procedure()
169
169
  .rest({ method: 'POST', path: '/auth/login' })
170
170
  .use(
171
171
  rateLimiter.login((ctx) => {
@@ -198,7 +198,7 @@ export const authProcedures = defineProcedures('auth', {
198
198
  });
199
199
  }),
200
200
 
201
- refresh: procedure()
201
+ createRefresh: procedure()
202
202
  .rest({ method: 'POST', path: '/auth/refresh' })
203
203
  .use(rateLimiter.refresh())
204
204
  .input(RefreshInput)
@@ -247,7 +247,7 @@ export const authProcedures = defineProcedures('auth', {
247
247
  }
248
248
  }),
249
249
 
250
- logout: procedure()
250
+ deleteSession: procedure()
251
251
  .rest({ method: 'POST', path: '/auth/logout' })
252
252
  .guard(authenticated)
253
253
  .output(LogoutResponse)
@@ -4,8 +4,9 @@
4
4
  "compilerOptions": {
5
5
  "rootDir": "./src",
6
6
  "outDir": "./dist",
7
- "declaration": false,
8
- "declarationMap": false
7
+ "composite": true,
8
+ "declaration": true,
9
+ "declarationMap": true
9
10
  },
10
11
  "include": ["src/**/*"],
11
12
  "exclude": ["node_modules", "dist", "**/*.test.ts", "**/*.spec.ts"]
@@ -247,6 +247,54 @@
247
247
  margin-top: 0.5rem;
248
248
  }
249
249
 
250
+ /* Table */
251
+ .tableContainer {
252
+ background: #111;
253
+ border: 1px solid #222;
254
+ border-radius: 12px;
255
+ overflow: hidden;
256
+ }
257
+
258
+ .table {
259
+ width: 100%;
260
+ border-collapse: collapse;
261
+ }
262
+
263
+ .table th,
264
+ .table td {
265
+ padding: 1rem 1.5rem;
266
+ text-align: left;
267
+ }
268
+
269
+ .table th {
270
+ background: #0a0a0a;
271
+ color: #888;
272
+ font-weight: 600;
273
+ font-size: 0.85rem;
274
+ text-transform: uppercase;
275
+ letter-spacing: 0.05em;
276
+ border-bottom: 1px solid #222;
277
+ }
278
+
279
+ .table td {
280
+ color: #fff;
281
+ border-bottom: 1px solid #1a1a1a;
282
+ }
283
+
284
+ .table tbody tr:hover {
285
+ background: #1a1a1a;
286
+ }
287
+
288
+ .table tbody tr:last-child td {
289
+ border-bottom: none;
290
+ }
291
+
292
+ .emptyState {
293
+ text-align: center;
294
+ color: #666;
295
+ padding: 2rem !important;
296
+ }
297
+
250
298
  /* Responsive */
251
299
  @media (max-width: 768px) {
252
300
  .nav {
@@ -1,19 +1,12 @@
1
1
  import { StrictMode } from 'react';
2
2
  import { createRoot } from 'react-dom/client';
3
3
  import { RouterProvider, createRouter } from '@tanstack/react-router';
4
- import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
4
+ import { VeloxProvider } from '@veloxts/client/react';
5
5
  import { routeTree } from './routeTree.gen';
6
6
  import './styles/global.css';
7
7
 
8
- // Create query client for data fetching
9
- const queryClient = new QueryClient({
10
- defaultOptions: {
11
- queries: {
12
- staleTime: 1000 * 60, // 1 minute
13
- retry: 1,
14
- },
15
- },
16
- });
8
+ // Import router type from API for full type safety
9
+ import type { AppRouter } from '../../api/src/index.js';
17
10
 
18
11
  // Create router with route tree
19
12
  const router = createRouter({ routeTree });
@@ -25,14 +18,40 @@ declare module '@tanstack/react-router' {
25
18
  }
26
19
  }
27
20
 
21
+ /* @if auth */
22
+ // Dynamic headers for auth - fetches token on each request
23
+ const getAuthHeaders = () => {
24
+ const token = localStorage.getItem('token');
25
+ return token ? { Authorization: `Bearer ${token}` } : {};
26
+ };
27
+
28
+ // Route mappings for auth procedures with custom .rest() endpoints
29
+ const routes = {
30
+ auth: {
31
+ createAccount: '/auth/register',
32
+ createSession: '/auth/login',
33
+ createRefresh: '/auth/refresh',
34
+ deleteSession: '/auth/logout',
35
+ getMe: '/auth/me',
36
+ },
37
+ };
38
+ /* @endif auth */
39
+
28
40
  // Render application
29
41
  const rootElement = document.getElementById('root');
30
42
  if (!rootElement) throw new Error('Root element not found');
31
43
 
32
44
  createRoot(rootElement).render(
33
45
  <StrictMode>
34
- <QueryClientProvider client={queryClient}>
46
+ {/* @if default */}
47
+ <VeloxProvider<AppRouter> config={{ baseUrl: '/api' }}>
48
+ <RouterProvider router={router} />
49
+ </VeloxProvider>
50
+ {/* @endif default */}
51
+ {/* @if auth */}
52
+ <VeloxProvider<AppRouter> config={{ baseUrl: '/api', headers: getAuthHeaders, routes }}>
35
53
  <RouterProvider router={router} />
36
- </QueryClientProvider>
54
+ </VeloxProvider>
55
+ {/* @endif auth */}
37
56
  </StrictMode>
38
57
  );
@@ -10,17 +10,18 @@
10
10
  "type-check": "tsc --noEmit"
11
11
  },
12
12
  "dependencies": {
13
- "react": "19.1.0",
14
- "react-dom": "19.1.0",
15
- "@tanstack/react-router": "1.140.0",
16
- "@tanstack/react-query": "5.90.12"
13
+ "@tanstack/react-query": "5.90.12",
14
+ "@tanstack/react-router": "1.140.5",
15
+ "@veloxts/client": "__VELOXTS_VERSION__",
16
+ "react": "19.2.1",
17
+ "react-dom": "19.2.1"
17
18
  },
18
19
  "devDependencies": {
19
- "@types/react": "19.1.6",
20
- "@types/react-dom": "19.1.5",
20
+ "@types/react": "19.2.7",
21
+ "@types/react-dom": "19.2.3",
21
22
  "@vitejs/plugin-react": "5.1.2",
22
- "@tanstack/router-plugin": "1.140.0",
23
- "vite": "6.4.1",
23
+ "@tanstack/router-plugin": "1.140.5",
24
+ "vite": "7.2.7",
24
25
  "typescript": "5.9.3"
25
26
  }
26
27
  }
@@ -1,23 +1,44 @@
1
1
  import { createRootRoute, Outlet, Link } from '@tanstack/react-router';
2
2
  import styles from '@/App.module.css';
3
+ /* @if auth */
4
+ import { useQuery } from '@veloxts/client/react';
5
+ import type { AppRouter } from '../../../api/src/index.js';
6
+ /* @endif auth */
3
7
 
4
8
  export const Route = createRootRoute({
5
9
  component: RootLayout,
6
10
  });
7
11
 
8
12
  function RootLayout() {
13
+ /* @if auth */
14
+ const { data: user } = useQuery<AppRouter, 'auth', 'getMe'>('auth', 'getMe', {}, { retry: false });
15
+ const isAuthenticated = !!user;
16
+ /* @endif auth */
17
+
9
18
  return (
10
19
  <div className={styles.app}>
11
20
  <nav className={styles.nav}>
12
21
  <div className={styles.navBrand}>
13
22
  <Link to="/" className={styles.logo}>
14
- VeloxTS
23
+ Velox TS
15
24
  </Link>
16
25
  </div>
17
26
  <div className={styles.navLinks}>
18
27
  <Link to="/" className={styles.navLink} activeProps={{ className: styles.navLinkActive }}>
19
28
  Home
20
29
  </Link>
30
+ {/* @if default */}
31
+ <Link to="/users" className={styles.navLink} activeProps={{ className: styles.navLinkActive }}>
32
+ Users
33
+ </Link>
34
+ {/* @endif default */}
35
+ {/* @if auth */}
36
+ {isAuthenticated && (
37
+ <Link to="/users" className={styles.navLink} activeProps={{ className: styles.navLinkActive }}>
38
+ Users
39
+ </Link>
40
+ )}
41
+ {/* @endif auth */}
21
42
  <Link to="/about" className={styles.navLink} activeProps={{ className: styles.navLinkActive }}>
22
43
  About
23
44
  </Link>
@@ -1,49 +1,9 @@
1
1
  import { createFileRoute } from '@tanstack/react-router';
2
- import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
2
+ import { useQuery, useMutation, useQueryClient } from '@veloxts/client/react';
3
3
  import { useState } from 'react';
4
+ import type { AppRouter } from '../../../api/src/index.js';
4
5
  import styles from '@/App.module.css';
5
6
 
6
- // API helpers
7
- const api = {
8
- get: async <T,>(path: string): Promise<T> => {
9
- const token = localStorage.getItem('accessToken');
10
- const res = await fetch(`/api${path}`, {
11
- headers: token ? { Authorization: `Bearer ${token}` } : {},
12
- });
13
- if (!res.ok) throw new Error(`HTTP ${res.status}`);
14
- return res.json();
15
- },
16
- post: async <T,>(path: string, data: unknown): Promise<T> => {
17
- const token = localStorage.getItem('accessToken');
18
- const res = await fetch(`/api${path}`, {
19
- method: 'POST',
20
- headers: {
21
- 'Content-Type': 'application/json',
22
- ...(token ? { Authorization: `Bearer ${token}` } : {}),
23
- },
24
- body: JSON.stringify(data),
25
- });
26
- if (!res.ok) {
27
- const error = await res.json().catch(() => ({}));
28
- throw new Error(error.message || `HTTP ${res.status}`);
29
- }
30
- return res.json();
31
- },
32
- };
33
-
34
- interface User {
35
- id: string;
36
- name: string;
37
- email: string;
38
- roles?: string[];
39
- }
40
-
41
- interface AuthResponse {
42
- user: User;
43
- accessToken: string;
44
- refreshToken: string;
45
- }
46
-
47
7
  export const Route = createFileRoute('/')({
48
8
  component: HomePage,
49
9
  });
@@ -57,19 +17,18 @@ function HomePage() {
57
17
  const [error, setError] = useState('');
58
18
 
59
19
  // Check if user is logged in
60
- const { data: user, isLoading } = useQuery({
61
- queryKey: ['me'],
62
- queryFn: () => api.get<User>('/auth/me'),
63
- retry: false,
64
- });
20
+ const { data: user, isLoading } = useQuery<AppRouter, 'auth', 'getMe'>(
21
+ 'auth',
22
+ 'getMe',
23
+ {},
24
+ { retry: false }
25
+ );
65
26
 
66
- const login = useMutation({
67
- mutationFn: (data: { email: string; password: string }) =>
68
- api.post<AuthResponse>('/auth/login', data),
27
+ const login = useMutation<AppRouter, 'auth', 'createSession'>('auth', 'createSession', {
69
28
  onSuccess: (data) => {
70
- localStorage.setItem('accessToken', data.accessToken);
29
+ localStorage.setItem('token', data.accessToken);
71
30
  localStorage.setItem('refreshToken', data.refreshToken);
72
- queryClient.invalidateQueries({ queryKey: ['me'] });
31
+ queryClient.invalidateQueries({ queryKey: ['auth', 'getMe'] });
73
32
  setError('');
74
33
  },
75
34
  onError: (err) => {
@@ -77,13 +36,11 @@ function HomePage() {
77
36
  },
78
37
  });
79
38
 
80
- const register = useMutation({
81
- mutationFn: (data: { name: string; email: string; password: string }) =>
82
- api.post<AuthResponse>('/auth/register', data),
39
+ const register = useMutation<AppRouter, 'auth', 'createAccount'>('auth', 'createAccount', {
83
40
  onSuccess: (data) => {
84
- localStorage.setItem('accessToken', data.accessToken);
41
+ localStorage.setItem('token', data.accessToken);
85
42
  localStorage.setItem('refreshToken', data.refreshToken);
86
- queryClient.invalidateQueries({ queryKey: ['me'] });
43
+ queryClient.invalidateQueries({ queryKey: ['auth', 'getMe'] });
87
44
  setError('');
88
45
  },
89
46
  onError: (err) => {
@@ -91,12 +48,11 @@ function HomePage() {
91
48
  },
92
49
  });
93
50
 
94
- const logout = useMutation({
95
- mutationFn: () => api.post('/auth/logout', {}),
51
+ const logout = useMutation<AppRouter, 'auth', 'deleteSession'>('auth', 'deleteSession', {
96
52
  onSuccess: () => {
97
- localStorage.removeItem('accessToken');
53
+ localStorage.removeItem('token');
98
54
  localStorage.removeItem('refreshToken');
99
- queryClient.setQueryData(['me'], null);
55
+ queryClient.setQueryData(['auth', 'getMe'], null);
100
56
  },
101
57
  });
102
58
 
@@ -1,32 +1,18 @@
1
1
  import { createFileRoute } from '@tanstack/react-router';
2
- import { useQuery } from '@tanstack/react-query';
2
+ import { useQuery } from '@veloxts/client/react';
3
+ import type { AppRouter } from '../../../api/src/index.js';
3
4
  import styles from '@/App.module.css';
4
5
 
5
- // API helper
6
- const api = {
7
- get: async <T,>(path: string): Promise<T> => {
8
- const res = await fetch(`/api${path}`);
9
- if (!res.ok) throw new Error(`HTTP ${res.status}`);
10
- return res.json();
11
- },
12
- };
13
-
14
6
  export const Route = createFileRoute('/')({
15
7
  component: HomePage,
16
8
  });
17
9
 
18
- interface HealthResponse {
19
- status: string;
20
- version: string;
21
- timestamp: string;
22
- uptime: number;
23
- }
24
-
25
10
  function HomePage() {
26
- const { data: health, isLoading, error } = useQuery({
27
- queryKey: ['health'],
28
- queryFn: () => api.get<HealthResponse>('/health'),
29
- });
11
+ const { data: health, isLoading, error } = useQuery<AppRouter, 'health', 'check'>(
12
+ 'health',
13
+ 'check',
14
+ {}
15
+ );
30
16
 
31
17
  return (
32
18
  <div className={styles.container}>
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Users Page - Demonstrates type-safe data fetching with VeloxTS hooks
3
+ */
4
+
5
+ import { createFileRoute } from '@tanstack/react-router';
6
+ import { useQuery } from '@veloxts/client/react';
7
+ import type { AppRouter } from '../../../api/src/index.js';
8
+ import styles from '@/App.module.css';
9
+
10
+ export const Route = createFileRoute('/users')({
11
+ component: UsersPage,
12
+ });
13
+
14
+ function UsersPage() {
15
+ const { data, isLoading, error } = useQuery<AppRouter, 'users', 'listUsers'>(
16
+ 'users',
17
+ 'listUsers',
18
+ {}
19
+ );
20
+
21
+ return (
22
+ <div className={styles.container}>
23
+ <div className={styles.hero}>
24
+ <h1 className={styles.title}>Users</h1>
25
+ <p className={styles.subtitle}>
26
+ Type-safe data fetching with VeloxTS hooks
27
+ </p>
28
+ </div>
29
+
30
+ {isLoading ? (
31
+ <p className={styles.loading}>Loading users...</p>
32
+ ) : error ? (
33
+ <p className={styles.error}>Error: {error.message}</p>
34
+ ) : (
35
+ <div className={styles.tableContainer}>
36
+ <table className={styles.table}>
37
+ <thead>
38
+ <tr>
39
+ <th>Name</th>
40
+ <th>Email</th>
41
+ <th>Created</th>
42
+ </tr>
43
+ </thead>
44
+ <tbody>
45
+ {data?.data.map((user) => (
46
+ <tr key={user.id}>
47
+ <td>{user.name}</td>
48
+ <td>{user.email}</td>
49
+ <td>{new Date(user.createdAt).toLocaleDateString()}</td>
50
+ </tr>
51
+ ))}
52
+ {data?.data.length === 0 && (
53
+ <tr>
54
+ <td colSpan={3} className={styles.emptyState}>
55
+ No users found. Create one via the API!
56
+ </td>
57
+ </tr>
58
+ )}
59
+ </tbody>
60
+ </table>
61
+ {data && (
62
+ <p className={styles.meta}>
63
+ Page {data.meta.page} - {data.meta.total} total users
64
+ </p>
65
+ )}
66
+ </div>
67
+ )}
68
+ </div>
69
+ );
70
+ }
@@ -20,5 +20,6 @@
20
20
  "@/*": ["./src/*"]
21
21
  }
22
22
  },
23
- "include": ["src"]
23
+ "include": ["src"],
24
+ "references": [{ "path": "../api" }]
24
25
  }