@kalutskii/foundation 0.6.22 → 0.6.24

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 CHANGED
@@ -144,7 +144,7 @@ schema.parse({ page: '2', isActive: 'true' }); // { page: 2, isActive: true }
144
144
 
145
145
  `asQuery` preprocesses string values from query parameters — coercing `'true'`/`'false'` to booleans and numeric strings to numbers — before passing them to the Zod schema for validation.
146
146
 
147
- ### 8. Build flat query schemas from nested objects
147
+ ### 7. Build flat query schemas from nested objects
148
148
 
149
149
  ```typescript
150
150
  import { asQuerySchema } from '@kalutskii/foundation';
@@ -171,29 +171,62 @@ schema.parse({ sort: { field: 'name', order: 'asc' } }); // throws
171
171
 
172
172
  `asQuerySchema` flattens nested `z.object(...)` fields to the top level, making it suitable for flat query parameter validation. Nested object fields are lifted, while optionality is preserved: required parents keep their fields required, optional parents make all promoted fields optional. The result is a strict schema (unknown keys are rejected).
173
173
 
174
- ### 8. Use pagination schema
174
+ ### 8. Build reusable search schemas
175
175
 
176
176
  ```typescript
177
- import { refinePagination, zodPaginationSchema, zodPaginationShape } from '@kalutskii/foundation';
177
+ import { zodPaginationSchema, zodSearchSchema } from '@kalutskii/foundation';
178
178
  import { z } from 'zod';
179
179
 
180
- // Use as a standalone schema
181
- const options = zodPaginationSchema.parse({ offset: '0', limit: '20' });
180
+ const assetSchema = z.object({
181
+ status: z.enum(['active', 'archived']),
182
+ categoryId: z.number(),
183
+ });
184
+
185
+ const assetSearchSchema = zodSearchSchema({
186
+ filters: assetSchema.pick({ status: true, categoryId: true }),
187
+ });
188
+
189
+ type AssetSearch = z.infer<typeof assetSearchSchema>;
190
+
191
+ assetSearchSchema.parse({
192
+ where: { status: 'active' },
193
+ query: 'asset name',
194
+ pagination: { offset: 0, limit: 20 },
195
+ });
196
+
197
+ // Pagination remains available as a standalone reusable schema.
198
+ zodPaginationSchema.parse({ offset: '0', limit: '20' });
182
199
  // { offset: 0, limit: 20 }
200
+ ```
183
201
 
184
- // Spread shape into a larger query schema
185
- const querySchema = z.object({
186
- search: z.string().optional(),
187
- ...zodPaginationShape,
202
+ ### 9. Share bulk selection between frontend and backend
203
+
204
+ ```typescript
205
+ import { zodBulkSelectionSchema, zodSearchSchema } from '@kalutskii/foundation';
206
+ import { z } from 'zod';
207
+
208
+ const assetBulkSelectionSchema = zodBulkSelectionSchema({
209
+ identifierSchema: z.string().min(1),
188
210
  });
189
211
 
190
- // Strip undefined pagination values before passing to a query builder (e.g. Drizzle)
191
- await db.query.users.findMany({
192
- ...refinePagination(options),
212
+ const assetBulkFilterSchema = zodSearchSchema({
213
+ filters: assetSchema.pick({ status: true, categoryId: true }),
214
+ paginationEnabled: false,
193
215
  });
216
+
217
+ const assetBulkRequestSchema = z
218
+ .object({
219
+ selection: assetBulkSelectionSchema,
220
+ filter: assetBulkFilterSchema,
221
+ })
222
+ .strict();
223
+
224
+ type AssetBulkRequest = z.infer<typeof assetBulkRequestSchema>;
194
225
  ```
195
226
 
196
- ### 9. Work with JWT using `ZodJWTService`
227
+ In `include` mode, the backend targets only `identifiers`. In `exclude` mode, it resolves all entities matching the same filter snapshot and removes `excludedIdentifiers` from that operation.
228
+
229
+ ### 10. Work with JWT using `ZodJWTService`
197
230
 
198
231
  ```typescript
199
232
  import { ZodJWTService } from '@kalutskii/foundation';
@@ -210,7 +243,7 @@ const payload = await jwt.verifyOrThrow(token, 'secret');
210
243
  const decoded = await jwt.decode(token);
211
244
  ```
212
245
 
213
- ### 10. Datetime helpers
246
+ ### 11. Datetime helpers
214
247
 
215
248
  ```typescript
216
249
  import { formatTime, getFormattedDate, getFormattedTime, getZonedTime } from '@kalutskii/foundation';
@@ -221,7 +254,7 @@ getFormattedDate({ tz: 'Europe/Moscow', withTime: false }); // '22.06.2026'
221
254
  formatTime(new Date(), { tz: 'Europe/Moscow' }); // '15:30:00, 22 июня 2026 (+3 UTC)'
222
255
  ```
223
256
 
224
- ### 11. Logging
257
+ ### 12. Logging
225
258
 
226
259
  ```typescript
227
260
  import { log } from '@kalutskii/foundation';
@@ -239,8 +272,10 @@ The package exports all public APIs from a single entrypoint:
239
272
  - **HTTP**: `success`, `failure`, `fetchSafely`, `fetchAndThrow`, constants, schemas.
240
273
  - **Hono**: `respond`, `onHandlerError`, `honoLoggingHandler`.
241
274
  - **Utilities**: `safeExecute`, `measureExecutionTime`, `generateRandomString`, `log`, `getColoredHTTPStatus`, datetime helpers.
275
+ - **Zod Bulk**: `zodBulkSelectionSchema`, `ZodBulkSelection`, `ZodBulkIncludeSelection`, `ZodBulkExcludeSelection`.
242
276
  - **Zod JWT**: `ZodJWTService`.
243
- - **Zod Pagination**: `zodPaginationSchema`, `zodPaginationShape`, `refinePagination`, `ZodPaginationOptions`.
277
+ - **Zod Search**: `zodSearchSchema`, `ZodSearchSchemaOptions`.
278
+ - **Zod Pagination**: `zodPaginationSchema`, `zodPaginationShape`, `ZodPaginationOptions`.
244
279
  - **Zod Flatten**: `asQuerySchema`, `flattenZodShape`, `isZodObject`, `isZodOptional`, `unwrapOptional`, `FlattenZodShape`.
245
280
  - **Zod Validation**: `asQuery`, `AsQuery`, `AtLeastOne`.
246
281
  - **Type Utilities**: `Simplify`.
package/dist/index.d.ts CHANGED
@@ -1,8 +1,8 @@
1
- import { SQL, Simplify as Simplify$1 } from 'drizzle-orm';
1
+ import { SQL } from 'drizzle-orm';
2
2
  import { ErrorHandler, MiddlewareHandler, Context, TypedResponse } from 'hono';
3
3
  import { Locale } from 'date-fns';
4
- import { SymmetricAlgorithm } from 'hono/utils/jwt/jwa';
5
4
  import z, { ZodObject, ZodRawShape, z as z$1 } from 'zod';
5
+ import { SymmetricAlgorithm } from 'hono/utils/jwt/jwa';
6
6
 
7
7
  /**
8
8
  * Builds a Drizzle SQL `where` condition from a plain object.
@@ -222,6 +222,52 @@ type Simplify<T> = {
222
222
  [K in keyof T]: T[K];
223
223
  } & {};
224
224
 
225
+ /**
226
+ * Builds a strict selection contract for bulk operations across paginated data.
227
+ * The identifier schema is shared by explicit and all-matching selection modes.
228
+ *
229
+ * `include` targets only identifiers listed by the client. `exclude` targets every
230
+ * item matching the accompanying search snapshot except excluded identifiers.
231
+ *
232
+ * @example
233
+ * const assetBulkSelectionSchema = zodBulkSelectionSchema({
234
+ * identifierSchema: z.string().min(1),
235
+ * });
236
+ */
237
+ declare const zodBulkSelectionSchema: <const TIdentifierSchema extends z.ZodType<string | number>>({ identifierSchema, }: {
238
+ /**
239
+ * Schema used to validate every included or excluded entity identifier.
240
+ * Its transforms and exact inferred output are preserved in both branches.
241
+ */
242
+ identifierSchema: TIdentifierSchema;
243
+ }) => z.ZodDiscriminatedUnion<[z.ZodObject<{
244
+ mode: z.ZodLiteral<"include">;
245
+ identifiers: z.ZodArray<TIdentifierSchema>;
246
+ }, z.core.$strict>, z.ZodObject<{
247
+ mode: z.ZodLiteral<"exclude">;
248
+ excludedIdentifiers: z.ZodArray<TIdentifierSchema>;
249
+ }, z.core.$strict>], "mode">;
250
+
251
+ /**
252
+ * Shared bulk-selection payload produced by `zodBulkSelectionSchema`.
253
+ * String identifiers are used by default for frontend table integrations.
254
+ */
255
+ type ZodBulkSelection<TIdentifier extends string | number = string> = z.infer<ReturnType<typeof zodBulkSelectionSchema<z.ZodType<TIdentifier>>>>;
256
+ /**
257
+ * Explicit bulk selection containing only identifiers chosen by the client.
258
+ * This branch does not require resolving an all-matching search snapshot.
259
+ */
260
+ type ZodBulkIncludeSelection<TIdentifier extends string | number = string> = Extract<ZodBulkSelection<TIdentifier>, {
261
+ mode: 'include';
262
+ }>;
263
+ /**
264
+ * All-matching bulk selection containing identifiers excluded by the client.
265
+ * Backend handlers must resolve targets from the same search snapshot.
266
+ */
267
+ type ZodBulkExcludeSelection<TIdentifier extends string | number = string> = Extract<ZodBulkSelection<TIdentifier>, {
268
+ mode: 'exclude';
269
+ }>;
270
+
225
271
  /** Options for configuring the JWT service. */
226
272
  type JWTServiceOptions = {
227
273
  /** The algorithm to use for signing and verifying JWTs. Defaults to 'HS256'. */
@@ -274,26 +320,122 @@ declare class ZodJWTService<TPayloadOrSchema> {
274
320
  verifyOrThrow(token: string, secret: string): Promise<Payload<TPayloadOrSchema>>;
275
321
  }
276
322
 
323
+ /**
324
+ * Validates offset-based pagination shared by search request contracts.
325
+ * Missing fields inside the required object receive predictable defaults.
326
+ */
277
327
  declare const zodPaginationSchema: z.ZodObject<{
278
328
  offset: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
279
329
  limit: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
280
330
  }, z.core.$strip>;
281
331
  /**
282
- * Reusable pagination fields for flat query schemas, allowing for
283
- * consistent validation of pagination parameters across different endpoints.
284
- *
285
- * Spread into another `z.object(...)` when composing a larger query schema,
286
- * or use `zodPaginationSchema.extend(...)` when building directly from the schema.
332
+ * Exposes pagination fields for composition into other object schemas.
333
+ * The shape stays derived from the schema to prevent contract divergence.
287
334
  */
288
335
  declare const zodPaginationShape: {
289
336
  offset: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
290
337
  limit: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
291
338
  };
339
+
292
340
  /**
293
- * TypeScript type representing the pagination options validated by the `zodPaginationSchema`.
294
- * Read documentation for `zodPaginationSchema` for more details on the structure and usage of this type.
341
+ * TypeScript output produced after successful pagination validation.
342
+ * Defaulted fields are represented as required numeric properties.
295
343
  */
296
344
  type ZodPaginationOptions = z.infer<typeof zodPaginationSchema>;
345
+ /**
346
+ * Feature flags shared by both supported search schema composition modes.
347
+ * Literal values are preserved in the resulting runtime and static shapes.
348
+ */
349
+ type ZodSearchFeatureOptions<TQueryEnabled extends boolean, TPaginationEnabled extends boolean> = {
350
+ /**
351
+ * Controls whether an optional non-empty `query` field is generated.
352
+ * The field is enabled when this option is omitted from the call.
353
+ */
354
+ queryEnabled?: TQueryEnabled;
355
+ /**
356
+ * Controls whether a required `pagination` object is generated.
357
+ * The field is enabled when this option is omitted from the call.
358
+ */
359
+ paginationEnabled?: TPaginationEnabled;
360
+ };
361
+ /**
362
+ * Configuration used to compose a reusable search request schema.
363
+ * Exactly one source must be provided for the resulting `where` field.
364
+ *
365
+ * `filters` is the concise mode that applies partial and non-empty rules.
366
+ * `whereSchema` accepts a fully prepared schema with custom Zod effects.
367
+ */
368
+ type ZodSearchSchemaOptions<TShape extends z.ZodRawShape = never, TWhereSchema extends z.ZodType<Record<string, unknown>> = never, TQueryEnabled extends boolean = true, TPaginationEnabled extends boolean = true> = ZodSearchFeatureOptions<TQueryEnabled, TPaginationEnabled> & ({
369
+ /**
370
+ * Object schema whose fields become optional filters inside `where`.
371
+ * The factory requires one defined value whenever `where` is present.
372
+ */
373
+ filters: z.ZodObject<TShape>;
374
+ /** Prevents combining automatic filters with a prepared schema. */
375
+ whereSchema?: never;
376
+ } | {
377
+ /** Prevents combining a prepared schema with automatic filters. */
378
+ filters?: never;
379
+ /**
380
+ * Prepared schema used directly to validate the `where` object.
381
+ * Its refinements, transforms, and inferred output are preserved.
382
+ */
383
+ whereSchema: TWhereSchema;
384
+ });
385
+
386
+ /**
387
+ * Optional text query shared by search request contracts.
388
+ * Provided values are trimmed and must contain visible text.
389
+ */
390
+ declare const zodSearchQuerySchema: z.ZodOptional<z.ZodString>;
391
+ /**
392
+ * Makes every supplied filter optional while requiring one defined value.
393
+ * Top-level optionality is added later for both composition modes equally.
394
+ */
395
+ declare const createZodSearchWhereSchema: <TShape extends z.ZodRawShape>(filters: z.ZodObject<TShape>) => z.ZodPipe<z.ZodObject<{ -readonly [k in keyof TShape]: z.ZodOptional<TShape[k]>; }, z.core.$strip>, z.ZodTransform<Awaited<AtLeastOne<z.core.$InferObjectOutput<{ -readonly [k in keyof TShape]: z.ZodOptional<TShape[k]>; }, {}>, keyof z.core.$InferObjectOutput<{ -readonly [k in keyof TShape]: z.ZodOptional<TShape[k]>; }, {}>>>, z.core.$InferObjectOutput<{ -readonly [k in keyof TShape]: z.ZodOptional<TShape[k]>; }, {}>>>;
396
+ /**
397
+ * Empty schema shape used when a search feature is explicitly disabled.
398
+ * Intersections remove disabled fields without widening enabled branches.
399
+ */
400
+ type ZodDisabledSearchShape = Record<never, never>;
401
+ /**
402
+ * Resolves the schema used by `where` from the selected composition mode.
403
+ * Prepared schemas remain untouched, including their effects and output.
404
+ */
405
+ type ZodSearchWhereSchema<TShape extends z.ZodRawShape, TWhereSchema extends z.ZodType<Record<string, unknown>>> = [
406
+ TWhereSchema
407
+ ] extends [never] ? ReturnType<typeof createZodSearchWhereSchema<TShape>> : TWhereSchema;
408
+ /**
409
+ * Schema-level shape assembled from the selected source and feature flags.
410
+ * Keeping Zod schemas here makes runtime composition the contract source.
411
+ */
412
+ type ZodSearchShape<TShape extends z.ZodRawShape, TWhereSchema extends z.ZodType<Record<string, unknown>>, TQueryEnabled extends boolean, TPaginationEnabled extends boolean> = {
413
+ where: z.ZodOptional<ZodSearchWhereSchema<TShape, TWhereSchema>>;
414
+ } & (TQueryEnabled extends false ? ZodDisabledSearchShape : {
415
+ query: typeof zodSearchQuerySchema;
416
+ }) & (TPaginationEnabled extends false ? ZodDisabledSearchShape : {
417
+ pagination: typeof zodPaginationSchema;
418
+ });
419
+ /**
420
+ * Builds a strict schema for reusable search request contracts.
421
+ * The optional `where` object must contain one defined filter.
422
+ *
423
+ * Query is optional and non-empty; pagination is required by default.
424
+ * Literal feature flags update both runtime and inferred static shapes.
425
+ *
426
+ * Pass `filters` for automatic partial and non-empty validation, or use
427
+ * `whereSchema` to preserve a prepared schema with custom Zod effects.
428
+ *
429
+ * @example
430
+ * const assetSearchSchema = zodSearchSchema({
431
+ * filters: assetSchema.pick({ status: true }),
432
+ * });
433
+ *
434
+ * const refinedAssetSearchSchema = zodSearchSchema({
435
+ * whereSchema: zodAtLeastOne(assetSchema.pick({ status: true }).partial()),
436
+ * });
437
+ */
438
+ declare const zodSearchSchema: <const TShape extends z.ZodRawShape = never, const TWhereSchema extends z.ZodType<Record<string, unknown>> = never, const TQueryEnabled extends boolean = true, const TPaginationEnabled extends boolean = true>(options: ZodSearchSchemaOptions<TShape, TWhereSchema, TQueryEnabled, TPaginationEnabled>) => z.ZodObject<ZodSearchShape<TShape, TWhereSchema, TQueryEnabled, TPaginationEnabled> extends infer T ? { -readonly [P in keyof T]: T[P]; } : never, z.core.$strict>;
297
439
 
298
440
  type QueryPrimitive = string | number | boolean | bigint | Date;
299
441
  /**
@@ -316,7 +458,7 @@ type AsQuery<T> = T extends null | undefined ? T : T extends QueryPrimitive ? st
316
458
  * // Invalid: {}, { a: undefined, b: undefined, c: undefined }
317
459
  * ```
318
460
  */
319
- type AtLeastOne<T, Keys extends keyof T = keyof T> = Keys extends keyof T ? Simplify$1<Required<Pick<T, Keys>> & Partial<Omit<T, Keys>>> : never;
461
+ type AtLeastOne<T, Keys extends keyof T = keyof T> = Keys extends keyof T ? Simplify<Required<Pick<T, Keys>> & Partial<Omit<T, Keys>>> : never;
320
462
 
321
463
  /**
322
464
  * Wraps a partial Zod object schema with:
@@ -356,4 +498,4 @@ declare const asQuery: <T extends z.ZodTypeAny>(schema: T) => z.ZodPreprocess<T>
356
498
  */
357
499
  declare const isPlainObject: (value: unknown) => value is Record<string, unknown>;
358
500
 
359
- 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 Payload, type PayloadSchema, type ReplaceDotsWithUnderscores, SUCCESS_STATUS_CODES, type Simplify, type StringEnumRecord, type SuccessStatusCode, ZodJWTService, type ZodPaginationOptions, asQuery, createStringEnumRecord, failure, fetchAndThrow, fetchSafely, formatTime, generateRandomString, getColoredHTTPStatus, getFormattedDate, getFormattedTime, getUTCOffset, getZonedTime, honoLoggingHandler, isPlainObject, log, measureExecutionTime, onHandlerError, parseQueryValue, respond, safeExecute, sqlWhere, success, zodAtLeastOne, zodPaginationSchema, zodPaginationShape };
501
+ 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 Payload, type PayloadSchema, type ReplaceDotsWithUnderscores, SUCCESS_STATUS_CODES, type Simplify, type StringEnumRecord, type SuccessStatusCode, type ZodBulkExcludeSelection, type ZodBulkIncludeSelection, type ZodBulkSelection, ZodJWTService, type ZodPaginationOptions, type ZodSearchSchemaOptions, asQuery, createStringEnumRecord, failure, fetchAndThrow, fetchSafely, formatTime, generateRandomString, getColoredHTTPStatus, getFormattedDate, getFormattedTime, getUTCOffset, getZonedTime, honoLoggingHandler, isPlainObject, log, measureExecutionTime, onHandlerError, parseQueryValue, respond, safeExecute, sqlWhere, success, zodAtLeastOne, zodBulkSelectionSchema, zodPaginationSchema, zodPaginationShape, zodSearchSchema };
package/dist/index.js CHANGED
@@ -164,6 +164,19 @@ async function measureExecutionTime(execution) {
164
164
  return { result, executionTime: Math.round(executionTime) };
165
165
  }
166
166
 
167
+ // src/zod-bulk/zod-bulk.schemas.ts
168
+ import z from "zod";
169
+ var DEFAULT_ERROR_MESSAGE = "Selection identifiers must be provided.";
170
+ var zodBulkSelectionSchema = ({ identifierSchema }) => {
171
+ const identifiersSchema = z.array(identifierSchema).refine((identifiers) => new Set(identifiers).size === identifiers.length, {
172
+ message: DEFAULT_ERROR_MESSAGE
173
+ });
174
+ return z.discriminatedUnion("mode", [
175
+ z.object({ mode: z.literal("include"), identifiers: identifiersSchema }).strict(),
176
+ z.object({ mode: z.literal("exclude"), excludedIdentifiers: identifiersSchema }).strict()
177
+ ]);
178
+ };
179
+
167
180
  // src/zod-jwt/zod-jwt.schemas.ts
168
181
  import { decode as decodeJWT, sign as signJWT, verify as verifyJWT } from "hono/jwt";
169
182
  var ZodJWTService = class {
@@ -213,26 +226,48 @@ var ZodJWTService = class {
213
226
  }
214
227
  };
215
228
 
216
- // src/zod-pagination/zod-pagination.schemas.ts
217
- import z from "zod";
218
- var zodPaginationSchema = z.object({
219
- /** Integer representing the starting point for pagination. */
220
- offset: z.coerce.number().int().nonnegative().default(0),
221
- /** Integer representing the maximum number of items to return. */
222
- limit: z.coerce.number().int().positive().default(10)
229
+ // src/zod-search/zod-search.pagination.schemas.ts
230
+ import z2 from "zod";
231
+ var zodPaginationSchema = z2.object({
232
+ /**
233
+ * Zero-based number of records skipped before collecting a result page.
234
+ * String values are coerced to support validation of URL query input.
235
+ */
236
+ offset: z2.coerce.number().int().nonnegative().default(0),
237
+ /**
238
+ * Positive maximum number of records returned in a single result page.
239
+ * String values are coerced to support validation of URL query input.
240
+ */
241
+ limit: z2.coerce.number().int().positive().default(10)
223
242
  });
224
243
  var zodPaginationShape = zodPaginationSchema.shape;
225
244
 
245
+ // src/zod-search/zod-search.schemas.ts
246
+ import z3 from "zod";
247
+
226
248
  // src/zod-validation/zod-validation.refiners.ts
227
- var DEFAULT_ERROR_MESSAGE = "Invalid input. At least one field must be provided.";
249
+ var DEFAULT_ERROR_MESSAGE2 = "Invalid input. At least one field must be provided.";
228
250
  var zodAtLeastOne = (schema) => schema.superRefine((val, ctx) => {
229
251
  const hasValue = Object.values(val).some((v) => v !== void 0);
230
252
  if (!hasValue)
231
- ctx.addIssue({ code: "custom", message: DEFAULT_ERROR_MESSAGE });
253
+ ctx.addIssue({ code: "custom", message: DEFAULT_ERROR_MESSAGE2 });
232
254
  }).transform((val) => val);
233
255
 
256
+ // src/zod-search/zod-search.schemas.ts
257
+ var zodSearchQuerySchema = z3.string().trim().min(1).optional();
258
+ var createZodSearchWhereSchema = (filters) => zodAtLeastOne(filters.partial());
259
+ var zodSearchSchema = (options) => {
260
+ const whereSchema = options.filters !== void 0 ? createZodSearchWhereSchema(options.filters) : options.whereSchema;
261
+ const shape = {
262
+ where: whereSchema.optional(),
263
+ ...options.queryEnabled !== false ? { query: zodSearchQuerySchema } : {},
264
+ ...options.paginationEnabled !== false ? { pagination: zodPaginationSchema } : {}
265
+ };
266
+ return z3.object(shape).strict();
267
+ };
268
+
234
269
  // src/zod-validation/zod-validation.parsing.ts
235
- import z2 from "zod";
270
+ import z4 from "zod";
236
271
 
237
272
  // src/zod-validation/zod-validation.utilities.ts
238
273
  var isPlainObject = (value) => {
@@ -259,7 +294,7 @@ var parseQueryValue = (value) => {
259
294
  return Number(normalized);
260
295
  return value;
261
296
  };
262
- var asQuery = (schema) => z2.preprocess(parseQueryValue, schema);
297
+ var asQuery = (schema) => z4.preprocess(parseQueryValue, schema);
263
298
  export {
264
299
  EXCEPTION_STATUS_CODES,
265
300
  SUCCESS_STATUS_CODES,
@@ -287,6 +322,8 @@ export {
287
322
  sqlWhere,
288
323
  success,
289
324
  zodAtLeastOne,
325
+ zodBulkSelectionSchema,
290
326
  zodPaginationSchema,
291
- zodPaginationShape
327
+ zodPaginationShape,
328
+ zodSearchSchema
292
329
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kalutskii/foundation",
3
- "version": "0.6.22",
3
+ "version": "0.6.24",
4
4
  "description": "Typescript collection of most common utilities, schemas and functions among private projects.",
5
5
  "type": "module",
6
6
  "repository": {
@@ -14,6 +14,7 @@
14
14
  "build": "tsup",
15
15
  "lint": "eslint . --ext .ts --fix",
16
16
  "format": "prettier --write .",
17
+ "test": "bun test",
17
18
  "typecheck": "tsc --noEmit"
18
19
  },
19
20
  "exports": {