@arkstack/common 0.17.12 → 0.17.13

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
@@ -739,15 +739,30 @@ Key exported types from the package:
739
739
 
740
740
  **`src/utils/helpers.ts`**
741
741
 
742
- #### `perPage(query)`
742
+ #### `perPage(query, defaults?)`
743
743
 
744
- Extracts a safe pagination limit from a query object. Clamps the result between `1` and `50`, defaulting to `15`.
744
+ Extracts a safe pagination limit from a query object. Clamps the result between `1` and `50` or the configured default `maxPerPage`, defaulting to `25` or the configured default `perPage`.
745
745
 
746
746
  ```ts
747
747
  import { perPage } from '@arkstack/common';
748
748
 
749
749
  const limit = perPage({ limit: 100 }); // 50 (clamped)
750
- const limit2 = perPage({}); // 15 (default)
750
+ const limit2 = perPage({ limit: 100 }, { maxPerPage: 100 }); // 100
751
+ const limit3 = perPage({}); // 25 (default)
752
+ const limit3 = perPage({}, { perPage: 100 }); // 100
753
+ ```
754
+
755
+ #### `resolvePagination(query, defaults?)`
756
+
757
+ Extracts the current page and a safe pagination limit from a query object. Clamps the resulting `perPage` between `1` and `50` or the configured default `maxPerPage`, defaulting to `25` or the configured default `perPage`.
758
+
759
+ ```ts
760
+ import { resolvePagination } from '@arkstack/common';
761
+
762
+ const limit = resolvePagination({ limit: 100 }); // {perPage: 50, page: 1} (clamped)
763
+ const limi2 = resolvePagination({ limit: 100 }, { maxPerPage: 100 }); // {perPage: 100, page: 1}
764
+ const limit3 = resolvePagination({}); // {perPage: 50, page: 1} (default)
765
+ const limit4 = resolvePagination({}, { perPage: 100, page: 2 }); // {perPage: 100, page: 2}
751
766
  ```
752
767
 
753
768
  #### `getModel(modelName)`
@@ -0,0 +1,531 @@
1
+ import { JitiOptions, JitiResolveOptions } from "jiti";
2
+ import { TOTP } from "otpauth";
3
+ import { ChalkInstance } from "chalk";
4
+ import { Model, ModelStatic } from "arkormx";
5
+
6
+ //#region src/Logger.d.ts
7
+ declare class Console {
8
+ static log: (...args: any[]) => string | void;
9
+ static debug: (...args: any[]) => void;
10
+ static warn: (...args: any[]) => void[];
11
+ static info: (...args: any[]) => void[];
12
+ static error: (...args: any[]) => void[];
13
+ }
14
+ declare class Logger {
15
+ /**
16
+ * Global verbosity configuration
17
+ */
18
+ private static verbosity;
19
+ private static isQuiet;
20
+ private static isSilent;
21
+ /**
22
+ * Configure global verbosity levels
23
+ */
24
+ static configure(options?: {
25
+ verbosity?: number;
26
+ quiet?: boolean;
27
+ silent?: boolean;
28
+ }): void;
29
+ /**
30
+ * Check if output should be suppressed
31
+ */
32
+ private static shouldSuppressOutput;
33
+ /**
34
+ * Logs the message in two columns
35
+ *
36
+ * @param name
37
+ * @param value
38
+ * @param log If set to false, array of [name, dots, value] output will be returned and not logged
39
+ * @returns
40
+ */
41
+ static twoColumnDetail(name: string, value: string, log?: true, spacer?: string): void;
42
+ static twoColumnDetail(name: string, value: string, log?: false, spacer?: string): [string, string, string];
43
+ /**
44
+ * Logs the message in two columns
45
+ *
46
+ * @param name
47
+ * @param desc
48
+ * @param width
49
+ * @param log If set to false, array of [name, dots, value] output will be returned and not logged
50
+ * @returns
51
+ */
52
+ static describe(name: string, desc: string, width?: number, log?: true): void;
53
+ static describe(name: string, desc: string, width?: number, log?: false): [string, string, string];
54
+ /**
55
+ * Logs the message in two columns but allways passing status
56
+ *
57
+ * @param name
58
+ * @param value
59
+ * @param status
60
+ * @param exit
61
+ * @param preserveCol
62
+ */
63
+ static split(name: string, value: string, status?: 'success' | 'info' | 'error', exit?: boolean, preserveCol?: boolean, spacer?: string): void;
64
+ /**
65
+ * Wraps text with chalk
66
+ *
67
+ * @param txt
68
+ * @param color
69
+ * @param preserveCol
70
+ * @returns
71
+ */
72
+ static textFormat(txt: unknown | unknown[], color: (...text: unknown[]) => string, preserveCol?: boolean): string;
73
+ /**
74
+ * Logs a success message
75
+ *
76
+ * @param msg
77
+ * @param exit
78
+ * @param preserveCol
79
+ */
80
+ static success(msg: any, exit?: boolean, preserveCol?: boolean): void;
81
+ /**
82
+ * Logs an informational message
83
+ *
84
+ * @param msg
85
+ * @param exit
86
+ * @param preserveCol
87
+ */
88
+ static info(msg: any, exit?: boolean, preserveCol?: boolean): void;
89
+ /**
90
+ * Logs an error message
91
+ *
92
+ * @param msg
93
+ * @param exit
94
+ * @param preserveCol
95
+ */
96
+ static error(msg: any, exit?: boolean, preserveCol?: boolean): void;
97
+ /**
98
+ * Logs a warning message
99
+ *
100
+ * @param msg
101
+ * @param exit
102
+ * @param preserveCol
103
+ */
104
+ static warn(msg: any, exit?: boolean, preserveCol?: boolean): void;
105
+ /**
106
+ * Logs a debug message (only shown with verbosity >= 3)
107
+ *
108
+ * @param msg
109
+ * @param exit
110
+ * @param preserveCol
111
+ */
112
+ static debug<M = any>(msg: M | M[], exit?: boolean, preserveCol?: boolean): void;
113
+ /**
114
+ * Terminates the process
115
+ */
116
+ static quiet(): void;
117
+ static chalker(styles: LoggerChalk[]): (input: any) => string;
118
+ /**
119
+ * Parse an array formated message and logs it
120
+ *
121
+ * @param config
122
+ * @param joiner
123
+ * @param log If set to false, string output will be returned and not logged
124
+ * @param sc color to use ue on split text if : is found
125
+ */
126
+ static parse(config: LoggerParseSignature, joiner?: string, log?: true, sc?: LoggerChalk): void;
127
+ static parse(config: LoggerParseSignature, joiner?: string, log?: false, sc?: LoggerChalk): string;
128
+ /**
129
+ * Ouput formater object or format the output
130
+ *
131
+ * @returns
132
+ */
133
+ static log: LoggerLog;
134
+ /**
135
+ * A simple console like output logger
136
+ *
137
+ * @returns
138
+ */
139
+ static console(): typeof Console;
140
+ }
141
+ //#endregion
142
+ //#region src/locales.d.ts
143
+ declare const locales: readonly ["af_ZA", "ar", "az", "bn_BD", "cs_CZ", "cy", "da", "de", "de_AT", "de_CH", "dv", "el", "en", "en_AU", "en_AU_ocker", "en_BORK", "en_CA", "en_GB", "en_GH", "en_HK", "en_IE", "en_IN", "en_NG", "en_US", "en_ZA", "eo", "es", "es_MX", "fa", "fi", "fr", "fr_BE", "fr_CA", "fr_CH", "fr_LU", "fr_SN", "he", "hr", "hu", "hy", "id_ID", "it", "ja", "ka_GE", "ko", "ku_ckb", "ku_kmr_latin", "lv", "mk", "mn_MN_cyrl", "nb_NO", "ne", "nl", "nl_BE", "pl", "pt_BR", "pt_PT", "ro", "ro_MD", "ru", "sk", "sl_SI", "sr_RS_latin", "sv", "ta_IN", "th", "tr", "uk", "ur", "uz_UZ_latin", "vi", "yo_NG", "zh_CN", "zh_TW", "zu_ZA"];
144
+ //#endregion
145
+ //#region src/types.d.ts
146
+ interface ConfigRegistry {}
147
+ /**
148
+ * Map of known environment variables to their (coerced) value types.
149
+ *
150
+ * Used to give {@link GlobalEnv | env()} precise return types. Unknown keys fall
151
+ * back to `string`. Augment this interface (declaration merging) to register
152
+ * application-specific variables:
153
+ *
154
+ * ```ts
155
+ * declare module '@arkstack/common' {
156
+ * interface EnvRegistry { MY_FLAG: boolean }
157
+ * }
158
+ * ```
159
+ */
160
+ interface EnvRegistry {
161
+ APP_NAME: string;
162
+ APP_ENV: 'development' | 'production' | 'staging' | 'local';
163
+ APP_KEY: string;
164
+ APP_URL: string;
165
+ APP_HOST: string;
166
+ APP_PORT: number;
167
+ APP_DEBUG: boolean;
168
+ APP_TIMEZONE: string;
169
+ APP_LOCALE: typeof locales[number];
170
+ APP_FALLBACK_LOCALE: typeof locales[number];
171
+ APP_FAKER_LOCALE: typeof locales[number];
172
+ NODE_ENV: 'development' | 'production' | 'test';
173
+ PORT: number;
174
+ HOST: string;
175
+ FRONTEND_URL: string;
176
+ OUTPUT_DIR: string;
177
+ OUTPUT_DIR_DEV: string;
178
+ CONFIG_PATH: string;
179
+ TUNNEL: boolean;
180
+ NGROK_AUTHTOKEN: string;
181
+ NGROK_DOMAIN: string;
182
+ FILESYSTEM_DISK: string;
183
+ CACHE_STORE: string;
184
+ CACHE_PREFIX: string;
185
+ CACHE_TABLE: string;
186
+ QUEUE_CONNECTION: string;
187
+ QUEUE_TABLE: string;
188
+ QUEUE_NAME: string;
189
+ QUEUE_RETRY_AFTER: number;
190
+ REDIS_HOST: string;
191
+ REDIS_PORT: number;
192
+ REDIS_PASSWORD: string;
193
+ REDIS_CACHE_DB: number;
194
+ REDIS_QUEUE_DB: number;
195
+ JWT_EXPIRES_IN: string;
196
+ SESSION_LIFETIME: number;
197
+ TWO_FACTOR_SMS_TTL_MINUTES: number;
198
+ DATABASE_URL: string;
199
+ DB_CONNECTION: string;
200
+ DB_HOST: string;
201
+ DB_PORT: number;
202
+ DB_DATABASE: string;
203
+ DB_USERNAME: string;
204
+ DB_PASSWORD: string;
205
+ MAIL_HOST: string;
206
+ MAIL_PORT: number;
207
+ MAIL_SECURE: boolean;
208
+ MAIL_USERNAME: string;
209
+ MAIL_PASSWORD: string;
210
+ MAIL_FROM_ADDRESS: string;
211
+ MAIL_TEST_ADDRESS: string;
212
+ AWS_ACCESS_KEY_ID: string;
213
+ AWS_SECRET_ACCESS_KEY: string;
214
+ AWS_DEFAULT_REGION: string;
215
+ AWS_BUCKET: string;
216
+ AWS_URL: string;
217
+ AWS_ENDPOINT: string;
218
+ }
219
+ /**
220
+ * App Confifuration
221
+ */
222
+ interface AppConfig {
223
+ [key: string]: any;
224
+ env: string;
225
+ key: string;
226
+ url: string;
227
+ host: string;
228
+ name: string;
229
+ frontend_url: string;
230
+ debug: boolean;
231
+ timezone: string;
232
+ locale: typeof locales[number];
233
+ fallback_locale: typeof locales[number];
234
+ faker_locale: typeof locales[number];
235
+ }
236
+ /**
237
+ * Known environment variable names.
238
+ */
239
+ type EnvKey = keyof EnvRegistry & string;
240
+ /** The registered type for a known key, or `string` for an unknown one. */
241
+ type EnvLookup<K extends string> = [K] extends [EnvKey] ? EnvRegistry[K] : string;
242
+ type UnionToIntersection<U> = (U extends any ? (x: U) => void : never) extends ((x: infer I) => void) ? I : never;
243
+ type MergedConfig<X> = UnionToIntersection<X>;
244
+ type Primitive = string | number | boolean | null | undefined | Function;
245
+ type LoggerChalk = keyof ChalkInstance | ChalkInstance | (keyof ChalkInstance)[];
246
+ type LoggerParseSignature = [string, LoggerChalk][];
247
+ type DotPathValue<T, P extends string> = P extends `${infer Head}.${infer Tail}` ? Head extends keyof T ? DotPathValue<T[Head], Tail> : never : P extends keyof T ? T[P] : never;
248
+ type DotPath<T> = T extends Primitive ? never : T extends any[] ? never : { [K in keyof T & string]: T[K] extends Primitive ? `${K}` : T[K] extends any[] ? `${K}` : `${K}` | `${K}.${DotPath<T[K]>}` }[keyof T & string];
249
+ /**
250
+ * Ouput formater object or format the output
251
+ *
252
+ * @param config
253
+ * @param joiner
254
+ * @param log If set to false, string output will be returned and not logged
255
+ * @param sc color to use ue on split text if : is found
256
+ *
257
+ * @returns
258
+ */
259
+ interface LoggerLog {
260
+ (): typeof Logger;
261
+ <L extends boolean>(config: string, joiner: LoggerChalk, log?: L, sc?: LoggerChalk): L extends true ? void : string;
262
+ <L extends boolean>(config: LoggerParseSignature, joiner?: string, log?: L, sc?: LoggerChalk): L extends true ? void : string;
263
+ <L extends boolean>(config?: LoggerParseSignature, joiner?: string, log?: L, sc?: LoggerChalk): L extends true ? void : string | Logger;
264
+ }
265
+ /**
266
+ * Return type of {@link GlobalEnv | env()}.
267
+ *
268
+ * When an explicit value type `X` is given it wins (backward compatible with
269
+ * `env<boolean>('FLAG')`). Otherwise the type registered for the key `K` is used
270
+ * — falling back to `string` for unknown keys. A provided default `D` is unioned
271
+ * into the result.
272
+ */
273
+ type EnvReturn<X, K extends string, D> = [X] extends [never] ? [D] extends [undefined] ? EnvLookup<K> : EnvLookup<K> | D : [D] extends [undefined] ? X : X | D;
274
+ interface GlobalEnv {
275
+ <X = never, D = undefined, K extends (keyof EnvRegistry | (string & {})) = keyof EnvRegistry>(env: K, defaultValue?: D): EnvReturn<X, K, D>;
276
+ }
277
+ type ConfigShape = keyof ConfigRegistry extends never ? Record<string, any> : ConfigRegistry;
278
+ interface GlobalConfig {
279
+ <X extends ConfigShape>(): X;
280
+ <X extends ConfigShape, P extends DotPath<X>>(key: P): DotPathValue<X, P>;
281
+ <X extends ConfigShape, P extends DotPath<X>>(key: Record<P, Partial<DotPathValue<X, P>>>): void;
282
+ <X extends ConfigShape, P extends DotPath<X>, D>(key: P, defaultValue: D): DotPathValue<X, P> | D;
283
+ }
284
+ interface FileImporter {
285
+ <T = unknown>(filePath: string): Promise<T>;
286
+ <T = unknown>(filePath: string, userOptions?: JitiOptions | undefined): Promise<T>;
287
+ <T = unknown>(filePath: string, userOptions?: JitiOptions | undefined, resolveOptions?: (JitiResolveOptions & {
288
+ default?: true;
289
+ })): Promise<T>;
290
+ }
291
+ type ArkstackErrorShape = Error & {
292
+ cause?: unknown;
293
+ code?: number | string;
294
+ errors?: unknown;
295
+ getModelName?: () => string;
296
+ status?: number;
297
+ statusCode?: number; /** Custom properties merged into the error response payload. */
298
+ body?: Record<string, unknown>;
299
+ };
300
+ interface ArkstackErrorPayload {
301
+ status: 'error';
302
+ code: number;
303
+ message: string;
304
+ errors?: unknown;
305
+ stack?: string;
306
+ /** Custom fields contributed by an exception's `body`. */
307
+ [key: string]: unknown;
308
+ }
309
+ interface HookRegistry {}
310
+ type Position = 'before' | 'after' | (string & {});
311
+ type IHook = { [P in Position]?: (...args: any[]) => void };
312
+ type HookName = keyof HookRegistry extends never ? string : keyof HookRegistry | (string & {});
313
+ type HookFor<N extends string> = N extends keyof HookRegistry ? HookRegistry[N] : IHook;
314
+ type HookPos<N extends string, P extends string> = N extends keyof HookRegistry ? P extends keyof HookRegistry[N] ? HookRegistry[N][P] : (...args: any[]) => void : (...args: any[]) => void;
315
+ type HookPositions<N extends string> = N extends keyof HookRegistry ? keyof HookRegistry[N] : Position;
316
+ type HookArgs<N extends string, P extends string> = N extends keyof HookRegistry ? P extends keyof HookRegistry[N] ? HookRegistry[N][P] extends ((...args: infer A) => any) ? A : any[] : any[] : any[];
317
+ type Choice<Value> = {
318
+ value: Value;
319
+ name?: string;
320
+ description?: string;
321
+ short?: string;
322
+ disabled?: boolean | string;
323
+ type?: never;
324
+ };
325
+ type Choices = readonly string[] | readonly Choice<string>[];
326
+ type PaginationOptions = {
327
+ page: number;
328
+ perPage: number;
329
+ };
330
+ /**
331
+ * A single source → destination mapping a package wants to publish into the
332
+ * consuming application.
333
+ */
334
+ interface PublishEntry {
335
+ /** Absolute path to the file or directory shipped by the package. */
336
+ from: string;
337
+ /**
338
+ * Destination path, relative to the application root, where the artifact is
339
+ * written when published.
340
+ */
341
+ to: string;
342
+ }
343
+ /**
344
+ * A group of publishable artifacts registered by a package.
345
+ */
346
+ interface PublishGroup {
347
+ /**
348
+ * The package registering the artifacts, e.g. `@arkstack/cache`.
349
+ */
350
+ package: string;
351
+ /**
352
+ * Optional tag for selective publishing (`ark publish --tag <tag>`). A
353
+ * package may register several groups under different tags.
354
+ */
355
+ tag?: string;
356
+ /** The files/directories to publish. */
357
+ entries: PublishEntry[];
358
+ }
359
+ /** Optional filter applied when reading the registry. */
360
+ interface PublishFilter {
361
+ package?: string;
362
+ tag?: string;
363
+ }
364
+ /** Optional filter applied when reading the registry. */
365
+ interface PublishConfirmation {
366
+ /**
367
+ * The package registering the confirmation, e.g. `@arkstack/cache`.
368
+ */
369
+ package: string;
370
+ /**
371
+ * A message describing what the confirmation is
372
+ * for, e.g. "Are you sure you want to publish the cache migrations?"
373
+ */
374
+ message: string;
375
+ /**
376
+ * Options to choose from.
377
+ */
378
+ options: Choices;
379
+ /**
380
+ * A callback function to handle the selected choice and the stub file.
381
+ *
382
+ * @param choice
383
+ * @param stub
384
+ * @returns
385
+ */
386
+ callback?: (choice: Choice<string>['value'], stub: string) => string | Promise<string>;
387
+ }
388
+ //#endregion
389
+ //#region src/utils/encryption.d.ts
390
+ declare class Encryption {
391
+ private static readonly algorithm;
392
+ private static getKey;
393
+ static encrypt(value: string): string;
394
+ static decrypt(payload: string): string;
395
+ }
396
+ //#endregion
397
+ //#region src/utils/hash.d.ts
398
+ declare class Hash {
399
+ /**
400
+ * Hash a value using bcrypt
401
+ *
402
+ * @param value
403
+ * @returns
404
+ */
405
+ static make(value: string): Promise<string>;
406
+ /**
407
+ * Verify a value against a hashed value
408
+ *
409
+ * @param value
410
+ * @param hashedValue
411
+ * @returns
412
+ */
413
+ static verify(value: string, hashedValue: string): Promise<boolean>;
414
+ /**
415
+ * Generate a one-time password (OTP) using TOTP algorithm
416
+ *
417
+ * @param digits The number of digits for the OTP, default is 6.
418
+ * @param label A label to identify the OTP, can be an email or phone number.
419
+ * @param period Interval of time for which a token is valid, in seconds.
420
+ * @returns
421
+ */
422
+ static otp(digits?: number, label?: string, period?: number): TOTP;
423
+ static totp(secret: string, label: string, issuer?: string, period?: number): TOTP;
424
+ }
425
+ //#endregion
426
+ //#region src/utils/helpers.d.ts
427
+ type AbstractModelConstructor<TModel = unknown> = abstract new (attributes?: Record<string, unknown>) => TModel;
428
+ type ModelConstructor<TModel extends Model = Model> = AbstractModelConstructor<TModel> & Pick<ModelStatic<TModel>, keyof ModelStatic<TModel>>;
429
+ interface ModelRegistry {}
430
+ type ModelName = Extract<keyof ModelRegistry, string>;
431
+ /**
432
+ * Checks and asserts if target is a class
433
+ *
434
+ * @param target
435
+ * @returns
436
+ */
437
+ declare const isClass: <T = unknown>(target: unknown) => target is new (...args: any[]) => T;
438
+ declare const normalizePositiveInteger: (value: unknown, fallback: number) => number;
439
+ /**
440
+ * Extracts a safe pagination limit from a query object.
441
+ *
442
+ * @param query
443
+ * @param defaults
444
+ * @default const defaults = { pageSize: 25, maxPageSize: 50 }
445
+ * @returns
446
+ */
447
+ declare const perPage: (query: {
448
+ limit?: number;
449
+ perPage?: number;
450
+ per_page?: number;
451
+ "per-page"?: number;
452
+ }, defaults?: {
453
+ perPage?: number;
454
+ maxPerPage?: number;
455
+ }) => number;
456
+ /**
457
+ * Extracts the current page and a safe pagination limit from a query object.
458
+ *
459
+ * @param query
460
+ * @param defaults
461
+ * @default const defaults = { currentPage: 1, pageSize: 25, maxPageSize: 50 }
462
+ * @returns
463
+ */
464
+ declare const resolvePagination: (query: {
465
+ page?: number;
466
+ limit?: number;
467
+ perPage?: number;
468
+ per_page?: number;
469
+ "per-page"?: number;
470
+ }, defaults?: {
471
+ page?: number;
472
+ perPage?: number;
473
+ maxPerPage?: number;
474
+ }) => PaginationOptions;
475
+ /**
476
+ * Import an application model by name.
477
+ *
478
+ * Apps can augment `ModelRegistry` to make `getModel('User')` return `typeof User`.
479
+ * Without a registry entry, pass the class type explicitly: `getModel<typeof User>('User')`.
480
+ *
481
+ * @param modelName
482
+ */
483
+ declare function getModel<TName extends ModelName>(modelName: TName): Promise<ModelRegistry[TName]>;
484
+ declare function getModel<TModel extends AbstractModelConstructor = ModelConstructor>(modelName: string): Promise<TModel>;
485
+ /**
486
+ * Synchronously import an application model by name.
487
+ *
488
+ * Apps can augment `ModelRegistry` to make `getModel('User')` return `typeof User`.
489
+ * Without a registry entry, pass the class type explicitly: `getModel<typeof User>('User')`.
490
+ *
491
+ * @param modelName
492
+ */
493
+ declare function getModelSync<TName extends ModelName>(modelName: TName): ModelRegistry[TName];
494
+ declare function getModelSync<TModel extends AbstractModelConstructor = ModelConstructor>(modelName: string): TModel;
495
+ declare const initializeGlobalContext: ({
496
+ Request,
497
+ Response,
498
+ Session
499
+ }?: {
500
+ Request?: any;
501
+ Response?: any;
502
+ Session?: any;
503
+ }) => Promise<void>;
504
+ /**
505
+ * Thows to abort the current request
506
+ *
507
+ * @param message
508
+ * @param code
509
+ * @throws {RequestException}
510
+ */
511
+ declare const abort: (message?: string, code?: number) => void;
512
+ /**
513
+ * Asserts that a boolean condition is true.
514
+ *
515
+ * @param boolean
516
+ * @param message
517
+ * @param code
518
+ * @throws {RequestException} Throws if the boolean condition is true.
519
+ */
520
+ declare const abortIf: <T>(boolean: T, message?: string, code?: number) => asserts boolean is T;
521
+ /**
522
+ * Asserts that a value is not null or undefined.
523
+ *
524
+ * @param value
525
+ * @param message
526
+ * @param code
527
+ * @throws {RequestException} Throws if the value is null or undefined.
528
+ */
529
+ declare const assertFound: <T>(value: T | null | undefined, message: string, code?: number) => asserts value is T;
530
+ //#endregion
531
+ export { GlobalConfig as A, LoggerLog as B, DotPath as C, EnvRegistry as D, EnvLookup as E, HookPos as F, PublishConfirmation as G, MergedConfig as H, HookPositions as I, PublishGroup as J, PublishEntry as K, HookRegistry as L, HookArgs as M, HookFor as N, EnvReturn as O, HookName as P, IHook as R, ConfigShape as S, EnvKey as T, PaginationOptions as U, LoggerParseSignature as V, Primitive as W, Logger as X, UnionToIntersection as Y, ArkstackErrorPayload as _, abortIf as a, Choices as b, getModelSync as c, normalizePositiveInteger as d, perPage as f, AppConfig as g, Encryption as h, abort as i, GlobalEnv as j, FileImporter as k, initializeGlobalContext as l, Hash as m, ModelConstructor as n, assertFound as o, resolvePagination as p, PublishFilter as q, ModelRegistry as r, getModel as s, AbstractModelConstructor as t, isClass as u, ArkstackErrorShape as v, DotPathValue as w, ConfigRegistry as x, Choice as y, LoggerChalk as z };
package/dist/index.d.ts CHANGED
@@ -1,9 +1,7 @@
1
1
  /// <reference path="./app.d.ts" />
2
- import { a as abortIf, c as getModelSync, d as perPage, f as Hash, i as abort, l as initializeGlobalContext, n as ModelConstructor, o as assertFound, p as Encryption, r as ModelRegistry, s as getModel, t as AbstractModelConstructor, u as isClass } from "./helpers-Bn6dk-9j.js";
3
- import { JitiOptions, JitiResolveOptions } from "jiti";
2
+ import { A as GlobalConfig, B as LoggerLog, C as DotPath, D as EnvRegistry, E as EnvLookup, F as HookPos, G as PublishConfirmation, H as MergedConfig, I as HookPositions, J as PublishGroup, K as PublishEntry, L as HookRegistry, M as HookArgs, N as HookFor, O as EnvReturn, P as HookName, R as IHook, S as ConfigShape, T as EnvKey, U as PaginationOptions, V as LoggerParseSignature, W as Primitive, X as Logger, Y as UnionToIntersection, _ as ArkstackErrorPayload, a as abortIf, b as Choices, c as getModelSync, d as normalizePositiveInteger, f as perPage, g as AppConfig, h as Encryption, i as abort, j as GlobalEnv, k as FileImporter, l as initializeGlobalContext, m as Hash, n as ModelConstructor, o as assertFound, p as resolvePagination, q as PublishFilter, r as ModelRegistry, s as getModel, t as AbstractModelConstructor, u as isClass, v as ArkstackErrorShape, w as DotPathValue, x as ConfigRegistry, y as Choice, z as LoggerChalk } from "./helpers-CC35u6ti.js";
4
3
  import { Arkstack } from "@arkstack/contract";
5
4
  import pino from "pino";
6
- import { ChalkInstance } from "chalk";
7
5
 
8
6
  //#region src/lifecycle.d.ts
9
7
  declare const bindGracefulShutdown: (shutdown: () => Promise<void> | void, defer?: boolean) => void;
@@ -34,385 +32,6 @@ declare const renderError: ({
34
32
  //#region src/prototypes.d.ts
35
33
  declare const loadPrototypes: () => void;
36
34
  //#endregion
37
- //#region src/Logger.d.ts
38
- declare class Console {
39
- static log: (...args: any[]) => string | void;
40
- static debug: (...args: any[]) => void;
41
- static warn: (...args: any[]) => void[];
42
- static info: (...args: any[]) => void[];
43
- static error: (...args: any[]) => void[];
44
- }
45
- declare class Logger {
46
- /**
47
- * Global verbosity configuration
48
- */
49
- private static verbosity;
50
- private static isQuiet;
51
- private static isSilent;
52
- /**
53
- * Configure global verbosity levels
54
- */
55
- static configure(options?: {
56
- verbosity?: number;
57
- quiet?: boolean;
58
- silent?: boolean;
59
- }): void;
60
- /**
61
- * Check if output should be suppressed
62
- */
63
- private static shouldSuppressOutput;
64
- /**
65
- * Logs the message in two columns
66
- *
67
- * @param name
68
- * @param value
69
- * @param log If set to false, array of [name, dots, value] output will be returned and not logged
70
- * @returns
71
- */
72
- static twoColumnDetail(name: string, value: string, log?: true, spacer?: string): void;
73
- static twoColumnDetail(name: string, value: string, log?: false, spacer?: string): [string, string, string];
74
- /**
75
- * Logs the message in two columns
76
- *
77
- * @param name
78
- * @param desc
79
- * @param width
80
- * @param log If set to false, array of [name, dots, value] output will be returned and not logged
81
- * @returns
82
- */
83
- static describe(name: string, desc: string, width?: number, log?: true): void;
84
- static describe(name: string, desc: string, width?: number, log?: false): [string, string, string];
85
- /**
86
- * Logs the message in two columns but allways passing status
87
- *
88
- * @param name
89
- * @param value
90
- * @param status
91
- * @param exit
92
- * @param preserveCol
93
- */
94
- static split(name: string, value: string, status?: 'success' | 'info' | 'error', exit?: boolean, preserveCol?: boolean, spacer?: string): void;
95
- /**
96
- * Wraps text with chalk
97
- *
98
- * @param txt
99
- * @param color
100
- * @param preserveCol
101
- * @returns
102
- */
103
- static textFormat(txt: unknown | unknown[], color: (...text: unknown[]) => string, preserveCol?: boolean): string;
104
- /**
105
- * Logs a success message
106
- *
107
- * @param msg
108
- * @param exit
109
- * @param preserveCol
110
- */
111
- static success(msg: any, exit?: boolean, preserveCol?: boolean): void;
112
- /**
113
- * Logs an informational message
114
- *
115
- * @param msg
116
- * @param exit
117
- * @param preserveCol
118
- */
119
- static info(msg: any, exit?: boolean, preserveCol?: boolean): void;
120
- /**
121
- * Logs an error message
122
- *
123
- * @param msg
124
- * @param exit
125
- * @param preserveCol
126
- */
127
- static error(msg: any, exit?: boolean, preserveCol?: boolean): void;
128
- /**
129
- * Logs a warning message
130
- *
131
- * @param msg
132
- * @param exit
133
- * @param preserveCol
134
- */
135
- static warn(msg: any, exit?: boolean, preserveCol?: boolean): void;
136
- /**
137
- * Logs a debug message (only shown with verbosity >= 3)
138
- *
139
- * @param msg
140
- * @param exit
141
- * @param preserveCol
142
- */
143
- static debug<M = any>(msg: M | M[], exit?: boolean, preserveCol?: boolean): void;
144
- /**
145
- * Terminates the process
146
- */
147
- static quiet(): void;
148
- static chalker(styles: LoggerChalk[]): (input: any) => string;
149
- /**
150
- * Parse an array formated message and logs it
151
- *
152
- * @param config
153
- * @param joiner
154
- * @param log If set to false, string output will be returned and not logged
155
- * @param sc color to use ue on split text if : is found
156
- */
157
- static parse(config: LoggerParseSignature, joiner?: string, log?: true, sc?: LoggerChalk): void;
158
- static parse(config: LoggerParseSignature, joiner?: string, log?: false, sc?: LoggerChalk): string;
159
- /**
160
- * Ouput formater object or format the output
161
- *
162
- * @returns
163
- */
164
- static log: LoggerLog;
165
- /**
166
- * A simple console like output logger
167
- *
168
- * @returns
169
- */
170
- static console(): typeof Console;
171
- }
172
- //#endregion
173
- //#region src/locales.d.ts
174
- declare const locales: readonly ["af_ZA", "ar", "az", "bn_BD", "cs_CZ", "cy", "da", "de", "de_AT", "de_CH", "dv", "el", "en", "en_AU", "en_AU_ocker", "en_BORK", "en_CA", "en_GB", "en_GH", "en_HK", "en_IE", "en_IN", "en_NG", "en_US", "en_ZA", "eo", "es", "es_MX", "fa", "fi", "fr", "fr_BE", "fr_CA", "fr_CH", "fr_LU", "fr_SN", "he", "hr", "hu", "hy", "id_ID", "it", "ja", "ka_GE", "ko", "ku_ckb", "ku_kmr_latin", "lv", "mk", "mn_MN_cyrl", "nb_NO", "ne", "nl", "nl_BE", "pl", "pt_BR", "pt_PT", "ro", "ro_MD", "ru", "sk", "sl_SI", "sr_RS_latin", "sv", "ta_IN", "th", "tr", "uk", "ur", "uz_UZ_latin", "vi", "yo_NG", "zh_CN", "zh_TW", "zu_ZA"];
175
- //#endregion
176
- //#region src/types.d.ts
177
- interface ConfigRegistry {}
178
- /**
179
- * Map of known environment variables to their (coerced) value types.
180
- *
181
- * Used to give {@link GlobalEnv | env()} precise return types. Unknown keys fall
182
- * back to `string`. Augment this interface (declaration merging) to register
183
- * application-specific variables:
184
- *
185
- * ```ts
186
- * declare module '@arkstack/common' {
187
- * interface EnvRegistry { MY_FLAG: boolean }
188
- * }
189
- * ```
190
- */
191
- interface EnvRegistry {
192
- APP_NAME: string;
193
- APP_ENV: 'development' | 'production' | 'staging' | 'local';
194
- APP_KEY: string;
195
- APP_URL: string;
196
- APP_HOST: string;
197
- APP_PORT: number;
198
- APP_DEBUG: boolean;
199
- APP_TIMEZONE: string;
200
- APP_LOCALE: typeof locales[number];
201
- APP_FALLBACK_LOCALE: typeof locales[number];
202
- APP_FAKER_LOCALE: typeof locales[number];
203
- NODE_ENV: 'development' | 'production' | 'test';
204
- PORT: number;
205
- HOST: string;
206
- FRONTEND_URL: string;
207
- OUTPUT_DIR: string;
208
- OUTPUT_DIR_DEV: string;
209
- CONFIG_PATH: string;
210
- TUNNEL: boolean;
211
- NGROK_AUTHTOKEN: string;
212
- NGROK_DOMAIN: string;
213
- FILESYSTEM_DISK: string;
214
- CACHE_STORE: string;
215
- CACHE_PREFIX: string;
216
- CACHE_TABLE: string;
217
- QUEUE_CONNECTION: string;
218
- QUEUE_TABLE: string;
219
- QUEUE_NAME: string;
220
- QUEUE_RETRY_AFTER: number;
221
- REDIS_HOST: string;
222
- REDIS_PORT: number;
223
- REDIS_PASSWORD: string;
224
- REDIS_CACHE_DB: number;
225
- REDIS_QUEUE_DB: number;
226
- JWT_EXPIRES_IN: string;
227
- SESSION_LIFETIME: number;
228
- TWO_FACTOR_SMS_TTL_MINUTES: number;
229
- DATABASE_URL: string;
230
- DB_CONNECTION: string;
231
- DB_HOST: string;
232
- DB_PORT: number;
233
- DB_DATABASE: string;
234
- DB_USERNAME: string;
235
- DB_PASSWORD: string;
236
- MAIL_HOST: string;
237
- MAIL_PORT: number;
238
- MAIL_SECURE: boolean;
239
- MAIL_USERNAME: string;
240
- MAIL_PASSWORD: string;
241
- MAIL_FROM_ADDRESS: string;
242
- MAIL_TEST_ADDRESS: string;
243
- AWS_ACCESS_KEY_ID: string;
244
- AWS_SECRET_ACCESS_KEY: string;
245
- AWS_DEFAULT_REGION: string;
246
- AWS_BUCKET: string;
247
- AWS_URL: string;
248
- AWS_ENDPOINT: string;
249
- }
250
- /**
251
- * App Confifuration
252
- */
253
- interface AppConfig {
254
- [key: string]: any;
255
- env: string;
256
- key: string;
257
- url: string;
258
- host: string;
259
- name: string;
260
- frontend_url: string;
261
- debug: boolean;
262
- timezone: string;
263
- locale: typeof locales[number];
264
- fallback_locale: typeof locales[number];
265
- faker_locale: typeof locales[number];
266
- }
267
- /**
268
- * Known environment variable names.
269
- */
270
- type EnvKey = keyof EnvRegistry & string;
271
- /** The registered type for a known key, or `string` for an unknown one. */
272
- type EnvLookup<K extends string> = [K] extends [EnvKey] ? EnvRegistry[K] : string;
273
- type UnionToIntersection<U> = (U extends any ? (x: U) => void : never) extends ((x: infer I) => void) ? I : never;
274
- type MergedConfig<X> = UnionToIntersection<X>;
275
- type Primitive = string | number | boolean | null | undefined | Function;
276
- type LoggerChalk = keyof ChalkInstance | ChalkInstance | (keyof ChalkInstance)[];
277
- type LoggerParseSignature = [string, LoggerChalk][];
278
- type DotPathValue<T, P extends string> = P extends `${infer Head}.${infer Tail}` ? Head extends keyof T ? DotPathValue<T[Head], Tail> : never : P extends keyof T ? T[P] : never;
279
- type DotPath<T> = T extends Primitive ? never : T extends any[] ? never : { [K in keyof T & string]: T[K] extends Primitive ? `${K}` : T[K] extends any[] ? `${K}` : `${K}` | `${K}.${DotPath<T[K]>}` }[keyof T & string];
280
- /**
281
- * Ouput formater object or format the output
282
- *
283
- * @param config
284
- * @param joiner
285
- * @param log If set to false, string output will be returned and not logged
286
- * @param sc color to use ue on split text if : is found
287
- *
288
- * @returns
289
- */
290
- interface LoggerLog {
291
- (): typeof Logger;
292
- <L extends boolean>(config: string, joiner: LoggerChalk, log?: L, sc?: LoggerChalk): L extends true ? void : string;
293
- <L extends boolean>(config: LoggerParseSignature, joiner?: string, log?: L, sc?: LoggerChalk): L extends true ? void : string;
294
- <L extends boolean>(config?: LoggerParseSignature, joiner?: string, log?: L, sc?: LoggerChalk): L extends true ? void : string | Logger;
295
- }
296
- /**
297
- * Return type of {@link GlobalEnv | env()}.
298
- *
299
- * When an explicit value type `X` is given it wins (backward compatible with
300
- * `env<boolean>('FLAG')`). Otherwise the type registered for the key `K` is used
301
- * — falling back to `string` for unknown keys. A provided default `D` is unioned
302
- * into the result.
303
- */
304
- type EnvReturn<X, K extends string, D> = [X] extends [never] ? [D] extends [undefined] ? EnvLookup<K> : EnvLookup<K> | D : [D] extends [undefined] ? X : X | D;
305
- interface GlobalEnv {
306
- <X = never, D = undefined, K extends (keyof EnvRegistry | (string & {})) = keyof EnvRegistry>(env: K, defaultValue?: D): EnvReturn<X, K, D>;
307
- }
308
- type ConfigShape = keyof ConfigRegistry extends never ? Record<string, any> : ConfigRegistry;
309
- interface GlobalConfig {
310
- <X extends ConfigShape>(): X;
311
- <X extends ConfigShape, P extends DotPath<X>>(key: P): DotPathValue<X, P>;
312
- <X extends ConfigShape, P extends DotPath<X>>(key: Record<P, Partial<DotPathValue<X, P>>>): void;
313
- <X extends ConfigShape, P extends DotPath<X>, D>(key: P, defaultValue: D): DotPathValue<X, P> | D;
314
- }
315
- interface FileImporter {
316
- <T = unknown>(filePath: string): Promise<T>;
317
- <T = unknown>(filePath: string, userOptions?: JitiOptions | undefined): Promise<T>;
318
- <T = unknown>(filePath: string, userOptions?: JitiOptions | undefined, resolveOptions?: (JitiResolveOptions & {
319
- default?: true;
320
- })): Promise<T>;
321
- }
322
- type ArkstackErrorShape = Error & {
323
- cause?: unknown;
324
- code?: number | string;
325
- errors?: unknown;
326
- getModelName?: () => string;
327
- status?: number;
328
- statusCode?: number; /** Custom properties merged into the error response payload. */
329
- body?: Record<string, unknown>;
330
- };
331
- interface ArkstackErrorPayload {
332
- status: 'error';
333
- code: number;
334
- message: string;
335
- errors?: unknown;
336
- stack?: string;
337
- /** Custom fields contributed by an exception's `body`. */
338
- [key: string]: unknown;
339
- }
340
- interface HookRegistry {}
341
- type Position = 'before' | 'after' | (string & {});
342
- type IHook = { [P in Position]?: (...args: any[]) => void };
343
- type HookName = keyof HookRegistry extends never ? string : keyof HookRegistry | (string & {});
344
- type HookFor<N extends string> = N extends keyof HookRegistry ? HookRegistry[N] : IHook;
345
- type HookPos<N extends string, P extends string> = N extends keyof HookRegistry ? P extends keyof HookRegistry[N] ? HookRegistry[N][P] : (...args: any[]) => void : (...args: any[]) => void;
346
- type HookPositions<N extends string> = N extends keyof HookRegistry ? keyof HookRegistry[N] : Position;
347
- type HookArgs<N extends string, P extends string> = N extends keyof HookRegistry ? P extends keyof HookRegistry[N] ? HookRegistry[N][P] extends ((...args: infer A) => any) ? A : any[] : any[] : any[];
348
- type Choice<Value> = {
349
- value: Value;
350
- name?: string;
351
- description?: string;
352
- short?: string;
353
- disabled?: boolean | string;
354
- type?: never;
355
- };
356
- type Choices = readonly string[] | readonly Choice<string>[];
357
- /**
358
- * A single source → destination mapping a package wants to publish into the
359
- * consuming application.
360
- */
361
- interface PublishEntry {
362
- /** Absolute path to the file or directory shipped by the package. */
363
- from: string;
364
- /**
365
- * Destination path, relative to the application root, where the artifact is
366
- * written when published.
367
- */
368
- to: string;
369
- }
370
- /**
371
- * A group of publishable artifacts registered by a package.
372
- */
373
- interface PublishGroup {
374
- /**
375
- * The package registering the artifacts, e.g. `@arkstack/cache`.
376
- */
377
- package: string;
378
- /**
379
- * Optional tag for selective publishing (`ark publish --tag <tag>`). A
380
- * package may register several groups under different tags.
381
- */
382
- tag?: string;
383
- /** The files/directories to publish. */
384
- entries: PublishEntry[];
385
- }
386
- /** Optional filter applied when reading the registry. */
387
- interface PublishFilter {
388
- package?: string;
389
- tag?: string;
390
- }
391
- /** Optional filter applied when reading the registry. */
392
- interface PublishConfirmation {
393
- /**
394
- * The package registering the confirmation, e.g. `@arkstack/cache`.
395
- */
396
- package: string;
397
- /**
398
- * A message describing what the confirmation is
399
- * for, e.g. "Are you sure you want to publish the cache migrations?"
400
- */
401
- message: string;
402
- /**
403
- * Options to choose from.
404
- */
405
- options: Choices;
406
- /**
407
- * A callback function to handle the selected choice and the stub file.
408
- *
409
- * @param choice
410
- * @param stub
411
- * @returns
412
- */
413
- callback?: (choice: Choice<string>['value'], stub: string) => string | Promise<string>;
414
- }
415
- //#endregion
416
35
  //#region src/system.d.ts
417
36
  /**
418
37
  * Read the .env file
@@ -870,4 +489,4 @@ declare const devTlsCredentials: (host?: string) => Promise<TlsCredentials>;
870
489
  */
871
490
  declare const localNetworkAddress: () => string | undefined;
872
491
  //#endregion
873
- export { AbstractModelConstructor, AppConfig, AppException, ArkstackErrorPayload, ArkstackErrorShape, CONFIG_KEY, Choice, Choices, ConfigLoader, ConfigRegistry, ConfigShape, DotPath, DotPathValue, Encryption, EnvKey, EnvLoader, EnvLookup, EnvRegistry, EnvReturn, ErrorHandler, Exception, FileImporter, GlobalConfig, GlobalEnv, Hash, Hook, HookArgs, HookFor, HookName, HookPos, HookPositions, HookRegistry, IHook, Logger, LoggerChalk, LoggerLog, LoggerParseSignature, MergedConfig, ModelConstructor, ModelRegistry, Primitive, PublishConfirmation, PublishEntry, PublishFilter, PublishGroup, Publisher, RequestException, TlsCredentials, UnionToIntersection, abort, abortIf, appKey, appUrl, assertFound, bindGracefulShutdown, bootWithDetectedPort, config, configLoader, createErrorPayload, devTlsCredentials, discoverCommands, env, envLoader, getErrorLogger, getModel, getModelSync, getPrimaryError, getValidationErrors, importFile, initializeGlobalContext, interopDefault, isClass, isModelNotFoundError, isValidationError, loadPrototypes, localNetworkAddress, logUnhandledError, nodeEnv, normalizeStatusCode, outputDir, perPage, rebuildOutput, renderError, resolveRuntimeDir, resolveRuntimeModule, serializeError, shouldHideStack, shouldLogError, toErrorShape, toOutputPath };
492
+ export { AbstractModelConstructor, AppConfig, AppException, ArkstackErrorPayload, ArkstackErrorShape, CONFIG_KEY, Choice, Choices, ConfigLoader, ConfigRegistry, ConfigShape, DotPath, DotPathValue, Encryption, EnvKey, EnvLoader, EnvLookup, EnvRegistry, EnvReturn, ErrorHandler, Exception, FileImporter, GlobalConfig, GlobalEnv, Hash, Hook, HookArgs, HookFor, HookName, HookPos, HookPositions, HookRegistry, IHook, Logger, LoggerChalk, LoggerLog, LoggerParseSignature, MergedConfig, ModelConstructor, ModelRegistry, PaginationOptions, Primitive, PublishConfirmation, PublishEntry, PublishFilter, PublishGroup, Publisher, RequestException, TlsCredentials, UnionToIntersection, abort, abortIf, appKey, appUrl, assertFound, bindGracefulShutdown, bootWithDetectedPort, config, configLoader, createErrorPayload, devTlsCredentials, discoverCommands, env, envLoader, getErrorLogger, getModel, getModelSync, getPrimaryError, getValidationErrors, importFile, initializeGlobalContext, interopDefault, isClass, isModelNotFoundError, isValidationError, loadPrototypes, localNetworkAddress, logUnhandledError, nodeEnv, normalizePositiveInteger, normalizeStatusCode, outputDir, perPage, rebuildOutput, renderError, resolvePagination, resolveRuntimeDir, resolveRuntimeModule, serializeError, shouldHideStack, shouldLogError, toErrorShape, toOutputPath };
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { _ as EnvLoader, a as env, c as nodeEnv, d as resolveRuntimeDir, f as resolveRuntimeModule, g as configLoader, h as ConfigLoader, i as discoverCommands, l as outputDir, m as CONFIG_KEY, n as appUrl, o as importFile, p as toOutputPath, r as config, s as interopDefault, t as appKey, u as rebuildOutput, v as envLoader } from "./system-XvUhJFS0.js";
2
- import { _ as Exception, c as abortIf, d as getModelSync, f as initializeGlobalContext, g as AppException, h as RequestException, l as assertFound, m as perPage, p as isClass, s as abort, u as getModel, v as Hash, y as Encryption } from "./utils-C3mcZZMN.js";
2
+ import { _ as RequestException, b as Hash, c as abortIf, d as getModelSync, f as initializeGlobalContext, g as resolvePagination, h as perPage, l as assertFound, m as normalizePositiveInteger, p as isClass, s as abort, u as getModel, v as AppException, x as Encryption, y as Exception } from "./utils-CaaL-9im.js";
3
3
  import { Hook as Hook$1 } from "@arkstack/foundry";
4
4
  import { Arkstack } from "@arkstack/contract";
5
5
  import { str } from "@h3ravel/support";
@@ -599,4 +599,4 @@ const localNetworkAddress = () => {
599
599
  for (const list of Object.values(networkInterfaces())) for (const net of list ?? []) if (net.family === "IPv4" && !net.internal) return net.address;
600
600
  };
601
601
  //#endregion
602
- export { AppException, CONFIG_KEY, ConfigLoader, Encryption, EnvLoader, ErrorHandler, Exception, Hash, Hook, Logger, Publisher, RequestException, abort, abortIf, appKey, appUrl, assertFound, bindGracefulShutdown, bootWithDetectedPort, config, configLoader, createErrorPayload, devTlsCredentials, discoverCommands, env, envLoader, getErrorLogger, getModel, getModelSync, getPrimaryError, getValidationErrors, importFile, initializeGlobalContext, interopDefault, isClass, isModelNotFoundError, isValidationError, loadPrototypes, localNetworkAddress, logUnhandledError, nodeEnv, normalizeStatusCode, outputDir, perPage, rebuildOutput, renderError, resolveRuntimeDir, resolveRuntimeModule, serializeError, shouldHideStack, shouldLogError, toErrorShape, toOutputPath };
602
+ export { AppException, CONFIG_KEY, ConfigLoader, Encryption, EnvLoader, ErrorHandler, Exception, Hash, Hook, Logger, Publisher, RequestException, abort, abortIf, appKey, appUrl, assertFound, bindGracefulShutdown, bootWithDetectedPort, config, configLoader, createErrorPayload, devTlsCredentials, discoverCommands, env, envLoader, getErrorLogger, getModel, getModelSync, getPrimaryError, getValidationErrors, importFile, initializeGlobalContext, interopDefault, isClass, isModelNotFoundError, isValidationError, loadPrototypes, localNetworkAddress, logUnhandledError, nodeEnv, normalizePositiveInteger, normalizeStatusCode, outputDir, perPage, rebuildOutput, renderError, resolvePagination, resolveRuntimeDir, resolveRuntimeModule, serializeError, shouldHideStack, shouldLogError, toErrorShape, toOutputPath };
@@ -1,4 +1,4 @@
1
- import { a as abortIf, c as getModelSync, d as perPage, f as Hash, i as abort, l as initializeGlobalContext, n as ModelConstructor, o as assertFound, p as Encryption, r as ModelRegistry, s as getModel, t as AbstractModelConstructor, u as isClass } from "../helpers-Bn6dk-9j.js";
1
+ import { a as abortIf, c as getModelSync, d as normalizePositiveInteger, f as perPage, h as Encryption, i as abort, l as initializeGlobalContext, m as Hash, n as ModelConstructor, o as assertFound, p as resolvePagination, r as ModelRegistry, s as getModel, t as AbstractModelConstructor, u as isClass } from "../helpers-CC35u6ti.js";
2
2
  import { Model } from "arkormx";
3
3
 
4
4
  //#region src/utils/traits.d.ts
@@ -185,4 +185,4 @@ type Derived<T extends (Trait | TypeFactory<Trait> | Cons)> = T extends TypeFact
185
185
  */
186
186
  declare function uses<T extends (Trait | TypeFactory<Trait> | Cons)>(instance: unknown, trait: T): instance is Derived<T>;
187
187
  //#endregion
188
- export { AbstractModelConstructor, Derived, Encryption, Hash, ModelConstructor, ModelRegistry, Trait, abort, abortIf, assertFound, callTraitMethods, crc32, getModel, getModelSync, getTraitMethods, initializeGlobalContext, isClass, perPage, trait, use, uses };
188
+ export { AbstractModelConstructor, Derived, Encryption, Hash, ModelConstructor, ModelRegistry, Trait, abort, abortIf, assertFound, callTraitMethods, crc32, getModel, getModelSync, getTraitMethods, initializeGlobalContext, isClass, normalizePositiveInteger, perPage, resolvePagination, trait, use, uses };
@@ -1,2 +1,2 @@
1
- import { a as use, c as abortIf, d as getModelSync, f as initializeGlobalContext, i as trait, l as assertFound, m as perPage, n as crc32, o as uses, p as isClass, r as getTraitMethods, s as abort, t as callTraitMethods, u as getModel, v as Hash, y as Encryption } from "../utils-C3mcZZMN.js";
2
- export { Encryption, Hash, abort, abortIf, assertFound, callTraitMethods, crc32, getModel, getModelSync, getTraitMethods, initializeGlobalContext, isClass, perPage, trait, use, uses };
1
+ import { a as use, b as Hash, c as abortIf, d as getModelSync, f as initializeGlobalContext, g as resolvePagination, h as perPage, i as trait, l as assertFound, m as normalizePositiveInteger, n as crc32, o as uses, p as isClass, r as getTraitMethods, s as abort, t as callTraitMethods, u as getModel, x as Encryption } from "../utils-CaaL-9im.js";
2
+ export { Encryption, Hash, abort, abortIf, assertFound, callTraitMethods, crc32, getModel, getModelSync, getTraitMethods, initializeGlobalContext, isClass, normalizePositiveInteger, perPage, resolvePagination, trait, use, uses };
@@ -170,15 +170,36 @@ var RequestException = class RequestException extends AppException {
170
170
  const isClass = (target) => {
171
171
  return typeof target === "function" && /^class\s/.test(Function.prototype.toString.call(target));
172
172
  };
173
+ const normalizePositiveInteger = (value, fallback) => {
174
+ const parsed = Number(value);
175
+ if (!Number.isInteger(parsed) || parsed < 1) return fallback;
176
+ return parsed;
177
+ };
173
178
  /**
174
- * Resolves the number of items to return per page based on the provided query parameters.
179
+ * Extracts a safe pagination limit from a query object.
175
180
  *
176
181
  * @param query
182
+ * @param defaults
183
+ * @default const defaults = { pageSize: 25, maxPageSize: 50 }
177
184
  * @returns
178
185
  */
179
- const perPage = (query) => {
180
- const requestedPerPage = Number(query.limit ?? query.perPage ?? query["per-page"] ?? query.per_page ?? 15);
181
- return Number.isFinite(requestedPerPage) && requestedPerPage > 0 ? Math.min(requestedPerPage, 50) : 15;
186
+ const perPage = (query, defaults) => {
187
+ const requestedPerPage = normalizePositiveInteger(query.limit ?? query.perPage ?? query["per-page"] ?? query.per_page, defaults?.perPage ?? 25);
188
+ return Math.min(requestedPerPage, defaults?.maxPerPage ?? 50);
189
+ };
190
+ /**
191
+ * Extracts the current page and a safe pagination limit from a query object.
192
+ *
193
+ * @param query
194
+ * @param defaults
195
+ * @default const defaults = { currentPage: 1, pageSize: 25, maxPageSize: 50 }
196
+ * @returns
197
+ */
198
+ const resolvePagination = (query, defaults) => {
199
+ return {
200
+ page: normalizePositiveInteger(query.page, defaults?.page ?? 1),
201
+ perPage: perPage(query, defaults)
202
+ };
182
203
  };
183
204
  async function getModel(modelName) {
184
205
  const resolveModelExport = (module, modelName) => {
@@ -466,4 +487,4 @@ function uses(instance, trait) {
466
487
  return false;
467
488
  }
468
489
  //#endregion
469
- export { Exception as _, use as a, abortIf as c, getModelSync as d, initializeGlobalContext as f, AppException as g, RequestException as h, trait as i, assertFound as l, perPage as m, crc32 as n, uses as o, isClass as p, getTraitMethods as r, abort as s, callTraitMethods as t, getModel as u, Hash as v, Encryption as y };
490
+ export { RequestException as _, use as a, Hash as b, abortIf as c, getModelSync as d, initializeGlobalContext as f, resolvePagination as g, perPage as h, trait as i, assertFound as l, normalizePositiveInteger as m, crc32 as n, uses as o, isClass as p, getTraitMethods as r, abort as s, callTraitMethods as t, getModel as u, AppException as v, Encryption as x, Exception as y };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arkstack/common",
3
- "version": "0.17.12",
3
+ "version": "0.17.13",
4
4
  "type": "module",
5
5
  "description": "Core utilities, primitives, and shared infrastructure for the Arkstack ecosystem.",
6
6
  "homepage": "https://arkstack.toneflix.net",
@@ -47,8 +47,8 @@
47
47
  "peerDependencies": {
48
48
  "@h3ravel/support": "^2.2.4",
49
49
  "arkormx": "^2.12.0",
50
- "@arkstack/contract": "^0.17.12",
51
- "@arkstack/foundry": "^0.17.12"
50
+ "@arkstack/contract": "^0.17.13",
51
+ "@arkstack/foundry": "^0.17.13"
52
52
  },
53
53
  "optionalDependencies": {
54
54
  "@faker-js/faker": "^10.4.0"
@@ -1,121 +0,0 @@
1
- import { TOTP } from "otpauth";
2
- import { Model, ModelStatic } from "arkormx";
3
-
4
- //#region src/utils/encryption.d.ts
5
- declare class Encryption {
6
- private static readonly algorithm;
7
- private static getKey;
8
- static encrypt(value: string): string;
9
- static decrypt(payload: string): string;
10
- }
11
- //#endregion
12
- //#region src/utils/hash.d.ts
13
- declare class Hash {
14
- /**
15
- * Hash a value using bcrypt
16
- *
17
- * @param value
18
- * @returns
19
- */
20
- static make(value: string): Promise<string>;
21
- /**
22
- * Verify a value against a hashed value
23
- *
24
- * @param value
25
- * @param hashedValue
26
- * @returns
27
- */
28
- static verify(value: string, hashedValue: string): Promise<boolean>;
29
- /**
30
- * Generate a one-time password (OTP) using TOTP algorithm
31
- *
32
- * @param digits The number of digits for the OTP, default is 6.
33
- * @param label A label to identify the OTP, can be an email or phone number.
34
- * @param period Interval of time for which a token is valid, in seconds.
35
- * @returns
36
- */
37
- static otp(digits?: number, label?: string, period?: number): TOTP;
38
- static totp(secret: string, label: string, issuer?: string, period?: number): TOTP;
39
- }
40
- //#endregion
41
- //#region src/utils/helpers.d.ts
42
- type AbstractModelConstructor<TModel = unknown> = abstract new (attributes?: Record<string, unknown>) => TModel;
43
- type ModelConstructor<TModel extends Model = Model> = AbstractModelConstructor<TModel> & Pick<ModelStatic<TModel>, keyof ModelStatic<TModel>>;
44
- interface ModelRegistry {}
45
- type ModelName = Extract<keyof ModelRegistry, string>;
46
- /**
47
- * Checks and asserts if target is a class
48
- *
49
- * @param target
50
- * @returns
51
- */
52
- declare const isClass: <T = unknown>(target: unknown) => target is new (...args: any[]) => T;
53
- /**
54
- * Resolves the number of items to return per page based on the provided query parameters.
55
- *
56
- * @param query
57
- * @returns
58
- */
59
- declare const perPage: (query: {
60
- limit?: number;
61
- perPage?: number;
62
- per_page?: number;
63
- "per-page"?: number;
64
- }) => number;
65
- /**
66
- * Import an application model by name.
67
- *
68
- * Apps can augment `ModelRegistry` to make `getModel('User')` return `typeof User`.
69
- * Without a registry entry, pass the class type explicitly: `getModel<typeof User>('User')`.
70
- *
71
- * @param modelName
72
- */
73
- declare function getModel<TName extends ModelName>(modelName: TName): Promise<ModelRegistry[TName]>;
74
- declare function getModel<TModel extends AbstractModelConstructor = ModelConstructor>(modelName: string): Promise<TModel>;
75
- /**
76
- * Synchronously import an application model by name.
77
- *
78
- * Apps can augment `ModelRegistry` to make `getModel('User')` return `typeof User`.
79
- * Without a registry entry, pass the class type explicitly: `getModel<typeof User>('User')`.
80
- *
81
- * @param modelName
82
- */
83
- declare function getModelSync<TName extends ModelName>(modelName: TName): ModelRegistry[TName];
84
- declare function getModelSync<TModel extends AbstractModelConstructor = ModelConstructor>(modelName: string): TModel;
85
- declare const initializeGlobalContext: ({
86
- Request,
87
- Response,
88
- Session
89
- }?: {
90
- Request?: any;
91
- Response?: any;
92
- Session?: any;
93
- }) => Promise<void>;
94
- /**
95
- * Thows to abort the current request
96
- *
97
- * @param message
98
- * @param code
99
- * @throws {RequestException}
100
- */
101
- declare const abort: (message?: string, code?: number) => void;
102
- /**
103
- * Asserts that a boolean condition is true.
104
- *
105
- * @param boolean
106
- * @param message
107
- * @param code
108
- * @throws {RequestException} Throws if the boolean condition is true.
109
- */
110
- declare const abortIf: <T>(boolean: T, message?: string, code?: number) => asserts boolean is T;
111
- /**
112
- * Asserts that a value is not null or undefined.
113
- *
114
- * @param value
115
- * @param message
116
- * @param code
117
- * @throws {RequestException} Throws if the value is null or undefined.
118
- */
119
- declare const assertFound: <T>(value: T | null | undefined, message: string, code?: number) => asserts value is T;
120
- //#endregion
121
- export { abortIf as a, getModelSync as c, perPage as d, Hash as f, abort as i, initializeGlobalContext as l, ModelConstructor as n, assertFound as o, Encryption as p, ModelRegistry as r, getModel as s, AbstractModelConstructor as t, isClass as u };