@kalutskii/foundation 0.6.20 → 0.6.22

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 CHANGED
@@ -58,29 +58,6 @@ type FetchResult<T> = {
58
58
  data: null;
59
59
  };
60
60
 
61
- type QueryPrimitive = string | number | boolean | bigint | Date;
62
- /**
63
- * Recursively transforms all fields of T to `string`, matching how query parameters are serialized.
64
- * Handles nested objects, arrays, and primitive values (including null and undefined as optional).
65
- */
66
- type AsQuery<T> = T extends null | undefined ? T : T extends QueryPrimitive ? string : T extends readonly (infer Item)[] ? AsQuery<Item>[] : T extends object ? {
67
- [Key in keyof T]: AsQuery<T[Key]>;
68
- } : string;
69
- /**
70
- * Utility type that ensures at least one property from the specified
71
- * keys of a given type T is required, while the rest remain optional.
72
- *
73
- * This is useful for scenarios where you want to enforce that at least one
74
- * of several optional (nullable) properties must be provided in an object.
75
- *
76
- * ```typescript
77
- * type Example = AtLeastOne<{ a?: string; b?: number; c?: boolean }>;
78
- * // Valid: { a: "hello" }, { b: 42 }, { c: true }, { a: "hello", b: 42 }
79
- * // Invalid: {}, { a: undefined, b: undefined, c: undefined }
80
- * ```
81
- */
82
- type AtLeastOne<T, Keys extends keyof T = keyof T> = Keys extends keyof T ? Simplify$1<Required<Pick<T, Keys>> & Partial<Omit<T, Keys>>> : never;
83
-
84
61
  /**
85
62
  * Wraps c.json with a typed success payload / (or void data) & possible APIError response.
86
63
  * When no data is provided, responds with an empty object {} (purely for type consistency).
@@ -88,7 +65,7 @@ type AtLeastOne<T, Keys extends keyof T = keyof T> = Keys extends keyof T ? Simp
88
65
  declare function respond<T extends object = Record<string, never>, S extends SuccessStatusCode = SuccessStatusCode>(c: Context, options: {
89
66
  status: S;
90
67
  data?: T;
91
- }): Response & TypedResponse<APISuccess<AsQuery<T>> | APIError, S, 'json'>;
68
+ }): Response & TypedResponse<APISuccess<T> | APIError, S, 'json'>;
92
69
 
93
70
  /**
94
71
  * Factory for creating successful API responses with serializable data.
@@ -174,6 +151,24 @@ declare const formatTime: (time: Date, { locale, tz }?: {
174
151
  tz?: string;
175
152
  }) => string;
176
153
 
154
+ /**
155
+ * Recursively replaces dots in a string with underscores in a type-safe manner.
156
+ * Example: `ReplaceDotsWithUnderscores<'foo.bar.baz.ok'>` → `'foo_bar_baz_ok'`.
157
+ */
158
+ type ReplaceDotsWithUnderscores<T extends string> = T extends `${infer A}.${infer B}` ? `${A}_${ReplaceDotsWithUnderscores<B>}` : T;
159
+ /**
160
+ * Type-safe record mapping string values to ergonomic enum-like keys.
161
+ * Keys are uppercased and dots are replaced with underscores.
162
+ */
163
+ type StringEnumRecord<T extends readonly string[]> = Readonly<{
164
+ [Value in T[number] as Uppercase<ReplaceDotsWithUnderscores<Value>>]: Value;
165
+ }>;
166
+ /**
167
+ * Creates an immutable enum-like record from a readonly string array.
168
+ * Example: `['foo.s', 'baz'] as const` → `{ FOO_S: 'foo.s', BAZ: 'baz' }`.
169
+ */
170
+ declare function createStringEnumRecord<const T extends readonly string[]>(values: T): StringEnumRecord<T>;
171
+
177
172
  /**
178
173
  * Safely executes functions and handles errors without using try/catch in the calling code.
179
174
  * Example usage: `safeExecute(() => fetchData(), (error) => console.error(error))`
@@ -300,6 +295,29 @@ declare const zodPaginationShape: {
300
295
  */
301
296
  type ZodPaginationOptions = z.infer<typeof zodPaginationSchema>;
302
297
 
298
+ type QueryPrimitive = string | number | boolean | bigint | Date;
299
+ /**
300
+ * Recursively transforms all fields of T to `string`, matching how query parameters are serialized.
301
+ * Handles nested objects, arrays, and primitive values (including null and undefined as optional).
302
+ */
303
+ type AsQuery<T> = T extends null | undefined ? T : T extends QueryPrimitive ? string : T extends readonly (infer Item)[] ? AsQuery<Item>[] : T extends object ? {
304
+ [Key in keyof T]: AsQuery<T[Key]>;
305
+ } : string;
306
+ /**
307
+ * Utility type that ensures at least one property from the specified
308
+ * keys of a given type T is required, while the rest remain optional.
309
+ *
310
+ * This is useful for scenarios where you want to enforce that at least one
311
+ * of several optional (nullable) properties must be provided in an object.
312
+ *
313
+ * ```typescript
314
+ * type Example = AtLeastOne<{ a?: string; b?: number; c?: boolean }>;
315
+ * // Valid: { a: "hello" }, { b: 42 }, { c: true }, { a: "hello", b: 42 }
316
+ * // Invalid: {}, { a: undefined, b: undefined, c: undefined }
317
+ * ```
318
+ */
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;
320
+
303
321
  /**
304
322
  * Wraps a partial Zod object schema with:
305
323
  * 1. A runtime check ensuring at least one field is non-undefined.
@@ -338,4 +356,4 @@ declare const asQuery: <T extends z.ZodTypeAny>(schema: T) => z.ZodPreprocess<T>
338
356
  */
339
357
  declare const isPlainObject: (value: unknown) => value is Record<string, unknown>;
340
358
 
341
- 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, SUCCESS_STATUS_CODES, type Simplify, type SuccessStatusCode, ZodJWTService, type ZodPaginationOptions, asQuery, failure, fetchAndThrow, fetchSafely, formatTime, generateRandomString, getColoredHTTPStatus, getFormattedDate, getFormattedTime, getUTCOffset, getZonedTime, honoLoggingHandler, isPlainObject, log, measureExecutionTime, onHandlerError, parseQueryValue, respond, safeExecute, sqlWhere, success, zodAtLeastOne, zodPaginationSchema, zodPaginationShape };
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 };
package/dist/index.js CHANGED
@@ -142,6 +142,11 @@ async function fetchAndThrow(fetcher) {
142
142
  return response.data;
143
143
  }
144
144
 
145
+ // src/utilities/enums.utilities.ts
146
+ function createStringEnumRecord(values) {
147
+ return Object.freeze(Object.fromEntries(values.map((value) => [value.replace(/\./g, "_").toUpperCase(), value])));
148
+ }
149
+
145
150
  // src/utilities/execution.utilities.ts
146
151
  async function safeExecute(fn, onError) {
147
152
  try {
@@ -260,6 +265,7 @@ export {
260
265
  SUCCESS_STATUS_CODES,
261
266
  ZodJWTService,
262
267
  asQuery,
268
+ createStringEnumRecord,
263
269
  failure,
264
270
  fetchAndThrow,
265
271
  fetchSafely,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kalutskii/foundation",
3
- "version": "0.6.20",
3
+ "version": "0.6.22",
4
4
  "description": "Typescript collection of most common utilities, schemas and functions among private projects.",
5
5
  "type": "module",
6
6
  "repository": {