@pcg/core 1.0.0-alpha.0 → 1.0.0-alpha.1
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/.turbo/turbo-build.log +4 -3
- package/CHANGELOG.md +7 -0
- package/dist/index.d.ts +1 -11
- package/dist/index.js +1 -12
- package/dist/index.js.map +1 -1
- package/package.json +3 -2
- package/src/tools/is-object.ts +1 -10
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
|
|
2
2
|
|
|
3
|
-
> @pcg/core@1.0.0-alpha.0 build /Users/
|
|
3
|
+
> @pcg/core@1.0.0-alpha.0 build /Users/vangolenko/node/pcg/packages/core
|
|
4
4
|
> tsdown
|
|
5
5
|
|
|
6
6
|
[34mℹ[39m tsdown [2mv0.15.12[22m powered by rolldown [2mv1.0.0-beta.45[22m
|
|
7
|
-
[34mℹ[39m Using tsdown config: [4m/Users/
|
|
7
|
+
[34mℹ[39m Using tsdown config: [4m/Users/vangolenko/node/pcg/packages/core/tsdown.config.ts[24m
|
|
8
8
|
[34mℹ[39m entry: [34msrc/index.ts[39m
|
|
9
9
|
[34mℹ[39m tsconfig: [34m../../tsconfig.build.json[39m
|
|
10
10
|
[34mℹ[39m Build start
|
|
11
|
+
[34mℹ[39m Cleaning 3 files
|
|
11
12
|
[34mℹ[39m [2mdist/[22m[1mindex.js[22m [2m 66.24 kB[22m [2m│ gzip: 16.24 kB[22m
|
|
12
13
|
[34mℹ[39m [2mdist/[22mindex.js.map [2m118.05 kB[22m [2m│ gzip: 27.87 kB[22m
|
|
13
14
|
[34mℹ[39m [2mdist/[22m[32m[1mindex.d.ts[22m[39m [2m 46.49 kB[22m [2m│ gzip: 11.11 kB[22m
|
|
14
15
|
[34mℹ[39m 3 files, total: 230.77 kB
|
|
15
|
-
[32m✔[39m Build complete in [
|
|
16
|
+
[32m✔[39m Build complete in [32m4442ms[39m
|
package/CHANGELOG.md
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ArgumentsHost, ConsoleLogger, DynamicModule, HttpException, HttpServer, HttpStatus, LogLevel, LoggerService, OnModuleInit, Provider, Type, ValidationError, ValidationPipe } from "@nestjs/common";
|
|
2
2
|
import { BaseEntity, DataSource, EntityManager, LogLevel as LogLevel$1, LogMessage, ObjectLiteral, Repository, SelectQueryBuilder } from "typeorm";
|
|
3
3
|
import * as _nestjs_config0 from "@nestjs/config";
|
|
4
|
+
import { isObject } from "@pcg/predicates";
|
|
4
5
|
import { AbstractLogger } from "typeorm/logger/AbstractLogger.js";
|
|
5
6
|
import * as winston from "winston";
|
|
6
7
|
import { LogEntry, Logger as Logger$1, LoggerOptions } from "winston";
|
|
@@ -1160,17 +1161,6 @@ declare const fetchTotalWithQuery: <T extends ObjectLiteral>(query: SelectQueryB
|
|
|
1160
1161
|
*/
|
|
1161
1162
|
declare const generateEntityId: (product: string, prefix: string, delimiter?: string, size?: number) => string;
|
|
1162
1163
|
//#endregion
|
|
1163
|
-
//#region src/tools/is-object.d.ts
|
|
1164
|
-
/**
|
|
1165
|
-
* Checks if the given value is an object (not an array).
|
|
1166
|
-
* @param {unknown} obj - The value to check.
|
|
1167
|
-
* @returns {boolean} Returns true if `obj` is an object, false otherwise.
|
|
1168
|
-
* @example
|
|
1169
|
-
* isObject({ a: 1 }); // Returns true
|
|
1170
|
-
* isObject([1, 2, 3]); // Returns false
|
|
1171
|
-
*/
|
|
1172
|
-
declare const isObject: (obj: unknown) => obj is Record<string, unknown>;
|
|
1173
|
-
//#endregion
|
|
1174
1164
|
//#region src/types/express-request.d.ts
|
|
1175
1165
|
interface NestExpressRequest extends Request {
|
|
1176
1166
|
appShortname: string;
|
package/dist/index.js
CHANGED
|
@@ -7,6 +7,7 @@ import { Type as Type$1, plainToInstance } from "class-transformer";
|
|
|
7
7
|
import { IsBoolean, IsEnum, IsNumber, IsOptional, IsString, Min, validateSync } from "class-validator";
|
|
8
8
|
import { ArgsType, Field, Int, ObjectType } from "@nestjs/graphql";
|
|
9
9
|
import { isFunction, isObject as isObject$1, isPlainObject } from "@nestjs/common/utils/shared.utils";
|
|
10
|
+
import { isObject } from "@pcg/predicates";
|
|
10
11
|
import { GraphQLError } from "graphql";
|
|
11
12
|
import { AbstractLogger } from "typeorm/logger/AbstractLogger.js";
|
|
12
13
|
import * as winston from "winston";
|
|
@@ -763,18 +764,6 @@ const NESTKIT_SYSTEM_LOGGER_PROVIDER = "NestKitSystemLogger";
|
|
|
763
764
|
*/
|
|
764
765
|
const NESTKIT_LOGGER_FACTORY_PROVIDER = "NestKitLoggerFactory";
|
|
765
766
|
|
|
766
|
-
//#endregion
|
|
767
|
-
//#region src/tools/is-object.ts
|
|
768
|
-
/**
|
|
769
|
-
* Checks if the given value is an object (not an array).
|
|
770
|
-
* @param {unknown} obj - The value to check.
|
|
771
|
-
* @returns {boolean} Returns true if `obj` is an object, false otherwise.
|
|
772
|
-
* @example
|
|
773
|
-
* isObject({ a: 1 }); // Returns true
|
|
774
|
-
* isObject([1, 2, 3]); // Returns false
|
|
775
|
-
*/
|
|
776
|
-
const isObject = (obj) => obj !== null && !!obj && typeof obj === "object" && !Array.isArray(obj);
|
|
777
|
-
|
|
778
767
|
//#endregion
|
|
779
768
|
//#region src/logger/classes/logger.ts
|
|
780
769
|
/**
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["Type","IdService","appConfig: AppConfigType","IdModule","CursorPaginationPageInfo","CursorPaginationInput","OffsetPaginationInput","OffsetPaginationPageInfo","winstonLogger: WinstonLogger","context: LoggerContext","errorObject: DestructuredError","NestSystemLogger","winstonLogger: WinstonLogger","context: LoggerContext","Logger","providers: Provider[]","LoggerModule","nestLikeColorScheme: Record<string, bare.Format>","context","format","winstonOptions: winston.LoggerOptions","params: NestJsResourceServiceParams<T, GOBO, F, O>","Type","meta: ListMeta","result: Partial<UndefinedRemoved<T>>","HttpExceptionFilter","applicationRef: HttpServer","loggerFactory: LoggerFactory","isObject","body: {\n message: string;\n key?: string;\n stack?: string;\n context?: LoggerContext;\n statusCode: number;\n }"],"sources":["../src/enums/app-env.enum.ts","../src/enums/app-mode.enum.ts","../src/tools/env.ts","../src/configs/app.config.ts","../src/enums/app-server.enum.ts","../src/enums/worker-mode.enum.ts","../src/tools/generate-entity-id.ts","../src/modules/id/id.service.ts","../src/modules/id/id.module.ts","../src/errors/nest-error.ts","../src/errors/bad-request.error.ts","../src/errors/not-found.error.ts","../src/pagination/constants.ts","../src/errors/forbidden.error.ts","../src/errors/access-denied.error.ts","../src/errors/input-validation.error.ts","../src/errors/unauthorized.error.ts","../src/pagination/cursor/cursor-pagination.types.ts","../src/pagination/cursor/cursor-pagination.input.ts","../src/pagination/offset/offset-pagination.helpers.ts","../src/pagination/offset/offset-pagination.input.ts","../src/pagination/offset/offset-pagination.types.ts","../src/tools/stringify-opts.ts","../src/logger/logger.constants.ts","../src/tools/is-object.ts","../src/logger/classes/logger.ts","../src/logger/classes/nest-system-logger.ts","../src/logger/classes/typeorm-logger.ts","../src/logger/classes/logger-factory.ts","../src/logger/logger.providers.ts","../src/logger/logger.module.ts","../src/logger/winston.tools.ts","../src/configs/logger.config.ts","../src/abstracts/nestjs-service.ts","../src/abstracts/nestjs-resource-service.ts","../src/db/snake-naming.strategy.ts","../src/configs/db.config.ts","../src/tools/compose.ts","../src/tools/convert-to-bigint.ts","../src/tools/fetch-total-with-query.ts","../src/tools/create-list-meta.ts","../src/tools/define-statuses.ts","../src/tools/get-request-language.ts","../src/tools/postgres/locale-to-pg-collate.ts","../src/tools/remove-undefined-properties.ts","../src/tools/request-id.ts","../src/tools/wait.ts","../src/tools/typeorm/add-filter.ts","../src/tools/typeorm/is-alias-already-busy.ts","../src/tools/typeorm/ensure-inner-join.ts","../src/tools/typeorm/ensure-left-join.ts","../src/validation/validation-pipe.ts","../src/exceptions/http-exceptions.filter.ts"],"sourcesContent":["/**\n * Application environment enum\n */\nexport enum AppEnv {\n /**\n * Local environment.\n * Used for local development on your machine.\n */\n LOCAL = 'local',\n\n /**\n * Test environment.\n * Used when running tests.\n */\n TEST = 'test',\n\n /**\n * Development environment.\n * Used when deploying to a development server.\n * Development server provide early access to new features.\n */\n DEVELOPMENT = 'development',\n\n /**\n * Stage environment.\n * Used when deploying to a stage server.\n * Stage is a pre-production environment.\n */\n STAGE = 'stage',\n\n /**\n * Production environment.\n * Used when deploying to a production server.\n */\n PRODUCTION = 'production',\n}\n","export enum AppMode {\n STANDALONE = 'standalone',\n PARENT = 'parent',\n CHILD = 'child',\n}\n","import { Type as ClassConstructor } from '@nestjs/common';\nimport { plainToInstance } from 'class-transformer';\nimport { validateSync } from 'class-validator';\n\nimport { AppEnv } from '#/enums/app-env.enum';\n\n/**\n * Validate environment variables using class-validator\n *\n * @param cls - class with environment variables\n * @throws Error if validation fails\n * @returns validated config as typed object\n * @example\n * ```ts\n * export class AppConfigEnvironmentVariables {\n * @Type(() => Number)\n * @IsNumber()\n * PORT = 3000;\n * }\n *\n * const env = validateEnv(AppConfigEnvironmentVariables); // typed object\n * // env.PORT is now a number\n * ```\n */\nexport const validateEnv = <T>(cls: ClassConstructor<T>): T => {\n const validatedConfig = plainToInstance(\n cls,\n process.env,\n {\n enableImplicitConversion: true,\n },\n );\n\n const errors = validateSync(validatedConfig as unknown as object, {\n skipMissingProperties: false,\n });\n\n if (errors.length > 0) {\n throw new Error(errors.toString());\n }\n\n return validatedConfig;\n};\n\n/**\n * Returns a string with a dash prefix based on the current environment.\n * If the environment is development or local, returns '-dev'.\n * If the environment is stage, returns '-stage'.\n * Otherwise, returns an empty string.\n *\n * @returns a string with a dash prefix based on the current environment\n * @example\n * ```typescript\n * const name = `my-app${withDashEnv()}`;\n * ```\n */\nexport const withDashEnv = () => {\n if (process.env.APP_ENV === AppEnv.DEVELOPMENT || process.env.APP_ENV === AppEnv.LOCAL || process.env.APP_ENV === AppEnv.TEST) {\n return '-dev';\n }\n\n if (process.env.APP_ENV === AppEnv.STAGE) {\n return '-stage';\n }\n\n return '';\n};\n\n/**\n * Returns a string with a dash prefix based on the current environment.\n * If the environment is development or local, returns '.dev'.\n * If the environment is stage, returns '.stage'.\n * Otherwise, returns an empty string.\n *\n * @returns a string with a dot prefix based on the current environment\n * @example\n * ```typescript\n * const name = `config${withDotEnv()}`;\n * ```\n */\nexport const withDotEnv = () => {\n if (process.env.APP_ENV === AppEnv.DEVELOPMENT || process.env.APP_ENV === AppEnv.LOCAL || process.env.APP_ENV === AppEnv.TEST) {\n return '.dev';\n }\n\n if (process.env.APP_ENV === AppEnv.STAGE) {\n return '.stage';\n }\n\n return '';\n};\n\n/**\n * Returns a string with a colon prefix based on the current environment.\n * If the environment is development or local, returns ':dev'.\n * If the environment is stage, returns ':stage'.\n * Otherwise, returns an empty string.\n *\n * @returns a string with a colon prefix based on the current environment\n * @example\n * ```typescript\n * const name = `my:app${withColonEnv()}`;\n * ```\n */\nexport const withColonEnv = () => {\n if (process.env.APP_ENV === AppEnv.DEVELOPMENT || process.env.APP_ENV === AppEnv.LOCAL || process.env.APP_ENV === AppEnv.TEST) {\n return ':dev';\n }\n\n if (process.env.APP_ENV === AppEnv.STAGE) {\n return ':stage';\n }\n\n return '';\n};\n\n/**\n * Returns a string with an underscore prefix based on the current environment.\n * If the environment is development or local, returns '_dev'.\n * If the environment is stage, returns '_stage'.\n * Otherwise, returns an empty string.\n *\n * @returns a string with an underscore prefix based on the current environment\n * @example\n * ```typescript\n * const name = `my_app${withUnderscoreEnv()}`;\n * ```\n */\nexport const withUnderscoreEnv = () => {\n if (process.env.APP_ENV === AppEnv.DEVELOPMENT || process.env.APP_ENV === AppEnv.LOCAL || process.env.APP_ENV === AppEnv.TEST) {\n return '_dev';\n }\n\n if (process.env.APP_ENV === AppEnv.STAGE) {\n return '_stage';\n }\n\n return '';\n};\n","import { Inject } from '@nestjs/common';\nimport { getConfigToken, registerAs } from '@nestjs/config';\nimport { Type } from 'class-transformer';\nimport {\n IsEnum, IsNumber, IsOptional, IsString,\n} from 'class-validator';\n\nimport { AppEnv } from '../enums/app-env.enum.js';\nimport { AppMode } from '../enums/app-mode.enum.js';\nimport { validateEnv } from '../tools/env.js';\n\n/**\n * NestJS injection token for app config\n */\nexport const APP_CONFIG_TOKEN = 'APP_CONFIG_TOKEN';\n\nexport const InjectAppConfig = () => Inject(getConfigToken(APP_CONFIG_TOKEN));\n\n/**\n * Application config environment variables\n */\nexport class AppConfigEnvironmentVariables {\n /**\n * Application port\n * @example\n * ```yaml\n * PORT: 3000\n * ```\n */\n @Type(() => Number)\n @IsNumber()\n PORT = 3000;\n\n /**\n * Application host\n * @example\n * ```yaml\n * APP_HOST: 'https://app-api.example.com'\n * # or\n * APP_HOST: 'http://localhost:3000'\n * ```\n */\n @IsOptional()\n @IsString()\n APP_HOST!: string;\n\n /**\n * Application UI host\n * @example\n * ```yaml\n * APP_UI_HOST: 'https://app.example.com'\n * # or\n * APP_UI_HOST: 'http://localhost:4200'\n * ```\n */\n @IsOptional()\n @IsString()\n APP_UI_HOST!: string;\n\n /**\n * Application environment. Can be 'local', 'development', 'stage', 'production'\n * @example\n * ```yaml\n * APP_ENV: 'local'\n * ```\n */\n @IsEnum(AppEnv)\n APP_ENV!: AppEnv;\n\n /**\n * Application service account id (user with type SA in users table)\n * @example\n * ```yaml\n * APP_SERVICE_ACCOUNT_ID: 'hcu:xxxxxxxxxxx'\n * ```\n */\n @IsOptional()\n @IsString()\n APP_SERVICE_ACCOUNT_ID?: string;\n\n /**\n * Application fallback language\n * @example\n * ```yaml\n * FALLBACK_LANGUAGE: 'es'\n * ```\n */\n @IsOptional()\n @IsString()\n FALLBACK_LANGUAGE = 'en';\n}\n\nexport interface AppConfigType {\n /**\n * Application environment\n * @example 'local', 'development', 'stage', 'production'\n */\n env: AppEnv;\n\n /**\n * Application name\n * @example 'Jetstream'\n */\n name: string;\n\n /**\n * Application shortname\n * @example 'js'\n */\n shortname: string;\n\n /**\n * Application port\n * @example 3000\n */\n port: number;\n\n /**\n * Application mode\n * @example 'standalone'\n */\n mode: AppMode;\n\n /**\n * Application host\n * @example 'https://app-api.example.com or http://localhost:3000'\n */\n host?: string;\n\n /**\n * Application UI host\n * @example 'https://app.example.com or http://localhost:8080'\n */\n uiHost?: string;\n\n /**\n * Application fallback language\n * @example 'en'\n */\n fallbackLanguage: string;\n\n /**\n * Application service account id (user with type SA in users table)\n * @example 'hcu:xxxxxxxxxxx'\n */\n appServiceAccountId?: string;\n}\n\nexport interface AppConfigOptions {\n name: string;\n shortname: string;\n mode?: AppMode;\n}\n\n/**\n * Create Main Application Config\n * @example\n * ```ts\n * // src/config/index.ts\n *\n * import { createAppConfig } from '#/dist/configs';\n *\n * export const appConfig = createAppConfig({\n * name: 'Jetstream',\n * shortname: 'js',\n * });\n * ```\n */\nexport const createAppConfig = (opts: AppConfigOptions) => {\n return registerAs(APP_CONFIG_TOKEN, (): AppConfigType => {\n const env = validateEnv(AppConfigEnvironmentVariables);\n\n return {\n env: env.APP_ENV,\n name: opts.name,\n shortname: opts.shortname,\n port: env.PORT,\n host: env.APP_HOST,\n mode: opts.mode || AppMode.STANDALONE,\n uiHost: env.APP_UI_HOST,\n appServiceAccountId: env.APP_SERVICE_ACCOUNT_ID,\n fallbackLanguage: env.FALLBACK_LANGUAGE,\n };\n });\n};\n","/**\n * Enum for the NestJS server mode\n */\nexport enum AppServer {\n /**\n * NestJS HTTP server with GraphQL\n */\n HTTP = 'http',\n\n /**\n * NestJS gRPC server\n */\n GRPC = 'grpc',\n\n /**\n * NestJS WebSocket server\n */\n WS = 'ws',\n\n /**\n * Run as a worker\n */\n WORKER = 'worker',\n\n /**\n * Run as an agent\n */\n AGENT = 'agent',\n\n /**\n * Run as an bot (e.g. Slack bot)\n */\n BOT = 'bot',\n\n /**\n * Run as Cloud Run job\n */\n CLOUDRUN_JOB = 'cloudrun-job',\n}\n","export enum WorkerMode {\n /**\n * Run jobs in loop\n */\n LOOP = 'loop',\n\n /**\n * Run one job and exit\n */\n ONE_JOB = 'one-job',\n}\n","import { createRandomString } from '@pcg/text-kit';\n\n/**\n * Generates a unique entity identifier by combining product name, entity prefix, delimiter, and random string.\n *\n * @param product - The product short name to include in the entity ID (e.g., 'fwd' for Forward)\n * @param prefix - The entity type prefix to include in the entity ID (e.g., 'u' for user, 'org' for organization)\n * @param delimiter - The delimiter to separate components (default: ':')\n * @param size - The length of the random string component (default: 11)\n * @returns A formatted entity ID string in the format: `${product}${prefix}${delimiter}${randomString}`\n *\n * @example\n * ```typescript\n * generateEntityId('fwd', 'org')\n * // Returns: 'fwdorg:A1b2C3d4E5f'\n *\n * generateEntityId('myapp', 'u', '_', 8)\n * // Returns: 'myappuser_A1b2C3d4'\n * ```\n */\nexport const generateEntityId = (product: string, prefix: string, delimiter = ':', size = 11): string => {\n return `${product}${prefix}${delimiter}${createRandomString(size)}`;\n};\n","import { Inject, Injectable } from '@nestjs/common';\nimport { getConfigToken } from '@nestjs/config';\nimport { createRandomString } from '@pcg/text-kit';\n\nimport { APP_CONFIG_TOKEN, type AppConfigType } from '#/configs/app.config';\nimport { AppEnv } from '#/enums';\nimport { generateEntityId } from '#/tools/generate-entity-id';\n\n/**\n * An IdService is a service within your application that provides methods to generate unique IDs\n * for entities and other data objects.\n */\n@Injectable()\nexport class IdService {\n constructor(\n @Inject(getConfigToken(APP_CONFIG_TOKEN)) private readonly appConfig: AppConfigType,\n ) {}\n\n /**\n * Returns a delimiter string based on the current environment.\n * This delimiter is used in constructing the entity IDs.\n * The delimiter is ':dev:' for development environments,\n * :stage:' for staging environments and ':' for other environments.\n *\n * This allows for better differentiation and traceability of entities across various environments.\n */\n get delimiter() {\n switch (this.appConfig.env) {\n case AppEnv.TEST:\n return ':test:';\n case AppEnv.DEVELOPMENT:\n return ':dev:';\n case AppEnv.STAGE:\n return ':stage:';\n default:\n return ':';\n }\n }\n\n /**\n * Generates unique id for entity\n * @param prefix - entity id prefix in database (e.g. 'u' for users)\n * @param app - app shortname (e.g. 'js')\n * @returns id in format 'jsu:xxxxxxxxxxx' or 'jsu:stage:xxxxxxxxxxx' for staging environment\n */\n generateEntityId(prefix: string, app?: string): string {\n return generateEntityId(app ?? this.appConfig.shortname, prefix, this.delimiter, 11);\n }\n\n /**\n * Generates unique id with length 11\n * @returns id in format 'xxxxxxxxxxx'\n */\n generateId(size?: number) {\n return createRandomString(size);\n }\n}\n","import { Global, Module } from '@nestjs/common';\n\nimport { IdService } from './id.service.js';\n\n/**\n * An IdModule is a module within your application that provides services to generate unique IDs\n * for entities and other data objects.\n * @example\n * ```ts\n * // app.module.ts\n * import { IdModule } from './id.module';\n *\n * @Module({\n * imports: [IdModule],\n * controllers: [AppController],\n * providers: [AppService],\n * })\n * export class AppModule {}\n * ```\n */\n@Global()\n@Module({\n providers: [IdService],\n exports: [IdService],\n})\nexport class IdModule {}\n","import { HttpStatus } from '@nestjs/common';\n\n/**\n * Configuration options for creating a NestError instance.\n *\n * @interface NestErrorOptions\n */\nexport interface NestErrorOptions {\n /** The human-readable error message describing what went wrong */\n message: string;\n\n /**\n * A unique identifier or error code for categorizing and handling the error\n * @example\n * 'AUTH_USER_NOT_FOUND'\n * */\n key: string;\n\n /** The underlying error that caused this error, if any */\n cause?: unknown;\n\n /** Additional contextual information related to the error occurrence */\n context?: Record<string, unknown>;\n\n /**\n * Whether the error should be silenced (i.e., not logged or reported)\n */\n silent?: boolean;\n}\n\n/**\n * Custom error class for NestJS applications that extends the native Error class.\n *\n * This error class provides additional context and structured error handling\n * capabilities beyond the standard Error object.\n *\n * @example\n * ```typescript\n * throw new NestError({\n * key: 'AUTH_USER_NOT_FOUND',\n * message: 'User with the specified ID was not found',\n * context: { userId: '123' },\n * cause: originalError\n * });\n * ```\n */\nexport class NestError extends Error {\n key!: string;\n context?: Record<string, unknown>;\n httpStatusCode = HttpStatus.INTERNAL_SERVER_ERROR;\n silent!: boolean;\n\n constructor(opts: NestErrorOptions) {\n super(opts.message, opts.cause instanceof Error ? {\n cause: opts.cause,\n } : undefined);\n\n this.name = 'NestError';\n this.key = opts.key;\n this.context = opts.context;\n this.silent = opts.silent ?? false;\n }\n}\n","import { NestError, NestErrorOptions } from './nest-error.js';\n\nexport class BadRequestError extends NestError {\n constructor(opts: NestErrorOptions) {\n super(opts);\n this.name = 'BadRequestError';\n this.httpStatusCode = 400;\n }\n}\n","import { NestError, NestErrorOptions } from './nest-error.js';\n\nexport class NotFoundError extends NestError {\n constructor(opts: NestErrorOptions) {\n super(opts);\n this.name = 'NotFoundError';\n this.httpStatusCode = 404;\n }\n}\n","/**\n * Pagination max limit value\n */\nexport const PAGINATION_MAX_LIMIT = 1000;\n\n/**\n * Pagination default limit value\n */\nexport const PAGINATION_DEFAULT_LIMIT = 20;\n","import { NestError, NestErrorOptions } from './nest-error.js';\n\nexport class ForbiddenError extends NestError {\n constructor(opts: NestErrorOptions) {\n super(opts);\n this.name = 'ForbiddenError';\n this.httpStatusCode = 403;\n }\n}\n","import { ForbiddenError } from './forbidden.error.js';\n\nexport interface AccessDeniedErrorOptions {\n action: string;\n context: Record<string, unknown>;\n message?: string;\n}\n\nexport class AccessDeniedError extends ForbiddenError {\n constructor(opts: AccessDeniedErrorOptions) {\n super({\n key: 'AUTH_ACCESS_DENIED',\n message: opts.message || `Access denied: you don't have permission to perform \"${opts.action}\" action`,\n context: opts.context,\n });\n this.name = 'AccessDeniedError';\n }\n}\n","import { ValidationError } from '@nestjs/common';\nimport { NestError } from './nest-error.js';\n\nexport class InputValidationError extends NestError {\n constructor(errors?: ValidationError[]) {\n super({\n message: 'Input validation failed',\n key: 'NST_INPUT_VALIDATION_ERROR',\n context: errors ? {\n errors,\n } : undefined,\n });\n this.name = 'InputValidationError';\n this.httpStatusCode = 400;\n }\n}\n","import { NestError, NestErrorOptions } from './nest-error.js';\n\nexport class UnauthorizedError extends NestError {\n constructor(opts: NestErrorOptions) {\n super(opts);\n this.name = 'UnauthorizedError';\n this.httpStatusCode = 401;\n }\n}\n","import { Type } from '@nestjs/common';\nimport { Field, ObjectType } from '@nestjs/graphql';\n\nimport type { MaybeNull } from '#/types/maybe';\n\n@ObjectType()\nexport class CursorPaginationPageInfo {\n /**\n * The cursor to the first item in the list\n */\n @Field(() => String, {\n nullable: true,\n })\n startCursor!: MaybeNull<string>;\n\n /**\n * The cursor to the last item in the list\n */\n @Field(() => String, {\n nullable: true,\n })\n endCursor!: MaybeNull<string>;\n\n /**\n * Whether there are more items in the list before the start cursor\n */\n @Field(() => Boolean, {\n nullable: true,\n })\n hasPreviousPage?: boolean;\n\n /**\n * Whether there are more items in the list after the end cursor\n */\n @Field(() => Boolean, {\n nullable: true,\n })\n hasNextPage?: boolean;\n}\n\n/**\n * The edge type for cursor pagination\n */\nexport interface IEdge<T> {\n /**\n * The cursor for the item\n */\n cursor: string;\n\n /**\n * The item\n */\n node: T;\n}\n\nexport interface ICursorPaginated<T> {\n /**\n * The list of edges\n */\n edges: IEdge<T>[];\n\n /**\n * The pagination info\n */\n pageInfo: CursorPaginationPageInfo;\n}\n\n/**\n * Creates a new GraphQL object type with the name `Paginated${classRef.name}`\n * that implements the `ICursorPaginated` interface\n * @param classRef The class reference of the items\n *\n * @example Create PaginatedMessages type\n * ```ts\n * @ObjectType()\n * class PaginatedMessages extends CursorPaginated(Message) {}\n * ```\n */\n// eslint-disable-next-line func-style\nexport function CursorPaginated<T>(classRef: Type<T>): Type<ICursorPaginated<T>> {\n @ObjectType(`${classRef.name}Edge`)\n abstract class EdgeType implements IEdge<T> {\n /**\n * The cursor for the item\n */\n @Field(() => String, {\n description: 'The cursor for the item',\n })\n cursor!: string;\n\n /**\n * The item\n */\n @Field(() => classRef, {\n description: 'The item',\n })\n node!: T;\n }\n\n @ObjectType({\n isAbstract: true,\n })\n abstract class CursorPaginatedType implements ICursorPaginated<T> {\n /**\n * The list of edges\n */\n @Field(() => [EdgeType], {\n description: 'The list of edges',\n })\n edges!: EdgeType[];\n\n /**\n * The pagination info\n */\n @Field(() => CursorPaginationPageInfo, {\n description: 'The pagination info',\n })\n pageInfo!: CursorPaginationPageInfo;\n }\n\n return CursorPaginatedType as Type<ICursorPaginated<T>>;\n}\n\nexport enum CursorOrderBy {\n createdAt_ASC = 'createdAt_ASC',\n createdAt_DESC = 'createdAt_DESC',\n}\n","import {\n ArgsType,\n Field, Int,\n} from '@nestjs/graphql';\nimport { IsOptional, Min } from 'class-validator';\n\n@ArgsType()\nexport class CursorPaginationInput {\n /**\n * The amount of items to be requested per page from the start\n * @example\n * ```graphql\n * query {\n * messages(first: 3) {\n * edges {\n * cursor\n * node {\n * id\n * }\n * }\n * }\n * }\n * ```\n */\n @Field(() => Int, {\n nullable: true,\n })\n @Min(1)\n @IsOptional()\n first?: number;\n\n /**\n * The cursor to start the pagination\n * @example\n * ```graphql\n * query {\n * messages(first: 3, after: \"xxx\") {\n * edges {\n * cursor\n * node {\n * id\n * }\n * }\n * }\n * }\n * ```\n */\n @Field(() => String, {\n nullable: true,\n })\n after?: string;\n\n /**\n * The amount of items to be requested per page from the end\n * @example\n * ```graphql\n * query {\n * messages(last: 2) {\n * edges {\n * cursor\n * node {\n * id\n * }\n * }\n * }\n * }\n * ```\n */\n @Field(() => Int, {\n nullable: true,\n })\n @Min(1)\n @IsOptional()\n last?: number;\n\n /**\n * The cursor to end the pagination\n * @example\n * ```graphql\n * query {\n * messages(last: 2, before: \"xxx\") {\n * edges {\n * cursor\n * node {\n * id\n * }\n * }\n * }\n * }\n * ```\n */\n @Field(() => String, {\n nullable: true,\n })\n before?: string;\n}\n","import { snakeCase } from '@pcg/text-kit';\nimport { GraphQLResolveInfo } from 'graphql';\n\nimport { ListMeta } from '#/types/list-meta';\n\nimport { PAGINATION_DEFAULT_LIMIT } from '../constants.js';\nimport { requiresTotalCount, truncPaginationLimit } from '../tools.js';\nimport { OffsetErrorMessage, OffsetPaginationError } from './offset-pagination.exception.js';\nimport { OffsetPaginationInput } from './offset-pagination.input.js';\nimport { IOffsetPaginated } from './offset-pagination.types.js';\n\nexport type SortOrder = 'ASC' | 'DESC';\n\nexport interface SortParams<T> {\n /**\n * Original sort field name.\n * @example\n * const orderBy = 'createdAt_ASC';\n * const sort = extractSortParams(orderBy); // sort.fieldName = 'uploaderName';\n * if (sort.fieldName === uploaderName) {\n * ...\n * }\n */\n fieldName: T;\n\n /**\n * Database column name. Camel cased fieldName.\n * @example\n * const orderBy = 'createdAt_ASC';\n * const sort = extractSortParams(orderBy); // sort.columnName = 'created_at';\n * query.orderBy(`v.${sort.columnName}`, sort.direction);\n */\n columnName: string;\n\n /**\n * Sort direction (or order) (ASC | DESC)\n * @example\n * const orderBy = 'createdAt_ASC';\n * const sort = extractSortParams(orderBy); // sort.direction = 'ASC';\n * query.orderBy(`v.${sort.columnName}`, sort.direction);\n */\n direction: SortOrder;\n}\n\n/**\n * Extract sort field name and sort direction from orderBy string.\n * @example\n * const orderBy = 'createdAt_ASC';\n *\n * // sort.fieldName = 'createdAt', sort.direction = 'ASC'; sort.columnName = 'created_at';\n * const sort = extractSortParams(orderBy);\n */\nexport const extractSortParams = <T>(orderBy: string): SortParams<T> => {\n const slices = orderBy.split('_');\n\n if (slices.length !== 2) {\n throw new Error('Invalid orderBy argument');\n }\n\n return {\n fieldName: slices[0] as unknown as T,\n direction: slices[1] as unknown as SortOrder,\n columnName: snakeCase(slices[0]),\n };\n};\n\nexport interface OffsetPaginationOptions {\n limit?: number;\n offset?: number;\n\n /**\n * If true, total count will be calculated by additional SELECT COUNT.\n * @default true\n */\n needCountTotal: boolean;\n}\n\nexport interface CreateOffsetPaginationOptionsParams {\n maxLimit?: number;\n defaultLimit?: number;\n}\n\nexport const createOffsetPaginationOptions = (\n input: OffsetPaginationInput,\n info: GraphQLResolveInfo,\n params?: CreateOffsetPaginationOptionsParams,\n): OffsetPaginationOptions => {\n const options: OffsetPaginationOptions = {\n needCountTotal: requiresTotalCount(info),\n limit: params?.defaultLimit ?? PAGINATION_DEFAULT_LIMIT,\n };\n\n if (input.limit) {\n options.limit = truncPaginationLimit(Number(input.limit), params?.maxLimit);\n\n if (input.page) {\n options.offset = (Number(input.page) - 1) * options.limit;\n }\n }\n\n return options;\n};\n\nexport const offsetPaginatedOutput = <T>(items: T[], {\n limit,\n offset = 0,\n total = 0,\n}: ListMeta): IOffsetPaginated<T> => {\n if (!limit) {\n throw new OffsetPaginationError(OffsetErrorMessage.OUTPUT_LIMIT);\n }\n\n return {\n items,\n pageInfo: {\n totalPages: Math.ceil(total / limit),\n totalItems: total,\n page: (offset / limit) + 1,\n limit,\n },\n };\n};\n","import {\n ArgsType,\n Field, Int,\n} from '@nestjs/graphql';\n\nimport { PAGINATION_DEFAULT_LIMIT } from '../constants.js';\n\n@ArgsType()\nexport class OffsetPaginationInput {\n /**\n * the amount of items to be requested per page\n */\n @Field(() => Int, {\n description: 'the amount of items to be requested per page',\n defaultValue: PAGINATION_DEFAULT_LIMIT,\n nullable: true,\n })\n limit?: number;\n\n /**\n * @default 1\n * the page that is requested\n */\n @Field(() => Int, {\n defaultValue: 1,\n description: 'the page that is requested',\n })\n page?: number = 1;\n}\n\n","import { Type } from '@nestjs/common';\nimport {\n Field, Int,\n ObjectType,\n} from '@nestjs/graphql';\n\n@ObjectType()\nexport class OffsetPaginationPageInfo {\n /**\n * The total amount of pages\n * (total items / limit)\n */\n @Field(() => Int, {\n description: 'The total amount of pages (total items / limit)',\n })\n totalPages!: number;\n\n /**\n * The total amount of items\n */\n @Field(() => Int, {\n description: 'The total amount of items',\n })\n totalItems!: number;\n\n /**\n * The current page\n */\n @Field(() => Int, {\n description: 'The current page',\n })\n page!: number;\n\n /**\n * The amount of items to be requested per page\n */\n @Field(() => Int, {\n description: 'The amount of items to be requested per page',\n })\n limit!: number;\n}\n\nexport interface IOffsetPaginated<T> {\n items: T[];\n pageInfo: OffsetPaginationPageInfo;\n}\n\n/**\n * Creates a new GraphQL object type with the name `Paginated${classRef.name}`\n * that implements the `IOffsetPaginated` interface\n * @param classRef The class reference of the items\n *\n * @example Create PaginatedUsers type\n * ```ts\n * @ObjectType()\n * class PaginatedUsers extends OffsetPaginated(User) {}\n * ```\n */\n// eslint-disable-next-line func-style\nexport function OffsetPaginated<T>(classRef: Type<T>): Type<IOffsetPaginated<T>> {\n @ObjectType({\n isAbstract: true,\n })\n abstract class OffsetPaginatedType implements IOffsetPaginated<T> {\n /**\n * The items of the current page\n */\n @Field(() => [classRef], {\n description: 'The items of the current page',\n })\n items!: T[];\n\n /**\n * The pagination information\n * (total pages, total items, current page, limit)\n */\n @Field(() => OffsetPaginationPageInfo)\n pageInfo!: OffsetPaginationPageInfo;\n }\n\n return OffsetPaginatedType as Type<IOffsetPaginated<T>>;\n}\n","/**\n * Converts an object into a human-readable string representation.\n *\n * Takes an object and transforms it into a string where each key-value pair\n * is formatted as \"key JSON-value\" and all pairs are joined with \" and \".\n *\n * @param opts - The object to stringify\n * @returns A string representation of the object with entries joined by \" and \"\n *\n * @example\n * ```ts\n * stringifyOpts({ name: 'John', age: 30 })\n * // Returns: 'name \"John\" and age 30'\n * ```\n */\nexport const stringifyOpts = (opts: object) => {\n return Object.entries(opts)\n .map(([key, value]) => `${key} ${JSON.stringify(value)}`)\n .join(' and ');\n};\n","/**\n * Injection token for Winston logger module configuration options\n */\nexport const NESTKIT_LOGGER_MODULE_OPTIONS = 'NestKitLoggerModuleOptions';\n\n/**\n * Injection token for the Winston logger instance provider\n */\nexport const NESTKIT_WINSTON_LOGGER_PROVIDER = 'NestKitLogger';\n\n/**\n * Injection token for the main NestKit logger provider\n */\nexport const NESTKIT_LOGGER_PROVIDER = 'NestKitLogger';\n\n/**\n * Injection token for the NestJS system logger provider\n */\nexport const NESTKIT_SYSTEM_LOGGER_PROVIDER = 'NestKitSystemLogger';\n\n/**\n * Injection token for the logger factory provider\n */\nexport const NESTKIT_LOGGER_FACTORY_PROVIDER = 'NestKitLoggerFactory';\n","/**\n * Checks if the given value is an object (not an array).\n * @param {unknown} obj - The value to check.\n * @returns {boolean} Returns true if `obj` is an object, false otherwise.\n * @example\n * isObject({ a: 1 }); // Returns true\n * isObject([1, 2, 3]); // Returns false\n */\nexport const isObject = (obj: unknown): obj is Record<string, unknown> =>\n obj !== null && !!obj && typeof obj === 'object' && !Array.isArray(obj);\n",";\nimport { isObject } from '#/tools/is-object.js';\nimport { ApolloError } from '@apollo/client/core';\nimport { HttpException } from '@nestjs/common';\nimport { GraphQLError } from 'graphql';\nimport { LogEntry, Logger as WinstonLogger } from 'winston';\n\nimport { BaseServiceMethodContext } from '#/context';\nimport { NestError } from '#/errors/index.js';\nimport { HttpExceptionResponse } from '#/exceptions/http-exception-response';\n// import { getErrorMessages as getApolloErrorMessages } from '@deep/graphql-kit';\nimport type {\n DestructuredError,\n InfoObject, LoggerContext,\n WinstonLogLevel,\n} from '../logger.interfaces.js';\n\n/**\n * Logger with context for NestJS (from NestKit)\n */\nexport class Logger {\n constructor(\n private readonly winstonLogger: WinstonLogger,\n private context: LoggerContext = {\n },\n ) {}\n\n /**\n * Created child logger with specific context\n * @param context - object with scope, action and other data\n * @returns - new logger with context\n * @example\n * ```ts\n * class SomeService {\n * logger: Logger;\n *\n * constructor(\n * @InjectLoggerFactory() private readonly loggerFactory: LoggerFactory,\n * ) {\n * // Create logger for this service\n * this.winstonLogger = this.winstonLoggerFactory.create({\n * scope: SomeService.name,\n * })\n * }\n *\n * // Create child logger for some method\n * getOne(id: string) {\n * const logger = this.winstonLogger.child({\n * action: this.someMethod.name,\n * id,\n * });\n * }\n * ```\n */\n // https://www.npmjs.com/package/json-log#log2--logchilddata\n child(context: LoggerContext): Logger {\n return new Logger(this.winstonLogger, {\n ...this.context,\n ...context,\n });\n }\n\n /**\n * Created child logger for nest service method\n * Automatically parse service method context and add it to logger context\n * @param name - service method name\n * @param ctx - service method context\n * @param other - custom logger context\n * @returns - new logger with context\n */\n forMethod(name: string, ctx?: BaseServiceMethodContext, other?: LoggerContext) {\n const context: LoggerContext = {\n action: name,\n };\n\n if (ctx) {\n Object.assign(context, {\n requestId: ctx.requestId,\n });\n\n if (!ctx.user) {\n throw new Error('User is required for strict method context. Use guards: @UseGuards(JwtAuthGuard) or @UseGuards(GraphQLJwtAuthGuard)');\n }\n\n Object.assign(context, {\n requestId: ctx.requestId,\n userId: ctx.user.id,\n });\n }\n\n if (other) {\n Object.assign(context, other);\n }\n\n return this.child(context);\n }\n\n /**\n * Set data to logger context\n * @param key - context data key (ex: 'firstName')\n * @param value - context data value (ex: 'John')\n */\n setContext(key: string, value: unknown): void;\n setContext(context: LoggerContext): void;\n setContext(...args: unknown[]): void {\n if (\n args.length === 2 &&\n typeof args[0] === 'string' &&\n typeof args[1] !== 'undefined'\n ) {\n const key = args[0];\n const value = args[1];\n this.context[key] = value;\n } else {\n this.context = {\n ...this.context,\n ...(args[0] as LoggerContext),\n };\n }\n }\n\n /**\n * Get logger context data\n * @returns - logger context\n */\n getContext(): LoggerContext {\n return structuredClone(this.context);\n }\n\n /**\n * Write a 'log' level log.\n */\n log(entry: LogEntry): void;\n log(level: WinstonLogLevel, message: string, context?: LoggerContext): void;\n log(...args: unknown[]): void {\n if (isObject(args[0])) {\n this.winstonLogger.log({\n ...this.context,\n ...(args[0] as LogEntry),\n });\n } else {\n this.winstonLogger.log({\n level: args[0] as WinstonLogLevel,\n message: args[1] as string,\n ...this.context,\n ...(args[2] as LoggerContext),\n });\n }\n }\n\n /**\n * Write a 'info' level log.\n */\n info(message: string, context?: LoggerContext): void;\n info(infoObject: InfoObject): void;\n info(...args: unknown[]): void {\n if (typeof args[0] === 'string') {\n this.winstonLogger.info({\n message: args[0],\n ...this.context,\n ...(args[1] as LoggerContext),\n });\n } else {\n this.winstonLogger.info({\n ...this.context,\n ...(args[0] as InfoObject),\n });\n }\n }\n\n /**\n * Write an 'error' level log.\n */\n error(message: string, context?: LoggerContext): void;\n error(message: string, error: Error, context?: LoggerContext): void;\n error(error: NestError): void;\n error(error: Error, context?: LoggerContext): void;\n error(...args: unknown[]): void {\n if (args[0] instanceof NestError) {\n const err = args[0];\n this.winstonLogger.error({\n ...this.context,\n ...(args[1] as LoggerContext),\n ...this.destructureError(err),\n });\n } else if (args[0] instanceof Error) {\n const err = args[0];\n this.winstonLogger.error({\n ...this.context,\n ...(args[1] as LoggerContext),\n ...this.destructureError(err),\n });\n } else if (typeof args[0] === 'string' && args[1] instanceof Error) {\n const message = args[0];\n const err = args[1];\n this.winstonLogger.error({\n message: message,\n ...this.context,\n ...(args[2] as LoggerContext),\n error: this.destructureError(err),\n });\n } else if (typeof args[0] === 'string') {\n const message = args[0];\n this.winstonLogger.error({\n message,\n ...this.context,\n ...(args[1] as LoggerContext),\n });\n }\n }\n\n /**\n * Creates plain object from error\n * @see {@link DestructuredError}\n */\n protected destructureError(error: unknown): DestructuredError {\n const errorObject: DestructuredError = {\n };\n\n if (error instanceof NestError) {\n errorObject.message = error.message;\n errorObject.stack = error.stack;\n errorObject.context = error.context;\n errorObject.statusCode = error.httpStatusCode;\n errorObject.errorKey = error.key;\n if (error.cause instanceof Error) {\n errorObject.cause = this.destructureError(error.cause);\n }\n } else if (error instanceof Error) {\n errorObject.message = error.message;\n errorObject.stack = error.stack;\n }\n\n if (error instanceof HttpException) {\n errorObject.statusCode = error.getStatus();\n\n const response = error.getResponse() as HttpExceptionResponse;\n\n if (isObject(response)) {\n if (response.key) {\n errorObject.errorKey = response.key;\n }\n\n if (response.context) {\n if (!errorObject.context) {\n errorObject.context = {\n };\n }\n\n errorObject.context = {\n ...errorObject.context,\n ...response.context,\n };\n }\n\n if (response.error) {\n errorObject.cause = this.destructureError(response.error);\n }\n }\n\n return errorObject;\n } else if (error instanceof GraphQLError) {\n const ctx = JSON.parse(JSON.stringify({\n locations: error.locations,\n positions: error.positions,\n source: error.source,\n }));\n\n errorObject.context = {\n ...errorObject.context,\n ...ctx,\n };\n // } else if (error instanceof ApolloError) {\n // const messages = getApolloErrorMessages(error);\n // errorObject.message = messages.join('\\n');\n }\n\n return errorObject;\n }\n\n /**\n * Write a 'warn' level log.\n */\n warn(message: string, context?: LoggerContext): void;\n warn(infoObject: InfoObject): void;\n warn(...args: unknown[]): void {\n if (typeof args[0] === 'string') {\n this.winstonLogger.warn({\n message: args[0],\n ...this.context,\n ...(args[1] as LoggerContext),\n });\n } else {\n this.winstonLogger.warn({\n ...this.context,\n ...(args[0] as InfoObject),\n });\n }\n }\n\n /**\n * Write a 'debug' level log.\n */\n debug(message: string, context?: LoggerContext): void;\n debug(infoObject: InfoObject): void;\n debug(...args: unknown[]): void {\n if (typeof args[0] === 'string') {\n this.winstonLogger.debug({\n message: args[0],\n ...this.context,\n ...(args[1] as LoggerContext),\n });\n } else {\n this.winstonLogger.debug({\n ...this.context,\n ...(args[0] as InfoObject),\n });\n }\n }\n\n /**\n * Write a 'verbose' level log.\n */\n verbose(message: string, context?: LoggerContext): void;\n verbose(infoObject: InfoObject): void;\n verbose(...args: unknown[]): void {\n if (typeof args[0] === 'string') {\n this.winstonLogger.verbose({\n message: args[0],\n ...this.context,\n ...(args[1] as LoggerContext),\n });\n } else {\n this.winstonLogger.verbose({\n ...this.context,\n ...(args[0] as InfoObject),\n });\n }\n }\n}\n",";\n\nimport {\n ConsoleLogger, Inject, Injectable, LogLevel as NestLogLevel,\n} from '@nestjs/common';\nimport { isFunction, isPlainObject } from '@nestjs/common/utils/shared.utils';\n\nimport { NESTKIT_LOGGER_PROVIDER } from '../logger.constants.js';\nimport type { WinstonLogLevel } from '../logger.interfaces.js';\nimport { Logger } from './logger.js';\n\n@Injectable()\nexport class NestSystemLogger extends ConsoleLogger {\n @Inject(NESTKIT_LOGGER_PROVIDER) private readonly logger!: Logger;\n\n protected printMessages(messages: unknown[], context?: string | undefined, logLevel?: NestLogLevel | undefined): void {\n for (const message of messages) {\n this.logger.log(this.getWinstonLogLevel(logLevel), this.stringifyMessage(message), {\n scope: context,\n });\n }\n }\n\n protected stringifyMessage(message: unknown): string {\n // If the message is a function, call it and re-resolve its value.\n if (isFunction(message)) {\n return this.stringifyMessage(message());\n }\n\n if (isPlainObject(message) || Array.isArray(message)) {\n return JSON.stringify(\n message,\n (key, value) =>\n typeof value === 'bigint' ? value.toString() : value,\n 2,\n );\n }\n\n return String(message);\n }\n\n private getWinstonLogLevel(level?: NestLogLevel): WinstonLogLevel {\n switch (level) {\n case 'log':\n return 'info';\n\n case 'verbose':\n return 'verbose';\n\n case 'debug':\n return 'debug';\n\n case 'warn':\n return 'warn';\n\n case 'error':\n return 'error';\n\n default:\n return 'info';\n }\n }\n}\n","import type { LogLevel, LogMessage } from 'typeorm';\nimport { AbstractLogger } from 'typeorm/logger/AbstractLogger.js';\nimport type { LoggerOptions } from 'typeorm/logger/LoggerOptions.js';\n\nimport { type LoggerContext } from '../logger.interfaces.js';\nimport { Logger } from './logger.js';\n\nexport class TypeOrmLoggerOptions {\n enabled?: boolean;\n logger!: Logger;\n levels?: LoggerOptions;\n}\n\nexport class TypeOrmLogger extends AbstractLogger {\n logger: Logger;\n\n constructor(opts: TypeOrmLoggerOptions) {\n super(opts.enabled && opts.levels ? opts.levels : false);\n\n this.logger = opts.logger;\n }\n\n /**\n * Write log to specific output.\n */\n protected writeLog(\n level: LogLevel, // \"query\" | \"schema\" | \"error\" | \"warn\" | \"info\" | \"log\" | \"migration\";\n logMessage: LogMessage | LogMessage[],\n ) {\n const messages = this.prepareLogMessages(logMessage, {\n highlightSql: false,\n });\n\n for (const message of messages) {\n switch (message.type ?? level) {\n case 'log':\n case 'query':\n case 'schema-build':\n this.logger.debug(String(message.message), this.getCtx(message));\n break;\n\n case 'migration':\n case 'info':\n if (message.prefix) {\n this.logger.info(`${message.prefix} ${message.message}`, this.getCtx(message));\n } else {\n this.logger.info(String(message.message), this.getCtx(message));\n }\n break;\n\n case 'warn':\n case 'query-slow':\n if (message.prefix) {\n this.logger.warn(`${message.prefix} ${message.message}`, this.getCtx(message));\n } else {\n this.logger.warn(String(message.message), this.getCtx(message));\n }\n break;\n\n case 'error':\n case 'query-error':\n if (message.prefix) {\n this.logger.error(`[${message.prefix}] ${message.message}`, this.getCtx(message));\n } else {\n this.logger.error(String(message.message), this.getCtx(message));\n }\n break;\n }\n }\n }\n\n private getCtx(message: LogMessage): LoggerContext {\n const ctx = {\n ...message.additionalInfo,\n };\n\n if (Array.isArray(ctx.parameters)) {\n ctx.parameters = message.parameters;\n }\n\n return ctx;\n }\n}\n","import { Logger as WinstonLogger } from 'winston';\n\nimport { LoggerContext } from '../logger.interfaces.js';\nimport { Logger } from './logger.js';\nimport { TypeOrmLogger, TypeOrmLoggerOptions } from './typeorm-logger.js';\n\n/**\n * Logger factory for creating loggers with predefined context\n * Factory is singleton, so it keep original winston `Logger` instance\n * and is can be injected to any service\n */\nexport class LoggerFactory {\n constructor(\n private readonly winstonLogger: WinstonLogger,\n private context: LoggerContext = {\n },\n ) {}\n\n /**\n * Created new logger with specific context merge it with global context\n * @param context - specific action with scope, and other data\n * @returns - new logger with context\n * @example\n * ```ts\n * class SomeService {\n * logger: Logger;\n *\n * constructor(\n * @InjectLoggerFactory() private readonly loggerFactory: LoggerFactory,\n * ) {\n * // Create logger for this service\n * this.logger = this.loggerFactory.create({\n * scope: SomeService.name,\n * })\n * }\n * ```\n */\n create(context: LoggerContext = {\n }) {\n return new Logger(this.winstonLogger, {\n ...this.context,\n ...context,\n });\n }\n\n createTypeOrmLogger(opts: Omit<TypeOrmLoggerOptions, 'logger'>) {\n return new TypeOrmLogger({\n logger: this.create({\n scope: 'TypeORM',\n }),\n ...opts,\n });\n }\n}\n","import {\n Inject, Provider, Type,\n} from '@nestjs/common';\nimport {\n createLogger,\n Logger,\n LoggerOptions,\n} from 'winston';\n\nimport { LoggerFactory } from './classes/logger-factory.js';\nimport { NestSystemLogger } from './classes/nest-system-logger.js';\nimport {\n NESTKIT_LOGGER_FACTORY_PROVIDER,\n NESTKIT_LOGGER_MODULE_OPTIONS,\n NESTKIT_LOGGER_PROVIDER,\n NESTKIT_SYSTEM_LOGGER_PROVIDER,\n NESTKIT_WINSTON_LOGGER_PROVIDER,\n} from './logger.constants.js';\nimport {\n LoggerModuleAsyncOptions,\n LoggerModuleOptions,\n LoggerModuleOptionsFactory,\n} from './logger.interfaces.js';\n\n/**\n * Syntax sugar. Injects logger via NESTKIT_LOGGER_PROVIDER token\n * @example\n * ```ts\n * class SomeService {\n * constructor(\n * @InjectLogger() private readonly logger: Logger\n * ) {}\n * ```\n */\nexport const InjectLogger = () => Inject(NESTKIT_LOGGER_PROVIDER);\n\n/**\n * Syntax sugar. Injects winston logger factory by WINSTON_MODULE_FACTORY_PROVIDER token\n * @example\n * ```ts\n * class SomeService {\n * constructor(\n * @InjectLoggerFactory() private readonly loggerFactory: LoggerFactory\n * ) {}\n * ```\n */\nexport const InjectLoggerFactory = () => Inject(NESTKIT_LOGGER_FACTORY_PROVIDER);\n\nexport const createNestLogger = (\n loggerOpts: LoggerModuleOptions,\n): Logger => {\n return new Logger(createLogger(loggerOpts));\n};\n\nexport const createLoggerProviders = (\n loggerOpts: LoggerModuleOptions,\n): Provider[] => {\n return [\n {\n provide: NESTKIT_WINSTON_LOGGER_PROVIDER,\n useFactory: () => createLogger(loggerOpts),\n },\n {\n provide: NESTKIT_LOGGER_PROVIDER,\n useFactory: (logger: Logger) => {\n return new Logger(logger);\n },\n inject: [NESTKIT_WINSTON_LOGGER_PROVIDER],\n },\n {\n provide: NESTKIT_SYSTEM_LOGGER_PROVIDER,\n useClass: NestSystemLogger,\n },\n {\n provide: NESTKIT_LOGGER_FACTORY_PROVIDER,\n useFactory: (logger: Logger) => {\n return new LoggerFactory(logger);\n },\n inject: [NESTKIT_WINSTON_LOGGER_PROVIDER],\n },\n ];\n};\n\nexport const createLoggerAsyncProviders = (\n options: LoggerModuleAsyncOptions,\n): Provider[] => {\n const providers: Provider[] = [\n {\n provide: NESTKIT_WINSTON_LOGGER_PROVIDER,\n useFactory: (loggerOpts: LoggerOptions) => createLogger(loggerOpts),\n inject: [NESTKIT_LOGGER_MODULE_OPTIONS],\n },\n {\n provide: NESTKIT_LOGGER_PROVIDER,\n useFactory: (logger: Logger) => {\n return new Logger(logger);\n },\n inject: [NESTKIT_WINSTON_LOGGER_PROVIDER],\n },\n {\n provide: NESTKIT_SYSTEM_LOGGER_PROVIDER,\n useClass: NestSystemLogger,\n },\n {\n provide: NESTKIT_LOGGER_FACTORY_PROVIDER,\n useFactory: (logger: Logger) => {\n return new LoggerFactory(logger);\n },\n inject: [NESTKIT_WINSTON_LOGGER_PROVIDER],\n },\n ];\n\n if (options.useClass) {\n const useClass = options.useClass as Type<LoggerModuleOptionsFactory>;\n providers.push(\n ...[\n {\n provide: NESTKIT_LOGGER_MODULE_OPTIONS,\n useFactory: async (optionsFactory: LoggerModuleOptionsFactory) =>\n await optionsFactory.createLoggerModuleOptions(),\n inject: [useClass],\n },\n {\n provide: useClass,\n useClass,\n },\n ],\n );\n }\n\n if (options.useFactory) {\n providers.push({\n provide: NESTKIT_LOGGER_MODULE_OPTIONS,\n useFactory: options.useFactory,\n inject: options.inject || [],\n });\n }\n\n return providers;\n};\n","import {\n DynamicModule, Global, LoggerService, Module,\n} from '@nestjs/common';\n\nimport {\n LoggerModuleAsyncOptions,\n LoggerModuleOptions,\n} from './logger.interfaces.js';\nimport {\n createLoggerAsyncProviders,\n createLoggerProviders,\n createNestLogger,\n} from './logger.providers.js';\n\n@Global()\n@Module({\n})\nexport class LoggerModule {\n public static forRoot(options: LoggerModuleOptions): DynamicModule {\n const providers = createLoggerProviders(options);\n\n return {\n module: LoggerModule,\n providers: providers,\n exports: providers,\n };\n }\n\n public static forRootAsync(\n options: LoggerModuleAsyncOptions,\n ): DynamicModule {\n const providers = createLoggerAsyncProviders(options);\n\n return {\n module: LoggerModule,\n imports: options.imports,\n providers: providers,\n exports: providers,\n } as DynamicModule;\n }\n\n public static createLogger(options: LoggerModuleOptions): LoggerService {\n return createNestLogger(options);\n }\n}\n","import { LogLevel } from '@nestjs/common';\nimport clc from 'cli-color';\nimport bare from 'cli-color/bare';\nimport { Format } from 'logform';\nimport { format } from 'winston';\nimport { DestructuredError } from './logger.interfaces.js';\n\nconst nestLikeColorScheme: Record<string, bare.Format> = {\n log: clc.greenBright,\n info: clc.greenBright,\n error: clc.red,\n warn: clc.yellow,\n debug: clc.magentaBright,\n verbose: clc.cyanBright,\n};\n\n/**\n * Options for nest-like formatting\n */\nexport interface CreatePrettyMessageOptions {\n /**\n * Application name\n * @example 'Jetstream'\n */\n appName: string;\n\n /**\n * Log level (info, error, warn, debug, verbose, log)\n * @example 'info'\n */\n level: LogLevel;\n\n /**\n * Timestamp in ISO 8601 format\n * @example '2021-06-10T16:33:42.000Z'\n */\n timestamp: string;\n\n /**\n * Message text\n * @example 'Failed to create cloudlfare output'\n */\n message: string;\n\n /**\n * Scope where the message was logged\n * @example 'VideoService'\n */\n scope?: string;\n\n /**\n * Action where the message was logged\n * @example 'createOutput'\n */\n action?: string;\n\n /**\n * Error stack from Error object (`Error.stack`)\n */\n stack?: string;\n\n /**\n * Message context (additional data)\n * @example { id: 'xxx' }\n */\n context: Record<string, unknown>;\n\n /**\n * Error key from 'enum'\n * @example 'NST_SA_EMAIL_NOT_UNIQUE'\n */\n errorKey?: string;\n\n /**\n * HTTP status code\n * @example '400'\n */\n statusCode?: string;\n\n /**\n * Parent path for child errors\n * @example 'MainService.start --> VideoService.createOutput'\n */\n parentPath?: string;\n\n /**\n * Error cause\n */\n cause?: DestructuredError;\n\n /**\n * Recursion depth\n * @example 0\n */\n deep?: number;\n}\n\n/**\n * Create a pretty message for the logger with nest-like formatting\n * Use recursion to print child errors\n * @param vars - message variables\n * @returns - formatted message\n * @example\n * [Jetstream] - 6/10/2022, 4:33:42 PM ERROR [VideoService.createOutput] Failed to create cloudlfare output\n */\nexport const createPrettyMessage = ({\n appName,\n action,\n level,\n timestamp,\n message,\n scope,\n stack,\n errorKey,\n // statusCode,\n context,\n parentPath,\n cause,\n deep = 0,\n}: CreatePrettyMessageOptions): string => {\n if ('undefined' !== typeof timestamp) {\n // Only format the timestamp to a locale representation if it's ISO 8601 format. Any format\n // that is not a valid date string will throw, just ignore it (it will be printed as-is).\n try {\n if (timestamp === new Date(timestamp).toISOString()) {\n timestamp = new Date(timestamp).toLocaleString();\n }\n } catch {\n // Ignore\n }\n }\n\n const color =\n nestLikeColorScheme[level] || ((text: string): string => text);\n\n if (errorKey) {\n message += ` [${errorKey}]`;\n }\n\n // [Nest] 9539 - 05/26/2022, 9:00:29 AM LOG [InstanceLoader] OrganizationsModule dependencies initialized +1ms\n\n const sAppName = color(`[${appName}]`);\n const sTimestamp = timestamp ? `${timestamp} ` : '';\n const sLevel = color(level.toUpperCase());\n\n let path = '';\n let sPath = '';\n if ('undefined' !== typeof scope && 'undefined' !== typeof action) {\n path = `${scope}.${action}`;\n } else if ('undefined' !== typeof scope) {\n path = scope;\n } else if ('undefined' !== typeof action) {\n path = action;\n }\n\n // SyncWorker.sync --> CloudflareApi.createOutput]\n if (path && parentPath) {\n path = `${parentPath} --> ${path}`;\n } else if (parentPath) {\n path = parentPath;\n }\n\n if (path) {\n sPath = clc.yellow(` [${path}]`);\n }\n\n // const sDeep = color(printDeep(deep));\n const sMessage = color(` ${message}`);\n const sStack = 'undefined' !== typeof stack ? color(`\\n ${stack}`) : '';\n\n let sRecursion = '';\n if (cause) {\n const {\n action,\n scope,\n ...context\n } = cause?.context || {\n };\n\n /**\n * Print child errors recursively\n */\n sRecursion = cause ? `\\n${createPrettyMessage({\n appName,\n action,\n level,\n timestamp,\n message: cause.message ?? message,\n scope,\n stack: cause.stack,\n errorKey: cause.errorKey,\n context,\n parentPath: path,\n cause: cause.cause,\n deep: deep + 1,\n })}` : '';\n }\n\n const sContext = context && Object.keys(context).length > 0 ? color(` -- ${JSON.stringify(context, null, 2)}`) : '';\n\n // sAppName sTimestamp sLevel sPath sMessage\n // [Jetstream] - 6/10/2022, 4:33:42 PM ERROR [VideoService.createOutput] Failer to create cloudlfare output\n return `${sAppName} - ${sTimestamp} ${sLevel}${sPath}${sMessage}${sStack}${sContext}${sRecursion}`;\n};\n\n/**\n * Create a nest-like console format\n * @param appName - App name (Jetstream, WHATSBIBLE, etc.)\n * @returns Winston format\n */\nexport const nestLikeConsoleFormat = (appName = 'Nest'): Format =>\n format.printf(\n ({\n level,\n timestamp,\n message,\n scope,\n action,\n // ms,\n stack,\n errorKey,\n statusCode,\n error: cause,\n ...context\n }) => {\n return createPrettyMessage({\n appName,\n action,\n level: level as LogLevel,\n timestamp,\n message,\n stack,\n context,\n scope,\n errorKey,\n statusCode,\n cause,\n deep: 0,\n } as CreatePrettyMessageOptions);\n },\n );\n","import { Inject } from '@nestjs/common';\nimport { getConfigToken, registerAs } from '@nestjs/config';\nimport * as winston from 'winston';\n\nimport { nestLikeConsoleFormat } from '#/logger';\n\n/**\n * NestJS injection token for Logger config\n */\nexport const LOGGER_CONFIG_TOKEN = 'LOGGER_CONFIG_TOKEN';\n\nexport const InjectLoggerConfig = () => Inject(getConfigToken(LOGGER_CONFIG_TOKEN));\n\nexport interface CreateLoggerConfigOptions {\n appName: string;\n useConsole?: boolean;\n consoleLevel?: winston.LoggerOptions['level'];\n transports?: winston.transport[];\n}\n/**\n * Create NestJS Logger config\n * @example\n * ```ts\n * // src/config/index.ts\n *\n * import { createLoggerConfig } from '#/dist/configs';\n *\n * export const LoggerConfig = createLoggerConfig();\n * ```\n */\nexport const createLoggerConfig = (opts: CreateLoggerConfigOptions) => {\n return registerAs(LOGGER_CONFIG_TOKEN, () => {\n const format = [\n winston.format.splat(),\n winston.format.timestamp(),\n nestLikeConsoleFormat(opts.appName),\n ];\n\n const winstonOptions: winston.LoggerOptions = {\n transports: [],\n };\n\n if (!Array.isArray(winstonOptions.transports)) {\n return winstonOptions;\n }\n\n if (opts.useConsole) {\n winstonOptions.transports.push(\n new winston.transports.Console({\n level: opts.consoleLevel ?? 'debug',\n format: winston.format.combine(...format),\n }),\n );\n }\n\n if (opts.transports) {\n winstonOptions.transports.push(...opts.transports);\n }\n\n return winstonOptions;\n });\n};\n","import { OnModuleInit } from '@nestjs/common';\n\nimport {\n InjectLoggerFactory, Logger, LoggerFactory,\n} from '#/logger';\n\n/**\n * Abstract service class for NestJS services\n * Automatically initializes logger with the constructor name as scope\n */\nexport abstract class NestJsService implements OnModuleInit {\n @InjectLoggerFactory()\n protected readonly loggerFactory!: LoggerFactory;\n\n protected logger!: Logger;\n\n /**\n * Initialize logger using the constructor name as scope\n */\n onModuleInit() {\n this.logger = this.loggerFactory.create({\n scope: this.constructor.name,\n });\n }\n}\n","import { Inject, Type } from '@nestjs/common';\nimport { InjectDataSource } from '@nestjs/typeorm';\nimport {\n BaseEntity, DataSource, FindOptionsWhere, Repository,\n SelectQueryBuilder,\n} from 'typeorm';\n\nimport { IdService } from '#/modules/id';\nimport { MaybeNull } from '#/types/maybe';\n\nimport { BaseServiceMethodContext } from '#/context/service-method-context.js';\nimport { BadRequestError } from '#/errors/bad-request.error.js';\nimport { NotFoundError } from '#/errors/not-found.error.js';\nimport { extractSortParams } from '#/pagination';\nimport { stringifyOpts } from '#/tools/stringify-opts';\nimport { NestJsService } from './nestjs-service.js';\n\nexport interface NestJsResourceFilter {\n ids?: string[];\n search?: string;\n}\n\nexport interface GetOneByOptions {\n id?: string;\n}\n\nexport interface NestJsResourceServiceParams<\n T extends BaseEntity,\n GOBO extends GetOneByOptions,\n F extends NestJsResourceFilter,\n O\n> {\n entity: {\n type: Type<T>;\n idPrefix: string;\n alias: string;\n };\n types: {\n getByOpts: GOBO;\n filter: F;\n orderBy: O;\n };\n}\n\nexport abstract class NestJsResourceService<\n T extends BaseEntity,\n GOBO extends GetOneByOptions,\n F extends NestJsResourceFilter,\n O\n> extends NestJsService {\n constructor(private readonly params: NestJsResourceServiceParams<T, GOBO, F, O>) {\n super();\n }\n\n @Inject(IdService) protected readonly idService!: IdService;\n @InjectDataSource() protected readonly dataSource!: DataSource;\n\n public get repository(): Repository<T> {\n return this.dataSource.getRepository(this.params.entity.type);\n }\n\n protected generateEntityId(): string {\n return this.idService.generateEntityId(this.params.entity.idPrefix);\n }\n\n get entityName(): string {\n return this.params.entity.type.name;\n }\n\n get alias(): string {\n return this.params.entity.alias;\n }\n\n async getOneBy<GOBO extends GetOneByOptions>(opts: GOBO): Promise<MaybeNull<T>> {\n const logger = this.logger.child({\n action: this.getOneBy.name,\n ...opts as Record<string, unknown>,\n });\n\n if (Object.values(opts).filter((v) => v).length === 0) {\n throw new BadRequestError({\n message: 'Empty options',\n key: 'NST_GET_ONE_BY_EMPTY_OPTIONS',\n context: logger.getContext(),\n });\n }\n\n return await this.repository.findOneBy({\n ...opts,\n } as FindOptionsWhere<T>);\n }\n\n async getOne(id: string): Promise<MaybeNull<T>> {\n return await this.getOneBy({\n id,\n });\n }\n\n async getOneByOrFail<GOBO extends GetOneByOptions>(opts: GOBO, ctx: BaseServiceMethodContext): Promise<T> {\n const logger = this.logger.forMethod(this.getOneByOrFail.name, ctx, {\n ...opts as Record<string, unknown>,\n });\n\n const item = await this.getOneBy(opts);\n\n if (!item) {\n throw new NotFoundError({\n message: `${this.entityName} with ${stringifyOpts(opts)} not found`,\n key: 'NST_CHANNELS_NOT_FOUND',\n context: logger.getContext(),\n });\n }\n\n return item;\n }\n\n protected async getOneOrFail(id: string, ctx: BaseServiceMethodContext): Promise<T> {\n return await this.getOneByOrFail({\n id,\n }, ctx);\n }\n\n protected applyFilterToQuery(query: SelectQueryBuilder<T>, filter?: F): void {\n if (!filter) {\n return;\n }\n\n if (filter.search) {\n query.andWhere(`${this.alias}.title LIKE :search`, {\n search: `%${filter.search}%`,\n });\n }\n\n return;\n }\n\n protected applySearchToQuery(query: SelectQueryBuilder<T>, search?: string): void {\n if (!search) {\n return;\n }\n\n query.andWhere(`${this.alias}.title LIKE :search`, {\n search: `%${search}%`,\n });\n\n return;\n }\n\n protected applyOrderByToQuery(query: SelectQueryBuilder<T>, orderBy: O): void {\n const sort = extractSortParams(orderBy as string);\n\n query.addOrderBy(`${this.alias}.${sort.columnName}`, sort.direction);\n }\n}\n","import {\n pluralToSingular,\n singularToPlural,\n snakeCase,\n} from '@pcg/text-kit';\nimport {\n DefaultNamingStrategy, NamingStrategyInterface, Table,\n} from 'typeorm';\n\n/**\n * Snake case naming strategy for typeorm.\n * Determines table and column names from class and property names.\n */\nexport class SnakeNamingStrategy\n extends DefaultNamingStrategy\n implements NamingStrategyInterface {\n /**\n * Create a table name from a class name.\n * @param className - The class name of the entity\n * @param customName - The custom table name\n * @returns The table name\n * @example Create table name from class name\n * ```ts\n * @Entity()\n * class User {}\n * // returns 'users'\n *\n * @Entity('custom_table_name')\n * class User {}\n * // returns 'custom_table_name'\n *\n *```\n */\n tableName(className: string, customName?: string): string {\n if (customName) {\n return customName;\n }\n\n const snakeClassName = snakeCase(className);\n\n // if many-to-many table, use the table name as is\n if (snakeClassName.includes('_to_')) {\n return snakeClassName;\n }\n\n const parts = snakeClassName.split('_');\n if (parts.length === 1) {\n return singularToPlural(snakeClassName);\n }\n\n return parts\n .map((name, i) => (i === 0 ? name : singularToPlural(name)))\n .join('_');\n }\n\n /**\n * Create a column name from a property name.\n * @param propertyName - The property name of the entity\n * @param customName - The custom column name\n * @param embeddedPrefixes - The embedded prefixes\n * @returns The table column name\n * @example Create column name from property name\n * ```ts\n * @Entity()\n * class User {\n * @Column()\n * firstName: string; // returns 'first_name'\n *\n * @Column('custom_last_name')\n * lastName: string; // returns 'custom_last_name'\n * }\n * ```\n */\n columnName(\n propertyName: string,\n customName?: string,\n embeddedPrefixes: string[] = [],\n ): string {\n return (\n snakeCase(embeddedPrefixes.concat('').join('_')) +\n (customName ? customName : snakeCase(propertyName))\n );\n }\n\n // ???\n relationName(propertyName: string): string {\n return snakeCase(propertyName);\n }\n\n // ???\n joinColumnName(relationName: string, referencedColumnName: string): string {\n return snakeCase(relationName + '_' + referencedColumnName);\n }\n\n /**\n * Create join table name for many-to-many relations.\n * @returns join table name\n * @example\n * ```ts\n * @Entity()\n * class Post {\n * @ManyToMany(() => Theme) // post_to_theme\n * themes: Theme[];\n * }\n *\n */\n joinTableName(firstTableName: string, secondTableName: string): string {\n return snakeCase(\n pluralToSingular(firstTableName) +\n '_to_' +\n pluralToSingular(secondTableName),\n );\n }\n\n // ???\n joinTableColumnName(\n tableName: string,\n propertyName: string,\n columnName?: string,\n ): string {\n return snakeCase(\n pluralToSingular(tableName) + '_' + (columnName ? columnName : propertyName),\n );\n }\n\n eagerJoinRelationAlias(alias: string, propertyPath: string): string {\n return alias + '__' + propertyPath.replace('.', '_');\n }\n\n /**\n * Create a primary key name.\n * @param tableOrName - The table or table name\n * @param columnNames - The column names\n * @returns The primary key name\n * @example\n * ```ts\n * @Entity()\n * class User {\n * @PrimaryColumn()\n * id: string;\n * }\n *\n * // returns 'pk_users__id'\n */\n primaryKeyName(tableOrName: Table | string, columnNames: string[]): string {\n tableOrName =\n typeof tableOrName === 'string' ? tableOrName : tableOrName.name;\n\n let name = tableOrName;\n for (const column of columnNames) {\n name += `__${column}`;\n }\n\n name = this.simplifyName(name);\n\n return `pk_${name}`;\n }\n\n /**\n * Create a foreign key name.\n * @param tableOrName - The table or table name\n * @param columnNames - The column names\n * @returns The foreign key name\n * @example\n * ```ts\n * @Entity()\n * class User {\n * @PrimaryColumn()\n * id: string;\n * }\n * @Entity()\n * class Post {\n * @PrimaryColumn()\n * id: string;\n *\n * @ManyToOne(() => User, user => user.posts)\n * user: User;\n * }\n *\n * // returns 'fk_posts__user_id__users__id'\n * ```\n */\n foreignKeyName(tableOrName: Table | string, columnNames: string[]): string {\n tableOrName =\n typeof tableOrName === 'string' ? tableOrName : tableOrName.name;\n\n let name = tableOrName;\n for (const column of columnNames) {\n name += `__${column}`;\n }\n\n name = this.simplifyName(name);\n\n return `fk_${name}`;\n }\n\n /**\n * Create an index name.\n * @param tableOrName - The table or table name\n * @param columnNames - The column names\n * @returns The index name\n * @example\n * ```ts\n * @Entity()\n * class User {\n * @Index()\n * @Column()\n * email: string;\n * }\n * // returns 'idx_users__email'\n * ```\n */\n indexName(tableOrName: Table | string, columnNames: string[]): string {\n tableOrName =\n typeof tableOrName === 'string' ? tableOrName : tableOrName.name;\n\n let name = tableOrName;\n for (const column of columnNames) {\n name += `__${column}`;\n }\n\n name = this.simplifyName(name);\n\n return `idx_${name}`;\n }\n\n /**\n * Create a unique constraint name.\n * @param tableOrName - The table or table name\n * @param columnNames - The column names\n * @returns The unique constraint name\n * @example\n * ```ts\n * @Entity()\n * class User {\n * @Unique()\n * @Column()\n * email: string;\n * }\n * // returns 'uq_users__email'\n * ```\n */\n uniqueConstraintName(\n tableOrName: Table | string,\n columnNames: string[],\n ): string {\n tableOrName =\n typeof tableOrName === 'string' ? tableOrName : tableOrName.name;\n\n let name = tableOrName;\n for (const column of columnNames) {\n name += `__${column}`;\n }\n\n name = this.simplifyName(name);\n\n return `uq_${name}`;\n }\n\n private simplifyName(name: string): string {\n if (name.length > 50) {\n const pieces = name.split('__');\n\n const simplified = pieces.map((piece) => {\n if (piece.includes('_to_')) {\n return piece.split('_').map((p) => p[0]).join('');\n }\n\n return piece;\n });\n\n return simplified.join('__');\n }\n\n return name;\n }\n}\n","import { Inject } from '@nestjs/common';\nimport { getConfigToken, registerAs } from '@nestjs/config';\nimport { Type } from 'class-transformer';\nimport {\n IsBoolean,\n IsNumber, IsOptional, IsString,\n} from 'class-validator';\nimport { PostgresConnectionOptions } from 'typeorm/driver/postgres/PostgresConnectionOptions.js';\n\nimport { SnakeNamingStrategy } from '#/db/snake-naming.strategy';\nimport { validateEnv } from '#/tools/env';\nimport fg from 'fast-glob';\n\n/**\n * NestJS injection token for postgres db config\n */\nexport const DB_CONFIG_TOKEN = 'DB_CONFIG_TOKEN';\n\nexport const InjectDbConfig = () => Inject(getConfigToken(DB_CONFIG_TOKEN));\n\n/**\n * Postgres db config environment variables\n */\nclass DbConfigEnvironmentVariables {\n /**\n * Postgres host\n * @example\n * ```yaml\n * POSTGRES_HOST: 'localhost'\n * ```\n */\n @IsString()\n POSTGRES_HOST!: string;\n\n /**\n * Postgres port\n * @example\n * ```yaml\n * POSTGRES_PORT: 5432\n * ```\n */\n @Type(() => Number)\n @IsNumber()\n POSTGRES_PORT!: number;\n\n /**\n * Postgres user\n * @example\n * ```yaml\n * POSTGRES_USER: 'app'\n * ```\n */\n @IsString()\n POSTGRES_USER!: string;\n\n /**\n * Postgres password\n * @example\n * ```yaml\n * POSTGRES_PASS: 'qwerty'\n * ```\n */\n @IsString()\n POSTGRES_PASS!: string;\n\n /**\n * Postgres database name\n * @example\n * ```yaml\n * POSTGRES_DB: 'jetstream'\n * ```\n */\n @IsString()\n POSTGRES_DB!: string;\n\n /**\n * Enable postgres logging\n * @example\n * ```yaml\n * POSTGRES_IS_LOGGING_ENABLED: \"true\"\n * ```\n */\n @Type(() => Boolean)\n @IsOptional()\n @IsBoolean()\n POSTGRES_IS_LOGGING_ENABLED?: boolean;\n}\n\n/**\n * Postgres Database Config\n */\nexport const createDbConfig = (opts?: Partial<PostgresConnectionOptions>) => {\n return registerAs(DB_CONFIG_TOKEN, (): PostgresConnectionOptions => {\n const env = validateEnv(DbConfigEnvironmentVariables);\n\n const baseEntities = [\n 'dist/**/*.entity.js',\n 'node_modules/@deep/nest-kit/dist/modules/**/*.entity.js',\n ];\n\n const entities = [\n ...(opts?.entities as string[] ?? baseEntities),\n ];\n\n return {\n type: 'postgres',\n logging: env.POSTGRES_IS_LOGGING_ENABLED,\n host: env.POSTGRES_HOST,\n port: env.POSTGRES_PORT,\n username: env.POSTGRES_USER,\n password: env.POSTGRES_PASS,\n database: env.POSTGRES_DB,\n synchronize: false,\n migrations: ['dist/migrations/*.js'],\n subscribers: ['dist/**/*.entity-subscriber.js'],\n migrationsRun: true,\n namingStrategy: new SnakeNamingStrategy(),\n ...opts,\n entities: fg.sync(entities),\n };\n });\n};\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nexport type Constructor = new (...args: any[]) => any\n\ntype MixinFunction<TInput, TOutput> = (source: TInput) => TOutput\n\n/**\n * Compose a class by applying mixins to it.\n * The code is inspired by https://justinfagnani.com/2015/12/21/real-mixins-with-javascript-classes/, its\n * just that I have added the support for static types too.\n *\n * @param baseClass - The base class to extend\n * @param mixins - One or more mixin functions to apply sequentially\n * @returns The composed class with all mixins applied\n */\nexport function compose<TBase extends Constructor, TResult1>(\n baseClass: TBase,\n mixin1: MixinFunction<TBase, TResult1>\n): TResult1\nexport function compose<TBase extends Constructor, TResult1, TResult2>(\n baseClass: TBase,\n mixin1: MixinFunction<TBase, TResult1>,\n mixin2: MixinFunction<TResult1, TResult2>\n): TResult2\nexport function compose<TBase extends Constructor, TResult1, TResult2, TResult3>(\n baseClass: TBase,\n mixin1: MixinFunction<TBase, TResult1>,\n mixin2: MixinFunction<TResult1, TResult2>,\n mixin3: MixinFunction<TResult2, TResult3>\n): TResult3\nexport function compose<TBase extends Constructor, TResult1, TResult2, TResult3, TResult4>(\n baseClass: TBase,\n mixin1: MixinFunction<TBase, TResult1>,\n mixin2: MixinFunction<TResult1, TResult2>,\n mixin3: MixinFunction<TResult2, TResult3>,\n mixin4: MixinFunction<TResult3, TResult4>\n): TResult4\nexport function compose<TBase extends Constructor, TResult1, TResult2, TResult3, TResult4, TResult5>(\n baseClass: TBase,\n mixin1: MixinFunction<TBase, TResult1>,\n mixin2: MixinFunction<TResult1, TResult2>,\n mixin3: MixinFunction<TResult2, TResult3>,\n mixin4: MixinFunction<TResult3, TResult4>,\n mixin5: MixinFunction<TResult4, TResult5>\n): TResult5\nexport function compose<TBase extends Constructor, TResult1, TResult2, TResult3, TResult4, TResult5, TResult6>(\n baseClass: TBase,\n mixin1: MixinFunction<TBase, TResult1>,\n mixin2: MixinFunction<TResult1, TResult2>,\n mixin3: MixinFunction<TResult2, TResult3>,\n mixin4: MixinFunction<TResult3, TResult4>,\n mixin5: MixinFunction<TResult4, TResult5>,\n mixin6: MixinFunction<TResult5, TResult6>\n): TResult6\nexport function compose<TBase extends Constructor, TResult1, TResult2, TResult3, TResult4, TResult5, TResult6, TResult7>(\n baseClass: TBase,\n mixin1: MixinFunction<TBase, TResult1>,\n mixin2: MixinFunction<TResult1, TResult2>,\n mixin3: MixinFunction<TResult2, TResult3>,\n mixin4: MixinFunction<TResult3, TResult4>,\n mixin5: MixinFunction<TResult4, TResult5>,\n mixin6: MixinFunction<TResult5, TResult6>,\n mixin7: MixinFunction<TResult6, TResult7>\n): TResult7\nexport function compose<TBase extends Constructor, TResult1, TResult2, TResult3, TResult4, TResult5, TResult6, TResult7, TResult8>(\n baseClass: TBase,\n mixin1: MixinFunction<TBase, TResult1>,\n mixin2: MixinFunction<TResult1, TResult2>,\n mixin3: MixinFunction<TResult2, TResult3>,\n mixin4: MixinFunction<TResult3, TResult4>,\n mixin5: MixinFunction<TResult4, TResult5>,\n mixin6: MixinFunction<TResult5, TResult6>,\n mixin7: MixinFunction<TResult6, TResult7>,\n mixin8: MixinFunction<TResult7, TResult8>\n): TResult8\nexport function compose<TBase extends Constructor, TResult1, TResult2, TResult3, TResult4, TResult5, TResult6, TResult7, TResult8, TResult9>(\n baseClass: TBase,\n mixin1: MixinFunction<TBase, TResult1>,\n mixin2: MixinFunction<TResult1, TResult2>,\n mixin3: MixinFunction<TResult2, TResult3>,\n mixin4: MixinFunction<TResult3, TResult4>,\n mixin5: MixinFunction<TResult4, TResult5>,\n mixin6: MixinFunction<TResult5, TResult6>,\n mixin7: MixinFunction<TResult6, TResult7>,\n mixin8: MixinFunction<TResult7, TResult8>,\n mixin9: MixinFunction<TResult8, TResult9>\n): TResult9\nexport function compose<TBase extends Constructor, TMixin extends MixinFunction<TBase, TBase>>(\n baseClass: TBase,\n ...mixins: TMixin[]\n) {\n return mixins.reduce((currentClass, mixin) => mixin(currentClass), baseClass);\n}\n","/**\n * Converts a number or string value to a BigInt, preserving null and undefined values.\n *\n * @param value - The value to convert. Can be a number, string, undefined, or null.\n * @returns The converted BigInt value, or the original value if it was null or undefined.\n *\n * @example\n * ```typescript\n * convertToBigInt(123) // returns 123n\n * convertToBigInt(\"456\") // returns 456n\n * convertToBigInt(null) // returns null\n * convertToBigInt(undefined) // returns undefined\n * ```\n *\n * @throws {RangeError} Throws when the input cannot be converted to a valid BigInt.\n */\nexport const convertToBigInt = (value: number | string | undefined | null): bigint | undefined | null => {\n if (value === null) {\n return value;\n }\n\n if (typeof value === 'undefined') {\n return value;\n }\n\n return BigInt(value);\n};\n","import { ObjectLiteral, SelectQueryBuilder } from 'typeorm';\n\n/**\n * Returns total count of items with typeorm query\n * @param query - typeorm query builder\n * @returns total count of items\n */\n/**\n * Returns total count of items with typeorm query\n * @param query - typeorm query builder\n * @returns total count of items\n */\nexport const fetchTotalWithQuery = async <T extends ObjectLiteral>(\n query: SelectQueryBuilder<T>,\n): Promise<number> => {\n const totalQueryBuilder = query.clone();\n\n // Clear any pagination settings\n totalQueryBuilder\n .offset(undefined)\n .limit(undefined)\n .skip(undefined)\n .take(undefined)\n .orderBy();\n\n const hasDistinctOn = totalQueryBuilder.expressionMap.selectDistinctOn && totalQueryBuilder.expressionMap.selectDistinctOn.length > 0;\n const isGrouped = totalQueryBuilder.expressionMap.groupBys && totalQueryBuilder.expressionMap.groupBys.length > 0;\n\n // Check if the original query has DISTINCT ON or GROUP BY\n if (hasDistinctOn || isGrouped) {\n // Wrap the query (either with DISTINCT ON or GROUP BY) in a subquery and count the results\n const subQuery = totalQueryBuilder.getQuery();\n\n const result = await query.connection\n .createQueryBuilder()\n .select('COUNT(*)', 'rowsCount')\n .from(`(${subQuery})`, 'subQuery')\n .setParameters(totalQueryBuilder.getParameters())\n .getRawOne<{\n rowsCount: number;\n }>();\n\n return result?.rowsCount ?? 0;\n }\n\n // If no DISTINCT ON or GROUP BY, just get the count directly\n return await totalQueryBuilder.getCount();\n};\n","import { ListMeta } from '#/types/list-meta';\nimport type { ObjectLiteral, SelectQueryBuilder } from 'typeorm';\nimport { fetchTotalWithQuery } from './fetch-total-with-query.js';\n\nexport interface CreateListMetaOptions<T extends ObjectLiteral> {\n /**\n * Typeorm query builder\n */\n query: SelectQueryBuilder<T>;\n\n /**\n * If true, total count will be calculated by additional SELECT COUNT.\n */\n needCountTotal?: boolean;\n\n /**\n * Limit of items\n */\n limit?: number;\n\n /**\n * Offset of items\n */\n offset?: number;\n}\n\n/**\n * Create list meta object\n * @returns list meta object\n * @example\n * class UsersService {\n * async getMany(opts: GetManyUsersOptions): Promise<[User[], ListMeta]> {\n * ...\n * return Promise.all([\n * query.getMany(),\n * createListMeta<User>({\n * query,\n * needCountTotal,\n * limit,\n * offset,\n * }),\n * ]);\n * }\n */\nexport const createListMeta = async <T extends ObjectLiteral>(\n {\n query,\n needCountTotal = false,\n limit,\n offset,\n }: CreateListMetaOptions<T>,\n): Promise<ListMeta> => {\n const meta: ListMeta = {\n limit,\n offset,\n };\n\n if (needCountTotal) {\n meta.total = await fetchTotalWithQuery(query);\n }\n\n return meta;\n};\n\n","/**\n * Define statuses. Returns array of statuses from filter or default statuses\n * @param statuses - array of statuses from filter. Can be undefined\n * @param defaultStatuses - array of default statuses\n * @returns final array of statuses\n * @example\n * const statuses = defineStatuses(['active', 'pending'], ['active']);\n * // statuses = ['active', 'pending']\n *\n * const statuses = defineStatuses(undefined, ['active']);\n * // statuses = ['active']\n */\nexport const defineStatuses = <T>(statuses: T[] | undefined, defaultStatuses: T[]) => {\n return Array.isArray(statuses) ? statuses : defaultStatuses;\n};\n","import { parse } from 'accept-language-parser';\n\nimport { NestExpressRequest } from '#/types/express-request';\n\nexport const getRequestLanguage = (req: NestExpressRequest, fallbackLanguage: string): string => {\n const headers = req?.headers as ({\n ['accept-language']?: string;\n });\n\n return parse(headers['accept-language'])\n ?.[0]\n ?.code ?? fallbackLanguage;\n};\n","/**\n * Converts a locale string to a PostgreSQL collation identifier.\n *\n * @param locale - The locale string to convert (e.g., 'uk', 'en')\n * @returns The PostgreSQL collation identifier (e.g., 'uk_UA', 'en_US')\n *\n * @example\n * ```typescript\n * localeToPgCollate('uk') // returns 'uk_UA'\n * localeToPgCollate('en') // returns 'en_US'\n * ```\n */\nexport const localeToPgCollate = (locale: string) => {\n let collate = 'en_US';\n\n if (locale === 'uk') {\n collate = 'uk_UA';\n }\n\n return collate;\n};\n","type DefinedValuesOnly<T> = {\n [K in keyof T]: T[K] extends undefined ? never : K;\n}[keyof T];\n\ntype UndefinedRemoved<T> = {\n [K in DefinedValuesOnly<T>]: T[K];\n};\n\nexport const removeUndefinedProperties = <T extends object>(obj: T): UndefinedRemoved<T> => {\n const result: Partial<UndefinedRemoved<T>> = {\n };\n\n for (const key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key) && obj[key as keyof T] !== undefined) {\n (result as Record<string, unknown>)[key] = obj[key as keyof T];\n }\n }\n\n return result as UndefinedRemoved<T>;\n};\n","import { createRandomString } from '@pcg/text-kit';\n\nimport { NestExpressRequest } from '#/types/express-request';\n\n\nexport const generateRequestId = (appShortName: string) => {\n return `${appShortName}req:${createRandomString()}`;\n};\n\nexport const extractRequestId = (req: NestExpressRequest): string => {\n const headers = req?.headers as ({\n 'x-request-id'?: string;\n 'x-cloud-trace-context'?: string;\n });\n\n if (headers?.['x-request-id']) {\n return headers['x-request-id'];\n }\n\n if (headers['x-cloud-trace-context']) {\n return req.appShortname + `req:${headers['x-cloud-trace-context']}`;\n }\n\n return generateRequestId(req.appShortname);\n};\n","/**\n * Pauses execution for a specified amount of time using a Promise.\n * @param ms - The amount of time to pause in milliseconds.\n * @returns A Promise that resolves after the specified amount of time has elapsed.\n * @deprecated use wait instead\n */\nexport const pauseWithPromise = async (ms: number): Promise<void> => {\n return await new Promise((resolve) => {\n setTimeout(() => {\n resolve();\n }, ms);\n });\n};\n\n/**\n * Pauses execution for a specified amount of time using a Promise.\n * @param ms - The amount of time to pause in milliseconds.\n * @returns A Promise that resolves after the specified amount of time has elapsed.\n */\nexport const wait = async (ms: number): Promise<void> => {\n return await new Promise((resolve) => {\n setTimeout(() => {\n resolve();\n }, ms);\n });\n};\n","import {\n Brackets, In, IsNull, ObjectLiteral, SelectQueryBuilder, WhereExpressionBuilder,\n} from 'typeorm';\n\nimport { MaybeNull } from '#/types/maybe';\n\n/**\n * Adds a filter condition to a TypeORM SelectQueryBuilder based on the provided field and value(s).\n *\n * Handles three types of filtering:\n * - Single value filtering: when a single non-null value is provided\n * - Multiple value filtering: when an array of values is provided\n * - Null value filtering: when null is explicitly provided as the filter value\n *\n * @template T - The entity type that extends ObjectLiteral\n * @template K - The field name key type that must be a string key of T\n *\n * @param query - The TypeORM SelectQueryBuilder instance to add the filter to\n * @param fieldName - The name of the field to filter by, must be a valid key of entity T\n * @param valueOrValues - The filter value(s). Can be:\n * - A single value of type T[K]\n * - An array of values of type T[K]\n * - null to filter for null values\n * - An array containing null values\n * @example\n * ```typescript\n * // Single value filter\n * addFilterByField(queryBuilder, 'status', 'active');\n * // Multiple values filter\n * addFilterByField(queryBuilder, 'id', [1, 2, 3]);\n * // Null value filter\n * addFilterByField(queryBuilder, 'deletedAt', null);\n * ```\n *\n * @returns void - Modifies the query builder in place\n */\nexport const addFilterByField = <\n T extends ObjectLiteral,\n K extends (keyof T & string)\n>(query: SelectQueryBuilder<T>, fieldName: K, valueOrValues: MaybeNull<T[K]> | MaybeNull<T[K]>[]): void => {\n const isFilterValueMultiple = Array.isArray(valueOrValues);\n\n if (isFilterValueMultiple) {\n addMultipleFilter(query, fieldName, valueOrValues);\n } else if (valueOrValues === null) {\n addNullableFilter(query, fieldName);\n } else {\n addSingleFilter(query, fieldName, valueOrValues);\n }\n};\n\n/**\n * Adds a filter to a TypeORM query that matches multiple values for a given column,\n * including support for null values.\n *\n * @template T - The entity type that extends ObjectLiteral\n * @template K - The key type that must be both a key of T and a string\n * @param query - The TypeORM SelectQueryBuilder instance to add the filter to\n * @param columnName - The name of the column to filter on\n * @param values - An array of values to match, which may include null\n *\n * @remarks\n * This function creates an OR condition that matches any of the provided values.\n * If the values array includes null, a separate null check is added to the filter.\n * Non-null values are handled using TypeORM's `In` operator.\n *\n * @example\n * ```typescript\n * const query = repository.createQueryBuilder('user');\n * addMultipleFilter(query, 'status', ['active', 'pending', null]);\n * // Generates: WHERE (status IS NULL OR status IN ('active', 'pending'))\n * ```\n */\nconst addMultipleFilter = <\n T extends ObjectLiteral,\n K extends (keyof T & string)\n>(query: SelectQueryBuilder<T>, columnName: K, values: MaybeNull<T[K]>[]): void => {\n query.andWhere(new Brackets((subQuery) => {\n if (values.includes(null)) {\n addNullValueToMultipleFilter(subQuery, columnName);\n }\n\n const notNullValues = values.filter((v) => v !== null);\n subQuery.orWhere({\n [columnName]: In(notNullValues),\n });\n }));\n};\n\n/**\n * Adds a single filter condition to a TypeORM SelectQueryBuilder.\n *\n * @template T - The entity type that extends ObjectLiteral\n * @template K - The column name type, constrained to string keys of T\n *\n * @param query - The SelectQueryBuilder instance to add the filter to\n * @param columnName - The name of the column to filter on\n * @param value - The value to filter by, must match the type of the column\n *\n * @returns void\n *\n * @example\n * ```typescript\n * const query = repository.createQueryBuilder('user');\n * addSingleFilter(query, 'email', 'user@example.com');\n * // Results in: WHERE user.email = 'user@example.com'\n * ```\n */\nconst addSingleFilter = <\n T extends ObjectLiteral,\n K extends (keyof T & string)\n>(query: SelectQueryBuilder<T>, columnName: K, value: T[K]): void => {\n query.andWhere({\n [columnName]: value,\n });\n};\n\n/**\n * Adds a nullable filter to a TypeORM query builder.\n *\n * This function applies a WHERE clause that filters for NULL values in the specified column.\n * The filter is combined with existing conditions using AND logic.\n *\n * @template T - The entity type that extends ObjectLiteral\n * @param query - The TypeORM SelectQueryBuilder instance to add the filter to\n * @param columnName - The name of the column to check for NULL values\n * @returns void\n *\n * @example\n * ```typescript\n * const query = repository.createQueryBuilder('user');\n * addNullableFilter(query, 'deletedAt');\n * // Results in: WHERE deletedAt IS NULL\n * ```\n */\nconst addNullableFilter = <T extends ObjectLiteral>(query: SelectQueryBuilder<T>, columnName: string): void => {\n query.andWhere({\n [columnName]: IsNull(),\n });\n};\n\n/**\n * Adds an OR condition to the query to check if the specified column is NULL.\n *\n * This function is used to extend filtering logic by adding a null value check\n * as an alternative condition in a WHERE clause.\n *\n * @param query - The TypeORM WhereExpressionBuilder instance to which the null condition will be added\n * @param columnName - The name of the database column to check for NULL values\n *\n * @returns void\n *\n * @example\n * ```typescript\n * const queryBuilder = repository.createQueryBuilder('user');\n * addNullValueToMultipleFilter(queryBuilder, 'deletedAt');\n * // Results in: WHERE ... OR deletedAt IS NULL\n * ```\n */\nconst addNullValueToMultipleFilter = (query: WhereExpressionBuilder, columnName: string): void => {\n query.orWhere({\n [columnName]: IsNull(),\n });\n};\n","import { ObjectLiteral, SelectQueryBuilder } from 'typeorm';\n\n/**\n * Checks if a given alias is already used in the query builder's join attributes.\n *\n * This utility function inspects the query builder's expression map to determine\n * whether a specific alias name has already been assigned to any join attribute.\n * This is useful to avoid alias conflicts when building complex TypeORM queries.\n *\n * @template T - The entity type that extends ObjectLiteral\n * @param {SelectQueryBuilder<T>} query - The TypeORM SelectQueryBuilder instance to check\n * @param {string} alias - The alias name to search for in the join attributes\n * @returns {boolean} True if the alias is already used in any join attribute, false otherwise\n *\n * @example\n * ```typescript\n * const query = repository.createQueryBuilder('user');\n * const isBusy = isAliasAlreadyBusy(query, 'profile');\n * if (!isBusy) {\n * query.leftJoinAndSelect('user.profile', 'profile');\n * }\n * ```\n */\nexport const isAliasAlreadyBusy = <T extends ObjectLiteral>(query: SelectQueryBuilder<T>, alias: string) =>\n query.expressionMap.joinAttributes.some((a) => a.alias.name === alias);\n","import { ObjectLiteral, SelectQueryBuilder } from 'typeorm';\nimport { isAliasAlreadyBusy } from './is-alias-already-busy.js';\n\n/**\n * Ensures an inner join is added to the TypeORM query builder only if the alias is not already in use.\n *\n * This function checks if the specified alias is already being used in the query builder.\n * If the alias is available, it adds an inner join with the provided entity, alias, and optional condition.\n * If the alias is already busy, the function returns without making any changes to the query.\n *\n * @template T - The entity type that extends ObjectLiteral\n * @param query - The TypeORM SelectQueryBuilder instance to add the inner join to\n * @param entity - The entity class (Function) or entity name (string) to join\n * @param alias - The alias to use for the joined entity\n * @param condition - Optional join condition as a string\n * @returns void\n *\n * @example\n * ```typescript\n * const query = repository.createQueryBuilder('user');\n * ensureInnerJoin(query, Profile, 'profile', 'profile.userId = user.id');\n * ```\n */\nexport const ensureInnerJoin = <T extends ObjectLiteral>(\n query: SelectQueryBuilder<T>,\n // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\n entity: Function | string,\n alias: string,\n condition?: string,\n): void => {\n if (isAliasAlreadyBusy(query, alias)) {\n return;\n }\n\n query.innerJoin(entity, alias, condition);\n};\n","import { ObjectLiteral, SelectQueryBuilder } from 'typeorm';\nimport { isAliasAlreadyBusy } from './is-alias-already-busy.js';\n\n/**\n * Ensures a left join is added to a TypeORM query builder if the alias is not already in use.\n *\n * This function checks if the specified alias is already being used in the query.\n * If the alias is available, it performs a left join with the provided entity, alias, and optional condition.\n * If the alias is already busy, the function returns early without modifying the query.\n *\n * @template T - The entity type that extends ObjectLiteral\n * @param query - The TypeORM SelectQueryBuilder instance to add the left join to\n * @param entity - The entity class (Function) or table name (string) to join\n * @param alias - The alias name to use for the joined entity\n * @param condition - Optional join condition as a string (e.g., \"alias.id = entity.foreignId\")\n * @returns void\n *\n * @example\n * ```typescript\n * ensureLeftJoin(queryBuilder, User, 'user', 'user.id = post.userId');\n * ```\n */\nexport const ensureLeftJoin = <T extends ObjectLiteral>(\n query: SelectQueryBuilder<T>,\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\n entity: Function | string,\n alias: string,\n condition?: string,\n): void => {\n if (isAliasAlreadyBusy(query, alias)) {\n return;\n }\n\n query.leftJoin(entity, alias, condition);\n};\n","import { InputValidationError } from '#/errors';\nimport { ValidationError, ValidationPipe } from '@nestjs/common';\n\nexport class NestKitValidationPipe extends ValidationPipe {\n createExceptionFactory() {\n return (validationErrors: ValidationError[] = []) => {\n if (!this.isDetailedOutputDisabled) {\n return new InputValidationError(validationErrors);\n }\n\n return new InputValidationError();\n };\n }\n}\n","import {\n ArgumentsHost, Catch, HttpException, HttpServer,\n} from '@nestjs/common';\nimport { isObject } from '@nestjs/common/utils/shared.utils';\nimport { GqlArgumentsHost } from '@nestjs/graphql/dist/services/gql-arguments-host';\n\nimport { AppEnv } from '#/enums/app-env.enum';\nimport {\n Logger, LoggerContext, LoggerFactory,\n} from '#/logger';\nimport { HttpExceptionResponse } from './http-exception-response.js';\n\ntype ContextType = 'http' | 'ws' | 'rpc' | 'graphql';\n\n/**\n * Http exception filter for NestJS\n * It is used to correctly log all http exceptions\n * @deprecated use NestErrorFilter instead\n * @see NestErrorFilter\n * @example\n * ```ts\n * // main.ts\n * const { httpAdapter } = app.get(HttpAdapterHost);\n * const loggerFactory = app.get(WINSTON_MODULE_FACTORY_PROVIDER);\n * app.useGlobalFilters(new HttpExceptionFilter(httpAdapter, loggerFactory));\n * ```\n */\n@Catch(HttpException)\nexport class HttpExceptionFilter {\n private readonly logger: Logger;\n\n constructor(\n protected readonly applicationRef: HttpServer,\n private readonly loggerFactory: LoggerFactory,\n ) {\n this.logger = this.loggerFactory.create({\n scope: HttpExceptionFilter.name,\n });\n }\n\n catch(exception: HttpException, host: ArgumentsHost) {\n const gqlHost = GqlArgumentsHost.create(host);\n const type = gqlHost.getType<ContextType>();\n\n const response = exception.getResponse() as HttpExceptionResponse;\n if (!response?.silent) {\n if (isObject(response)) {\n const logger = this.loggerFactory.create(response.context);\n\n if (response.error instanceof Error) {\n logger.error(response.message, response.error);\n } else {\n logger.error(exception);\n }\n } else {\n this.logger.error(exception);\n }\n }\n\n if (type !== 'http') {\n return exception;\n }\n\n /**\n * If request is http, then we need to send response to client\n */\n let body: {\n message: string;\n key?: string;\n stack?: string;\n context?: LoggerContext;\n statusCode: number;\n };\n\n if (isObject(response)) {\n body = {\n key: response.key,\n message: response.message,\n context: response.context,\n statusCode: exception.getStatus(),\n };\n\n if (response.error instanceof Error && process.env.NODE_ENV !== AppEnv.PRODUCTION) {\n body.stack = response.error.stack;\n }\n } else {\n body = {\n statusCode: exception.getStatus(),\n message: response,\n };\n }\n\n this.applicationRef.reply(host.getArgByIndex(1), body, exception.getStatus());\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["Type","IdService","appConfig: AppConfigType","IdModule","CursorPaginationPageInfo","CursorPaginationInput","OffsetPaginationInput","OffsetPaginationPageInfo","winstonLogger: WinstonLogger","context: LoggerContext","errorObject: DestructuredError","NestSystemLogger","winstonLogger: WinstonLogger","context: LoggerContext","Logger","providers: Provider[]","LoggerModule","nestLikeColorScheme: Record<string, bare.Format>","context","format","winstonOptions: winston.LoggerOptions","params: NestJsResourceServiceParams<T, GOBO, F, O>","Type","meta: ListMeta","result: Partial<UndefinedRemoved<T>>","HttpExceptionFilter","applicationRef: HttpServer","loggerFactory: LoggerFactory","isObject","body: {\n message: string;\n key?: string;\n stack?: string;\n context?: LoggerContext;\n statusCode: number;\n }"],"sources":["../src/enums/app-env.enum.ts","../src/enums/app-mode.enum.ts","../src/tools/env.ts","../src/configs/app.config.ts","../src/enums/app-server.enum.ts","../src/enums/worker-mode.enum.ts","../src/tools/generate-entity-id.ts","../src/modules/id/id.service.ts","../src/modules/id/id.module.ts","../src/errors/nest-error.ts","../src/errors/bad-request.error.ts","../src/errors/not-found.error.ts","../src/pagination/constants.ts","../src/errors/forbidden.error.ts","../src/errors/access-denied.error.ts","../src/errors/input-validation.error.ts","../src/errors/unauthorized.error.ts","../src/pagination/cursor/cursor-pagination.types.ts","../src/pagination/cursor/cursor-pagination.input.ts","../src/pagination/offset/offset-pagination.helpers.ts","../src/pagination/offset/offset-pagination.input.ts","../src/pagination/offset/offset-pagination.types.ts","../src/tools/stringify-opts.ts","../src/logger/logger.constants.ts","../src/logger/classes/logger.ts","../src/logger/classes/nest-system-logger.ts","../src/logger/classes/typeorm-logger.ts","../src/logger/classes/logger-factory.ts","../src/logger/logger.providers.ts","../src/logger/logger.module.ts","../src/logger/winston.tools.ts","../src/configs/logger.config.ts","../src/abstracts/nestjs-service.ts","../src/abstracts/nestjs-resource-service.ts","../src/db/snake-naming.strategy.ts","../src/configs/db.config.ts","../src/tools/compose.ts","../src/tools/convert-to-bigint.ts","../src/tools/fetch-total-with-query.ts","../src/tools/create-list-meta.ts","../src/tools/define-statuses.ts","../src/tools/get-request-language.ts","../src/tools/postgres/locale-to-pg-collate.ts","../src/tools/remove-undefined-properties.ts","../src/tools/request-id.ts","../src/tools/wait.ts","../src/tools/typeorm/add-filter.ts","../src/tools/typeorm/is-alias-already-busy.ts","../src/tools/typeorm/ensure-inner-join.ts","../src/tools/typeorm/ensure-left-join.ts","../src/validation/validation-pipe.ts","../src/exceptions/http-exceptions.filter.ts"],"sourcesContent":["/**\n * Application environment enum\n */\nexport enum AppEnv {\n /**\n * Local environment.\n * Used for local development on your machine.\n */\n LOCAL = 'local',\n\n /**\n * Test environment.\n * Used when running tests.\n */\n TEST = 'test',\n\n /**\n * Development environment.\n * Used when deploying to a development server.\n * Development server provide early access to new features.\n */\n DEVELOPMENT = 'development',\n\n /**\n * Stage environment.\n * Used when deploying to a stage server.\n * Stage is a pre-production environment.\n */\n STAGE = 'stage',\n\n /**\n * Production environment.\n * Used when deploying to a production server.\n */\n PRODUCTION = 'production',\n}\n","export enum AppMode {\n STANDALONE = 'standalone',\n PARENT = 'parent',\n CHILD = 'child',\n}\n","import { Type as ClassConstructor } from '@nestjs/common';\nimport { plainToInstance } from 'class-transformer';\nimport { validateSync } from 'class-validator';\n\nimport { AppEnv } from '#/enums/app-env.enum';\n\n/**\n * Validate environment variables using class-validator\n *\n * @param cls - class with environment variables\n * @throws Error if validation fails\n * @returns validated config as typed object\n * @example\n * ```ts\n * export class AppConfigEnvironmentVariables {\n * @Type(() => Number)\n * @IsNumber()\n * PORT = 3000;\n * }\n *\n * const env = validateEnv(AppConfigEnvironmentVariables); // typed object\n * // env.PORT is now a number\n * ```\n */\nexport const validateEnv = <T>(cls: ClassConstructor<T>): T => {\n const validatedConfig = plainToInstance(\n cls,\n process.env,\n {\n enableImplicitConversion: true,\n },\n );\n\n const errors = validateSync(validatedConfig as unknown as object, {\n skipMissingProperties: false,\n });\n\n if (errors.length > 0) {\n throw new Error(errors.toString());\n }\n\n return validatedConfig;\n};\n\n/**\n * Returns a string with a dash prefix based on the current environment.\n * If the environment is development or local, returns '-dev'.\n * If the environment is stage, returns '-stage'.\n * Otherwise, returns an empty string.\n *\n * @returns a string with a dash prefix based on the current environment\n * @example\n * ```typescript\n * const name = `my-app${withDashEnv()}`;\n * ```\n */\nexport const withDashEnv = () => {\n if (process.env.APP_ENV === AppEnv.DEVELOPMENT || process.env.APP_ENV === AppEnv.LOCAL || process.env.APP_ENV === AppEnv.TEST) {\n return '-dev';\n }\n\n if (process.env.APP_ENV === AppEnv.STAGE) {\n return '-stage';\n }\n\n return '';\n};\n\n/**\n * Returns a string with a dash prefix based on the current environment.\n * If the environment is development or local, returns '.dev'.\n * If the environment is stage, returns '.stage'.\n * Otherwise, returns an empty string.\n *\n * @returns a string with a dot prefix based on the current environment\n * @example\n * ```typescript\n * const name = `config${withDotEnv()}`;\n * ```\n */\nexport const withDotEnv = () => {\n if (process.env.APP_ENV === AppEnv.DEVELOPMENT || process.env.APP_ENV === AppEnv.LOCAL || process.env.APP_ENV === AppEnv.TEST) {\n return '.dev';\n }\n\n if (process.env.APP_ENV === AppEnv.STAGE) {\n return '.stage';\n }\n\n return '';\n};\n\n/**\n * Returns a string with a colon prefix based on the current environment.\n * If the environment is development or local, returns ':dev'.\n * If the environment is stage, returns ':stage'.\n * Otherwise, returns an empty string.\n *\n * @returns a string with a colon prefix based on the current environment\n * @example\n * ```typescript\n * const name = `my:app${withColonEnv()}`;\n * ```\n */\nexport const withColonEnv = () => {\n if (process.env.APP_ENV === AppEnv.DEVELOPMENT || process.env.APP_ENV === AppEnv.LOCAL || process.env.APP_ENV === AppEnv.TEST) {\n return ':dev';\n }\n\n if (process.env.APP_ENV === AppEnv.STAGE) {\n return ':stage';\n }\n\n return '';\n};\n\n/**\n * Returns a string with an underscore prefix based on the current environment.\n * If the environment is development or local, returns '_dev'.\n * If the environment is stage, returns '_stage'.\n * Otherwise, returns an empty string.\n *\n * @returns a string with an underscore prefix based on the current environment\n * @example\n * ```typescript\n * const name = `my_app${withUnderscoreEnv()}`;\n * ```\n */\nexport const withUnderscoreEnv = () => {\n if (process.env.APP_ENV === AppEnv.DEVELOPMENT || process.env.APP_ENV === AppEnv.LOCAL || process.env.APP_ENV === AppEnv.TEST) {\n return '_dev';\n }\n\n if (process.env.APP_ENV === AppEnv.STAGE) {\n return '_stage';\n }\n\n return '';\n};\n","import { Inject } from '@nestjs/common';\nimport { getConfigToken, registerAs } from '@nestjs/config';\nimport { Type } from 'class-transformer';\nimport {\n IsEnum, IsNumber, IsOptional, IsString,\n} from 'class-validator';\n\nimport { AppEnv } from '../enums/app-env.enum.js';\nimport { AppMode } from '../enums/app-mode.enum.js';\nimport { validateEnv } from '../tools/env.js';\n\n/**\n * NestJS injection token for app config\n */\nexport const APP_CONFIG_TOKEN = 'APP_CONFIG_TOKEN';\n\nexport const InjectAppConfig = () => Inject(getConfigToken(APP_CONFIG_TOKEN));\n\n/**\n * Application config environment variables\n */\nexport class AppConfigEnvironmentVariables {\n /**\n * Application port\n * @example\n * ```yaml\n * PORT: 3000\n * ```\n */\n @Type(() => Number)\n @IsNumber()\n PORT = 3000;\n\n /**\n * Application host\n * @example\n * ```yaml\n * APP_HOST: 'https://app-api.example.com'\n * # or\n * APP_HOST: 'http://localhost:3000'\n * ```\n */\n @IsOptional()\n @IsString()\n APP_HOST!: string;\n\n /**\n * Application UI host\n * @example\n * ```yaml\n * APP_UI_HOST: 'https://app.example.com'\n * # or\n * APP_UI_HOST: 'http://localhost:4200'\n * ```\n */\n @IsOptional()\n @IsString()\n APP_UI_HOST!: string;\n\n /**\n * Application environment. Can be 'local', 'development', 'stage', 'production'\n * @example\n * ```yaml\n * APP_ENV: 'local'\n * ```\n */\n @IsEnum(AppEnv)\n APP_ENV!: AppEnv;\n\n /**\n * Application service account id (user with type SA in users table)\n * @example\n * ```yaml\n * APP_SERVICE_ACCOUNT_ID: 'hcu:xxxxxxxxxxx'\n * ```\n */\n @IsOptional()\n @IsString()\n APP_SERVICE_ACCOUNT_ID?: string;\n\n /**\n * Application fallback language\n * @example\n * ```yaml\n * FALLBACK_LANGUAGE: 'es'\n * ```\n */\n @IsOptional()\n @IsString()\n FALLBACK_LANGUAGE = 'en';\n}\n\nexport interface AppConfigType {\n /**\n * Application environment\n * @example 'local', 'development', 'stage', 'production'\n */\n env: AppEnv;\n\n /**\n * Application name\n * @example 'Jetstream'\n */\n name: string;\n\n /**\n * Application shortname\n * @example 'js'\n */\n shortname: string;\n\n /**\n * Application port\n * @example 3000\n */\n port: number;\n\n /**\n * Application mode\n * @example 'standalone'\n */\n mode: AppMode;\n\n /**\n * Application host\n * @example 'https://app-api.example.com or http://localhost:3000'\n */\n host?: string;\n\n /**\n * Application UI host\n * @example 'https://app.example.com or http://localhost:8080'\n */\n uiHost?: string;\n\n /**\n * Application fallback language\n * @example 'en'\n */\n fallbackLanguage: string;\n\n /**\n * Application service account id (user with type SA in users table)\n * @example 'hcu:xxxxxxxxxxx'\n */\n appServiceAccountId?: string;\n}\n\nexport interface AppConfigOptions {\n name: string;\n shortname: string;\n mode?: AppMode;\n}\n\n/**\n * Create Main Application Config\n * @example\n * ```ts\n * // src/config/index.ts\n *\n * import { createAppConfig } from '#/dist/configs';\n *\n * export const appConfig = createAppConfig({\n * name: 'Jetstream',\n * shortname: 'js',\n * });\n * ```\n */\nexport const createAppConfig = (opts: AppConfigOptions) => {\n return registerAs(APP_CONFIG_TOKEN, (): AppConfigType => {\n const env = validateEnv(AppConfigEnvironmentVariables);\n\n return {\n env: env.APP_ENV,\n name: opts.name,\n shortname: opts.shortname,\n port: env.PORT,\n host: env.APP_HOST,\n mode: opts.mode || AppMode.STANDALONE,\n uiHost: env.APP_UI_HOST,\n appServiceAccountId: env.APP_SERVICE_ACCOUNT_ID,\n fallbackLanguage: env.FALLBACK_LANGUAGE,\n };\n });\n};\n","/**\n * Enum for the NestJS server mode\n */\nexport enum AppServer {\n /**\n * NestJS HTTP server with GraphQL\n */\n HTTP = 'http',\n\n /**\n * NestJS gRPC server\n */\n GRPC = 'grpc',\n\n /**\n * NestJS WebSocket server\n */\n WS = 'ws',\n\n /**\n * Run as a worker\n */\n WORKER = 'worker',\n\n /**\n * Run as an agent\n */\n AGENT = 'agent',\n\n /**\n * Run as an bot (e.g. Slack bot)\n */\n BOT = 'bot',\n\n /**\n * Run as Cloud Run job\n */\n CLOUDRUN_JOB = 'cloudrun-job',\n}\n","export enum WorkerMode {\n /**\n * Run jobs in loop\n */\n LOOP = 'loop',\n\n /**\n * Run one job and exit\n */\n ONE_JOB = 'one-job',\n}\n","import { createRandomString } from '@pcg/text-kit';\n\n/**\n * Generates a unique entity identifier by combining product name, entity prefix, delimiter, and random string.\n *\n * @param product - The product short name to include in the entity ID (e.g., 'fwd' for Forward)\n * @param prefix - The entity type prefix to include in the entity ID (e.g., 'u' for user, 'org' for organization)\n * @param delimiter - The delimiter to separate components (default: ':')\n * @param size - The length of the random string component (default: 11)\n * @returns A formatted entity ID string in the format: `${product}${prefix}${delimiter}${randomString}`\n *\n * @example\n * ```typescript\n * generateEntityId('fwd', 'org')\n * // Returns: 'fwdorg:A1b2C3d4E5f'\n *\n * generateEntityId('myapp', 'u', '_', 8)\n * // Returns: 'myappuser_A1b2C3d4'\n * ```\n */\nexport const generateEntityId = (product: string, prefix: string, delimiter = ':', size = 11): string => {\n return `${product}${prefix}${delimiter}${createRandomString(size)}`;\n};\n","import { Inject, Injectable } from '@nestjs/common';\nimport { getConfigToken } from '@nestjs/config';\nimport { createRandomString } from '@pcg/text-kit';\n\nimport { APP_CONFIG_TOKEN, type AppConfigType } from '#/configs/app.config';\nimport { AppEnv } from '#/enums';\nimport { generateEntityId } from '#/tools/generate-entity-id';\n\n/**\n * An IdService is a service within your application that provides methods to generate unique IDs\n * for entities and other data objects.\n */\n@Injectable()\nexport class IdService {\n constructor(\n @Inject(getConfigToken(APP_CONFIG_TOKEN)) private readonly appConfig: AppConfigType,\n ) {}\n\n /**\n * Returns a delimiter string based on the current environment.\n * This delimiter is used in constructing the entity IDs.\n * The delimiter is ':dev:' for development environments,\n * :stage:' for staging environments and ':' for other environments.\n *\n * This allows for better differentiation and traceability of entities across various environments.\n */\n get delimiter() {\n switch (this.appConfig.env) {\n case AppEnv.TEST:\n return ':test:';\n case AppEnv.DEVELOPMENT:\n return ':dev:';\n case AppEnv.STAGE:\n return ':stage:';\n default:\n return ':';\n }\n }\n\n /**\n * Generates unique id for entity\n * @param prefix - entity id prefix in database (e.g. 'u' for users)\n * @param app - app shortname (e.g. 'js')\n * @returns id in format 'jsu:xxxxxxxxxxx' or 'jsu:stage:xxxxxxxxxxx' for staging environment\n */\n generateEntityId(prefix: string, app?: string): string {\n return generateEntityId(app ?? this.appConfig.shortname, prefix, this.delimiter, 11);\n }\n\n /**\n * Generates unique id with length 11\n * @returns id in format 'xxxxxxxxxxx'\n */\n generateId(size?: number) {\n return createRandomString(size);\n }\n}\n","import { Global, Module } from '@nestjs/common';\n\nimport { IdService } from './id.service.js';\n\n/**\n * An IdModule is a module within your application that provides services to generate unique IDs\n * for entities and other data objects.\n * @example\n * ```ts\n * // app.module.ts\n * import { IdModule } from './id.module';\n *\n * @Module({\n * imports: [IdModule],\n * controllers: [AppController],\n * providers: [AppService],\n * })\n * export class AppModule {}\n * ```\n */\n@Global()\n@Module({\n providers: [IdService],\n exports: [IdService],\n})\nexport class IdModule {}\n","import { HttpStatus } from '@nestjs/common';\n\n/**\n * Configuration options for creating a NestError instance.\n *\n * @interface NestErrorOptions\n */\nexport interface NestErrorOptions {\n /** The human-readable error message describing what went wrong */\n message: string;\n\n /**\n * A unique identifier or error code for categorizing and handling the error\n * @example\n * 'AUTH_USER_NOT_FOUND'\n * */\n key: string;\n\n /** The underlying error that caused this error, if any */\n cause?: unknown;\n\n /** Additional contextual information related to the error occurrence */\n context?: Record<string, unknown>;\n\n /**\n * Whether the error should be silenced (i.e., not logged or reported)\n */\n silent?: boolean;\n}\n\n/**\n * Custom error class for NestJS applications that extends the native Error class.\n *\n * This error class provides additional context and structured error handling\n * capabilities beyond the standard Error object.\n *\n * @example\n * ```typescript\n * throw new NestError({\n * key: 'AUTH_USER_NOT_FOUND',\n * message: 'User with the specified ID was not found',\n * context: { userId: '123' },\n * cause: originalError\n * });\n * ```\n */\nexport class NestError extends Error {\n key!: string;\n context?: Record<string, unknown>;\n httpStatusCode = HttpStatus.INTERNAL_SERVER_ERROR;\n silent!: boolean;\n\n constructor(opts: NestErrorOptions) {\n super(opts.message, opts.cause instanceof Error ? {\n cause: opts.cause,\n } : undefined);\n\n this.name = 'NestError';\n this.key = opts.key;\n this.context = opts.context;\n this.silent = opts.silent ?? false;\n }\n}\n","import { NestError, NestErrorOptions } from './nest-error.js';\n\nexport class BadRequestError extends NestError {\n constructor(opts: NestErrorOptions) {\n super(opts);\n this.name = 'BadRequestError';\n this.httpStatusCode = 400;\n }\n}\n","import { NestError, NestErrorOptions } from './nest-error.js';\n\nexport class NotFoundError extends NestError {\n constructor(opts: NestErrorOptions) {\n super(opts);\n this.name = 'NotFoundError';\n this.httpStatusCode = 404;\n }\n}\n","/**\n * Pagination max limit value\n */\nexport const PAGINATION_MAX_LIMIT = 1000;\n\n/**\n * Pagination default limit value\n */\nexport const PAGINATION_DEFAULT_LIMIT = 20;\n","import { NestError, NestErrorOptions } from './nest-error.js';\n\nexport class ForbiddenError extends NestError {\n constructor(opts: NestErrorOptions) {\n super(opts);\n this.name = 'ForbiddenError';\n this.httpStatusCode = 403;\n }\n}\n","import { ForbiddenError } from './forbidden.error.js';\n\nexport interface AccessDeniedErrorOptions {\n action: string;\n context: Record<string, unknown>;\n message?: string;\n}\n\nexport class AccessDeniedError extends ForbiddenError {\n constructor(opts: AccessDeniedErrorOptions) {\n super({\n key: 'AUTH_ACCESS_DENIED',\n message: opts.message || `Access denied: you don't have permission to perform \"${opts.action}\" action`,\n context: opts.context,\n });\n this.name = 'AccessDeniedError';\n }\n}\n","import { ValidationError } from '@nestjs/common';\nimport { NestError } from './nest-error.js';\n\nexport class InputValidationError extends NestError {\n constructor(errors?: ValidationError[]) {\n super({\n message: 'Input validation failed',\n key: 'NST_INPUT_VALIDATION_ERROR',\n context: errors ? {\n errors,\n } : undefined,\n });\n this.name = 'InputValidationError';\n this.httpStatusCode = 400;\n }\n}\n","import { NestError, NestErrorOptions } from './nest-error.js';\n\nexport class UnauthorizedError extends NestError {\n constructor(opts: NestErrorOptions) {\n super(opts);\n this.name = 'UnauthorizedError';\n this.httpStatusCode = 401;\n }\n}\n","import { Type } from '@nestjs/common';\nimport { Field, ObjectType } from '@nestjs/graphql';\n\nimport type { MaybeNull } from '#/types/maybe';\n\n@ObjectType()\nexport class CursorPaginationPageInfo {\n /**\n * The cursor to the first item in the list\n */\n @Field(() => String, {\n nullable: true,\n })\n startCursor!: MaybeNull<string>;\n\n /**\n * The cursor to the last item in the list\n */\n @Field(() => String, {\n nullable: true,\n })\n endCursor!: MaybeNull<string>;\n\n /**\n * Whether there are more items in the list before the start cursor\n */\n @Field(() => Boolean, {\n nullable: true,\n })\n hasPreviousPage?: boolean;\n\n /**\n * Whether there are more items in the list after the end cursor\n */\n @Field(() => Boolean, {\n nullable: true,\n })\n hasNextPage?: boolean;\n}\n\n/**\n * The edge type for cursor pagination\n */\nexport interface IEdge<T> {\n /**\n * The cursor for the item\n */\n cursor: string;\n\n /**\n * The item\n */\n node: T;\n}\n\nexport interface ICursorPaginated<T> {\n /**\n * The list of edges\n */\n edges: IEdge<T>[];\n\n /**\n * The pagination info\n */\n pageInfo: CursorPaginationPageInfo;\n}\n\n/**\n * Creates a new GraphQL object type with the name `Paginated${classRef.name}`\n * that implements the `ICursorPaginated` interface\n * @param classRef The class reference of the items\n *\n * @example Create PaginatedMessages type\n * ```ts\n * @ObjectType()\n * class PaginatedMessages extends CursorPaginated(Message) {}\n * ```\n */\n// eslint-disable-next-line func-style\nexport function CursorPaginated<T>(classRef: Type<T>): Type<ICursorPaginated<T>> {\n @ObjectType(`${classRef.name}Edge`)\n abstract class EdgeType implements IEdge<T> {\n /**\n * The cursor for the item\n */\n @Field(() => String, {\n description: 'The cursor for the item',\n })\n cursor!: string;\n\n /**\n * The item\n */\n @Field(() => classRef, {\n description: 'The item',\n })\n node!: T;\n }\n\n @ObjectType({\n isAbstract: true,\n })\n abstract class CursorPaginatedType implements ICursorPaginated<T> {\n /**\n * The list of edges\n */\n @Field(() => [EdgeType], {\n description: 'The list of edges',\n })\n edges!: EdgeType[];\n\n /**\n * The pagination info\n */\n @Field(() => CursorPaginationPageInfo, {\n description: 'The pagination info',\n })\n pageInfo!: CursorPaginationPageInfo;\n }\n\n return CursorPaginatedType as Type<ICursorPaginated<T>>;\n}\n\nexport enum CursorOrderBy {\n createdAt_ASC = 'createdAt_ASC',\n createdAt_DESC = 'createdAt_DESC',\n}\n","import {\n ArgsType,\n Field, Int,\n} from '@nestjs/graphql';\nimport { IsOptional, Min } from 'class-validator';\n\n@ArgsType()\nexport class CursorPaginationInput {\n /**\n * The amount of items to be requested per page from the start\n * @example\n * ```graphql\n * query {\n * messages(first: 3) {\n * edges {\n * cursor\n * node {\n * id\n * }\n * }\n * }\n * }\n * ```\n */\n @Field(() => Int, {\n nullable: true,\n })\n @Min(1)\n @IsOptional()\n first?: number;\n\n /**\n * The cursor to start the pagination\n * @example\n * ```graphql\n * query {\n * messages(first: 3, after: \"xxx\") {\n * edges {\n * cursor\n * node {\n * id\n * }\n * }\n * }\n * }\n * ```\n */\n @Field(() => String, {\n nullable: true,\n })\n after?: string;\n\n /**\n * The amount of items to be requested per page from the end\n * @example\n * ```graphql\n * query {\n * messages(last: 2) {\n * edges {\n * cursor\n * node {\n * id\n * }\n * }\n * }\n * }\n * ```\n */\n @Field(() => Int, {\n nullable: true,\n })\n @Min(1)\n @IsOptional()\n last?: number;\n\n /**\n * The cursor to end the pagination\n * @example\n * ```graphql\n * query {\n * messages(last: 2, before: \"xxx\") {\n * edges {\n * cursor\n * node {\n * id\n * }\n * }\n * }\n * }\n * ```\n */\n @Field(() => String, {\n nullable: true,\n })\n before?: string;\n}\n","import { snakeCase } from '@pcg/text-kit';\nimport { GraphQLResolveInfo } from 'graphql';\n\nimport { ListMeta } from '#/types/list-meta';\n\nimport { PAGINATION_DEFAULT_LIMIT } from '../constants.js';\nimport { requiresTotalCount, truncPaginationLimit } from '../tools.js';\nimport { OffsetErrorMessage, OffsetPaginationError } from './offset-pagination.exception.js';\nimport { OffsetPaginationInput } from './offset-pagination.input.js';\nimport { IOffsetPaginated } from './offset-pagination.types.js';\n\nexport type SortOrder = 'ASC' | 'DESC';\n\nexport interface SortParams<T> {\n /**\n * Original sort field name.\n * @example\n * const orderBy = 'createdAt_ASC';\n * const sort = extractSortParams(orderBy); // sort.fieldName = 'uploaderName';\n * if (sort.fieldName === uploaderName) {\n * ...\n * }\n */\n fieldName: T;\n\n /**\n * Database column name. Camel cased fieldName.\n * @example\n * const orderBy = 'createdAt_ASC';\n * const sort = extractSortParams(orderBy); // sort.columnName = 'created_at';\n * query.orderBy(`v.${sort.columnName}`, sort.direction);\n */\n columnName: string;\n\n /**\n * Sort direction (or order) (ASC | DESC)\n * @example\n * const orderBy = 'createdAt_ASC';\n * const sort = extractSortParams(orderBy); // sort.direction = 'ASC';\n * query.orderBy(`v.${sort.columnName}`, sort.direction);\n */\n direction: SortOrder;\n}\n\n/**\n * Extract sort field name and sort direction from orderBy string.\n * @example\n * const orderBy = 'createdAt_ASC';\n *\n * // sort.fieldName = 'createdAt', sort.direction = 'ASC'; sort.columnName = 'created_at';\n * const sort = extractSortParams(orderBy);\n */\nexport const extractSortParams = <T>(orderBy: string): SortParams<T> => {\n const slices = orderBy.split('_');\n\n if (slices.length !== 2) {\n throw new Error('Invalid orderBy argument');\n }\n\n return {\n fieldName: slices[0] as unknown as T,\n direction: slices[1] as unknown as SortOrder,\n columnName: snakeCase(slices[0]),\n };\n};\n\nexport interface OffsetPaginationOptions {\n limit?: number;\n offset?: number;\n\n /**\n * If true, total count will be calculated by additional SELECT COUNT.\n * @default true\n */\n needCountTotal: boolean;\n}\n\nexport interface CreateOffsetPaginationOptionsParams {\n maxLimit?: number;\n defaultLimit?: number;\n}\n\nexport const createOffsetPaginationOptions = (\n input: OffsetPaginationInput,\n info: GraphQLResolveInfo,\n params?: CreateOffsetPaginationOptionsParams,\n): OffsetPaginationOptions => {\n const options: OffsetPaginationOptions = {\n needCountTotal: requiresTotalCount(info),\n limit: params?.defaultLimit ?? PAGINATION_DEFAULT_LIMIT,\n };\n\n if (input.limit) {\n options.limit = truncPaginationLimit(Number(input.limit), params?.maxLimit);\n\n if (input.page) {\n options.offset = (Number(input.page) - 1) * options.limit;\n }\n }\n\n return options;\n};\n\nexport const offsetPaginatedOutput = <T>(items: T[], {\n limit,\n offset = 0,\n total = 0,\n}: ListMeta): IOffsetPaginated<T> => {\n if (!limit) {\n throw new OffsetPaginationError(OffsetErrorMessage.OUTPUT_LIMIT);\n }\n\n return {\n items,\n pageInfo: {\n totalPages: Math.ceil(total / limit),\n totalItems: total,\n page: (offset / limit) + 1,\n limit,\n },\n };\n};\n","import {\n ArgsType,\n Field, Int,\n} from '@nestjs/graphql';\n\nimport { PAGINATION_DEFAULT_LIMIT } from '../constants.js';\n\n@ArgsType()\nexport class OffsetPaginationInput {\n /**\n * the amount of items to be requested per page\n */\n @Field(() => Int, {\n description: 'the amount of items to be requested per page',\n defaultValue: PAGINATION_DEFAULT_LIMIT,\n nullable: true,\n })\n limit?: number;\n\n /**\n * @default 1\n * the page that is requested\n */\n @Field(() => Int, {\n defaultValue: 1,\n description: 'the page that is requested',\n })\n page?: number = 1;\n}\n\n","import { Type } from '@nestjs/common';\nimport {\n Field, Int,\n ObjectType,\n} from '@nestjs/graphql';\n\n@ObjectType()\nexport class OffsetPaginationPageInfo {\n /**\n * The total amount of pages\n * (total items / limit)\n */\n @Field(() => Int, {\n description: 'The total amount of pages (total items / limit)',\n })\n totalPages!: number;\n\n /**\n * The total amount of items\n */\n @Field(() => Int, {\n description: 'The total amount of items',\n })\n totalItems!: number;\n\n /**\n * The current page\n */\n @Field(() => Int, {\n description: 'The current page',\n })\n page!: number;\n\n /**\n * The amount of items to be requested per page\n */\n @Field(() => Int, {\n description: 'The amount of items to be requested per page',\n })\n limit!: number;\n}\n\nexport interface IOffsetPaginated<T> {\n items: T[];\n pageInfo: OffsetPaginationPageInfo;\n}\n\n/**\n * Creates a new GraphQL object type with the name `Paginated${classRef.name}`\n * that implements the `IOffsetPaginated` interface\n * @param classRef The class reference of the items\n *\n * @example Create PaginatedUsers type\n * ```ts\n * @ObjectType()\n * class PaginatedUsers extends OffsetPaginated(User) {}\n * ```\n */\n// eslint-disable-next-line func-style\nexport function OffsetPaginated<T>(classRef: Type<T>): Type<IOffsetPaginated<T>> {\n @ObjectType({\n isAbstract: true,\n })\n abstract class OffsetPaginatedType implements IOffsetPaginated<T> {\n /**\n * The items of the current page\n */\n @Field(() => [classRef], {\n description: 'The items of the current page',\n })\n items!: T[];\n\n /**\n * The pagination information\n * (total pages, total items, current page, limit)\n */\n @Field(() => OffsetPaginationPageInfo)\n pageInfo!: OffsetPaginationPageInfo;\n }\n\n return OffsetPaginatedType as Type<IOffsetPaginated<T>>;\n}\n","/**\n * Converts an object into a human-readable string representation.\n *\n * Takes an object and transforms it into a string where each key-value pair\n * is formatted as \"key JSON-value\" and all pairs are joined with \" and \".\n *\n * @param opts - The object to stringify\n * @returns A string representation of the object with entries joined by \" and \"\n *\n * @example\n * ```ts\n * stringifyOpts({ name: 'John', age: 30 })\n * // Returns: 'name \"John\" and age 30'\n * ```\n */\nexport const stringifyOpts = (opts: object) => {\n return Object.entries(opts)\n .map(([key, value]) => `${key} ${JSON.stringify(value)}`)\n .join(' and ');\n};\n","/**\n * Injection token for Winston logger module configuration options\n */\nexport const NESTKIT_LOGGER_MODULE_OPTIONS = 'NestKitLoggerModuleOptions';\n\n/**\n * Injection token for the Winston logger instance provider\n */\nexport const NESTKIT_WINSTON_LOGGER_PROVIDER = 'NestKitLogger';\n\n/**\n * Injection token for the main NestKit logger provider\n */\nexport const NESTKIT_LOGGER_PROVIDER = 'NestKitLogger';\n\n/**\n * Injection token for the NestJS system logger provider\n */\nexport const NESTKIT_SYSTEM_LOGGER_PROVIDER = 'NestKitSystemLogger';\n\n/**\n * Injection token for the logger factory provider\n */\nexport const NESTKIT_LOGGER_FACTORY_PROVIDER = 'NestKitLoggerFactory';\n",";\nimport { isObject } from '#/tools/is-object.js';\nimport { ApolloError } from '@apollo/client/core';\nimport { HttpException } from '@nestjs/common';\nimport { GraphQLError } from 'graphql';\nimport { LogEntry, Logger as WinstonLogger } from 'winston';\n\nimport { BaseServiceMethodContext } from '#/context';\nimport { NestError } from '#/errors/index.js';\nimport { HttpExceptionResponse } from '#/exceptions/http-exception-response';\n// import { getErrorMessages as getApolloErrorMessages } from '@deep/graphql-kit';\nimport type {\n DestructuredError,\n InfoObject, LoggerContext,\n WinstonLogLevel,\n} from '../logger.interfaces.js';\n\n/**\n * Logger with context for NestJS (from NestKit)\n */\nexport class Logger {\n constructor(\n private readonly winstonLogger: WinstonLogger,\n private context: LoggerContext = {\n },\n ) {}\n\n /**\n * Created child logger with specific context\n * @param context - object with scope, action and other data\n * @returns - new logger with context\n * @example\n * ```ts\n * class SomeService {\n * logger: Logger;\n *\n * constructor(\n * @InjectLoggerFactory() private readonly loggerFactory: LoggerFactory,\n * ) {\n * // Create logger for this service\n * this.winstonLogger = this.winstonLoggerFactory.create({\n * scope: SomeService.name,\n * })\n * }\n *\n * // Create child logger for some method\n * getOne(id: string) {\n * const logger = this.winstonLogger.child({\n * action: this.someMethod.name,\n * id,\n * });\n * }\n * ```\n */\n // https://www.npmjs.com/package/json-log#log2--logchilddata\n child(context: LoggerContext): Logger {\n return new Logger(this.winstonLogger, {\n ...this.context,\n ...context,\n });\n }\n\n /**\n * Created child logger for nest service method\n * Automatically parse service method context and add it to logger context\n * @param name - service method name\n * @param ctx - service method context\n * @param other - custom logger context\n * @returns - new logger with context\n */\n forMethod(name: string, ctx?: BaseServiceMethodContext, other?: LoggerContext) {\n const context: LoggerContext = {\n action: name,\n };\n\n if (ctx) {\n Object.assign(context, {\n requestId: ctx.requestId,\n });\n\n if (!ctx.user) {\n throw new Error('User is required for strict method context. Use guards: @UseGuards(JwtAuthGuard) or @UseGuards(GraphQLJwtAuthGuard)');\n }\n\n Object.assign(context, {\n requestId: ctx.requestId,\n userId: ctx.user.id,\n });\n }\n\n if (other) {\n Object.assign(context, other);\n }\n\n return this.child(context);\n }\n\n /**\n * Set data to logger context\n * @param key - context data key (ex: 'firstName')\n * @param value - context data value (ex: 'John')\n */\n setContext(key: string, value: unknown): void;\n setContext(context: LoggerContext): void;\n setContext(...args: unknown[]): void {\n if (\n args.length === 2 &&\n typeof args[0] === 'string' &&\n typeof args[1] !== 'undefined'\n ) {\n const key = args[0];\n const value = args[1];\n this.context[key] = value;\n } else {\n this.context = {\n ...this.context,\n ...(args[0] as LoggerContext),\n };\n }\n }\n\n /**\n * Get logger context data\n * @returns - logger context\n */\n getContext(): LoggerContext {\n return structuredClone(this.context);\n }\n\n /**\n * Write a 'log' level log.\n */\n log(entry: LogEntry): void;\n log(level: WinstonLogLevel, message: string, context?: LoggerContext): void;\n log(...args: unknown[]): void {\n if (isObject(args[0])) {\n this.winstonLogger.log({\n ...this.context,\n ...(args[0] as LogEntry),\n });\n } else {\n this.winstonLogger.log({\n level: args[0] as WinstonLogLevel,\n message: args[1] as string,\n ...this.context,\n ...(args[2] as LoggerContext),\n });\n }\n }\n\n /**\n * Write a 'info' level log.\n */\n info(message: string, context?: LoggerContext): void;\n info(infoObject: InfoObject): void;\n info(...args: unknown[]): void {\n if (typeof args[0] === 'string') {\n this.winstonLogger.info({\n message: args[0],\n ...this.context,\n ...(args[1] as LoggerContext),\n });\n } else {\n this.winstonLogger.info({\n ...this.context,\n ...(args[0] as InfoObject),\n });\n }\n }\n\n /**\n * Write an 'error' level log.\n */\n error(message: string, context?: LoggerContext): void;\n error(message: string, error: Error, context?: LoggerContext): void;\n error(error: NestError): void;\n error(error: Error, context?: LoggerContext): void;\n error(...args: unknown[]): void {\n if (args[0] instanceof NestError) {\n const err = args[0];\n this.winstonLogger.error({\n ...this.context,\n ...(args[1] as LoggerContext),\n ...this.destructureError(err),\n });\n } else if (args[0] instanceof Error) {\n const err = args[0];\n this.winstonLogger.error({\n ...this.context,\n ...(args[1] as LoggerContext),\n ...this.destructureError(err),\n });\n } else if (typeof args[0] === 'string' && args[1] instanceof Error) {\n const message = args[0];\n const err = args[1];\n this.winstonLogger.error({\n message: message,\n ...this.context,\n ...(args[2] as LoggerContext),\n error: this.destructureError(err),\n });\n } else if (typeof args[0] === 'string') {\n const message = args[0];\n this.winstonLogger.error({\n message,\n ...this.context,\n ...(args[1] as LoggerContext),\n });\n }\n }\n\n /**\n * Creates plain object from error\n * @see {@link DestructuredError}\n */\n protected destructureError(error: unknown): DestructuredError {\n const errorObject: DestructuredError = {\n };\n\n if (error instanceof NestError) {\n errorObject.message = error.message;\n errorObject.stack = error.stack;\n errorObject.context = error.context;\n errorObject.statusCode = error.httpStatusCode;\n errorObject.errorKey = error.key;\n if (error.cause instanceof Error) {\n errorObject.cause = this.destructureError(error.cause);\n }\n } else if (error instanceof Error) {\n errorObject.message = error.message;\n errorObject.stack = error.stack;\n }\n\n if (error instanceof HttpException) {\n errorObject.statusCode = error.getStatus();\n\n const response = error.getResponse() as HttpExceptionResponse;\n\n if (isObject(response)) {\n if (response.key) {\n errorObject.errorKey = response.key;\n }\n\n if (response.context) {\n if (!errorObject.context) {\n errorObject.context = {\n };\n }\n\n errorObject.context = {\n ...errorObject.context,\n ...response.context,\n };\n }\n\n if (response.error) {\n errorObject.cause = this.destructureError(response.error);\n }\n }\n\n return errorObject;\n } else if (error instanceof GraphQLError) {\n const ctx = JSON.parse(JSON.stringify({\n locations: error.locations,\n positions: error.positions,\n source: error.source,\n }));\n\n errorObject.context = {\n ...errorObject.context,\n ...ctx,\n };\n // } else if (error instanceof ApolloError) {\n // const messages = getApolloErrorMessages(error);\n // errorObject.message = messages.join('\\n');\n }\n\n return errorObject;\n }\n\n /**\n * Write a 'warn' level log.\n */\n warn(message: string, context?: LoggerContext): void;\n warn(infoObject: InfoObject): void;\n warn(...args: unknown[]): void {\n if (typeof args[0] === 'string') {\n this.winstonLogger.warn({\n message: args[0],\n ...this.context,\n ...(args[1] as LoggerContext),\n });\n } else {\n this.winstonLogger.warn({\n ...this.context,\n ...(args[0] as InfoObject),\n });\n }\n }\n\n /**\n * Write a 'debug' level log.\n */\n debug(message: string, context?: LoggerContext): void;\n debug(infoObject: InfoObject): void;\n debug(...args: unknown[]): void {\n if (typeof args[0] === 'string') {\n this.winstonLogger.debug({\n message: args[0],\n ...this.context,\n ...(args[1] as LoggerContext),\n });\n } else {\n this.winstonLogger.debug({\n ...this.context,\n ...(args[0] as InfoObject),\n });\n }\n }\n\n /**\n * Write a 'verbose' level log.\n */\n verbose(message: string, context?: LoggerContext): void;\n verbose(infoObject: InfoObject): void;\n verbose(...args: unknown[]): void {\n if (typeof args[0] === 'string') {\n this.winstonLogger.verbose({\n message: args[0],\n ...this.context,\n ...(args[1] as LoggerContext),\n });\n } else {\n this.winstonLogger.verbose({\n ...this.context,\n ...(args[0] as InfoObject),\n });\n }\n }\n}\n",";\n\nimport {\n ConsoleLogger, Inject, Injectable, LogLevel as NestLogLevel,\n} from '@nestjs/common';\nimport { isFunction, isPlainObject } from '@nestjs/common/utils/shared.utils';\n\nimport { NESTKIT_LOGGER_PROVIDER } from '../logger.constants.js';\nimport type { WinstonLogLevel } from '../logger.interfaces.js';\nimport { Logger } from './logger.js';\n\n@Injectable()\nexport class NestSystemLogger extends ConsoleLogger {\n @Inject(NESTKIT_LOGGER_PROVIDER) private readonly logger!: Logger;\n\n protected printMessages(messages: unknown[], context?: string | undefined, logLevel?: NestLogLevel | undefined): void {\n for (const message of messages) {\n this.logger.log(this.getWinstonLogLevel(logLevel), this.stringifyMessage(message), {\n scope: context,\n });\n }\n }\n\n protected stringifyMessage(message: unknown): string {\n // If the message is a function, call it and re-resolve its value.\n if (isFunction(message)) {\n return this.stringifyMessage(message());\n }\n\n if (isPlainObject(message) || Array.isArray(message)) {\n return JSON.stringify(\n message,\n (key, value) =>\n typeof value === 'bigint' ? value.toString() : value,\n 2,\n );\n }\n\n return String(message);\n }\n\n private getWinstonLogLevel(level?: NestLogLevel): WinstonLogLevel {\n switch (level) {\n case 'log':\n return 'info';\n\n case 'verbose':\n return 'verbose';\n\n case 'debug':\n return 'debug';\n\n case 'warn':\n return 'warn';\n\n case 'error':\n return 'error';\n\n default:\n return 'info';\n }\n }\n}\n","import type { LogLevel, LogMessage } from 'typeorm';\nimport { AbstractLogger } from 'typeorm/logger/AbstractLogger.js';\nimport type { LoggerOptions } from 'typeorm/logger/LoggerOptions.js';\n\nimport { type LoggerContext } from '../logger.interfaces.js';\nimport { Logger } from './logger.js';\n\nexport class TypeOrmLoggerOptions {\n enabled?: boolean;\n logger!: Logger;\n levels?: LoggerOptions;\n}\n\nexport class TypeOrmLogger extends AbstractLogger {\n logger: Logger;\n\n constructor(opts: TypeOrmLoggerOptions) {\n super(opts.enabled && opts.levels ? opts.levels : false);\n\n this.logger = opts.logger;\n }\n\n /**\n * Write log to specific output.\n */\n protected writeLog(\n level: LogLevel, // \"query\" | \"schema\" | \"error\" | \"warn\" | \"info\" | \"log\" | \"migration\";\n logMessage: LogMessage | LogMessage[],\n ) {\n const messages = this.prepareLogMessages(logMessage, {\n highlightSql: false,\n });\n\n for (const message of messages) {\n switch (message.type ?? level) {\n case 'log':\n case 'query':\n case 'schema-build':\n this.logger.debug(String(message.message), this.getCtx(message));\n break;\n\n case 'migration':\n case 'info':\n if (message.prefix) {\n this.logger.info(`${message.prefix} ${message.message}`, this.getCtx(message));\n } else {\n this.logger.info(String(message.message), this.getCtx(message));\n }\n break;\n\n case 'warn':\n case 'query-slow':\n if (message.prefix) {\n this.logger.warn(`${message.prefix} ${message.message}`, this.getCtx(message));\n } else {\n this.logger.warn(String(message.message), this.getCtx(message));\n }\n break;\n\n case 'error':\n case 'query-error':\n if (message.prefix) {\n this.logger.error(`[${message.prefix}] ${message.message}`, this.getCtx(message));\n } else {\n this.logger.error(String(message.message), this.getCtx(message));\n }\n break;\n }\n }\n }\n\n private getCtx(message: LogMessage): LoggerContext {\n const ctx = {\n ...message.additionalInfo,\n };\n\n if (Array.isArray(ctx.parameters)) {\n ctx.parameters = message.parameters;\n }\n\n return ctx;\n }\n}\n","import { Logger as WinstonLogger } from 'winston';\n\nimport { LoggerContext } from '../logger.interfaces.js';\nimport { Logger } from './logger.js';\nimport { TypeOrmLogger, TypeOrmLoggerOptions } from './typeorm-logger.js';\n\n/**\n * Logger factory for creating loggers with predefined context\n * Factory is singleton, so it keep original winston `Logger` instance\n * and is can be injected to any service\n */\nexport class LoggerFactory {\n constructor(\n private readonly winstonLogger: WinstonLogger,\n private context: LoggerContext = {\n },\n ) {}\n\n /**\n * Created new logger with specific context merge it with global context\n * @param context - specific action with scope, and other data\n * @returns - new logger with context\n * @example\n * ```ts\n * class SomeService {\n * logger: Logger;\n *\n * constructor(\n * @InjectLoggerFactory() private readonly loggerFactory: LoggerFactory,\n * ) {\n * // Create logger for this service\n * this.logger = this.loggerFactory.create({\n * scope: SomeService.name,\n * })\n * }\n * ```\n */\n create(context: LoggerContext = {\n }) {\n return new Logger(this.winstonLogger, {\n ...this.context,\n ...context,\n });\n }\n\n createTypeOrmLogger(opts: Omit<TypeOrmLoggerOptions, 'logger'>) {\n return new TypeOrmLogger({\n logger: this.create({\n scope: 'TypeORM',\n }),\n ...opts,\n });\n }\n}\n","import {\n Inject, Provider, Type,\n} from '@nestjs/common';\nimport {\n createLogger,\n Logger,\n LoggerOptions,\n} from 'winston';\n\nimport { LoggerFactory } from './classes/logger-factory.js';\nimport { NestSystemLogger } from './classes/nest-system-logger.js';\nimport {\n NESTKIT_LOGGER_FACTORY_PROVIDER,\n NESTKIT_LOGGER_MODULE_OPTIONS,\n NESTKIT_LOGGER_PROVIDER,\n NESTKIT_SYSTEM_LOGGER_PROVIDER,\n NESTKIT_WINSTON_LOGGER_PROVIDER,\n} from './logger.constants.js';\nimport {\n LoggerModuleAsyncOptions,\n LoggerModuleOptions,\n LoggerModuleOptionsFactory,\n} from './logger.interfaces.js';\n\n/**\n * Syntax sugar. Injects logger via NESTKIT_LOGGER_PROVIDER token\n * @example\n * ```ts\n * class SomeService {\n * constructor(\n * @InjectLogger() private readonly logger: Logger\n * ) {}\n * ```\n */\nexport const InjectLogger = () => Inject(NESTKIT_LOGGER_PROVIDER);\n\n/**\n * Syntax sugar. Injects winston logger factory by WINSTON_MODULE_FACTORY_PROVIDER token\n * @example\n * ```ts\n * class SomeService {\n * constructor(\n * @InjectLoggerFactory() private readonly loggerFactory: LoggerFactory\n * ) {}\n * ```\n */\nexport const InjectLoggerFactory = () => Inject(NESTKIT_LOGGER_FACTORY_PROVIDER);\n\nexport const createNestLogger = (\n loggerOpts: LoggerModuleOptions,\n): Logger => {\n return new Logger(createLogger(loggerOpts));\n};\n\nexport const createLoggerProviders = (\n loggerOpts: LoggerModuleOptions,\n): Provider[] => {\n return [\n {\n provide: NESTKIT_WINSTON_LOGGER_PROVIDER,\n useFactory: () => createLogger(loggerOpts),\n },\n {\n provide: NESTKIT_LOGGER_PROVIDER,\n useFactory: (logger: Logger) => {\n return new Logger(logger);\n },\n inject: [NESTKIT_WINSTON_LOGGER_PROVIDER],\n },\n {\n provide: NESTKIT_SYSTEM_LOGGER_PROVIDER,\n useClass: NestSystemLogger,\n },\n {\n provide: NESTKIT_LOGGER_FACTORY_PROVIDER,\n useFactory: (logger: Logger) => {\n return new LoggerFactory(logger);\n },\n inject: [NESTKIT_WINSTON_LOGGER_PROVIDER],\n },\n ];\n};\n\nexport const createLoggerAsyncProviders = (\n options: LoggerModuleAsyncOptions,\n): Provider[] => {\n const providers: Provider[] = [\n {\n provide: NESTKIT_WINSTON_LOGGER_PROVIDER,\n useFactory: (loggerOpts: LoggerOptions) => createLogger(loggerOpts),\n inject: [NESTKIT_LOGGER_MODULE_OPTIONS],\n },\n {\n provide: NESTKIT_LOGGER_PROVIDER,\n useFactory: (logger: Logger) => {\n return new Logger(logger);\n },\n inject: [NESTKIT_WINSTON_LOGGER_PROVIDER],\n },\n {\n provide: NESTKIT_SYSTEM_LOGGER_PROVIDER,\n useClass: NestSystemLogger,\n },\n {\n provide: NESTKIT_LOGGER_FACTORY_PROVIDER,\n useFactory: (logger: Logger) => {\n return new LoggerFactory(logger);\n },\n inject: [NESTKIT_WINSTON_LOGGER_PROVIDER],\n },\n ];\n\n if (options.useClass) {\n const useClass = options.useClass as Type<LoggerModuleOptionsFactory>;\n providers.push(\n ...[\n {\n provide: NESTKIT_LOGGER_MODULE_OPTIONS,\n useFactory: async (optionsFactory: LoggerModuleOptionsFactory) =>\n await optionsFactory.createLoggerModuleOptions(),\n inject: [useClass],\n },\n {\n provide: useClass,\n useClass,\n },\n ],\n );\n }\n\n if (options.useFactory) {\n providers.push({\n provide: NESTKIT_LOGGER_MODULE_OPTIONS,\n useFactory: options.useFactory,\n inject: options.inject || [],\n });\n }\n\n return providers;\n};\n","import {\n DynamicModule, Global, LoggerService, Module,\n} from '@nestjs/common';\n\nimport {\n LoggerModuleAsyncOptions,\n LoggerModuleOptions,\n} from './logger.interfaces.js';\nimport {\n createLoggerAsyncProviders,\n createLoggerProviders,\n createNestLogger,\n} from './logger.providers.js';\n\n@Global()\n@Module({\n})\nexport class LoggerModule {\n public static forRoot(options: LoggerModuleOptions): DynamicModule {\n const providers = createLoggerProviders(options);\n\n return {\n module: LoggerModule,\n providers: providers,\n exports: providers,\n };\n }\n\n public static forRootAsync(\n options: LoggerModuleAsyncOptions,\n ): DynamicModule {\n const providers = createLoggerAsyncProviders(options);\n\n return {\n module: LoggerModule,\n imports: options.imports,\n providers: providers,\n exports: providers,\n } as DynamicModule;\n }\n\n public static createLogger(options: LoggerModuleOptions): LoggerService {\n return createNestLogger(options);\n }\n}\n","import { LogLevel } from '@nestjs/common';\nimport clc from 'cli-color';\nimport bare from 'cli-color/bare';\nimport { Format } from 'logform';\nimport { format } from 'winston';\nimport { DestructuredError } from './logger.interfaces.js';\n\nconst nestLikeColorScheme: Record<string, bare.Format> = {\n log: clc.greenBright,\n info: clc.greenBright,\n error: clc.red,\n warn: clc.yellow,\n debug: clc.magentaBright,\n verbose: clc.cyanBright,\n};\n\n/**\n * Options for nest-like formatting\n */\nexport interface CreatePrettyMessageOptions {\n /**\n * Application name\n * @example 'Jetstream'\n */\n appName: string;\n\n /**\n * Log level (info, error, warn, debug, verbose, log)\n * @example 'info'\n */\n level: LogLevel;\n\n /**\n * Timestamp in ISO 8601 format\n * @example '2021-06-10T16:33:42.000Z'\n */\n timestamp: string;\n\n /**\n * Message text\n * @example 'Failed to create cloudlfare output'\n */\n message: string;\n\n /**\n * Scope where the message was logged\n * @example 'VideoService'\n */\n scope?: string;\n\n /**\n * Action where the message was logged\n * @example 'createOutput'\n */\n action?: string;\n\n /**\n * Error stack from Error object (`Error.stack`)\n */\n stack?: string;\n\n /**\n * Message context (additional data)\n * @example { id: 'xxx' }\n */\n context: Record<string, unknown>;\n\n /**\n * Error key from 'enum'\n * @example 'NST_SA_EMAIL_NOT_UNIQUE'\n */\n errorKey?: string;\n\n /**\n * HTTP status code\n * @example '400'\n */\n statusCode?: string;\n\n /**\n * Parent path for child errors\n * @example 'MainService.start --> VideoService.createOutput'\n */\n parentPath?: string;\n\n /**\n * Error cause\n */\n cause?: DestructuredError;\n\n /**\n * Recursion depth\n * @example 0\n */\n deep?: number;\n}\n\n/**\n * Create a pretty message for the logger with nest-like formatting\n * Use recursion to print child errors\n * @param vars - message variables\n * @returns - formatted message\n * @example\n * [Jetstream] - 6/10/2022, 4:33:42 PM ERROR [VideoService.createOutput] Failed to create cloudlfare output\n */\nexport const createPrettyMessage = ({\n appName,\n action,\n level,\n timestamp,\n message,\n scope,\n stack,\n errorKey,\n // statusCode,\n context,\n parentPath,\n cause,\n deep = 0,\n}: CreatePrettyMessageOptions): string => {\n if ('undefined' !== typeof timestamp) {\n // Only format the timestamp to a locale representation if it's ISO 8601 format. Any format\n // that is not a valid date string will throw, just ignore it (it will be printed as-is).\n try {\n if (timestamp === new Date(timestamp).toISOString()) {\n timestamp = new Date(timestamp).toLocaleString();\n }\n } catch {\n // Ignore\n }\n }\n\n const color =\n nestLikeColorScheme[level] || ((text: string): string => text);\n\n if (errorKey) {\n message += ` [${errorKey}]`;\n }\n\n // [Nest] 9539 - 05/26/2022, 9:00:29 AM LOG [InstanceLoader] OrganizationsModule dependencies initialized +1ms\n\n const sAppName = color(`[${appName}]`);\n const sTimestamp = timestamp ? `${timestamp} ` : '';\n const sLevel = color(level.toUpperCase());\n\n let path = '';\n let sPath = '';\n if ('undefined' !== typeof scope && 'undefined' !== typeof action) {\n path = `${scope}.${action}`;\n } else if ('undefined' !== typeof scope) {\n path = scope;\n } else if ('undefined' !== typeof action) {\n path = action;\n }\n\n // SyncWorker.sync --> CloudflareApi.createOutput]\n if (path && parentPath) {\n path = `${parentPath} --> ${path}`;\n } else if (parentPath) {\n path = parentPath;\n }\n\n if (path) {\n sPath = clc.yellow(` [${path}]`);\n }\n\n // const sDeep = color(printDeep(deep));\n const sMessage = color(` ${message}`);\n const sStack = 'undefined' !== typeof stack ? color(`\\n ${stack}`) : '';\n\n let sRecursion = '';\n if (cause) {\n const {\n action,\n scope,\n ...context\n } = cause?.context || {\n };\n\n /**\n * Print child errors recursively\n */\n sRecursion = cause ? `\\n${createPrettyMessage({\n appName,\n action,\n level,\n timestamp,\n message: cause.message ?? message,\n scope,\n stack: cause.stack,\n errorKey: cause.errorKey,\n context,\n parentPath: path,\n cause: cause.cause,\n deep: deep + 1,\n })}` : '';\n }\n\n const sContext = context && Object.keys(context).length > 0 ? color(` -- ${JSON.stringify(context, null, 2)}`) : '';\n\n // sAppName sTimestamp sLevel sPath sMessage\n // [Jetstream] - 6/10/2022, 4:33:42 PM ERROR [VideoService.createOutput] Failer to create cloudlfare output\n return `${sAppName} - ${sTimestamp} ${sLevel}${sPath}${sMessage}${sStack}${sContext}${sRecursion}`;\n};\n\n/**\n * Create a nest-like console format\n * @param appName - App name (Jetstream, WHATSBIBLE, etc.)\n * @returns Winston format\n */\nexport const nestLikeConsoleFormat = (appName = 'Nest'): Format =>\n format.printf(\n ({\n level,\n timestamp,\n message,\n scope,\n action,\n // ms,\n stack,\n errorKey,\n statusCode,\n error: cause,\n ...context\n }) => {\n return createPrettyMessage({\n appName,\n action,\n level: level as LogLevel,\n timestamp,\n message,\n stack,\n context,\n scope,\n errorKey,\n statusCode,\n cause,\n deep: 0,\n } as CreatePrettyMessageOptions);\n },\n );\n","import { Inject } from '@nestjs/common';\nimport { getConfigToken, registerAs } from '@nestjs/config';\nimport * as winston from 'winston';\n\nimport { nestLikeConsoleFormat } from '#/logger';\n\n/**\n * NestJS injection token for Logger config\n */\nexport const LOGGER_CONFIG_TOKEN = 'LOGGER_CONFIG_TOKEN';\n\nexport const InjectLoggerConfig = () => Inject(getConfigToken(LOGGER_CONFIG_TOKEN));\n\nexport interface CreateLoggerConfigOptions {\n appName: string;\n useConsole?: boolean;\n consoleLevel?: winston.LoggerOptions['level'];\n transports?: winston.transport[];\n}\n/**\n * Create NestJS Logger config\n * @example\n * ```ts\n * // src/config/index.ts\n *\n * import { createLoggerConfig } from '#/dist/configs';\n *\n * export const LoggerConfig = createLoggerConfig();\n * ```\n */\nexport const createLoggerConfig = (opts: CreateLoggerConfigOptions) => {\n return registerAs(LOGGER_CONFIG_TOKEN, () => {\n const format = [\n winston.format.splat(),\n winston.format.timestamp(),\n nestLikeConsoleFormat(opts.appName),\n ];\n\n const winstonOptions: winston.LoggerOptions = {\n transports: [],\n };\n\n if (!Array.isArray(winstonOptions.transports)) {\n return winstonOptions;\n }\n\n if (opts.useConsole) {\n winstonOptions.transports.push(\n new winston.transports.Console({\n level: opts.consoleLevel ?? 'debug',\n format: winston.format.combine(...format),\n }),\n );\n }\n\n if (opts.transports) {\n winstonOptions.transports.push(...opts.transports);\n }\n\n return winstonOptions;\n });\n};\n","import { OnModuleInit } from '@nestjs/common';\n\nimport {\n InjectLoggerFactory, Logger, LoggerFactory,\n} from '#/logger';\n\n/**\n * Abstract service class for NestJS services\n * Automatically initializes logger with the constructor name as scope\n */\nexport abstract class NestJsService implements OnModuleInit {\n @InjectLoggerFactory()\n protected readonly loggerFactory!: LoggerFactory;\n\n protected logger!: Logger;\n\n /**\n * Initialize logger using the constructor name as scope\n */\n onModuleInit() {\n this.logger = this.loggerFactory.create({\n scope: this.constructor.name,\n });\n }\n}\n","import { Inject, Type } from '@nestjs/common';\nimport { InjectDataSource } from '@nestjs/typeorm';\nimport {\n BaseEntity, DataSource, FindOptionsWhere, Repository,\n SelectQueryBuilder,\n} from 'typeorm';\n\nimport { IdService } from '#/modules/id';\nimport { MaybeNull } from '#/types/maybe';\n\nimport { BaseServiceMethodContext } from '#/context/service-method-context.js';\nimport { BadRequestError } from '#/errors/bad-request.error.js';\nimport { NotFoundError } from '#/errors/not-found.error.js';\nimport { extractSortParams } from '#/pagination';\nimport { stringifyOpts } from '#/tools/stringify-opts';\nimport { NestJsService } from './nestjs-service.js';\n\nexport interface NestJsResourceFilter {\n ids?: string[];\n search?: string;\n}\n\nexport interface GetOneByOptions {\n id?: string;\n}\n\nexport interface NestJsResourceServiceParams<\n T extends BaseEntity,\n GOBO extends GetOneByOptions,\n F extends NestJsResourceFilter,\n O\n> {\n entity: {\n type: Type<T>;\n idPrefix: string;\n alias: string;\n };\n types: {\n getByOpts: GOBO;\n filter: F;\n orderBy: O;\n };\n}\n\nexport abstract class NestJsResourceService<\n T extends BaseEntity,\n GOBO extends GetOneByOptions,\n F extends NestJsResourceFilter,\n O\n> extends NestJsService {\n constructor(private readonly params: NestJsResourceServiceParams<T, GOBO, F, O>) {\n super();\n }\n\n @Inject(IdService) protected readonly idService!: IdService;\n @InjectDataSource() protected readonly dataSource!: DataSource;\n\n public get repository(): Repository<T> {\n return this.dataSource.getRepository(this.params.entity.type);\n }\n\n protected generateEntityId(): string {\n return this.idService.generateEntityId(this.params.entity.idPrefix);\n }\n\n get entityName(): string {\n return this.params.entity.type.name;\n }\n\n get alias(): string {\n return this.params.entity.alias;\n }\n\n async getOneBy<GOBO extends GetOneByOptions>(opts: GOBO): Promise<MaybeNull<T>> {\n const logger = this.logger.child({\n action: this.getOneBy.name,\n ...opts as Record<string, unknown>,\n });\n\n if (Object.values(opts).filter((v) => v).length === 0) {\n throw new BadRequestError({\n message: 'Empty options',\n key: 'NST_GET_ONE_BY_EMPTY_OPTIONS',\n context: logger.getContext(),\n });\n }\n\n return await this.repository.findOneBy({\n ...opts,\n } as FindOptionsWhere<T>);\n }\n\n async getOne(id: string): Promise<MaybeNull<T>> {\n return await this.getOneBy({\n id,\n });\n }\n\n async getOneByOrFail<GOBO extends GetOneByOptions>(opts: GOBO, ctx: BaseServiceMethodContext): Promise<T> {\n const logger = this.logger.forMethod(this.getOneByOrFail.name, ctx, {\n ...opts as Record<string, unknown>,\n });\n\n const item = await this.getOneBy(opts);\n\n if (!item) {\n throw new NotFoundError({\n message: `${this.entityName} with ${stringifyOpts(opts)} not found`,\n key: 'NST_CHANNELS_NOT_FOUND',\n context: logger.getContext(),\n });\n }\n\n return item;\n }\n\n protected async getOneOrFail(id: string, ctx: BaseServiceMethodContext): Promise<T> {\n return await this.getOneByOrFail({\n id,\n }, ctx);\n }\n\n protected applyFilterToQuery(query: SelectQueryBuilder<T>, filter?: F): void {\n if (!filter) {\n return;\n }\n\n if (filter.search) {\n query.andWhere(`${this.alias}.title LIKE :search`, {\n search: `%${filter.search}%`,\n });\n }\n\n return;\n }\n\n protected applySearchToQuery(query: SelectQueryBuilder<T>, search?: string): void {\n if (!search) {\n return;\n }\n\n query.andWhere(`${this.alias}.title LIKE :search`, {\n search: `%${search}%`,\n });\n\n return;\n }\n\n protected applyOrderByToQuery(query: SelectQueryBuilder<T>, orderBy: O): void {\n const sort = extractSortParams(orderBy as string);\n\n query.addOrderBy(`${this.alias}.${sort.columnName}`, sort.direction);\n }\n}\n","import {\n pluralToSingular,\n singularToPlural,\n snakeCase,\n} from '@pcg/text-kit';\nimport {\n DefaultNamingStrategy, NamingStrategyInterface, Table,\n} from 'typeorm';\n\n/**\n * Snake case naming strategy for typeorm.\n * Determines table and column names from class and property names.\n */\nexport class SnakeNamingStrategy\n extends DefaultNamingStrategy\n implements NamingStrategyInterface {\n /**\n * Create a table name from a class name.\n * @param className - The class name of the entity\n * @param customName - The custom table name\n * @returns The table name\n * @example Create table name from class name\n * ```ts\n * @Entity()\n * class User {}\n * // returns 'users'\n *\n * @Entity('custom_table_name')\n * class User {}\n * // returns 'custom_table_name'\n *\n *```\n */\n tableName(className: string, customName?: string): string {\n if (customName) {\n return customName;\n }\n\n const snakeClassName = snakeCase(className);\n\n // if many-to-many table, use the table name as is\n if (snakeClassName.includes('_to_')) {\n return snakeClassName;\n }\n\n const parts = snakeClassName.split('_');\n if (parts.length === 1) {\n return singularToPlural(snakeClassName);\n }\n\n return parts\n .map((name, i) => (i === 0 ? name : singularToPlural(name)))\n .join('_');\n }\n\n /**\n * Create a column name from a property name.\n * @param propertyName - The property name of the entity\n * @param customName - The custom column name\n * @param embeddedPrefixes - The embedded prefixes\n * @returns The table column name\n * @example Create column name from property name\n * ```ts\n * @Entity()\n * class User {\n * @Column()\n * firstName: string; // returns 'first_name'\n *\n * @Column('custom_last_name')\n * lastName: string; // returns 'custom_last_name'\n * }\n * ```\n */\n columnName(\n propertyName: string,\n customName?: string,\n embeddedPrefixes: string[] = [],\n ): string {\n return (\n snakeCase(embeddedPrefixes.concat('').join('_')) +\n (customName ? customName : snakeCase(propertyName))\n );\n }\n\n // ???\n relationName(propertyName: string): string {\n return snakeCase(propertyName);\n }\n\n // ???\n joinColumnName(relationName: string, referencedColumnName: string): string {\n return snakeCase(relationName + '_' + referencedColumnName);\n }\n\n /**\n * Create join table name for many-to-many relations.\n * @returns join table name\n * @example\n * ```ts\n * @Entity()\n * class Post {\n * @ManyToMany(() => Theme) // post_to_theme\n * themes: Theme[];\n * }\n *\n */\n joinTableName(firstTableName: string, secondTableName: string): string {\n return snakeCase(\n pluralToSingular(firstTableName) +\n '_to_' +\n pluralToSingular(secondTableName),\n );\n }\n\n // ???\n joinTableColumnName(\n tableName: string,\n propertyName: string,\n columnName?: string,\n ): string {\n return snakeCase(\n pluralToSingular(tableName) + '_' + (columnName ? columnName : propertyName),\n );\n }\n\n eagerJoinRelationAlias(alias: string, propertyPath: string): string {\n return alias + '__' + propertyPath.replace('.', '_');\n }\n\n /**\n * Create a primary key name.\n * @param tableOrName - The table or table name\n * @param columnNames - The column names\n * @returns The primary key name\n * @example\n * ```ts\n * @Entity()\n * class User {\n * @PrimaryColumn()\n * id: string;\n * }\n *\n * // returns 'pk_users__id'\n */\n primaryKeyName(tableOrName: Table | string, columnNames: string[]): string {\n tableOrName =\n typeof tableOrName === 'string' ? tableOrName : tableOrName.name;\n\n let name = tableOrName;\n for (const column of columnNames) {\n name += `__${column}`;\n }\n\n name = this.simplifyName(name);\n\n return `pk_${name}`;\n }\n\n /**\n * Create a foreign key name.\n * @param tableOrName - The table or table name\n * @param columnNames - The column names\n * @returns The foreign key name\n * @example\n * ```ts\n * @Entity()\n * class User {\n * @PrimaryColumn()\n * id: string;\n * }\n * @Entity()\n * class Post {\n * @PrimaryColumn()\n * id: string;\n *\n * @ManyToOne(() => User, user => user.posts)\n * user: User;\n * }\n *\n * // returns 'fk_posts__user_id__users__id'\n * ```\n */\n foreignKeyName(tableOrName: Table | string, columnNames: string[]): string {\n tableOrName =\n typeof tableOrName === 'string' ? tableOrName : tableOrName.name;\n\n let name = tableOrName;\n for (const column of columnNames) {\n name += `__${column}`;\n }\n\n name = this.simplifyName(name);\n\n return `fk_${name}`;\n }\n\n /**\n * Create an index name.\n * @param tableOrName - The table or table name\n * @param columnNames - The column names\n * @returns The index name\n * @example\n * ```ts\n * @Entity()\n * class User {\n * @Index()\n * @Column()\n * email: string;\n * }\n * // returns 'idx_users__email'\n * ```\n */\n indexName(tableOrName: Table | string, columnNames: string[]): string {\n tableOrName =\n typeof tableOrName === 'string' ? tableOrName : tableOrName.name;\n\n let name = tableOrName;\n for (const column of columnNames) {\n name += `__${column}`;\n }\n\n name = this.simplifyName(name);\n\n return `idx_${name}`;\n }\n\n /**\n * Create a unique constraint name.\n * @param tableOrName - The table or table name\n * @param columnNames - The column names\n * @returns The unique constraint name\n * @example\n * ```ts\n * @Entity()\n * class User {\n * @Unique()\n * @Column()\n * email: string;\n * }\n * // returns 'uq_users__email'\n * ```\n */\n uniqueConstraintName(\n tableOrName: Table | string,\n columnNames: string[],\n ): string {\n tableOrName =\n typeof tableOrName === 'string' ? tableOrName : tableOrName.name;\n\n let name = tableOrName;\n for (const column of columnNames) {\n name += `__${column}`;\n }\n\n name = this.simplifyName(name);\n\n return `uq_${name}`;\n }\n\n private simplifyName(name: string): string {\n if (name.length > 50) {\n const pieces = name.split('__');\n\n const simplified = pieces.map((piece) => {\n if (piece.includes('_to_')) {\n return piece.split('_').map((p) => p[0]).join('');\n }\n\n return piece;\n });\n\n return simplified.join('__');\n }\n\n return name;\n }\n}\n","import { Inject } from '@nestjs/common';\nimport { getConfigToken, registerAs } from '@nestjs/config';\nimport { Type } from 'class-transformer';\nimport {\n IsBoolean,\n IsNumber, IsOptional, IsString,\n} from 'class-validator';\nimport { PostgresConnectionOptions } from 'typeorm/driver/postgres/PostgresConnectionOptions.js';\n\nimport { SnakeNamingStrategy } from '#/db/snake-naming.strategy';\nimport { validateEnv } from '#/tools/env';\nimport fg from 'fast-glob';\n\n/**\n * NestJS injection token for postgres db config\n */\nexport const DB_CONFIG_TOKEN = 'DB_CONFIG_TOKEN';\n\nexport const InjectDbConfig = () => Inject(getConfigToken(DB_CONFIG_TOKEN));\n\n/**\n * Postgres db config environment variables\n */\nclass DbConfigEnvironmentVariables {\n /**\n * Postgres host\n * @example\n * ```yaml\n * POSTGRES_HOST: 'localhost'\n * ```\n */\n @IsString()\n POSTGRES_HOST!: string;\n\n /**\n * Postgres port\n * @example\n * ```yaml\n * POSTGRES_PORT: 5432\n * ```\n */\n @Type(() => Number)\n @IsNumber()\n POSTGRES_PORT!: number;\n\n /**\n * Postgres user\n * @example\n * ```yaml\n * POSTGRES_USER: 'app'\n * ```\n */\n @IsString()\n POSTGRES_USER!: string;\n\n /**\n * Postgres password\n * @example\n * ```yaml\n * POSTGRES_PASS: 'qwerty'\n * ```\n */\n @IsString()\n POSTGRES_PASS!: string;\n\n /**\n * Postgres database name\n * @example\n * ```yaml\n * POSTGRES_DB: 'jetstream'\n * ```\n */\n @IsString()\n POSTGRES_DB!: string;\n\n /**\n * Enable postgres logging\n * @example\n * ```yaml\n * POSTGRES_IS_LOGGING_ENABLED: \"true\"\n * ```\n */\n @Type(() => Boolean)\n @IsOptional()\n @IsBoolean()\n POSTGRES_IS_LOGGING_ENABLED?: boolean;\n}\n\n/**\n * Postgres Database Config\n */\nexport const createDbConfig = (opts?: Partial<PostgresConnectionOptions>) => {\n return registerAs(DB_CONFIG_TOKEN, (): PostgresConnectionOptions => {\n const env = validateEnv(DbConfigEnvironmentVariables);\n\n const baseEntities = [\n 'dist/**/*.entity.js',\n 'node_modules/@deep/nest-kit/dist/modules/**/*.entity.js',\n ];\n\n const entities = [\n ...(opts?.entities as string[] ?? baseEntities),\n ];\n\n return {\n type: 'postgres',\n logging: env.POSTGRES_IS_LOGGING_ENABLED,\n host: env.POSTGRES_HOST,\n port: env.POSTGRES_PORT,\n username: env.POSTGRES_USER,\n password: env.POSTGRES_PASS,\n database: env.POSTGRES_DB,\n synchronize: false,\n migrations: ['dist/migrations/*.js'],\n subscribers: ['dist/**/*.entity-subscriber.js'],\n migrationsRun: true,\n namingStrategy: new SnakeNamingStrategy(),\n ...opts,\n entities: fg.sync(entities),\n };\n });\n};\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nexport type Constructor = new (...args: any[]) => any\n\ntype MixinFunction<TInput, TOutput> = (source: TInput) => TOutput\n\n/**\n * Compose a class by applying mixins to it.\n * The code is inspired by https://justinfagnani.com/2015/12/21/real-mixins-with-javascript-classes/, its\n * just that I have added the support for static types too.\n *\n * @param baseClass - The base class to extend\n * @param mixins - One or more mixin functions to apply sequentially\n * @returns The composed class with all mixins applied\n */\nexport function compose<TBase extends Constructor, TResult1>(\n baseClass: TBase,\n mixin1: MixinFunction<TBase, TResult1>\n): TResult1\nexport function compose<TBase extends Constructor, TResult1, TResult2>(\n baseClass: TBase,\n mixin1: MixinFunction<TBase, TResult1>,\n mixin2: MixinFunction<TResult1, TResult2>\n): TResult2\nexport function compose<TBase extends Constructor, TResult1, TResult2, TResult3>(\n baseClass: TBase,\n mixin1: MixinFunction<TBase, TResult1>,\n mixin2: MixinFunction<TResult1, TResult2>,\n mixin3: MixinFunction<TResult2, TResult3>\n): TResult3\nexport function compose<TBase extends Constructor, TResult1, TResult2, TResult3, TResult4>(\n baseClass: TBase,\n mixin1: MixinFunction<TBase, TResult1>,\n mixin2: MixinFunction<TResult1, TResult2>,\n mixin3: MixinFunction<TResult2, TResult3>,\n mixin4: MixinFunction<TResult3, TResult4>\n): TResult4\nexport function compose<TBase extends Constructor, TResult1, TResult2, TResult3, TResult4, TResult5>(\n baseClass: TBase,\n mixin1: MixinFunction<TBase, TResult1>,\n mixin2: MixinFunction<TResult1, TResult2>,\n mixin3: MixinFunction<TResult2, TResult3>,\n mixin4: MixinFunction<TResult3, TResult4>,\n mixin5: MixinFunction<TResult4, TResult5>\n): TResult5\nexport function compose<TBase extends Constructor, TResult1, TResult2, TResult3, TResult4, TResult5, TResult6>(\n baseClass: TBase,\n mixin1: MixinFunction<TBase, TResult1>,\n mixin2: MixinFunction<TResult1, TResult2>,\n mixin3: MixinFunction<TResult2, TResult3>,\n mixin4: MixinFunction<TResult3, TResult4>,\n mixin5: MixinFunction<TResult4, TResult5>,\n mixin6: MixinFunction<TResult5, TResult6>\n): TResult6\nexport function compose<TBase extends Constructor, TResult1, TResult2, TResult3, TResult4, TResult5, TResult6, TResult7>(\n baseClass: TBase,\n mixin1: MixinFunction<TBase, TResult1>,\n mixin2: MixinFunction<TResult1, TResult2>,\n mixin3: MixinFunction<TResult2, TResult3>,\n mixin4: MixinFunction<TResult3, TResult4>,\n mixin5: MixinFunction<TResult4, TResult5>,\n mixin6: MixinFunction<TResult5, TResult6>,\n mixin7: MixinFunction<TResult6, TResult7>\n): TResult7\nexport function compose<TBase extends Constructor, TResult1, TResult2, TResult3, TResult4, TResult5, TResult6, TResult7, TResult8>(\n baseClass: TBase,\n mixin1: MixinFunction<TBase, TResult1>,\n mixin2: MixinFunction<TResult1, TResult2>,\n mixin3: MixinFunction<TResult2, TResult3>,\n mixin4: MixinFunction<TResult3, TResult4>,\n mixin5: MixinFunction<TResult4, TResult5>,\n mixin6: MixinFunction<TResult5, TResult6>,\n mixin7: MixinFunction<TResult6, TResult7>,\n mixin8: MixinFunction<TResult7, TResult8>\n): TResult8\nexport function compose<TBase extends Constructor, TResult1, TResult2, TResult3, TResult4, TResult5, TResult6, TResult7, TResult8, TResult9>(\n baseClass: TBase,\n mixin1: MixinFunction<TBase, TResult1>,\n mixin2: MixinFunction<TResult1, TResult2>,\n mixin3: MixinFunction<TResult2, TResult3>,\n mixin4: MixinFunction<TResult3, TResult4>,\n mixin5: MixinFunction<TResult4, TResult5>,\n mixin6: MixinFunction<TResult5, TResult6>,\n mixin7: MixinFunction<TResult6, TResult7>,\n mixin8: MixinFunction<TResult7, TResult8>,\n mixin9: MixinFunction<TResult8, TResult9>\n): TResult9\nexport function compose<TBase extends Constructor, TMixin extends MixinFunction<TBase, TBase>>(\n baseClass: TBase,\n ...mixins: TMixin[]\n) {\n return mixins.reduce((currentClass, mixin) => mixin(currentClass), baseClass);\n}\n","/**\n * Converts a number or string value to a BigInt, preserving null and undefined values.\n *\n * @param value - The value to convert. Can be a number, string, undefined, or null.\n * @returns The converted BigInt value, or the original value if it was null or undefined.\n *\n * @example\n * ```typescript\n * convertToBigInt(123) // returns 123n\n * convertToBigInt(\"456\") // returns 456n\n * convertToBigInt(null) // returns null\n * convertToBigInt(undefined) // returns undefined\n * ```\n *\n * @throws {RangeError} Throws when the input cannot be converted to a valid BigInt.\n */\nexport const convertToBigInt = (value: number | string | undefined | null): bigint | undefined | null => {\n if (value === null) {\n return value;\n }\n\n if (typeof value === 'undefined') {\n return value;\n }\n\n return BigInt(value);\n};\n","import { ObjectLiteral, SelectQueryBuilder } from 'typeorm';\n\n/**\n * Returns total count of items with typeorm query\n * @param query - typeorm query builder\n * @returns total count of items\n */\n/**\n * Returns total count of items with typeorm query\n * @param query - typeorm query builder\n * @returns total count of items\n */\nexport const fetchTotalWithQuery = async <T extends ObjectLiteral>(\n query: SelectQueryBuilder<T>,\n): Promise<number> => {\n const totalQueryBuilder = query.clone();\n\n // Clear any pagination settings\n totalQueryBuilder\n .offset(undefined)\n .limit(undefined)\n .skip(undefined)\n .take(undefined)\n .orderBy();\n\n const hasDistinctOn = totalQueryBuilder.expressionMap.selectDistinctOn && totalQueryBuilder.expressionMap.selectDistinctOn.length > 0;\n const isGrouped = totalQueryBuilder.expressionMap.groupBys && totalQueryBuilder.expressionMap.groupBys.length > 0;\n\n // Check if the original query has DISTINCT ON or GROUP BY\n if (hasDistinctOn || isGrouped) {\n // Wrap the query (either with DISTINCT ON or GROUP BY) in a subquery and count the results\n const subQuery = totalQueryBuilder.getQuery();\n\n const result = await query.connection\n .createQueryBuilder()\n .select('COUNT(*)', 'rowsCount')\n .from(`(${subQuery})`, 'subQuery')\n .setParameters(totalQueryBuilder.getParameters())\n .getRawOne<{\n rowsCount: number;\n }>();\n\n return result?.rowsCount ?? 0;\n }\n\n // If no DISTINCT ON or GROUP BY, just get the count directly\n return await totalQueryBuilder.getCount();\n};\n","import { ListMeta } from '#/types/list-meta';\nimport type { ObjectLiteral, SelectQueryBuilder } from 'typeorm';\nimport { fetchTotalWithQuery } from './fetch-total-with-query.js';\n\nexport interface CreateListMetaOptions<T extends ObjectLiteral> {\n /**\n * Typeorm query builder\n */\n query: SelectQueryBuilder<T>;\n\n /**\n * If true, total count will be calculated by additional SELECT COUNT.\n */\n needCountTotal?: boolean;\n\n /**\n * Limit of items\n */\n limit?: number;\n\n /**\n * Offset of items\n */\n offset?: number;\n}\n\n/**\n * Create list meta object\n * @returns list meta object\n * @example\n * class UsersService {\n * async getMany(opts: GetManyUsersOptions): Promise<[User[], ListMeta]> {\n * ...\n * return Promise.all([\n * query.getMany(),\n * createListMeta<User>({\n * query,\n * needCountTotal,\n * limit,\n * offset,\n * }),\n * ]);\n * }\n */\nexport const createListMeta = async <T extends ObjectLiteral>(\n {\n query,\n needCountTotal = false,\n limit,\n offset,\n }: CreateListMetaOptions<T>,\n): Promise<ListMeta> => {\n const meta: ListMeta = {\n limit,\n offset,\n };\n\n if (needCountTotal) {\n meta.total = await fetchTotalWithQuery(query);\n }\n\n return meta;\n};\n\n","/**\n * Define statuses. Returns array of statuses from filter or default statuses\n * @param statuses - array of statuses from filter. Can be undefined\n * @param defaultStatuses - array of default statuses\n * @returns final array of statuses\n * @example\n * const statuses = defineStatuses(['active', 'pending'], ['active']);\n * // statuses = ['active', 'pending']\n *\n * const statuses = defineStatuses(undefined, ['active']);\n * // statuses = ['active']\n */\nexport const defineStatuses = <T>(statuses: T[] | undefined, defaultStatuses: T[]) => {\n return Array.isArray(statuses) ? statuses : defaultStatuses;\n};\n","import { parse } from 'accept-language-parser';\n\nimport { NestExpressRequest } from '#/types/express-request';\n\nexport const getRequestLanguage = (req: NestExpressRequest, fallbackLanguage: string): string => {\n const headers = req?.headers as ({\n ['accept-language']?: string;\n });\n\n return parse(headers['accept-language'])\n ?.[0]\n ?.code ?? fallbackLanguage;\n};\n","/**\n * Converts a locale string to a PostgreSQL collation identifier.\n *\n * @param locale - The locale string to convert (e.g., 'uk', 'en')\n * @returns The PostgreSQL collation identifier (e.g., 'uk_UA', 'en_US')\n *\n * @example\n * ```typescript\n * localeToPgCollate('uk') // returns 'uk_UA'\n * localeToPgCollate('en') // returns 'en_US'\n * ```\n */\nexport const localeToPgCollate = (locale: string) => {\n let collate = 'en_US';\n\n if (locale === 'uk') {\n collate = 'uk_UA';\n }\n\n return collate;\n};\n","type DefinedValuesOnly<T> = {\n [K in keyof T]: T[K] extends undefined ? never : K;\n}[keyof T];\n\ntype UndefinedRemoved<T> = {\n [K in DefinedValuesOnly<T>]: T[K];\n};\n\nexport const removeUndefinedProperties = <T extends object>(obj: T): UndefinedRemoved<T> => {\n const result: Partial<UndefinedRemoved<T>> = {\n };\n\n for (const key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key) && obj[key as keyof T] !== undefined) {\n (result as Record<string, unknown>)[key] = obj[key as keyof T];\n }\n }\n\n return result as UndefinedRemoved<T>;\n};\n","import { createRandomString } from '@pcg/text-kit';\n\nimport { NestExpressRequest } from '#/types/express-request';\n\n\nexport const generateRequestId = (appShortName: string) => {\n return `${appShortName}req:${createRandomString()}`;\n};\n\nexport const extractRequestId = (req: NestExpressRequest): string => {\n const headers = req?.headers as ({\n 'x-request-id'?: string;\n 'x-cloud-trace-context'?: string;\n });\n\n if (headers?.['x-request-id']) {\n return headers['x-request-id'];\n }\n\n if (headers['x-cloud-trace-context']) {\n return req.appShortname + `req:${headers['x-cloud-trace-context']}`;\n }\n\n return generateRequestId(req.appShortname);\n};\n","/**\n * Pauses execution for a specified amount of time using a Promise.\n * @param ms - The amount of time to pause in milliseconds.\n * @returns A Promise that resolves after the specified amount of time has elapsed.\n * @deprecated use wait instead\n */\nexport const pauseWithPromise = async (ms: number): Promise<void> => {\n return await new Promise((resolve) => {\n setTimeout(() => {\n resolve();\n }, ms);\n });\n};\n\n/**\n * Pauses execution for a specified amount of time using a Promise.\n * @param ms - The amount of time to pause in milliseconds.\n * @returns A Promise that resolves after the specified amount of time has elapsed.\n */\nexport const wait = async (ms: number): Promise<void> => {\n return await new Promise((resolve) => {\n setTimeout(() => {\n resolve();\n }, ms);\n });\n};\n","import {\n Brackets, In, IsNull, ObjectLiteral, SelectQueryBuilder, WhereExpressionBuilder,\n} from 'typeorm';\n\nimport { MaybeNull } from '#/types/maybe';\n\n/**\n * Adds a filter condition to a TypeORM SelectQueryBuilder based on the provided field and value(s).\n *\n * Handles three types of filtering:\n * - Single value filtering: when a single non-null value is provided\n * - Multiple value filtering: when an array of values is provided\n * - Null value filtering: when null is explicitly provided as the filter value\n *\n * @template T - The entity type that extends ObjectLiteral\n * @template K - The field name key type that must be a string key of T\n *\n * @param query - The TypeORM SelectQueryBuilder instance to add the filter to\n * @param fieldName - The name of the field to filter by, must be a valid key of entity T\n * @param valueOrValues - The filter value(s). Can be:\n * - A single value of type T[K]\n * - An array of values of type T[K]\n * - null to filter for null values\n * - An array containing null values\n * @example\n * ```typescript\n * // Single value filter\n * addFilterByField(queryBuilder, 'status', 'active');\n * // Multiple values filter\n * addFilterByField(queryBuilder, 'id', [1, 2, 3]);\n * // Null value filter\n * addFilterByField(queryBuilder, 'deletedAt', null);\n * ```\n *\n * @returns void - Modifies the query builder in place\n */\nexport const addFilterByField = <\n T extends ObjectLiteral,\n K extends (keyof T & string)\n>(query: SelectQueryBuilder<T>, fieldName: K, valueOrValues: MaybeNull<T[K]> | MaybeNull<T[K]>[]): void => {\n const isFilterValueMultiple = Array.isArray(valueOrValues);\n\n if (isFilterValueMultiple) {\n addMultipleFilter(query, fieldName, valueOrValues);\n } else if (valueOrValues === null) {\n addNullableFilter(query, fieldName);\n } else {\n addSingleFilter(query, fieldName, valueOrValues);\n }\n};\n\n/**\n * Adds a filter to a TypeORM query that matches multiple values for a given column,\n * including support for null values.\n *\n * @template T - The entity type that extends ObjectLiteral\n * @template K - The key type that must be both a key of T and a string\n * @param query - The TypeORM SelectQueryBuilder instance to add the filter to\n * @param columnName - The name of the column to filter on\n * @param values - An array of values to match, which may include null\n *\n * @remarks\n * This function creates an OR condition that matches any of the provided values.\n * If the values array includes null, a separate null check is added to the filter.\n * Non-null values are handled using TypeORM's `In` operator.\n *\n * @example\n * ```typescript\n * const query = repository.createQueryBuilder('user');\n * addMultipleFilter(query, 'status', ['active', 'pending', null]);\n * // Generates: WHERE (status IS NULL OR status IN ('active', 'pending'))\n * ```\n */\nconst addMultipleFilter = <\n T extends ObjectLiteral,\n K extends (keyof T & string)\n>(query: SelectQueryBuilder<T>, columnName: K, values: MaybeNull<T[K]>[]): void => {\n query.andWhere(new Brackets((subQuery) => {\n if (values.includes(null)) {\n addNullValueToMultipleFilter(subQuery, columnName);\n }\n\n const notNullValues = values.filter((v) => v !== null);\n subQuery.orWhere({\n [columnName]: In(notNullValues),\n });\n }));\n};\n\n/**\n * Adds a single filter condition to a TypeORM SelectQueryBuilder.\n *\n * @template T - The entity type that extends ObjectLiteral\n * @template K - The column name type, constrained to string keys of T\n *\n * @param query - The SelectQueryBuilder instance to add the filter to\n * @param columnName - The name of the column to filter on\n * @param value - The value to filter by, must match the type of the column\n *\n * @returns void\n *\n * @example\n * ```typescript\n * const query = repository.createQueryBuilder('user');\n * addSingleFilter(query, 'email', 'user@example.com');\n * // Results in: WHERE user.email = 'user@example.com'\n * ```\n */\nconst addSingleFilter = <\n T extends ObjectLiteral,\n K extends (keyof T & string)\n>(query: SelectQueryBuilder<T>, columnName: K, value: T[K]): void => {\n query.andWhere({\n [columnName]: value,\n });\n};\n\n/**\n * Adds a nullable filter to a TypeORM query builder.\n *\n * This function applies a WHERE clause that filters for NULL values in the specified column.\n * The filter is combined with existing conditions using AND logic.\n *\n * @template T - The entity type that extends ObjectLiteral\n * @param query - The TypeORM SelectQueryBuilder instance to add the filter to\n * @param columnName - The name of the column to check for NULL values\n * @returns void\n *\n * @example\n * ```typescript\n * const query = repository.createQueryBuilder('user');\n * addNullableFilter(query, 'deletedAt');\n * // Results in: WHERE deletedAt IS NULL\n * ```\n */\nconst addNullableFilter = <T extends ObjectLiteral>(query: SelectQueryBuilder<T>, columnName: string): void => {\n query.andWhere({\n [columnName]: IsNull(),\n });\n};\n\n/**\n * Adds an OR condition to the query to check if the specified column is NULL.\n *\n * This function is used to extend filtering logic by adding a null value check\n * as an alternative condition in a WHERE clause.\n *\n * @param query - The TypeORM WhereExpressionBuilder instance to which the null condition will be added\n * @param columnName - The name of the database column to check for NULL values\n *\n * @returns void\n *\n * @example\n * ```typescript\n * const queryBuilder = repository.createQueryBuilder('user');\n * addNullValueToMultipleFilter(queryBuilder, 'deletedAt');\n * // Results in: WHERE ... OR deletedAt IS NULL\n * ```\n */\nconst addNullValueToMultipleFilter = (query: WhereExpressionBuilder, columnName: string): void => {\n query.orWhere({\n [columnName]: IsNull(),\n });\n};\n","import { ObjectLiteral, SelectQueryBuilder } from 'typeorm';\n\n/**\n * Checks if a given alias is already used in the query builder's join attributes.\n *\n * This utility function inspects the query builder's expression map to determine\n * whether a specific alias name has already been assigned to any join attribute.\n * This is useful to avoid alias conflicts when building complex TypeORM queries.\n *\n * @template T - The entity type that extends ObjectLiteral\n * @param {SelectQueryBuilder<T>} query - The TypeORM SelectQueryBuilder instance to check\n * @param {string} alias - The alias name to search for in the join attributes\n * @returns {boolean} True if the alias is already used in any join attribute, false otherwise\n *\n * @example\n * ```typescript\n * const query = repository.createQueryBuilder('user');\n * const isBusy = isAliasAlreadyBusy(query, 'profile');\n * if (!isBusy) {\n * query.leftJoinAndSelect('user.profile', 'profile');\n * }\n * ```\n */\nexport const isAliasAlreadyBusy = <T extends ObjectLiteral>(query: SelectQueryBuilder<T>, alias: string) =>\n query.expressionMap.joinAttributes.some((a) => a.alias.name === alias);\n","import { ObjectLiteral, SelectQueryBuilder } from 'typeorm';\nimport { isAliasAlreadyBusy } from './is-alias-already-busy.js';\n\n/**\n * Ensures an inner join is added to the TypeORM query builder only if the alias is not already in use.\n *\n * This function checks if the specified alias is already being used in the query builder.\n * If the alias is available, it adds an inner join with the provided entity, alias, and optional condition.\n * If the alias is already busy, the function returns without making any changes to the query.\n *\n * @template T - The entity type that extends ObjectLiteral\n * @param query - The TypeORM SelectQueryBuilder instance to add the inner join to\n * @param entity - The entity class (Function) or entity name (string) to join\n * @param alias - The alias to use for the joined entity\n * @param condition - Optional join condition as a string\n * @returns void\n *\n * @example\n * ```typescript\n * const query = repository.createQueryBuilder('user');\n * ensureInnerJoin(query, Profile, 'profile', 'profile.userId = user.id');\n * ```\n */\nexport const ensureInnerJoin = <T extends ObjectLiteral>(\n query: SelectQueryBuilder<T>,\n // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\n entity: Function | string,\n alias: string,\n condition?: string,\n): void => {\n if (isAliasAlreadyBusy(query, alias)) {\n return;\n }\n\n query.innerJoin(entity, alias, condition);\n};\n","import { ObjectLiteral, SelectQueryBuilder } from 'typeorm';\nimport { isAliasAlreadyBusy } from './is-alias-already-busy.js';\n\n/**\n * Ensures a left join is added to a TypeORM query builder if the alias is not already in use.\n *\n * This function checks if the specified alias is already being used in the query.\n * If the alias is available, it performs a left join with the provided entity, alias, and optional condition.\n * If the alias is already busy, the function returns early without modifying the query.\n *\n * @template T - The entity type that extends ObjectLiteral\n * @param query - The TypeORM SelectQueryBuilder instance to add the left join to\n * @param entity - The entity class (Function) or table name (string) to join\n * @param alias - The alias name to use for the joined entity\n * @param condition - Optional join condition as a string (e.g., \"alias.id = entity.foreignId\")\n * @returns void\n *\n * @example\n * ```typescript\n * ensureLeftJoin(queryBuilder, User, 'user', 'user.id = post.userId');\n * ```\n */\nexport const ensureLeftJoin = <T extends ObjectLiteral>(\n query: SelectQueryBuilder<T>,\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\n entity: Function | string,\n alias: string,\n condition?: string,\n): void => {\n if (isAliasAlreadyBusy(query, alias)) {\n return;\n }\n\n query.leftJoin(entity, alias, condition);\n};\n","import { InputValidationError } from '#/errors';\nimport { ValidationError, ValidationPipe } from '@nestjs/common';\n\nexport class NestKitValidationPipe extends ValidationPipe {\n createExceptionFactory() {\n return (validationErrors: ValidationError[] = []) => {\n if (!this.isDetailedOutputDisabled) {\n return new InputValidationError(validationErrors);\n }\n\n return new InputValidationError();\n };\n }\n}\n","import {\n ArgumentsHost, Catch, HttpException, HttpServer,\n} from '@nestjs/common';\nimport { isObject } from '@nestjs/common/utils/shared.utils';\nimport { GqlArgumentsHost } from '@nestjs/graphql/dist/services/gql-arguments-host';\n\nimport { AppEnv } from '#/enums/app-env.enum';\nimport {\n Logger, LoggerContext, LoggerFactory,\n} from '#/logger';\nimport { HttpExceptionResponse } from './http-exception-response.js';\n\ntype ContextType = 'http' | 'ws' | 'rpc' | 'graphql';\n\n/**\n * Http exception filter for NestJS\n * It is used to correctly log all http exceptions\n * @deprecated use NestErrorFilter instead\n * @see NestErrorFilter\n * @example\n * ```ts\n * // main.ts\n * const { httpAdapter } = app.get(HttpAdapterHost);\n * const loggerFactory = app.get(WINSTON_MODULE_FACTORY_PROVIDER);\n * app.useGlobalFilters(new HttpExceptionFilter(httpAdapter, loggerFactory));\n * ```\n */\n@Catch(HttpException)\nexport class HttpExceptionFilter {\n private readonly logger: Logger;\n\n constructor(\n protected readonly applicationRef: HttpServer,\n private readonly loggerFactory: LoggerFactory,\n ) {\n this.logger = this.loggerFactory.create({\n scope: HttpExceptionFilter.name,\n });\n }\n\n catch(exception: HttpException, host: ArgumentsHost) {\n const gqlHost = GqlArgumentsHost.create(host);\n const type = gqlHost.getType<ContextType>();\n\n const response = exception.getResponse() as HttpExceptionResponse;\n if (!response?.silent) {\n if (isObject(response)) {\n const logger = this.loggerFactory.create(response.context);\n\n if (response.error instanceof Error) {\n logger.error(response.message, response.error);\n } else {\n logger.error(exception);\n }\n } else {\n this.logger.error(exception);\n }\n }\n\n if (type !== 'http') {\n return exception;\n }\n\n /**\n * If request is http, then we need to send response to client\n */\n let body: {\n message: string;\n key?: string;\n stack?: string;\n context?: LoggerContext;\n statusCode: number;\n };\n\n if (isObject(response)) {\n body = {\n key: response.key,\n message: response.message,\n context: response.context,\n statusCode: exception.getStatus(),\n };\n\n if (response.error instanceof Error && process.env.NODE_ENV !== AppEnv.PRODUCTION) {\n body.stack = response.error.stack;\n }\n } else {\n body = {\n statusCode: exception.getStatus(),\n message: response,\n };\n }\n\n this.applicationRef.reply(host.getArgByIndex(1), body, exception.getStatus());\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAGA,IAAY,4CAAL;;;;;AAKL;;;;;AAMA;;;;;;AAOA;;;;;;AAOA;;;;;AAMA;;;;;;AClCF,IAAY,8CAAL;AACL;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;ACqBF,MAAa,eAAkB,QAAgC;CAC7D,MAAM,kBAAkB,gBACtB,KACA,QAAQ,KACR,EACE,0BAA0B,MAC3B,CACF;CAED,MAAM,SAAS,aAAa,iBAAsC,EAChE,uBAAuB,OACxB,CAAC;AAEF,KAAI,OAAO,SAAS,EAClB,OAAM,IAAI,MAAM,OAAO,UAAU,CAAC;AAGpC,QAAO;;;;;;;;;;;;;;AAeT,MAAa,oBAAoB;AAC/B,KAAI,QAAQ,IAAI,YAAY,OAAO,eAAe,QAAQ,IAAI,YAAY,OAAO,SAAS,QAAQ,IAAI,YAAY,OAAO,KACvH,QAAO;AAGT,KAAI,QAAQ,IAAI,YAAY,OAAO,MACjC,QAAO;AAGT,QAAO;;;;;;;;;;;;;;AAeT,MAAa,mBAAmB;AAC9B,KAAI,QAAQ,IAAI,YAAY,OAAO,eAAe,QAAQ,IAAI,YAAY,OAAO,SAAS,QAAQ,IAAI,YAAY,OAAO,KACvH,QAAO;AAGT,KAAI,QAAQ,IAAI,YAAY,OAAO,MACjC,QAAO;AAGT,QAAO;;;;;;;;;;;;;;AAeT,MAAa,qBAAqB;AAChC,KAAI,QAAQ,IAAI,YAAY,OAAO,eAAe,QAAQ,IAAI,YAAY,OAAO,SAAS,QAAQ,IAAI,YAAY,OAAO,KACvH,QAAO;AAGT,KAAI,QAAQ,IAAI,YAAY,OAAO,MACjC,QAAO;AAGT,QAAO;;;;;;;;;;;;;;AAeT,MAAa,0BAA0B;AACrC,KAAI,QAAQ,IAAI,YAAY,OAAO,eAAe,QAAQ,IAAI,YAAY,OAAO,SAAS,QAAQ,IAAI,YAAY,OAAO,KACvH,QAAO;AAGT,KAAI,QAAQ,IAAI,YAAY,OAAO,MACjC,QAAO;AAGT,QAAO;;;;;;;;;;;;;;;;;;;;;;;;AC3HT,MAAa,mBAAmB;AAEhC,MAAa,wBAAwB,OAAO,eAAe,iBAAiB,CAAC;;;;AAK7E,IAAa,gCAAb,MAA2C;;;;;;;;CAQzC,AAEA,OAAO;;;;;;;;;;CAWP,AAEA;;;;;;;;;;CAWA,AAEA;;;;;;;;CASA,AACA;;;;;;;;CASA,AAEA;;;;;;;;CASA,AAEA,oBAAoB;;;CA5DnBA,aAAW,OAAO;CAClB,UAAU;;;;CAYV,YAAY;CACZ,UAAU;;;;CAYV,YAAY;CACZ,UAAU;;;YAUV,OAAO,OAAO;;CAUd,YAAY;CACZ,UAAU;;;;CAUV,YAAY;CACZ,UAAU;;;;;;;;;;;;;;;;;AAgFb,MAAa,mBAAmB,SAA2B;AACzD,QAAO,WAAW,wBAAuC;EACvD,MAAM,MAAM,YAAY,8BAA8B;AAEtD,SAAO;GACL,KAAK,IAAI;GACT,MAAM,KAAK;GACX,WAAW,KAAK;GAChB,MAAM,IAAI;GACV,MAAM,IAAI;GACV,MAAM,KAAK,QAAQ,QAAQ;GAC3B,QAAQ,IAAI;GACZ,qBAAqB,IAAI;GACzB,kBAAkB,IAAI;GACvB;GACD;;;;;;;;ACpLJ,IAAY,kDAAL;;;;AAIL;;;;AAKA;;;;AAKA;;;;AAKA;;;;AAKA;;;;AAKA;;;;AAKA;;;;;;ACrCF,IAAY,oDAAL;;;;AAIL;;;;AAKA;;;;;;;;;;;;;;;;;;;;;;;;ACWF,MAAa,oBAAoB,SAAiB,QAAgB,YAAY,KAAK,OAAO,OAAe;AACvG,QAAO,GAAG,UAAU,SAAS,YAAY,mBAAmB,KAAK;;;;;;;;;;;;;ACR5D,sBAAMC,YAAU;CACrB,YACE,AAA2DC,WAC3D;EAD2D;;;;;;;;;;CAW7D,IAAI,YAAY;AACd,UAAQ,KAAK,UAAU,KAAvB;GACE,KAAK,OAAO,KACV,QAAO;GACT,KAAK,OAAO,YACV,QAAO;GACT,KAAK,OAAO,MACV,QAAO;GACT,QACE,QAAO;;;;;;;;;CAUb,iBAAiB,QAAgB,KAAsB;AACrD,SAAO,iBAAiB,OAAO,KAAK,UAAU,WAAW,QAAQ,KAAK,WAAW,GAAG;;;;;;CAOtF,WAAW,MAAe;AACxB,SAAO,mBAAmB,KAAK;;;;CA1ClC,YAAY;oBAGR,OAAO,eAAe,iBAAiB,CAAC;;;;;;ACUtC,qBAAMC,WAAS;uBALrB,QAAQ,EACR,OAAO;CACN,WAAW,CAAC,UAAU;CACtB,SAAS,CAAC,UAAU;CACrB,CAAC;;;;;;;;;;;;;;;;;;;;ACsBF,IAAa,YAAb,cAA+B,MAAM;CACnC;CACA;CACA,iBAAiB,WAAW;CAC5B;CAEA,YAAY,MAAwB;AAClC,QAAM,KAAK,SAAS,KAAK,iBAAiB,QAAQ,EAChD,OAAO,KAAK,OACb,GAAG,OAAU;AAEd,OAAK,OAAO;AACZ,OAAK,MAAM,KAAK;AAChB,OAAK,UAAU,KAAK;AACpB,OAAK,SAAS,KAAK,UAAU;;;;;;AC1DjC,IAAa,kBAAb,cAAqC,UAAU;CAC7C,YAAY,MAAwB;AAClC,QAAM,KAAK;AACX,OAAK,OAAO;AACZ,OAAK,iBAAiB;;;;;;ACJ1B,IAAa,gBAAb,cAAmC,UAAU;CAC3C,YAAY,MAAwB;AAClC,QAAM,KAAK;AACX,OAAK,OAAO;AACZ,OAAK,iBAAiB;;;;;;;;;ACE1B,MAAa,2BAA2B;;;;ACNxC,IAAa,iBAAb,cAAoC,UAAU;CAC5C,YAAY,MAAwB;AAClC,QAAM,KAAK;AACX,OAAK,OAAO;AACZ,OAAK,iBAAiB;;;;;;ACE1B,IAAa,oBAAb,cAAuC,eAAe;CACpD,YAAY,MAAgC;AAC1C,QAAM;GACJ,KAAK;GACL,SAAS,KAAK,WAAW,wDAAwD,KAAK,OAAO;GAC7F,SAAS,KAAK;GACf,CAAC;AACF,OAAK,OAAO;;;;;;ACZhB,IAAa,uBAAb,cAA0C,UAAU;CAClD,YAAY,QAA4B;AACtC,QAAM;GACJ,SAAS;GACT,KAAK;GACL,SAAS,SAAS,EAChB,QACD,GAAG;GACL,CAAC;AACF,OAAK,OAAO;AACZ,OAAK,iBAAiB;;;;;;ACX1B,IAAa,oBAAb,cAAuC,UAAU;CAC/C,YAAY,MAAwB;AAClC,QAAM,KAAK;AACX,OAAK,OAAO;AACZ,OAAK,iBAAiB;;;;;;ACAnB,qCAAMC,2BAAyB;;;;CAIpC,AAGA;;;;CAKA,AAGA;;;;CAKA,AAGA;;;;CAKA,AAGA;;YA3BC,YAAY,QAAQ,EACnB,UAAU,MACX,CAAC;YAMD,YAAY,QAAQ,EACnB,UAAU,MACX,CAAC;YAMD,YAAY,SAAS,EACpB,UAAU,MACX,CAAC;YAMD,YAAY,SAAS,EACpB,UAAU,MACX,CAAC;uCA/BH,YAAY;;;;ACEN,kCAAMC,wBAAsB;;;;;;;;;;;;;;;;;CAiBjC,AAKA;;;;;;;;;;;;;;;;;CAkBA,AAGA;;;;;;;;;;;;;;;;;CAkBA,AAKA;;;;;;;;;;;;;;;;;CAkBA,AAGA;;;CAtEC,YAAY,KAAK,EAChB,UAAU,MACX,CAAC;CACD,IAAI,EAAE;CACN,YAAY;;;YAmBZ,YAAY,QAAQ,EACnB,UAAU,MACX,CAAC;;CAmBD,YAAY,KAAK,EAChB,UAAU,MACX,CAAC;CACD,IAAI,EAAE;CACN,YAAY;;;YAmBZ,YAAY,QAAQ,EACnB,UAAU,MACX,CAAC;oCAvFH,UAAU;;;;;;;;;;;;AC8CX,MAAa,qBAAwB,YAAmC;CACtE,MAAM,SAAS,QAAQ,MAAM,IAAI;AAEjC,KAAI,OAAO,WAAW,EACpB,OAAM,IAAI,MAAM,2BAA2B;AAG7C,QAAO;EACL,WAAW,OAAO;EAClB,WAAW,OAAO;EAClB,YAAY,UAAU,OAAO,GAAG;EACjC;;;;;ACvDI,kCAAMC,wBAAsB;;;;CAIjC,AAKA;;;;;CAMA,AAIA,OAAgB;;YAff,YAAY,KAAK;CAChB,aAAa;CACb,cAAc;CACd,UAAU;CACX,CAAC;YAOD,YAAY,KAAK;CAChB,cAAc;CACd,aAAa;CACd,CAAC;oCAnBH,UAAU;;;;ACAJ,qCAAMC,2BAAyB;;;;;CAKpC,AAGA;;;;CAKA,AAGA;;;;CAKA,AAGA;;;;CAKA,AAGA;;YA3BC,YAAY,KAAK,EAChB,aAAa,mDACd,CAAC;YAMD,YAAY,KAAK,EAChB,aAAa,6BACd,CAAC;YAMD,YAAY,KAAK,EAChB,aAAa,oBACd,CAAC;YAMD,YAAY,KAAK,EAChB,aAAa,gDACd,CAAC;uCAhCH,YAAY;;;;;;;;;;;;;;;;;;;ACSb,MAAa,iBAAiB,SAAiB;AAC7C,QAAO,OAAO,QAAQ,KAAK,CACxB,KAAK,CAAC,KAAK,WAAW,GAAG,IAAI,GAAG,KAAK,UAAU,MAAM,GAAG,CACxD,KAAK,QAAQ;;;;;;;;ACflB,MAAa,gCAAgC;;;;AAK7C,MAAa,kCAAkC;;;;AAK/C,MAAa,0BAA0B;;;;AAKvC,MAAa,iCAAiC;;;;AAK9C,MAAa,kCAAkC;;;;;;;ACH/C,IAAa,SAAb,MAAa,OAAO;CAClB,YACE,AAAiBC,eACjB,AAAQC,UAAyB,EAChC,EACD;EAHiB;EACT;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgCV,MAAM,SAAgC;AACpC,SAAO,IAAI,OAAO,KAAK,eAAe;GACpC,GAAG,KAAK;GACR,GAAG;GACJ,CAAC;;;;;;;;;;CAWJ,UAAU,MAAc,KAAgC,OAAuB;EAC7E,MAAMA,UAAyB,EAC7B,QAAQ,MACT;AAED,MAAI,KAAK;AACP,UAAO,OAAO,SAAS,EACrB,WAAW,IAAI,WAChB,CAAC;AAEF,OAAI,CAAC,IAAI,KACP,OAAM,IAAI,MAAM,sHAAsH;AAGxI,UAAO,OAAO,SAAS;IACrB,WAAW,IAAI;IACf,QAAQ,IAAI,KAAK;IAClB,CAAC;;AAGJ,MAAI,MACF,QAAO,OAAO,SAAS,MAAM;AAG/B,SAAO,KAAK,MAAM,QAAQ;;CAU5B,WAAW,GAAG,MAAuB;AACnC,MACE,KAAK,WAAW,KAChB,OAAO,KAAK,OAAO,YACnB,OAAO,KAAK,OAAO,aACnB;GACA,MAAM,MAAM,KAAK;GACjB,MAAM,QAAQ,KAAK;AACnB,QAAK,QAAQ,OAAO;QAEpB,MAAK,UAAU;GACb,GAAG,KAAK;GACR,GAAI,KAAK;GACV;;;;;;CAQL,aAA4B;AAC1B,SAAO,gBAAgB,KAAK,QAAQ;;CAQtC,IAAI,GAAG,MAAuB;AAC5B,MAAI,SAAS,KAAK,GAAG,CACnB,MAAK,cAAc,IAAI;GACrB,GAAG,KAAK;GACR,GAAI,KAAK;GACV,CAAC;MAEF,MAAK,cAAc,IAAI;GACrB,OAAO,KAAK;GACZ,SAAS,KAAK;GACd,GAAG,KAAK;GACR,GAAI,KAAK;GACV,CAAC;;CASN,KAAK,GAAG,MAAuB;AAC7B,MAAI,OAAO,KAAK,OAAO,SACrB,MAAK,cAAc,KAAK;GACtB,SAAS,KAAK;GACd,GAAG,KAAK;GACR,GAAI,KAAK;GACV,CAAC;MAEF,MAAK,cAAc,KAAK;GACtB,GAAG,KAAK;GACR,GAAI,KAAK;GACV,CAAC;;CAWN,MAAM,GAAG,MAAuB;AAC9B,MAAI,KAAK,cAAc,WAAW;GAChC,MAAM,MAAM,KAAK;AACjB,QAAK,cAAc,MAAM;IACvB,GAAG,KAAK;IACR,GAAI,KAAK;IACT,GAAG,KAAK,iBAAiB,IAAI;IAC9B,CAAC;aACO,KAAK,cAAc,OAAO;GACnC,MAAM,MAAM,KAAK;AACjB,QAAK,cAAc,MAAM;IACvB,GAAG,KAAK;IACR,GAAI,KAAK;IACT,GAAG,KAAK,iBAAiB,IAAI;IAC9B,CAAC;aACO,OAAO,KAAK,OAAO,YAAY,KAAK,cAAc,OAAO;GAClE,MAAM,UAAU,KAAK;GACrB,MAAM,MAAM,KAAK;AACjB,QAAK,cAAc,MAAM;IACd;IACT,GAAG,KAAK;IACR,GAAI,KAAK;IACT,OAAO,KAAK,iBAAiB,IAAI;IAClC,CAAC;aACO,OAAO,KAAK,OAAO,UAAU;GACtC,MAAM,UAAU,KAAK;AACrB,QAAK,cAAc,MAAM;IACvB;IACA,GAAG,KAAK;IACR,GAAI,KAAK;IACV,CAAC;;;;;;;CAQN,AAAU,iBAAiB,OAAmC;EAC5D,MAAMC,cAAiC,EACtC;AAED,MAAI,iBAAiB,WAAW;AAC9B,eAAY,UAAU,MAAM;AAC5B,eAAY,QAAQ,MAAM;AAC1B,eAAY,UAAU,MAAM;AAC5B,eAAY,aAAa,MAAM;AAC/B,eAAY,WAAW,MAAM;AAC7B,OAAI,MAAM,iBAAiB,MACzB,aAAY,QAAQ,KAAK,iBAAiB,MAAM,MAAM;aAE/C,iBAAiB,OAAO;AACjC,eAAY,UAAU,MAAM;AAC5B,eAAY,QAAQ,MAAM;;AAG5B,MAAI,iBAAiB,eAAe;AAClC,eAAY,aAAa,MAAM,WAAW;GAE1C,MAAM,WAAW,MAAM,aAAa;AAEpC,OAAI,SAAS,SAAS,EAAE;AACtB,QAAI,SAAS,IACX,aAAY,WAAW,SAAS;AAGlC,QAAI,SAAS,SAAS;AACpB,SAAI,CAAC,YAAY,QACf,aAAY,UAAU,EACrB;AAGH,iBAAY,UAAU;MACpB,GAAG,YAAY;MACf,GAAG,SAAS;MACb;;AAGH,QAAI,SAAS,MACX,aAAY,QAAQ,KAAK,iBAAiB,SAAS,MAAM;;AAI7D,UAAO;aACE,iBAAiB,cAAc;GACxC,MAAM,MAAM,KAAK,MAAM,KAAK,UAAU;IACpC,WAAW,MAAM;IACjB,WAAW,MAAM;IACjB,QAAQ,MAAM;IACf,CAAC,CAAC;AAEH,eAAY,UAAU;IACpB,GAAG,YAAY;IACf,GAAG;IACJ;;AAMH,SAAO;;CAQT,KAAK,GAAG,MAAuB;AAC7B,MAAI,OAAO,KAAK,OAAO,SACrB,MAAK,cAAc,KAAK;GACtB,SAAS,KAAK;GACd,GAAG,KAAK;GACR,GAAI,KAAK;GACV,CAAC;MAEF,MAAK,cAAc,KAAK;GACtB,GAAG,KAAK;GACR,GAAI,KAAK;GACV,CAAC;;CASN,MAAM,GAAG,MAAuB;AAC9B,MAAI,OAAO,KAAK,OAAO,SACrB,MAAK,cAAc,MAAM;GACvB,SAAS,KAAK;GACd,GAAG,KAAK;GACR,GAAI,KAAK;GACV,CAAC;MAEF,MAAK,cAAc,MAAM;GACvB,GAAG,KAAK;GACR,GAAI,KAAK;GACV,CAAC;;CASN,QAAQ,GAAG,MAAuB;AAChC,MAAI,OAAO,KAAK,OAAO,SACrB,MAAK,cAAc,QAAQ;GACzB,SAAS,KAAK;GACd,GAAG,KAAK;GACR,GAAI,KAAK;GACV,CAAC;MAEF,MAAK,cAAc,QAAQ;GACzB,GAAG,KAAK;GACR,GAAI,KAAK;GACV,CAAC;;;;;;;ACpUD,6BAAMC,2BAAyB,cAAc;CAClD,AAAkD;CAElD,AAAU,cAAc,UAAqB,SAA8B,UAA2C;AACpH,OAAK,MAAM,WAAW,SACpB,MAAK,OAAO,IAAI,KAAK,mBAAmB,SAAS,EAAE,KAAK,iBAAiB,QAAQ,EAAE,EACjF,OAAO,SACR,CAAC;;CAIN,AAAU,iBAAiB,SAA0B;AAEnD,MAAI,WAAW,QAAQ,CACrB,QAAO,KAAK,iBAAiB,SAAS,CAAC;AAGzC,MAAI,cAAc,QAAQ,IAAI,MAAM,QAAQ,QAAQ,CAClD,QAAO,KAAK,UACV,UACC,KAAK,UACJ,OAAO,UAAU,WAAW,MAAM,UAAU,GAAG,OACjD,EACD;AAGH,SAAO,OAAO,QAAQ;;CAGxB,AAAQ,mBAAmB,OAAuC;AAChE,UAAQ,OAAR;GACE,KAAK,MACH,QAAO;GAET,KAAK,UACH,QAAO;GAET,KAAK,QACH,QAAO;GAET,KAAK,OACH,QAAO;GAET,KAAK,QACH,QAAO;GAET,QACE,QAAO;;;;YA9CZ,OAAO,wBAAwB;+BAFjC,YAAY;;;;ACJb,IAAa,uBAAb,MAAkC;CAChC;CACA;CACA;;AAGF,IAAa,gBAAb,cAAmC,eAAe;CAChD;CAEA,YAAY,MAA4B;AACtC,QAAM,KAAK,WAAW,KAAK,SAAS,KAAK,SAAS,MAAM;AAExD,OAAK,SAAS,KAAK;;;;;CAMrB,AAAU,SACR,OACA,YACA;EACA,MAAM,WAAW,KAAK,mBAAmB,YAAY,EACnD,cAAc,OACf,CAAC;AAEF,OAAK,MAAM,WAAW,SACpB,SAAQ,QAAQ,QAAQ,OAAxB;GACE,KAAK;GACL,KAAK;GACL,KAAK;AACH,SAAK,OAAO,MAAM,OAAO,QAAQ,QAAQ,EAAE,KAAK,OAAO,QAAQ,CAAC;AAChE;GAEF,KAAK;GACL,KAAK;AACH,QAAI,QAAQ,OACV,MAAK,OAAO,KAAK,GAAG,QAAQ,OAAO,GAAG,QAAQ,WAAW,KAAK,OAAO,QAAQ,CAAC;QAE9E,MAAK,OAAO,KAAK,OAAO,QAAQ,QAAQ,EAAE,KAAK,OAAO,QAAQ,CAAC;AAEjE;GAEF,KAAK;GACL,KAAK;AACH,QAAI,QAAQ,OACV,MAAK,OAAO,KAAK,GAAG,QAAQ,OAAO,GAAG,QAAQ,WAAW,KAAK,OAAO,QAAQ,CAAC;QAE9E,MAAK,OAAO,KAAK,OAAO,QAAQ,QAAQ,EAAE,KAAK,OAAO,QAAQ,CAAC;AAEjE;GAEF,KAAK;GACL,KAAK;AACH,QAAI,QAAQ,OACV,MAAK,OAAO,MAAM,IAAI,QAAQ,OAAO,IAAI,QAAQ,WAAW,KAAK,OAAO,QAAQ,CAAC;QAEjF,MAAK,OAAO,MAAM,OAAO,QAAQ,QAAQ,EAAE,KAAK,OAAO,QAAQ,CAAC;AAElE;;;CAKR,AAAQ,OAAO,SAAoC;EACjD,MAAM,MAAM,EACV,GAAG,QAAQ,gBACZ;AAED,MAAI,MAAM,QAAQ,IAAI,WAAW,CAC/B,KAAI,aAAa,QAAQ;AAG3B,SAAO;;;;;;;;;;;ACrEX,IAAa,gBAAb,MAA2B;CACzB,YACE,AAAiBC,eACjB,AAAQC,UAAyB,EAChC,EACD;EAHiB;EACT;;;;;;;;;;;;;;;;;;;;;CAuBV,OAAO,UAAyB,EAC/B,EAAE;AACD,SAAO,IAAI,OAAO,KAAK,eAAe;GACpC,GAAG,KAAK;GACR,GAAG;GACJ,CAAC;;CAGJ,oBAAoB,MAA4C;AAC9D,SAAO,IAAI,cAAc;GACvB,QAAQ,KAAK,OAAO,EAClB,OAAO,WACR,CAAC;GACF,GAAG;GACJ,CAAC;;;;;;;;;;;;;;;;ACjBN,MAAa,qBAAqB,OAAO,wBAAwB;;;;;;;;;;;AAYjE,MAAa,4BAA4B,OAAO,gCAAgC;AAEhF,MAAa,oBACX,eACW;AACX,QAAO,IAAIC,SAAO,aAAa,WAAW,CAAC;;AAG7C,MAAa,yBACX,eACe;AACf,QAAO;EACL;GACE,SAAS;GACT,kBAAkB,aAAa,WAAW;GAC3C;EACD;GACE,SAAS;GACT,aAAa,WAAmB;AAC9B,WAAO,IAAIA,SAAO,OAAO;;GAE3B,QAAQ,CAAC,gCAAgC;GAC1C;EACD;GACE,SAAS;GACT,UAAU;GACX;EACD;GACE,SAAS;GACT,aAAa,WAAmB;AAC9B,WAAO,IAAI,cAAc,OAAO;;GAElC,QAAQ,CAAC,gCAAgC;GAC1C;EACF;;AAGH,MAAa,8BACX,YACe;CACf,MAAMC,YAAwB;EAC5B;GACE,SAAS;GACT,aAAa,eAA8B,aAAa,WAAW;GACnE,QAAQ,CAAC,8BAA8B;GACxC;EACD;GACE,SAAS;GACT,aAAa,WAAmB;AAC9B,WAAO,IAAID,SAAO,OAAO;;GAE3B,QAAQ,CAAC,gCAAgC;GAC1C;EACD;GACE,SAAS;GACT,UAAU;GACX;EACD;GACE,SAAS;GACT,aAAa,WAAmB;AAC9B,WAAO,IAAI,cAAc,OAAO;;GAElC,QAAQ,CAAC,gCAAgC;GAC1C;EACF;AAED,KAAI,QAAQ,UAAU;EACpB,MAAM,WAAW,QAAQ;AACzB,YAAU,KACR,GAAG,CACD;GACE,SAAS;GACT,YAAY,OAAO,mBACjB,MAAM,eAAe,2BAA2B;GAClD,QAAQ,CAAC,SAAS;GACnB,EACD;GACE,SAAS;GACT;GACD,CACF,CACF;;AAGH,KAAI,QAAQ,WACV,WAAU,KAAK;EACb,SAAS;EACT,YAAY,QAAQ;EACpB,QAAQ,QAAQ,UAAU,EAAE;EAC7B,CAAC;AAGJ,QAAO;;;;;;ACzHF,yCAAME,eAAa;CACxB,OAAc,QAAQ,SAA6C;EACjE,MAAM,YAAY,sBAAsB,QAAQ;AAEhD,SAAO;GACL;GACW;GACX,SAAS;GACV;;CAGH,OAAc,aACZ,SACe;EACf,MAAM,YAAY,2BAA2B,QAAQ;AAErD,SAAO;GACL;GACA,SAAS,QAAQ;GACN;GACX,SAAS;GACV;;CAGH,OAAc,aAAa,SAA6C;AACtE,SAAO,iBAAiB,QAAQ;;;2CA5BnC,QAAQ,EACR,OAAO,EACP,CAAC;;;;ACTF,MAAMC,sBAAmD;CACvD,KAAK,IAAI;CACT,MAAM,IAAI;CACV,OAAO,IAAI;CACX,MAAM,IAAI;CACV,OAAO,IAAI;CACX,SAAS,IAAI;CACd;;;;;;;;;AA2FD,MAAa,uBAAuB,EAClC,SACA,QACA,OACA,WACA,SACA,OACA,OACA,UAEA,SACA,YACA,OACA,OAAO,QACiC;AACxC,KAAI,gBAAgB,OAAO,UAGzB,KAAI;AACF,MAAI,cAAc,IAAI,KAAK,UAAU,CAAC,aAAa,CACjD,aAAY,IAAI,KAAK,UAAU,CAAC,gBAAgB;SAE5C;CAKV,MAAM,QACJ,oBAAoB,YAAY,SAAyB;AAE3D,KAAI,SACF,YAAW,KAAK,SAAS;CAK3B,MAAM,WAAW,MAAM,IAAI,QAAQ,GAAG;CACtC,MAAM,aAAa,YAAY,GAAG,UAAU,KAAK;CACjD,MAAM,SAAS,MAAM,MAAM,aAAa,CAAC;CAEzC,IAAI,OAAO;CACX,IAAI,QAAQ;AACZ,KAAI,gBAAgB,OAAO,SAAS,gBAAgB,OAAO,OACzD,QAAO,GAAG,MAAM,GAAG;UACV,gBAAgB,OAAO,MAChC,QAAO;UACE,gBAAgB,OAAO,OAChC,QAAO;AAIT,KAAI,QAAQ,WACV,QAAO,GAAG,WAAW,OAAO;UACnB,WACT,QAAO;AAGT,KAAI,KACF,SAAQ,IAAI,OAAO,KAAK,KAAK,GAAG;CAIlC,MAAM,WAAW,MAAM,IAAI,UAAU;CACrC,MAAM,SAAS,gBAAgB,OAAO,QAAQ,MAAM,MAAM,QAAQ,GAAG;CAErE,IAAI,aAAa;AACjB,KAAI,OAAO;EACT,MAAM,EACJ,kBACA,eACA,GAAGC,cACD,OAAO,WAAW,EACrB;;;;AAKD,eAAa,QAAQ,KAAK,oBAAoB;GAC5C;GACA;GACA;GACA;GACA,SAAS,MAAM,WAAW;GAC1B;GACA,OAAO,MAAM;GACb,UAAU,MAAM;GAChB;GACA,YAAY;GACZ,OAAO,MAAM;GACb,MAAM,OAAO;GACd,CAAC,KAAK;;CAGT,MAAM,WAAW,WAAW,OAAO,KAAK,QAAQ,CAAC,SAAS,IAAI,MAAM,OAAO,KAAK,UAAU,SAAS,MAAM,EAAE,GAAG,GAAG;AAIjH,QAAO,GAAG,SAAS,MAAM,WAAW,OAAO,SAAS,QAAQ,WAAW,SAAS,WAAW;;;;;;;AAQ7F,MAAa,yBAAyB,UAAU,WAC9C,OAAO,QACJ,EACC,OACA,WACA,SACA,OACA,QAEA,OACA,UACA,YACA,OAAO,MACP,GAAG,cACC;AACJ,QAAO,oBAAoB;EACzB;EACA;EACO;EACP;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,MAAM;EACP,CAA+B;EAEnC;;;;;;;ACvOH,MAAa,sBAAsB;AAEnC,MAAa,2BAA2B,OAAO,eAAe,oBAAoB,CAAC;;;;;;;;;;;;AAmBnF,MAAa,sBAAsB,SAAoC;AACrE,QAAO,WAAW,2BAA2B;EAC3C,MAAMC,WAAS;GACb,QAAQ,OAAO,OAAO;GACtB,QAAQ,OAAO,WAAW;GAC1B,sBAAsB,KAAK,QAAQ;GACpC;EAED,MAAMC,iBAAwC,EAC5C,YAAY,EAAE,EACf;AAED,MAAI,CAAC,MAAM,QAAQ,eAAe,WAAW,CAC3C,QAAO;AAGT,MAAI,KAAK,WACP,gBAAe,WAAW,KACxB,IAAI,QAAQ,WAAW,QAAQ;GAC7B,OAAO,KAAK,gBAAgB;GAC5B,QAAQ,QAAQ,OAAO,QAAQ,GAAGD,SAAO;GAC1C,CAAC,CACH;AAGH,MAAI,KAAK,WACP,gBAAe,WAAW,KAAK,GAAG,KAAK,WAAW;AAGpD,SAAO;GACP;;;;;;;;;;AClDJ,IAAsB,gBAAtB,MAA4D;CAC1D,AACmB;CAEnB,AAAU;;;;CAKV,eAAe;AACb,OAAK,SAAS,KAAK,cAAc,OAAO,EACtC,OAAO,KAAK,YAAY,MACzB,CAAC;;;YAXH,qBAAqB;;;;;ACiCxB,IAAsB,wBAAtB,cAKU,cAAc;CACtB,YAAY,AAAiBE,QAAoD;AAC/E,SAAO;EADoB;;CAI7B,AAAsC;CACtC,AAAuC;CAEvC,IAAW,aAA4B;AACrC,SAAO,KAAK,WAAW,cAAc,KAAK,OAAO,OAAO,KAAK;;CAG/D,AAAU,mBAA2B;AACnC,SAAO,KAAK,UAAU,iBAAiB,KAAK,OAAO,OAAO,SAAS;;CAGrE,IAAI,aAAqB;AACvB,SAAO,KAAK,OAAO,OAAO,KAAK;;CAGjC,IAAI,QAAgB;AAClB,SAAO,KAAK,OAAO,OAAO;;CAG5B,MAAM,SAAuC,MAAmC;EAC9E,MAAM,SAAS,KAAK,OAAO,MAAM;GAC/B,QAAQ,KAAK,SAAS;GACtB,GAAG;GACJ,CAAC;AAEF,MAAI,OAAO,OAAO,KAAK,CAAC,QAAQ,MAAM,EAAE,CAAC,WAAW,EAClD,OAAM,IAAI,gBAAgB;GACxB,SAAS;GACT,KAAK;GACL,SAAS,OAAO,YAAY;GAC7B,CAAC;AAGJ,SAAO,MAAM,KAAK,WAAW,UAAU,EACrC,GAAG,MACJ,CAAwB;;CAG3B,MAAM,OAAO,IAAmC;AAC9C,SAAO,MAAM,KAAK,SAAS,EACzB,IACD,CAAC;;CAGJ,MAAM,eAA6C,MAAY,KAA2C;EACxG,MAAM,SAAS,KAAK,OAAO,UAAU,KAAK,eAAe,MAAM,KAAK,EAClE,GAAG,MACJ,CAAC;EAEF,MAAM,OAAO,MAAM,KAAK,SAAS,KAAK;AAEtC,MAAI,CAAC,KACH,OAAM,IAAI,cAAc;GACtB,SAAS,GAAG,KAAK,WAAW,QAAQ,cAAc,KAAK,CAAC;GACxD,KAAK;GACL,SAAS,OAAO,YAAY;GAC7B,CAAC;AAGJ,SAAO;;CAGT,MAAgB,aAAa,IAAY,KAA2C;AAClF,SAAO,MAAM,KAAK,eAAe,EAC/B,IACD,EAAE,IAAI;;CAGT,AAAU,mBAAmB,OAA8B,QAAkB;AAC3E,MAAI,CAAC,OACH;AAGF,MAAI,OAAO,OACT,OAAM,SAAS,GAAG,KAAK,MAAM,sBAAsB,EACjD,QAAQ,IAAI,OAAO,OAAO,IAC3B,CAAC;;CAMN,AAAU,mBAAmB,OAA8B,QAAuB;AAChF,MAAI,CAAC,OACH;AAGF,QAAM,SAAS,GAAG,KAAK,MAAM,sBAAsB,EACjD,QAAQ,IAAI,OAAO,IACpB,CAAC;;CAKJ,AAAU,oBAAoB,OAA8B,SAAkB;EAC5E,MAAM,OAAO,kBAAkB,QAAkB;AAEjD,QAAM,WAAW,GAAG,KAAK,MAAM,GAAG,KAAK,cAAc,KAAK,UAAU;;;YAjGrE,OAAO,UAAU;YACjB,kBAAkB;;;;;;;;AC1CrB,IAAa,sBAAb,cACU,sBAC2B;;;;;;;;;;;;;;;;;;CAkBnC,UAAU,WAAmB,YAA6B;AACxD,MAAI,WACF,QAAO;EAGT,MAAM,iBAAiB,UAAU,UAAU;AAG3C,MAAI,eAAe,SAAS,OAAO,CACjC,QAAO;EAGT,MAAM,QAAQ,eAAe,MAAM,IAAI;AACvC,MAAI,MAAM,WAAW,EACnB,QAAO,iBAAiB,eAAe;AAGzC,SAAO,MACJ,KAAK,MAAM,MAAO,MAAM,IAAI,OAAO,iBAAiB,KAAK,CAAE,CAC3D,KAAK,IAAI;;;;;;;;;;;;;;;;;;;;CAqBd,WACE,cACA,YACA,mBAA6B,EAAE,EACvB;AACR,SACE,UAAU,iBAAiB,OAAO,GAAG,CAAC,KAAK,IAAI,CAAC,IAC/C,aAAa,aAAa,UAAU,aAAa;;CAKtD,aAAa,cAA8B;AACzC,SAAO,UAAU,aAAa;;CAIhC,eAAe,cAAsB,sBAAsC;AACzE,SAAO,UAAU,eAAe,MAAM,qBAAqB;;;;;;;;;;;;;;CAe7D,cAAc,gBAAwB,iBAAiC;AACrE,SAAO,UACL,iBAAiB,eAAe,GAC9B,SACA,iBAAiB,gBAAgB,CACpC;;CAIH,oBACE,WACA,cACA,YACQ;AACR,SAAO,UACL,iBAAiB,UAAU,GAAG,OAAO,aAAa,aAAa,cAChE;;CAGH,uBAAuB,OAAe,cAA8B;AAClE,SAAO,QAAQ,OAAO,aAAa,QAAQ,KAAK,IAAI;;;;;;;;;;;;;;;;;CAkBtD,eAAe,aAA6B,aAA+B;AACzE,gBACE,OAAO,gBAAgB,WAAW,cAAc,YAAY;EAE9D,IAAI,OAAO;AACX,OAAK,MAAM,UAAU,YACnB,SAAQ,KAAK;AAGf,SAAO,KAAK,aAAa,KAAK;AAE9B,SAAO,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;CA2Bf,eAAe,aAA6B,aAA+B;AACzE,gBACE,OAAO,gBAAgB,WAAW,cAAc,YAAY;EAE9D,IAAI,OAAO;AACX,OAAK,MAAM,UAAU,YACnB,SAAQ,KAAK;AAGf,SAAO,KAAK,aAAa,KAAK;AAE9B,SAAO,MAAM;;;;;;;;;;;;;;;;;;CAmBf,UAAU,aAA6B,aAA+B;AACpE,gBACE,OAAO,gBAAgB,WAAW,cAAc,YAAY;EAE9D,IAAI,OAAO;AACX,OAAK,MAAM,UAAU,YACnB,SAAQ,KAAK;AAGf,SAAO,KAAK,aAAa,KAAK;AAE9B,SAAO,OAAO;;;;;;;;;;;;;;;;;;CAmBhB,qBACE,aACA,aACQ;AACR,gBACE,OAAO,gBAAgB,WAAW,cAAc,YAAY;EAE9D,IAAI,OAAO;AACX,OAAK,MAAM,UAAU,YACnB,SAAQ,KAAK;AAGf,SAAO,KAAK,aAAa,KAAK;AAE9B,SAAO,MAAM;;CAGf,AAAQ,aAAa,MAAsB;AACzC,MAAI,KAAK,SAAS,GAWhB,QAVe,KAAK,MAAM,KAAK,CAEL,KAAK,UAAU;AACvC,OAAI,MAAM,SAAS,OAAO,CACxB,QAAO,MAAM,MAAM,IAAI,CAAC,KAAK,MAAM,EAAE,GAAG,CAAC,KAAK,GAAG;AAGnD,UAAO;IACP,CAEgB,KAAK,KAAK;AAG9B,SAAO;;;;;;;;;AClQX,MAAa,kBAAkB;AAE/B,MAAa,uBAAuB,OAAO,eAAe,gBAAgB,CAAC;;;;AAK3E,IAAM,+BAAN,MAAmC;;;;;;;;CAQjC,AACA;;;;;;;;CASA,AAEA;;;;;;;;CASA,AACA;;;;;;;;CASA,AACA;;;;;;;;CASA,AACA;;;;;;;;CASA,AAGA;;YAtDC,UAAU;;CAUVC,aAAW,OAAO;CAClB,UAAU;;;YAUV,UAAU;YAUV,UAAU;YAUV,UAAU;;CAUVA,aAAW,QAAQ;CACnB,YAAY;CACZ,WAAW;;;;;;AAOd,MAAa,kBAAkB,SAA8C;AAC3E,QAAO,WAAW,uBAAkD;EAClE,MAAM,MAAM,YAAY,6BAA6B;EAOrD,MAAM,WAAW,CACf,GAAI,MAAM,YANS,CACnB,uBACA,0DACD,CAIA;AAED,SAAO;GACL,MAAM;GACN,SAAS,IAAI;GACb,MAAM,IAAI;GACV,MAAM,IAAI;GACV,UAAU,IAAI;GACd,UAAU,IAAI;GACd,UAAU,IAAI;GACd,aAAa;GACb,YAAY,CAAC,uBAAuB;GACpC,aAAa,CAAC,iCAAiC;GAC/C,eAAe;GACf,gBAAgB,IAAI,qBAAqB;GACzC,GAAG;GACH,UAAU,GAAG,KAAK,SAAS;GAC5B;GACD;;;;;AClCJ,SAAgB,QACd,WACA,GAAG,QACH;AACA,QAAO,OAAO,QAAQ,cAAc,UAAU,MAAM,aAAa,EAAE,UAAU;;;;;;;;;;;;;;;;;;;;;AC1E/E,MAAa,mBAAmB,UAAyE;AACvG,KAAI,UAAU,KACZ,QAAO;AAGT,KAAI,OAAO,UAAU,YACnB,QAAO;AAGT,QAAO,OAAO,MAAM;;;;;;;;;;;;;;;ACbtB,MAAa,sBAAsB,OACjC,UACoB;CACpB,MAAM,oBAAoB,MAAM,OAAO;AAGvC,mBACG,OAAO,OAAU,CACjB,MAAM,OAAU,CAChB,KAAK,OAAU,CACf,KAAK,OAAU,CACf,SAAS;CAEZ,MAAM,gBAAgB,kBAAkB,cAAc,oBAAoB,kBAAkB,cAAc,iBAAiB,SAAS;CACpI,MAAM,YAAY,kBAAkB,cAAc,YAAY,kBAAkB,cAAc,SAAS,SAAS;AAGhH,KAAI,iBAAiB,WAAW;EAE9B,MAAM,WAAW,kBAAkB,UAAU;AAW7C,UATe,MAAM,MAAM,WACxB,oBAAoB,CACpB,OAAO,YAAY,YAAY,CAC/B,KAAK,IAAI,SAAS,IAAI,WAAW,CACjC,cAAc,kBAAkB,eAAe,CAAC,CAChD,WAEC,GAEW,aAAa;;AAI9B,QAAO,MAAM,kBAAkB,UAAU;;;;;;;;;;;;;;;;;;;;;;;ACF3C,MAAa,iBAAiB,OAC5B,EACE,OACA,iBAAiB,OACjB,OACA,aAEoB;CACtB,MAAMC,OAAiB;EACrB;EACA;EACD;AAED,KAAI,eACF,MAAK,QAAQ,MAAM,oBAAoB,MAAM;AAG/C,QAAO;;;;;;;;;;;;;;;;;ACjDT,MAAa,kBAAqB,UAA2B,oBAAyB;AACpF,QAAO,MAAM,QAAQ,SAAS,GAAG,WAAW;;;;;ACT9C,MAAa,sBAAsB,KAAyB,qBAAqC;CAC/F,MAAM,UAAU,KAAK;AAIrB,QAAO,MAAM,QAAQ,mBAAmB,GACnC,IACD,QAAQ;;;;;;;;;;;;;;;;;ACCd,MAAa,qBAAqB,WAAmB;CACnD,IAAI,UAAU;AAEd,KAAI,WAAW,KACb,WAAU;AAGZ,QAAO;;;;;ACXT,MAAa,6BAA+C,QAAgC;CAC1F,MAAMC,SAAuC,EAC5C;AAED,MAAK,MAAM,OAAO,IAChB,KAAI,OAAO,UAAU,eAAe,KAAK,KAAK,IAAI,IAAI,IAAI,SAAoB,OAC5E,CAAC,OAAmC,OAAO,IAAI;AAInD,QAAO;;;;;ACbT,MAAa,qBAAqB,iBAAyB;AACzD,QAAO,GAAG,aAAa,MAAM,oBAAoB;;AAGnD,MAAa,oBAAoB,QAAoC;CACnE,MAAM,UAAU,KAAK;AAKrB,KAAI,UAAU,gBACZ,QAAO,QAAQ;AAGjB,KAAI,QAAQ,yBACV,QAAO,IAAI,eAAe,OAAO,QAAQ;AAG3C,QAAO,kBAAkB,IAAI,aAAa;;;;;;;;;;;ACjB5C,MAAa,mBAAmB,OAAO,OAA8B;AACnE,QAAO,MAAM,IAAI,SAAS,YAAY;AACpC,mBAAiB;AACf,YAAS;KACR,GAAG;GACN;;;;;;;AAQJ,MAAa,OAAO,OAAO,OAA8B;AACvD,QAAO,MAAM,IAAI,SAAS,YAAY;AACpC,mBAAiB;AACf,YAAS;KACR,GAAG;GACN;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACYJ,MAAa,oBAGX,OAA8B,WAAc,kBAA6D;AAGzG,KAF8B,MAAM,QAAQ,cAAc,CAGxD,mBAAkB,OAAO,WAAW,cAAc;UACzC,kBAAkB,KAC3B,mBAAkB,OAAO,UAAU;KAEnC,iBAAgB,OAAO,WAAW,cAAc;;;;;;;;;;;;;;;;;;;;;;;;AA0BpD,MAAM,qBAGJ,OAA8B,YAAe,WAAoC;AACjF,OAAM,SAAS,IAAI,UAAU,aAAa;AACxC,MAAI,OAAO,SAAS,KAAK,CACvB,8BAA6B,UAAU,WAAW;EAGpD,MAAM,gBAAgB,OAAO,QAAQ,MAAM,MAAM,KAAK;AACtD,WAAS,QAAQ,GACd,aAAa,GAAG,cAAc,EAChC,CAAC;GACF,CAAC;;;;;;;;;;;;;;;;;;;;;AAsBL,MAAM,mBAGJ,OAA8B,YAAe,UAAsB;AACnE,OAAM,SAAS,GACZ,aAAa,OACf,CAAC;;;;;;;;;;;;;;;;;;;;AAqBJ,MAAM,qBAA8C,OAA8B,eAA6B;AAC7G,OAAM,SAAS,GACZ,aAAa,QAAQ,EACvB,CAAC;;;;;;;;;;;;;;;;;;;;AAqBJ,MAAM,gCAAgC,OAA+B,eAA6B;AAChG,OAAM,QAAQ,GACX,aAAa,QAAQ,EACvB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;AC3IJ,MAAa,sBAA+C,OAA8B,UACxF,MAAM,cAAc,eAAe,MAAM,MAAM,EAAE,MAAM,SAAS,MAAM;;;;;;;;;;;;;;;;;;;;;;;;ACDxE,MAAa,mBACX,OAEA,QACA,OACA,cACS;AACT,KAAI,mBAAmB,OAAO,MAAM,CAClC;AAGF,OAAM,UAAU,QAAQ,OAAO,UAAU;;;;;;;;;;;;;;;;;;;;;;;;ACZ3C,MAAa,kBACX,OAGA,QACA,OACA,cACS;AACT,KAAI,mBAAmB,OAAO,MAAM,CAClC;AAGF,OAAM,SAAS,QAAQ,OAAO,UAAU;;;;;AC/B1C,IAAa,wBAAb,cAA2C,eAAe;CACxD,yBAAyB;AACvB,UAAQ,mBAAsC,EAAE,KAAK;AACnD,OAAI,CAAC,KAAK,yBACR,QAAO,IAAI,qBAAqB,iBAAiB;AAGnD,UAAO,IAAI,sBAAsB;;;;;;;;ACkBhC,uDAAMC,sBAAoB;CAC/B,AAAiB;CAEjB,YACE,AAAmBC,gBACnB,AAAiBC,eACjB;EAFmB;EACF;AAEjB,OAAK,SAAS,KAAK,cAAc,OAAO,EACtC,4BAA2B,MAC5B,CAAC;;CAGJ,MAAM,WAA0B,MAAqB;EAEnD,MAAM,OADU,iBAAiB,OAAO,KAAK,CACxB,SAAsB;EAE3C,MAAM,WAAW,UAAU,aAAa;AACxC,MAAI,CAAC,UAAU,OACb,KAAIC,WAAS,SAAS,EAAE;GACtB,MAAM,SAAS,KAAK,cAAc,OAAO,SAAS,QAAQ;AAE1D,OAAI,SAAS,iBAAiB,MAC5B,QAAO,MAAM,SAAS,SAAS,SAAS,MAAM;OAE9C,QAAO,MAAM,UAAU;QAGzB,MAAK,OAAO,MAAM,UAAU;AAIhC,MAAI,SAAS,OACX,QAAO;;;;EAMT,IAAIC;AAQJ,MAAID,WAAS,SAAS,EAAE;AACtB,UAAO;IACL,KAAK,SAAS;IACd,SAAS,SAAS;IAClB,SAAS,SAAS;IAClB,YAAY,UAAU,WAAW;IAClC;AAED,OAAI,SAAS,iBAAiB,SAAS,QAAQ,IAAI,aAAa,OAAO,WACrE,MAAK,QAAQ,SAAS,MAAM;QAG9B,QAAO;GACL,YAAY,UAAU,WAAW;GACjC,SAAS;GACV;AAGH,OAAK,eAAe,MAAM,KAAK,cAAc,EAAE,EAAE,MAAM,UAAU,WAAW,CAAC;;;yDAjEhF,MAAM,cAAc"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pcg/core",
|
|
3
|
-
"version": "1.0.0-alpha.
|
|
3
|
+
"version": "1.0.0-alpha.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -10,7 +10,8 @@
|
|
|
10
10
|
"fast-glob": "^3.3.3",
|
|
11
11
|
"graphql-subscriptions": "^3.0.0",
|
|
12
12
|
"logform": "^2.7.0",
|
|
13
|
-
"@pcg/text-kit": "1.0.0-alpha.0"
|
|
13
|
+
"@pcg/text-kit": "1.0.0-alpha.0",
|
|
14
|
+
"@pcg/predicates": "1.0.0-alpha.1"
|
|
14
15
|
},
|
|
15
16
|
"devDependencies": {
|
|
16
17
|
"@apollo/client": "^3.12.8",
|
package/src/tools/is-object.ts
CHANGED
|
@@ -1,10 +1 @@
|
|
|
1
|
-
|
|
2
|
-
* Checks if the given value is an object (not an array).
|
|
3
|
-
* @param {unknown} obj - The value to check.
|
|
4
|
-
* @returns {boolean} Returns true if `obj` is an object, false otherwise.
|
|
5
|
-
* @example
|
|
6
|
-
* isObject({ a: 1 }); // Returns true
|
|
7
|
-
* isObject([1, 2, 3]); // Returns false
|
|
8
|
-
*/
|
|
9
|
-
export const isObject = (obj: unknown): obj is Record<string, unknown> =>
|
|
10
|
-
obj !== null && !!obj && typeof obj === 'object' && !Array.isArray(obj);
|
|
1
|
+
export { isObject } from '@pcg/predicates';
|