vitek-plugin 0.1.0-beta → 0.1.2-beta

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/README.md CHANGED
@@ -1,162 +1,36 @@
1
1
  <div align="center">
2
- <img src="./src/assets/logo.webp" alt="Vitek Plugin Logo" width="200" height="200" />
2
+ <img src="./docs/public/logo.webp" alt="Vitek Plugin Logo" width="200" height="200" />
3
3
 
4
4
  # Vitek Plugin
5
5
 
6
6
  **File-based HTTP API generation for Vite**
7
7
 
8
- [![Version](https://img.shields.io/badge/version-0.1.0--beta-orange.svg)](https://github.com/yourusername/vitek-plugin)
8
+ [![Version](https://img.shields.io/badge/version-0.1.1--beta-orange.svg)](https://github.com/martinsbicudo/vitek-plugin)
9
9
  [![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
10
10
  [![Vite](https://img.shields.io/badge/vite-^5.0.0-646CFF.svg)](https://vitejs.dev/)
11
11
 
12
- > ⚠️ **Beta Version**: This project is currently in beta/testing phase. APIs may change in future releases.
12
+ > **Beta Version**: This project is currently in beta. APIs may change in future releases.
13
13
  </div>
14
14
 
15
15
  ---
16
16
 
17
- ## 🎯 About the Name "Vitek"
17
+ Vitek is a Vite plugin that turns a folder of files into an HTTP API.
18
18
 
19
- **Vitek** is a portmanteau combining **"Vite"** (the build tool) and **"tek"** (a suffix suggesting technology/toolkit). The name reflects the plugin's core purpose: bringing powerful API generation capabilities to the Vite ecosystem.
19
+ **Note:** The API runs with the Vite **development server** (`npm run dev` / `pnpm dev`). For **production**, run `vite build` then **vitek-serve** (add `"start": "vitek-serve"` to your scripts and run `pnpm start`)—this serves both static assets and the API from one process. `vite preview` is for quick local preview of the static build only; for static + API use vitek-serve. Set `buildApi: false` if you do not want the API in build/production. Write endpoints as `[name].[method].ts` (or `.js`) under `src/api`, and get automatic routing, type generation, and typed client helpers.
20
20
 
21
- The "tek" suffix is commonly used in technology naming to denote tools and frameworks (similar to "kit" or "toolkit"), making "Vitek" a natural fit for a plugin that extends Vite's functionality with file-based API routing and type generation.
21
+ **Full documentation:** [docs/](./docs/) · [View online](https://martinsbicudo.github.io/vitek-plugin/) (VitePress run `npm run docs:dev` or `pnpm docs:dev` to view locally).
22
22
 
23
- ---
24
-
25
- ## 📖 Overview
26
-
27
- **Vitek** is a powerful Vite plugin that enables automatic file-based HTTP API generation. Write your API endpoints as simple TypeScript/JavaScript files, and Vitek handles all the configuration, type generation, and integration with the Vite development server.
28
-
29
- ### Why Vitek?
30
-
31
- - 🚀 **Zero Configuration**: Works out of the box with Vite - no separate server setup needed
32
- - 📁 **File-Based Routing**: Organize your API like your file system - intuitive and scalable
33
- - 🔥 **Hot Reload**: Automatic reloading of routes and middlewares on file changes
34
- - 💪 **Type-Safe**: Full TypeScript support with auto-generated types and client helpers
35
- - 🎯 **Developer Experience**: Generated client helpers for seamless frontend integration
36
- - 🏗️ **Modular Architecture**: Core logic is runtime-agnostic, ready for other environments
37
- - ⚡ **Lightweight**: Minimal overhead, runs directly in Vite's dev server
38
- - 🔄 **Unified Development**: Same server for frontend and backend during development
39
- - 📦 **No Dependencies**: Works with your existing Vite setup without additional runtime dependencies
23
+ **Examples:** [examples/](./examples/) — `basic-js`, `js-react`, `typescript-react`, and `docker`.
40
24
 
41
25
  ---
42
26
 
43
- ## 🆚 Vitek vs. Other Solutions
44
-
45
- ### Comparison with Framework-Specific Solutions
46
-
47
- #### **Next.js API Routes**
48
-
49
- - **Next.js**: Requires Next.js framework, tightly coupled to React ecosystem
50
- - **Vitek**: Framework-agnostic, works with any frontend (React, Vue, Svelte, vanilla JS)
51
- - **Vitek Advantage**: More flexible, lighter weight, not tied to a specific framework
52
-
53
- #### **SvelteKit API Routes**
54
-
55
- - **SvelteKit**: Requires SvelteKit framework, Svelte-specific
56
- - **Vitek**: Works with any frontend framework or no framework at all
57
- - **Vitek Advantage**: Universal solution, not limited to Svelte projects
58
-
59
- #### **Nuxt.js Server Routes**
60
-
61
- - **Nuxt.js**: Vue.js-specific, requires Nuxt framework
62
- - **Vitek**: Framework-independent, works with any stack
63
- - **Vitek Advantage**: More versatile, can be used in any Vite project
64
-
65
- ### Comparison with Standalone Backend Solutions
66
-
67
- #### **Express.js / Fastify**
68
-
69
- - **Express/Fastify**: Separate Node.js server, requires server setup and configuration
70
- - **Vitek**: Integrated with Vite dev server, no separate server needed
71
- - **Vitek Advantage**: Simpler setup, unified development environment, automatic hot reload
72
-
73
- #### **Hono**
74
-
75
- - **Hono**: Fast web framework, but still requires separate server setup
76
- - **Vitek**: File-based routing with automatic type generation, integrated with Vite
77
- - **Vitek Advantage**: Better DX with file-based routing, automatic client generation
78
-
79
- #### **tRPC**
80
-
81
- - **tRPC**: Type-safe RPC framework, requires separate server setup
82
- - **Vitek**: File-based REST API with automatic type generation, integrated with Vite
83
- - **Vitek Advantage**: Simpler setup, standard REST API, works with any HTTP client
84
-
85
- ### Comparison with Full-Stack Frameworks
86
-
87
- #### **Remix**
88
-
89
- - **Remix**: Full-stack React framework with server-side rendering
90
- - **Vitek**: Lightweight API layer, works with any frontend
91
- - **Vitek Advantage**: More flexible, lighter, not tied to React or SSR
92
-
93
- ### Why Choose Vitek?
94
-
95
- **Choose Vitek if you:**
96
-
97
- - ✅ Want to add API routes to an existing Vite project
98
- - ✅ Prefer file-based routing over manual route registration
99
- - ✅ Want automatic type generation for your API
100
- - ✅ Need a lightweight solution without framework lock-in
101
- - ✅ Want unified development (frontend + backend in one server)
102
- - ✅ Prefer REST APIs over RPC or GraphQL
103
- - ✅ Want zero configuration and minimal setup
104
-
105
- **Consider alternatives if you:**
106
-
107
- - Need server-side rendering (use Next.js, Remix, or SvelteKit)
108
- - Want GraphQL (use Apollo Server or similar)
109
- - Need advanced features like WebSockets out of the box (use Express/Fastify with Socket.io)
110
- - Are building a full-stack framework from scratch (use Hono, Express, or Fastify)
111
- - Need production-ready server features (use Express, Fastify, or Hono with proper setup)
112
-
113
- **Vitek's sweet spot**: Adding API routes to Vite projects with minimal configuration, automatic type safety, and excellent developer experience.
114
-
115
- ---
116
-
117
- ## ✨ Features
118
-
119
- - ✅ **File-based routing**: Automatic routes based on file structure
120
- - ✅ **Zero config**: Works automatically with the Vite server
121
- - ✅ **Hot reload**: Automatically reloads routes and middlewares on save
122
- - ✅ **Type-safe**: Automatically generates TypeScript types for all routes
123
- - ✅ **Client helpers**: Generates typed functions to call the API from the frontend
124
- - ✅ **Hierarchical middleware**: Middlewares per folder/subfolder
125
- - ✅ **All HTTP methods**: GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS
126
- - ✅ **Dynamic parameters**: Support for `[id]` and `[...ids]` (catch-all)
127
- - ✅ **Typed query params**: Define types for query parameters
128
- - ✅ **Typed body**: Define types for request body
129
- - ✅ **JavaScript support**: Works with both TypeScript and JavaScript projects
130
- - ✅ **Isolated core**: Modular architecture, ready for other runtimes
131
- - ✅ **Response control**: Custom status codes and headers via response helpers
132
- - ✅ **HTTP error classes**: Built-in error classes with automatic status code mapping
133
- - ✅ **Request validation**: Optional runtime validation for body and query parameters
134
- - ✅ **Enhanced logging**: Configurable log levels and request/response logging
135
-
136
- ---
137
-
138
- ## 📦 Installation
27
+ ## Quick Start
139
28
 
140
29
  ```bash
141
30
  npm install vitek-plugin
142
- # or
143
- pnpm add vitek-plugin
144
- # or
145
- yarn add vitek-plugin
146
31
  ```
147
32
 
148
- **Requirements:**
149
-
150
- - Vite ^5.0.0
151
- - Node.js 18+ (for development)
152
-
153
- ---
154
-
155
- ## ⚡ Quick Start
156
-
157
- ### 1. Configure the Plugin
158
-
159
- Add Vitek to your `vite.config.ts`:
33
+ **vite.config.ts:**
160
34
 
161
35
  ```typescript
162
36
  import { defineConfig } from "vite";
@@ -167,742 +41,24 @@ export default defineConfig({
167
41
  });
168
42
  ```
169
43
 
170
- ### 2. Create Your First Route
171
-
172
- Create `src/api/health.get.ts`:
173
-
174
- ```typescript
175
- import type { VitekContext } from "vitek-plugin";
176
-
177
- export default function handler(context: VitekContext) {
178
- return {
179
- status: "ok",
180
- timestamp: new Date().toISOString(),
181
- };
182
- }
183
- ```
184
-
185
- ### 3. Start the Development Server
186
-
187
- ```bash
188
- npm run dev
189
- ```
190
-
191
- Visit: `http://localhost:5173/api/health` 🎉
192
-
193
- ---
194
-
195
- ## 📁 File Structure
196
-
197
- ### Naming Convention
198
-
199
- Files follow the pattern: `[name].[method].ts` or `[name].[method].js`
200
-
201
- ```
202
- src/api/
203
- ├── middleware.ts # Global middleware (optional)
204
- ├── health.get.ts # GET /api/health
205
- ├── users/
206
- │ ├── middleware.ts # Middleware for /api/users/*
207
- │ ├── [id].get.ts # GET /api/users/:id
208
- │ ├── [id].put.ts # PUT /api/users/:id
209
- │ └── [id]/
210
- │ ├── middleware.ts # Middleware for /api/users/:id/*
211
- │ └── posts.get.ts # GET /api/users/:id/posts
212
- └── posts/
213
- ├── index.get.ts # GET /api/posts
214
- ├── index.post.ts # POST /api/posts
215
- ├── [id].get.ts # GET /api/posts/:id
216
- └── [...ids].get.ts # GET /api/posts/*ids (catch-all)
217
- ```
218
-
219
- ### Dynamic Parameters
220
-
221
- - **Single parameter**: `[id].get.ts` → `:id`
222
- - Example: `users/[id].get.ts` → `/api/users/:id`
223
- - **Catch-all**: `[...ids].get.ts` → `*ids`
224
- - Example: `posts/[...ids].get.ts` → `/api/posts/*ids`
225
- - Captures: `/api/posts/1/2/3` → `params.ids = "1/2/3"`
226
-
227
- ### Supported HTTP Methods
228
-
229
- All HTTP methods are supported through file extension:
230
-
231
- - `.get.ts` → GET
232
- - `.post.ts` → POST
233
- - `.put.ts` → PUT
234
- - `.patch.ts` → PATCH
235
- - `.delete.ts` → DELETE
236
- - `.head.ts` → HEAD
237
- - `.options.ts` → OPTIONS
238
-
239
- ---
240
-
241
- ## 🎯 Usage Examples
242
-
243
- ### Example 1: Simple GET Route
244
-
245
- ```typescript
246
- // src/api/health.get.ts
247
- import type { VitekContext } from "vitek-plugin";
248
-
249
- export default function handler(context: VitekContext) {
250
- return {
251
- status: "ok",
252
- timestamp: new Date().toISOString(),
253
- };
254
- }
255
- ```
256
-
257
- ### Example 2: Route with Dynamic Parameter
258
-
259
- ```typescript
260
- // src/api/users/[id].get.ts
261
- import type { VitekContext } from "vitek-plugin";
262
-
263
- export default async function handler(context: VitekContext) {
264
- const { params } = context;
265
-
266
- return {
267
- id: params.id,
268
- name: `User ${params.id}`,
269
- email: `user${params.id}@example.com`,
270
- };
271
- }
272
- ```
273
-
274
- ### Example 3: POST Route with Typed Body
275
-
276
- ```typescript
277
- // src/api/posts/index.post.ts
278
- import type { VitekContext } from "vitek-plugin";
279
-
280
- export type Body = {
281
- title: string;
282
- content: string;
283
- authorId: number;
284
- tags?: string[];
285
- };
286
-
287
- export default async function handler(context: VitekContext) {
288
- const { body } = context;
289
-
290
- return {
291
- message: "Post created",
292
- post: {
293
- id: Math.random(),
294
- ...body,
295
- createdAt: new Date().toISOString(),
296
- },
297
- };
298
- }
299
- ```
300
-
301
- ### Example 4: Route with Query Parameters
44
+ **src/api/health.get.ts:**
302
45
 
303
46
  ```typescript
304
- // src/api/posts/index.get.ts
305
47
  import type { VitekContext } from "vitek-plugin";
306
48
 
307
- export type Query = {
308
- limit?: number;
309
- offset?: number;
310
- };
311
-
312
- export default async function handler(context: VitekContext) {
313
- const { query } = context;
314
-
315
- const limit = query.limit ? Number(query.limit) : 10;
316
- const offset = query.offset ? Number(query.offset) : 0;
317
-
318
- return {
319
- posts: [],
320
- pagination: { limit, offset },
321
- };
322
- }
323
- ```
324
-
325
- ### Example 5: Complete Route (Params + Body + Query)
326
-
327
- ```typescript
328
- // src/api/posts/[id]/comments.post.ts
329
- import type { VitekContext } from "vitek-plugin";
330
-
331
- export type Body = {
332
- text: string;
333
- authorId: number;
334
- };
335
-
336
- export type Query = {
337
- notify?: boolean;
338
- sendEmail?: boolean;
339
- };
340
-
341
- export default async function handler(context: VitekContext) {
342
- const { params, body, query } = context;
343
-
344
- return {
345
- message: "Comment created",
346
- postId: params.id,
347
- comment: {
348
- id: Math.random(),
349
- ...body,
350
- postId: params.id,
351
- notify: query.notify || false,
352
- },
353
- };
354
- }
355
- ```
356
-
357
- ### Example 6: Catch-All Route
358
-
359
- ```typescript
360
- // src/api/posts/[...ids].get.ts
361
- import type { VitekContext } from "vitek-plugin";
362
-
363
- export default async function handler(context: VitekContext) {
364
- const { params } = context;
365
-
366
- // params.ids contains all segments: "1/2/3" for /api/posts/1/2/3
367
- const ids = params.ids.split("/");
368
-
369
- return {
370
- ids,
371
- message: "Multiple posts requested",
372
- };
373
- }
374
- ```
375
-
376
- ---
377
-
378
- ## 🔌 Middlewares
379
-
380
- ### Global Middleware
381
-
382
- Create `src/api/middleware.ts` to apply middlewares to all routes:
383
-
384
- ```typescript
385
- // src/api/middleware.ts
386
- import type { Middleware } from "vitek-plugin";
387
-
388
- export default [
389
- async (context, next) => {
390
- // Executes before the route
391
- console.log(`[Global] ${context.method} ${context.path}`);
392
-
393
- await next(); // Continues to next middleware/handler
394
-
395
- // Executes after the route
396
- console.log(`[Global] Completed ${context.path}`);
397
- },
398
- ] satisfies Middleware[];
399
- ```
400
-
401
- ### Hierarchical Middleware by Folder
402
-
403
- Middlewares are applied hierarchically based on folder structure:
404
-
405
- ```typescript
406
- // src/api/posts/middleware.ts
407
- // Applies to: /api/posts, /api/posts/:id, /api/posts/:id/comments, etc.
408
-
409
- import type { Middleware } from "vitek-plugin";
410
-
411
- export default [
412
- async (context, next) => {
413
- console.log(`[Posts Middleware] ${context.method} ${context.path}`);
414
- await next();
415
- },
416
- ] satisfies Middleware[];
417
- ```
418
-
419
- ```typescript
420
- // src/api/posts/[id]/middleware.ts
421
- // Applies to: /api/posts/:id/comments, but NOT /api/posts
422
-
423
- import type { Middleware } from "vitek-plugin";
424
-
425
- export default [
426
- async (context, next) => {
427
- // Validate post exists
428
- const postId = context.params.id;
429
- console.log(`[Post ID Middleware] Validating post ${postId}`);
430
- await next();
431
- },
432
- ] satisfies Middleware[];
433
- ```
434
-
435
- **Middleware execution order:**
436
-
437
- 1. Global middleware (`src/api/middleware.ts`)
438
- 2. Folder-specific middleware (e.g., `src/api/posts/middleware.ts`)
439
- 3. Nested folder middleware (e.g., `src/api/posts/[id]/middleware.ts`)
440
- 4. Route handler
441
-
442
- ---
443
-
444
- ## 🎯 Response Handling
445
-
446
- Vitek provides flexible response handling with support for custom status codes and headers.
447
-
448
- ### Basic Response (Backward Compatible)
449
-
450
- Returning a plain object automatically creates a 200 OK JSON response:
451
-
452
- ```typescript
453
- export default function handler(context: VitekContext) {
454
- return { message: "Success" }; // Status 200, JSON
455
- }
456
- ```
457
-
458
- ### Custom Status Codes and Headers
459
-
460
- Use response helpers for full control over HTTP responses:
461
-
462
- ```typescript
463
- import { created, notFound, json } from "vitek-plugin";
464
-
465
- export default function handler(context: VitekContext) {
466
- // 201 Created
467
- return created({ id: 123, message: "Resource created" });
468
-
469
- // 404 Not Found
470
- return notFound({ error: "Resource not found" });
471
-
472
- // Custom status and headers
473
- return json(
474
- { data: "custom" },
475
- {
476
- status: 201,
477
- headers: { "X-Custom-Header": "value" },
478
- }
479
- );
480
- }
481
- ```
482
-
483
- ### Available Response Helpers
484
-
485
- - `ok(body, headers?)` - 200 OK
486
- - `created(body, headers?)` - 201 Created
487
- - `noContent(headers?)` - 204 No Content
488
- - `badRequest(body, headers?)` - 400 Bad Request
489
- - `unauthorized(body, headers?)` - 401 Unauthorized
490
- - `forbidden(body, headers?)` - 403 Forbidden
491
- - `notFound(body, headers?)` - 404 Not Found
492
- - `conflict(body, headers?)` - 409 Conflict
493
- - `unprocessableEntity(body, headers?)` - 422 Validation Error
494
- - `tooManyRequests(body, headers?)` - 429 Too Many Requests
495
- - `internalServerError(body, headers?)` - 500 Internal Server Error
496
- - `redirect(url, permanent?, preserveMethod?)` - 301/302/307/308 Redirect
497
- - `json(body, options?)` - Custom JSON response with status and headers
498
-
499
- ---
500
-
501
- ## ⚠️ Error Handling
502
-
503
- Vitek provides HTTP error classes for better error handling with automatic status code mapping.
504
-
505
- ### HTTP Error Classes
506
-
507
- ```typescript
508
- import {
509
- BadRequestError,
510
- NotFoundError,
511
- UnauthorizedError,
512
- ValidationError,
513
- } from "vitek-plugin";
514
-
515
- export default function handler(context: VitekContext) {
516
- const { params } = context;
517
-
518
- if (!params.id) {
519
- throw new BadRequestError("ID is required"); // Returns 400
520
- }
521
-
522
- const resource = findResource(params.id);
523
- if (!resource) {
524
- throw new NotFoundError("Resource not found"); // Returns 404
525
- }
526
-
527
- // Validation errors with field details
528
- throw new ValidationError("Validation failed", {
529
- email: ["Invalid email format"],
530
- age: ["Must be 18 or older"],
531
- }); // Returns 422
532
- }
533
- ```
534
-
535
- ### Available Error Classes
536
-
537
- - `BadRequestError` - 400 Bad Request
538
- - `UnauthorizedError` - 401 Unauthorized
539
- - `ForbiddenError` - 403 Forbidden
540
- - `NotFoundError` - 404 Not Found
541
- - `ConflictError` - 409 Conflict
542
- - `ValidationError` - 422 Unprocessable Entity (with field errors)
543
- - `TooManyRequestsError` - 429 Too Many Requests
544
- - `InternalServerError` - 500 Internal Server Error
545
-
546
- All errors automatically return the appropriate HTTP status code and JSON error response.
547
-
548
- ---
549
-
550
- ## ✅ Request Validation
551
-
552
- Vitek provides optional runtime validation for request body and query parameters.
553
-
554
- ### Manual Validation
555
-
556
- Use validation helpers in your handlers:
557
-
558
- ```typescript
559
- import { validateBody, validateQuery, ValidationError } from "vitek-plugin";
560
- import type { ValidationSchema } from "vitek-plugin";
561
-
562
- export type Body = {
563
- title: string;
564
- content: string;
565
- authorId: number;
566
- };
567
-
568
- export default function handler(context: VitekContext) {
569
- // Validate body
570
- const body = validateBody(context.body, {
571
- title: { type: "string", required: true, min: 1, max: 200 },
572
- content: { type: "string", required: true, min: 10 },
573
- authorId: { type: "number", required: true, min: 1 },
574
- });
575
-
576
- // Validate query
577
- const query = validateQuery(context.query, {
578
- limit: { type: "number", min: 1, max: 100 },
579
- offset: { type: "number", min: 0 },
580
- });
581
-
582
- // If validation fails, ValidationError (422) is thrown automatically
583
- return { message: "Validated successfully", body, query };
584
- }
585
- ```
586
-
587
- ### Validation Rules
588
-
589
- ```typescript
590
- type ValidationRule = {
591
- type: "string" | "number" | "boolean" | "object" | "array";
592
- required?: boolean;
593
- min?: number; // For strings: min length, for numbers: min value, for arrays: min items
594
- max?: number; // For strings: max length, for numbers: max value, for arrays: max items
595
- pattern?: string | RegExp; // For strings: regex pattern
596
- custom?: (value: any) => boolean | string; // Custom validator
597
- };
598
- ```
599
-
600
- ### Validation Functions
601
-
602
- - `validate(data, schema)` - Returns validation result without throwing
603
- - `validateOrThrow(data, schema)` - Throws `ValidationError` if invalid
604
- - `validateBody(body, schema)` - Validates request body
605
- - `validateQuery(query, schema)` - Validates query parameters
606
-
607
- ---
608
-
609
- ## 📝 Type Generation
610
-
611
- Vitek automatically generates TypeScript types for all your routes.
612
-
613
- ### `src/api.types.ts`
614
-
615
- Contains all route types and parameter definitions:
616
-
617
- ```typescript
618
- // Auto-generated by Vitek - DO NOT EDIT
619
-
620
- export type VitekParams = Record<string, string>;
621
- export type VitekQuery = Record<string, string | string[]>;
622
-
623
- export interface UsersIdGetParams extends VitekParams {
624
- id: string;
49
+ export default function handler(_context: VitekContext) {
50
+ return { status: "ok", timestamp: new Date().toISOString() };
625
51
  }
626
-
627
- export type PostsPostBody = {
628
- title: string;
629
- content: string;
630
- authorId: number;
631
- tags?: string[];
632
- };
633
-
634
- export type PostsIndexGetQuery = {
635
- limit?: number;
636
- offset?: number;
637
- };
638
-
639
- // Union type with all routes
640
- export type VitekRoute =
641
- | { pattern: "users/:id"; method: "get"; params: UsersIdGetParams }
642
- | { pattern: "posts"; method: "post"; params: PostsPostBody };
643
- // ...
644
- ```
645
-
646
- ### `src/api.services.ts` (TypeScript) or `src/api.services.js` (JavaScript)
647
-
648
- Contains typed helper functions to call the API from the frontend:
649
-
650
- ```typescript
651
- import { getUsersById, postPosts, getPostsIdComments } from "./api.services";
652
-
653
- // GET /api/users/:id
654
- const user = await getUsersById({ id: "123" });
655
-
656
- // POST /api/posts (with body)
657
- const post = await postPosts({
658
- title: "Hello",
659
- content: "World",
660
- });
661
-
662
- // GET /api/posts/:id/comments (with params + query)
663
- const comments = await getPostsIdComments(
664
- { id: "123" }, // params
665
- { limit: 10, offset: 0 } // query
666
- );
667
- ```
668
-
669
- **Generated services features:**
670
-
671
- - ✅ Only necessary parameters are included (`params`, `body`, `query` only appear if defined)
672
- - ✅ Unique function names automatically generated
673
- - ✅ Complete types for autocomplete and type-checking (TypeScript projects)
674
- - ✅ Last parameter is always `options?: RequestInit` for fetch customization
675
-
676
- **Note:** For JavaScript projects, Vitek generates `api.services.js` without TypeScript types. For TypeScript projects, it generates both `api.types.ts` and `api.services.ts`.
677
-
678
- ---
679
-
680
- ## ⚙️ Configuration
681
-
682
- ### Plugin Options
683
-
684
- ```typescript
685
- import { vitek } from "vitek-plugin";
686
-
687
- export default defineConfig({
688
- plugins: [
689
- vitek({
690
- apiDir: "src/api", // API directory (default: 'src/api')
691
- apiBasePath: "/api", // API base path (default: '/api')
692
- enableValidation: false, // Enable automatic validation (default: false)
693
- logging: {
694
- level: "info", // Log level: 'debug' | 'info' | 'warn' | 'error'
695
- enableRequestLogging: false, // Log all requests/responses (default: false)
696
- enableRouteLogging: true, // Log route matches (default: true)
697
- },
698
- }),
699
- ],
700
- });
701
- ```
702
-
703
- ### Options
704
-
705
- | Option | Type | Default | Description |
706
- | ------------------------------ | ---------------------------------------- | ----------- | ------------------------------------------------------------------------------------------ |
707
- | `apiDir` | `string` | `'src/api'` | Directory where API route files are located |
708
- | `apiBasePath` | `string` | `'/api'` | Base path for all API routes |
709
- | `enableValidation` | `boolean` | `false` | Enable automatic request validation (currently manual validation is available via helpers) |
710
- | `logging` | `object` | `undefined` | Logging configuration |
711
- | `logging.level` | `'debug' \| 'info' \| 'warn' \| 'error'` | `'info'` | Minimum log level to display |
712
- | `logging.enableRequestLogging` | `boolean` | `false` | Log all HTTP requests with method, path, status code, and duration |
713
- | `logging.enableRouteLogging` | `boolean` | `true` | Log route matches when requests are handled |
714
-
715
- ---
716
-
717
- ## 📖 Examples
718
-
719
- This repository includes three complete examples demonstrating different use cases:
720
-
721
- ### [basic-js](./examples/basic-js/)
722
-
723
- **Pure JavaScript, no frameworks**
724
-
725
- - Minimal example with pure JavaScript
726
- - No TypeScript, no React
727
- - Simple HTML page with fetch API
728
- - Perfect for understanding the basics
729
-
730
- **When to use**: Start here if you want to learn the fundamentals without any framework overhead.
731
-
732
- ### [js-react](./examples/js-react/)
733
-
734
- **JavaScript with React (no TypeScript)**
735
-
736
- - React application in JavaScript
737
- - Uses generated services (without TypeScript types)
738
- - Demonstrates Vitek integration with React
739
- - Intermediate complexity
740
-
741
- **When to use**: Perfect for React projects that prefer JavaScript over TypeScript.
742
-
743
- ### [typescript-react](./examples/typescript-react/)
744
-
745
- **Complete TypeScript with React**
746
-
747
- - Full-featured example with TypeScript and React
748
- - Complete type-safety with generated types
749
- - Hierarchical middlewares
750
- - All HTTP methods and advanced features
751
- - Most comprehensive example
752
-
753
- **When to use**: Reference implementation showing all Vitek features with full type-safety.
754
-
755
- ---
756
-
757
- ## 🏗️ Architecture
758
-
759
- Vitek follows a modular architecture:
760
-
761
- - **Core**: Logic independent of Vite (reusable for other runtimes)
762
- - **Adapters**: Integration with different runtimes (currently Vite)
763
- - **Plugin**: Thin layer that registers the plugin in Vite
764
-
765
- This allows the core to be used in other contexts (standalone Node.js, other bundlers, etc).
766
-
767
- ```
768
- vitek-plugin/
769
- ├── src/
770
- │ ├── core/ # Runtime-agnostic core logic
771
- │ │ ├── context/ # Context creation
772
- │ │ ├── file-system/ # File scanning and watching
773
- │ │ ├── middleware/ # Middleware composition
774
- │ │ ├── normalize/ # Path normalization
775
- │ │ ├── routing/ # Route parsing and matching
776
- │ │ ├── types/ # Type generation
777
- │ │ └── validation/ # Request validation
778
- │ ├── adapters/ # Runtime-specific adapters
779
- │ │ └── vite/ # Vite integration
780
- │ ├── shared/ # Shared utilities
781
- │ │ ├── errors.ts # Error classes
782
- │ │ └── response-helpers.ts # Response helper functions
783
- │ └── plugin.ts # Vite plugin entry point
784
- ```
785
-
786
- ---
787
-
788
- ## 🔍 How It Works
789
-
790
- 1. **Scan**: The plugin scans `src/api` looking for route files and middlewares
791
- 2. **Loading**: Loads handlers and middlewares using Vite's module system
792
- 3. **Type Generation**: Analyzes files and automatically generates TypeScript types (for TS projects)
793
- 4. **Service Generation**: Creates typed helper functions for the frontend
794
- 5. **Integration**: Registers middleware in the Vite server to intercept `/api/*` requests
795
- 6. **Hot Reload**: Watches for file changes and automatically reloads
796
-
797
- ---
798
-
799
- ## 🛠️ Development
800
-
801
- ### Building the Plugin
802
-
803
- ```bash
804
- npm run build
805
- # or
806
- pnpm build
807
- ```
808
-
809
- ### Development Mode
810
-
811
- ```bash
812
- npm run dev
813
- # or
814
- pnpm dev
815
52
  ```
816
53
 
817
- This runs TypeScript compiler in watch mode.
818
-
819
- ---
820
-
821
- ## 🤝 Contributing
822
-
823
- To contribute, make sure to follow the steps below:
824
-
825
- 1. Create a new branch:
826
-
827
- ```shell
828
- git checkout -b feat/your-new-feature
829
- ```
830
-
831
- 2. Make your changes, add unit tests (if applicable) and test with `npm link`
832
-
833
- On vitek-plugin project:
834
-
835
- ```shell
836
- npm link
837
- ```
838
-
839
- On your app/project:
840
-
841
- ```shell
842
- npm link vitek-plugin
843
- ```
844
-
845
- This will create a symlink into your `node_modules` app, and you can test iteratively. You can check more about npm-link [here](https://docs.npmjs.com/cli/v9/commands/npm-link)
846
-
847
- 3. Before to push your changes to origin, open your pull request and fill all required fields.
848
- 1. Make sure to fill the **Release** section with what your pull request changes. **This section is required to merge pull request.**
849
- 4. Set a _required_ `semver` label according to your change:
850
- 1. `semver:patch`: used when you submit a fix to a bug, enhance performance, etc;
851
- 2. `semver:minor`: used when you submit a new component, new feature, etc;
852
- 3. `semver:major`: used when you submit some breaking change, etc;
853
- 4. `semver:prerelease`: used when you submit a prerelease (ex: `0.1.0-beta.1`);
854
- 5. `semver:bypass`: used to update docs, or something that doesn't affect the build.
855
-
856
- > Info: Once you have merged your pull request, with all required fields, GitHub Actions will be responsible to create a new build and publish.
54
+ Then `npm run dev` and open `http://localhost:5173/api/health`.
857
55
 
858
56
  ---
859
57
 
860
- ## 📄 License
861
-
862
- This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
58
+ ## Links
863
59
 
864
- **MIT License** means:
865
-
866
- - ✅ Free to use for personal and commercial projects
867
- - ✅ Free to modify
868
- - ✅ Free to distribute
869
- - ✅ Free to use privately
870
- - ✅ No warranty or liability
871
-
872
- ---
873
-
874
- ## ⚠️ Beta Status
875
-
876
- **This project is currently in beta/testing phase.**
877
-
878
- - Version: `0.1.0-beta`
879
- - APIs may change in future releases
880
- - Some features may be experimental
881
- - Feedback and bug reports are welcome!
882
-
883
- ---
884
-
885
- ## 🙏 Acknowledgments
886
-
887
- - Built with [Vite](https://vitejs.dev/)
888
- - Inspired by file-based routing patterns from Next.js and SvelteKit
889
- - Type generation powered by TypeScript
890
-
891
- ---
892
-
893
- ## 📞 Support
894
-
895
- - 🐛 **Found a bug?** [Open an issue](https://github.com/yourusername/vitek-plugin/issues)
896
- - 💡 **Have a suggestion?** [Open a discussion](https://github.com/yourusername/vitek-plugin/discussions)
897
- - 📖 **Need help?** Check the [examples](./examples/) directory
898
-
899
- ---
900
-
901
- <div align="center">
902
- <p>Made with ❤️ for the Vite community</p>
903
- <p>
904
- <a href="https://github.com/yourusername/vitek-plugin">GitHub</a> •
905
- <a href="https://npmjs.com/package/vitek-plugin">NPM</a> •
906
- <a href="LICENSE">License</a>
907
- </p>
908
- </div>
60
+ - [Documentation](./docs/) — [view online](https://martinsbicudo.github.io/vitek-plugin/) · guides, API reference, configuration, examples
61
+ - [Examples](./examples/) — basic-js, js-react, typescript-react, docker
62
+ - [GitHub](https://github.com/martinsbicudo/vitek-plugin)
63
+ - [NPM](https://www.npmjs.com/package/vitek-plugin)
64
+ - [License](LICENSE)