@vritti/api-sdk 0.2.3 → 0.2.5

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.cts CHANGED
@@ -5,26 +5,13 @@ import { Reflector } from '@nestjs/core';
5
5
  import { JwtService, JwtModuleOptions, JwtSignOptions } from '@nestjs/jwt';
6
6
  import { FastifyRequest, FastifyReply } from 'fastify';
7
7
  import { NodePgDatabase } from 'drizzle-orm/node-postgres';
8
+ import * as drizzle_orm from 'drizzle-orm';
8
9
  import { Column, SQL, InferInsertModel, InferSelectModel } from 'drizzle-orm';
10
+ import * as drizzle_orm_pg_core from 'drizzle-orm/pg-core';
9
11
  import { PgTable } from 'drizzle-orm/pg-core';
10
12
  import { Observable } from 'rxjs';
11
13
  import { AsyncLocalStorage } from 'node:async_hooks';
12
14
 
13
- interface TenantInfo {
14
- id: string;
15
- subdomain: string;
16
- type: 'SHARED' | 'DEDICATED';
17
- status: string;
18
- schemaName?: string;
19
- databaseName?: string;
20
- databaseHost?: string;
21
- databasePort?: number;
22
- databaseUsername?: string;
23
- databasePassword?: string;
24
- databaseSslMode?: string;
25
- connectionPoolSize?: number;
26
- }
27
-
28
15
  declare module 'fastify' {
29
16
  interface FastifyRequest {
30
17
  sessionInfo?: {
@@ -32,7 +19,6 @@ declare module 'fastify' {
32
19
  sessionId: string;
33
20
  sessionType: string;
34
21
  };
35
- tenant?: TenantInfo;
36
22
  cookies?: Record<string, string>;
37
23
  }
38
24
  }
@@ -45,16 +31,16 @@ declare const AccessToken: (...dataOrPipes: unknown[]) => ParameterDecorator;
45
31
 
46
32
  declare const CookieDomain: (...dataOrPipes: unknown[]) => ParameterDecorator;
47
33
 
48
- declare const Onboarding: () => _nestjs_common.CustomDecorator<string>;
49
-
50
34
  declare const Public: () => _nestjs_common.CustomDecorator<string>;
51
35
 
52
36
  declare const RefreshCookieOptions: (...dataOrPipes: unknown[]) => ParameterDecorator;
53
37
 
54
38
  declare const RefreshTokenCookie: (...dataOrPipes: unknown[]) => ParameterDecorator;
55
39
 
56
- declare const RESET_KEY = "isReset";
57
- declare const Reset: () => _nestjs_common.CustomDecorator<string>;
40
+ declare const REQUIRE_SESSION_KEY = "requiredSessionTypes";
41
+ declare const RequireSession: (...types: string[]) => _nestjs_common.CustomDecorator<string>;
42
+
43
+ declare const Subdomain: (...dataOrPipes: unknown[]) => ParameterDecorator;
58
44
 
59
45
  interface SessionInfo {
60
46
  userId: string;
@@ -202,6 +188,7 @@ interface GuardConfig {
202
188
  tenantHeaderName: string;
203
189
  authHeaderName: string;
204
190
  tokenPrefix: string;
191
+ defaultSessionTypes: string[];
205
192
  }
206
193
  interface ApiSdkConfig {
207
194
  cookie?: Partial<CookieConfig>;
@@ -246,9 +233,7 @@ interface DatabaseModuleOptions {
246
233
  primaryDb: PrimaryDbConfig;
247
234
  drizzleSchema: RegisteredSchema;
248
235
  drizzleRelations?: Record<string, any>;
249
- connectionCacheTTL?: number;
250
236
  maxConnections?: number;
251
- encryptionKey?: string;
252
237
  }
253
238
 
254
239
  declare class DatabaseModule {
@@ -256,14 +241,56 @@ declare class DatabaseModule {
256
241
  useFactory: (...args: unknown[]) => Promise<DatabaseModuleOptions> | DatabaseModuleOptions;
257
242
  inject?: InjectionToken[];
258
243
  }): DynamicModule;
259
- static forMicroservice(options: {
260
- useFactory: (...args: unknown[]) => Promise<DatabaseModuleOptions> | DatabaseModuleOptions;
261
- inject?: InjectionToken[];
262
- }): DynamicModule;
263
- private static createDynamicModule;
264
244
  }
265
245
 
266
- declare const Tenant: (...dataOrPipes: unknown[]) => ParameterDecorator;
246
+ interface UploadedFileResult {
247
+ buffer: Buffer;
248
+ filename: string;
249
+ mimetype: string;
250
+ }
251
+ /**
252
+ * Extracts a single uploaded file from a Fastify multipart request.
253
+ *
254
+ * Requires `@fastify/multipart` to be registered on the Fastify instance.
255
+ * Throws `BadRequestException` if no file is present in the request.
256
+ *
257
+ * @example
258
+ * ```typescript
259
+ * @Post('upload')
260
+ * @ApiConsumes('multipart/form-data')
261
+ * async upload(@UploadedFile() file: UploadedFileResult) {
262
+ * // file.buffer, file.filename, file.mimetype
263
+ * }
264
+ * ```
265
+ */
266
+ declare const UploadedFile: (...dataOrPipes: unknown[]) => ParameterDecorator;
267
+
268
+ declare class CreateResponseDto<T> {
269
+ success: boolean;
270
+ message: string;
271
+ data: T;
272
+ }
273
+
274
+ declare class ValidatedRowDto {
275
+ index: number;
276
+ data: Record<string, string>;
277
+ valid: boolean;
278
+ errors: string[];
279
+ }
280
+ declare class ImportSummaryDto {
281
+ total: number;
282
+ valid: number;
283
+ invalid: number;
284
+ }
285
+ declare class ImportResponseDto {
286
+ success: boolean;
287
+ message: string;
288
+ created?: number;
289
+ updated?: number;
290
+ skipped?: number;
291
+ rows?: ValidatedRowDto[];
292
+ summary?: ImportSummaryDto;
293
+ }
267
294
 
268
295
  declare class SelectOptionsQueryDto {
269
296
  search?: string;
@@ -345,20 +372,11 @@ declare class PrimaryDatabaseService implements OnModuleInit, OnModuleDestroy {
345
372
  private readonly logger;
346
373
  private pool;
347
374
  private db;
348
- private readonly tenantConfigCache;
349
- private readonly cacheTTL;
350
375
  constructor(options: DatabaseModuleOptions);
351
376
  onModuleInit(): Promise<void>;
352
377
  private initializeDrizzleClient;
353
- private buildPrimaryDbUrl;
354
- private maskPassword;
355
- getTenantInfo(tenantIdentifier: string): Promise<TenantInfo | null>;
356
- private cacheInfo;
357
- clearTenantCache(tenantIdentifier: string): void;
358
- clearAllCaches(): void;
359
378
  get drizzleClient(): TypedDrizzleClient;
360
379
  get schema(): typeof this$1.options.drizzleSchema;
361
- private decrypt;
362
380
  onModuleDestroy(): Promise<void>;
363
381
  }
364
382
 
@@ -401,6 +419,7 @@ interface FindForSelectConfig {
401
419
  groupIdKey?: string;
402
420
  joins?: FindForSelectJoin[];
403
421
  conditions?: SQL[];
422
+ distinct?: boolean;
404
423
  }
405
424
 
406
425
  type RelationsWhereFilter = Record<string, unknown>;
@@ -427,7 +446,7 @@ declare abstract class PrimaryBaseRepository<TTable extends PgTable, TInsert = I
427
446
  protected get db(): TypedDrizzleClient;
428
447
  protected get model(): TypedRelationalQueryBuilder<TSelect>;
429
448
  constructor(database: PrimaryDatabaseService, table: TTable);
430
- create(data: TInsert): Promise<TSelect>;
449
+ create(data: TInsert, tx?: TypedDrizzleClient): Promise<TSelect>;
431
450
  findById(id: string): Promise<TSelect | undefined>;
432
451
  findOne(where: RelationsWhereFilter): Promise<TSelect | undefined>;
433
452
  findMany(options?: {
@@ -445,87 +464,28 @@ declare abstract class PrimaryBaseRepository<TTable extends PgTable, TInsert = I
445
464
  offset?: number;
446
465
  leftJoin?: {
447
466
  table: PgTable;
448
- on: SQL;
467
+ on: SQL | undefined;
449
468
  };
469
+ leftJoins?: {
470
+ table: PgTable;
471
+ on: SQL | undefined;
472
+ }[];
473
+ groupBy?: (Column | SQL)[];
450
474
  }): Promise<{
451
475
  result: TResult[];
452
476
  count: number;
453
477
  }>;
454
- update(id: string, data: Partial<TInsert>): Promise<TSelect>;
455
- updateMany(where: SQL, data: Partial<TInsert>): Promise<{
456
- count: number;
457
- }>;
458
- delete(id: string): Promise<TSelect>;
459
- deleteMany(where: SQL): Promise<{
460
- count: number;
461
- }>;
462
- count(where?: SQL): Promise<number>;
463
- exists(where: SQL): Promise<boolean>;
464
- findForSelect(config: FindForSelectConfig): Promise<SelectQueryResult>;
465
- }
466
-
467
- declare class TenantContextService {
468
- private tenantInfo;
469
- setTenant(tenantInfo: TenantInfo): void;
470
- getTenant(): TenantInfo;
471
- hasTenant(): boolean;
472
- clearTenant(): void;
473
- getTenantIdSafe(): string | null;
474
- getTenantSubdomainSafe(): string | null;
475
- }
476
-
477
- declare class TenantDatabaseService implements OnModuleDestroy {
478
- private readonly options;
479
- private readonly tenantContext;
480
- private readonly logger;
481
- private readonly clients;
482
- private readonly clientLastUsed;
483
- private cleanupInterval?;
484
- constructor(options: DatabaseModuleOptions, tenantContext: TenantContextService);
485
- get drizzleClient(): TypedDrizzleClient;
486
- get schema(): Record<string, unknown>;
487
- private getDbClient;
488
- private createDbClientSync;
489
- private buildTenantDbUrl;
490
- private buildCacheKey;
491
- private startConnectionCleaner;
492
- private cleanupIdleConnections;
493
- getPoolStats(): {
494
- activeConnections: number;
495
- tenants: string[];
496
- };
497
- private maskPassword;
498
- onModuleDestroy(): Promise<void>;
499
- }
500
-
501
- type ExtractTableName<TTable extends PgTable> = TTable['_']['name'];
502
- declare abstract class TenantBaseRepository<TTable extends PgTable, TInsert = InferInsertModel<TTable>, TSelect = InferSelectModel<TTable>> {
503
- protected readonly database: TenantDatabaseService;
504
- protected readonly table: TTable;
505
- protected readonly logger: Logger;
506
- private readonly tableName;
507
- protected get db(): TypedDrizzleClient;
508
- protected get model(): TypedDrizzleClient['query'][ExtractTableName<TTable> & keyof TypedDrizzleClient['query']];
509
- constructor(database: TenantDatabaseService, table: TTable);
510
- create(data: TInsert): Promise<TSelect>;
511
- findById(id: string): Promise<TSelect | null>;
512
- findOne(where: SQL): Promise<TSelect | null>;
513
- findMany(options?: {
514
- where?: SQL;
515
- orderBy?: SQL;
516
- limit?: number;
517
- offset?: number;
518
- }): Promise<TSelect[]>;
519
- update(id: string, data: Partial<TInsert>): Promise<TSelect>;
520
- updateMany(where: SQL, data: Partial<TInsert>): Promise<{
478
+ update(id: string, data: Partial<TInsert>, tx?: TypedDrizzleClient): Promise<TSelect>;
479
+ updateMany(where: SQL, data: Partial<TInsert>, tx?: TypedDrizzleClient): Promise<{
521
480
  count: number;
522
481
  }>;
523
- delete(id: string): Promise<TSelect>;
524
- deleteMany(where: SQL): Promise<{
482
+ delete(id: string, tx?: TypedDrizzleClient): Promise<TSelect>;
483
+ deleteMany(where: SQL, tx?: TypedDrizzleClient): Promise<{
525
484
  count: number;
526
485
  }>;
527
486
  count(where?: SQL): Promise<number>;
528
487
  exists(where: SQL): Promise<boolean>;
488
+ transaction<T>(callback: (tx: TypedDrizzleClient) => Promise<T>): Promise<T>;
529
489
  findForSelect(config: FindForSelectConfig): Promise<SelectQueryResult>;
530
490
  }
531
491
 
@@ -543,6 +503,11 @@ declare class EmailService {
543
503
  sendPasswordResetEmail(email: string, otp: string, expiresAt: Date, displayName?: string): Promise<void>;
544
504
  sendEmailChangeNotification(oldEmail: string, newEmail: string, revertToken: string, revertExpiresAt: Date, displayName?: string): Promise<void>;
545
505
  sendEmailRevertConfirmation(email: string, displayName?: string): Promise<void>;
506
+ sendInviteEmail(params: {
507
+ to: string;
508
+ name: string;
509
+ inviteUrl: string;
510
+ }): Promise<void>;
546
511
  verifyConnection(): Promise<boolean>;
547
512
  private sendEmail;
548
513
  }
@@ -649,6 +614,7 @@ declare function getHttpStatusTitle(status: number): string;
649
614
  declare class HttpExceptionFilter implements ExceptionFilter {
650
615
  private readonly logger;
651
616
  catch(exception: unknown, host: ArgumentsHost): void;
617
+ private isHttpException;
652
618
  private isAxiosError;
653
619
  }
654
620
 
@@ -772,4 +738,118 @@ declare function normalizePhoneNumber(phone: string): string;
772
738
 
773
739
  declare function parseExpiryToMs(expiry: string): number;
774
740
 
775
- export { AccessToken, type AccessTokenPayload, type ApiErrorResponse, type ApiSdkConfig, AuthConfigModule, BadGatewayException, BadRequestException, CACHE_PROVIDER, CacheModule, CacheService, type ColumnPinning, ConflictException, type CookieConfig, CookieDomain, type CookieSerializeOptions, type CorrelationContext, CorrelationIdMiddleware, DEFAULT_CORRELATION_HEADER, DatabaseModule, type DatabaseModuleOptions, type DensityType, EmailModule, EmailService, type FieldDefinition, type FieldError, type FieldMap, type FilterCondition, type FilterOperator, FilterProcessor, type FindForSelectConfig, type FindForSelectJoin, ForbiddenException, GoneException, type GuardConfig, HttpExceptionFilter, HttpLoggerInterceptor, type HttpLoggerOptions, HttpProblemException, type ICacheProvider, InternalServerErrorException, JwtAuthService, type JwtConfig, LOGGER_MODULE_OPTIONS, type LogFormat, type LogLevel, type LogMetadata, LoggerModule, type LoggerModuleAsyncOptions, type LoggerModuleOptions, type LoggerOptionsFactory, LoggerService, MethodNotAllowedException, NotAcceptableException, NotFoundException, NotImplementedException, Onboarding, PayloadTooLargeException, PrimaryBaseRepository, PrimaryDatabaseService, type PrimaryDbConfig, type ProblemDetails, type ProblemOptions, Public, RESET_KEY, RedisCacheProvider, RefreshCookieOptions, RefreshTokenCookie, type RefreshTokenPayload, type RegisteredSchema, RequestTimeoutException, Reset, RootModule, SKIP_CSRF_KEY, SelectOptionsQueryDto, type SelectQueryGroup, type SelectQueryOption, type SelectQueryResult, ServiceUnavailableException, SessionData, type SessionInfo, SkipCsrf, type SortCondition, SuccessResponseDto, TableResponseDto, type TableViewState, Tenant, TenantBaseRepository, TenantContextService, TenantDatabaseService, type TenantInfo, type TokenExpiry, TokenType, TooManyRequestsException, type TypedDrizzleClient, UnauthorizedException, UnprocessableEntityException, UnsupportedMediaTypeException, UserId, ValidationException, VrittiAuthGuard, addCorrelationIdToResponse, configureApiSdk, correlationStorage, defineConfig, extractCountryFromPhone, generateCorrelationId, getConfig, getCorrelationContext, getHttpStatusTitle, getJwtExpiry, getRefreshCookieOptions, getRefreshCookieOptionsForHost, getTokenExpiry, hashToken, jwtConfigFactory, normalizePhoneNumber, parseExpiryToMs, resetConfig, runWithCorrelationContext, updateCorrelationContext, verifyTokenHash };
741
+ declare const DATA_TABLE_VIEWS_TABLE: unique symbol;
742
+
743
+ interface DataTableModuleOptions {
744
+ tableViews: PgTable;
745
+ }
746
+ declare class DataTableModule {
747
+ static forRoot(options: DataTableModuleOptions): DynamicModule;
748
+ }
749
+
750
+ declare function dataTableViewsColumns(): {
751
+ id: drizzle_orm.HasDefault<drizzle_orm.IsPrimaryKey<drizzle_orm_pg_core.PgUUIDBuilder>>;
752
+ userId: drizzle_orm.NotNull<drizzle_orm_pg_core.PgUUIDBuilder>;
753
+ tableSlug: drizzle_orm.NotNull<drizzle_orm_pg_core.PgVarcharBuilder<[string, ...string[]]>>;
754
+ name: drizzle_orm.NotNull<drizzle_orm_pg_core.PgVarcharBuilder<[string, ...string[]]>>;
755
+ state: drizzle_orm.$Type<drizzle_orm.NotNull<drizzle_orm_pg_core.PgJsonbBuilder>, TableViewState>;
756
+ isShared: drizzle_orm.HasDefault<drizzle_orm.NotNull<drizzle_orm_pg_core.PgBooleanBuilder>>;
757
+ createdAt: drizzle_orm.HasDefault<drizzle_orm.NotNull<drizzle_orm_pg_core.PgTimestampBuilder>>;
758
+ updatedAt: drizzle_orm.HasDefault<drizzle_orm_pg_core.PgTimestampBuilder>;
759
+ };
760
+ declare function dataTableViewsIndexes(table: any): drizzle_orm_pg_core.IndexBuilder[];
761
+ interface DataTableViewRecord {
762
+ id: string;
763
+ userId: string;
764
+ tableSlug: string;
765
+ name: string;
766
+ state: TableViewState;
767
+ isShared: boolean;
768
+ createdAt: Date;
769
+ updatedAt: Date | null | undefined;
770
+ }
771
+ interface NewDataTableViewRecord {
772
+ userId: string;
773
+ tableSlug: string;
774
+ name: string;
775
+ state: TableViewState;
776
+ isShared?: boolean;
777
+ }
778
+
779
+ declare class DataTableViewDto {
780
+ id: string;
781
+ name: string | null;
782
+ tableSlug: string;
783
+ state: TableViewState;
784
+ isShared: boolean;
785
+ isOwn: boolean;
786
+ createdAt: Date;
787
+ updatedAt: Date | null;
788
+ static from(view: DataTableViewRecord, userId: string): DataTableViewDto;
789
+ }
790
+
791
+ declare class CreateDataTableViewDto {
792
+ name: string;
793
+ tableSlug: string;
794
+ state: TableViewState;
795
+ isShared?: boolean;
796
+ }
797
+
798
+ declare class UpdateDataTableViewDto {
799
+ state: TableViewState;
800
+ }
801
+
802
+ declare class DataTableViewsRepository extends PrimaryBaseRepository<PgTable, NewDataTableViewRecord, DataTableViewRecord> {
803
+ constructor(database: PrimaryDatabaseService, table: PgTable);
804
+ findPersonalViewsBySlug(userId: string, tableSlug: string): Promise<DataTableViewRecord[]>;
805
+ findSharedViewsBySlug(tableSlug: string): Promise<DataTableViewRecord[]>;
806
+ }
807
+
808
+ declare class DataTableViewsService {
809
+ private readonly dataTableViewsRepository;
810
+ private readonly cacheService;
811
+ private readonly configService;
812
+ private readonly logger;
813
+ constructor(dataTableViewsRepository: DataTableViewsRepository, cacheService: CacheService, configService: ConfigService);
814
+ private personalViewsKey;
815
+ private sharedViewsKey;
816
+ private get viewsTtl();
817
+ private getOrCachePersonalViews;
818
+ private getOrCacheSharedViews;
819
+ private invalidateViewsCache;
820
+ findViews(userId: string, tableSlug: string): Promise<DataTableViewDto[]>;
821
+ createView(userId: string, dto: CreateDataTableViewDto): Promise<DataTableViewDto>;
822
+ updateView(userId: string, id: string, dto: UpdateDataTableViewDto): Promise<DataTableViewDto>;
823
+ toggleShareView(userId: string, id: string, isShared: boolean): Promise<DataTableViewDto>;
824
+ renameView(userId: string, id: string, name: string): Promise<DataTableViewDto>;
825
+ deleteView(userId: string, id: string): Promise<DataTableViewDto>;
826
+ }
827
+
828
+ declare class UpsertDataTableStateDto {
829
+ tableSlug: string;
830
+ state: TableViewState;
831
+ activeViewId?: string | null;
832
+ }
833
+
834
+ declare class DataTableStateService {
835
+ private readonly cacheService;
836
+ private readonly configService;
837
+ private readonly logger;
838
+ constructor(cacheService: CacheService, configService: ConfigService);
839
+ private get stateTtl();
840
+ upsertCurrentState(userId: string, dto: UpsertDataTableStateDto): Promise<void>;
841
+ getCurrentState(userId: string, tableSlug: string): Promise<{
842
+ state: TableViewState;
843
+ activeViewId: string | null;
844
+ }>;
845
+ }
846
+
847
+ declare class RenameDataTableViewDto {
848
+ name: string;
849
+ }
850
+
851
+ declare class ToggleShareDataTableViewDto {
852
+ isShared: boolean;
853
+ }
854
+
855
+ export { AccessToken, type AccessTokenPayload, type ApiErrorResponse, type ApiSdkConfig, AuthConfigModule, BadGatewayException, BadRequestException, CACHE_PROVIDER, CacheModule, CacheService, type ColumnPinning, ConflictException, type CookieConfig, CookieDomain, type CookieSerializeOptions, type CorrelationContext, CorrelationIdMiddleware, CreateDataTableViewDto, CreateResponseDto, DATA_TABLE_VIEWS_TABLE, DEFAULT_CORRELATION_HEADER, DataTableModule, type DataTableModuleOptions, DataTableStateService, DataTableViewDto, type DataTableViewRecord, DataTableViewsService, DatabaseModule, type DatabaseModuleOptions, type DensityType, EmailModule, EmailService, type FieldDefinition, type FieldError, type FieldMap, type FilterCondition, type FilterOperator, FilterProcessor, type FindForSelectConfig, type FindForSelectJoin, ForbiddenException, GoneException, type GuardConfig, HttpExceptionFilter, HttpLoggerInterceptor, type HttpLoggerOptions, HttpProblemException, type ICacheProvider, ImportResponseDto, ImportSummaryDto, InternalServerErrorException, JwtAuthService, type JwtConfig, LOGGER_MODULE_OPTIONS, type LogFormat, type LogLevel, type LogMetadata, LoggerModule, type LoggerModuleAsyncOptions, type LoggerModuleOptions, type LoggerOptionsFactory, LoggerService, MethodNotAllowedException, type NewDataTableViewRecord, NotAcceptableException, NotFoundException, NotImplementedException, PayloadTooLargeException, PrimaryBaseRepository, PrimaryDatabaseService, type PrimaryDbConfig, type ProblemDetails, type ProblemOptions, Public, REQUIRE_SESSION_KEY, RedisCacheProvider, RefreshCookieOptions, RefreshTokenCookie, type RefreshTokenPayload, type RegisteredSchema, RenameDataTableViewDto, RequestTimeoutException, RequireSession, RootModule, SKIP_CSRF_KEY, type SearchState, SelectOptionsQueryDto, type SelectQueryGroup, type SelectQueryOption, type SelectQueryResult, ServiceUnavailableException, SessionData, type SessionInfo, SkipCsrf, type SortCondition, Subdomain, SuccessResponseDto, TableResponseDto, type TableViewState, ToggleShareDataTableViewDto, type TokenExpiry, TokenType, TooManyRequestsException, type TypedDrizzleClient, UnauthorizedException, UnprocessableEntityException, UnsupportedMediaTypeException, UpdateDataTableViewDto, UploadedFile, type UploadedFileResult, UpsertDataTableStateDto, UserId, ValidatedRowDto, ValidationException, VrittiAuthGuard, addCorrelationIdToResponse, configureApiSdk, correlationStorage, dataTableViewsColumns, dataTableViewsIndexes, defineConfig, extractCountryFromPhone, generateCorrelationId, getConfig, getCorrelationContext, getHttpStatusTitle, getJwtExpiry, getRefreshCookieOptions, getRefreshCookieOptionsForHost, getTokenExpiry, hashToken, jwtConfigFactory, normalizePhoneNumber, parseExpiryToMs, resetConfig, runWithCorrelationContext, updateCorrelationContext, verifyTokenHash };