@spfn/core 0.1.0-alpha.81 → 0.1.0-alpha.83
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/dist/cache/index.js +6 -115
- package/dist/cache/index.js.map +1 -1
- package/dist/client/index.d.ts +2 -2
- package/dist/codegen/generators/index.js +6 -113
- package/dist/codegen/generators/index.js.map +1 -1
- package/dist/codegen/index.d.ts +2 -2
- package/dist/codegen/index.js +6 -113
- package/dist/codegen/index.js.map +1 -1
- package/dist/db/index.d.ts +1 -0
- package/dist/db/index.js +41 -114
- package/dist/db/index.js.map +1 -1
- package/dist/env/index.js +6 -113
- package/dist/env/index.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +160 -157
- package/dist/index.js.map +1 -1
- package/dist/logger/index.d.ts +90 -34
- package/dist/logger/index.js +7 -116
- package/dist/logger/index.js.map +1 -1
- package/dist/middleware/index.d.ts +29 -2
- package/dist/middleware/index.js +22 -117
- package/dist/middleware/index.js.map +1 -1
- package/dist/route/index.d.ts +3 -3
- package/dist/route/index.js +12 -131
- package/dist/route/index.js.map +1 -1
- package/dist/server/index.d.ts +110 -4
- package/dist/server/index.js +160 -157
- package/dist/server/index.js.map +1 -1
- package/dist/{types-DYueuoD6.d.ts → types/index.d.ts} +19 -60
- package/dist/types/index.js +38 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types-BXibIEyj.d.ts +60 -0
- package/package.json +7 -3
- package/dist/error-handler-wjLL3v-a.d.ts +0 -44
|
@@ -1,9 +1,22 @@
|
|
|
1
|
-
import { Context } from 'hono';
|
|
2
|
-
import { ContentfulStatusCode } from 'hono/utils/http-status';
|
|
3
1
|
import * as _sinclair_typebox from '@sinclair/typebox';
|
|
4
|
-
import { TSchema
|
|
5
|
-
import { b as ErrorResponse } from './error-handler-wjLL3v-a.js';
|
|
2
|
+
import { TSchema } from '@sinclair/typebox';
|
|
6
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
|
+
}
|
|
7
20
|
/**
|
|
8
21
|
* Success response wrapper
|
|
9
22
|
*/
|
|
@@ -23,7 +36,7 @@ interface ApiSuccessResponse<T = any> {
|
|
|
23
36
|
};
|
|
24
37
|
}
|
|
25
38
|
/**
|
|
26
|
-
* Error response type (
|
|
39
|
+
* Error response type (alias for ErrorResponse)
|
|
27
40
|
*/
|
|
28
41
|
type ApiErrorResponse = ErrorResponse;
|
|
29
42
|
/**
|
|
@@ -105,58 +118,4 @@ declare function ApiResponseSchema<T extends TSchema>(dataSchema: T): _sinclair_
|
|
|
105
118
|
}>>;
|
|
106
119
|
}>;
|
|
107
120
|
|
|
108
|
-
|
|
109
|
-
* File-based Routing System Type Definitions
|
|
110
|
-
*/
|
|
111
|
-
type HeaderRecord = Record<string, string | string[]>;
|
|
112
|
-
type RouteMeta = {
|
|
113
|
-
public?: boolean;
|
|
114
|
-
skipMiddlewares?: string[];
|
|
115
|
-
tags?: string[];
|
|
116
|
-
description?: string;
|
|
117
|
-
deprecated?: boolean;
|
|
118
|
-
};
|
|
119
|
-
/**
|
|
120
|
-
* Route Contract: TypeBox-based type-safe route definition
|
|
121
|
-
*
|
|
122
|
-
* Defines the shape of request/response for a route endpoint
|
|
123
|
-
*/
|
|
124
|
-
type RouteContract = {
|
|
125
|
-
method: HttpMethod;
|
|
126
|
-
path: string;
|
|
127
|
-
params?: TSchema;
|
|
128
|
-
query?: TSchema;
|
|
129
|
-
body?: TSchema;
|
|
130
|
-
response: TSchema;
|
|
131
|
-
meta?: RouteMeta;
|
|
132
|
-
};
|
|
133
|
-
/**
|
|
134
|
-
* Infer types from RouteContract
|
|
135
|
-
*
|
|
136
|
-
* Extracts TypeScript types from TypeBox schemas
|
|
137
|
-
*/
|
|
138
|
-
type InferContract<TContract extends RouteContract> = {
|
|
139
|
-
params: TContract['params'] extends TSchema ? Static<TContract['params']> : Record<string, never>;
|
|
140
|
-
query: TContract['query'] extends TSchema ? Static<TContract['query']> : Record<string, never>;
|
|
141
|
-
body: TContract['body'] extends TSchema ? Static<TContract['body']> : Record<string, never>;
|
|
142
|
-
response: TContract['response'] extends TSchema ? Static<TContract['response']> : unknown;
|
|
143
|
-
};
|
|
144
|
-
/**
|
|
145
|
-
* RouteContext: Route Handler Dedicated Context
|
|
146
|
-
*
|
|
147
|
-
* Generic version with contract-based type inference
|
|
148
|
-
*/
|
|
149
|
-
type RouteContext<TContract extends RouteContract = any> = {
|
|
150
|
-
params: InferContract<TContract>['params'];
|
|
151
|
-
query: InferContract<TContract>['query'];
|
|
152
|
-
data(): Promise<InferContract<TContract>['body']>;
|
|
153
|
-
json(data: InferContract<TContract>['response'], status?: ContentfulStatusCode, headers?: HeaderRecord): Response;
|
|
154
|
-
success<T>(data: T, meta?: ApiSuccessResponse<T>['meta'], status?: number): Response;
|
|
155
|
-
paginated<T>(data: T[], page: number, limit: number, total: number): Response;
|
|
156
|
-
raw: Context;
|
|
157
|
-
};
|
|
158
|
-
type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
|
|
159
|
-
type RouteHandler<TContract extends RouteContract = any> = (c: RouteContext<TContract>) => Response | Promise<Response>;
|
|
160
|
-
declare function isHttpMethod(value: unknown): value is HttpMethod;
|
|
161
|
-
|
|
162
|
-
export { ApiSuccessSchema as A, type HttpMethod as H, type InferContract as I, type RouteContext as R, type RouteContract as a, type RouteHandler as b, ApiErrorSchema as c, ApiResponseSchema as d, type ApiSuccessResponse as e, type ApiErrorResponse as f, type ApiResponse as g, type HeaderRecord as h, isHttpMethod as i, type RouteMeta as j };
|
|
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.
|
|
3
|
+
"version": "0.1.0-alpha.83",
|
|
4
4
|
"description": "SPFN Framework Core - File-based routing, transactions, repository pattern",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -41,6 +41,11 @@
|
|
|
41
41
|
"import": "./dist/middleware/index.js",
|
|
42
42
|
"require": "./dist/middleware/index.js"
|
|
43
43
|
},
|
|
44
|
+
"./types": {
|
|
45
|
+
"types": "./dist/types/index.d.ts",
|
|
46
|
+
"import": "./dist/types/index.js",
|
|
47
|
+
"require": "./dist/types/index.js"
|
|
48
|
+
},
|
|
44
49
|
"./cache": {
|
|
45
50
|
"types": "./dist/cache/index.d.ts",
|
|
46
51
|
"import": "./dist/cache/index.js",
|
|
@@ -116,12 +121,11 @@
|
|
|
116
121
|
"chalk": "^5.6.2",
|
|
117
122
|
"chokidar": "^4.0.3",
|
|
118
123
|
"dotenv": "^17.2.3",
|
|
119
|
-
"drizzle-orm": "^0.44.
|
|
124
|
+
"drizzle-orm": "^0.44.7",
|
|
120
125
|
"drizzle-typebox": "^0.1.0",
|
|
121
126
|
"hono": "^4.9.0",
|
|
122
127
|
"jiti": "^2.6.1",
|
|
123
128
|
"micromatch": "^4.0.8",
|
|
124
|
-
"pino": "^10.0.0",
|
|
125
129
|
"postgres": "^3.4.0",
|
|
126
130
|
"typescript": "^5.3.3",
|
|
127
131
|
"zod": "^4.1.11"
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import { Context } from 'hono';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Error Handler Middleware
|
|
5
|
-
*
|
|
6
|
-
* Generic middleware that converts errors with statusCode to HTTP responses
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
interface ErrorHandlerOptions {
|
|
10
|
-
/**
|
|
11
|
-
* Include stack trace in response
|
|
12
|
-
* @default process.env.NODE_ENV !== 'production'
|
|
13
|
-
*/
|
|
14
|
-
includeStack?: boolean;
|
|
15
|
-
/**
|
|
16
|
-
* Enable error logging
|
|
17
|
-
* @default true
|
|
18
|
-
*/
|
|
19
|
-
enableLogging?: boolean;
|
|
20
|
-
}
|
|
21
|
-
/**
|
|
22
|
-
* Standard error response format
|
|
23
|
-
*
|
|
24
|
-
* Used by ErrorHandler middleware for all error responses.
|
|
25
|
-
* Compatible with ApiResponse pattern for consistent API responses.
|
|
26
|
-
*/
|
|
27
|
-
interface ErrorResponse {
|
|
28
|
-
success: false;
|
|
29
|
-
error: {
|
|
30
|
-
message: string;
|
|
31
|
-
type: string;
|
|
32
|
-
statusCode: number;
|
|
33
|
-
stack?: string;
|
|
34
|
-
details?: any;
|
|
35
|
-
};
|
|
36
|
-
}
|
|
37
|
-
/**
|
|
38
|
-
* Error handler middleware
|
|
39
|
-
*
|
|
40
|
-
* Used in Hono's onError hook
|
|
41
|
-
*/
|
|
42
|
-
declare function ErrorHandler(options?: ErrorHandlerOptions): (err: Error, c: Context) => Response | Promise<Response>;
|
|
43
|
-
|
|
44
|
-
export { ErrorHandler as E, type ErrorHandlerOptions as a, type ErrorResponse as b };
|