@kalutskii/foundation 0.7.9 → 0.7.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -1
- package/dist/index.d.ts +80 -4
- package/dist/index.js +45 -23
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -24,7 +24,7 @@ The package contains several deliberately isolated areas:
|
|
|
24
24
|
| ---------------- | ----------------------------------------------------------------------------------------- |
|
|
25
25
|
| `utilities` | Framework-independent datetime, enum, execution, generation, logging, and type utilities. |
|
|
26
26
|
| `http` | Shared HTTP result contracts, factories, status constants, and result resolvers. |
|
|
27
|
-
| `upload` | Shared file-format metadata,
|
|
27
|
+
| `upload` | Shared upload presets, file-format metadata, validation, and reusable Zod schemas. |
|
|
28
28
|
| `zod-validation` | Generic Zod parsing, validation, refinement, and related type utilities. |
|
|
29
29
|
| `zod-search` | Reusable search and pagination contracts composed from lower-level Zod primitives. |
|
|
30
30
|
| `zod-bulk` | Include/exclude selection contracts shared by frontend and backend bulk operations. |
|
|
@@ -122,6 +122,7 @@ single public API boundary and should export only symbols intentionally supporte
|
|
|
122
122
|
| `*.services.ts` | Stateful service classes that coordinate one external capability. |
|
|
123
123
|
| `*.validation.ts` | Ordered validation behavior returning stable domain error keys. |
|
|
124
124
|
| `*.factory.ts` | Functions whose primary responsibility is constructing non-schema values. |
|
|
125
|
+
| `*.presets.ts` | Ready-to-use policies composed from public domain values. |
|
|
125
126
|
| `*.resolvers.ts` | Functions that unwrap, normalize, or translate an existing result. |
|
|
126
127
|
| `*.utilities.ts` | Stateless reusable behavior that has no narrower architectural owner. |
|
|
127
128
|
| `*.parsing.ts` | Input parsing and preprocessing before domain validation. |
|
package/dist/index.d.ts
CHANGED
|
@@ -20,10 +20,21 @@ declare function sqlWhere(table: unknown, where: Record<string, unknown>): SQL;
|
|
|
20
20
|
declare const onHandlerError: ErrorHandler;
|
|
21
21
|
|
|
22
22
|
/**
|
|
23
|
-
*
|
|
24
|
-
*
|
|
23
|
+
* Options controlling which request details the Hono logger may expose.
|
|
24
|
+
* Secure mode excludes query parameters and body content from log output.
|
|
25
25
|
*/
|
|
26
|
-
|
|
26
|
+
type HonoLoggingOptions = {
|
|
27
|
+
/**
|
|
28
|
+
* Prevents query parameters and request bodies from being read or logged.
|
|
29
|
+
* Defaults to `false`, preserving detailed request logging.
|
|
30
|
+
*/
|
|
31
|
+
secure?: boolean;
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* Creates middleware that logs request metadata and an optional body preview.
|
|
35
|
+
* Multipart bodies remain unread, while secure mode omits all sensitive input details.
|
|
36
|
+
*/
|
|
37
|
+
declare function honoLoggingHandler(options?: HonoLoggingOptions): MiddlewareHandler;
|
|
27
38
|
|
|
28
39
|
declare const SUCCESS_STATUS_CODES: readonly [200, 201, 202, 307];
|
|
29
40
|
declare const EXCEPTION_STATUS_CODES: readonly [400, 401, 403, 404, 405, 409, 500];
|
|
@@ -194,6 +205,32 @@ declare const uploadValidationError: Readonly<{
|
|
|
194
205
|
}>;
|
|
195
206
|
|
|
196
207
|
type FileFormatConfig = (typeof fileFormatsConfig)[FileFormat];
|
|
208
|
+
/**
|
|
209
|
+
* Shared upload policy consumed by browser controls and backend validation.
|
|
210
|
+
* One preset keeps format, size, capacity, and fallback rules synchronized.
|
|
211
|
+
*/
|
|
212
|
+
type UploadPreset<TFormats extends readonly FileFormat[] = readonly FileFormat[]> = Readonly<{
|
|
213
|
+
/**
|
|
214
|
+
* Supported formats accepted by every consumer of the preset.
|
|
215
|
+
* Const inference preserves the supplied format tuple without widening.
|
|
216
|
+
*/
|
|
217
|
+
formats: TFormats;
|
|
218
|
+
/**
|
|
219
|
+
* Maximum accepted size of one uploaded file measured in bytes.
|
|
220
|
+
* Schema and client validation can share this exact numeric boundary.
|
|
221
|
+
*/
|
|
222
|
+
maxFileSize: number;
|
|
223
|
+
/**
|
|
224
|
+
* Optional maximum number of files retained by one upload collection.
|
|
225
|
+
* Single-file controls can set this value to `1` for shared capacity rules.
|
|
226
|
+
*/
|
|
227
|
+
maxFilesCount?: number;
|
|
228
|
+
/**
|
|
229
|
+
* Allows extensions to compensate for absent or unreliable MIME metadata.
|
|
230
|
+
* The fallback remains disabled when this option is omitted.
|
|
231
|
+
*/
|
|
232
|
+
extensionFallback?: boolean;
|
|
233
|
+
}>;
|
|
197
234
|
/**
|
|
198
235
|
* Constraints used to validate an incoming collection of browser files.
|
|
199
236
|
* Existing and incoming counts are combined when enforcing capacity.
|
|
@@ -258,6 +295,45 @@ type ZodUploadFileSchemaOptions = Readonly<{
|
|
|
258
295
|
extensionFallback?: boolean;
|
|
259
296
|
}>;
|
|
260
297
|
|
|
298
|
+
/**
|
|
299
|
+
* Defines one shared upload policy while preserving its literal format tuple.
|
|
300
|
+
* The resulting preset can drive schemas, picker hints, and batch validation.
|
|
301
|
+
*
|
|
302
|
+
* @example
|
|
303
|
+
* const imageUploadPreset = defineUploadPreset({
|
|
304
|
+
* formats: [fileFormat.JPG, fileFormat.PNG, fileFormat.WEBP],
|
|
305
|
+
* maxFileSize: 8 * 1024 * 1024,
|
|
306
|
+
* maxFilesCount: 1,
|
|
307
|
+
* });
|
|
308
|
+
*/
|
|
309
|
+
declare function defineUploadPreset<const TFormats extends readonly FileFormat[]>(preset: UploadPreset<TFormats>): UploadPreset<TFormats>;
|
|
310
|
+
|
|
311
|
+
/**
|
|
312
|
+
* Default maximum size of one file accepted by the built-in upload presets.
|
|
313
|
+
* The 20 MiB boundary matches the existing upload component policy.
|
|
314
|
+
*/
|
|
315
|
+
declare const DEFAULT_UPLOAD_MAX_FILE_SIZE: number;
|
|
316
|
+
/**
|
|
317
|
+
* Ready-to-use policy for every image format supported by the upload catalog.
|
|
318
|
+
* Each image may occupy up to 20 MiB while collection capacity remains unrestricted.
|
|
319
|
+
*/
|
|
320
|
+
declare const imageUploadPreset: Readonly<{
|
|
321
|
+
formats: readonly ["png", "jpg", "webp", "avif", "heic"];
|
|
322
|
+
maxFileSize: number;
|
|
323
|
+
maxFilesCount?: number;
|
|
324
|
+
extensionFallback?: boolean;
|
|
325
|
+
}>;
|
|
326
|
+
/**
|
|
327
|
+
* Ready-to-use policy for every document format supported by the upload catalog.
|
|
328
|
+
* Each document may occupy up to 20 MiB while collection capacity remains unrestricted.
|
|
329
|
+
*/
|
|
330
|
+
declare const documentUploadPreset: Readonly<{
|
|
331
|
+
formats: readonly ["pdf", "rtf", "txt"];
|
|
332
|
+
maxFileSize: number;
|
|
333
|
+
maxFilesCount?: number;
|
|
334
|
+
extensionFallback?: boolean;
|
|
335
|
+
}>;
|
|
336
|
+
|
|
261
337
|
/**
|
|
262
338
|
* Builds a reusable Zod schema for one uploaded file with format and size.
|
|
263
339
|
* MIME matching is strict unless extension fallback is explicitly enabled.
|
|
@@ -767,4 +843,4 @@ declare const asQuery: <T extends z.ZodTypeAny>(schema: T) => z.ZodPreprocess<T>
|
|
|
767
843
|
*/
|
|
768
844
|
declare const isPlainObject: (value: unknown) => value is Record<string, unknown>;
|
|
769
845
|
|
|
770
|
-
export { type APIContractData, type APIContractError, type APIContractResult, type APIError, type APISuccess, type AsQuery, type AtLeastOne, EXCEPTION_STATUS_CODES, type ExceptionStatusCode, type FetchResult, type FileFormat, type FileFormatConfig, type HonoFileRespondOptions, type HonoRespondOptions, type JWTServiceOptions, type JWTSignOptions, type MeasuredExecution, type Payload, type PayloadSchema, type ReplaceDotsWithUnderscores, SUCCESS_STATUS_CODES, type Simplify, type StringEnumRecord, type SuccessStatusCode, type UploadFilesValidationOptions, type UploadFilesValidationResult, type UploadValidationError, type ZodBulkExcludeSelection, type ZodBulkIncludeSelection, type ZodBulkSelection, ZodJWTService, type ZodPaginationOptions, type ZodSearchSchemaOptions, type ZodUploadFileSchemaOptions, asQuery, createStringEnumRecord, createUploadAccept, createZodSearchWhereSchema, failure, fetchAndThrow, fetchSafely, fileFormat, fileFormatsArray, fileFormatsConfig, fileFormatsRecord, fileRespond, formatTime, generateRandomString, getColoredHTTPStatus, getFileExtension, getFormattedDate, getFormattedTime, getUTCOffset, getZonedTime, honoLoggingHandler, isFileExtensionSupported, isFileFormatSupported, isFileMimeTypeSupported, isPlainObject, log, matchesMimeType, measureExecutionTime, normalizeFileExtension, onHandlerError, parseQueryValue, respond, safeExecute, sqlWhere, success, uploadValidationError, uploadValidationErrorsArray, uploadValidationErrorsRecord, validateUploadFile, validateUploadFiles, zodAtLeastOne, zodBulkSelectionSchema, zodPaginationSchema, zodPaginationShape, zodSearchQuerySchema, zodSearchSchema, zodUploadFileSchema };
|
|
846
|
+
export { type APIContractData, type APIContractError, type APIContractResult, type APIError, type APISuccess, type AsQuery, type AtLeastOne, DEFAULT_UPLOAD_MAX_FILE_SIZE, EXCEPTION_STATUS_CODES, type ExceptionStatusCode, type FetchResult, type FileFormat, type FileFormatConfig, type HonoFileRespondOptions, type HonoLoggingOptions, type HonoRespondOptions, type JWTServiceOptions, type JWTSignOptions, type MeasuredExecution, type Payload, type PayloadSchema, type ReplaceDotsWithUnderscores, SUCCESS_STATUS_CODES, type Simplify, type StringEnumRecord, type SuccessStatusCode, type UploadFilesValidationOptions, type UploadFilesValidationResult, type UploadPreset, type UploadValidationError, type ZodBulkExcludeSelection, type ZodBulkIncludeSelection, type ZodBulkSelection, ZodJWTService, type ZodPaginationOptions, type ZodSearchSchemaOptions, type ZodUploadFileSchemaOptions, asQuery, createStringEnumRecord, createUploadAccept, createZodSearchWhereSchema, defineUploadPreset, documentUploadPreset, failure, fetchAndThrow, fetchSafely, fileFormat, fileFormatsArray, fileFormatsConfig, fileFormatsRecord, fileRespond, formatTime, generateRandomString, getColoredHTTPStatus, getFileExtension, getFormattedDate, getFormattedTime, getUTCOffset, getZonedTime, honoLoggingHandler, imageUploadPreset, isFileExtensionSupported, isFileFormatSupported, isFileMimeTypeSupported, isPlainObject, log, matchesMimeType, measureExecutionTime, normalizeFileExtension, onHandlerError, parseQueryValue, respond, safeExecute, sqlWhere, success, uploadValidationError, uploadValidationErrorsArray, uploadValidationErrorsRecord, validateUploadFile, validateUploadFiles, zodAtLeastOne, zodBulkSelectionSchema, zodPaginationSchema, zodPaginationShape, zodSearchQuerySchema, zodSearchSchema, zodUploadFileSchema };
|
package/dist/index.js
CHANGED
|
@@ -119,29 +119,31 @@ var onHandlerError = (error, c) => {
|
|
|
119
119
|
|
|
120
120
|
// src/hono/hono.logging.ts
|
|
121
121
|
import { blue as blue2, bold, dim as dim2, white as white2 } from "kleur/colors";
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
};
|
|
122
|
+
function honoLoggingHandler(options = {}) {
|
|
123
|
+
return async (c, next) => {
|
|
124
|
+
const searchParams = new URL(c.req.url).searchParams.toString();
|
|
125
|
+
const body = c.req.header("content-type")?.includes("multipart/form-data") ? (
|
|
126
|
+
// Multipart content remains unread to avoid buffering uploaded files;
|
|
127
|
+
// The placeholder records its presence without exposing any fields;
|
|
128
|
+
"[multipart]"
|
|
129
|
+
) : (
|
|
130
|
+
// Other bodies are read from a clone and normalized for one-line output;
|
|
131
|
+
// The original request stream remains available to downstream handlers;
|
|
132
|
+
(await c.req.raw.clone().text()).replaceAll(/\s+/g, " ").trim()
|
|
133
|
+
);
|
|
134
|
+
const bodyPreview = body.length > 60 ? `${body.slice(0, 30)}\u2026${body.slice(-30)}` : body;
|
|
135
|
+
const startTime = performance.now();
|
|
136
|
+
await next();
|
|
137
|
+
const duration = Math.round(performance.now() - startTime);
|
|
138
|
+
const coloredMethod = bold(blue2(c.req.method.padEnd(4)));
|
|
139
|
+
const coloredStatus = getColoredHTTPStatus(c.res.status)(String(c.res.status).padEnd(4));
|
|
140
|
+
const coloredTime = dim2(`${duration}ms`.padStart(6));
|
|
141
|
+
const coloredPath = white2(c.req.path.padEnd(32));
|
|
142
|
+
const coloredSearchParams = options.secure ? "" : dim2(` (${searchParams})`);
|
|
143
|
+
const coloredBody = options.secure ? "" : dim2(` ${bodyPreview}`);
|
|
144
|
+
log.info(`${coloredMethod} ${coloredStatus} ${coloredTime} ${coloredPath}${coloredSearchParams}${coloredBody}`, "hono");
|
|
145
|
+
};
|
|
146
|
+
}
|
|
145
147
|
|
|
146
148
|
// src/hono/hono.respond.ts
|
|
147
149
|
function respond(c, options) {
|
|
@@ -208,6 +210,22 @@ var fileFormatsConfig = {
|
|
|
208
210
|
[fileFormatsRecord.TXT]: { name: "TXT", mimeTypes: ["text/plain"], extensions: [".txt"] }
|
|
209
211
|
};
|
|
210
212
|
|
|
213
|
+
// src/upload/upload.factory.ts
|
|
214
|
+
function defineUploadPreset(preset) {
|
|
215
|
+
return preset;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// src/upload/upload.presets.ts
|
|
219
|
+
var DEFAULT_UPLOAD_MAX_FILE_SIZE = 20 * 1024 * 1024;
|
|
220
|
+
var imageUploadPreset = defineUploadPreset({
|
|
221
|
+
formats: [fileFormat.PNG, fileFormat.JPG, fileFormat.WEBP, fileFormat.AVIF, fileFormat.HEIC],
|
|
222
|
+
maxFileSize: DEFAULT_UPLOAD_MAX_FILE_SIZE
|
|
223
|
+
});
|
|
224
|
+
var documentUploadPreset = defineUploadPreset({
|
|
225
|
+
formats: [fileFormat.PDF, fileFormat.RTF, fileFormat.TXT],
|
|
226
|
+
maxFileSize: DEFAULT_UPLOAD_MAX_FILE_SIZE
|
|
227
|
+
});
|
|
228
|
+
|
|
211
229
|
// src/upload/upload.schemas.ts
|
|
212
230
|
import { z } from "zod";
|
|
213
231
|
|
|
@@ -430,6 +448,7 @@ var parseQueryValue = (value) => {
|
|
|
430
448
|
};
|
|
431
449
|
var asQuery = (schema) => z5.preprocess(parseQueryValue, schema);
|
|
432
450
|
export {
|
|
451
|
+
DEFAULT_UPLOAD_MAX_FILE_SIZE,
|
|
433
452
|
EXCEPTION_STATUS_CODES,
|
|
434
453
|
SUCCESS_STATUS_CODES,
|
|
435
454
|
ZodJWTService,
|
|
@@ -437,6 +456,8 @@ export {
|
|
|
437
456
|
createStringEnumRecord,
|
|
438
457
|
createUploadAccept,
|
|
439
458
|
createZodSearchWhereSchema,
|
|
459
|
+
defineUploadPreset,
|
|
460
|
+
documentUploadPreset,
|
|
440
461
|
failure,
|
|
441
462
|
fetchAndThrow,
|
|
442
463
|
fetchSafely,
|
|
@@ -454,6 +475,7 @@ export {
|
|
|
454
475
|
getUTCOffset,
|
|
455
476
|
getZonedTime,
|
|
456
477
|
honoLoggingHandler,
|
|
478
|
+
imageUploadPreset,
|
|
457
479
|
isFileExtensionSupported,
|
|
458
480
|
isFileFormatSupported,
|
|
459
481
|
isFileMimeTypeSupported,
|