@kalutskii/foundation 0.4.5 → 0.5.1
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/index.d.ts +110 -47
- package/dist/index.js +49 -25
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -3,6 +3,18 @@ import z$1, { z, ZodNumber } from 'zod';
|
|
|
3
3
|
import { Locale } from 'date-fns';
|
|
4
4
|
import { SymmetricAlgorithm } from 'hono/utils/jwt/jwa';
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
* Global error handler for Hono framework. Catches all exceptions thrown in route handlers and middlewares.
|
|
8
|
+
* Distinguishes between expected HTTPExceptions (mapped to their status codes) and unexpected errors (500).
|
|
9
|
+
*/
|
|
10
|
+
declare const onHandlerError: ErrorHandler;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Request logging middleware for Hono, providing deeply detailed logs for each incoming request.
|
|
14
|
+
* Example log output: [12:12:12 (+4 UTC)] hono | POST 200 123ms /api/v1/users (search=term)
|
|
15
|
+
*/
|
|
16
|
+
declare const honoLoggingHandler: MiddlewareHandler;
|
|
17
|
+
|
|
6
18
|
declare const SUCCESS_STATUS_CODES: readonly [200, 201, 202, 307];
|
|
7
19
|
declare const EXCEPTION_STATUS_CODES: readonly [400, 401, 403, 404, 405, 409, 500];
|
|
8
20
|
|
|
@@ -30,47 +42,6 @@ type FetchResult<T> = {
|
|
|
30
42
|
data: null;
|
|
31
43
|
};
|
|
32
44
|
|
|
33
|
-
/**
|
|
34
|
-
* Factory for creating successful API responses with serializable data.
|
|
35
|
-
* Example usage: `success({ status: 200, data: { message: 'Operation successful' } })`
|
|
36
|
-
*/
|
|
37
|
-
declare function success<T = unknown>({ status, data }: {
|
|
38
|
-
status: SuccessStatusCode;
|
|
39
|
-
data: T;
|
|
40
|
-
}): APISuccess<T>;
|
|
41
|
-
/**
|
|
42
|
-
* Factory for creating API error responses, including the error message.
|
|
43
|
-
* Example usage: `failure({ status: 404, error: 'User not found' })`
|
|
44
|
-
*/
|
|
45
|
-
declare function failure({ status, error }: {
|
|
46
|
-
status: ExceptionStatusCode;
|
|
47
|
-
error: string;
|
|
48
|
-
}): APIError;
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* Resolves an APIContractResult fetcher into a FetchResult discriminated union.
|
|
52
|
-
* Does not throw errors, instead returning them in the error property of the FetchResult.
|
|
53
|
-
* Example usage: const result = await fetchSafely(() => api.fetchUser(userId));
|
|
54
|
-
*/
|
|
55
|
-
declare function fetchSafely<TResult extends APIContractResult<unknown>>(fetcher: () => Promise<TResult>): Promise<FetchResult<APIContractData<TResult>>>;
|
|
56
|
-
/**
|
|
57
|
-
* Resolves an APIContractResult fetcher, throwing an error if the result is an APIError.
|
|
58
|
-
* Example usage: const data = await fetchAndThrow(() => api.fetchUser(userId));
|
|
59
|
-
*/
|
|
60
|
-
declare function fetchAndThrow<TResult extends APIContractResult<unknown>>(fetcher: () => Promise<TResult>): Promise<APIContractData<TResult>>;
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* Global error handler for Hono framework. Catches all exceptions thrown in route handlers and middlewares.
|
|
64
|
-
* Distinguishes between expected HTTPExceptions (mapped to their status codes) and unexpected errors (500).
|
|
65
|
-
*/
|
|
66
|
-
declare const onHandlerError: ErrorHandler;
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* Request logging middleware for Hono, providing deeply detailed logs for each incoming request.
|
|
70
|
-
* Example log output: [12:12:12 (+4 UTC)] hono | POST 200 123ms /api/v1/users (search=term)
|
|
71
|
-
*/
|
|
72
|
-
declare const honoLoggingHandler: MiddlewareHandler;
|
|
73
|
-
|
|
74
45
|
/**
|
|
75
46
|
* Type utility that recursively transforms all Date fields to string, as well as handling arrays and objects.
|
|
76
47
|
* This is necessary for proper typing when working with RPC, as JSON does not support the Date type directly.
|
|
@@ -109,6 +80,74 @@ declare function respond<T extends object = Record<string, never>, S extends Suc
|
|
|
109
80
|
data?: T;
|
|
110
81
|
}): Response & TypedResponse<APISuccess<SerializeDates<T>> | APIError, S, 'json'>;
|
|
111
82
|
|
|
83
|
+
/**
|
|
84
|
+
* Factory for creating successful API responses with serializable data.
|
|
85
|
+
* Example usage: `success({ status: 200, data: { message: 'Operation successful' } })`
|
|
86
|
+
*/
|
|
87
|
+
declare function success<T = unknown>({ status, data }: {
|
|
88
|
+
status: SuccessStatusCode;
|
|
89
|
+
data: T;
|
|
90
|
+
}): APISuccess<T>;
|
|
91
|
+
/**
|
|
92
|
+
* Factory for creating API error responses, including the error message.
|
|
93
|
+
* Example usage: `failure({ status: 404, error: 'User not found' })`
|
|
94
|
+
*/
|
|
95
|
+
declare function failure({ status, error }: {
|
|
96
|
+
status: ExceptionStatusCode;
|
|
97
|
+
error: string;
|
|
98
|
+
}): APIError;
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Resolves an APIContractResult fetcher into a FetchResult discriminated union.
|
|
102
|
+
* Does not throw errors, instead returning them in the error property of the FetchResult.
|
|
103
|
+
* Example usage: const result = await fetchSafely(() => api.fetchUser(userId));
|
|
104
|
+
*/
|
|
105
|
+
declare function fetchSafely<TResult extends APIContractResult<unknown>>(fetcher: () => Promise<TResult>): Promise<FetchResult<APIContractData<TResult>>>;
|
|
106
|
+
/**
|
|
107
|
+
* Resolves an APIContractResult fetcher, throwing an error if the result is an APIError.
|
|
108
|
+
* Example usage: const data = await fetchAndThrow(() => api.fetchUser(userId));
|
|
109
|
+
*/
|
|
110
|
+
declare function fetchAndThrow<TResult extends APIContractResult<unknown>>(fetcher: () => Promise<TResult>): Promise<APIContractData<TResult>>;
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* A Zod schema for validating pagination options, specifically the `offset` and `limit` parameters.
|
|
114
|
+
* - `offset`: An optional non-negative integer representing the starting point for pagination.
|
|
115
|
+
* - `limit`: An optional positive integer representing the maximum number of items to return.
|
|
116
|
+
*
|
|
117
|
+
* This schema can be used to inject in other Zod schemas for validating pagination options:
|
|
118
|
+
*
|
|
119
|
+
* ```ts
|
|
120
|
+
* const mySchema = paginationSchema.extend({
|
|
121
|
+
* // other fields here
|
|
122
|
+
* });
|
|
123
|
+
* ```
|
|
124
|
+
*/
|
|
125
|
+
declare const paginationSchema: z$1.ZodObject<{
|
|
126
|
+
offset: z$1.ZodOptional<z$1.ZodNumber>;
|
|
127
|
+
limit: z$1.ZodOptional<z$1.ZodNumber>;
|
|
128
|
+
}, z$1.core.$strip>;
|
|
129
|
+
/**
|
|
130
|
+
* A TypeScript type representing the pagination options validated by the `paginationSchema`.
|
|
131
|
+
* Read documentation for `paginationSchema` for more details on the structure and usage of this type.
|
|
132
|
+
*/
|
|
133
|
+
type PaginationOptions = z$1.infer<typeof paginationSchema>;
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* A utility function that extracts pagination options from the provided input.
|
|
137
|
+
* It returns an object containing the `offset` and `limit` properties if they are defined.
|
|
138
|
+
* If the input is undefined or does not contain these properties, it returns an empty object.
|
|
139
|
+
*
|
|
140
|
+
* ```ts
|
|
141
|
+
* await db.query.someTable.findMany({
|
|
142
|
+
* ...getPagination(options),
|
|
143
|
+
* });
|
|
144
|
+
* ```
|
|
145
|
+
*/
|
|
146
|
+
declare const getPagination: (options?: PaginationOptions) => {
|
|
147
|
+
offset?: number | undefined;
|
|
148
|
+
limit?: number | undefined;
|
|
149
|
+
};
|
|
150
|
+
|
|
112
151
|
/**
|
|
113
152
|
* Returns the current time in the specified timezone.
|
|
114
153
|
* Example usage: `getZonedTime({ tz: 'America/New_York' }) = new Date('2026-03-15T12:00:00Z')`
|
|
@@ -191,21 +230,42 @@ declare const log: {
|
|
|
191
230
|
error: (message: string, service?: string, stack?: string) => void;
|
|
192
231
|
};
|
|
193
232
|
|
|
233
|
+
/**
|
|
234
|
+
* Utility type that simplifies a given type T by flattening its structure.
|
|
235
|
+
* This is particularly useful for improving the readability of complex types.
|
|
236
|
+
*/
|
|
237
|
+
type Simplify<T> = {
|
|
238
|
+
[K in keyof T]: T[K];
|
|
239
|
+
} & {};
|
|
194
240
|
/**
|
|
195
241
|
* A utility type that represents a value that can be of type T or null.
|
|
196
242
|
* Commonly used for optional fields in data models or function return types.
|
|
197
243
|
*
|
|
198
|
-
* ```
|
|
244
|
+
* ```ts
|
|
199
245
|
* export type ObjectSelect = XOR<
|
|
200
246
|
* Pick<Object, 'id'>,
|
|
201
247
|
* Pick<Object, 'anotherUniqueField'>
|
|
202
248
|
* >;
|
|
203
249
|
*/
|
|
204
|
-
type XOR<T, U> =
|
|
250
|
+
type XOR<T, U> = Simplify<T & {
|
|
205
251
|
[K in keyof U]?: never;
|
|
206
|
-
}
|
|
252
|
+
}> | Simplify<U & {
|
|
207
253
|
[K in keyof T]?: never;
|
|
208
|
-
}
|
|
254
|
+
}>;
|
|
255
|
+
/**
|
|
256
|
+
* Utility type that ensures at least one property from the specified
|
|
257
|
+
* keys of a given type T is required, while the rest remain optional.
|
|
258
|
+
*
|
|
259
|
+
* This is useful for scenarios where you want to enforce that at least one
|
|
260
|
+
* of several optional (nullable) properties must be provided in an object.
|
|
261
|
+
*
|
|
262
|
+
* ```ts
|
|
263
|
+
* type Example = AtLeastOne<{ a?: string; b?: number; c?: boolean }>;
|
|
264
|
+
* // Valid: { a: "hello" }, { b: 42 }, { c: true }, { a: "hello", b: 42 }
|
|
265
|
+
* // Invalid: {}, { a: undefined, b: undefined, c: undefined }
|
|
266
|
+
* ```
|
|
267
|
+
*/
|
|
268
|
+
type AtLeastOne<T, Keys extends keyof T = keyof T> = Keys extends keyof T ? Simplify<Required<Pick<T, Keys>> & Partial<Omit<T, Keys>>> : never;
|
|
209
269
|
|
|
210
270
|
/** Options for configuring the JWT service. */
|
|
211
271
|
type JWTServiceOptions = {
|
|
@@ -241,15 +301,18 @@ declare class ZodJWTService<TPayloadOrSchema> {
|
|
|
241
301
|
/**
|
|
242
302
|
* Decodes a JWT token, and if a Zod schema is provided, validates the payload against it.
|
|
243
303
|
* Returns the decoded payload if valid, or null if invalid or if the token cannot be decoded.
|
|
304
|
+
*
|
|
244
305
|
* Example usage: `const payload = await JWTServiceInstance.decode(token);`
|
|
245
306
|
*/
|
|
246
307
|
decode(token: string): Promise<Payload<TPayloadOrSchema> | null>;
|
|
247
308
|
/**
|
|
248
309
|
* Verifies and decodes a JWT token using the provided secret and configured algorithm,
|
|
249
|
-
* then validates the payload against the Zod schema if one is provided.
|
|
310
|
+
* then validates the payload against the Zod schema if one is provided.
|
|
311
|
+
*
|
|
312
|
+
* Throws an error if verification fails or if the payload is invalid according to the schema.
|
|
250
313
|
* Example usage: `const payload = await JWTServiceInstance.verifyOrThrow(token, 'my-secret');`
|
|
251
314
|
*/
|
|
252
315
|
verifyOrThrow(token: string, secret: string): Promise<Payload<TPayloadOrSchema>>;
|
|
253
316
|
}
|
|
254
317
|
|
|
255
|
-
export { type APIContractData, type APIContractError, type APIContractResult, type APIError, type APISuccess, type AsQuery, EXCEPTION_STATUS_CODES, type ExceptionStatusCode, type FetchResult, type JWTServiceOptions, type JWTSignOptions, type MeasuredExecution, type Payload, type PayloadSchema, SUCCESS_STATUS_CODES, type SerializeDates, type SuccessStatusCode, type XOR, ZodJWTService, asQueryBoolean, asQueryNumber, failure, fetchAndThrow, fetchSafely, formatTime, generateRandomString, getColoredHTTPStatus, getFormattedDate, getFormattedTime, getUTCOffset, getZonedTime, honoLoggingHandler, log, measureExecutionTime, onHandlerError, respond, safeExecute, success };
|
|
318
|
+
export { type APIContractData, type APIContractError, type APIContractResult, type APIError, type APISuccess, type AsQuery, type AtLeastOne, EXCEPTION_STATUS_CODES, type ExceptionStatusCode, type FetchResult, type JWTServiceOptions, type JWTSignOptions, type MeasuredExecution, type PaginationOptions, type Payload, type PayloadSchema, SUCCESS_STATUS_CODES, type SerializeDates, type Simplify, type SuccessStatusCode, type XOR, ZodJWTService, asQueryBoolean, asQueryNumber, failure, fetchAndThrow, fetchSafely, formatTime, generateRandomString, getColoredHTTPStatus, getFormattedDate, getFormattedTime, getPagination, getUTCOffset, getZonedTime, honoLoggingHandler, log, measureExecutionTime, onHandlerError, paginationSchema, respond, safeExecute, success };
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
// src/
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
// src/hono/hono.execution.ts
|
|
2
|
+
import { HTTPException } from "hono/http-exception";
|
|
3
|
+
import { red as red2 } from "kleur/colors";
|
|
4
4
|
|
|
5
5
|
// src/http/http.factory.ts
|
|
6
6
|
function success({ status, data }) {
|
|
@@ -10,24 +10,6 @@ function failure({ status, error }) {
|
|
|
10
10
|
return { kind: "error", status, error };
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
// src/http/http.resolvers.ts
|
|
14
|
-
async function fetchSafely(fetcher) {
|
|
15
|
-
const response = await fetcher();
|
|
16
|
-
if (response.kind === "error")
|
|
17
|
-
return { error: response.error, data: null };
|
|
18
|
-
return { error: null, data: response.data };
|
|
19
|
-
}
|
|
20
|
-
async function fetchAndThrow(fetcher) {
|
|
21
|
-
const response = await fetcher();
|
|
22
|
-
if (response.kind === "error")
|
|
23
|
-
throw new Error(response.error);
|
|
24
|
-
return response.data;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
// src/hono/hono.execution.ts
|
|
28
|
-
import { HTTPException } from "hono/http-exception";
|
|
29
|
-
import { red as red2 } from "kleur/colors";
|
|
30
|
-
|
|
31
13
|
// src/utilities/generation.utilities.ts
|
|
32
14
|
var DEFAULT_CHARACTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
|
33
15
|
function generateRandomString(length = 10) {
|
|
@@ -130,6 +112,43 @@ function respond(c, options) {
|
|
|
130
112
|
return c.json(success({ status: options.status, data: options.data ?? {} }), options.status);
|
|
131
113
|
}
|
|
132
114
|
|
|
115
|
+
// src/http/http.constants.ts
|
|
116
|
+
var SUCCESS_STATUS_CODES = [200, 201, 202, 307];
|
|
117
|
+
var EXCEPTION_STATUS_CODES = [400, 401, 403, 404, 405, 409, 500];
|
|
118
|
+
|
|
119
|
+
// src/http/http.resolvers.ts
|
|
120
|
+
async function fetchSafely(fetcher) {
|
|
121
|
+
const response = await fetcher();
|
|
122
|
+
if (response.kind === "error")
|
|
123
|
+
return { error: response.error, data: null };
|
|
124
|
+
return { error: null, data: response.data };
|
|
125
|
+
}
|
|
126
|
+
async function fetchAndThrow(fetcher) {
|
|
127
|
+
const response = await fetcher();
|
|
128
|
+
if (response.kind === "error")
|
|
129
|
+
throw new Error(response.error);
|
|
130
|
+
return response.data;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// src/pagination/pagination.schemas.ts
|
|
134
|
+
import z from "zod";
|
|
135
|
+
var paginationSchema = z.object({
|
|
136
|
+
offset: z.number().int().nonnegative().optional(),
|
|
137
|
+
limit: z.number().int().positive().optional()
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
// src/pagination/pagination.utilities.ts
|
|
141
|
+
var getPagination = (options) => {
|
|
142
|
+
const pagination = {};
|
|
143
|
+
if (options?.offset !== void 0) {
|
|
144
|
+
pagination.offset = options.offset;
|
|
145
|
+
}
|
|
146
|
+
if (options?.limit !== void 0) {
|
|
147
|
+
pagination.limit = options.limit;
|
|
148
|
+
}
|
|
149
|
+
return pagination;
|
|
150
|
+
};
|
|
151
|
+
|
|
133
152
|
// src/utilities/execution.utilities.ts
|
|
134
153
|
async function safeExecute(fn, onError) {
|
|
135
154
|
try {
|
|
@@ -148,12 +167,12 @@ async function measureExecutionTime(execution) {
|
|
|
148
167
|
}
|
|
149
168
|
|
|
150
169
|
// src/utilities/serialization.utilities.ts
|
|
151
|
-
import { z } from "zod";
|
|
152
|
-
var asQueryNumber = (schema) =>
|
|
170
|
+
import { z as z2 } from "zod";
|
|
171
|
+
var asQueryNumber = (schema) => z2.preprocess((v) => typeof v === "string" ? Number(v) : v, schema);
|
|
153
172
|
var asQueryBoolean = (schema) => {
|
|
154
173
|
const POSITIVE_VALUES = ["1", "true", "yes", "y", "on"];
|
|
155
174
|
const NEGATIVE_VALUES = ["0", "false", "no", "n", "off"];
|
|
156
|
-
return
|
|
175
|
+
return z2.preprocess((value) => {
|
|
157
176
|
if (typeof value === "boolean")
|
|
158
177
|
return value;
|
|
159
178
|
if (typeof value === "string") {
|
|
@@ -189,6 +208,7 @@ var ZodJWTService = class {
|
|
|
189
208
|
/**
|
|
190
209
|
* Decodes a JWT token, and if a Zod schema is provided, validates the payload against it.
|
|
191
210
|
* Returns the decoded payload if valid, or null if invalid or if the token cannot be decoded.
|
|
211
|
+
*
|
|
192
212
|
* Example usage: `const payload = await JWTServiceInstance.decode(token);`
|
|
193
213
|
*/
|
|
194
214
|
async decode(token) {
|
|
@@ -201,7 +221,9 @@ var ZodJWTService = class {
|
|
|
201
221
|
}
|
|
202
222
|
/**
|
|
203
223
|
* Verifies and decodes a JWT token using the provided secret and configured algorithm,
|
|
204
|
-
* then validates the payload against the Zod schema if one is provided.
|
|
224
|
+
* then validates the payload against the Zod schema if one is provided.
|
|
225
|
+
*
|
|
226
|
+
* Throws an error if verification fails or if the payload is invalid according to the schema.
|
|
205
227
|
* Example usage: `const payload = await JWTServiceInstance.verifyOrThrow(token, 'my-secret');`
|
|
206
228
|
*/
|
|
207
229
|
async verifyOrThrow(token, secret) {
|
|
@@ -226,12 +248,14 @@ export {
|
|
|
226
248
|
getColoredHTTPStatus,
|
|
227
249
|
getFormattedDate,
|
|
228
250
|
getFormattedTime,
|
|
251
|
+
getPagination,
|
|
229
252
|
getUTCOffset,
|
|
230
253
|
getZonedTime,
|
|
231
254
|
honoLoggingHandler,
|
|
232
255
|
log,
|
|
233
256
|
measureExecutionTime,
|
|
234
257
|
onHandlerError,
|
|
258
|
+
paginationSchema,
|
|
235
259
|
respond,
|
|
236
260
|
safeExecute,
|
|
237
261
|
success
|