@spfn/core 0.1.0-alpha.8 → 0.1.0-alpha.82

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/README.md +169 -195
  2. package/dist/auto-loader-JFaZ9gON.d.ts +80 -0
  3. package/dist/cache/index.d.ts +211 -0
  4. package/dist/cache/index.js +1013 -0
  5. package/dist/cache/index.js.map +1 -0
  6. package/dist/client/index.d.ts +131 -92
  7. package/dist/client/index.js +93 -85
  8. package/dist/client/index.js.map +1 -1
  9. package/dist/codegen/generators/index.d.ts +19 -0
  10. package/dist/codegen/generators/index.js +1521 -0
  11. package/dist/codegen/generators/index.js.map +1 -0
  12. package/dist/codegen/index.d.ts +76 -60
  13. package/dist/codegen/index.js +1506 -735
  14. package/dist/codegen/index.js.map +1 -1
  15. package/dist/database-errors-BNNmLTJE.d.ts +86 -0
  16. package/dist/db/index.d.ts +844 -44
  17. package/dist/db/index.js +1281 -1307
  18. package/dist/db/index.js.map +1 -1
  19. package/dist/env/index.d.ts +508 -0
  20. package/dist/env/index.js +1127 -0
  21. package/dist/env/index.js.map +1 -0
  22. package/dist/errors/index.d.ts +136 -0
  23. package/dist/errors/index.js +172 -0
  24. package/dist/errors/index.js.map +1 -0
  25. package/dist/index-DHiAqhKv.d.ts +101 -0
  26. package/dist/index.d.ts +3 -374
  27. package/dist/index.js +2424 -2178
  28. package/dist/index.js.map +1 -1
  29. package/dist/logger/index.d.ts +94 -0
  30. package/dist/logger/index.js +795 -0
  31. package/dist/logger/index.js.map +1 -0
  32. package/dist/middleware/index.d.ts +60 -0
  33. package/dist/middleware/index.js +918 -0
  34. package/dist/middleware/index.js.map +1 -0
  35. package/dist/route/index.d.ts +21 -53
  36. package/dist/route/index.js +1259 -219
  37. package/dist/route/index.js.map +1 -1
  38. package/dist/server/index.d.ts +18 -0
  39. package/dist/server/index.js +2419 -2059
  40. package/dist/server/index.js.map +1 -1
  41. package/dist/types/index.d.ts +121 -0
  42. package/dist/types/index.js +38 -0
  43. package/dist/types/index.js.map +1 -0
  44. package/dist/types-BXibIEyj.d.ts +60 -0
  45. package/package.json +67 -17
  46. package/dist/auto-loader-C44TcLmM.d.ts +0 -125
  47. package/dist/bind-pssq1NRT.d.ts +0 -34
  48. package/dist/postgres-errors-CY_Es8EJ.d.ts +0 -1703
  49. package/dist/scripts/index.d.ts +0 -24
  50. package/dist/scripts/index.js +0 -1201
  51. package/dist/scripts/index.js.map +0 -1
  52. package/dist/scripts/templates/api-index.template.txt +0 -10
  53. package/dist/scripts/templates/api-tag.template.txt +0 -11
  54. package/dist/scripts/templates/contract.template.txt +0 -87
  55. package/dist/scripts/templates/entity-type.template.txt +0 -31
  56. package/dist/scripts/templates/entity.template.txt +0 -19
  57. package/dist/scripts/templates/index.template.txt +0 -10
  58. package/dist/scripts/templates/repository.template.txt +0 -37
  59. package/dist/scripts/templates/routes-id.template.txt +0 -59
  60. package/dist/scripts/templates/routes-index.template.txt +0 -44
  61. package/dist/types-SlzTr8ZO.d.ts +0 -143
@@ -0,0 +1,121 @@
1
+ import * as _sinclair_typebox from '@sinclair/typebox';
2
+ import { TSchema } from '@sinclair/typebox';
3
+
4
+ /**
5
+ * Standard error response format
6
+ *
7
+ * Used by ErrorHandler middleware for all error responses.
8
+ * Compatible with ApiResponse pattern for consistent API responses.
9
+ */
10
+ interface ErrorResponse {
11
+ success: false;
12
+ error: {
13
+ message: string;
14
+ type: string;
15
+ statusCode: number;
16
+ stack?: string;
17
+ details?: any;
18
+ };
19
+ }
20
+ /**
21
+ * Success response wrapper
22
+ */
23
+ interface ApiSuccessResponse<T = any> {
24
+ success: true;
25
+ data: T;
26
+ meta?: {
27
+ timestamp?: string;
28
+ requestId?: string;
29
+ pagination?: {
30
+ page: number;
31
+ limit: number;
32
+ total: number;
33
+ totalPages: number;
34
+ };
35
+ [key: string]: any;
36
+ };
37
+ }
38
+ /**
39
+ * Error response type (alias for ErrorResponse)
40
+ */
41
+ type ApiErrorResponse = ErrorResponse;
42
+ /**
43
+ * Unified API response type
44
+ */
45
+ type ApiResponse<T = any> = ApiSuccessResponse<T> | ApiErrorResponse;
46
+ /**
47
+ * Creates a TypeBox schema for ApiSuccessResponse<T>
48
+ *
49
+ * @example
50
+ * ```ts
51
+ * const UserSchema = Type.Object({
52
+ * id: Type.String(),
53
+ * name: Type.String(),
54
+ * });
55
+ *
56
+ * const contract = {
57
+ * response: ApiSuccessSchema(UserSchema),
58
+ * };
59
+ * ```
60
+ */
61
+ declare function ApiSuccessSchema<T extends TSchema>(dataSchema: T): _sinclair_typebox.TObject<{
62
+ success: _sinclair_typebox.TLiteral<true>;
63
+ data: T;
64
+ meta: _sinclair_typebox.TOptional<_sinclair_typebox.TObject<{
65
+ timestamp: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
66
+ requestId: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
67
+ pagination: _sinclair_typebox.TOptional<_sinclair_typebox.TObject<{
68
+ page: _sinclair_typebox.TNumber;
69
+ limit: _sinclair_typebox.TNumber;
70
+ total: _sinclair_typebox.TNumber;
71
+ totalPages: _sinclair_typebox.TNumber;
72
+ }>>;
73
+ }>>;
74
+ }>;
75
+ /**
76
+ * Creates a TypeBox schema for ApiErrorResponse
77
+ */
78
+ declare function ApiErrorSchema(): _sinclair_typebox.TObject<{
79
+ success: _sinclair_typebox.TLiteral<false>;
80
+ error: _sinclair_typebox.TObject<{
81
+ message: _sinclair_typebox.TString;
82
+ type: _sinclair_typebox.TString;
83
+ statusCode: _sinclair_typebox.TNumber;
84
+ stack: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
85
+ details: _sinclair_typebox.TOptional<_sinclair_typebox.TAny>;
86
+ }>;
87
+ }>;
88
+ /**
89
+ * Creates a TypeBox schema for ApiSuccessResponse<T>
90
+ *
91
+ * Use this in your route contract's response field for standardized responses.
92
+ * Note: ContractClient throws ApiClientError on failure, so only success type is needed.
93
+ *
94
+ * @example
95
+ * ```ts
96
+ * const contract = {
97
+ * method: 'GET',
98
+ * path: '/users/:id',
99
+ * response: ApiResponseSchema(Type.Object({
100
+ * id: Type.String(),
101
+ * name: Type.String(),
102
+ * })),
103
+ * };
104
+ * ```
105
+ */
106
+ declare function ApiResponseSchema<T extends TSchema>(dataSchema: T): _sinclair_typebox.TObject<{
107
+ success: _sinclair_typebox.TLiteral<true>;
108
+ data: T;
109
+ meta: _sinclair_typebox.TOptional<_sinclair_typebox.TObject<{
110
+ timestamp: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
111
+ requestId: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
112
+ pagination: _sinclair_typebox.TOptional<_sinclair_typebox.TObject<{
113
+ page: _sinclair_typebox.TNumber;
114
+ limit: _sinclair_typebox.TNumber;
115
+ total: _sinclair_typebox.TNumber;
116
+ totalPages: _sinclair_typebox.TNumber;
117
+ }>>;
118
+ }>>;
119
+ }>;
120
+
121
+ export { type ApiErrorResponse, ApiErrorSchema, type ApiResponse, ApiResponseSchema, type ApiSuccessResponse, ApiSuccessSchema, type ErrorResponse };
@@ -0,0 +1,38 @@
1
+ import { Type } from '@sinclair/typebox';
2
+
3
+ // src/types/api-response.ts
4
+ function ApiSuccessSchema(dataSchema) {
5
+ return Type.Object({
6
+ success: Type.Literal(true),
7
+ data: dataSchema,
8
+ meta: Type.Optional(Type.Object({
9
+ timestamp: Type.Optional(Type.String()),
10
+ requestId: Type.Optional(Type.String()),
11
+ pagination: Type.Optional(Type.Object({
12
+ page: Type.Number(),
13
+ limit: Type.Number(),
14
+ total: Type.Number(),
15
+ totalPages: Type.Number()
16
+ }))
17
+ }))
18
+ });
19
+ }
20
+ function ApiErrorSchema() {
21
+ return Type.Object({
22
+ success: Type.Literal(false),
23
+ error: Type.Object({
24
+ message: Type.String(),
25
+ type: Type.String(),
26
+ statusCode: Type.Number(),
27
+ stack: Type.Optional(Type.String()),
28
+ details: Type.Optional(Type.Any())
29
+ })
30
+ });
31
+ }
32
+ function ApiResponseSchema(dataSchema) {
33
+ return ApiSuccessSchema(dataSchema);
34
+ }
35
+
36
+ export { ApiErrorSchema, ApiResponseSchema, ApiSuccessSchema };
37
+ //# sourceMappingURL=index.js.map
38
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/types/api-response.ts"],"names":[],"mappings":";;;AAiFO,SAAS,iBAAoC,UAAA,EACpD;AACI,EAAA,OAAO,KAAK,MAAA,CAAO;AAAA,IACf,OAAA,EAAS,IAAA,CAAK,OAAA,CAAQ,IAAI,CAAA;AAAA,IAC1B,IAAA,EAAM,UAAA;AAAA,IACN,IAAA,EAAM,IAAA,CAAK,QAAA,CAAS,IAAA,CAAK,MAAA,CAAO;AAAA,MAC5B,SAAA,EAAW,IAAA,CAAK,QAAA,CAAS,IAAA,CAAK,QAAQ,CAAA;AAAA,MACtC,SAAA,EAAW,IAAA,CAAK,QAAA,CAAS,IAAA,CAAK,QAAQ,CAAA;AAAA,MACtC,UAAA,EAAY,IAAA,CAAK,QAAA,CAAS,IAAA,CAAK,MAAA,CAAO;AAAA,QAClC,IAAA,EAAM,KAAK,MAAA,EAAO;AAAA,QAClB,KAAA,EAAO,KAAK,MAAA,EAAO;AAAA,QACnB,KAAA,EAAO,KAAK,MAAA,EAAO;AAAA,QACnB,UAAA,EAAY,KAAK,MAAA;AAAO,OAC3B,CAAC;AAAA,KACL,CAAC;AAAA,GACL,CAAA;AACL;AAKO,SAAS,cAAA,GAChB;AACI,EAAA,OAAO,KAAK,MAAA,CAAO;AAAA,IACf,OAAA,EAAS,IAAA,CAAK,OAAA,CAAQ,KAAK,CAAA;AAAA,IAC3B,KAAA,EAAO,KAAK,MAAA,CAAO;AAAA,MACf,OAAA,EAAS,KAAK,MAAA,EAAO;AAAA,MACrB,IAAA,EAAM,KAAK,MAAA,EAAO;AAAA,MAClB,UAAA,EAAY,KAAK,MAAA,EAAO;AAAA,MACxB,KAAA,EAAO,IAAA,CAAK,QAAA,CAAS,IAAA,CAAK,QAAQ,CAAA;AAAA,MAClC,OAAA,EAAS,IAAA,CAAK,QAAA,CAAS,IAAA,CAAK,KAAK;AAAA,KACpC;AAAA,GACJ,CAAA;AACL;AAoBO,SAAS,kBAAqC,UAAA,EACrD;AACI,EAAA,OAAO,iBAAiB,UAAU,CAAA;AACtC","file":"index.js","sourcesContent":["/**\n * Standard API Response Types & Schemas\n *\n * Pure TypeBox schemas and type definitions for API responses.\n * Can be used in both server and client code.\n */\n\nimport type { TSchema } from '@sinclair/typebox';\nimport { Type } from '@sinclair/typebox';\n\n// ============================================================================\n// Type Definitions\n// ============================================================================\n\n/**\n * Standard error response format\n *\n * Used by ErrorHandler middleware for all error responses.\n * Compatible with ApiResponse pattern for consistent API responses.\n */\nexport interface ErrorResponse\n{\n success: false;\n error: {\n message: string;\n type: string;\n statusCode: number;\n stack?: string;\n details?: any;\n };\n}\n\n/**\n * Success response wrapper\n */\nexport interface ApiSuccessResponse<T = any>\n{\n success: true;\n data: T;\n meta?: {\n timestamp?: string;\n requestId?: string;\n pagination?: {\n page: number;\n limit: number;\n total: number;\n totalPages: number;\n };\n [key: string]: any;\n };\n}\n\n/**\n * Error response type (alias for ErrorResponse)\n */\nexport type ApiErrorResponse = ErrorResponse;\n\n/**\n * Unified API response type\n */\nexport type ApiResponse<T = any> = ApiSuccessResponse<T> | ApiErrorResponse;\n\n// ============================================================================\n// TypeBox Schema Helpers\n// ============================================================================\n\n/**\n * Creates a TypeBox schema for ApiSuccessResponse<T>\n *\n * @example\n * ```ts\n * const UserSchema = Type.Object({\n * id: Type.String(),\n * name: Type.String(),\n * });\n *\n * const contract = {\n * response: ApiSuccessSchema(UserSchema),\n * };\n * ```\n */\nexport function ApiSuccessSchema<T extends TSchema>(dataSchema: T)\n{\n return Type.Object({\n success: Type.Literal(true),\n data: dataSchema,\n meta: Type.Optional(Type.Object({\n timestamp: Type.Optional(Type.String()),\n requestId: Type.Optional(Type.String()),\n pagination: Type.Optional(Type.Object({\n page: Type.Number(),\n limit: Type.Number(),\n total: Type.Number(),\n totalPages: Type.Number(),\n })),\n })),\n });\n}\n\n/**\n * Creates a TypeBox schema for ApiErrorResponse\n */\nexport function ApiErrorSchema()\n{\n return Type.Object({\n success: Type.Literal(false),\n error: Type.Object({\n message: Type.String(),\n type: Type.String(),\n statusCode: Type.Number(),\n stack: Type.Optional(Type.String()),\n details: Type.Optional(Type.Any()),\n }),\n });\n}\n\n/**\n * Creates a TypeBox schema for ApiSuccessResponse<T>\n *\n * Use this in your route contract's response field for standardized responses.\n * Note: ContractClient throws ApiClientError on failure, so only success type is needed.\n *\n * @example\n * ```ts\n * const contract = {\n * method: 'GET',\n * path: '/users/:id',\n * response: ApiResponseSchema(Type.Object({\n * id: Type.String(),\n * name: Type.String(),\n * })),\n * };\n * ```\n */\nexport function ApiResponseSchema<T extends TSchema>(dataSchema: T)\n{\n return ApiSuccessSchema(dataSchema);\n}\n"]}
@@ -0,0 +1,60 @@
1
+ import { Context } from 'hono';
2
+ import { ContentfulStatusCode } from 'hono/utils/http-status';
3
+ import { TSchema, Static } from '@sinclair/typebox';
4
+ import { ApiSuccessResponse } from './types/index.js';
5
+
6
+ /**
7
+ * File-based Routing System Type Definitions
8
+ */
9
+ type HeaderRecord = Record<string, string | string[]>;
10
+ type RouteMeta = {
11
+ public?: boolean;
12
+ skipMiddlewares?: string[];
13
+ tags?: string[];
14
+ description?: string;
15
+ deprecated?: boolean;
16
+ };
17
+ /**
18
+ * Route Contract: TypeBox-based type-safe route definition
19
+ *
20
+ * Defines the shape of request/response for a route endpoint
21
+ */
22
+ type RouteContract = {
23
+ method: HttpMethod;
24
+ path: string;
25
+ params?: TSchema;
26
+ query?: TSchema;
27
+ body?: TSchema;
28
+ response: TSchema;
29
+ meta?: RouteMeta;
30
+ };
31
+ /**
32
+ * Infer types from RouteContract
33
+ *
34
+ * Extracts TypeScript types from TypeBox schemas
35
+ */
36
+ type InferContract<TContract extends RouteContract> = {
37
+ params: TContract['params'] extends TSchema ? Static<TContract['params']> : Record<string, never>;
38
+ query: TContract['query'] extends TSchema ? Static<TContract['query']> : Record<string, never>;
39
+ body: TContract['body'] extends TSchema ? Static<TContract['body']> : Record<string, never>;
40
+ response: TContract['response'] extends TSchema ? Static<TContract['response']> : unknown;
41
+ };
42
+ /**
43
+ * RouteContext: Route Handler Dedicated Context
44
+ *
45
+ * Generic version with contract-based type inference
46
+ */
47
+ type RouteContext<TContract extends RouteContract = any> = {
48
+ params: InferContract<TContract>['params'];
49
+ query: InferContract<TContract>['query'];
50
+ data(): Promise<InferContract<TContract>['body']>;
51
+ json(data: InferContract<TContract>['response'], status?: ContentfulStatusCode, headers?: HeaderRecord): Response;
52
+ success<T>(data: T, meta?: ApiSuccessResponse<T>['meta'], status?: number): Response;
53
+ paginated<T>(data: T[], page: number, limit: number, total: number): Response;
54
+ raw: Context;
55
+ };
56
+ type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
57
+ type RouteHandler<TContract extends RouteContract = any> = (c: RouteContext<TContract>) => Response | Promise<Response>;
58
+ declare function isHttpMethod(value: unknown): value is HttpMethod;
59
+
60
+ export { type HttpMethod as H, type InferContract as I, type RouteContext as R, type RouteContract as a, type RouteHandler as b, type HeaderRecord as c, type RouteMeta as d, isHttpMethod as i };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@spfn/core",
3
- "version": "0.1.0-alpha.8",
3
+ "version": "0.1.0-alpha.82",
4
4
  "description": "SPFN Framework Core - File-based routing, transactions, repository pattern",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -31,15 +31,50 @@
31
31
  "import": "./dist/server/index.js",
32
32
  "require": "./dist/server/index.js"
33
33
  },
34
- "./scripts": {
35
- "types": "./dist/scripts/index.d.ts",
36
- "import": "./dist/scripts/index.js",
37
- "require": "./dist/scripts/index.js"
34
+ "./errors": {
35
+ "types": "./dist/errors/index.d.ts",
36
+ "import": "./dist/errors/index.js",
37
+ "require": "./dist/errors/index.js"
38
+ },
39
+ "./middleware": {
40
+ "types": "./dist/middleware/index.d.ts",
41
+ "import": "./dist/middleware/index.js",
42
+ "require": "./dist/middleware/index.js"
43
+ },
44
+ "./types": {
45
+ "types": "./dist/types/index.d.ts",
46
+ "import": "./dist/types/index.js",
47
+ "require": "./dist/types/index.js"
48
+ },
49
+ "./cache": {
50
+ "types": "./dist/cache/index.d.ts",
51
+ "import": "./dist/cache/index.js",
52
+ "require": "./dist/cache/index.js"
38
53
  },
39
54
  "./codegen": {
40
55
  "types": "./dist/codegen/index.d.ts",
41
56
  "import": "./dist/codegen/index.js",
42
57
  "require": "./dist/codegen/index.js"
58
+ },
59
+ "./env": {
60
+ "types": "./dist/env/index.d.ts",
61
+ "import": "./dist/env/index.js",
62
+ "require": "./dist/env/index.js"
63
+ },
64
+ "./logger": {
65
+ "types": "./dist/logger/index.d.ts",
66
+ "import": "./dist/logger/index.js",
67
+ "require": "./dist/logger/index.js"
68
+ },
69
+ "./generators": {
70
+ "types": "./dist/codegen/generators/index.d.ts",
71
+ "import": "./dist/codegen/generators/index.js",
72
+ "require": "./dist/codegen/generators/index.js"
73
+ },
74
+ "./codegen/generators": {
75
+ "types": "./dist/codegen/generators/index.d.ts",
76
+ "import": "./dist/codegen/generators/index.js",
77
+ "require": "./dist/codegen/generators/index.js"
43
78
  }
44
79
  },
45
80
  "keywords": [
@@ -86,21 +121,27 @@
86
121
  "chalk": "^5.6.2",
87
122
  "chokidar": "^4.0.3",
88
123
  "dotenv": "^17.2.3",
89
- "drizzle-orm": "^0.44.6",
124
+ "drizzle-orm": "^0.44.7",
90
125
  "drizzle-typebox": "^0.1.0",
91
126
  "hono": "^4.9.0",
127
+ "jiti": "^2.6.1",
128
+ "micromatch": "^4.0.8",
92
129
  "pino": "^10.0.0",
93
130
  "postgres": "^3.4.0",
94
131
  "typescript": "^5.3.3",
95
132
  "zod": "^4.1.11"
96
133
  },
97
134
  "optionalDependencies": {
98
- "ioredis": "^5.4.1"
135
+ "ioredis": "^5.4.1",
136
+ "pino-pretty": "^11.0.0"
99
137
  },
100
138
  "devDependencies": {
139
+ "@types/micromatch": "^4.0.9",
101
140
  "@types/node": "^20.11.0",
141
+ "@vitest/coverage-v8": "^4.0.6",
142
+ "drizzle-kit": "^0.31.5",
102
143
  "tsup": "^8.0.0",
103
- "vitest": "^3.2.4"
144
+ "vitest": "^4.0.6"
104
145
  },
105
146
  "files": [
106
147
  "dist",
@@ -114,15 +155,24 @@
114
155
  },
115
156
  "scripts": {
116
157
  "build": "tsup",
117
- "dev": "tsup --watch",
158
+ "dev": "tsup",
118
159
  "test": "vitest",
119
- "test:codegen": "vitest run --config vitest.codegen.config.ts",
120
- "test:db": "dotenv -e .env.test -- vitest src/tests/db",
121
- "docker:test:up": "docker compose -f ../../docker-compose.test.yml up -d",
122
- "docker:test:down": "docker compose -f ../../docker-compose.test.yml down",
123
- "docker:test:logs": "docker compose -f ../../docker-compose.test.yml logs -f",
124
- "type-check": "tsc --noEmit",
125
- "generate:client": "node dist/scripts/generate-client.js",
126
- "generate:client:watch": "node dist/scripts/generate-client.js --watch"
160
+ "test:unit": "vitest --config vitest.unit.config.ts",
161
+ "test:integration": "vitest --config vitest.integration.config.ts",
162
+ "test:coverage": "vitest run --config vitest.unit.config.ts --coverage",
163
+ "test:logger": "vitest src/logger",
164
+ "test:errors": "vitest src/errors",
165
+ "test:codegen": "vitest src/codegen",
166
+ "test:route": "vitest src/route",
167
+ "test:client": "vitest src/client",
168
+ "test:middleware": "vitest src/middleware",
169
+ "test:env": "vitest src/env",
170
+ "test:cache": "vitest src/cache --config vitest.integration.config.ts",
171
+ "test:db": "vitest src/db --config vitest.integration.config.ts",
172
+ "test:server": "vitest src/server --config vitest.integration.config.ts",
173
+ "docker:test:up": "docker compose -f docker-compose.test.yml up -d",
174
+ "docker:test:down": "docker compose -f docker-compose.test.yml down",
175
+ "docker:test:logs": "docker compose -f docker-compose.test.yml logs -f",
176
+ "type-check": "tsc --noEmit"
127
177
  }
128
178
  }
@@ -1,125 +0,0 @@
1
- import { Hono } from 'hono';
2
-
3
- /**
4
- * Extend Hono Context to support skipMiddlewares metadata
5
- */
6
- declare module 'hono' {
7
- interface ContextVariableMap {
8
- _skipMiddlewares?: string[];
9
- }
10
- }
11
- /**
12
- * AutoRouteLoader: Simplified File-based Routing System
13
- *
14
- * ## Features
15
- * - 📁 Auto-discovery: Scans routes directory and auto-registers
16
- * - 🔄 Dynamic routes: [id] → :id, [...slug] → *
17
- * - 📊 Statistics: Route registration stats for dashboard
18
- * - 🏷️ Grouping: Natural grouping by directory structure
19
- *
20
- * ## Usage
21
- * ```typescript
22
- * const app = new Hono();
23
- * await loadRoutes(app);
24
- * ```
25
- */
26
- type RouteInfo = {
27
- /** URL path (e.g., /users/:id) */
28
- path: string;
29
- /** File path relative to routes dir */
30
- file: string;
31
- /** Route metadata from export */
32
- meta?: {
33
- description?: string;
34
- tags?: string[];
35
- auth?: boolean;
36
- [key: string]: unknown;
37
- };
38
- /** Priority (1=static, 2=dynamic, 3=catch-all) */
39
- priority: number;
40
- };
41
- type RouteStats = {
42
- total: number;
43
- byPriority: {
44
- static: number;
45
- dynamic: number;
46
- catchAll: number;
47
- };
48
- byTag: Record<string, number>;
49
- routes: RouteInfo[];
50
- };
51
- declare class AutoRouteLoader {
52
- private routesDir;
53
- private routes;
54
- private registeredRoutes;
55
- private debug;
56
- private readonly middlewares;
57
- constructor(routesDir: string, debug?: boolean, middlewares?: Array<{
58
- name: string;
59
- handler: any;
60
- }>);
61
- /**
62
- * Load all routes from directory
63
- */
64
- load(app: Hono): Promise<RouteStats>;
65
- /**
66
- * Get route statistics
67
- */
68
- getStats(): RouteStats;
69
- /**
70
- * Recursively scan directory for .ts files
71
- */
72
- private scanFiles;
73
- /**
74
- * Check if file is a valid route file
75
- */
76
- private isValidRouteFile;
77
- /**
78
- * Load and register a single route
79
- * Returns true if successful, false if failed
80
- */
81
- private loadRoute;
82
- /**
83
- * Convert file path to URL path
84
- *
85
- * Examples:
86
- * - users/index.ts → /users
87
- * - users/[id].ts → /users/:id
88
- * - posts/[...slug].ts → /posts/*
89
- */
90
- private fileToPath;
91
- /**
92
- * Calculate route priority
93
- * 1 = static, 2 = dynamic, 3 = catch-all
94
- */
95
- private calculatePriority;
96
- /**
97
- * Normalize path for conflict detection
98
- *
99
- * Converts dynamic parameter names to generic placeholders:
100
- * - /users/:id → /users/:param
101
- * - /users/:userId → /users/:param (conflict!)
102
- * - /posts/* → /posts/* (unchanged)
103
- *
104
- * This allows detection of routes with different param names
105
- * that would match the same URL patterns.
106
- */
107
- private normalizePath;
108
- /**
109
- * Log statistics
110
- */
111
- private logStats;
112
- }
113
- /**
114
- * Load routes from default location (src/server/routes)
115
- */
116
- declare function loadRoutes(app: Hono, options?: {
117
- routesDir?: string;
118
- debug?: boolean;
119
- middlewares?: Array<{
120
- name: string;
121
- handler: any;
122
- }>;
123
- }): Promise<RouteStats>;
124
-
125
- export { AutoRouteLoader as A, type RouteInfo as R, type RouteStats as a, loadRoutes as l };
@@ -1,34 +0,0 @@
1
- import { Context } from 'hono';
2
- import { R as RouteContract, c as RouteContext } from './types-SlzTr8ZO.js';
3
-
4
- /**
5
- * Contract-based Route Handler Wrapper
6
- *
7
- * Binds a contract to a route handler, providing automatic validation
8
- * and type-safe context creation.
9
- *
10
- * ## Features
11
- * - ✅ Automatic params/query/body validation using TypeBox
12
- * - ✅ Type-safe RouteContext with contract-based inference
13
- * - ✅ Clean separation: bind() for validation, Hono for middleware
14
- *
15
- * ## Usage
16
- *
17
- * ```typescript
18
- * // Basic usage
19
- * export const GET = bind(contract, async (c) => {
20
- * return c.json({ data: 'public' });
21
- * });
22
- *
23
- * // For middleware, use Hono's app-level or route-level middleware:
24
- * // app.use('/api/*', authMiddleware);
25
- * // app.get('/users/:id', authMiddleware, bind(contract, handler));
26
- * ```
27
- *
28
- * @param contract - Route contract defining params, query, body, response schemas
29
- * @param handler - Route handler function
30
- * @returns Hono-compatible handler function
31
- */
32
- declare function bind<TContract extends RouteContract>(contract: TContract, handler: (c: RouteContext<TContract>) => Response | Promise<Response>): (rawContext: Context) => Promise<Response>;
33
-
34
- export { bind as b };