typeorm-extension
Version:
A library to create/drop database, simple seeding data sets, ...
1 lines • 256 kB
Source Map (JSON)
{"version":3,"file":"index.cjs","sources":["../src/errors/base.ts","../src/errors/driver.ts","../src/errors/options.ts","../src/query/utils/alias.ts","../src/query/utils/key.ts","../src/utils/code-transformation/constants.ts","../src/utils/code-transformation/module.ts","../src/utils/entity.ts","../src/utils/separator.ts","../src/utils/slash.ts","../src/utils/tsconfig/module.ts","../src/utils/file-path.ts","../src/utils/file-system.ts","../src/utils/has-property.ts","../src/utils/object.ts","../src/utils/promise.ts","../src/query/utils/option.ts","../src/query/parameter/fields/module.ts","../src/query/parameter/filters/module.ts","../src/query/parameter/pagination/module.ts","../src/query/parameter/relations/module.ts","../src/query/parameter/sort/module.ts","../src/query/module.ts","../src/data-source/find/module.ts","../src/env/constants.ts","../src/env/utils.ts","../src/env/module.ts","../src/data-source/options/utils/merge.ts","../src/data-source/options/utils/env.ts","../src/data-source/options/module.ts","../src/data-source/options/singleton.ts","../src/data-source/singleton.ts","../src/database/check.ts","../src/database/driver/utils/charset.ts","../src/database/driver/utils/character-set.ts","../src/database/driver/utils/build.ts","../src/database/driver/utils/create.ts","../src/database/utils/context.ts","../src/database/utils/migration.ts","../src/database/utils/query.ts","../src/database/utils/schema.ts","../src/database/driver/postgres.ts","../src/database/driver/cockroachdb.ts","../src/database/driver/mongodb.ts","../src/database/driver/mssql.ts","../src/database/driver/mysql.ts","../src/database/driver/oracle.ts","../src/database/driver/sqlite.ts","../src/database/create.ts","../src/database/drop.ts","../src/cli/commands/database/create.ts","../src/cli/commands/database/drop.ts","../src/seeder/entity.ts","../src/seeder/factory/module.ts","../src/seeder/factory/manager.ts","../src/seeder/utils/file-path.ts","../src/seeder/utils/prepare.ts","../src/seeder/utils/template.ts","../src/seeder/factory/utils.ts","../src/seeder/executor.ts","../src/seeder/module.ts","../src/cli/commands/seed/create.ts","../src/cli/commands/seed/run.ts","../src/helpers/entity/error.ts","../src/helpers/entity/metadata.ts","../src/helpers/entity/property-names.ts","../src/helpers/entity/join-columns.ts","../src/helpers/entity/uniqueness.ts"],"sourcesContent":["export class TypeormExtensionError extends Error {\n\n}\n","import { TypeormExtensionError } from './base';\n\nexport class DriverError extends TypeormExtensionError {\n constructor(message?: string) {\n super(message || 'A database driver related error has occurred.');\n }\n\n static undeterminable() {\n return new DriverError('The driver could not be determined.');\n }\n\n static notSupported(driverName: string) {\n return new DriverError(`The driver ${driverName} is not supported yet.`);\n }\n}\n","import { TypeormExtensionError } from './base';\n\nexport class OptionsError extends TypeormExtensionError {\n constructor(message?: string) {\n super(message || 'A database options related error has occurred');\n }\n\n static undeterminable() {\n return new OptionsError('The database options could not be determined.');\n }\n\n static notFound() {\n return new OptionsError('The database options could not be located/loaded.');\n }\n\n static databaseNotDefined() {\n return new OptionsError('The database name to connect to is not defined.');\n }\n}\n","import type { QueryRelationsApplyOutput } from '../parameter';\n\nexport function getAliasForPath(items?: QueryRelationsApplyOutput, path?: string) {\n if (typeof path === 'undefined' || typeof items === 'undefined') {\n return undefined;\n }\n\n for (let i = 0; i < items.length; i++) {\n if (items[i].key === path) {\n return items[i].value;\n }\n }\n\n return undefined;\n}\n","export function buildKeyWithPrefix(name: string, prefix?: string) {\n if (prefix) {\n return `${prefix}.${name}`;\n }\n\n return name;\n}\n","export enum CodeTransformation {\n JUST_IN_TIME = 'jit',\n NONE = 'none',\n}\n","import process from 'node:process';\nimport { CodeTransformation } from './constants';\n\nexport function detectCodeTransformation() : `${CodeTransformation}` {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n if (process[Symbol.for('ts-node.register.instance')]) {\n return CodeTransformation.JUST_IN_TIME;\n }\n\n return CodeTransformation.NONE;\n}\n\nexport function isCodeTransformation(input: string) {\n return detectCodeTransformation() === input;\n}\n","import type { EntitySchema, ObjectType } from 'typeorm';\nimport { InstanceChecker } from 'typeorm';\n\nexport function getEntityName<O>(entity: ObjectType<O> | EntitySchema<O>) : string {\n if (typeof entity === 'function') {\n return entity.name;\n }\n\n if (InstanceChecker.isEntitySchema(entity)) {\n return entity.options.name;\n }\n\n return new (entity as any)().constructor.name;\n}\n","export function canReplaceWindowsSeparator(input: string) : boolean {\n // https://superuser.com/questions/176388/why-does-windows-use-backslashes-for-paths-and-unix-forward-slashes/176395#176395\n if (input.startsWith('\\\\\\\\?\\\\')) {\n return false;\n }\n\n let characterIndex: number;\n\n const specialCharacters = ['[', '{', '(', '^', '$', '.', '|', '?', '*', '+'];\n for (let i = 0; i < specialCharacters.length; i++) {\n characterIndex = input.indexOf(specialCharacters[i]);\n if (characterIndex !== -1) {\n // special character is prefixed with \\, no transformation allowed\n if (characterIndex !== 0 && input[characterIndex - 1] === '\\\\') {\n return false;\n }\n }\n }\n\n return true;\n}\n\nexport function replaceWindowSeparator(input: string) {\n return input.replace(/\\\\/g, '/');\n}\n\nexport function safeReplaceWindowsSeparator(input: string): string {\n if (input.indexOf('\\\\') === -1 || !canReplaceWindowsSeparator(input)) {\n return input;\n }\n\n return replaceWindowSeparator(input);\n}\n","const TRAILING_SLASH_RE = /\\/$|\\/\\?/;\n\nexport function hasTrailingSlash(input = '', queryParams = false): boolean {\n if (!queryParams) {\n return input.endsWith('/');\n }\n\n return TRAILING_SLASH_RE.test(input);\n}\n\nexport function withoutTrailingSlash(input = '', queryParams = false): string {\n if (!queryParams) {\n return (hasTrailingSlash(input) ? input.slice(0, -1) : input) || '/';\n }\n\n if (!hasTrailingSlash(input, true)) {\n return input || '/';\n }\n\n const [s0, ...s] = input.split('?');\n\n return (s0.slice(0, -1) || '/') + (s.length ? `?${s.join('?')}` : '');\n}\n","import { isObject, load } from 'locter';\nimport path from 'node:path';\nimport type { TSConfig } from './type';\n\nexport async function readTSConfig(input?: string) : Promise<TSConfig> {\n input = input || process.cwd();\n input = path.isAbsolute(input) ?\n input :\n path.resolve(process.cwd(), input);\n\n const filePath = input.indexOf('.json') === -1 ?\n path.join(input, 'tsconfig.json') :\n input;\n\n try {\n const tsConfig = await load(filePath);\n\n if (isObject(tsConfig)) {\n return tsConfig;\n }\n } catch (e) {\n // don't do anything ;)\n }\n\n return {};\n}\n","import { isObject } from 'locter';\nimport path from 'node:path';\nimport { CodeTransformation, isCodeTransformation } from './code-transformation';\nimport { canReplaceWindowsSeparator, replaceWindowSeparator } from './separator';\nimport { withoutTrailingSlash } from './slash';\nimport type { TSConfig } from './tsconfig';\nimport { readTSConfig } from './tsconfig';\n\nconst stripLeadingModifier = (text: string) => {\n if (text.startsWith('./')) {\n text = text.substring(2);\n }\n\n return text;\n};\n\nexport function transformFilePath(\n input: string,\n dist?: string,\n src?: string,\n): string {\n let separator = path.sep;\n const windowsSeparatorReplaceable = canReplaceWindowsSeparator(input);\n if (windowsSeparatorReplaceable) {\n separator = '/';\n input = replaceWindowSeparator(input);\n }\n\n let base = input;\n let baseIndex = input.lastIndexOf(separator);\n if (baseIndex !== -1) {\n base = base.substring(baseIndex + 1);\n }\n\n if (src) {\n if (windowsSeparatorReplaceable) {\n src = replaceWindowSeparator(src);\n }\n\n src = withoutTrailingSlash(stripLeadingModifier(src));\n }\n src = src || 'src';\n\n if (dist) {\n if (windowsSeparatorReplaceable) {\n dist = replaceWindowSeparator(dist);\n }\n\n dist = withoutTrailingSlash(stripLeadingModifier(dist));\n }\n dist = dist || 'dist';\n\n if (\n input.indexOf(src) !== -1 &&\n input.indexOf(dist) === -1\n ) {\n const lastIndex = input.lastIndexOf(src);\n const prevCharacter = input.substring(lastIndex - 1, lastIndex);\n if (!prevCharacter || prevCharacter === separator) {\n input = input.substring(0, lastIndex) +\n dist +\n input.substring(lastIndex + src.length);\n\n baseIndex = input.lastIndexOf(separator);\n }\n }\n\n // if the path already contains a js file extension, we are done\n const jsExtensions = ['js', 'cjs', 'mjs'];\n for (let i = 0; i < jsExtensions.length; i++) {\n if (base.indexOf(jsExtensions[i]) !== -1) {\n return input;\n }\n }\n\n const tsExtensions = ['ts', 'cts', 'mts'];\n for (let i = 0; i < tsExtensions.length; i++) {\n const regex = new RegExp(`(\\\\.${tsExtensions[i]}|${tsExtensions[i]})`, 'g');\n let matchesSum: number | undefined;\n const matches = base.match(regex);\n if (Array.isArray(matches)) {\n matchesSum = matches.length;\n }\n\n let matchesCounter = 0;\n\n const bracketIndex = base.lastIndexOf('{');\n base = base.replace(\n regex,\n (...args) => {\n matchesCounter++;\n\n // if the file extension name comes after the last bracket index,\n // we can be pretty sure that the extension name is not part of a filename\n if (\n (args[2] >= bracketIndex && bracketIndex !== -1) ||\n (bracketIndex === -1 && matchesCounter === matchesSum)\n ) {\n return args[0].startsWith('.') ? `.${jsExtensions[i]}` : jsExtensions[i];\n }\n\n return args[0];\n },\n );\n }\n\n if (baseIndex !== -1) {\n base = input.substring(0, baseIndex + 1) + base;\n }\n\n return stripLeadingModifier(base);\n}\nexport async function adjustFilePath<T extends unknown | unknown[]>(\n input: T,\n tsconfig?: string | TSConfig,\n): Promise<T> {\n if (isCodeTransformation(CodeTransformation.JUST_IN_TIME)) {\n return input;\n }\n\n if (!isObject(tsconfig)) {\n tsconfig = await readTSConfig(tsconfig);\n }\n\n const { compilerOptions } = tsconfig;\n\n if (typeof input === 'string') {\n return transformFilePath(input, compilerOptions?.outDir) as T;\n }\n\n if (Array.isArray(input)) {\n for (let i = 0; i < input.length; i++) {\n if (typeof input[i] === 'string') {\n input[i] = transformFilePath(input[i], compilerOptions?.outDir);\n }\n }\n }\n\n return input;\n}\n\nexport async function adjustFilePaths<T extends Record<string, any>>(\n input: T,\n keys?: (keyof T)[],\n tsconfig?: string | TSConfig,\n): Promise<T> {\n if (isCodeTransformation(CodeTransformation.JUST_IN_TIME)) {\n return input;\n }\n\n if (!isObject(tsconfig)) {\n tsconfig = await readTSConfig(tsconfig);\n }\n\n keys = keys || Object.keys(input);\n\n for (let i = 0; i < keys.length; i++) {\n input[keys[i]] = await adjustFilePath(input[keys[i]], tsconfig);\n }\n\n return input;\n}\n\nexport function resolveFilePath(filePath: string, root?: string) {\n if (path.isAbsolute(filePath)) {\n return filePath;\n }\n\n return filePath.startsWith('/') ?\n filePath :\n path.resolve(root || process.cwd(), filePath);\n}\n\nexport function parseFilePath(filePath: string, root?: string) {\n const fullPath = resolveFilePath(filePath, root);\n\n const directory = path.dirname(fullPath);\n const name = path.basename(fullPath);\n\n return {\n directory,\n name,\n };\n}\n","import fs from 'node:fs';\n\nexport async function isDirectory(input: string) : Promise<boolean> {\n try {\n const stat = await fs.promises.stat(input);\n return stat.isDirectory();\n } catch (e) {\n return false;\n }\n}\n","export function hasOwnProperty<X extends Record<string, any>, Y extends PropertyKey>(obj: X, prop: Y): obj is X & Record<Y, unknown> {\n return Object.prototype.hasOwnProperty.call(obj, prop);\n}\n\nexport function hasStringProperty<X extends Record<string, any>, Y extends PropertyKey>(obj: X, prop: Y): obj is X & Record<Y, string> {\n return hasOwnProperty(obj, prop) &&\n typeof obj[prop] === 'string';\n}\n","export function pickRecord(data: Record<string, any>, keys: string[]) {\n const output : Record<string, any> = {};\n for (let i = 0; i < keys.length; i++) {\n output[keys[i]] = data[keys[i]];\n }\n\n return output;\n}\n","import { isObject } from 'locter';\n\nexport function isPromise(p: unknown): p is Promise<unknown> {\n return isObject(p) &&\n (\n p instanceof Promise ||\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n typeof p.then === 'function'\n );\n}\n","import { hasOwnProperty } from '../../utils';\n\nexport function isQueryOptionDefined(\n input: Record<string, any> | boolean,\n option: string | string[],\n) {\n if (typeof input === 'boolean') {\n return false;\n }\n\n const options = Array.isArray(option) ? option : [option];\n\n for (let i = 0; i < options.length; i++) {\n if (hasOwnProperty(input, options[i])) {\n return true;\n }\n }\n\n return false;\n}\n","import {\n parseQueryFields,\n} from 'rapiq';\n\nimport type { ObjectLiteral, SelectQueryBuilder } from 'typeorm';\nimport { buildKeyWithPrefix, getAliasForPath } from '../../utils';\nimport type { QueryFieldsApplyOptions, QueryFieldsApplyOutput } from './type';\n\n/**\n * Apply parsed fields parameter data on the db query.\n *\n * @param query\n * @param data\n */\n/* istanbul ignore next */\nexport function applyQueryFieldsParseOutput<T extends ObjectLiteral = ObjectLiteral>(\n query: SelectQueryBuilder<T>,\n data: QueryFieldsApplyOutput,\n options: QueryFieldsApplyOptions<T> = {},\n) {\n if (data.length === 0) {\n return data;\n }\n\n query.select(data.map((field) => {\n const alias = getAliasForPath(options.relations, field.path) ||\n options.defaultAlias ||\n options.defaultPath;\n\n return buildKeyWithPrefix(field.key, alias);\n }));\n\n return data;\n}\n\n/**\n * Apply raw fields parameter data on the db query.\n *\n * @param query\n * @param data\n * @param options\n */\nexport function applyQueryFields<T extends ObjectLiteral = ObjectLiteral>(\n query: SelectQueryBuilder<T>,\n data: unknown,\n options?: QueryFieldsApplyOptions<T>,\n) : QueryFieldsApplyOutput {\n options = options || {};\n if (options.defaultAlias) {\n options.defaultPath = options.defaultAlias;\n }\n\n return applyQueryFieldsParseOutput(query, parseQueryFields(data, options), options);\n}\n\n/**\n * Apply raw fields parameter data on the db query.\n *\n * @param query\n * @param data\n * @param options\n */\nexport function applyFields<T extends ObjectLiteral = ObjectLiteral>(\n query: SelectQueryBuilder<T>,\n data: unknown,\n options?: QueryFieldsApplyOptions<T>,\n) : QueryFieldsApplyOutput {\n return applyQueryFields(query, data, options);\n}\n","import type { FiltersParseOutput } from 'rapiq';\nimport { FilterComparisonOperator, parseQueryFilters } from 'rapiq';\n\nimport type { ObjectLiteral, SelectQueryBuilder, WhereExpressionBuilder } from 'typeorm';\nimport { Brackets } from 'typeorm';\nimport { buildKeyWithPrefix, getAliasForPath } from '../../utils';\nimport type {\n QueryFiltersApplyOptions,\n QueryFiltersApplyOutput,\n QueryFiltersOutput,\n} from './type';\n\n// --------------------------------------------------\n\nexport function transformParsedFilters<T extends ObjectLiteral = ObjectLiteral>(\n data: FiltersParseOutput,\n options: QueryFiltersApplyOptions<T> = {},\n) : QueryFiltersOutput {\n const items : QueryFiltersOutput = [];\n\n for (let i = 0; i < data.length; i++) {\n const alias = getAliasForPath(options.relations, data[i].path) ||\n options.defaultAlias ||\n options.defaultPath;\n\n const fullKey : string = buildKeyWithPrefix(data[i].key, alias);\n\n const filter = data[i];\n\n const statement : string[] = [\n fullKey,\n ];\n\n let bindingKey : string;\n if (options.bindingKey) {\n bindingKey = options.bindingKey(fullKey)\n .replace('.', '_');\n } else {\n bindingKey = `filter_${fullKey.replace('.', '_')}`;\n }\n\n if (filter.value === null || typeof filter.value === 'undefined') {\n statement.push('IS');\n\n if (filter.operator === FilterComparisonOperator.NOT_EQUAL) {\n statement.push('NOT');\n }\n\n statement.push('NULL');\n\n items.push({\n statement: statement.join(' '),\n binding: {},\n });\n\n continue;\n }\n\n switch (filter.operator) {\n case FilterComparisonOperator.EQUAL:\n case FilterComparisonOperator.NOT_EQUAL: {\n if (filter.operator === FilterComparisonOperator.EQUAL) {\n statement.push('=');\n } else {\n statement.push('!=');\n }\n\n statement.push(`:${bindingKey}`);\n break;\n }\n case FilterComparisonOperator.LIKE:\n case FilterComparisonOperator.NOT_LIKE: {\n if (filter.operator === FilterComparisonOperator.NOT_LIKE) {\n statement.push('NOT');\n }\n\n statement.push('LIKE');\n\n statement.push(`:${bindingKey}`);\n\n filter.value += '%';\n break;\n }\n\n case FilterComparisonOperator.IN:\n case FilterComparisonOperator.NOT_IN: {\n if (filter.operator === FilterComparisonOperator.NOT_IN) {\n statement.push('NOT');\n }\n\n statement.push('IN');\n\n statement.push(`(:...${bindingKey})`);\n\n if (Array.isArray(filter.value)) {\n const nullIndex = (filter.value as unknown[]).indexOf(null);\n if (nullIndex !== -1) {\n filter.value.splice(nullIndex, 1);\n\n statement.unshift('(');\n if (filter.operator === FilterComparisonOperator.NOT_IN) {\n statement.push('AND');\n } else {\n statement.push('OR');\n }\n statement.push(fullKey);\n statement.push('IS');\n\n if (filter.operator === FilterComparisonOperator.NOT_IN) {\n statement.push('NOT');\n }\n\n statement.push('NULL');\n statement.push(')');\n }\n }\n break;\n }\n case FilterComparisonOperator.LESS_THAN:\n case FilterComparisonOperator.LESS_THAN_EQUAL:\n case FilterComparisonOperator.GREATER_THAN:\n case FilterComparisonOperator.GREATER_THAN_EQUAL: {\n if (filter.operator === FilterComparisonOperator.LESS_THAN) {\n statement.push('<');\n } else if (filter.operator === FilterComparisonOperator.LESS_THAN_EQUAL) {\n statement.push('<=');\n } else if (filter.operator === FilterComparisonOperator.GREATER_THAN) {\n statement.push('>');\n } else {\n statement.push('>=');\n }\n\n statement.push(`:${bindingKey}`);\n break;\n }\n }\n\n items.push({\n statement: statement.join(' '),\n binding: { [bindingKey]: filter.value },\n });\n }\n\n return items;\n}\n\n/**\n * Apply transformed filter[s] parameter data on the db query.\n *\n * @param query\n * @param data\n */\nexport function applyFiltersTransformed<T extends ObjectLiteral = ObjectLiteral>(\n query: SelectQueryBuilder<T> | WhereExpressionBuilder,\n data: QueryFiltersOutput,\n) : QueryFiltersOutput {\n if (data.length === 0) {\n return data;\n }\n\n /* istanbul ignore next */\n query.andWhere(new Brackets((qb) => {\n for (let i = 0; i < data.length; i++) {\n if (i === 0) {\n qb.where(data[i].statement, data[i].binding);\n } else {\n qb.andWhere(data[i].statement, data[i].binding);\n }\n }\n }));\n\n return data;\n}\n\n/**\n * Apply parsed filter[s] parameter data on the db query.\n *\n * @param query\n * @param data\n * @param options\n */\nexport function applyQueryFiltersParseOutput<T extends ObjectLiteral = ObjectLiteral>(\n query: SelectQueryBuilder<T> | WhereExpressionBuilder,\n data: FiltersParseOutput,\n options?: QueryFiltersApplyOptions<T>,\n) : QueryFiltersApplyOutput {\n applyFiltersTransformed(query, transformParsedFilters<T>(data, options));\n\n return data;\n}\n\n// --------------------------------------------------\n\n/**\n * Apply raw filter[s] parameter data on the db query.\n *\n * @param query\n * @param data\n * @param options\n */\nexport function applyQueryFilters<T extends ObjectLiteral = ObjectLiteral>(\n query: SelectQueryBuilder<T>,\n data: unknown,\n options?: QueryFiltersApplyOptions<T>,\n) : QueryFiltersApplyOutput {\n options = options || {};\n if (options.defaultAlias) {\n options.defaultPath = options.defaultAlias;\n }\n\n return applyQueryFiltersParseOutput(\n query,\n parseQueryFilters(data, options),\n options,\n );\n}\n\n/**\n * Apply raw filter[s] parameter data on the db query.\n *\n * @param query\n * @param data\n * @param options\n */\nexport function applyFilters<T extends ObjectLiteral = ObjectLiteral>(\n query: SelectQueryBuilder<T>,\n data: unknown,\n options?: QueryFiltersApplyOptions<T>,\n) : QueryFiltersApplyOutput {\n return applyQueryFilters(query, data, options);\n}\n","import type { ObjectLiteral } from 'rapiq';\nimport { parseQueryPagination } from 'rapiq';\nimport type { SelectQueryBuilder } from 'typeorm';\nimport type { QueryPaginationApplyOptions, QueryPaginationApplyOutput } from './type';\n\n/**\n * Apply parsed page/pagination parameter data on the db query.\n *\n * @param query\n * @param data\n */\nexport function applyQueryPaginationParseOutput<T extends ObjectLiteral = ObjectLiteral>(\n query: SelectQueryBuilder<T>,\n data: QueryPaginationApplyOutput,\n) {\n /* istanbul ignore next */\n if (typeof data.limit !== 'undefined') {\n query.take(data.limit);\n\n if (typeof data.offset === 'undefined') {\n query.skip(0);\n }\n }\n\n /* istanbul ignore next */\n if (typeof data.offset !== 'undefined') {\n query.skip(data.offset);\n }\n\n return data;\n}\n\n/**\n * Apply raw page/pagination parameter data on the db query.\n *\n * @param query\n * @param data\n * @param options\n */\nexport function applyQueryPagination<T extends ObjectLiteral = ObjectLiteral>(\n query: SelectQueryBuilder<T>,\n data: unknown,\n options?: QueryPaginationApplyOptions,\n) : QueryPaginationApplyOutput {\n return applyQueryPaginationParseOutput(query, parseQueryPagination(data, options));\n}\n\n/**\n * Apply raw page/pagination parameter data on the db query.\n *\n * @param query\n * @param data\n * @param options\n */\nexport function applyPagination<T extends ObjectLiteral = ObjectLiteral>(\n query: SelectQueryBuilder<T>,\n data: unknown,\n options?: QueryPaginationApplyOptions,\n) : QueryPaginationApplyOutput {\n return applyQueryPagination(query, data, options);\n}\n","import type { RelationsParseOutput } from 'rapiq';\nimport { parseQueryRelations } from 'rapiq';\nimport type { ObjectLiteral, SelectQueryBuilder } from 'typeorm';\nimport { buildKeyWithPrefix } from '../../utils';\nimport type { QueryRelationsApplyOptions, QueryRelationsApplyOutput } from './type';\n\n/**\n * Apply parsed include/relation parameter data on the db query.\n *\n * @param query\n * @param data\n * @param options\n */\nexport function applyQueryRelationsParseOutput<T extends ObjectLiteral = ObjectLiteral>(\n query: SelectQueryBuilder<T>,\n data: RelationsParseOutput,\n options?: QueryRelationsApplyOptions<T>,\n) : QueryRelationsApplyOutput {\n options = options || {};\n for (let i = 0; i < data.length; i++) {\n const parts = data[i].key.split('.');\n\n let key : string;\n if (parts.length > 1) {\n key = parts.slice(-2).join('.');\n } else {\n key = buildKeyWithPrefix(data[i].key, options.defaultAlias);\n }\n\n data[i].key = key;\n\n /* istanbul ignore next */\n query.leftJoinAndSelect(key, data[i].value);\n }\n\n return data;\n}\n\n/**\n * Apply raw include/relations parameter data on the db query.\n *\n * @param query\n * @param data\n * @param options\n */\nexport function applyQueryRelations<T extends ObjectLiteral = ObjectLiteral>(\n query: SelectQueryBuilder<T>,\n data: unknown,\n options?: QueryRelationsApplyOptions<T>,\n) : QueryRelationsApplyOutput {\n return applyQueryRelationsParseOutput(query, parseQueryRelations(data, options), options);\n}\n\n/**\n * Apply raw include/relations parameter data on the db query.\n *\n * @param query\n * @param data\n * @param options\n */\nexport function applyRelations<T extends ObjectLiteral = ObjectLiteral>(\n query: SelectQueryBuilder<T>,\n data: unknown,\n options?: QueryRelationsApplyOptions<T>,\n) : QueryRelationsApplyOutput {\n return applyQueryRelations(query, data, options);\n}\n","import type { SortDirection, SortParseOutput } from 'rapiq';\nimport { parseQuerySort } from 'rapiq';\nimport type { ObjectLiteral, SelectQueryBuilder } from 'typeorm';\nimport { buildKeyWithPrefix } from '../../utils';\nimport type { QuerySortApplyOptions, QuerySortApplyOutput } from './type';\n\n// --------------------------------------------------\n\n/**\n * Apply parsed sort parameter data on the db query.\n *\n * @param query\n * @param data\n */\nexport function applyQuerySortParseOutput<T extends ObjectLiteral = ObjectLiteral>(\n query: SelectQueryBuilder<T>,\n data: SortParseOutput,\n) : QuerySortApplyOutput {\n if (data.length === 0) {\n return data;\n }\n\n const sort : Record<string, `${SortDirection}`> = {};\n\n for (let i = 0; i < data.length; i++) {\n const key = buildKeyWithPrefix(data[i].key, data[i].path);\n\n sort[key] = data[i].value;\n }\n\n query.orderBy(sort);\n\n return data;\n}\n\n/**\n * Apply raw sort parameter data on the db query.\n *\n * @param query\n * @param data\n * @param options\n */\nexport function applyQuerySort<T extends ObjectLiteral = ObjectLiteral>(\n query: SelectQueryBuilder<T>,\n data: unknown,\n options?: QuerySortApplyOptions<T>,\n) : SortParseOutput {\n options = options || {};\n if (options.defaultAlias) {\n options.defaultPath = options.defaultAlias;\n }\n\n return applyQuerySortParseOutput(query, parseQuerySort(data, options));\n}\n\n/**\n * Apply raw sort parameter data on the db query.\n *\n * @param query\n * @param data\n * @param options\n */\nexport function applySort<T extends ObjectLiteral = ObjectLiteral>(\n query: SelectQueryBuilder<T>,\n data: unknown,\n options?: QuerySortApplyOptions<T>,\n) : SortParseOutput {\n return applyQuerySort(query, data, options);\n}\n","import type { ParseInput, ParseOutput } from 'rapiq';\nimport { parseQuery } from 'rapiq';\nimport type { ObjectLiteral, SelectQueryBuilder } from 'typeorm';\nimport {\n applyQueryFieldsParseOutput,\n applyQueryFiltersParseOutput,\n applyQueryPaginationParseOutput,\n applyQueryRelationsParseOutput,\n applyQuerySortParseOutput,\n} from './parameter';\nimport type { QueryApplyOptions, QueryApplyOutput } from './type';\nimport { isQueryOptionDefined } from './utils';\n\nexport function applyQueryParseOutput<T extends ObjectLiteral = ObjectLiteral>(\n query: SelectQueryBuilder<T>,\n context: ParseOutput,\n): ParseOutput {\n if (context.fields) {\n applyQueryFieldsParseOutput(query, context.fields, {\n defaultAlias: context.defaultPath,\n relations: context.relations,\n });\n }\n\n if (context.filters) {\n applyQueryFiltersParseOutput(query, context.filters, {\n defaultAlias: context.defaultPath,\n relations: context.relations,\n });\n }\n\n if (context.pagination) {\n applyQueryPaginationParseOutput(query, context.pagination);\n }\n\n if (context.relations) {\n applyQueryRelationsParseOutput(query, context.relations, {\n defaultAlias: context.defaultPath,\n });\n }\n\n if (context.sort) {\n applyQuerySortParseOutput(query, context.sort);\n }\n\n return context;\n}\n\nexport function applyQuery<T extends ObjectLiteral = ObjectLiteral>(\n query: SelectQueryBuilder<T>,\n input: ParseInput,\n options?: QueryApplyOptions<T>,\n) : QueryApplyOutput {\n options = options || {};\n\n if (options.defaultAlias) {\n options.defaultPath = options.defaultAlias;\n }\n\n if (\n typeof options.fields === 'undefined' ||\n !isQueryOptionDefined(options.fields, ['allowed', 'default'])\n ) {\n options.fields = false;\n }\n\n if (\n typeof options.filters === 'undefined' ||\n !isQueryOptionDefined(options.filters, ['allowed', 'default'])\n ) {\n options.filters = false;\n }\n\n if (\n typeof options.pagination === 'undefined'\n ) {\n options.pagination = false;\n }\n\n if (\n typeof options.relations === 'undefined' ||\n !isQueryOptionDefined(options.relations, ['allowed'])\n ) {\n options.relations = false;\n }\n\n if (\n typeof options.sort === 'undefined' ||\n !isQueryOptionDefined(options.sort, ['allowed', 'default'])\n ) {\n options.sort = false;\n }\n\n const output = applyQueryParseOutput(query, parseQuery(input, options));\n\n return {\n ...output,\n ...(options.defaultAlias ? { defaultAlias: options.defaultAlias } : {}),\n };\n}\n","import {\n isObject,\n load,\n locate,\n removeFileNameExtension,\n} from 'locter';\nimport path from 'node:path';\nimport type { DataSource } from 'typeorm';\nimport { InstanceChecker } from 'typeorm';\nimport {\n adjustFilePath,\n isPromise,\n readTSConfig,\n safeReplaceWindowsSeparator,\n} from '../../utils';\nimport type { DataSourceFindOptions } from './type';\nimport type { TSConfig } from '../../utils';\n\nexport async function findDataSource(\n context: DataSourceFindOptions = {},\n) : Promise<DataSource | undefined> {\n let tsconfig : TSConfig | undefined;\n if (!context.preserveFilePaths) {\n if (isObject(context.tsconfig)) {\n tsconfig = context.tsconfig;\n } else {\n tsconfig = await readTSConfig(context.tsconfig);\n }\n }\n\n const files : string[] = [\n 'data-source',\n ];\n\n if (context.fileName) {\n context.fileName = removeFileNameExtension(\n context.fileName,\n ['.ts', '.mts', '.cts', '.js', '.mjs', '.cjs'],\n );\n\n if (context.fileName !== 'data-source') {\n files.unshift(context.fileName);\n }\n }\n\n let { directory } = context;\n let directoryIsPattern = false;\n if (context.directory) {\n if (path.isAbsolute(context.directory)) {\n directory = context.directory;\n } else {\n directoryIsPattern = true;\n directory = safeReplaceWindowsSeparator(context.directory);\n }\n\n if (!context.preserveFilePaths) {\n directory = await adjustFilePath(directory, tsconfig);\n }\n }\n\n const lookupPaths = [];\n for (let j = 0; j < files.length; j++) {\n if (\n directory &&\n directoryIsPattern\n ) {\n lookupPaths.push(path.posix.join(directory, files[j]));\n }\n\n lookupPaths.push(...[\n path.posix.join('src', files[j]),\n path.posix.join('src/{db,database}', files[j]),\n ]);\n }\n\n files.push(...lookupPaths);\n\n if (!context.preserveFilePaths) {\n for (let j = 0; j < files.length; j++) {\n files[j] = await adjustFilePath(files[j], tsconfig);\n }\n }\n\n for (let i = 0; i < files.length; i++) {\n const info = await locate(\n `${files[i]}.{js,cjs,mjs,ts,cts,mts}`,\n {\n path: [\n process.cwd(),\n ...(directory && !directoryIsPattern ? [directory] : []),\n ],\n ignore: ['**/*.d.ts'],\n },\n );\n\n if (info) {\n let moduleRecord = await load(info);\n\n if (isPromise(moduleRecord)) {\n moduleRecord = await moduleRecord;\n }\n\n if (InstanceChecker.isDataSource(moduleRecord)) {\n return moduleRecord;\n }\n\n if (!isObject(moduleRecord)) {\n continue;\n }\n\n const keys = Object.keys(moduleRecord);\n for (let j = 0; j < keys.length; j++) {\n let value = moduleRecord[keys[j]];\n\n if (isPromise(value)) {\n value = await value;\n }\n\n if (InstanceChecker.isDataSource(value)) {\n return value;\n }\n }\n }\n }\n\n return undefined;\n}\n","/*\n * Copyright (c) 2023-2023.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nexport enum EnvironmentName {\n DEVELOPMENT = 'development',\n PRODUCTION = 'production',\n TEST = 'test',\n}\n\nexport enum EnvironmentVariableName {\n ENV = 'NODE_ENV',\n\n // Seeder\n SEEDS = 'DB_SEEDS',\n SEEDS_ALT = 'TYPEORM_SEEDING_SEEDS',\n\n FACTORIES = 'DB_FACTORIES',\n FACTORIES_ALT = 'TYPEORM_SEEDING_FACTORIES',\n\n // Database\n TYPE = 'DB_TYPE',\n TYPE_ALT = 'TYPEORM_CONNECTION',\n\n URL = 'DB_URL',\n URL_ALT = 'TYPEORM_URL',\n\n HOST = 'DB_HOST',\n HOST_ALT = 'TYPEORM_HOST',\n\n PORT = 'DB_PORT',\n PORT_ALT = 'TYPEORM_PORT',\n\n USERNAME = 'DB_USERNAME',\n USERNAME_ALT = 'TYPEORM_USERNAME',\n\n PASSWORD = 'DB_PASSWORD',\n PASSWORD_ALT = 'TYPEORM_PASSWORD',\n\n DATABASE = 'DB_DATABASE',\n DATABASE_ALT = 'TYPEORM_DATABASE',\n\n SID = 'DB_SID',\n SID_ALT = 'TYPEORM_SID',\n\n SCHEMA = 'DB_SCHEMA',\n SCHEMA_ALT = 'TYPEORM_SCHEMA',\n\n SCHEMA_DROP = 'DB_DROP_SCHEMA',\n SCHEMA_DROP_ALT = 'TYPEORM_DROP_SCHEMA',\n\n DRIVER_EXTRA = 'DB_DRIVER_EXTRA',\n DRIVER_EXTRA_ALT = 'TYPEORM_DRIVER_EXTRA',\n\n SYNCHRONIZE = 'DB_SYNCHRONIZE',\n SYNCHRONIZE_ALT = 'TYPEORM_SYNCHRONIZE',\n\n MIGRATIONS = 'DB_MIGRATIONS',\n MIGRATIONS_ALT = 'TYPEORM_MIGRATIONS',\n\n MIGRATIONS_RUN = 'DB_MIGRATIONS_RUN',\n MIGRATIONS_RUN_ALT = 'TYPEORM_MIGRATIONS_RUN',\n\n MIGRATIONS_TABLE_NAME = 'DB_MIGRATIONS_TABLE_NAME',\n MIGRATIONS_TABLE_NAME_ALT = 'TYPEORM_MIGRATIONS_TABLE_NAME',\n\n ENTITIES = 'DB_ENTITIES',\n ENTITIES_ALT = 'TYPEORM_ENTITIES',\n\n ENTITY_PREFIX = 'DB_ENTITY_PREFIX',\n ENTITY_PREFIX_ALT = 'TYPEORM_ENTITY_PREFIX',\n\n METADATA_TABLE_NAME = 'DB_METADATA_TABLE_NAME',\n METADATA_TABLE_NAME_ALT = 'TYPEORM_METADATA_TABLE_NAME',\n\n SUBSCRIBERS = 'DB_SUBSCRIBERS',\n SUBSCRIBERS_ALT = 'TYPEORM_SUBSCRIBERS',\n\n LOGGING = 'DB_LOGGING',\n LOGGING_ALT = 'TYPEORM_LOGGING',\n\n LOGGER = 'DB_LOGGER',\n LOGGER_ALT = 'TYPEORM_LOGGER',\n\n MAX_QUERY_EXECUTION_TIME = 'DB_MAX_QUERY_EXECUTION_TIME',\n MAX_QUERY_EXECUTION_TIME_ALT = 'TYPEORM_MAX_QUERY_EXECUTION_TIME',\n\n DEBUG = 'DB_DEBUG',\n DEBUG_ALT = 'TYPEORM_DEBUG',\n\n UUID_EXTENSION = 'DB_UUID_EXTENSION',\n UUID_EXTENSION_ALT = 'TYPEORM_UUID_EXTENSION',\n\n CACHE = 'DB_CACHE',\n CACHE_ALT = 'TYPEORM_CACHE',\n\n CACHE_ALWAYS_ENABLED = 'DB_CACHE_ALWAYS_ENABLED',\n CACHE_ALWAYS_ENABLED_ALT = 'TYPEORM_CACHE_ALWAYS_ENABLED',\n\n CACHE_OPTIONS = 'DB_CACHE_OPTIONS',\n CACHE_OPTIONS_ALT = 'TYPEORM_CACHE_OPTIONS',\n\n CACHE_DURATION = 'DB_CACHE_DURATION',\n CACHE_DURATION_ALT = 'TYPEORM_CACHE_DURATION',\n}\n","import {\n oneOf, read, readBool, readInt, toArray, toBool,\n} from 'envix';\nimport type { DataSourceCacheOption } from '../data-source';\nimport { EnvironmentVariableName } from './constants';\n\nexport function transformLogging(input?: string) : boolean | string | string[] {\n const value = toBool(input);\n if (typeof value === 'boolean') {\n return value;\n }\n\n if (input === 'all') {\n return 'all';\n }\n\n return toArray(input) ?? [];\n}\n\nexport function transformCache(input?: string) : DataSourceCacheOption | undefined {\n const value = toBool(input);\n if (typeof value === 'boolean') {\n return value;\n }\n\n if (\n input === 'redis' ||\n input === 'ioredis' ||\n input === 'database' ||\n input === 'ioredis/cluster'\n ) {\n let options : Record<string, any> | undefined;\n const envCacheOptions = oneOf([\n read(EnvironmentVariableName.CACHE_OPTIONS),\n read(EnvironmentVariableName.CACHE_OPTIONS_ALT),\n ]);\n if (envCacheOptions) {\n options = JSON.parse(envCacheOptions);\n }\n\n return {\n type: input,\n options,\n alwaysEnabled: oneOf([\n readBool(EnvironmentVariableName.CACHE_ALWAYS_ENABLED),\n readBool(EnvironmentVariableName.CACHE_ALWAYS_ENABLED_ALT),\n ]),\n duration: oneOf([\n readInt(EnvironmentVariableName.CACHE_DURATION),\n readInt(EnvironmentVariableName.CACHE_DURATION_ALT),\n ]),\n };\n }\n\n return undefined;\n}\n","import {\n oneOf, read, readArray, readBool, readInt,\n} from 'envix';\nimport type { DatabaseType } from 'typeorm/driver/types/DatabaseType';\nimport { EnvironmentName, EnvironmentVariableName } from './constants';\nimport type { Environment } from './type';\nimport {\n transformCache,\n transformLogging,\n} from './utils';\n\nlet instance : Environment | undefined;\n\nexport function useEnv() : Environment;\nexport function useEnv<K extends keyof Environment>(key: K) : Environment[K];\nexport function useEnv(key?: string) : any {\n if (typeof instance !== 'undefined') {\n if (typeof key === 'string') {\n return instance[key as keyof Environment];\n }\n\n return instance;\n }\n\n const output: Environment = {\n env: read(EnvironmentVariableName.ENV, EnvironmentName.DEVELOPMENT) as `${EnvironmentName}`,\n\n // Seeder\n seeds: oneOf([\n readArray(EnvironmentVariableName.SEEDS),\n readArray(EnvironmentVariableName.SEEDS_ALT),\n ]) ?? [],\n factories: oneOf([\n readArray(EnvironmentVariableName.FACTORIES),\n readArray(EnvironmentVariableName.FACTORIES_ALT),\n ]) ?? [],\n\n // Database\n url: oneOf([\n read(EnvironmentVariableName.URL),\n read(EnvironmentVariableName.URL_ALT),\n ]),\n host: oneOf([\n read(EnvironmentVariableName.HOST),\n read(EnvironmentVariableName.HOST_ALT),\n ]),\n port: oneOf([\n readInt(EnvironmentVariableName.PORT),\n readInt(EnvironmentVariableName.PORT_ALT),\n ]),\n username: oneOf([\n read(EnvironmentVariableName.USERNAME),\n read(EnvironmentVariableName.USERNAME_ALT),\n ]),\n password: oneOf([\n read(EnvironmentVariableName.PASSWORD),\n read(EnvironmentVariableName.PASSWORD_ALT),\n ]),\n database: oneOf([\n read(EnvironmentVariableName.DATABASE),\n read(EnvironmentVariableName.DATABASE_ALT),\n ]),\n sid: oneOf([\n read(EnvironmentVariableName.SID),\n read(EnvironmentVariableName.SID_ALT),\n ]),\n schema: oneOf([\n read(EnvironmentVariableName.SCHEMA),\n read(EnvironmentVariableName.SCHEMA_ALT),\n ]),\n extra: oneOf([\n read(EnvironmentVariableName.DRIVER_EXTRA),\n read(EnvironmentVariableName.DRIVER_EXTRA_ALT),\n ]),\n synchronize: oneOf([\n readBool(EnvironmentVariableName.SYNCHRONIZE),\n readBool(EnvironmentVariableName.SYNCHRONIZE_ALT),\n ]),\n schemaDrop: oneOf([\n readBool(EnvironmentVariableName.SCHEMA_DROP),\n readBool(EnvironmentVariableName.SCHEMA_DROP_ALT),\n ]),\n migrationsRun: oneOf([\n readBool(EnvironmentVariableName.MIGRATIONS_RUN),\n readBool(EnvironmentVariableName.MIGRATIONS_RUN_ALT),\n ]),\n entities: oneOf([\n readArray(EnvironmentVariableName.ENTITIES),\n readArray(EnvironmentVariableName.ENTITIES_ALT),\n ]) ?? [],\n migrations: oneOf([\n readArray(EnvironmentVariableName.MIGRATIONS),\n readArray(EnvironmentVariableName.MIGRATIONS_ALT),\n ]) ?? [],\n migrationsTableName: oneOf([\n read(EnvironmentVariableName.MIGRATIONS_TABLE_NAME),\n read(EnvironmentVariableName.MIGRATIONS_TABLE_NAME_ALT),\n ]),\n metadataTableName: oneOf([\n read(EnvironmentVariableName.METADATA_TABLE_NAME),\n read(EnvironmentVariableName.METADATA_TABLE_NAME_ALT),\n ]),\n subscribers: oneOf([\n readArray(EnvironmentVariableName.SUBSCRIBERS),\n readArray(EnvironmentVariableName.SUBSCRIBERS_ALT),\n ]) ?? [],\n logging: transformLogging(oneOf([\n read(EnvironmentVariableName.LOGGING),\n read(EnvironmentVariableName.LOGGING_ALT),\n ])),\n logger: oneOf([\n read(EnvironmentVariableName.LOGGER),\n read(EnvironmentVariableName.LOGGER_ALT),\n ]),\n entityPrefix: oneOf([\n read(EnvironmentVariableName.ENTITY_PREFIX),\n read(EnvironmentVariableName.ENTITY_PREFIX_ALT),\n ]),\n maxQueryExecutionTime: oneOf([\n readInt(EnvironmentVariableName.MAX_QUERY_EXECUTION_TIME),\n readInt(EnvironmentVariableName.MAX_QUERY_EXECUTION_TIME_ALT),\n ]),\n debug: oneOf([\n read(EnvironmentVariableName.DEBUG),\n read(EnvironmentVariableName.DEBUG_ALT),\n ]),\n cache: transformCache(oneOf([\n read(EnvironmentVariableName.CACHE),\n read(EnvironmentVariableName.CACHE_ALT),\n ])),\n uuidExtension: oneOf([\n read(EnvironmentVariableName.UUID_EXTENSION),\n read(EnvironmentVariableName.UUID_EXTENSION_ALT),\n ]),\n\n };\n\n if (output.extra) {\n output.extra = JSON.parse(output.extra); // todo: ensure record<string,any> ??\n }\n\n let type : string | undefined;\n const envType = oneOf([\n read(EnvironmentVariableName.TYPE),\n read(EnvironmentVariableName.TYPE_ALT),\n ]);\n\n if (envType) {\n type = envType;\n } else {\n const envURL = oneOf([\n read(EnvironmentVariableName.URL),\n read(EnvironmentVariableName.URL_ALT),\n ]);\n\n if (envURL) {\n [type] = envURL.split('://');\n }\n }\n\n if (type) {\n output.type = type as DatabaseType; // todo: maybe validation here\n }\n\n instance = output;\n\n if (typeof key === 'string') {\n return output[key as keyof Environment];\n }\n\n return instance;\n}\n\nexport function resetEnv() {\n if (typeof instance !== 'undefined') {\n instance = undefined;\n }\n}\n","import { createMerger } from 'smob';\nimport type { DataSourceOptions } from 'typeorm';\n\nconst merge = createMerger({\n strategy: (target, key, value) => {\n if (typeof target[key] === 'undefined') {\n target[key] = value;\n\n return target;\n }\n\n return undefined;\n },\n});\n\nexport function mergeDataSourceOptions(\n target: DataSourceOptions,\n source: DataSourceOptions,\n) {\n if (target.type !== source.type) {\n return target;\n }\n\n return merge(target, source);\n}\n","import type { DataSourceOptions } from 'typeorm';\nimport type { BaseDataSourceOptions } from 'typeorm/data-source/BaseDataSourceOptions';\nimport type { PostgresConnectionOptions } from 'typeorm/driver/postgres/PostgresConnectionOptions';\nimport type { DatabaseType } from 'typeorm/driver/types/DatabaseType';\nimport type { LoggerOptions } from 'typeorm/logger/LoggerOptions';\nimport { useEnv } from '../../../env';\nimport { mergeDataSourceOptions } from './merge';\n\nexport function hasEnvDataSourceOptions() : boolean {\n return !!useEnv('type');\n}\n\n/* istanbul ignore next */\nexport function readDataSourceOptionsFromEnv() : DataSourceOptions | undefined {\n if (!hasEnvDataSourceOptions()) {\n return undefined;\n }\n\n // todo: include seeder options\n const base : Omit<BaseDataSourceOptions, 'poolSize'> = {\n type: useEnv('type') as DatabaseType,\n entities: useEnv('entities'),\n subscribers: useEnv('subscribers'),\n migrations: useEnv('migrations'),\n migrationsTableName: useEnv('migrationsTableName'),\n // migrationsTransactionMode: useEnv('migra')\n metadataTableName: useEnv('metadataTableName'),\n logging: useEnv('logging') as LoggerOptions,\n logger: useEnv('logger') as BaseDataSourceOptions['logger'],\n maxQueryExecutionTime: useEnv('maxQueryExecutionTime'),\n synchronize: useEnv('synchronize'),\n migrationsRun: useEnv('migrationsRun'),\n dropSchema: useEnv('schemaDrop'),\n entityPrefix: useEnv('entityPrefix'),\n extra: useEnv('extra'),\n cache: useEnv('cache'),\n };\n\n const credentialOptions = {\n url: useEnv('url'),\n host: useEnv('host'),\n port: useEnv('port'),\n username: useEnv('username'),\n password: useEnv('password'),\n database: useEnv('database'),\n };\n\n if (base.type === 'mysql' || base.type === 'mariadb') {\n return {\n ...base,\n ...credentialOptions,\n type: base.type,\n };\n }\n\n if (base.type === 'postgres') {\n return {\n ...base,\n ...credentialOptions,\n type: base.type,\n schema: useEnv('schema'),\n uuidExtension: useEnv('uuidExtension') as PostgresConnectionOptions['uuidExtension'],\n };\n }\n\n if (base.type === 'cockroachdb') {\n return {\n ...base,\n ...credentialOptions,\n type: base.type,\n schema: useEnv('schema'),\n timeTravelQueries: true,\n };\n }\n\n if (base.type === 'sqlite') {\n return {\n ...base,\n type: base.type,\n database: useEnv('database') || 'db.sqlite',\n };\n }\n\n if (base.type === 'better-sqlite3') {\n return {\n ...base,\n type: base.type,\n database: useEnv('database') || 'db.sqlite',\n };\n }\n\n if (base.type === 'mssql') {\n return {\n ...base,\n ...credentialOptions,\n type: base.type,\n schema: useEnv('schema'),\n };\n }\n\n if (base.type === 'oracle') {\n