@spfn/core 0.1.0-alpha.64 → 0.1.0-alpha.68

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 (37) hide show
  1. package/README.md +5 -5
  2. package/dist/{auto-loader-CdsxOceW.d.ts → auto-loader-JFaZ9gON.d.ts} +3 -2
  3. package/dist/cache/index.d.ts +211 -0
  4. package/dist/cache/index.js +992 -0
  5. package/dist/cache/index.js.map +1 -0
  6. package/dist/client/index.d.ts +2 -2
  7. package/dist/codegen/generators/index.d.ts +7 -6
  8. package/dist/codegen/generators/index.js +208 -27
  9. package/dist/codegen/generators/index.js.map +1 -1
  10. package/dist/codegen/index.d.ts +67 -118
  11. package/dist/codegen/index.js +1419 -1295
  12. package/dist/codegen/index.js.map +1 -1
  13. package/dist/database-errors-CoPrcOpq.d.ts +86 -0
  14. package/dist/db/index.d.ts +316 -9
  15. package/dist/db/index.js +6 -6
  16. package/dist/db/index.js.map +1 -1
  17. package/dist/error-handler-wjLL3v-a.d.ts +44 -0
  18. package/dist/errors/index.d.ts +119 -0
  19. package/dist/errors/index.js +160 -0
  20. package/dist/errors/index.js.map +1 -0
  21. package/dist/index-DHiAqhKv.d.ts +101 -0
  22. package/dist/index.d.ts +2 -228
  23. package/dist/index.js +274 -292
  24. package/dist/index.js.map +1 -1
  25. package/dist/middleware/index.d.ts +33 -0
  26. package/dist/middleware/index.js +890 -0
  27. package/dist/middleware/index.js.map +1 -0
  28. package/dist/route/index.d.ts +172 -7
  29. package/dist/route/index.js +209 -70
  30. package/dist/route/index.js.map +1 -1
  31. package/dist/server/index.js +267 -176
  32. package/dist/server/index.js.map +1 -1
  33. package/dist/{types-Bd8YsFSU.d.ts → types-CAON3Mmg.d.ts} +1 -1
  34. package/package.json +19 -2
  35. package/dist/bind-CSzshBtm.d.ts +0 -17
  36. package/dist/contract-generator-CqKsfsNE.d.ts +0 -52
  37. package/dist/postgres-errors-lw1aRUFe.d.ts +0 -397
@@ -0,0 +1,44 @@
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 };
@@ -0,0 +1,119 @@
1
+ import { D as DatabaseError } from '../database-errors-CoPrcOpq.js';
2
+ export { C as ConnectionError, a as ConstraintViolationError, b as DeadlockError, c as DuplicateEntryError, N as NotFoundError, Q as QueryError, T as TransactionError } from '../database-errors-CoPrcOpq.js';
3
+
4
+ /**
5
+ * HTTP Error Classes
6
+ *
7
+ * Standard HTTP error classes for API responses
8
+ * Covers common HTTP status codes beyond database errors
9
+ */
10
+ /**
11
+ * Base HTTP Error
12
+ *
13
+ * Base class for all HTTP-related errors
14
+ */
15
+ declare class HttpError<TDetails extends Record<string, unknown> = Record<string, unknown>> extends Error {
16
+ readonly statusCode: number;
17
+ readonly details?: TDetails;
18
+ readonly timestamp: Date;
19
+ constructor(message: string, statusCode: number, details?: TDetails);
20
+ /**
21
+ * Serialize error for API response
22
+ */
23
+ toJSON(): {
24
+ name: string;
25
+ message: string;
26
+ statusCode: number;
27
+ details: TDetails | undefined;
28
+ timestamp: string;
29
+ };
30
+ }
31
+ /**
32
+ * Bad Request Error (400)
33
+ *
34
+ * Generic bad request - malformed syntax, invalid parameters, etc.
35
+ */
36
+ declare class BadRequestError extends HttpError {
37
+ constructor(message?: string, details?: Record<string, any>);
38
+ }
39
+ /**
40
+ * Validation Error (400)
41
+ *
42
+ * Input validation failure (request params, query, body)
43
+ * Used by contract-based routing for automatic validation
44
+ */
45
+ declare class ValidationError extends HttpError {
46
+ constructor(message: string, details?: Record<string, any>);
47
+ }
48
+ /**
49
+ * Unauthorized Error (401)
50
+ *
51
+ * Authentication required or authentication failed
52
+ */
53
+ declare class UnauthorizedError extends HttpError {
54
+ constructor(message?: string, details?: Record<string, any>);
55
+ }
56
+ /**
57
+ * Forbidden Error (403)
58
+ *
59
+ * Authenticated but lacks permission to access resource
60
+ */
61
+ declare class ForbiddenError extends HttpError {
62
+ constructor(message?: string, details?: Record<string, any>);
63
+ }
64
+ /**
65
+ * Conflict Error (409)
66
+ *
67
+ * Generic conflict - resource state conflict, concurrent modification, etc.
68
+ * More general than DuplicateEntryError
69
+ */
70
+ declare class ConflictError extends HttpError {
71
+ constructor(message?: string, details?: Record<string, any>);
72
+ }
73
+ /**
74
+ * Too Many Requests Error (429)
75
+ *
76
+ * Rate limit exceeded
77
+ */
78
+ declare class TooManyRequestsError extends HttpError {
79
+ constructor(message?: string, retryAfter?: number, details?: Record<string, any>);
80
+ }
81
+ /**
82
+ * Internal Server Error (500)
83
+ *
84
+ * Generic server error when no specific error type applies
85
+ */
86
+ declare class InternalServerError extends HttpError {
87
+ constructor(message?: string, details?: Record<string, any>);
88
+ }
89
+ /**
90
+ * Service Unavailable Error (503)
91
+ *
92
+ * Service temporarily unavailable (maintenance, overload, etc.)
93
+ */
94
+ declare class ServiceUnavailableError extends HttpError {
95
+ constructor(message?: string, retryAfter?: number, details?: Record<string, any>);
96
+ }
97
+
98
+ /**
99
+ * Error Utility Functions
100
+ *
101
+ * Generic error type checking utilities
102
+ */
103
+
104
+ /**
105
+ * Check if error is a DatabaseError
106
+ */
107
+ declare function isDatabaseError(error: unknown): error is DatabaseError;
108
+ /**
109
+ * Check if error is an HttpError
110
+ */
111
+ declare function isHttpError(error: unknown): error is HttpError;
112
+ /**
113
+ * Check if error has a statusCode property
114
+ */
115
+ declare function hasStatusCode(error: unknown): error is {
116
+ statusCode: number;
117
+ };
118
+
119
+ export { BadRequestError, ConflictError, DatabaseError, ForbiddenError, HttpError, InternalServerError, ServiceUnavailableError, TooManyRequestsError, UnauthorizedError, ValidationError, hasStatusCode, isDatabaseError, isHttpError };
@@ -0,0 +1,160 @@
1
+ // src/errors/database-errors.ts
2
+ var DatabaseError = class extends Error {
3
+ statusCode;
4
+ details;
5
+ timestamp;
6
+ constructor(message, statusCode = 500, details) {
7
+ super(message);
8
+ this.name = "DatabaseError";
9
+ this.statusCode = statusCode;
10
+ this.details = details;
11
+ this.timestamp = /* @__PURE__ */ new Date();
12
+ Error.captureStackTrace(this, this.constructor);
13
+ }
14
+ /**
15
+ * Serialize error for API response
16
+ */
17
+ toJSON() {
18
+ return {
19
+ name: this.name,
20
+ message: this.message,
21
+ statusCode: this.statusCode,
22
+ details: this.details,
23
+ timestamp: this.timestamp.toISOString()
24
+ };
25
+ }
26
+ };
27
+ var ConnectionError = class extends DatabaseError {
28
+ constructor(message, details) {
29
+ super(message, 503, details);
30
+ this.name = "ConnectionError";
31
+ }
32
+ };
33
+ var QueryError = class extends DatabaseError {
34
+ constructor(message, statusCode = 500, details) {
35
+ super(message, statusCode, details);
36
+ this.name = "QueryError";
37
+ }
38
+ };
39
+ var NotFoundError = class extends QueryError {
40
+ constructor(resource, id) {
41
+ super(`${resource} with id ${id} not found`, 404, { resource, id });
42
+ this.name = "NotFoundError";
43
+ }
44
+ };
45
+ var ConstraintViolationError = class extends QueryError {
46
+ constructor(message, details) {
47
+ super(message, 400, details);
48
+ this.name = "ConstraintViolationError";
49
+ }
50
+ };
51
+ var TransactionError = class extends DatabaseError {
52
+ constructor(message, statusCode = 500, details) {
53
+ super(message, statusCode, details);
54
+ this.name = "TransactionError";
55
+ }
56
+ };
57
+ var DeadlockError = class extends TransactionError {
58
+ constructor(message, details) {
59
+ super(message, 409, details);
60
+ this.name = "DeadlockError";
61
+ }
62
+ };
63
+ var DuplicateEntryError = class extends QueryError {
64
+ constructor(field, value) {
65
+ super(`${field} '${value}' already exists`, 409, { field, value });
66
+ this.name = "DuplicateEntryError";
67
+ }
68
+ };
69
+
70
+ // src/errors/http-errors.ts
71
+ var HttpError = class extends Error {
72
+ statusCode;
73
+ details;
74
+ timestamp;
75
+ constructor(message, statusCode, details) {
76
+ super(message);
77
+ this.name = "HttpError";
78
+ this.statusCode = statusCode;
79
+ this.details = details;
80
+ this.timestamp = /* @__PURE__ */ new Date();
81
+ Error.captureStackTrace(this, this.constructor);
82
+ }
83
+ /**
84
+ * Serialize error for API response
85
+ */
86
+ toJSON() {
87
+ return {
88
+ name: this.name,
89
+ message: this.message,
90
+ statusCode: this.statusCode,
91
+ details: this.details,
92
+ timestamp: this.timestamp.toISOString()
93
+ };
94
+ }
95
+ };
96
+ var BadRequestError = class extends HttpError {
97
+ constructor(message = "Bad request", details) {
98
+ super(message, 400, details);
99
+ this.name = "BadRequestError";
100
+ }
101
+ };
102
+ var ValidationError = class extends HttpError {
103
+ constructor(message, details) {
104
+ super(message, 400, details);
105
+ this.name = "ValidationError";
106
+ }
107
+ };
108
+ var UnauthorizedError = class extends HttpError {
109
+ constructor(message = "Authentication required", details) {
110
+ super(message, 401, details);
111
+ this.name = "UnauthorizedError";
112
+ }
113
+ };
114
+ var ForbiddenError = class extends HttpError {
115
+ constructor(message = "Access forbidden", details) {
116
+ super(message, 403, details);
117
+ this.name = "ForbiddenError";
118
+ }
119
+ };
120
+ var ConflictError = class extends HttpError {
121
+ constructor(message = "Resource conflict", details) {
122
+ super(message, 409, details);
123
+ this.name = "ConflictError";
124
+ }
125
+ };
126
+ var TooManyRequestsError = class extends HttpError {
127
+ constructor(message = "Too many requests", retryAfter, details) {
128
+ const fullDetails = retryAfter ? { ...details, retryAfter } : details;
129
+ super(message, 429, fullDetails);
130
+ this.name = "TooManyRequestsError";
131
+ }
132
+ };
133
+ var InternalServerError = class extends HttpError {
134
+ constructor(message = "Internal server error", details) {
135
+ super(message, 500, details);
136
+ this.name = "InternalServerError";
137
+ }
138
+ };
139
+ var ServiceUnavailableError = class extends HttpError {
140
+ constructor(message = "Service unavailable", retryAfter, details) {
141
+ const fullDetails = retryAfter ? { ...details, retryAfter } : details;
142
+ super(message, 503, fullDetails);
143
+ this.name = "ServiceUnavailableError";
144
+ }
145
+ };
146
+
147
+ // src/errors/error-utils.ts
148
+ function isDatabaseError(error) {
149
+ return error instanceof DatabaseError;
150
+ }
151
+ function isHttpError(error) {
152
+ return error instanceof HttpError;
153
+ }
154
+ function hasStatusCode(error) {
155
+ return typeof error === "object" && error !== null && "statusCode" in error && typeof error.statusCode === "number";
156
+ }
157
+
158
+ export { BadRequestError, ConflictError, ConnectionError, ConstraintViolationError, DatabaseError, DeadlockError, DuplicateEntryError, ForbiddenError, HttpError, InternalServerError, NotFoundError, QueryError, ServiceUnavailableError, TooManyRequestsError, TransactionError, UnauthorizedError, ValidationError, hasStatusCode, isDatabaseError, isHttpError };
159
+ //# sourceMappingURL=index.js.map
160
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/errors/database-errors.ts","../../src/errors/http-errors.ts","../../src/errors/error-utils.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Database Error Classes\n *\n * Type-safe error handling with custom error class hierarchy\n * Mapped to HTTP status codes for API responses\n */\n\n/**\n * Base Database Error\n *\n * Base class for all database-related errors\n */\nexport class DatabaseError<TDetails extends Record<string, unknown> = Record<string, unknown>> extends Error\n{\n public readonly statusCode: number;\n public readonly details?: TDetails;\n public readonly timestamp: Date;\n\n constructor(\n message: string,\n statusCode: number = 500,\n details?: TDetails\n )\n {\n super(message);\n this.name = 'DatabaseError';\n this.statusCode = statusCode;\n this.details = details;\n this.timestamp = new Date();\n Error.captureStackTrace(this, this.constructor);\n }\n\n /**\n * Serialize error for API response\n */\n toJSON()\n {\n return {\n name: this.name,\n message: this.message,\n statusCode: this.statusCode,\n details: this.details,\n timestamp: this.timestamp.toISOString()\n };\n }\n}\n\n/**\n * Connection Error (503 Service Unavailable)\n *\n * Database connection failure, connection pool exhaustion, etc.\n */\nexport class ConnectionError extends DatabaseError\n{\n constructor(message: string, details?: Record<string, any>)\n {\n super(message, 503, details);\n this.name = 'ConnectionError';\n }\n}\n\n/**\n * Query Error (500 Internal Server Error)\n *\n * SQL query execution failure, syntax errors, etc.\n */\nexport class QueryError extends DatabaseError\n{\n constructor(message: string, statusCode: number = 500, details?: Record<string, any>)\n {\n super(message, statusCode, details);\n this.name = 'QueryError';\n }\n}\n\n/**\n * Not Found Error (404 Not Found)\n *\n * Requested resource does not exist\n */\nexport class NotFoundError extends QueryError\n{\n constructor(resource: string, id: string | number)\n {\n super(`${resource} with id ${id} not found`, 404, { resource, id });\n this.name = 'NotFoundError';\n }\n}\n\n/**\n * Constraint Violation Error (400 Bad Request)\n *\n * Database constraint violation (NOT NULL, CHECK, FOREIGN KEY, etc.)\n * This is different from HTTP ValidationError which validates request input\n */\nexport class ConstraintViolationError extends QueryError\n{\n constructor(message: string, details?: Record<string, any>)\n {\n super(message, 400, details);\n this.name = 'ConstraintViolationError';\n }\n}\n\n/**\n * Transaction Error (500 Internal Server Error)\n *\n * Transaction start/commit/rollback failure\n */\nexport class TransactionError extends DatabaseError\n{\n constructor(message: string, statusCode: number = 500, details?: Record<string, any>)\n {\n super(message, statusCode, details);\n this.name = 'TransactionError';\n }\n}\n\n/**\n * Deadlock Error (409 Conflict)\n *\n * Database deadlock detected\n */\nexport class DeadlockError extends TransactionError\n{\n constructor(message: string, details?: Record<string, any>)\n {\n super(message, 409, details);\n this.name = 'DeadlockError';\n }\n}\n\n/**\n * Duplicate Entry Error (409 Conflict)\n *\n * Unique constraint violation (e.g., duplicate email)\n */\nexport class DuplicateEntryError extends QueryError\n{\n constructor(field: string, value: string | number)\n {\n super(`${field} '${value}' already exists`, 409, { field, value });\n this.name = 'DuplicateEntryError';\n }\n}","/**\n * HTTP Error Classes\n *\n * Standard HTTP error classes for API responses\n * Covers common HTTP status codes beyond database errors\n */\n\n/**\n * Base HTTP Error\n *\n * Base class for all HTTP-related errors\n */\nexport class HttpError<TDetails extends Record<string, unknown> = Record<string, unknown>> extends Error\n{\n public readonly statusCode: number;\n public readonly details?: TDetails;\n public readonly timestamp: Date;\n\n constructor(\n message: string,\n statusCode: number,\n details?: TDetails\n )\n {\n super(message);\n this.name = 'HttpError';\n this.statusCode = statusCode;\n this.details = details;\n this.timestamp = new Date();\n Error.captureStackTrace(this, this.constructor);\n }\n\n /**\n * Serialize error for API response\n */\n toJSON()\n {\n return {\n name: this.name,\n message: this.message,\n statusCode: this.statusCode,\n details: this.details,\n timestamp: this.timestamp.toISOString()\n };\n }\n}\n\n/**\n * Bad Request Error (400)\n *\n * Generic bad request - malformed syntax, invalid parameters, etc.\n */\nexport class BadRequestError extends HttpError\n{\n constructor(message: string = 'Bad request', details?: Record<string, any>)\n {\n super(message, 400, details);\n this.name = 'BadRequestError';\n }\n}\n\n/**\n * Validation Error (400)\n *\n * Input validation failure (request params, query, body)\n * Used by contract-based routing for automatic validation\n */\nexport class ValidationError extends HttpError\n{\n constructor(message: string, details?: Record<string, any>)\n {\n super(message, 400, details);\n this.name = 'ValidationError';\n }\n}\n\n/**\n * Unauthorized Error (401)\n *\n * Authentication required or authentication failed\n */\nexport class UnauthorizedError extends HttpError\n{\n constructor(message: string = 'Authentication required', details?: Record<string, any>)\n {\n super(message, 401, details);\n this.name = 'UnauthorizedError';\n }\n}\n\n/**\n * Forbidden Error (403)\n *\n * Authenticated but lacks permission to access resource\n */\nexport class ForbiddenError extends HttpError\n{\n constructor(message: string = 'Access forbidden', details?: Record<string, any>)\n {\n super(message, 403, details);\n this.name = 'ForbiddenError';\n }\n}\n\n/**\n * Conflict Error (409)\n *\n * Generic conflict - resource state conflict, concurrent modification, etc.\n * More general than DuplicateEntryError\n */\nexport class ConflictError extends HttpError\n{\n constructor(message: string = 'Resource conflict', details?: Record<string, any>)\n {\n super(message, 409, details);\n this.name = 'ConflictError';\n }\n}\n\n/**\n * Too Many Requests Error (429)\n *\n * Rate limit exceeded\n */\nexport class TooManyRequestsError extends HttpError\n{\n constructor(\n message: string = 'Too many requests',\n retryAfter?: number,\n details?: Record<string, any>\n )\n {\n const fullDetails = retryAfter\n ? { ...details, retryAfter }\n : details;\n\n super(message, 429, fullDetails);\n this.name = 'TooManyRequestsError';\n }\n}\n\n/**\n * Internal Server Error (500)\n *\n * Generic server error when no specific error type applies\n */\nexport class InternalServerError extends HttpError\n{\n constructor(message: string = 'Internal server error', details?: Record<string, any>)\n {\n super(message, 500, details);\n this.name = 'InternalServerError';\n }\n}\n\n/**\n * Service Unavailable Error (503)\n *\n * Service temporarily unavailable (maintenance, overload, etc.)\n */\nexport class ServiceUnavailableError extends HttpError\n{\n constructor(\n message: string = 'Service unavailable',\n retryAfter?: number,\n details?: Record<string, any>\n )\n {\n const fullDetails = retryAfter\n ? { ...details, retryAfter }\n : details;\n\n super(message, 503, fullDetails);\n this.name = 'ServiceUnavailableError';\n }\n}","/**\n * Error Utility Functions\n *\n * Generic error type checking utilities\n */\n\nimport { DatabaseError } from './database-errors.js';\nimport { HttpError } from './http-errors.js';\n\n/**\n * Check if error is a DatabaseError\n */\nexport function isDatabaseError(error: unknown): error is DatabaseError\n{\n return error instanceof DatabaseError;\n}\n\n/**\n * Check if error is an HttpError\n */\nexport function isHttpError(error: unknown): error is HttpError\n{\n return error instanceof HttpError;\n}\n\n/**\n * Check if error has a statusCode property\n */\nexport function hasStatusCode(error: unknown): error is { statusCode: number }\n{\n return (\n typeof error === 'object' &&\n error !== null &&\n 'statusCode' in error &&\n typeof (error as any).statusCode === 'number'\n );\n}\n"]}
@@ -0,0 +1,101 @@
1
+ /**
2
+ * Generator Interface
3
+ *
4
+ * Defines the contract for code generators that can be orchestrated by the codegen system.
5
+ */
6
+ /**
7
+ * Generator execution trigger types
8
+ */
9
+ type GeneratorTrigger = 'watch' | 'manual' | 'build' | 'start';
10
+ interface GeneratorOptions {
11
+ /** Project root directory */
12
+ cwd: string;
13
+ /** Enable debug logging */
14
+ debug?: boolean;
15
+ /** Execution trigger information */
16
+ trigger?: {
17
+ /** How the generator was triggered */
18
+ type: GeneratorTrigger;
19
+ /** Changed file information (only for 'watch' trigger) */
20
+ changedFile?: {
21
+ path: string;
22
+ event: 'add' | 'change' | 'unlink';
23
+ };
24
+ };
25
+ /** Custom configuration options */
26
+ [key: string]: any;
27
+ }
28
+ interface Generator {
29
+ /** Unique generator name */
30
+ name: string;
31
+ /** File patterns to watch (glob patterns) */
32
+ watchPatterns: string[];
33
+ /**
34
+ * When this generator should run
35
+ *
36
+ * @default ['watch', 'manual', 'build']
37
+ *
38
+ * Examples:
39
+ * - ['watch', 'build']: Run during development and build (e.g., admin-nav-generator)
40
+ * - ['build', 'start']: Run during build and server start (e.g., db-migration)
41
+ * - ['watch', 'manual']: Run during development and manual CLI (e.g., contract-generator)
42
+ * - ['start']: Run only on server start (e.g., runtime config generator)
43
+ */
44
+ runOn?: GeneratorTrigger[];
45
+ /**
46
+ * Generate code
47
+ *
48
+ * Generator can implement incremental updates by checking `options.trigger.changedFile`.
49
+ * If incremental update is not possible, do full regeneration.
50
+ *
51
+ * @param options - Generator options with trigger context
52
+ *
53
+ * @example
54
+ * ```typescript
55
+ * async generate(options: GeneratorOptions): Promise<void>
56
+ * {
57
+ * // Check if incremental update is possible
58
+ * if (options.trigger?.changedFile)
59
+ * {
60
+ * const { path, event } = options.trigger.changedFile;
61
+ *
62
+ * if (canDoIncrementalUpdate(path, event))
63
+ * {
64
+ * await updateSingleFile(path);
65
+ * return;
66
+ * }
67
+ * }
68
+ *
69
+ * // Fallback: full regeneration
70
+ * await fullRegenerate();
71
+ * }
72
+ * ```
73
+ */
74
+ generate(options: GeneratorOptions): Promise<void>;
75
+ }
76
+
77
+ /**
78
+ * Contract Generator
79
+ *
80
+ * Generates type-safe API client from contract definitions
81
+ *
82
+ * Features:
83
+ * - Automatic scanning of contract files
84
+ * - Type-safe client generation with InferContract
85
+ * - Split output by resource for better code organization
86
+ * - Incremental updates when single files change (smart regeneration)
87
+ */
88
+
89
+ interface ContractGeneratorConfig {
90
+ /** Contracts directory (default: src/lib/contracts) */
91
+ contractsDir?: string;
92
+ /** Output directory (default: src/lib/api) */
93
+ outputPath?: string;
94
+ /** Base URL for API client */
95
+ baseUrl?: string;
96
+ /** When to run this generator (default: ['watch', 'manual', 'build']) */
97
+ runOn?: GeneratorTrigger[];
98
+ }
99
+ declare function createContractGenerator(config?: ContractGeneratorConfig): Generator;
100
+
101
+ export { type ContractGeneratorConfig as C, type Generator as G, type GeneratorTrigger as a, type GeneratorOptions as b, createContractGenerator as c };
package/dist/index.d.ts CHANGED
@@ -1,233 +1,7 @@
1
1
  export { AppFactory, ServerConfig, createServer, startServer } from './server/index.js';
2
- export { A as AutoRouteLoader, R as RouteInfo, a as RouteStats, l as loadRoutes } from './auto-loader-CdsxOceW.js';
3
- export { b as bind } from './bind-CSzshBtm.js';
4
- export { d as HttpMethod, I as InferContract, c as RouteContext, R as RouteContract, a as RouteHandler, i as isHttpMethod } from './types-Bd8YsFSU.js';
5
- import { D as DatabaseError } from './postgres-errors-lw1aRUFe.js';
6
- export { C as ConnectionError, l as DeadlockError, c as DrizzleConfigOptions, m as DuplicateEntryError, N as NotFoundError, Q as QueryError, h as TransactionContext, k as TransactionError, T as Transactional, j as TransactionalOptions, V as ValidationError, d as detectDialect, f as foreignKey, b as fromPostgresError, a as generateDrizzleConfigFile, g as getDrizzleConfig, e as getTransaction, i as id, o as optionalForeignKey, r as runWithTransaction, t as timestamps } from './postgres-errors-lw1aRUFe.js';
7
- import { Redis, Cluster } from 'ioredis';
8
- export { LogLevel, LoggerAdapter, logger } from './logger/index.js';
9
- import { Context, Next } from 'hono';
2
+ export { H as HttpMethod, I as InferContract, R as RouteContext, a as RouteContract, b as RouteHandler, i as isHttpMethod } from './types-CAON3Mmg.js';
3
+ import 'hono';
10
4
  import 'hono/cors';
11
5
  import '@hono/node-server';
12
6
  import 'hono/utils/http-status';
13
7
  import '@sinclair/typebox';
14
- import 'drizzle-orm';
15
- import 'drizzle-orm/pg-core';
16
- import 'drizzle-orm/postgres-js';
17
-
18
- /**
19
- * Error Utility Functions
20
- *
21
- * Generic error type checking utilities
22
- */
23
-
24
- /**
25
- * Check if error is a DatabaseError
26
- */
27
- declare function isDatabaseError(error: unknown): error is DatabaseError;
28
-
29
- /**
30
- * Redis factory with automatic environment variable detection
31
- * Supports: Single, Master-Replica, Sentinel, Cluster
32
- */
33
-
34
- interface RedisClients {
35
- /** Primary Redis for writes (or both read/write if no replica) */
36
- write?: Redis | Cluster;
37
- /** Replica Redis for reads (optional, falls back to write) */
38
- read?: Redis | Cluster;
39
- }
40
- /**
41
- * Create Redis client(s) from environment variables
42
- *
43
- * Supported patterns (priority order):
44
- * 1. Single instance: REDIS_URL
45
- * 2. Master-Replica: REDIS_WRITE_URL + REDIS_READ_URL
46
- * 3. Sentinel: REDIS_SENTINEL_HOSTS + REDIS_MASTER_NAME
47
- * 4. Cluster: REDIS_CLUSTER_NODES
48
- *
49
- * @returns Redis client(s) or undefined if no configuration found
50
- *
51
- * @example
52
- * ```bash
53
- * # Single (most common)
54
- * REDIS_URL=redis://localhost:6379
55
- * REDIS_URL=rediss://secure.redis.com:6380 # TLS
56
- *
57
- * # Master-Replica
58
- * REDIS_WRITE_URL=redis://master:6379
59
- * REDIS_READ_URL=redis://replica:6379
60
- *
61
- * # Sentinel
62
- * REDIS_SENTINEL_HOSTS=sentinel1:26379,sentinel2:26379
63
- * REDIS_MASTER_NAME=mymaster
64
- * REDIS_PASSWORD=secret
65
- *
66
- * # Cluster
67
- * REDIS_CLUSTER_NODES=node1:6379,node2:6379,node3:6379
68
- * REDIS_PASSWORD=secret
69
- * ```
70
- */
71
- declare function createRedisFromEnv(): Promise<RedisClients>;
72
- /**
73
- * Create single Redis client (backward compatibility)
74
- * Only returns write instance
75
- */
76
- declare function createSingleRedisFromEnv(): Promise<Redis | Cluster | undefined>;
77
-
78
- /**
79
- * Global Redis instance manager
80
- * Provides singleton access to Redis across all modules
81
- * Supports Master-Replica pattern with separate read/write instances
82
- */
83
-
84
- /**
85
- * Get global Redis write instance
86
- *
87
- * @returns Redis write instance or undefined if not initialized
88
- *
89
- * @example
90
- * ```typescript
91
- * import { getRedis } from '@spfn/core/cache';
92
- *
93
- * const redis = getRedis();
94
- * if (redis) {
95
- * await redis.set('key', 'value');
96
- * }
97
- * ```
98
- */
99
- declare function getRedis(): Redis | Cluster | undefined;
100
- /**
101
- * Get global Redis read instance (falls back to write if no replica)
102
- *
103
- * @returns Redis read instance or write instance as fallback
104
- *
105
- * @example
106
- * ```typescript
107
- * import { getRedisRead } from '@spfn/core/cache';
108
- *
109
- * const redis = getRedisRead();
110
- * if (redis) {
111
- * const value = await redis.get('key');
112
- * }
113
- * ```
114
- */
115
- declare function getRedisRead(): Redis | Cluster | undefined;
116
- /**
117
- * Set global Redis instances (for testing or manual configuration)
118
- *
119
- * @param write - Redis write instance
120
- * @param read - Redis read instance (optional, defaults to write)
121
- *
122
- * @example
123
- * ```typescript
124
- * import { setRedis } from '@spfn/core/cache';
125
- * import Redis from 'ioredis';
126
- *
127
- * const write = new Redis('redis://master:6379');
128
- * const read = new Redis('redis://replica:6379');
129
- * setRedis(write, read);
130
- * ```
131
- */
132
- declare function setRedis(write: Redis | Cluster | undefined, read?: Redis | Cluster | undefined): void;
133
- /**
134
- * Initialize Redis from environment variables
135
- * Automatically called by startServer()
136
- *
137
- * Supported environment variables:
138
- * - REDIS_URL (single instance)
139
- * - REDIS_WRITE_URL + REDIS_READ_URL (master-replica)
140
- * - REDIS_SENTINEL_HOSTS + REDIS_MASTER_NAME (sentinel)
141
- * - REDIS_CLUSTER_NODES (cluster)
142
- * - REDIS_TLS_REJECT_UNAUTHORIZED (TLS config)
143
- *
144
- * @returns Object with write and read instances
145
- *
146
- * @example
147
- * ```typescript
148
- * import { initRedis } from '@spfn/core/cache';
149
- *
150
- * // Manual initialization (not needed if using startServer)
151
- * const { write, read } = await initRedis();
152
- * ```
153
- */
154
- declare function initRedis(): Promise<{
155
- write?: Redis | Cluster;
156
- read?: Redis | Cluster;
157
- }>;
158
- /**
159
- * Close all Redis connections and cleanup
160
- *
161
- * @example
162
- * ```typescript
163
- * import { closeRedis } from '@spfn/core/cache';
164
- *
165
- * // During graceful shutdown
166
- * await closeRedis();
167
- * ```
168
- */
169
- declare function closeRedis(): Promise<void>;
170
- /**
171
- * Get Redis connection info (for debugging)
172
- */
173
- declare function getRedisInfo(): {
174
- hasWrite: boolean;
175
- hasRead: boolean;
176
- isReplica: boolean;
177
- };
178
-
179
- /**
180
- * Request Logger Middleware
181
- *
182
- * Automatic API request/response logging with performance monitoring
183
- */
184
-
185
- interface RequestLoggerConfig {
186
- /**
187
- * Paths to exclude from logging (health checks, etc.)
188
- */
189
- excludePaths?: string[];
190
- /**
191
- * Field names to mask for sensitive data
192
- */
193
- sensitiveFields?: string[];
194
- /**
195
- * Slow request threshold (ms)
196
- */
197
- slowRequestThreshold?: number;
198
- }
199
- /**
200
- * Mask sensitive data with circular reference handling
201
- */
202
- declare function maskSensitiveData(obj: any, sensitiveFields: string[], seen?: WeakSet<object>): any;
203
- /**
204
- * Request Logger middleware
205
- */
206
- declare function RequestLogger(config?: RequestLoggerConfig): (c: Context, next: Next) => Promise<void>;
207
-
208
- /**
209
- * Error Handler Middleware
210
- *
211
- * Generic middleware that converts errors with statusCode to HTTP responses
212
- */
213
-
214
- interface ErrorHandlerOptions {
215
- /**
216
- * Include stack trace in response
217
- * @default process.env.NODE_ENV !== 'production'
218
- */
219
- includeStack?: boolean;
220
- /**
221
- * Enable error logging
222
- * @default true
223
- */
224
- enableLogging?: boolean;
225
- }
226
- /**
227
- * Error handler middleware
228
- *
229
- * Used in Hono's onError hook
230
- */
231
- declare function ErrorHandler(options?: ErrorHandlerOptions): (err: Error, c: Context) => Response | Promise<Response>;
232
-
233
- export { DatabaseError, ErrorHandler, type ErrorHandlerOptions, type RedisClients, RequestLogger, type RequestLoggerConfig, closeRedis, createRedisFromEnv, createSingleRedisFromEnv, getRedis, getRedisInfo, getRedisRead, initRedis, isDatabaseError, maskSensitiveData, setRedis };