From b4cebd92190c74183b07f964a830eb2349cab6fb Mon Sep 17 00:00:00 2001 From: Dan Kochetov Date: Tue, 18 Apr 2023 23:37:55 +0300 Subject: [PATCH] Improve ESLint config and fix its errors --- .eslintignore | 1 + .eslintrc.yaml | 38 ++- drizzle-orm/src/alias.ts | 4 +- drizzle-orm/src/aws-data-api/common/index.ts | 35 ++- drizzle-orm/src/aws-data-api/pg/session.ts | 10 +- drizzle-orm/src/better-sqlite3/session.ts | 16 +- drizzle-orm/src/bun-sqlite/session.ts | 12 +- drizzle-orm/src/d1/session.ts | 8 +- drizzle-orm/src/errors.ts | 8 +- drizzle-orm/src/libsql/session.ts | 16 +- drizzle-orm/src/logger.ts | 10 +- drizzle-orm/src/migrator.ts | 8 +- drizzle-orm/src/mysql-core/columns/bigint.ts | 3 +- drizzle-orm/src/mysql-core/columns/binary.ts | 2 +- drizzle-orm/src/mysql-core/columns/char.ts | 2 +- drizzle-orm/src/mysql-core/columns/custom.ts | 12 +- .../src/mysql-core/columns/datetime.ts | 4 +- drizzle-orm/src/mysql-core/columns/decimal.ts | 4 +- drizzle-orm/src/mysql-core/columns/double.ts | 5 +- drizzle-orm/src/mysql-core/columns/enum.ts | 4 +- drizzle-orm/src/mysql-core/columns/int.ts | 2 +- .../src/mysql-core/columns/mediumint.ts | 2 +- drizzle-orm/src/mysql-core/columns/real.ts | 4 +- drizzle-orm/src/mysql-core/columns/serial.ts | 2 +- .../src/mysql-core/columns/smallint.ts | 2 +- drizzle-orm/src/mysql-core/columns/time.ts | 2 +- .../src/mysql-core/columns/timestamp.ts | 4 +- drizzle-orm/src/mysql-core/columns/tinyint.ts | 2 +- .../src/mysql-core/columns/varbinary.ts | 2 +- drizzle-orm/src/mysql-core/columns/varchar.ts | 2 +- drizzle-orm/src/mysql-core/dialect.ts | 71 +++--- drizzle-orm/src/mysql-core/indexes.ts | 1 + .../src/mysql-core/query-builders/delete.ts | 5 +- .../src/mysql-core/query-builders/insert.ts | 25 +- .../src/mysql-core/query-builders/select.ts | 15 +- .../src/mysql-core/query-builders/update.ts | 4 +- drizzle-orm/src/mysql-core/utils.ts | 6 +- drizzle-orm/src/mysql2/session.ts | 22 +- drizzle-orm/src/neon-serverless/session.ts | 8 +- drizzle-orm/src/node-postgres/session.ts | 8 +- drizzle-orm/src/pg-core/columns/bigint.ts | 3 +- drizzle-orm/src/pg-core/columns/bigserial.ts | 3 +- drizzle-orm/src/pg-core/columns/char.ts | 2 +- drizzle-orm/src/pg-core/columns/custom.ts | 12 +- .../src/pg-core/columns/double-precision.ts | 2 +- drizzle-orm/src/pg-core/columns/integer.ts | 2 +- drizzle-orm/src/pg-core/columns/json.ts | 2 +- drizzle-orm/src/pg-core/columns/jsonb.ts | 2 +- drizzle-orm/src/pg-core/columns/numeric.ts | 4 +- drizzle-orm/src/pg-core/columns/real.ts | 2 +- drizzle-orm/src/pg-core/columns/smallint.ts | 2 +- drizzle-orm/src/pg-core/columns/time.ts | 2 +- drizzle-orm/src/pg-core/columns/timestamp.ts | 4 +- drizzle-orm/src/pg-core/columns/varchar.ts | 2 +- drizzle-orm/src/pg-core/dialect.ts | 62 ++--- drizzle-orm/src/pg-core/foreign-keys.ts | 4 +- drizzle-orm/src/pg-core/indexes.ts | 1 + .../src/pg-core/query-builders/delete.ts | 4 +- .../src/pg-core/query-builders/insert.ts | 31 +-- .../refresh-materialized-view.ts | 7 +- .../src/pg-core/query-builders/select.ts | 14 +- .../src/pg-core/query-builders/update.ts | 3 +- drizzle-orm/src/pg-core/schema.ts | 2 +- drizzle-orm/src/pg-core/utils.ts | 12 +- .../src/planetscale-serverless/session.ts | 10 +- drizzle-orm/src/postgres-js/session.ts | 16 +- drizzle-orm/src/query-promise.ts | 2 +- drizzle-orm/src/sql-js/session.ts | 26 +- drizzle-orm/src/sql/expressions/conditions.ts | 60 ++--- drizzle-orm/src/sql/index.ts | 48 ++-- drizzle-orm/src/sqlite-core/checks.ts | 2 +- drizzle-orm/src/sqlite-core/columns/custom.ts | 12 +- drizzle-orm/src/sqlite-core/dialect.ts | 76 +++--- .../src/sqlite-core/query-builders/delete.ts | 7 +- .../src/sqlite-core/query-builders/insert.ts | 19 +- .../src/sqlite-core/query-builders/select.ts | 15 +- .../src/sqlite-core/query-builders/update.ts | 7 +- drizzle-orm/src/sqlite-core/table.ts | 2 - drizzle-orm/src/sqlite-core/utils.ts | 6 +- drizzle-orm/src/sqlite-proxy/migrator.ts | 36 ++- drizzle-orm/src/sqlite-proxy/session.ts | 24 +- drizzle-orm/src/subquery.ts | 4 +- drizzle-orm/src/utils.ts | 23 +- drizzle-orm/type-tests/knex/index.ts | 11 - drizzle-orm/type-tests/mysql/select.ts | 4 +- drizzle-orm/type-tests/mysql/tables.ts | 8 +- drizzle-orm/type-tests/pg/select.ts | 20 +- drizzle-orm/type-tests/pg/tables.ts | 20 +- drizzle-orm/type-tests/sqlite/insert.ts | 10 +- drizzle-orm/type-tests/sqlite/select.ts | 2 +- drizzle-orm/type-tests/sqlite/tables.ts | 4 +- drizzle-orm/type-tests/utils.ts | 1 + drizzle-zod/src/index.ts | 16 +- drizzle-zod/tests/pg.test.ts | 4 +- drizzle-zod/tests/sqlite.test.ts | 8 +- drizzle-zod/tests/utils.ts | 4 +- drizzle-zod/utils.ts | 1 + .../tests/awsdatapi.alltypes.test.ts | 122 ++++----- integration-tests/tests/awsdatapi.test.ts | 22 +- integration-tests/tests/better-sqlite.test.ts | 40 +-- integration-tests/tests/bun/sqlite.test.ts | 15 +- integration-tests/tests/libsql.test.ts | 45 ++-- integration-tests/tests/mysql-schema.test.ts | 97 +++---- integration-tests/tests/mysql.custom.test.ts | 78 +++--- integration-tests/tests/mysql.test.ts | 120 +++++---- integration-tests/tests/pg-schema.test.ts | 58 +++-- integration-tests/tests/pg.custom.test.ts | 20 +- integration-tests/tests/pg.test.ts | 212 ++++++++++------ .../planetscale-serverless/mysql.test.ts | 54 ++-- integration-tests/tests/postgres.js.test.ts | 115 +++++---- integration-tests/tests/sql.js.test.ts | 40 +-- integration-tests/tests/sqlite-proxy.test.ts | 34 +-- integration-tests/tests/utils.ts | 2 + package.json | 1 + pnpm-lock.yaml | 236 +++++++++++++++++- 115 files changed, 1375 insertions(+), 1019 deletions(-) diff --git a/.eslintignore b/.eslintignore index f06235c46..df9377dd5 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,2 +1,3 @@ node_modules dist +examples diff --git a/.eslintrc.yaml b/.eslintrc.yaml index 26abdb39c..faf2d1c5b 100644 --- a/.eslintrc.yaml +++ b/.eslintrc.yaml @@ -1,6 +1,8 @@ root: true extends: - - 'plugin:@typescript-eslint/base' + - 'eslint:recommended' + - 'plugin:@typescript-eslint/recommended' + - 'plugin:unicorn/recommended' parser: '@typescript-eslint/parser' plugins: - import @@ -17,3 +19,37 @@ rules: import/no-useless-path-segments: error import/newline-after-import: error import/no-duplicates: error + '@typescript-eslint/no-explicit-any': 'off' + '@typescript-eslint/no-non-null-assertion': 'off' + '@typescript-eslint/no-namespace': 'off' + '@typescript-eslint/no-unused-vars': + - error + - argsIgnorePattern: '^_' + varsIgnorePattern: '^_' + '@typescript-eslint/ban-types': + - error + - extendDefaults: true + types: + '{}' : false + '@typescript-eslint/no-this-alias': 'off' + '@typescript-eslint/no-var-requires': 'off' + 'unicorn/prefer-node-protocol': 'off' + 'unicorn/prefer-top-level-await': 'off' + 'unicorn/prevent-abbreviations': 'off' + 'unicorn/prefer-switch': 'off' + 'unicorn/catch-error-name': 'off' + 'unicorn/no-null': 'off' + 'unicorn/numeric-separators-style': 'off' + 'unicorn/explicit-length-check': 'off' + 'unicorn/filename-case': 'off' + 'unicorn/prefer-module': 'off' + 'unicorn/no-array-reduce': 'off' + 'unicorn/no-nested-ternary': 'off' + 'unicorn/no-useless-undefined': + - error + - checkArguments: false + 'unicorn/no-this-assignment': 'off' + 'unicorn/empty-brace-spaces': 'off' + 'unicorn/no-thenable': 'off' + 'unicorn/consistent-function-scoping': 'off' + 'unicorn/prefer-type-error': 'off' diff --git a/drizzle-orm/src/alias.ts b/drizzle-orm/src/alias.ts index 03357761b..aa5799dff 100644 --- a/drizzle-orm/src/alias.ts +++ b/drizzle-orm/src/alias.ts @@ -6,7 +6,7 @@ import { type View, ViewBaseConfig } from './view'; export class ColumnAliasProxyHandler implements ProxyHandler { constructor(private table: Table | View) {} - get(columnObj: TColumn, prop: string | symbol, receiver: any): any { + get(columnObj: TColumn, prop: string | symbol): any { if (prop === 'table') { return this.table; } @@ -18,7 +18,7 @@ export class ColumnAliasProxyHandler implements Proxy export class TableAliasProxyHandler implements ProxyHandler { constructor(private alias: string, private replaceOriginalName: boolean) {} - get(tableObj: T, prop: string | symbol, receiver: any): any { + get(tableObj: T, prop: string | symbol): any { if (prop === Table.Symbol.Name) { return this.alias; } diff --git a/drizzle-orm/src/aws-data-api/common/index.ts b/drizzle-orm/src/aws-data-api/common/index.ts index 034083494..bae9bdfbe 100644 --- a/drizzle-orm/src/aws-data-api/common/index.ts +++ b/drizzle-orm/src/aws-data-api/common/index.ts @@ -1,27 +1,28 @@ -import type { Field} from '@aws-sdk/client-rds-data'; +import type { Field } from '@aws-sdk/client-rds-data'; import { TypeHint } from '@aws-sdk/client-rds-data'; import type { QueryTypingsValue } from '~/sql'; export function getValueFromDataApi(row: Field) { - if (typeof row.stringValue !== 'undefined') { + if (row.stringValue !== undefined) { return row.stringValue; - } else if (typeof row.booleanValue !== 'undefined') { + } else if (row.booleanValue !== undefined) { return row.booleanValue; - } else if (typeof row.doubleValue !== 'undefined') { + } else if (row.doubleValue !== undefined) { return row.doubleValue; - } else if (typeof row.isNull !== 'undefined') { + } else if (row.isNull !== undefined) { return null; - } else if (typeof row.longValue !== 'undefined') { + } else if (row.longValue !== undefined) { return row.longValue; - } else if (typeof row.blobValue !== 'undefined') { + } else if (row.blobValue !== undefined) { return row.blobValue; - } else if (typeof row.arrayValue !== 'undefined') { - if (typeof row.arrayValue.stringValues !== 'undefined') { + // eslint-disable-next-line unicorn/no-negated-condition + } else if (row.arrayValue !== undefined) { + if (row.arrayValue.stringValues !== undefined) { return row.arrayValue.stringValues; } - throw Error('Unknown array type'); + throw new Error('Unknown array type'); } else { - throw Error('Unknown type'); + throw new Error('Unknown type'); } } @@ -44,7 +45,7 @@ export function typingsToAwsTypeHint(typings?: QueryTypingsValue): TypeHint | un } export function toValueParam(value: any, typings?: QueryTypingsValue): { value: Field; typeHint?: TypeHint } { - let response: { value: Field; typeHint?: TypeHint } = { + const response: { value: Field; typeHint?: TypeHint } = { value: {} as any, typeHint: typingsToAwsTypeHint(typings), }; @@ -52,11 +53,9 @@ export function toValueParam(value: any, typings?: QueryTypingsValue): { value: if (value === null) { response.value = { isNull: true }; } else if (typeof value === 'string') { - if (response.typeHint === 'DATE') { - response.value = { stringValue: value.split('T')[0]! }; - } else { - response.value = { stringValue: value }; - } + response.value = response.typeHint === 'DATE' + ? { stringValue: value.split('T')[0]! } + : { stringValue: value }; } else if (typeof value === 'number' && Number.isInteger(value)) { response.value = { longValue: value }; } else if (typeof value === 'number' && !Number.isInteger(value)) { @@ -66,7 +65,7 @@ export function toValueParam(value: any, typings?: QueryTypingsValue): { value: } else if (value instanceof Date) { response.value = { stringValue: value.toISOString().replace('T', ' ').replace('Z', '') }; } else { - throw Error(`Unknown type for ${value}`); + throw new Error(`Unknown type for ${value}`); } return response; diff --git a/drizzle-orm/src/aws-data-api/pg/session.ts b/drizzle-orm/src/aws-data-api/pg/session.ts index 69e7939bd..a9023ad29 100644 --- a/drizzle-orm/src/aws-data-api/pg/session.ts +++ b/drizzle-orm/src/aws-data-api/pg/session.ts @@ -56,21 +56,21 @@ export class AwsDataApiPreparedQuery extends Prep this.options.logger?.logQuery(this.rawQuery.input.sql!, this.rawQuery.input.parameters); - const { fields } = this; + const { fields, rawQuery, client, joinsNotNullableMap } = this; if (!fields) { - return await this.client.send(this.rawQuery); + return await client.send(rawQuery); } - const result = await this.client.send(this.rawQuery); + const result = await client.send(rawQuery); return result.records?.map((result: any) => { const mappedResult = result.map((res: any) => getValueFromDataApi(res)); - return mapResultRow(fields, mappedResult, this.joinsNotNullableMap); + return mapResultRow(fields, mappedResult, joinsNotNullableMap); }); } all(placeholderValues?: Record | undefined): Promise { - return this.execute(placeholderValues) + return this.execute(placeholderValues); } } diff --git a/drizzle-orm/src/better-sqlite3/session.ts b/drizzle-orm/src/better-sqlite3/session.ts index 0ce0396d6..442a0c4d9 100644 --- a/drizzle-orm/src/better-sqlite3/session.ts +++ b/drizzle-orm/src/better-sqlite3/session.ts @@ -78,32 +78,32 @@ export class PreparedQuery } all(placeholderValues?: Record): T['all'] { - const { fields } = this; + const { fields, joinsNotNullableMap, queryString, logger, stmt } = this; if (fields) { - return this.values(placeholderValues).map((row) => mapResultRow(fields, row, this.joinsNotNullableMap)); + return this.values(placeholderValues).map((row) => mapResultRow(fields, row, joinsNotNullableMap)); } const params = fillPlaceholders(this.params, placeholderValues ?? {}); - this.logger.logQuery(this.queryString, params); - return this.stmt.all(...params); + logger.logQuery(queryString, params); + return stmt.all(...params); } get(placeholderValues?: Record): T['get'] { const params = fillPlaceholders(this.params, placeholderValues ?? {}); this.logger.logQuery(this.queryString, params); - const { fields } = this; + const { fields, stmt, joinsNotNullableMap } = this; if (!fields) { - return this.stmt.get(...params); + return stmt.get(...params); } - const value = this.stmt.raw().get(...params); + const value = stmt.raw().get(...params); if (!value) { return undefined; } - return mapResultRow(fields, value, this.joinsNotNullableMap); + return mapResultRow(fields, value, joinsNotNullableMap); } values(placeholderValues?: Record): T['values'] { diff --git a/drizzle-orm/src/bun-sqlite/session.ts b/drizzle-orm/src/bun-sqlite/session.ts index 35a061fc2..40d3d202f 100644 --- a/drizzle-orm/src/bun-sqlite/session.ts +++ b/drizzle-orm/src/bun-sqlite/session.ts @@ -89,14 +89,14 @@ export class PreparedQuery } all(placeholderValues?: Record): T['all'] { - const { fields } = this; + const { fields, queryString, logger, joinsNotNullableMap, stmt } = this; if (fields) { - return this.values(placeholderValues).map((row) => mapResultRow(fields, row, this.joinsNotNullableMap)); + return this.values(placeholderValues).map((row) => mapResultRow(fields, row, joinsNotNullableMap)); } const params = fillPlaceholders(this.params, placeholderValues ?? {}); - this.logger.logQuery(this.queryString, params); - return this.stmt.all(...params); + logger.logQuery(queryString, params); + return stmt.all(...params); } get(placeholderValues?: Record): T['get'] { @@ -108,12 +108,12 @@ export class PreparedQuery return undefined; } - const { fields } = this; + const { fields, joinsNotNullableMap } = this; if (!fields) { return value; } - return mapResultRow(fields, value, this.joinsNotNullableMap); + return mapResultRow(fields, value, joinsNotNullableMap); } values(placeholderValues?: Record): T['values'] { diff --git a/drizzle-orm/src/d1/session.ts b/drizzle-orm/src/d1/session.ts index 559cb6766..4f518946d 100644 --- a/drizzle-orm/src/d1/session.ts +++ b/drizzle-orm/src/d1/session.ts @@ -90,16 +90,16 @@ export class PreparedQuery } all(placeholderValues?: Record): Promise { - const { fields } = this; + const { fields, joinsNotNullableMap, queryString, logger, stmt } = this; if (fields) { return this.values(placeholderValues).then((values) => - values.map((row) => mapResultRow(fields, row, this.joinsNotNullableMap)) + values.map((row) => mapResultRow(fields, row, joinsNotNullableMap)) ); } const params = fillPlaceholders(this.params, placeholderValues ?? {}); - this.logger.logQuery(this.queryString, params); - return this.stmt.bind(...params).all().then(({ results }) => results!); + logger.logQuery(queryString, params); + return stmt.bind(...params).all().then(({ results }) => results!); } get(placeholderValues?: Record): Promise { diff --git a/drizzle-orm/src/errors.ts b/drizzle-orm/src/errors.ts index 2e39a72b7..36d3d308d 100644 --- a/drizzle-orm/src/errors.ts +++ b/drizzle-orm/src/errors.ts @@ -5,11 +5,9 @@ export class DrizzleError extends Error { } static wrap(error: unknown, message?: string): DrizzleError { - if (error instanceof Error) { - return new DrizzleError(message ? `${message}: ${error.message}` : error.message, { cause: error }); - } else { - return new DrizzleError(message ?? String(error)); - } + return error instanceof Error + ? new DrizzleError(message ? `${message}: ${error.message}` : error.message, { cause: error }) + : new DrizzleError(message ?? String(error)); } } diff --git a/drizzle-orm/src/libsql/session.ts b/drizzle-orm/src/libsql/session.ts index b2f809d41..9a8c5ad73 100644 --- a/drizzle-orm/src/libsql/session.ts +++ b/drizzle-orm/src/libsql/session.ts @@ -48,7 +48,7 @@ export class LibSQLSession extends SQLiteSession<'async', ResultSet> { override async transaction( transaction: (db: LibSQLTransaction) => T | Promise, - config?: SQLiteTransactionConfig, + _config?: SQLiteTransactionConfig, ): Promise { // TODO: support transaction behavior const libsqlTx = await this.client.transaction(); @@ -103,7 +103,7 @@ export class PreparedQuery } all(placeholderValues?: Record): Promise { - const { fields } = this; + const { fields, joinsNotNullableMap, logger, queryString, tx, client } = this; if (fields) { const values = this.values(placeholderValues); @@ -111,17 +111,17 @@ export class PreparedQuery rows.map((row) => { return mapResultRow( fields, - Array.prototype.slice.call(row).map(normalizeFieldValue), - this.joinsNotNullableMap, + Array.prototype.slice.call(row).map((v) => normalizeFieldValue(v)), + joinsNotNullableMap, ); }) ); } const params = fillPlaceholders(this.params, placeholderValues ?? {}); - this.logger.logQuery(this.queryString, params); - const stmt: InStatement = { sql: this.queryString, args: params as InArgs }; - return (this.tx ? this.tx.execute(stmt) : this.client.execute(stmt)).then(({ rows }) => rows.map(normalizeRow)); + logger.logQuery(queryString, params); + const stmt: InStatement = { sql: queryString, args: params as InArgs }; + return (tx ? tx.execute(stmt) : client.execute(stmt)).then(({ rows }) => rows.map((row) => normalizeRow(row))); } get(placeholderValues?: Record): Promise { @@ -144,7 +144,7 @@ function normalizeRow(obj: any) { // turn them into objects what's what other SQLite drivers // do. return Object.keys(obj).reduce((acc: Record, key) => { - if (obj.propertyIsEnumerable(key)) { + if (Object.prototype.propertyIsEnumerable.call(obj, key)) { acc[key] = obj[key]; } return acc; diff --git a/drizzle-orm/src/logger.ts b/drizzle-orm/src/logger.ts index c79ab11d8..d9c179567 100644 --- a/drizzle-orm/src/logger.ts +++ b/drizzle-orm/src/logger.ts @@ -15,15 +15,15 @@ export class ConsoleLogWriter implements LogWriter { export class DefaultLogger implements Logger { readonly writer: LogWriter; - constructor(config: { writer: LogWriter } = { writer: new ConsoleLogWriter() }) { - this.writer = config.writer; + constructor(config?: { writer: LogWriter }) { + this.writer = config?.writer ?? new ConsoleLogWriter(); } logQuery(query: string, params: unknown[]): void { const stringifiedParams = params.map((p) => { try { return JSON.stringify(p); - } catch (e) { + } catch { return String(p); } }); @@ -33,5 +33,7 @@ export class DefaultLogger implements Logger { } export class NoopLogger implements Logger { - logQuery(): void {} + logQuery(): void { + // noop + } } diff --git a/drizzle-orm/src/migrator.ts b/drizzle-orm/src/migrator.ts index 7a9bbb800..87f185aaf 100644 --- a/drizzle-orm/src/migrator.ts +++ b/drizzle-orm/src/migrator.ts @@ -30,14 +30,14 @@ export function readMigrationFiles(config: string | MigrationConfig): MigrationM } if (!migrationFolderTo) { - throw Error('no migration folder defined'); + throw new Error('no migration folder defined'); } const migrationQueries: MigrationMeta[] = []; const journalPath = `${migrationFolderTo}/meta/_journal.json`; if (!fs.existsSync(journalPath)) { - throw Error(`Can't find meta/_journal.json file`); + throw new Error(`Can't find meta/_journal.json file`); } const journalAsString = fs.readFileSync(`${migrationFolderTo}/meta/_journal.json`).toString(); @@ -62,8 +62,8 @@ export function readMigrationFiles(config: string | MigrationConfig): MigrationM folderMillis: journalEntry.when, hash: crypto.createHash('sha256').update(query).digest('hex'), }); - } catch (e) { - throw Error(`No file ${migrationPath} found in ${migrationFolderTo} folder`); + } catch { + throw new Error(`No file ${migrationPath} found in ${migrationFolderTo} folder`); } } diff --git a/drizzle-orm/src/mysql-core/columns/bigint.ts b/drizzle-orm/src/mysql-core/columns/bigint.ts index e988b5b5e..f0a4dc6ee 100644 --- a/drizzle-orm/src/mysql-core/columns/bigint.ts +++ b/drizzle-orm/src/mysql-core/columns/bigint.ts @@ -44,7 +44,7 @@ export class MySqlBigInt53 extends MySqlColumnWithAu if (typeof value === 'number') { return value; } - return parseInt(value); + return Number(value); } } @@ -81,6 +81,7 @@ export class MySqlBigInt64 extends MySqlColumnWithAu return 'bigint'; } + // eslint-disable-next-line unicorn/prefer-native-coercion-functions override mapFromDriverValue(value: string): bigint { return BigInt(value); } diff --git a/drizzle-orm/src/mysql-core/columns/binary.ts b/drizzle-orm/src/mysql-core/columns/binary.ts index f30d28e3c..3ca7bc6e0 100644 --- a/drizzle-orm/src/mysql-core/columns/binary.ts +++ b/drizzle-orm/src/mysql-core/columns/binary.ts @@ -47,7 +47,7 @@ export class MySqlBinary extends MySqlColumn< length: number | undefined = this.config.length; getSQLType(): string { - return typeof this.length !== 'undefined' ? `binary(${this.length})` : `binary`; + return this.length === undefined ? `binary` : `binary(${this.length})`; } } diff --git a/drizzle-orm/src/mysql-core/columns/char.ts b/drizzle-orm/src/mysql-core/columns/char.ts index f7f3b6045..10994e6c9 100644 --- a/drizzle-orm/src/mysql-core/columns/char.ts +++ b/drizzle-orm/src/mysql-core/columns/char.ts @@ -49,7 +49,7 @@ export class MySqlChar readonly enumValues: T['enumValues'] = (this.config.enum ?? []) as T['enumValues']; getSQLType(): string { - return typeof this.length !== 'undefined' ? `char(${this.length})` : `char`; + return this.length === undefined ? `char` : `char(${this.length})`; } } diff --git a/drizzle-orm/src/mysql-core/columns/custom.ts b/drizzle-orm/src/mysql-core/columns/custom.ts index 5388cd8e4..9b34cb999 100644 --- a/drizzle-orm/src/mysql-core/columns/custom.ts +++ b/drizzle-orm/src/mysql-core/columns/custom.ts @@ -81,19 +81,11 @@ export class MySqlCustomColumn extends MySqlColumn readonly scale: number | undefined = this.config.scale; getSQLType(): string { - if (typeof this.precision !== 'undefined' && typeof this.scale !== 'undefined') { + if (this.precision !== undefined && this.scale !== undefined) { return `decimal(${this.precision},${this.scale})`; - } else if (typeof this.precision === 'undefined') { + } else if (this.precision === undefined) { return 'decimal'; } else { return `decimal(${this.precision})`; diff --git a/drizzle-orm/src/mysql-core/columns/double.ts b/drizzle-orm/src/mysql-core/columns/double.ts index a10cdf599..84647679e 100644 --- a/drizzle-orm/src/mysql-core/columns/double.ts +++ b/drizzle-orm/src/mysql-core/columns/double.ts @@ -45,10 +45,9 @@ export class MySqlDouble scale: number | undefined = this.config.scale; getSQLType(): string { - // return 'double'; - if (typeof this.precision !== 'undefined' && typeof this.scale !== 'undefined') { + if (this.precision !== undefined && this.scale !== undefined) { return `double(${this.precision},${this.scale})`; - } else if (typeof this.precision === 'undefined') { + } else if (this.precision === undefined) { return 'double'; } else { return `double(${this.precision})`; diff --git a/drizzle-orm/src/mysql-core/columns/enum.ts b/drizzle-orm/src/mysql-core/columns/enum.ts index 41d873e6d..05e7d5918 100644 --- a/drizzle-orm/src/mysql-core/columns/enum.ts +++ b/drizzle-orm/src/mysql-core/columns/enum.ts @@ -57,7 +57,9 @@ export function mysqlEnum, ): MySqlEnumColumnBuilderInitial> { - if (values.length === 0) throw Error(`You have an empty array for "${name}" enum values`); + if (values.length === 0) { + throw new Error(`You have an empty array for "${name}" enum values`); + } return new MySqlEnumColumnBuilder(name, values); } diff --git a/drizzle-orm/src/mysql-core/columns/int.ts b/drizzle-orm/src/mysql-core/columns/int.ts index e5f012a15..869efdd28 100644 --- a/drizzle-orm/src/mysql-core/columns/int.ts +++ b/drizzle-orm/src/mysql-core/columns/int.ts @@ -39,7 +39,7 @@ export class MySqlInt extends MySqlColumnWithAutoInc override mapFromDriverValue(value: number | string): number { if (typeof value === 'string') { - return parseInt(value); + return Number(value); } return value; } diff --git a/drizzle-orm/src/mysql-core/columns/mediumint.ts b/drizzle-orm/src/mysql-core/columns/mediumint.ts index 89a9f7d17..6b6a5adba 100644 --- a/drizzle-orm/src/mysql-core/columns/mediumint.ts +++ b/drizzle-orm/src/mysql-core/columns/mediumint.ts @@ -39,7 +39,7 @@ export class MySqlMediumInt extends MySqlColumnWithA override mapFromDriverValue(value: number | string): number { if (typeof value === 'string') { - return parseInt(value); + return Number(value); } return value; } diff --git a/drizzle-orm/src/mysql-core/columns/real.ts b/drizzle-orm/src/mysql-core/columns/real.ts index a14631c11..b61e0ab49 100644 --- a/drizzle-orm/src/mysql-core/columns/real.ts +++ b/drizzle-orm/src/mysql-core/columns/real.ts @@ -49,9 +49,9 @@ export class MySqlReal extends MySqlColumnWithAutoIn scale: number | undefined = this.config.scale; getSQLType(): string { - if (typeof this.precision !== 'undefined' && typeof this.scale !== 'undefined') { + if (this.precision !== undefined && this.scale !== undefined) { return `real(${this.precision}, ${this.scale})`; - } else if (typeof this.precision === 'undefined') { + } else if (this.precision === undefined) { return 'real'; } else { return `real(${this.precision})`; diff --git a/drizzle-orm/src/mysql-core/columns/serial.ts b/drizzle-orm/src/mysql-core/columns/serial.ts index 4af1d65fa..ee6cf2d31 100644 --- a/drizzle-orm/src/mysql-core/columns/serial.ts +++ b/drizzle-orm/src/mysql-core/columns/serial.ts @@ -47,7 +47,7 @@ export class MySqlSerial< override mapFromDriverValue(value: number | string): number { if (typeof value === 'string') { - return parseInt(value); + return Number(value); } return value; } diff --git a/drizzle-orm/src/mysql-core/columns/smallint.ts b/drizzle-orm/src/mysql-core/columns/smallint.ts index e39ee8b54..6811bdf37 100644 --- a/drizzle-orm/src/mysql-core/columns/smallint.ts +++ b/drizzle-orm/src/mysql-core/columns/smallint.ts @@ -39,7 +39,7 @@ export class MySqlSmallInt extends MySqlColumnWithAu override mapFromDriverValue(value: number | string): number { if (typeof value === 'string') { - return parseInt(value); + return Number(value); } return value; } diff --git a/drizzle-orm/src/mysql-core/columns/time.ts b/drizzle-orm/src/mysql-core/columns/time.ts index fe50e0dca..884247b7d 100644 --- a/drizzle-orm/src/mysql-core/columns/time.ts +++ b/drizzle-orm/src/mysql-core/columns/time.ts @@ -48,7 +48,7 @@ export class MySqlTime< readonly fsp: number | undefined = this.config.fsp; getSQLType(): string { - const precision = typeof this.fsp !== 'undefined' ? `(${this.fsp})` : ''; + const precision = this.fsp === undefined ? '' : `(${this.fsp})`; return `time${precision}`; } } diff --git a/drizzle-orm/src/mysql-core/columns/timestamp.ts b/drizzle-orm/src/mysql-core/columns/timestamp.ts index 8c39a5b41..65c07570d 100644 --- a/drizzle-orm/src/mysql-core/columns/timestamp.ts +++ b/drizzle-orm/src/mysql-core/columns/timestamp.ts @@ -45,7 +45,7 @@ export class MySqlTimestamp readonly fsp: number | undefined = this.config.fsp; getSQLType(): string { - const precision = typeof this.fsp !== 'undefined' ? `(${this.fsp})` : ''; + const precision = this.fsp === undefined ? '' : `(${this.fsp})`; return `timestamp${precision}`; } @@ -99,7 +99,7 @@ export class MySqlTimestampString readonly fsp: number | undefined = this.config.fsp; getSQLType(): string { - const precision = typeof this.fsp !== 'undefined' ? `(${this.fsp})` : ''; + const precision = this.fsp === undefined ? '' : `(${this.fsp})`; return `timestamp${precision}`; } } diff --git a/drizzle-orm/src/mysql-core/columns/tinyint.ts b/drizzle-orm/src/mysql-core/columns/tinyint.ts index 0154382d0..011095b89 100644 --- a/drizzle-orm/src/mysql-core/columns/tinyint.ts +++ b/drizzle-orm/src/mysql-core/columns/tinyint.ts @@ -39,7 +39,7 @@ export class MySqlTinyInt extends MySqlColumnWithAut override mapFromDriverValue(value: number | string): number { if (typeof value === 'string') { - return parseInt(value); + return Number(value); } return value; } diff --git a/drizzle-orm/src/mysql-core/columns/varbinary.ts b/drizzle-orm/src/mysql-core/columns/varbinary.ts index 95dc67081..4fd5cf451 100644 --- a/drizzle-orm/src/mysql-core/columns/varbinary.ts +++ b/drizzle-orm/src/mysql-core/columns/varbinary.ts @@ -46,7 +46,7 @@ export class MySqlVarBinary< length: number | undefined = this.config.length; getSQLType(): string { - return typeof this.length !== 'undefined' ? `varbinary(${this.length})` : `varbinary`; + return this.length === undefined ? `varbinary` : `varbinary(${this.length})`; } } diff --git a/drizzle-orm/src/mysql-core/columns/varchar.ts b/drizzle-orm/src/mysql-core/columns/varchar.ts index eaf88ec5d..3bc11bb68 100644 --- a/drizzle-orm/src/mysql-core/columns/varchar.ts +++ b/drizzle-orm/src/mysql-core/columns/varchar.ts @@ -50,7 +50,7 @@ export class MySqlVarChar readonly enumValues: T['enumValues'] = (this.config.enum ?? []) as T['enumValues']; getSQLType(): string { - return typeof this.length !== 'undefined' ? `varchar(${this.length})` : `varchar`; + return this.length === undefined ? `varchar` : `varchar(${this.length})`; } } diff --git a/drizzle-orm/src/mysql-core/dialect.ts b/drizzle-orm/src/mysql-core/dialect.ts index 61d0c03cd..3daa34044 100644 --- a/drizzle-orm/src/mysql-core/dialect.ts +++ b/drizzle-orm/src/mysql-core/dialect.ts @@ -28,11 +28,13 @@ import { MySqlViewBase } from './view'; export class MySqlDialect { async migrate(migrations: MigrationMeta[], session: MySqlSession, config: MigrationConfig): Promise { const migrationsTable = config.migrationsTable ?? '__drizzle_migrations'; - const migrationTableCreate = sql`create table if not exists ${name(migrationsTable)} ( - id serial primary key, - hash text not null, - created_at bigint - )`; + const migrationTableCreate = sql` + create table if not exists ${name(migrationsTable)} ( + id serial primary key, + hash text not null, + created_at bigint + ) + `; await session.execute(migrationTableCreate); const dbMigrations = await session.all<{ id: number; hash: string; created_at: string }>( @@ -45,7 +47,7 @@ export class MySqlDialect { for (const migration of migrations) { if ( !lastDbMigration - || parseInt(lastDbMigration.created_at, 10) < migration.folderMillis + || Number(lastDbMigration.created_at) < migration.folderMillis ) { for (const stmt of migration.sql) { await tx.execute(sql.raw(stmt)); @@ -64,7 +66,7 @@ export class MySqlDialect { return `\`${name}\``; } - escapeParam(num: number): string { + escapeParam(_num: number): string { return `?`; } @@ -88,15 +90,14 @@ export class MySqlDialect { const setSize = setEntries.length; return sql.fromList( setEntries - .map(([colName, value], i): SQL[] => { + .flatMap(([colName, value], i): SQL[] => { const col: AnyMySqlColumn = table[Table.Symbol.Columns][colName]!; const res = sql`${name(col.name)} = ${value}`; if (i < setSize - 1) { return [res, sql.raw(', ')]; } return [res]; - }) - .flat(1), + }), ); } @@ -130,7 +131,7 @@ export class MySqlDialect { const columnsLen = fields.length; const chunks = fields - .map(({ field }, i) => { + .flatMap(({ field }, i) => { const chunk: SQLChunk[] = []; if (field instanceof SQL.Aliased && field.isSelectionField) { @@ -169,8 +170,7 @@ export class MySqlDialect { } return chunk; - }) - .flat(1); + }); return sql.fromList(chunks); } @@ -180,7 +180,7 @@ export class MySqlDialect { MySqlSelectConfig, ): SQL { const fieldsList = orderSelectedFields(fields); - fieldsList.forEach((f) => { + for (const f of fieldsList) { if ( f.field instanceof Column && getTableName(f.field.table) @@ -200,19 +200,19 @@ export class MySqlDialect { }" field references a column "${tableName}"."${f.field.name}", but the table "${tableName}" is not part of the query! Did you forget to join it?`, ); } - }); + } const isSingleTable = joins.length === 0; let withSql: SQL | undefined; if (withList.length) { const withSqlChunks = [sql`with `]; - withList.forEach((w, i) => { + for (const [i, w] of withList.entries()) { withSqlChunks.push(sql`${name(w[SubqueryConfig].alias)} as (${w[SubqueryConfig].sql})`); if (i < withList.length - 1) { withSqlChunks.push(sql`, `); } - }); + } withSqlChunks.push(sql` `); withSql = sql.fromList(withSqlChunks); } @@ -221,7 +221,7 @@ export class MySqlDialect { const joinsArray: SQL[] = []; - joins.forEach((joinMeta, index) => { + for (const [index, joinMeta] of joins.entries()) { if (index === 0) { joinsArray.push(sql` `); } @@ -238,6 +238,15 @@ export class MySqlDialect { }${alias && sql` ${name(alias)}`} on ${joinMeta.on}`, ); } else if (table instanceof View) { + const viewName = table[ViewBaseConfig].name; + const viewSchema = table[ViewBaseConfig].schema; + const origViewName = table[ViewBaseConfig].originalName; + const alias = viewName === origViewName ? undefined : joinMeta.alias; + joinsArray.push( + sql`${sql.raw(joinMeta.joinType)} join ${viewSchema ? sql`${name(viewSchema)}.` : undefined}${ + name(origViewName) + }${alias && sql` ${name(alias)}`} on ${joinMeta.on}`, + ); } else { joinsArray.push( sql`${sql.raw(joinMeta.joinType)} join ${table} on ${joinMeta.on}`, @@ -246,7 +255,7 @@ export class MySqlDialect { if (index < joins.length - 1) { joinsArray.push(sql` `); } - }); + } const joinsSql = sql.fromList(joinsArray); @@ -255,24 +264,24 @@ export class MySqlDialect { const havingSql = having ? sql` having ${having}` : undefined; const orderByList: (AnyMySqlColumn | SQL | SQL.Aliased)[] = []; - orderBy.forEach((orderByValue, index) => { + for (const [index, orderByValue] of orderBy.entries()) { orderByList.push(orderByValue); if (index < orderBy.length - 1) { orderByList.push(sql`, `); } - }); + } const orderBySql = orderByList.length > 0 ? sql` order by ${sql.fromList(orderByList)}` : undefined; const groupByList: (SQL | AnyColumn | SQL.Aliased)[] = []; - groupBy.forEach((groupByValue, index) => { + for (const [index, groupByValue] of groupBy.entries()) { groupByList.push(groupByValue); if (index < groupBy.length - 1) { groupByList.push(sql`, `); } - }); + } const groupBySql = groupByList.length > 0 ? sql` group by ${sql.fromList(groupByList)}` : undefined; @@ -294,7 +303,7 @@ export class MySqlDialect { return sql`${withSql}select ${selection} from ${table}${joinsSql}${whereSql}${groupBySql}${havingSql}${orderBySql}${limitSql}${offsetSql}${lockingClausesSql}`; } - buildInsertQuery({ table, values, ignore, onConflict, returning }: MySqlInsertConfig): SQL { + buildInsertQuery({ table, values, ignore, onConflict }: MySqlInsertConfig): SQL { const isSingleValue = values.length === 1; const valuesSqlList: ((SQLChunk | SQL)[] | SQL)[] = []; const columns: Record = table[Table.Symbol.Columns]; @@ -303,30 +312,26 @@ export class MySqlDialect { : Object.entries(columns); const insertOrder = colEntries.map(([, column]) => name(column.name)); - values.forEach((value, valueIndex) => { + for (const [valueIndex, value] of values.entries()) { const valueList: (SQLChunk | SQL)[] = []; - colEntries.forEach(([fieldName]) => { + for (const [fieldName] of colEntries) { const colValue = value[fieldName]; - if (typeof colValue === 'undefined') { + if (colValue === undefined) { valueList.push(sql`default`); } else { valueList.push(colValue); } - }); + } valuesSqlList.push(valueList); if (valueIndex < values.length - 1) { valuesSqlList.push(sql`, `); } - }); + } const valuesSql = sql.fromList(valuesSqlList); const ignoreSql = ignore ? sql` ignore` : undefined; - const returningSql = returning - ? sql` returning ${this.buildSelection(returning, { isSingleTable: true })}` - : undefined; - const onConflictSql = onConflict ? sql` on duplicate key ${onConflict}` : undefined; return sql`insert${ignoreSql} into ${table} ${insertOrder} values ${valuesSql}${onConflictSql}`; diff --git a/drizzle-orm/src/mysql-core/indexes.ts b/drizzle-orm/src/mysql-core/indexes.ts index 115e7fda5..0a32d369e 100644 --- a/drizzle-orm/src/mysql-core/indexes.ts +++ b/drizzle-orm/src/mysql-core/indexes.ts @@ -42,6 +42,7 @@ export interface AnyIndexBuilder { build(table: AnyMySqlTable): Index; } +// eslint-disable-next-line @typescript-eslint/no-empty-interface export interface IndexBuilder extends AnyIndexBuilder {} export class IndexBuilder implements AnyIndexBuilder { diff --git a/drizzle-orm/src/mysql-core/query-builders/delete.ts b/drizzle-orm/src/mysql-core/query-builders/delete.ts index 7e958fc06..9bb7a26d3 100644 --- a/drizzle-orm/src/mysql-core/query-builders/delete.ts +++ b/drizzle-orm/src/mysql-core/query-builders/delete.ts @@ -18,9 +18,12 @@ export interface MySqlDeleteConfig { returning?: SelectedFieldsOrdered; } +// eslint-disable-next-line @typescript-eslint/no-empty-interface export interface MySqlDelete< + // eslint-disable-next-line @typescript-eslint/no-unused-vars TTable extends AnyMySqlTable, TQueryResult extends QueryResultHKT, + // eslint-disable-next-line @typescript-eslint/no-unused-vars TPreparedQueryHKT extends PreparedQueryHKTBase, > extends QueryPromise> {} @@ -53,7 +56,7 @@ export class MySqlDelete< } toSQL(): Omit { - const { typings, ...rest } = this.dialect.sqlToQuery(this.getSQL()); + const { typings: _typings, ...rest } = this.dialect.sqlToQuery(this.getSQL()); return rest; } diff --git a/drizzle-orm/src/mysql-core/query-builders/insert.ts b/drizzle-orm/src/mysql-core/query-builders/insert.ts index 774b387bd..0a00972b0 100644 --- a/drizzle-orm/src/mysql-core/query-builders/insert.ts +++ b/drizzle-orm/src/mysql-core/query-builders/insert.ts @@ -14,7 +14,6 @@ import { Param, SQL, sql } from '~/sql'; import { type InferModel, Table } from '~/table'; import type { Simplify } from '~/utils'; import { mapUpdateSet } from '~/utils'; -import type { SelectedFieldsOrdered } from './select.types'; import type { MySqlUpdateSetSource } from './update'; export interface MySqlInsertConfig { @@ -22,7 +21,6 @@ export interface MySqlInsertConfig values: Record[]; ignore: boolean; onConflict?: SQL; - returning?: SelectedFieldsOrdered; } export type AnyMySqlInsertConfig = MySqlInsertConfig; @@ -38,7 +36,7 @@ export class MySqlInsertBuilder< TQueryResult extends QueryResultHKT, TPreparedQueryHKT extends PreparedQueryHKTBase, > { - private shouldIgnore: boolean = false; + private shouldIgnore = false; constructor( private table: TTable, @@ -61,22 +59,14 @@ export class MySqlInsertBuilder< ...values: MySqlInsertValue[] | [MySqlInsertValue] | [MySqlInsertValue[]] ): MySqlInsert { if (values.length === 1) { - if (Array.isArray(values[0])) { - values = values[0]; - } else { - values = [values[0]]; - } + values = Array.isArray(values[0]) ? values[0] : [values[0]]; } const mappedValues = values.map((entry) => { const result: Record = {}; const cols = this.table[Table.Symbol.Columns]; for (const colKey of Object.keys(entry)) { const colValue = entry[colKey as keyof typeof entry]; - if (colValue instanceof SQL) { - result[colKey] = colValue; - } else { - result[colKey] = new Param(colValue, cols[colKey]); - } + result[colKey] = colValue instanceof SQL ? colValue : new Param(colValue, cols[colKey]); } return result; }); @@ -86,19 +76,18 @@ export class MySqlInsertBuilder< } export interface MySqlInsert< + // eslint-disable-next-line @typescript-eslint/no-unused-vars TTable extends AnyMySqlTable, TQueryResult extends QueryResultHKT, + // eslint-disable-next-line @typescript-eslint/no-unused-vars TPreparedQueryHKT extends PreparedQueryHKTBase, - TReturning = undefined, > extends QueryPromise>, SQLWrapper {} export class MySqlInsert< TTable extends AnyMySqlTable, TQueryResult extends QueryResultHKT, TPreparedQueryHKT extends PreparedQueryHKTBase, - TReturning = undefined, > extends QueryPromise> implements SQLWrapper { declare protected $table: TTable; - declare protected $return: TReturning; private config: MySqlInsertConfig; @@ -128,14 +117,14 @@ export class MySqlInsert< } toSQL(): Simplify> { - const { typings, ...rest } = this.dialect.sqlToQuery(this.getSQL()); + const { typings: _typings, ...rest } = this.dialect.sqlToQuery(this.getSQL()); return rest; } prepare() { return this.session.prepareQuery( this.dialect.sqlToQuery(this.getSQL()), - this.config.returning, + undefined, ) as PreparedQueryKind< TPreparedQueryHKT, PreparedQueryConfig & { diff --git a/drizzle-orm/src/mysql-core/query-builders/select.ts b/drizzle-orm/src/mysql-core/query-builders/select.ts index 847ac6858..528296c90 100644 --- a/drizzle-orm/src/mysql-core/query-builders/select.ts +++ b/drizzle-orm/src/mysql-core/query-builders/select.ts @@ -196,24 +196,28 @@ export abstract class MySqlSelectQueryBuilder< if (typeof tableName === 'string') { switch (joinType) { - case 'left': + case 'left': { this.joinsNotNullableMap[tableName] = false; break; - case 'right': + } + case 'right': { this.joinsNotNullableMap = Object.fromEntries( Object.entries(this.joinsNotNullableMap).map(([key]) => [key, false]), ); this.joinsNotNullableMap[tableName] = true; break; - case 'inner': + } + case 'inner': { this.joinsNotNullableMap[tableName] = true; break; - case 'full': + } + case 'full': { this.joinsNotNullableMap = Object.fromEntries( Object.entries(this.joinsNotNullableMap).map(([key]) => [key, false]), ); this.joinsNotNullableMap[tableName] = false; break; + } } } @@ -318,7 +322,7 @@ export abstract class MySqlSelectQueryBuilder< } toSQL(): Simplify> { - const { typings, ...rest } = this.dialect.sqlToQuery(this.getSQL()); + const { typings: _typings, ...rest } = this.dialect.sqlToQuery(this.getSQL()); return rest; } @@ -336,6 +340,7 @@ export interface MySqlSelect< TTableName extends string | undefined, TSelection extends ColumnsSelection, TSelectMode extends SelectMode, + // eslint-disable-next-line @typescript-eslint/no-unused-vars TPreparedQueryHKT extends PreparedQueryHKTBase, TNullabilityMap extends Record = TTableName extends string ? Record : {}, diff --git a/drizzle-orm/src/mysql-core/query-builders/update.ts b/drizzle-orm/src/mysql-core/query-builders/update.ts index 08739d757..59095a76a 100644 --- a/drizzle-orm/src/mysql-core/query-builders/update.ts +++ b/drizzle-orm/src/mysql-core/query-builders/update.ts @@ -49,8 +49,10 @@ export class MySqlUpdateBuilder< } export interface MySqlUpdate< + // eslint-disable-next-line @typescript-eslint/no-unused-vars TTable extends AnyMySqlTable, TQueryResult extends QueryResultHKT, + // eslint-disable-next-line @typescript-eslint/no-unused-vars TPreparedQueryHKT extends PreparedQueryHKTBase, > extends QueryPromise>, SQLWrapper {} export class MySqlUpdate< @@ -83,7 +85,7 @@ export class MySqlUpdate< } toSQL(): Omit { - const { typings, ...rest } = this.dialect.sqlToQuery(this.getSQL()); + const { typings: _typings, ...rest } = this.dialect.sqlToQuery(this.getSQL()); return rest; } diff --git a/drizzle-orm/src/mysql-core/utils.ts b/drizzle-orm/src/mysql-core/utils.ts index e386fcb4f..0aef62661 100644 --- a/drizzle-orm/src/mysql-core/utils.ts +++ b/drizzle-orm/src/mysql-core/utils.ts @@ -25,9 +25,9 @@ export function getTableConfig(table: AnyMySqlTable) { const extraConfigBuilder = table[MySqlTable.Symbol.ExtraConfigBuilder]; - if (typeof extraConfigBuilder !== 'undefined') { + if (extraConfigBuilder !== undefined) { const extraConfig = extraConfigBuilder(table[MySqlTable.Symbol.Columns]); - Object.values(extraConfig).forEach((builder) => { + for (const builder of Object.values(extraConfig)) { if (builder instanceof IndexBuilder) { indexes.push(builder.build(table)); } else if (builder instanceof CheckBuilder) { @@ -37,7 +37,7 @@ export function getTableConfig(table: AnyMySqlTable) { } else if (builder instanceof ForeignKeyBuilder) { foreignKeys.push(builder.build(table)); } - }); + } } return { diff --git a/drizzle-orm/src/mysql2/session.ts b/drizzle-orm/src/mysql2/session.ts index 824510dcc..84bda6e9d 100644 --- a/drizzle-orm/src/mysql2/session.ts +++ b/drizzle-orm/src/mysql2/session.ts @@ -74,15 +74,15 @@ export class MySql2PreparedQuery extends Prepared this.logger.logQuery(this.rawQuery.sql, params); - const { fields } = this; + const { fields, client, rawQuery, query, joinsNotNullableMap } = this; if (!fields) { - return this.client.query(this.rawQuery, params); + return client.query(rawQuery, params); } - const result = this.client.query(this.query, params); + const result = client.query(query, params); return result.then((result) => - result[0].map((row) => mapResultRow(fields, row, this.joinsNotNullableMap)) + result[0].map((row) => mapResultRow(fields, row, joinsNotNullableMap)) ); } @@ -94,8 +94,8 @@ export class MySql2PreparedQuery extends Prepared connection: CallbackConnection; }).connection; - const { fields } = this; - const driverQuery = fields ? conn.query(this.query, params) : conn.query(this.rawQuery, params); + const { fields, query, rawQuery, joinsNotNullableMap, client } = this; + const driverQuery = fields ? conn.query(query, params) : conn.query(rawQuery, params); const stream = driverQuery.stream(); @@ -117,12 +117,12 @@ export class MySql2PreparedQuery extends Prepared } else if (row instanceof Error) { throw row; } else { - yield (fields ? mapResultRow(fields, row as unknown[], this.joinsNotNullableMap) : row) as T['execute']; + yield (fields ? mapResultRow(fields, row as unknown[], joinsNotNullableMap) : row) as T['execute']; } } } finally { stream.off('data', dataListener); - if (isPool(this.client)) { + if (isPool(client)) { conn.end(); } } @@ -192,11 +192,7 @@ export class MySql2Session extends MySqlSession { await tx.execute(setTransactionConfigSql); } const startTransactionSql = this.getStartTransactionSQL(config); - if (startTransactionSql) { - await tx.execute(startTransactionSql); - } else { - await tx.execute(sql`begin`); - } + await (startTransactionSql ? tx.execute(startTransactionSql) : tx.execute(sql`begin`)); } else { await tx.execute(sql`begin`); } diff --git a/drizzle-orm/src/neon-serverless/session.ts b/drizzle-orm/src/neon-serverless/session.ts index 5d2682dc5..118322126 100644 --- a/drizzle-orm/src/neon-serverless/session.ts +++ b/drizzle-orm/src/neon-serverless/session.ts @@ -48,15 +48,15 @@ export class NeonPreparedQuery extends PreparedQu this.logger.logQuery(this.rawQuery.text, params); - const { fields } = this; + const { fields, client, rawQuery, query, joinsNotNullableMap } = this; if (!fields) { - return this.client.query(this.rawQuery, params); + return client.query(rawQuery, params); } - const result = this.client.query(this.query, params); + const result = client.query(query, params); return result.then((result) => - result.rows.map((row) => mapResultRow(fields, row, this.joinsNotNullableMap)) + result.rows.map((row) => mapResultRow(fields, row, joinsNotNullableMap)) ); } diff --git a/drizzle-orm/src/node-postgres/session.ts b/drizzle-orm/src/node-postgres/session.ts index 7d9eaec6e..6307dbf1d 100644 --- a/drizzle-orm/src/node-postgres/session.ts +++ b/drizzle-orm/src/node-postgres/session.ts @@ -47,15 +47,15 @@ export class NodePgPreparedQuery extends Prepared this.logger.logQuery(this.rawQuery.text, params); - const { fields } = this; + const { fields, rawQuery, client, query, joinsNotNullableMap } = this; if (!fields) { - return this.client.query(this.rawQuery, params); + return client.query(rawQuery, params); } - const result = this.client.query(this.query, params); + const result = client.query(query, params); return result.then((result) => - result.rows.map((row) => mapResultRow(fields, row, this.joinsNotNullableMap)) + result.rows.map((row) => mapResultRow(fields, row, joinsNotNullableMap)) ); } diff --git a/drizzle-orm/src/pg-core/columns/bigint.ts b/drizzle-orm/src/pg-core/columns/bigint.ts index e1d7a3c59..5781c8be0 100644 --- a/drizzle-orm/src/pg-core/columns/bigint.ts +++ b/drizzle-orm/src/pg-core/columns/bigint.ts @@ -40,7 +40,7 @@ export class PgBigInt53 extends PgColumn extends PgColumn extends PgColumn extends PgColumn readonly enumValues = this.config.enumValues; getSQLType(): string { - return typeof this.length !== 'undefined' ? `char(${this.length})` : `char`; + return this.length === undefined ? `char` : `char(${this.length})`; } } diff --git a/drizzle-orm/src/pg-core/columns/custom.ts b/drizzle-orm/src/pg-core/columns/custom.ts index 5e0e3f3b8..491860552 100644 --- a/drizzle-orm/src/pg-core/columns/custom.ts +++ b/drizzle-orm/src/pg-core/columns/custom.ts @@ -81,19 +81,11 @@ export class PgCustomColumn extends PgColumn extends PgColumn extends PgColumn extends PgColumn { if (typeof value === 'string') { try { return JSON.parse(value); - } catch (e) { + } catch { return value as T['data']; } } diff --git a/drizzle-orm/src/pg-core/columns/jsonb.ts b/drizzle-orm/src/pg-core/columns/jsonb.ts index 9b3bd7b80..e4bbc1bdf 100644 --- a/drizzle-orm/src/pg-core/columns/jsonb.ts +++ b/drizzle-orm/src/pg-core/columns/jsonb.ts @@ -49,7 +49,7 @@ export class PgJsonb extends PgColumn if (typeof value === 'string') { try { return JSON.parse(value); - } catch (e) { + } catch { return value as T['data']; } } diff --git a/drizzle-orm/src/pg-core/columns/numeric.ts b/drizzle-orm/src/pg-core/columns/numeric.ts index 55f6526ba..7e740731c 100644 --- a/drizzle-orm/src/pg-core/columns/numeric.ts +++ b/drizzle-orm/src/pg-core/columns/numeric.ts @@ -54,9 +54,9 @@ export class PgNumeric extends PgColumn extends PgColumn { override mapFromDriverValue = (value: string | number): number => { if (typeof value === 'string') { - return parseFloat(value); + return Number.parseFloat(value); } return value; }; diff --git a/drizzle-orm/src/pg-core/columns/smallint.ts b/drizzle-orm/src/pg-core/columns/smallint.ts index bc57035b8..54d6b8b93 100644 --- a/drizzle-orm/src/pg-core/columns/smallint.ts +++ b/drizzle-orm/src/pg-core/columns/smallint.ts @@ -37,7 +37,7 @@ export class PgSmallInt extends PgColumn { if (typeof value === 'string') { - return parseInt(value); + return Number(value); } return value; }; diff --git a/drizzle-orm/src/pg-core/columns/time.ts b/drizzle-orm/src/pg-core/columns/time.ts index 026f289a7..2477ec77d 100644 --- a/drizzle-orm/src/pg-core/columns/time.ts +++ b/drizzle-orm/src/pg-core/columns/time.ts @@ -57,7 +57,7 @@ export class PgTime extends PgColumn { } getSQLType(): string { - const precision = typeof this.precision !== 'undefined' ? `(${this.precision})` : ''; + const precision = this.precision === undefined ? '' : `(${this.precision})`; return `time${precision}${this.withTimezone ? ' with time zone' : ''}`; } } diff --git a/drizzle-orm/src/pg-core/columns/timestamp.ts b/drizzle-orm/src/pg-core/columns/timestamp.ts index 98ec54ce3..92c0b71a5 100644 --- a/drizzle-orm/src/pg-core/columns/timestamp.ts +++ b/drizzle-orm/src/pg-core/columns/timestamp.ts @@ -56,7 +56,7 @@ export class PgTimestamp extends PgColumn extends PgColumn readonly enumValues = this.config.enumValues; getSQLType(): string { - return typeof this.length !== 'undefined' ? `varchar(${this.length})` : `varchar`; + return this.length === undefined ? `varchar` : `varchar(${this.length})`; } } diff --git a/drizzle-orm/src/pg-core/dialect.ts b/drizzle-orm/src/pg-core/dialect.ts index 0aec8ff55..ffa554fec 100644 --- a/drizzle-orm/src/pg-core/dialect.ts +++ b/drizzle-orm/src/pg-core/dialect.ts @@ -17,11 +17,13 @@ import { type PgMaterializedView, PgViewBase } from './view'; export class PgDialect { async migrate(migrations: MigrationMeta[], session: PgSession): Promise { - const migrationTableCreate = sql`CREATE TABLE IF NOT EXISTS "drizzle"."__drizzle_migrations" ( - id SERIAL PRIMARY KEY, - hash text NOT NULL, - created_at bigint - )`; + const migrationTableCreate = sql` + CREATE TABLE IF NOT EXISTS "drizzle"."__drizzle_migrations" ( + id SERIAL PRIMARY KEY, + hash text NOT NULL, + created_at bigint + ) + `; await session.execute(sql`CREATE SCHEMA IF NOT EXISTS "drizzle"`); await session.execute(migrationTableCreate); @@ -34,7 +36,7 @@ export class PgDialect { for await (const migration of migrations) { if ( !lastDbMigration - || parseInt(lastDbMigration.created_at, 10) < migration.folderMillis + || Number(lastDbMigration.created_at) < migration.folderMillis ) { for (const stmt of migration.sql) { await tx.execute(sql.raw(stmt)); @@ -75,15 +77,14 @@ export class PgDialect { const setSize = setEntries.length; return sql.fromList( setEntries - .map(([colName, value], i): SQL[] => { + .flatMap(([colName, value], i): SQL[] => { const col: AnyPgColumn = table[Table.Symbol.Columns][colName]!; const res = sql`${name(col.name)} = ${value}`; if (i < setSize - 1) { return [res, sql.raw(', ')]; } return [res]; - }) - .flat(1), + }), ); } @@ -117,7 +118,7 @@ export class PgDialect { const columnsLen = fields.length; const chunks = fields - .map(({ field }, i) => { + .flatMap(({ field }, i) => { const chunk: SQLChunk[] = []; if (field instanceof SQL.Aliased && field.isSelectionField) { @@ -156,8 +157,7 @@ export class PgDialect { } return chunk; - }) - .flat(1); + }); return sql.fromList(chunks); } @@ -166,7 +166,7 @@ export class PgDialect { { withList, fields, where, having, table, joins, orderBy, groupBy, limit, offset, lockingClauses }: PgSelectConfig, ): SQL { const fieldsList = orderSelectedFields(fields); - fieldsList.forEach((f) => { + for (const f of fieldsList) { if ( f.field instanceof Column && getTableName(f.field.table) @@ -186,19 +186,19 @@ export class PgDialect { }" field references a column "${tableName}"."${f.field.name}", but the table "${tableName}" is not part of the query! Did you forget to join it?`, ); } - }); + } const isSingleTable = joins.length === 0; let withSql: SQL | undefined; if (withList.length) { const withSqlChunks = [sql`with `]; - withList.forEach((w, i) => { + for (const [i, w] of withList.entries()) { withSqlChunks.push(sql`${name(w[SubqueryConfig].alias)} as (${w[SubqueryConfig].sql})`); if (i < withList.length - 1) { withSqlChunks.push(sql`, `); } - }); + } withSqlChunks.push(sql` `); withSql = sql.fromList(withSqlChunks); } @@ -207,7 +207,7 @@ export class PgDialect { const joinsArray: SQL[] = []; - joins.forEach((joinMeta, index) => { + for (const [index, joinMeta] of joins.entries()) { if (index === 0) { joinsArray.push(sql` `); } @@ -231,7 +231,7 @@ export class PgDialect { if (index < joins.length - 1) { joinsArray.push(sql` `); } - }); + } const joinsSql = sql.fromList(joinsArray); @@ -240,24 +240,24 @@ export class PgDialect { const havingSql = having ? sql` having ${having}` : undefined; const orderByList: (AnyPgColumn | SQL | SQL.Aliased)[] = []; - orderBy.forEach((orderByValue, index) => { + for (const [index, orderByValue] of orderBy.entries()) { orderByList.push(orderByValue); if (index < orderBy.length - 1) { orderByList.push(sql`, `); } - }); + } const orderBySql = orderByList.length > 0 ? sql` order by ${sql.fromList(orderByList)}` : undefined; const groupByList: (SQL | AnyColumn | SQL.Aliased)[] = []; - groupBy.forEach((groupByValue, index) => { + for (const [index, groupByValue] of groupBy.entries()) { groupByList.push(groupByValue); if (index < groupBy.length - 1) { groupByList.push(sql`, `); } - }); + } const groupBySql = groupByList.length > 0 ? sql` group by ${sql.fromList(groupByList)}` : undefined; @@ -265,9 +265,9 @@ export class PgDialect { const offsetSql = offset ? sql` offset ${offset}` : undefined; - let lockingClausesSql = sql.empty(); - lockingClauses.forEach(({ strength, config }) => { - let clauseSql = sql` for ${sql.raw(strength)}`; + const lockingClausesSql = sql.empty(); + for (const { strength, config } of lockingClauses) { + const clauseSql = sql` for ${sql.raw(strength)}`; if (config.of) { clauseSql.append(sql` of ${config.of}`); } @@ -277,7 +277,7 @@ export class PgDialect { clauseSql.append(sql` skip locked`); } lockingClausesSql.append(clauseSql); - }); + } return sql`${withSql}select ${selection} from ${table}${joinsSql}${whereSql}${groupBySql}${havingSql}${orderBySql}${limitSql}${offsetSql}${lockingClausesSql}`; } @@ -291,21 +291,21 @@ export class PgDialect { : Object.entries(columns); const insertOrder = colEntries.map(([, column]) => name(column.name)); - values.forEach((value, valueIndex) => { + for (const [valueIndex, value] of values.entries()) { const valueList: (SQLChunk | SQL)[] = []; - colEntries.forEach(([fieldName]) => { + for (const [fieldName] of colEntries) { const colValue = value[fieldName]; - if (typeof colValue === 'undefined') { + if (colValue === undefined) { valueList.push(sql`default`); } else { valueList.push(colValue); } - }); + } valuesSqlList.push(valueList); if (valueIndex < values.length - 1) { valuesSqlList.push(sql`, `); } - }); + } const valuesSql = sql.fromList(valuesSqlList); diff --git a/drizzle-orm/src/pg-core/foreign-keys.ts b/drizzle-orm/src/pg-core/foreign-keys.ts index 7a4e16379..fa9761e34 100644 --- a/drizzle-orm/src/pg-core/foreign-keys.ts +++ b/drizzle-orm/src/pg-core/foreign-keys.ts @@ -40,12 +40,12 @@ export class ForeignKeyBuilder { } onUpdate(action: UpdateDeleteAction): this { - this._onUpdate = typeof action === 'undefined' ? 'no action' : action; + this._onUpdate = action === undefined ? 'no action' : action; return this; } onDelete(action: UpdateDeleteAction): this { - this._onDelete = typeof action === 'undefined' ? 'no action' : action; + this._onDelete = action === undefined ? 'no action' : action; return this; } diff --git a/drizzle-orm/src/pg-core/indexes.ts b/drizzle-orm/src/pg-core/indexes.ts index 11a812b7a..97790a2d4 100644 --- a/drizzle-orm/src/pg-core/indexes.ts +++ b/drizzle-orm/src/pg-core/indexes.ts @@ -62,6 +62,7 @@ export interface AnyIndexBuilder { build(table: AnyPgTable): Index; } +// eslint-disable-next-line @typescript-eslint/no-empty-interface export interface IndexBuilder extends AnyIndexBuilder {} export class IndexBuilder implements AnyIndexBuilder { diff --git a/drizzle-orm/src/pg-core/query-builders/delete.ts b/drizzle-orm/src/pg-core/query-builders/delete.ts index 991f8d5a5..e88e7290d 100644 --- a/drizzle-orm/src/pg-core/query-builders/delete.ts +++ b/drizzle-orm/src/pg-core/query-builders/delete.ts @@ -14,7 +14,9 @@ export interface PgDeleteConfig { returning?: SelectedFieldsOrdered; } +// eslint-disable-next-line @typescript-eslint/no-empty-interface export interface PgDelete< + // eslint-disable-next-line @typescript-eslint/no-unused-vars TTable extends AnyPgTable, TQueryResult extends QueryResultHKT, TReturning extends Record | undefined = undefined, @@ -58,7 +60,7 @@ export class PgDelete< } toSQL(): Simplify> { - const { typings, ...rest } = this.dialect.sqlToQuery(this.getSQL()); + const { typings: _typings, ...rest } = this.dialect.sqlToQuery(this.getSQL()); return rest; } diff --git a/drizzle-orm/src/pg-core/query-builders/insert.ts b/drizzle-orm/src/pg-core/query-builders/insert.ts index 9fccfce0b..d596a2250 100644 --- a/drizzle-orm/src/pg-core/query-builders/insert.ts +++ b/drizzle-orm/src/pg-core/query-builders/insert.ts @@ -42,22 +42,14 @@ export class PgInsertBuilder[] | [PgInsertValue] | [PgInsertValue[]] ): PgInsert { if (values.length === 1) { - if (Array.isArray(values[0])) { - values = values[0]; - } else { - values = [values[0]]; - } + values = Array.isArray(values[0]) ? values[0] : [values[0]]; } const mappedValues = values.map((entry) => { const result: Record = {}; const cols = this.table[Table.Symbol.Columns]; for (const colKey of Object.keys(entry)) { const colValue = entry[colKey as keyof typeof entry]; - if (colValue instanceof SQL) { - result[colKey] = colValue; - } else { - result[colKey] = new Param(colValue, cols[colKey]); - } + result[colKey] = colValue instanceof SQL ? colValue : new Param(colValue, cols[colKey]); } return result; }); @@ -67,6 +59,7 @@ export class PgInsertBuilder | undefined = undefined, @@ -115,11 +108,9 @@ export class PgInsert< this.config.onConflict = sql`do nothing`; } else { let targetColumn = ''; - if (Array.isArray(config.target)) { - targetColumn = config.target.map((it) => this.dialect.escapeName(it.name)).join(','); - } else { - targetColumn = this.dialect.escapeName(config.target.name); - } + targetColumn = Array.isArray(config.target) + ? config.target.map((it) => this.dialect.escapeName(it.name)).join(',') + : this.dialect.escapeName(config.target.name); const whereSql = config.where ? sql` where ${config.where}` : sql``; this.config.onConflict = sql`(${sql.raw(targetColumn)})${whereSql} do nothing`; @@ -135,11 +126,9 @@ export class PgInsert< const whereSql = config.where ? sql` where ${config.where}` : sql``; const setSql = this.dialect.buildUpdateSet(this.config.table, mapUpdateSet(this.config.table, config.set)); let targetColumn = ''; - if (Array.isArray(config.target)) { - targetColumn = config.target.map((it) => this.dialect.escapeName(it.name)).join(','); - } else { - targetColumn = this.dialect.escapeName(config.target.name); - } + targetColumn = Array.isArray(config.target) + ? config.target.map((it) => this.dialect.escapeName(it.name)).join(',') + : this.dialect.escapeName(config.target.name); this.config.onConflict = sql`(${sql.raw(targetColumn)})${whereSql} do update set ${setSql}`; return this; } @@ -150,7 +139,7 @@ export class PgInsert< } toSQL(): Simplify> { - const { typings, ...rest } = this.dialect.sqlToQuery(this.getSQL()); + const { typings: _typings, ...rest } = this.dialect.sqlToQuery(this.getSQL()); return rest; } diff --git a/drizzle-orm/src/pg-core/query-builders/refresh-materialized-view.ts b/drizzle-orm/src/pg-core/query-builders/refresh-materialized-view.ts index be1d67053..6078ad2df 100644 --- a/drizzle-orm/src/pg-core/query-builders/refresh-materialized-view.ts +++ b/drizzle-orm/src/pg-core/query-builders/refresh-materialized-view.ts @@ -5,6 +5,7 @@ import { QueryPromise } from '~/query-promise'; import type { Query, SQL } from '~/sql'; import type { Simplify } from '~/utils'; +// eslint-disable-next-line @typescript-eslint/no-empty-interface export interface PgRefreshMaterializedView extends QueryPromise> {} @@ -28,7 +29,7 @@ export class PgRefreshMaterializedView } concurrently(): this { - if (typeof this.config.withNoData !== 'undefined') { + if (this.config.withNoData !== undefined) { throw new Error('Cannot use concurrently and withNoData together'); } this.config.concurrently = true; @@ -36,7 +37,7 @@ export class PgRefreshMaterializedView } withNoData(): this { - if (typeof this.config.concurrently !== 'undefined') { + if (this.config.concurrently !== undefined) { throw new Error('Cannot use concurrently and withNoData together'); } this.config.withNoData = true; @@ -49,7 +50,7 @@ export class PgRefreshMaterializedView } toSQL(): Simplify> { - const { typings, ...rest } = this.dialect.sqlToQuery(this.getSQL()); + const { typings: _typings, ...rest } = this.dialect.sqlToQuery(this.getSQL()); return rest; } diff --git a/drizzle-orm/src/pg-core/query-builders/select.ts b/drizzle-orm/src/pg-core/query-builders/select.ts index 0b06f5ddb..1c1697508 100644 --- a/drizzle-orm/src/pg-core/query-builders/select.ts +++ b/drizzle-orm/src/pg-core/query-builders/select.ts @@ -186,24 +186,28 @@ export abstract class PgSelectQueryBuilder< if (typeof tableName === 'string') { switch (joinType) { - case 'left': + case 'left': { this.joinsNotNullableMap[tableName] = false; break; - case 'right': + } + case 'right': { this.joinsNotNullableMap = Object.fromEntries( Object.entries(this.joinsNotNullableMap).map(([key]) => [key, false]), ); this.joinsNotNullableMap[tableName] = true; break; - case 'inner': + } + case 'inner': { this.joinsNotNullableMap[tableName] = true; break; - case 'full': + } + case 'full': { this.joinsNotNullableMap = Object.fromEntries( Object.entries(this.joinsNotNullableMap).map(([key]) => [key, false]), ); this.joinsNotNullableMap[tableName] = false; break; + } } } @@ -308,7 +312,7 @@ export abstract class PgSelectQueryBuilder< } toSQL(): Simplify> { - const { typings, ...rest } = this.dialect.sqlToQuery(this.getSQL()); + const { typings: _typings, ...rest } = this.dialect.sqlToQuery(this.getSQL()); return rest; } diff --git a/drizzle-orm/src/pg-core/query-builders/update.ts b/drizzle-orm/src/pg-core/query-builders/update.ts index 2ddea4308..91a3e1966 100644 --- a/drizzle-orm/src/pg-core/query-builders/update.ts +++ b/drizzle-orm/src/pg-core/query-builders/update.ts @@ -43,6 +43,7 @@ export class PgUpdateBuilder | undefined = undefined, @@ -97,7 +98,7 @@ export class PgUpdate< } toSQL(): Omit { - const { typings, ...rest } = this.dialect.sqlToQuery(this.getSQL()); + const { typings: _typings, ...rest } = this.dialect.sqlToQuery(this.getSQL()); return rest; } diff --git a/drizzle-orm/src/pg-core/schema.ts b/drizzle-orm/src/pg-core/schema.ts index 1cbff1218..d8bd84476 100644 --- a/drizzle-orm/src/pg-core/schema.ts +++ b/drizzle-orm/src/pg-core/schema.ts @@ -26,7 +26,7 @@ export function isPgSchema(obj: unknown): obj is PgSchema { export function pgSchema(name: T) { if (name === 'public') { - throw Error( + throw new Error( `You can't specify 'public' as schema name. Postgres is using public schema by default. If you want to use 'public' schema, just use pgTable() instead of creating a schema`, ); } diff --git a/drizzle-orm/src/pg-core/utils.ts b/drizzle-orm/src/pg-core/utils.ts index 993f6a3b3..10c64c891 100644 --- a/drizzle-orm/src/pg-core/utils.ts +++ b/drizzle-orm/src/pg-core/utils.ts @@ -23,9 +23,9 @@ export function getTableConfig(table: TTable) { const extraConfigBuilder = table[PgTable.Symbol.ExtraConfigBuilder]; - if (typeof extraConfigBuilder !== 'undefined') { + if (extraConfigBuilder !== undefined) { const extraConfig = extraConfigBuilder(table[Table.Symbol.Columns]); - Object.values(extraConfig).forEach((builder) => { + for (const builder of Object.values(extraConfig)) { if (builder instanceof IndexBuilder) { indexes.push(builder.build(table)); } else if (builder instanceof CheckBuilder) { @@ -35,7 +35,7 @@ export function getTableConfig(table: TTable) { } else if (builder instanceof ForeignKeyBuilder) { foreignKeys.push(builder.build(table)); } - }); + } } return { @@ -79,7 +79,7 @@ function parsePgArrayValue(arrayString: string, startFrom: number, inQuotes: boo } if (char === '"') { - return [arrayString.substring(startFrom, i).replace(/\\/g, ''), i + 1]; + return [arrayString.slice(startFrom, i).replace(/\\/g, ''), i + 1]; } if (inQuotes) { @@ -87,11 +87,11 @@ function parsePgArrayValue(arrayString: string, startFrom: number, inQuotes: boo } if (char === ',' || char === '}') { - return [arrayString.substring(startFrom, i).replace(/\\/g, ''), i]; + return [arrayString.slice(startFrom, i).replace(/\\/g, ''), i]; } } - return [arrayString.substring(startFrom).replace(/\\/g, ''), arrayString.length]; + return [arrayString.slice(startFrom).replace(/\\/g, ''), arrayString.length]; } export function parsePgNestedArray(arrayString: string, startFrom = 0): [any[], number] { diff --git a/drizzle-orm/src/planetscale-serverless/session.ts b/drizzle-orm/src/planetscale-serverless/session.ts index f9f8f984c..4bcd4751d 100644 --- a/drizzle-orm/src/planetscale-serverless/session.ts +++ b/drizzle-orm/src/planetscale-serverless/session.ts @@ -35,19 +35,19 @@ export class PlanetScalePreparedQuery extends Pre this.logger.logQuery(this.queryString, params); - const { fields } = this; + const { fields, client, queryString, rawQuery, query, joinsNotNullableMap } = this; if (!fields) { - return this.client.execute(this.queryString, params, this.rawQuery); + return client.execute(queryString, params, rawQuery); } - const result = this.client.execute(this.queryString, params, this.query); + const result = client.execute(queryString, params, query); return result.then((eQuery) => - eQuery.rows.map((row) => mapResultRow(fields, row as unknown[], this.joinsNotNullableMap)) + eQuery.rows.map((row) => mapResultRow(fields, row as unknown[], joinsNotNullableMap)) ); } - override async *iterator(placeholderValues?: Record): AsyncGenerator { + override iterator(_placeholderValues?: Record): AsyncGenerator { throw new Error('Streaming is not supported by the PlanetScale Serverless driver'); } } diff --git a/drizzle-orm/src/postgres-js/session.ts b/drizzle-orm/src/postgres-js/session.ts index ee5ec1996..775e7e1ce 100644 --- a/drizzle-orm/src/postgres-js/session.ts +++ b/drizzle-orm/src/postgres-js/session.ts @@ -18,7 +18,6 @@ export class PostgresJsPreparedQuery extends Prep private params: unknown[], private logger: Logger, private fields: SelectedFieldsOrdered | undefined, - name: string | undefined, ) { super(); this.query = queryString; @@ -29,16 +28,14 @@ export class PostgresJsPreparedQuery extends Prep this.logger.logQuery(this.query, params); - const { fields } = this; + const { fields, query, client, joinsNotNullableMap } = this; if (!fields) { - return this.client.unsafe(this.query, params as any[]); + return client.unsafe(query, params as any[]); } - const result = this.client.unsafe(this.query, params as any[]).values(); + const result = client.unsafe(query, params as any[]).values(); - return result.then((result) => - result.map((row) => mapResultRow(fields, row, this.joinsNotNullableMap)) - ); + return result.then((result) => result.map((row) => mapResultRow(fields, row, joinsNotNullableMap))); } all(placeholderValues: Record | undefined = {}): Promise { @@ -74,9 +71,8 @@ export class PostgresJsSession extends PgSession( query: Query, fields: SelectedFieldsOrdered | undefined, - name: string | undefined, ): PreparedQuery { - return new PostgresJsPreparedQuery(this.client, query.sql, query.params, this.logger, fields, name); + return new PostgresJsPreparedQuery(this.client, query.sql, query.params, this.logger, fields); } query(query: string, params: unknown[]): Promise> { @@ -111,7 +107,7 @@ export class PostgresJsTransaction extends PgTransaction, - nestedIndex: number = 0, + nestedIndex = 0, ) { super(dialect, session, nestedIndex); } diff --git a/drizzle-orm/src/query-promise.ts b/drizzle-orm/src/query-promise.ts index 63d5e7c58..d809862f3 100644 --- a/drizzle-orm/src/query-promise.ts +++ b/drizzle-orm/src/query-promise.ts @@ -15,7 +15,7 @@ export abstract class QueryPromise implements Promise { }, (reason) => { onFinally?.(); - return Promise.reject(reason); + throw reason; }, ); } diff --git a/drizzle-orm/src/sql-js/session.ts b/drizzle-orm/src/sql-js/session.ts index c77729022..08d163fc8 100644 --- a/drizzle-orm/src/sql-js/session.ts +++ b/drizzle-orm/src/sql-js/session.ts @@ -100,22 +100,22 @@ export class PreparedQuery } all(placeholderValues?: Record): T['all'] { - const { fields } = this; + const { fields, joinsNotNullableMap, logger, queryString, stmt, isOneTimeQuery } = this; if (fields) { return this.values(placeholderValues).map((row) => - mapResultRow(fields, row.map(normalizeFieldValue), this.joinsNotNullableMap) + mapResultRow(fields, row.map((v) => normalizeFieldValue(v)), joinsNotNullableMap) ); } const params = fillPlaceholders(this.params, placeholderValues ?? {}); - this.logger.logQuery(this.queryString, params); - this.stmt.bind(params as BindParams); + logger.logQuery(queryString, params); + stmt.bind(params as BindParams); const rows: T['all'] = []; - while (this.stmt.step()) { - rows.push(this.stmt.getAsObject()); + while (stmt.step()) { + rows.push(stmt.getAsObject()); } - if (this.isOneTimeQuery) { + if (isOneTimeQuery) { this.free(); } @@ -126,20 +126,20 @@ export class PreparedQuery const params = fillPlaceholders(this.params, placeholderValues ?? {}); this.logger.logQuery(this.queryString, params); - const { fields } = this; + const { fields, stmt, isOneTimeQuery, joinsNotNullableMap } = this; if (!fields) { - const result = this.stmt.getAsObject(params as BindParams); + const result = stmt.getAsObject(params as BindParams); - if (this.isOneTimeQuery) { + if (isOneTimeQuery) { this.free(); } return result; } - const row = this.stmt.get(params as BindParams); + const row = stmt.get(params as BindParams); - if (this.isOneTimeQuery) { + if (isOneTimeQuery) { this.free(); } @@ -147,7 +147,7 @@ export class PreparedQuery return undefined; } - return mapResultRow(fields, row.map(normalizeFieldValue), this.joinsNotNullableMap); + return mapResultRow(fields, row.map((v) => normalizeFieldValue(v)), joinsNotNullableMap); } values(placeholderValues?: Record): T['values'] { diff --git a/drizzle-orm/src/sql/expressions/conditions.ts b/drizzle-orm/src/sql/expressions/conditions.ts index f5b601558..b1d0bc09a 100644 --- a/drizzle-orm/src/sql/expressions/conditions.ts +++ b/drizzle-orm/src/sql/expressions/conditions.ts @@ -22,7 +22,6 @@ export function bindIfParam(value: unknown, column: AnyColumn | SQL.Aliased): SQ return value as SQLChunk; } - /** * Test that two values are equal. * @@ -30,7 +29,7 @@ export function bindIfParam(value: unknown, column: AnyColumn | SQL.Aliased): SQ * two NULL values are not equal, so if you want to test * whether a value is null, you may want to use * `isNull` instead. - * + * * ## Examples * * ```ts @@ -63,7 +62,7 @@ export function eq( * two NULL values are not equal, so if you want to test * whether a value is not null, you may want to use * `isNotNull` instead. - * + * * ## Examples * * ```ts @@ -92,7 +91,7 @@ export function ne( /** * Combine a list of conditions with the `and` operator. Conditions * that are equal `undefined` are automatically ignored. - * + * * ## Examples * * ```ts @@ -111,25 +110,25 @@ export function and(...conditions: (SQL | undefined)[]): SQL | undefined { } const chunks: SQL[] = [sql.raw('(')]; - conditions - .filter((c): c is Exclude => typeof c !== 'undefined') - .forEach((condition, index) => { - if (index === 0) { - chunks.push(condition); - } else { - chunks.push(sql` and `, condition); - } - }); + for ( + const [index, condition] of conditions + .filter((c): c is Exclude => c !== undefined).entries() + ) { + if (index === 0) { + chunks.push(condition); + } else { + chunks.push(sql` and `, condition); + } + } chunks.push(sql`)`); return sql.fromList(chunks); } - /** * Combine a list of conditions with the `or` operator. Conditions * that are equal `undefined` are automatically ignored. - * + * * ## Examples * * ```ts @@ -148,15 +147,16 @@ export function or(...conditions: (SQL | undefined)[]): SQL | undefined { } const chunks: SQL[] = [sql.raw('(')]; - conditions - .filter((c): c is Exclude => typeof c !== 'undefined') - .forEach((condition, index) => { - if (index === 0) { - chunks.push(condition); - } else { - chunks.push(sql` or `, condition); - } - }); + for ( + const [index, condition] of conditions + .filter((c): c is Exclude => c !== undefined).entries() + ) { + if (index === 0) { + chunks.push(condition); + } else { + chunks.push(sql` or `, condition); + } + } chunks.push(sql`)`); return sql.fromList(chunks); @@ -164,7 +164,7 @@ export function or(...conditions: (SQL | undefined)[]): SQL | undefined { /** * Negate the meaning of an expression using the `not` keyword. - * + * * ## Examples * * ```ts @@ -177,7 +177,6 @@ export function not(condition: SQL): SQL { return sql`not ${condition}`; } - /** * Test that the first expression passed is greater than * the second expression. @@ -238,7 +237,6 @@ export function gte( return sql`${left} >= ${bindIfParam(right, left)}`; } - /** * Test that the first expression passed is less than * the second expression. @@ -268,7 +266,6 @@ export function lt( return sql`${left} < ${bindIfParam(right, left)}`; } - /** * Test that the first expression passed is less than * or equal to the second expression. @@ -298,13 +295,12 @@ export function lte( return sql`${left} <= ${bindIfParam(right, left)}`; } - /** * Test whether the first parameter, a column or expression, * has a value from a list passed as the second argument. * * ## Throws - * + * * The argument passed in the second array can’t be empty: * if an empty is provided, this method will throw. * @@ -346,7 +342,7 @@ export function inArray( * second argument. * * ## Throws - * + * * The argument passed in the second array can’t be empty: * if an empty is provided, this method will throw. * @@ -386,7 +382,6 @@ export function notInArray( return sql`${column} not in ${bindIfParam(values, column)}`; } - /** * Test whether an expression is NULL. By the SQL standard, * NULL is neither equal nor not equal to itself, so @@ -548,7 +543,6 @@ export function notBetween( return sql`${column} not between ${bindIfParam(min, column)} and ${bindIfParam(max, column)}`; } - /** * Compare a column to a pattern, which can include `%` and `_` * characters to match multiple variations. Including `%` diff --git a/drizzle-orm/src/sql/index.ts b/drizzle-orm/src/sql/index.ts index f2a1c476c..6a67b5161 100644 --- a/drizzle-orm/src/sql/index.ts +++ b/drizzle-orm/src/sql/index.ts @@ -50,13 +50,13 @@ export function isSQLWrapper(value: unknown): value is SQLWrapper { function mergeQueries(queries: Query[]): Query { const result: Query = { sql: '', params: [] }; - queries.forEach((query) => { + for (const query of queries) { result.sql += query.sql; result.params.push(...query.params); if (result.typings && query.typings?.length) { result.typings.push(...query.typings); } - }); + } return result; } @@ -98,7 +98,6 @@ export class SQL implements SQLWrapper { const { escapeName, escapeParam, - escapeString, prepareTyping, inlineParams, paramStartIndex, @@ -113,18 +112,18 @@ export class SQL implements SQLWrapper { return { sql: escapeName(chunk.value), params: [] }; } - if (typeof chunk === 'undefined') { + if (chunk === undefined) { return { sql: '', params: [] }; } if (Array.isArray(chunk)) { const result: SQLChunk[] = [new StringChunk('(')]; - chunk.forEach((p, i) => { + for (const [i, p] of chunk.entries()) { result.push(p); if (i < chunk.length - 1) { result.push(new StringChunk(', ')); } - }); + } result.push(new StringChunk(')')); return this.buildQueryFromSourceParams(result, config); } @@ -140,9 +139,9 @@ export class SQL implements SQLWrapper { const schemaName = chunk[Table.Symbol.Schema]; const tableName = chunk[Table.Symbol.Name]; return { - sql: typeof schemaName !== 'undefined' - ? escapeName(schemaName) + '.' + escapeName(tableName) - : escapeName(tableName), + sql: schemaName === undefined + ? escapeName(tableName) + : escapeName(schemaName) + '.' + escapeName(tableName), params: [], }; } @@ -155,15 +154,15 @@ export class SQL implements SQLWrapper { const schemaName = chunk[ViewBaseConfig].schema; const viewName = chunk[ViewBaseConfig].name; return { - sql: typeof schemaName !== 'undefined' - ? escapeName(schemaName) + '.' + escapeName(viewName) - : escapeName(viewName), + sql: schemaName === undefined + ? escapeName(viewName) + : escapeName(schemaName) + '.' + escapeName(viewName), params: [], }; } if (chunk instanceof Param) { - const mappedValue = chunk.value === null ? null : chunk.encoder.mapToDriverValue(chunk.value); + const mappedValue = (chunk.value === null) ? null : chunk.encoder.mapToDriverValue(chunk.value); if (mappedValue instanceof SQL) { return this.buildQueryFromSourceParams([mappedValue], config); @@ -174,14 +173,14 @@ export class SQL implements SQLWrapper { } let typings: QueryTypingsValue[] | undefined; - if (typeof prepareTyping !== 'undefined') { + if (prepareTyping !== undefined) { typings = [prepareTyping(chunk.encoder)]; } return { sql: escapeParam(paramStartIndex.value++, mappedValue), params: [mappedValue], typings }; } - if (chunk instanceof SQL.Aliased && typeof chunk.fieldAlias !== 'undefined') { + if (chunk instanceof SQL.Aliased && chunk.fieldAlias !== undefined) { return { sql: escapeName(chunk.fieldAlias), params: [] }; } @@ -253,7 +252,7 @@ export class SQL implements SQLWrapper { as(alias: string): SQL.Aliased; as(alias?: string): SQL | SQL.Aliased { // TODO: remove with deprecated overloads - if (typeof alias === 'undefined') { + if (alias === undefined) { return this; } @@ -265,11 +264,7 @@ export class SQL implements SQLWrapper { | DriverValueDecoder | DriverValueDecoder['mapFromDriverValue'], >(decoder: TDecoder): SQL> { - if (typeof decoder === 'function') { - this.decoder = { mapFromDriverValue: decoder }; - } else { - this.decoder = decoder; - } + this.decoder = typeof decoder === 'function' ? { mapFromDriverValue: decoder } : decoder; return this as SQL>; } @@ -379,10 +374,9 @@ export function sql(strings: TemplateStringsArray, ...params: SQLChunk[]): SQL { if (params.length > 0 || (strings.length > 0 && strings[0] !== '')) { queryChunks.push(new StringChunk(strings[0]!)); } - params.forEach((param, paramIndex) => { - queryChunks.push(param); - queryChunks.push(new StringChunk(strings[paramIndex + 1]!)); - }); + for (const [paramIndex, param] of params.entries()) { + queryChunks.push(param, new StringChunk(strings[paramIndex + 1]!)); + } return new SQL(queryChunks); } @@ -409,11 +403,11 @@ export namespace sql { */ export function join(chunks: SQLChunk[], separator: SQLChunk): SQL { const result: SQLChunk[] = []; - for (let i = 0; i < chunks.length; i++) { + for (const [i, chunk] of chunks.entries()) { if (i > 0) { result.push(separator); } - result.push(chunks[i]); + result.push(chunk); } return sql.fromList(result); } diff --git a/drizzle-orm/src/sqlite-core/checks.ts b/drizzle-orm/src/sqlite-core/checks.ts index 5052ffce2..20eaf60b9 100644 --- a/drizzle-orm/src/sqlite-core/checks.ts +++ b/drizzle-orm/src/sqlite-core/checks.ts @@ -25,6 +25,6 @@ export class Check { } } -export function check(name: string, value: SQL): CheckBuilder { +export function check(name: string, value: SQL): CheckBuilder { return new CheckBuilder(name, value); } diff --git a/drizzle-orm/src/sqlite-core/columns/custom.ts b/drizzle-orm/src/sqlite-core/columns/custom.ts index 4b0c89328..59436017d 100644 --- a/drizzle-orm/src/sqlite-core/columns/custom.ts +++ b/drizzle-orm/src/sqlite-core/columns/custom.ts @@ -81,19 +81,11 @@ export class SQLiteCustomColumn extends SQLiteColumn } override mapFromDriverValue(value: T['driverParam']): T['data'] { - if (typeof this.mapFrom === 'function') { - return this.mapFrom(value); - } else { - return value as T['data']; - } + return typeof this.mapFrom === 'function' ? this.mapFrom(value) : value as T['data']; } override mapToDriverValue(value: T['data']): T['driverParam'] { - if (typeof this.mapTo === 'function') { - return this.mapTo(value); - } else { - return value as T['data']; - } + return typeof this.mapTo === 'function' ? this.mapTo(value) : value as T['data']; } } diff --git a/drizzle-orm/src/sqlite-core/dialect.ts b/drizzle-orm/src/sqlite-core/dialect.ts index d5310c315..3cca4770d 100644 --- a/drizzle-orm/src/sqlite-core/dialect.ts +++ b/drizzle-orm/src/sqlite-core/dialect.ts @@ -19,7 +19,7 @@ export abstract class SQLiteDialect { return `"${name}"`; } - escapeParam(num: number): string { + escapeParam(_num: number): string { return '?'; } @@ -43,15 +43,14 @@ export abstract class SQLiteDialect { const setSize = setEntries.length; return sql.fromList( setEntries - .map(([colName, value], i): SQL[] => { + .flatMap(([colName, value], i): SQL[] => { const col: AnySQLiteColumn = table[Table.Symbol.Columns][colName]!; const res = sql`${name(col.name)} = ${value}`; if (i < setSize - 1) { return [res, sql.raw(', ')]; } return [res]; - }) - .flat(1), + }), ); } @@ -85,7 +84,7 @@ export abstract class SQLiteDialect { const columnsLen = fields.length; const chunks = fields - .map(({ field }, i) => { + .flatMap(({ field }, i) => { const chunk: SQLChunk[] = []; if (field instanceof SQL.Aliased && field.isSelectionField) { @@ -126,8 +125,7 @@ export abstract class SQLiteDialect { } return chunk; - }) - .flat(1); + }); return sql.fromList(chunks); } @@ -136,7 +134,7 @@ export abstract class SQLiteDialect { { withList, fields, where, having, table, joins, orderBy, groupBy, limit, offset }: SQLiteSelectConfig, ): SQL { const fieldsList = orderSelectedFields(fields); - fieldsList.forEach((f) => { + for (const f of fieldsList) { if ( f.field instanceof Column && getTableName(f.field.table) @@ -156,19 +154,19 @@ export abstract class SQLiteDialect { }" field references a column "${tableName}"."${f.field.name}", but the table "${tableName}" is not part of the query! Did you forget to join it?`, ); } - }); + } const isSingleTable = joins.length === 0; let withSql: SQL | undefined; if (withList.length) { const withSqlChunks = [sql`with `]; - withList.forEach((w, i) => { + for (const [i, w] of withList.entries()) { withSqlChunks.push(sql`${name(w[SubqueryConfig].alias)} as (${w[SubqueryConfig].sql})`); if (i < withList.length - 1) { withSqlChunks.push(sql`, `); } - }); + } withSqlChunks.push(sql` `); withSql = sql.fromList(withSqlChunks); } @@ -177,7 +175,7 @@ export abstract class SQLiteDialect { const joinsArray: SQL[] = []; - joins.forEach((joinMeta, index) => { + for (const [index, joinMeta] of joins.entries()) { if (index === 0) { joinsArray.push(sql` `); } @@ -201,7 +199,7 @@ export abstract class SQLiteDialect { if (index < joins.length - 1) { joinsArray.push(sql` `); } - }); + } const joinsSql = sql.fromList(joinsArray); @@ -210,22 +208,22 @@ export abstract class SQLiteDialect { const havingSql = having ? sql` having ${having}` : undefined; const orderByList: (AnySQLiteColumn | SQL | SQL.Aliased)[] = []; - orderBy.forEach((orderByValue, index) => { + for (const [index, orderByValue] of orderBy.entries()) { orderByList.push(orderByValue); if (index < orderBy.length - 1) { orderByList.push(sql`, `); } - }); + } const groupByList: (SQL | AnyColumn | SQL.Aliased)[] = []; - groupBy.forEach((groupByValue, index) => { + for (const [index, groupByValue] of groupBy.entries()) { groupByList.push(groupByValue); if (index < groupBy.length - 1) { groupByList.push(sql`, `); } - }); + } const groupBySql = groupByList.length > 0 ? sql` group by ${sql.fromList(groupByList)}` : undefined; @@ -247,18 +245,14 @@ export abstract class SQLiteDialect { : Object.entries(columns); const insertOrder = colEntries.map(([, column]) => name(column.name)); - values.forEach((value, valueIndex) => { + for (const [valueIndex, value] of values.entries()) { const valueList: (SQLChunk | SQL)[] = []; - colEntries.forEach(([fieldName, col]) => { + for (const [fieldName, col] of colEntries) { const colValue = value[fieldName]; - if (typeof colValue === 'undefined') { + if (colValue === undefined) { let defaultValue; if (col.default !== null && col.default !== undefined) { - if (col.default instanceof SQL) { - defaultValue = col.default; - } else { - defaultValue = param(col.default, col); - } + defaultValue = col.default instanceof SQL ? col.default : param(col.default, col); } else { defaultValue = sql`null`; } @@ -266,12 +260,12 @@ export abstract class SQLiteDialect { } else { valueList.push(colValue); } - }); + } valuesSqlList.push(valueList); if (valueIndex < values.length - 1) { valuesSqlList.push(sql`, `); } - }); + } const valuesSql = sql.fromList(valuesSqlList); @@ -295,11 +289,13 @@ export abstract class SQLiteDialect { export class SQLiteSyncDialect extends SQLiteDialect { migrate(migrations: MigrationMeta[], session: SQLiteSession<'sync'>): void { - const migrationTableCreate = sql`CREATE TABLE IF NOT EXISTS "__drizzle_migrations" ( - id SERIAL PRIMARY KEY, - hash text NOT NULL, - created_at numeric - )`; + const migrationTableCreate = sql` + CREATE TABLE IF NOT EXISTS "__drizzle_migrations" ( + id SERIAL PRIMARY KEY, + hash text NOT NULL, + created_at numeric + ) + `; session.run(migrationTableCreate); const dbMigrations = session.values<[number, string, string]>( @@ -311,7 +307,7 @@ export class SQLiteSyncDialect extends SQLiteDialect { try { for (const migration of migrations) { - if (!lastDbMigration || parseInt(lastDbMigration[2], 10)! < migration.folderMillis) { + if (!lastDbMigration || Number(lastDbMigration[2])! < migration.folderMillis) { for (const stmt of migration.sql) { session.run(sql.raw(stmt)); } @@ -331,11 +327,13 @@ export class SQLiteSyncDialect extends SQLiteDialect { export class SQLiteAsyncDialect extends SQLiteDialect { async migrate(migrations: MigrationMeta[], session: SQLiteSession<'async'>): Promise { - const migrationTableCreate = sql`CREATE TABLE IF NOT EXISTS "__drizzle_migrations" ( - id SERIAL PRIMARY KEY, - hash text NOT NULL, - created_at numeric - )`; + const migrationTableCreate = sql` + CREATE TABLE IF NOT EXISTS "__drizzle_migrations" ( + id SERIAL PRIMARY KEY, + hash text NOT NULL, + created_at numeric + ) + `; await session.run(migrationTableCreate); const dbMigrations = await session.values<[number, string, string]>( @@ -346,7 +344,7 @@ export class SQLiteAsyncDialect extends SQLiteDialect { await session.transaction(async (tx) => { for (const migration of migrations) { - if (!lastDbMigration || parseInt(lastDbMigration[2], 10)! < migration.folderMillis) { + if (!lastDbMigration || Number(lastDbMigration[2])! < migration.folderMillis) { for (const stmt of migration.sql) { await tx.run(sql.raw(stmt)); } diff --git a/drizzle-orm/src/sqlite-core/query-builders/delete.ts b/drizzle-orm/src/sqlite-core/query-builders/delete.ts index 85ce7f60b..02a358ecd 100644 --- a/drizzle-orm/src/sqlite-core/query-builders/delete.ts +++ b/drizzle-orm/src/sqlite-core/query-builders/delete.ts @@ -15,10 +15,15 @@ export interface SQLiteDeleteConfig { returning?: SelectedFieldsOrdered; } +// eslint-disable-next-line @typescript-eslint/no-empty-interface export interface SQLiteDelete< + // eslint-disable-next-line @typescript-eslint/no-unused-vars TTable extends AnySQLiteTable, + // eslint-disable-next-line @typescript-eslint/no-unused-vars TResultType extends 'sync' | 'async', + // eslint-disable-next-line @typescript-eslint/no-unused-vars TRunResult, + // eslint-disable-next-line @typescript-eslint/no-unused-vars TReturning = undefined, > extends SQLWrapper {} @@ -60,7 +65,7 @@ export class SQLiteDelete< } toSQL(): Omit { - const { typings, ...rest } = this.dialect.sqlToQuery(this.getSQL()); + const { typings: _typings, ...rest } = this.dialect.sqlToQuery(this.getSQL()); return rest; } diff --git a/drizzle-orm/src/sqlite-core/query-builders/insert.ts b/drizzle-orm/src/sqlite-core/query-builders/insert.ts index 951e3dc86..e8f908353 100644 --- a/drizzle-orm/src/sqlite-core/query-builders/insert.ts +++ b/drizzle-orm/src/sqlite-core/query-builders/insert.ts @@ -46,22 +46,14 @@ export class SQLiteInsertBuilder< ...values: SQLiteInsertValue[] | [SQLiteInsertValue] | [SQLiteInsertValue[]] ): SQLiteInsert { if (values.length === 1) { - if (Array.isArray(values[0])) { - values = values[0]; - } else { - values = [values[0]]; - } + values = Array.isArray(values[0]) ? values[0] : [values[0]]; } const mappedValues = values.map((entry) => { const result: Record = {}; const cols = this.table[Table.Symbol.Columns]; for (const colKey of Object.keys(entry)) { const colValue = entry[colKey as keyof typeof entry]; - if (colValue instanceof SQL) { - result[colKey] = colValue; - } else { - result[colKey] = new Param(colValue, cols[colKey]); - } + result[colKey] = colValue instanceof SQL ? colValue : new Param(colValue, cols[colKey]); } return result; }); @@ -70,10 +62,15 @@ export class SQLiteInsertBuilder< } } +// eslint-disable-next-line @typescript-eslint/no-empty-interface export interface SQLiteInsert< + // eslint-disable-next-line @typescript-eslint/no-unused-vars TTable extends AnySQLiteTable, + // eslint-disable-next-line @typescript-eslint/no-unused-vars TResultType extends 'sync' | 'async', + // eslint-disable-next-line @typescript-eslint/no-unused-vars TRunResult, + // eslint-disable-next-line @typescript-eslint/no-unused-vars TReturning = undefined, > extends SQLWrapper {} @@ -145,7 +142,7 @@ export class SQLiteInsert< } toSQL(): Simplify> { - const { typings, ...rest } = this.dialect.sqlToQuery(this.getSQL()); + const { typings: _typings, ...rest } = this.dialect.sqlToQuery(this.getSQL()); return rest; } diff --git a/drizzle-orm/src/sqlite-core/query-builders/select.ts b/drizzle-orm/src/sqlite-core/query-builders/select.ts index 848329c6c..9f1426009 100644 --- a/drizzle-orm/src/sqlite-core/query-builders/select.ts +++ b/drizzle-orm/src/sqlite-core/query-builders/select.ts @@ -198,24 +198,28 @@ export abstract class SQLiteSelectQueryBuilder< if (typeof tableName === 'string') { switch (joinType) { - case 'left': + case 'left': { this.joinsNotNullableMap[tableName] = false; break; - case 'right': + } + case 'right': { this.joinsNotNullableMap = Object.fromEntries( Object.entries(this.joinsNotNullableMap).map(([key]) => [key, false]), ); this.joinsNotNullableMap[tableName] = true; break; - case 'inner': + } + case 'inner': { this.joinsNotNullableMap[tableName] = true; break; - case 'full': + } + case 'full': { this.joinsNotNullableMap = Object.fromEntries( Object.entries(this.joinsNotNullableMap).map(([key]) => [key, false]), ); this.joinsNotNullableMap[tableName] = false; break; + } } } @@ -315,7 +319,7 @@ export abstract class SQLiteSelectQueryBuilder< } toSQL(): Simplify> { - const { typings, ...rest } = this.dialect.sqlToQuery(this.getSQL()); + const { typings: _typings, ...rest } = this.dialect.sqlToQuery(this.getSQL()); return rest; } @@ -336,6 +340,7 @@ export abstract class SQLiteSelectQueryBuilder< } } +// eslint-disable-next-line @typescript-eslint/no-empty-interface export interface SQLiteSelect< TTableName extends string | undefined, TResultType extends 'sync' | 'async', diff --git a/drizzle-orm/src/sqlite-core/query-builders/update.ts b/drizzle-orm/src/sqlite-core/query-builders/update.ts index 528bc59f3..e9f0fccae 100644 --- a/drizzle-orm/src/sqlite-core/query-builders/update.ts +++ b/drizzle-orm/src/sqlite-core/query-builders/update.ts @@ -45,10 +45,15 @@ export class SQLiteUpdateBuilder< } } +// eslint-disable-next-line @typescript-eslint/no-empty-interface export interface SQLiteUpdate< + // eslint-disable-next-line @typescript-eslint/no-unused-vars TTable extends AnySQLiteTable, + // eslint-disable-next-line @typescript-eslint/no-unused-vars TResultType extends 'sync' | 'async', + // eslint-disable-next-line @typescript-eslint/no-unused-vars TRunResult, + // eslint-disable-next-line @typescript-eslint/no-unused-vars TReturning = undefined, > extends SQLWrapper {} @@ -101,7 +106,7 @@ export class SQLiteUpdate< } toSQL(): Omit { - const { typings, ...rest } = this.dialect.sqlToQuery(this.getSQL()); + const { typings: _typings, ...rest } = this.dialect.sqlToQuery(this.getSQL()); return rest; } diff --git a/drizzle-orm/src/sqlite-core/table.ts b/drizzle-orm/src/sqlite-core/table.ts index bdf774ad4..096e52e63 100644 --- a/drizzle-orm/src/sqlite-core/table.ts +++ b/drizzle-orm/src/sqlite-core/table.ts @@ -63,8 +63,6 @@ export interface SQLiteTableFn { }>; } -type Arguments = T extends (...args: infer TArgs) => any ? TArgs : never; - function sqliteTableBase< TTableName extends string, TColumnsMap extends Record, diff --git a/drizzle-orm/src/sqlite-core/utils.ts b/drizzle-orm/src/sqlite-core/utils.ts index 551e1d68b..28ed3dc56 100644 --- a/drizzle-orm/src/sqlite-core/utils.ts +++ b/drizzle-orm/src/sqlite-core/utils.ts @@ -22,9 +22,9 @@ export function getTableConfig(table: TTable) { const extraConfigBuilder = table[SQLiteTable.Symbol.ExtraConfigBuilder]; - if (typeof extraConfigBuilder !== 'undefined') { + if (extraConfigBuilder !== undefined) { const extraConfig = extraConfigBuilder(table[SQLiteTable.Symbol.Columns]); - Object.values(extraConfig).forEach((builder) => { + for (const builder of Object.values(extraConfig)) { if (builder instanceof IndexBuilder) { indexes.push(builder.build(table)); } else if (builder instanceof CheckBuilder) { @@ -34,7 +34,7 @@ export function getTableConfig(table: TTable) { } else if (builder instanceof ForeignKeyBuilder) { foreignKeys.push(builder.build(table)); } - }); + } } return { diff --git a/drizzle-orm/src/sqlite-proxy/migrator.ts b/drizzle-orm/src/sqlite-proxy/migrator.ts index 8f5c0be94..7bbdb0ea8 100644 --- a/drizzle-orm/src/sqlite-proxy/migrator.ts +++ b/drizzle-orm/src/sqlite-proxy/migrator.ts @@ -1,4 +1,4 @@ -import type { MigrationConfig} from '~/migrator'; +import type { MigrationConfig } from '~/migrator'; import { readMigrationFiles } from '~/migrator'; import { sql } from '~/sql'; import type { SqliteRemoteDatabase } from './driver'; @@ -8,11 +8,13 @@ export type ProxyMigrator = (migrationQueries: string[]) => Promise; export async function migrate(db: SqliteRemoteDatabase, callback: ProxyMigrator, config: string | MigrationConfig) { const migrations = readMigrationFiles(config); - const migrationTableCreate = sql`CREATE TABLE IF NOT EXISTS "__drizzle_migrations" ( - id SERIAL PRIMARY KEY, - hash text NOT NULL, - created_at numeric - )`; + const migrationTableCreate = sql` + CREATE TABLE IF NOT EXISTS "__drizzle_migrations" ( + id SERIAL PRIMARY KEY, + hash text NOT NULL, + created_at numeric + ) + `; await db.run(migrationTableCreate); @@ -22,19 +24,15 @@ export async function migrate(db: SqliteRemoteDatabase, callback: ProxyMigrator, const lastDbMigration = dbMigrations[0] ?? undefined; - try { - const queriesToRun: string[] = []; - for (const migration of migrations) { - if (!lastDbMigration || parseInt(lastDbMigration[2], 10)! < migration.folderMillis) { - queriesToRun.push(...migration.sql); - queriesToRun.push( - `INSERT INTO "__drizzle_migrations" ("hash", "created_at") VALUES('${migration.hash}', '${migration.folderMillis}')`, - ); - } + const queriesToRun: string[] = []; + for (const migration of migrations) { + if (!lastDbMigration || Number(lastDbMigration[2])! < migration.folderMillis) { + queriesToRun.push( + ...migration.sql, + `INSERT INTO "__drizzle_migrations" ("hash", "created_at") VALUES('${migration.hash}', '${migration.folderMillis}')`, + ); } - - await callback(queriesToRun); - } catch (e) { - throw e; } + + await callback(queriesToRun); } diff --git a/drizzle-orm/src/sqlite-proxy/session.ts b/drizzle-orm/src/sqlite-proxy/session.ts index ad46476e0..cfe3292de 100644 --- a/drizzle-orm/src/sqlite-proxy/session.ts +++ b/drizzle-orm/src/sqlite-proxy/session.ts @@ -87,35 +87,33 @@ export class PreparedQuery } async all(placeholderValues?: Record): Promise { - const { fields } = this; + const { fields, queryString, logger, joinsNotNullableMap } = this; const params = fillPlaceholders(this.params, placeholderValues ?? {}); - this.logger.logQuery(this.queryString, params); + logger.logQuery(queryString, params); - const clientResult = this.client(this.queryString, params, 'all'); + const clientResult = this.client(queryString, params, 'all'); if (fields) { - return clientResult.then((values) => - values.rows.map((row) => mapResultRow(fields, row, this.joinsNotNullableMap)) - ); + return clientResult.then((values) => values.rows.map((row) => mapResultRow(fields, row, joinsNotNullableMap))); } - return this.client(this.queryString, params, 'all').then(({ rows }) => rows!); + return this.client(queryString, params, 'all').then(({ rows }) => rows!); } async get(placeholderValues?: Record): Promise { - const { fields } = this; + const { fields, queryString, logger, joinsNotNullableMap } = this; const params = fillPlaceholders(this.params, placeholderValues ?? {}); - this.logger.logQuery(this.queryString, params); + logger.logQuery(queryString, params); - const clientResult = await this.client(this.queryString, params, 'get'); + const clientResult = await this.client(queryString, params, 'get'); if (fields) { - if (typeof clientResult.rows === 'undefined') { - return mapResultRow(fields, [], this.joinsNotNullableMap); + if (clientResult.rows === undefined) { + return mapResultRow(fields, [], joinsNotNullableMap); } - return mapResultRow(fields, clientResult.rows, this.joinsNotNullableMap); + return mapResultRow(fields, clientResult.rows, joinsNotNullableMap); } return clientResult.rows; diff --git a/drizzle-orm/src/subquery.ts b/drizzle-orm/src/subquery.ts index 16942f7b8..7b8b4cc82 100644 --- a/drizzle-orm/src/subquery.ts +++ b/drizzle-orm/src/subquery.ts @@ -20,7 +20,7 @@ export class Subquery isWith: boolean; }; - constructor(sql: SQL, selection: Record, alias: string, isWith: boolean = false) { + constructor(sql: SQL, selection: Record, alias: string, isWith = false) { this[SubqueryConfig] = { sql, selection, @@ -69,7 +69,7 @@ export class SelectionProxyHandler this.config = { ...config }; } - get(subquery: T, prop: string | symbol, receiver: any): any { + get(subquery: T, prop: string | symbol): any { if (prop === SubqueryConfig) { return { ...subquery[SubqueryConfig as keyof typeof subquery], diff --git a/drizzle-orm/src/utils.ts b/drizzle-orm/src/utils.ts index 36096f360..d39051900 100644 --- a/drizzle-orm/src/utils.ts +++ b/drizzle-orm/src/utils.ts @@ -24,7 +24,7 @@ export function mapResultRow( decoder = field.sql.decoder; } let node = result; - path.forEach((pathChunk, pathChunkIndex) => { + for (const [pathChunkIndex, pathChunk] of path.entries()) { if (pathChunkIndex < path.length - 1) { if (!(pathChunk in node)) { node[pathChunk] = {}; @@ -37,11 +37,7 @@ export function mapResultRow( if (joinsNotNullableMap && field instanceof Column && path.length === 2) { const objectName = path[0]!; if (!(objectName in nullifyMap)) { - if (value === null) { - nullifyMap[objectName] = getTableName(field.table); - } else { - nullifyMap[objectName] = false; - } + nullifyMap[objectName] = value === null ? getTableName(field.table) : false; } else if ( typeof nullifyMap[objectName] === 'string' && nullifyMap[objectName] !== getTableName(field.table) ) { @@ -49,7 +45,7 @@ export function mapResultRow( } } } - }); + } return result; }, {}, @@ -57,11 +53,11 @@ export function mapResultRow( // Nullify all nested objects from nullifyMap that are nullable if (joinsNotNullableMap && Object.keys(nullifyMap).length > 0) { - Object.entries(nullifyMap).forEach(([objectName, tableName]) => { + for (const [objectName, tableName] of Object.entries(nullifyMap)) { if (typeof tableName === 'string' && !joinsNotNullableMap[tableName]) { result[objectName] = null; } - }); + } } return result as TResult; @@ -96,6 +92,7 @@ export function orderSelectedFields( export function mapUpdateSet(table: Table, values: Record): UpdateSet { return Object.fromEntries( Object.entries(values).map(([key, value]) => { + // eslint-disable-next-line unicorn/prefer-ternary if (value instanceof SQL || value === null || value === undefined) { return [key, value]; } else { @@ -210,15 +207,15 @@ export interface DrizzleTypeError { export type ValueOrArray = T | T[]; export function applyMixins(baseClass: any, extendedClasses: any[]) { - extendedClasses.forEach((extendedClass) => { - Object.getOwnPropertyNames(extendedClass.prototype).forEach((name) => { + for (const extendedClass of extendedClasses) { + for (const name of Object.getOwnPropertyNames(extendedClass.prototype)) { Object.defineProperty( baseClass.prototype, name, Object.getOwnPropertyDescriptor(extendedClass.prototype, name) || Object.create(null), ); - }); - }); + } + } } export type Or = T1 extends true ? true : T2 extends true ? true : false; diff --git a/drizzle-orm/type-tests/knex/index.ts b/drizzle-orm/type-tests/knex/index.ts index 959b63d50..01406e054 100644 --- a/drizzle-orm/type-tests/knex/index.ts +++ b/drizzle-orm/type-tests/knex/index.ts @@ -3,7 +3,6 @@ import { type Equal, Expect } from 'type-tests/utils'; import { pgTable, serial, text } from '~/pg-core'; import type { PromiseOf } from '~/utils'; import '~/knex'; -import type { InferModel } from '~/table'; const test = pgTable('test', { id: serial('id').primaryKey(), @@ -22,13 +21,3 @@ const db = Knex({}); const res = db('test').select(); Expect, typeof test['_']['model']['select'][]>>; } - -{ - // before - type Test = InferModel; -} - -{ - // after - type Test = typeof test['_']['model']['select']; -} diff --git a/drizzle-orm/type-tests/mysql/select.ts b/drizzle-orm/type-tests/mysql/select.ts index 74551588a..b4ab1706c 100644 --- a/drizzle-orm/type-tests/mysql/select.ts +++ b/drizzle-orm/type-tests/mysql/select.ts @@ -374,7 +374,7 @@ Expect< >; { - let authenticated = false; + const authenticated = false as boolean; const result = await db .select({ @@ -400,7 +400,7 @@ await db.select().from(users).for('update', { noWait: true }); await db .select() .from(users) - // @ts-expect-error + // @ts-expect-error - can't use both skipLocked and noWait .for('share', { noWait: true, skipLocked: true }); { diff --git a/drizzle-orm/type-tests/mysql/tables.ts b/drizzle-orm/type-tests/mysql/tables.ts index 40afca58f..89ef1ca0d 100644 --- a/drizzle-orm/type-tests/mysql/tables.ts +++ b/drizzle-orm/type-tests/mysql/tables.ts @@ -348,7 +348,7 @@ Expect< } { - const test = mysqlTable('test', { + mysqlTable('test', { bigint: bigint('bigint', { mode: 'bigint' }), number: bigint('number', { mode: 'number' }), date: date('date').default(new Date()), @@ -367,7 +367,7 @@ Expect< } { - const test = mysqlTable('test', { + mysqlTable('test', { col1: decimal('col1').default('1'), }); } @@ -408,12 +408,12 @@ Expect< } { - function getUsersTable(schemaName: TSchema) { + const getUsersTable = (schemaName: TSchema) => { return mysqlSchema(schemaName).table('users', { id: int('id').primaryKey(), name: text('name').notNull(), }); - } + }; const users1 = getUsersTable('id1'); Expect>; diff --git a/drizzle-orm/type-tests/pg/select.ts b/drizzle-orm/type-tests/pg/select.ts index b3633426d..daac279ba 100644 --- a/drizzle-orm/type-tests/pg/select.ts +++ b/drizzle-orm/type-tests/pg/select.ts @@ -39,7 +39,7 @@ const city1 = alias(cities, 'city1'); const leftJoinFull = await db.select().from(users).leftJoin(city, eq(users.id, city.id)); { - const result = await db.select().from(users).leftJoin(city, eq(users.id, city.id)); + await db.select().from(users).leftJoin(city, eq(users.id, city.id)); } Expect< @@ -723,7 +723,7 @@ Expect< > >; -const megaFullJoin = await db +await db .select({ user: { id: users.id, @@ -817,7 +817,7 @@ Expect< >; { - let authenticated = false; + const authenticated = false as boolean; const result = await db .select({ @@ -844,7 +844,7 @@ await db .for('no key update', { of: users }) .for('no key update', { of: users, skipLocked: true }) .for('share', { of: users, noWait: true }) - // @ts-expect-error + // @ts-expect-error - can't use both skipLocked and noWait .for('share', { of: users, noWait: true, skipLocked: true }); await db @@ -911,12 +911,12 @@ await db { // TODO: add to docs - function withPagination(qb: T) { + const withPagination = (qb: T) => { return qb.offset(10).limit(10); - } + }; const qb = db.select().from(users); - const result = await withPagination(qb); + await withPagination(qb); } { @@ -925,11 +925,11 @@ await db application: text('application', { enum: ['pending', 'approved'] }), }); - function startIt(whereCallback: (condition: SQL) => SQL | undefined = (c) => c) { + const startIt = (whereCallback: (condition: SQL) => SQL | undefined = (c) => c) => { return db.select().from(users).where(whereCallback(eq(users.developer, true))); - } + }; - const query = startIt((c) => and(c, eq(users.application, 'approved'))); + startIt((c) => and(c, eq(users.application, 'approved'))); } { diff --git a/drizzle-orm/type-tests/pg/tables.ts b/drizzle-orm/type-tests/pg/tables.ts index beee78d82..faf6c988a 100644 --- a/drizzle-orm/type-tests/pg/tables.ts +++ b/drizzle-orm/type-tests/pg/tables.ts @@ -645,9 +645,9 @@ await db.refreshMaterializedView(newYorkers2).withNoData().concurrently(); }, }); - const t1 = customTextRequired('t', { length: 10 }); - // @ts-expect-error - const t2 = customTextRequired('t'); + customTextRequired('t', { length: 10 }); + // @ts-expect-error - config is required + customTextRequired('t'); } { @@ -672,8 +672,8 @@ await db.refreshMaterializedView(newYorkers2).withNoData().concurrently(); }, }); - const t1 = customTextOptional('t', { length: 10 }); - const t2 = customTextOptional('t'); + customTextOptional('t', { length: 10 }); + customTextOptional('t'); } { @@ -734,7 +734,7 @@ await db.refreshMaterializedView(newYorkers2).withNoData().concurrently(); } { - const test = pgTable('test', { + pgTable('test', { bigint: bigint('bigint', { mode: 'bigint' }).default(BigInt(10)), bigintNumber: bigint('bigintNumber', { mode: 'number' }), bigserial: bigserial('bigserial', { mode: 'bigint' }).default(BigInt(10)), @@ -756,21 +756,21 @@ await db.refreshMaterializedView(newYorkers2).withNoData().concurrently(); { const a = ['a', 'b', 'c'] as const; const b = pgEnum('test', a); - const c = z.enum(b.enumValues); + z.enum(b.enumValues); } { const b = pgEnum('test', ['a', 'b', 'c']); - const c = z.enum(b.enumValues); + z.enum(b.enumValues); } { - function getUsersTable(schemaName: TSchema) { + const getUsersTable = (schemaName: TSchema) => { return pgSchema(schemaName).table('users', { id: integer('id').primaryKey(), name: text('name').notNull(), }); - } + }; const users1 = getUsersTable('id1'); Expect>; diff --git a/drizzle-orm/type-tests/sqlite/insert.ts b/drizzle-orm/type-tests/sqlite/insert.ts index 94a08b568..87694fe8a 100644 --- a/drizzle-orm/type-tests/sqlite/insert.ts +++ b/drizzle-orm/type-tests/sqlite/insert.ts @@ -140,9 +140,9 @@ Expect< }[], typeof insertReturningSqlBun> >; -const upsertDoNothing1 = db.insert(users).values(newUser).onConflictDoNothing().run(); -const upsertDoNothing2 = db.insert(users).values(newUser).onConflictDoNothing({ target: users.class }).run(); -const upsertDoNothing3 = db.insert(users).values(newUser).onConflictDoNothing({ +db.insert(users).values(newUser).onConflictDoNothing().run(); +db.insert(users).values(newUser).onConflictDoNothing({ target: users.class }).run(); +db.insert(users).values(newUser).onConflictDoNothing({ target: [ sql`${users.class} collate nocase asc`, sql`${users.age1} desc`, @@ -150,13 +150,13 @@ const upsertDoNothing3 = db.insert(users).values(newUser).onConflictDoNothing({ ], }).run(); -const upsertDoUpdate = db.insert(users).values(newUser).onConflictDoUpdate({ +db.insert(users).values(newUser).onConflictDoUpdate({ target: users.age1, set: { age1: sql`${users.age1} + 1` }, }) .run(); -const upsertAll = db.insert(users).values(newUser) +db.insert(users).values(newUser) .onConflictDoUpdate({ target: users.age1, set: { age1: sql`${users.age1} + 1` }, diff --git a/drizzle-orm/type-tests/sqlite/select.ts b/drizzle-orm/type-tests/sqlite/select.ts index 1203e243d..6a015f45e 100644 --- a/drizzle-orm/type-tests/sqlite/select.ts +++ b/drizzle-orm/type-tests/sqlite/select.ts @@ -391,7 +391,7 @@ Expect< >; { - let authenticated = false; + const authenticated = false as boolean; const result = db .select({ diff --git a/drizzle-orm/type-tests/sqlite/tables.ts b/drizzle-orm/type-tests/sqlite/tables.ts index 82defd722..6272dd055 100644 --- a/drizzle-orm/type-tests/sqlite/tables.ts +++ b/drizzle-orm/type-tests/sqlite/tables.ts @@ -245,12 +245,12 @@ Expect< } { - const test = sqliteTable('test', { + sqliteTable('test', { col1: integer('col1').default(1), col2: integer('col2', { mode: 'number' }).default(1), col3: integer('col3', { mode: 'timestamp' }).default(new Date()), col4: integer('col4', { mode: 'timestamp_ms' }).default(new Date()), - // @ts-expect-error + // @ts-expect-error - invalid mode col5: integer('col4', { mode: undefined }).default(new Date()), }); } diff --git a/drizzle-orm/type-tests/utils.ts b/drizzle-orm/type-tests/utils.ts index 5a350e642..b40fb9907 100644 --- a/drizzle-orm/type-tests/utils.ts +++ b/drizzle-orm/type-tests/utils.ts @@ -1,3 +1,4 @@ +// eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-function export function Expect() {} export type Equal = (() => T extends X ? 1 : 2) extends (() => T extends Y ? 1 : 2) ? true : false; diff --git a/drizzle-zod/src/index.ts b/drizzle-zod/src/index.ts index e0f394a3f..0229ac6e4 100644 --- a/drizzle-zod/src/index.ts +++ b/drizzle-zod/src/index.ts @@ -113,7 +113,7 @@ type GetZodType = TColumn['_']['data'] extends infer type ValueOrUpdater = T | ((arg: TUpdaterArg) => T); -type UnwrapValueOrUpdater = T extends ValueOrUpdater ? T : never; +type UnwrapValueOrUpdater = T extends ValueOrUpdater ? U : never; export type Refine = { [K in keyof TTable['_']['columns']]?: ValueOrUpdater< @@ -189,13 +189,13 @@ export function createInsertSchema< ); } - columnEntries.forEach(([name, column]) => { + for (const [name, column] of columnEntries) { if (!column.notNull) { schemaEntries[name] = schemaEntries[name]!.nullable().optional(); } else if (column.hasDefault) { schemaEntries[name] = schemaEntries[name]!.optional(); } - }); + } return z.object(schemaEntries) as z.ZodObject>; } @@ -236,11 +236,11 @@ export function createSelectSchema< ); } - columnEntries.forEach(([name, column]) => { + for (const [name, column] of columnEntries) { if (!column.notNull) { schemaEntries[name] = schemaEntries[name]!.nullable(); } - }); + } return z.object(schemaEntries) as z.ZodObject>; } @@ -253,11 +253,7 @@ function mapColumnToSchema(column: AnyColumn): z.ZodTypeAny { let type: z.ZodTypeAny | undefined; if (isWithEnum(column)) { - if (column.enumValues.length) { - type = z.enum(column.enumValues); - } else { - type = z.string(); - } + type = column.enumValues.length ? z.enum(column.enumValues) : z.string(); } if (!type) { diff --git a/drizzle-zod/tests/pg.test.ts b/drizzle-zod/tests/pg.test.ts index 0acc2a65e..14d30799c 100644 --- a/drizzle-zod/tests/pg.test.ts +++ b/drizzle-zod/tests/pg.test.ts @@ -27,14 +27,14 @@ test('users insert schema', (t) => { (() => { { createInsertSchema(users, { - // @ts-expect-error + // @ts-expect-error (missing property) foobar: z.number(), }); } { createInsertSchema(users, { - // @ts-expect-error + // @ts-expect-error (invalid type) id: 123, }); } diff --git a/drizzle-zod/tests/sqlite.test.ts b/drizzle-zod/tests/sqlite.test.ts index 50373e244..b076973b0 100644 --- a/drizzle-zod/tests/sqlite.test.ts +++ b/drizzle-zod/tests/sqlite.test.ts @@ -29,14 +29,14 @@ test('users insert schema', (t) => { (() => { { createInsertSchema(users, { - // @ts-expect-error + // @ts-expect-error (missing property) foobar: z.number(), }); } { createInsertSchema(users, { - // @ts-expect-error + // @ts-expect-error (invalid type) id: 123, }); } @@ -82,14 +82,14 @@ test('users select schema', (t) => { (() => { { createSelectSchema(users, { - // @ts-expect-error + // @ts-expect-error (missing property) foobar: z.number(), }); } { createSelectSchema(users, { - // @ts-expect-error + // @ts-expect-error (invalid type) id: 123, }); } diff --git a/drizzle-zod/tests/utils.ts b/drizzle-zod/tests/utils.ts index 012e1fe0a..a6e426ac2 100644 --- a/drizzle-zod/tests/utils.ts +++ b/drizzle-zod/tests/utils.ts @@ -4,7 +4,7 @@ import { z } from 'zod'; export function assertSchemasEqual(t: ExecutionContext, actual: T, expected: T) { t.deepEqual(Object.keys(actual.shape), Object.keys(expected.shape)); - Object.keys(actual.shape).forEach((key) => { + for (const key of Object.keys(actual.shape)) { t.deepEqual(actual.shape[key]!._def.typeName, expected.shape[key]?._def.typeName, `key: ${key}`); if (actual.shape[key] instanceof z.ZodOptional) { t.deepEqual( @@ -13,5 +13,5 @@ export function assertSchemasEqual(t: ExecutionContex `key (optional): ${key}`, ); } - }); + } } diff --git a/drizzle-zod/utils.ts b/drizzle-zod/utils.ts index 5a350e642..b40fb9907 100644 --- a/drizzle-zod/utils.ts +++ b/drizzle-zod/utils.ts @@ -1,3 +1,4 @@ +// eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-function export function Expect() {} export type Equal = (() => T extends X ? 1 : 2) extends (() => T extends Y ? 1 : 2) ? true : false; diff --git a/integration-tests/tests/awsdatapi.alltypes.test.ts b/integration-tests/tests/awsdatapi.alltypes.test.ts index 2e8ac36cf..e85cf9415 100644 --- a/integration-tests/tests/awsdatapi.alltypes.test.ts +++ b/integration-tests/tests/awsdatapi.alltypes.test.ts @@ -55,9 +55,9 @@ export const allColumns = pgTable('all_columns', { decimal: decimal('decimal', { precision: 100, scale: 2 }), decimaldef: decimal('decimaldef', { precision: 100, scale: 2 }).default('100.0'), doublePrecision: doublePrecision('doublePrecision'), - doublePrecisiondef: doublePrecision('doublePrecisiondef').default(100.0), + doublePrecisiondef: doublePrecision('doublePrecisiondef').default(100), real: real('real'), - realdef: real('realdef').default(100.0), + realdef: real('realdef').default(100), json: json('json').$type<{ attr: string }>(), jsondef: json('jsondef').$type<{ attr: string }>().default({ attr: 'value' }), jsonb: jsonb('jsonb').$type<{ attr: string }>(), @@ -99,47 +99,49 @@ test.before(async (t) => { // logger: new DefaultLogger(), }); - await ctx.db.execute(sql`CREATE TABLE IF NOT EXISTS "all_columns" ( - "smallint" smallint, - "smallint_def" smallint DEFAULT 10, - "integer" integer, - "integer_def" integer DEFAULT 10, - "numeric" numeric, - "numeric2" numeric(5), - "numeric3" numeric, - "numeric4" numeric(5, 2), - "numeridef" numeric DEFAULT '100', - "bigint" bigint, - "bigintdef" bigint DEFAULT 100, - "boolean" boolean, - "boolean_def" boolean DEFAULT true, - "text" text, - "textdef" text DEFAULT 'text', - "varchar" varchar, - "varchardef" varchar DEFAULT 'text', - "serial" serial, - "bigserial" bigserial, - "decimal" numeric(100, 2), - "decimaldef" numeric(100, 2) DEFAULT '100.0', - "doublePrecision" double precision, - "doublePrecisiondef" double precision DEFAULT 100, - "real" real, - "realdef" real DEFAULT 100, - "json" json, - "jsondef" json DEFAULT '{"attr":"value"}'::json, - "jsonb" jsonb, - "jsonbdef" jsonb DEFAULT '{"attr":"value"}'::jsonb, - "time" time, - "time2" time, - "timedefnow" time DEFAULT now(), - "timestamp" timestamp, - "timestamp2" timestamp (6) with time zone, - "timestamp3" timestamp with time zone, - "timestamp4" timestamp (4), - "timestampdef" timestamp DEFAULT now(), - "date" date, - "datedef" date DEFAULT now() - )`); + await ctx.db.execute(sql` + CREATE TABLE IF NOT EXISTS "all_columns" ( + "smallint" smallint, + "smallint_def" smallint DEFAULT 10, + "integer" integer, + "integer_def" integer DEFAULT 10, + "numeric" numeric, + "numeric2" numeric(5), + "numeric3" numeric, + "numeric4" numeric(5, 2), + "numeridef" numeric DEFAULT '100', + "bigint" bigint, + "bigintdef" bigint DEFAULT 100, + "boolean" boolean, + "boolean_def" boolean DEFAULT true, + "text" text, + "textdef" text DEFAULT 'text', + "varchar" varchar, + "varchardef" varchar DEFAULT 'text', + "serial" serial, + "bigserial" bigserial, + "decimal" numeric(100, 2), + "decimaldef" numeric(100, 2) DEFAULT '100.0', + "doublePrecision" double precision, + "doublePrecisiondef" double precision DEFAULT 100, + "real" real, + "realdef" real DEFAULT 100, + "json" json, + "jsondef" json DEFAULT '{"attr":"value"}'::json, + "jsonb" jsonb, + "jsonbdef" jsonb DEFAULT '{"attr":"value"}'::jsonb, + "time" time, + "time2" time, + "timedefnow" time DEFAULT now(), + "timestamp" timestamp, + "timestamp2" timestamp (6) with time zone, + "timestamp3" timestamp with time zone, + "timestamp4" timestamp (4), + "timestampdef" timestamp DEFAULT now(), + "date" date, + "datedef" date DEFAULT now() + ) + `); const now = new Date(); @@ -336,7 +338,7 @@ test.serial('[double precision] type with default', async (t) => { const { row } = t.context; t.assert(typeof row.doublePrecisiondef === 'number'); - t.is(row.doublePrecisiondef, 100.0); + t.is(row.doublePrecisiondef, 100); }); test.serial('[real] type', async (t) => { @@ -350,7 +352,7 @@ test.serial('[real] type with default', async (t) => { const { row } = t.context; t.assert(typeof row.realdef === 'number'); - t.is(row.realdef, 100.0); + t.is(row.realdef, 100); }); test.serial('[json] type', async (t) => { @@ -476,20 +478,22 @@ test.serial('select from enum', async (t) => { } as enum ('barbell', 'dumbbell', 'bodyweight', 'machine', 'cable', 'kettlebell')`, ); await db.execute(sql`create type ${name(categoryEnum.enumName)} as enum ('upper_body', 'lower_body', 'full_body')`); - await db.execute(sql`create table ${exercises} ( - id serial primary key, - name varchar not null, - force force, - level level, - mechanic mechanic, - equipment equipment, - instructions text, - category category, - primary_muscles muscle[], - secondary_muscles muscle[], - created_at timestamp not null default now(), - updated_at timestamp not null default now() - )`); + await db.execute(sql` + create table ${exercises} ( + id serial primary key, + name varchar not null, + force force, + level level, + mechanic mechanic, + equipment equipment, + instructions text, + category category, + primary_muscles muscle[], + secondary_muscles muscle[], + created_at timestamp not null default now(), + updated_at timestamp not null default now() + ) + `); await db.insert(exercises).values({ name: 'Bench Press', diff --git a/integration-tests/tests/awsdatapi.test.ts b/integration-tests/tests/awsdatapi.test.ts index f63b84fe4..50789b85b 100644 --- a/integration-tests/tests/awsdatapi.test.ts +++ b/integration-tests/tests/awsdatapi.test.ts @@ -58,21 +58,21 @@ test.beforeEach(async (t) => { await ctx.db.execute(sql`drop schema public cascade`); await ctx.db.execute(sql`create schema public`); await ctx.db.execute( - sql`create table users ( - id serial primary key, - name text not null, - verified boolean not null default false, - jsonb jsonb, - created_at timestamptz not null default now() - )`, + sql` + create table users ( + id serial primary key, + name text not null, + verified boolean not null default false, + jsonb jsonb, + created_at timestamptz not null default now() + ) + `, ); }); test.serial('select all fields', async (t) => { const { db } = t.context; - const now = Date.now(); - const insertResult = await db.insert(usersTable).values({ name: 'John' }); t.is(insertResult.numberOfRecordsUpdated, 1); @@ -141,8 +141,6 @@ test.serial('update returning sql', async (t) => { test.serial('update with returning all fields', async (t) => { const { db } = t.context; - const now = Date.now(); - await db.insert(usersTable).values({ name: 'John' }); const users = await db.update(usersTable).set({ name: 'Jane' }).where(eq(usersTable.name, 'John')).returning(); @@ -166,8 +164,6 @@ test.serial('update with returning partial', async (t) => { test.serial('delete with returning all fields', async (t) => { const { db } = t.context; - const now = Date.now(); - await db.insert(usersTable).values({ name: 'John' }); const users = await db.delete(usersTable).where(eq(usersTable.name, 'John')).returning(); diff --git a/integration-tests/tests/better-sqlite.test.ts b/integration-tests/tests/better-sqlite.test.ts index 5f679d041..ca4c40dcd 100644 --- a/integration-tests/tests/better-sqlite.test.ts +++ b/integration-tests/tests/better-sqlite.test.ts @@ -72,7 +72,7 @@ const anotherUsersMigratorTable = sqliteTable('another_users', { email: text('email').notNull(), }); -const pkExample = sqliteTable('pk_example', { +const _pkExample = sqliteTable('pk_example', { id: integer('id').primaryKey(), name: text('name').notNull(), email: text('email').notNull(), @@ -122,29 +122,34 @@ test.beforeEach((t) => { verified integer not null default 0, json blob, created_at integer not null default (strftime('%s', 'now')) - )`); + ) + `); ctx.db.run(sql` create table ${users2Table} ( id integer primary key, name text not null, city_id integer references ${citiesTable}(${name(citiesTable.id.name)}) - )`); + ) + `); ctx.db.run(sql` create table ${citiesTable} ( id integer primary key, name text not null - )`); + ) + `); ctx.db.run(sql` - create table ${courseCategoriesTable} ( - id integer primary key, - name text not null - )`); + create table ${courseCategoriesTable} ( + id integer primary key, + name text not null + ) + `); ctx.db.run(sql` create table ${coursesTable} ( id integer primary key, name text not null, category_id integer references ${courseCategoriesTable}(${name(courseCategoriesTable.id.name)}) - )`); + ) + `); ctx.db.run(sql` create table ${orders} ( id integer primary key, @@ -152,7 +157,8 @@ test.beforeEach((t) => { product text not null, amount integer not null, quantity integer not null - )`); + ) + `); }); test.serial('select all fields', (t) => { @@ -1479,12 +1485,12 @@ test.serial('insert with onConflict do nothing', (t) => { .run(); const res = db - .select({ id: usersTable.id, name: usersTable.name}) + .select({ id: usersTable.id, name: usersTable.name }) .from(usersTable) .where(eq(usersTable.id, 1)) .all(); - t.deepEqual(res, [{ id: 1, name: 'John' }]); + t.deepEqual(res, [{ id: 1, name: 'John' }]); }); test.serial('insert with onConflict do nothing using target', (t) => { @@ -1499,12 +1505,12 @@ test.serial('insert with onConflict do nothing using target', (t) => { .run(); const res = db - .select({ id: usersTable.id, name: usersTable.name}) + .select({ id: usersTable.id, name: usersTable.name }) .from(usersTable) .where(eq(usersTable.id, 1)) .all(); - t.deepEqual(res, [{ id: 1, name: 'John' }]); + t.deepEqual(res, [{ id: 1, name: 'John' }]); }); test.serial('insert with onConflict do update', (t) => { @@ -1515,14 +1521,14 @@ test.serial('insert with onConflict do update', (t) => { db .insert(usersTable) .values({ id: 1, name: 'John' }) - .onConflictDoUpdate({ target: usersTable.id, set: { name: 'John1' }}) + .onConflictDoUpdate({ target: usersTable.id, set: { name: 'John1' } }) .run(); const res = db - .select({ id: usersTable.id, name: usersTable.name}) + .select({ id: usersTable.id, name: usersTable.name }) .from(usersTable) .where(eq(usersTable.id, 1)) .all(); - t.deepEqual(res, [{ id: 1, name: 'John1' }]); + t.deepEqual(res, [{ id: 1, name: 'John1' }]); }); diff --git a/integration-tests/tests/bun/sqlite.test.ts b/integration-tests/tests/bun/sqlite.test.ts index 56da3009b..76bfe7145 100644 --- a/integration-tests/tests/bun/sqlite.test.ts +++ b/integration-tests/tests/bun/sqlite.test.ts @@ -37,13 +37,14 @@ test.before.each((ctx) => { db.run(sql`drop table if exists ${usersTable}`); db.run(sql` - create table ${usersTable} ( - id integer primary key, - name text not null, - verified integer not null default 0, - json blob, - created_at text not null default (strftime('%s', 'now')) - )`); + create table ${usersTable} ( + id integer primary key, + name text not null, + verified integer not null default 0, + json blob, + created_at text not null default (strftime('%s', 'now')) + ) + `); } catch (e) { console.error(e); } diff --git a/integration-tests/tests/libsql.test.ts b/integration-tests/tests/libsql.test.ts index f81abbda4..b05f2671d 100644 --- a/integration-tests/tests/libsql.test.ts +++ b/integration-tests/tests/libsql.test.ts @@ -80,7 +80,7 @@ const anotherUsersMigratorTable = sqliteTable('another_users', { email: text('email').notNull(), }); -const pkExample = sqliteTable('pk_example', { +const _pkExample = sqliteTable('pk_example', { id: integer('id').primaryKey(), name: text('name').notNull(), email: text('email').notNull(), @@ -95,7 +95,7 @@ test.before(async (t) => { if (!url) { throw new Error('LIBSQL_URL is not set'); } - let sleep = 250; + const sleep = 250; let timeLeft = 5000; let connected = false; let lastError: unknown | undefined; @@ -118,8 +118,7 @@ test.before(async (t) => { }); test.after.always(async (t) => { - const ctx = t.context; - // ctx.client.close(); + t.context.client.close(); }); test.beforeEach(async (t) => { @@ -139,31 +138,36 @@ test.beforeEach(async (t) => { verified integer not null default 0, json blob, created_at integer not null default (strftime('%s', 'now')) - )`); + ) + `); await ctx.db.run(sql` create table ${citiesTable} ( id integer primary key, name text not null - )`); + ) + `); await ctx.db.run(sql` - create table ${courseCategoriesTable} ( - id integer primary key, - name text not null - )`); + create table ${courseCategoriesTable} ( + id integer primary key, + name text not null + ) + `); await ctx.db.run(sql` create table ${users2Table} ( id integer primary key, name text not null, city_id integer references ${citiesTable}(${name(citiesTable.id.name)}) - )`); + ) + `); await ctx.db.run(sql` create table ${coursesTable} ( id integer primary key, name text not null, category_id integer references ${courseCategoriesTable}(${name(courseCategoriesTable.id.name)}) - )`); + ) + `); await ctx.db.run(sql` create table ${orders} ( id integer primary key, @@ -171,7 +175,8 @@ test.beforeEach(async (t) => { product text not null, amount integer not null, quantity integer not null - )`); + ) + `); }); test.serial('select all fields', async (t) => { @@ -1436,12 +1441,12 @@ test.serial('insert with onConflict do nothing', async (t) => { .run(); const res = await db - .select({ id: usersTable.id, name: usersTable.name}) + .select({ id: usersTable.id, name: usersTable.name }) .from(usersTable) .where(eq(usersTable.id, 1)) .all(); - t.deepEqual(res, [{ id: 1, name: 'John' }]); + t.deepEqual(res, [{ id: 1, name: 'John' }]); }); test.serial('insert with onConflict do nothing using target', async (t) => { @@ -1456,12 +1461,12 @@ test.serial('insert with onConflict do nothing using target', async (t) => { .run(); const res = await db - .select({ id: usersTable.id, name: usersTable.name}) + .select({ id: usersTable.id, name: usersTable.name }) .from(usersTable) .where(eq(usersTable.id, 1)) .all(); - t.deepEqual(res, [{ id: 1, name: 'John' }]); + t.deepEqual(res, [{ id: 1, name: 'John' }]); }); test.serial('insert with onConflict do update', async (t) => { @@ -1472,14 +1477,14 @@ test.serial('insert with onConflict do update', async (t) => { await db .insert(usersTable) .values({ id: 1, name: 'John' }) - .onConflictDoUpdate({ target: usersTable.id, set: { name: 'John1' }}) + .onConflictDoUpdate({ target: usersTable.id, set: { name: 'John1' } }) .run(); const res = await db - .select({ id: usersTable.id, name: usersTable.name}) + .select({ id: usersTable.id, name: usersTable.name }) .from(usersTable) .where(eq(usersTable.id, 1)) .all(); - t.deepEqual(res, [{ id: 1, name: 'John1' }]); + t.deepEqual(res, [{ id: 1, name: 'John1' }]); }); diff --git a/integration-tests/tests/mysql-schema.test.ts b/integration-tests/tests/mysql-schema.test.ts index f966f05bd..9ed136243 100644 --- a/integration-tests/tests/mysql-schema.test.ts +++ b/integration-tests/tests/mysql-schema.test.ts @@ -108,7 +108,7 @@ test.before(async (t) => { const ctx = t.context; const connectionString = process.env['MYSQL_CONNECTION_STRING'] ?? await createDockerDB(ctx); - let sleep = 1000; + const sleep = 1000; let timeLeft = 20000; let connected = false; let lastError: unknown | undefined; @@ -139,47 +139,53 @@ test.beforeEach(async (t) => { await ctx.db.execute(sql`drop schema if exists \`mySchema\``); await ctx.db.execute(sql`create schema if not exists \`mySchema\``); await ctx.db.execute( - sql`create table \`mySchema\`.\`userstest\` ( - \`id\` serial primary key, - \`name\` text not null, - \`verified\` boolean not null default false, - \`jsonb\` json, - \`created_at\` timestamp not null default now() - )`, + sql` + create table \`mySchema\`.\`userstest\` ( + \`id\` serial primary key, + \`name\` text not null, + \`verified\` boolean not null default false, + \`jsonb\` json, + \`created_at\` timestamp not null default now() + ) + `, ); await ctx.db.execute( - sql`create table \`mySchema\`.\`cities\` ( - \`id\` serial primary key, - \`name\` text not null - )`, + sql` + create table \`mySchema\`.\`cities\` ( + \`id\` serial primary key, + \`name\` text not null + ) + `, ); await ctx.db.execute( - sql`create table \`mySchema\`.\`users2\` ( - \`id\` serial primary key, - \`name\` text not null, - \`city_id\` int references \`mySchema\`.\`cities\`(\`id\`) - )`, + sql` + create table \`mySchema\`.\`users2\` ( + \`id\` serial primary key, + \`name\` text not null, + \`city_id\` int references \`mySchema\`.\`cities\`(\`id\`) + ) + `, ); await ctx.db.execute( - sql`create table \`datestable\` ( - \`date\` date, - \`date_as_string\` date, - \`time\` time, - \`datetime\` datetime, - \`datetime_as_string\` datetime, - \`year\` year - )`, + sql` + create table \`datestable\` ( + \`date\` date, + \`date_as_string\` date, + \`time\` time, + \`datetime\` datetime, + \`datetime_as_string\` datetime, + \`year\` year + ) + `, ); }); test.serial('select all fields', async (t) => { const { db } = t.context; - const now = Date.now(); - await db.insert(usersTable).values({ name: 'John' }); const result = await db.select().from(usersTable); @@ -240,8 +246,6 @@ test.serial('update returning sql', async (t) => { test.serial('update with returning all fields', async (t) => { const { db } = t.context; - const now = Date.now(); - await db.insert(usersTable).values({ name: 'John' }); const updatedUsers = await db.update(usersTable).set({ name: 'Jane' }).where(eq(usersTable.name, 'John')); @@ -273,8 +277,6 @@ test.serial('update with returning partial', async (t) => { test.serial('delete with returning all fields', async (t) => { const { db } = t.context; - const now = Date.now(); - await db.insert(usersTable).values({ name: 'John' }); const deletedUser = await db.delete(usersTable).where(eq(usersTable.name, 'John')); @@ -429,7 +431,8 @@ test.serial('build query', async (t) => { .toSQL(); t.deepEqual(query, { - sql: 'select \`id\`, \`name\` from `mySchema`.\`userstest\` group by \`userstest\`.\`id\`, \`userstest\`.\`name\`', + sql: + `select \`id\`, \`name\` from \`mySchema\`.\`userstest\` group by \`userstest\`.\`id\`, \`userstest\`.\`name\``, params: [], }); }); @@ -687,13 +690,15 @@ test.serial('select from tables with same name from different schema using alias const { db } = t.context; await db.execute(sql`drop table if exists \`userstest\``); await db.execute( - sql`create table \`userstest\` ( - \`id\` serial primary key, - \`name\` text not null, - \`verified\` boolean not null default false, - \`jsonb\` json, - \`created_at\` timestamp not null default now() - )`, + sql` + create table \`userstest\` ( + \`id\` serial primary key, + \`name\` text not null, + \`verified\` boolean not null default false, + \`jsonb\` json, + \`created_at\` timestamp not null default now() + ) + `, ); await db.insert(usersTable).values({ id: 10, name: 'Ivan' }); @@ -734,12 +739,14 @@ const tableWithEnums = mySchema.table('enums_test_case', { test.serial('Mysql enum test case #1', async (t) => { const { db } = t.context; - await db.execute(sql`create table ${tableWithEnums} ( - \`id\` serial primary key, - \`enum1\` ENUM('a', 'b', 'c') not null, - \`enum2\` ENUM('a', 'b', 'c') default 'a', - \`enum3\` ENUM('a', 'b', 'c') not null default 'b' - )`); + await db.execute(sql` + create table ${tableWithEnums} ( + \`id\` serial primary key, + \`enum1\` ENUM('a', 'b', 'c') not null, + \`enum2\` ENUM('a', 'b', 'c') default 'a', + \`enum3\` ENUM('a', 'b', 'c') not null default 'b' + ) + `); await db.insert(tableWithEnums).values( { id: 1, enum1: 'a', enum2: 'b', enum3: 'c' }, diff --git a/integration-tests/tests/mysql.custom.test.ts b/integration-tests/tests/mysql.custom.test.ts index cbb2ccad9..d926d1703 100644 --- a/integration-tests/tests/mysql.custom.test.ts +++ b/integration-tests/tests/mysql.custom.test.ts @@ -66,7 +66,7 @@ const customTimestamp = customType< { data: Date; driverData: string; config: { fsp: number } } >({ dataType(config) { - const precision = typeof config?.fsp !== 'undefined' ? ` (${config.fsp})` : ''; + const precision = config?.fsp === undefined ? '' : ` (${config.fsp})`; return `timestamp${precision}`; }, fromDriver(value: string): Date { @@ -76,9 +76,9 @@ const customTimestamp = customType< const customBinary = customType<{ data: string; driverData: Buffer; config: { length: number } }>({ dataType(config) { - return typeof config?.length !== 'undefined' - ? `binary(${config.length})` - : `binary`; + return config?.length === undefined + ? `binary` + : `binary(${config.length})`; }, toDriver(value) { @@ -159,7 +159,7 @@ test.before(async (t) => { const ctx = t.context; const connectionString = process.env['MYSQL_CONNECTION_STRING'] ?? await createDockerDB(ctx); - let sleep = 1000; + const sleep = 1000; let timeLeft = 20000; let connected = false; let lastError: unknown | undefined; @@ -191,40 +191,44 @@ test.beforeEach(async (t) => { await ctx.db.execute(sql`drop table if exists \`test_table\``); // await ctx.db.execute(sql`create schema public`); await ctx.db.execute( - sql`create table \`userstest\` ( - \`id\` serial primary key, - \`name\` text not null, - \`verified\` boolean not null default false, - \`jsonb\` json, - \`created_at\` timestamp not null default now() - )`, + sql` + create table \`userstest\` ( + \`id\` serial primary key, + \`name\` text not null, + \`verified\` boolean not null default false, + \`jsonb\` json, + \`created_at\` timestamp not null default now() + ) + `, ); await ctx.db.execute( - sql`create table \`datestable\` ( - \`date\` date, - \`date_as_string\` date, - \`time\` time, - \`datetime\` datetime, - \`datetime_as_string\` datetime, - \`year\` year - )`, + sql` + create table \`datestable\` ( + \`date\` date, + \`date_as_string\` date, + \`time\` time, + \`datetime\` datetime, + \`datetime_as_string\` datetime, + \`year\` year + ) + `, ); await ctx.db.execute( - sql`create table \`test_table\` ( - \`id\` binary(16) primary key, - \`sql_id\` binary(16), - \`raw_id\` varchar(64) - )`, + sql` + create table \`test_table\` ( + \`id\` binary(16) primary key, + \`sql_id\` binary(16), + \`raw_id\` varchar(64) + ) + `, ); }); test.serial('select all fields', async (t) => { const { db } = t.context; - const now = Date.now(); - await db.insert(usersTable).values({ name: 'John' }); const result = await db.select().from(usersTable); @@ -285,8 +289,6 @@ test.serial('update returning sql', async (t) => { test.serial('update with returning all fields', async (t) => { const { db } = t.context; - const now = Date.now(); - await db.insert(usersTable).values({ name: 'John' }); const updatedUsers = await db.update(usersTable).set({ name: 'Jane' }).where(eq(usersTable.name, 'John')); @@ -318,8 +320,6 @@ test.serial('update with returning partial', async (t) => { test.serial('delete with returning all fields', async (t) => { const { db } = t.context; - const now = Date.now(); - await db.insert(usersTable).values({ name: 'John' }); const deletedUser = await db.delete(usersTable).where(eq(usersTable.name, 'John')); @@ -474,7 +474,7 @@ test.serial('build query', async (t) => { .toSQL(); t.deepEqual(query, { - sql: 'select \`id\`, \`name\` from \`userstest\` group by \`userstest\`.\`id\`, \`userstest\`.\`name\`', + sql: `select \`id\`, \`name\` from \`userstest\` group by \`userstest\`.\`id\`, \`userstest\`.\`name\``, params: [], }); }); @@ -761,12 +761,14 @@ const tableWithEnums = mysqlTable('enums_test_case', { test.serial('Mysql enum test case #1', async (t) => { const { db } = t.context; - await db.execute(sql`create table \`enums_test_case\` ( - \`id\` serial primary key, - \`enum1\` ENUM('a', 'b', 'c') not null, - \`enum2\` ENUM('a', 'b', 'c') default 'a', - \`enum3\` ENUM('a', 'b', 'c') not null default 'b' - )`); + await db.execute(sql` + create table \`enums_test_case\` ( + \`id\` serial primary key, + \`enum1\` ENUM('a', 'b', 'c') not null, + \`enum2\` ENUM('a', 'b', 'c') default 'a', + \`enum3\` ENUM('a', 'b', 'c') not null default 'b' + ) + `); await db.insert(tableWithEnums).values( { id: 1, enum1: 'a', enum2: 'b', enum3: 'c' }, diff --git a/integration-tests/tests/mysql.test.ts b/integration-tests/tests/mysql.test.ts index 6e9c0594d..d90d29908 100644 --- a/integration-tests/tests/mysql.test.ts +++ b/integration-tests/tests/mysql.test.ts @@ -132,7 +132,7 @@ test.before(async (t) => { const ctx = t.context; const connectionString = process.env['MYSQL_CONNECTION_STRING'] ?? await createDockerDB(ctx); - let sleep = 1000; + const sleep = 1000; let timeLeft = 20000; let connected = false; let lastError: unknown | undefined; @@ -170,36 +170,40 @@ test.beforeEach(async (t) => { await ctx.db.execute(sql`drop table if exists \`cities\``); await ctx.db.execute( - sql`create table \`userstest\` ( - \`id\` serial primary key, - \`name\` text not null, - \`verified\` boolean not null default false, - \`jsonb\` json, - \`created_at\` timestamp not null default now() - )`, + sql` + create table \`userstest\` ( + \`id\` serial primary key, + \`name\` text not null, + \`verified\` boolean not null default false, + \`jsonb\` json, + \`created_at\` timestamp not null default now() + ) + `, ); await ctx.db.execute( - sql`create table \`users2\` ( - \`id\` serial primary key, - \`name\` text not null, - \`city_id\` int references \`cities\`(\`id\`) - )`, + sql` + create table \`users2\` ( + \`id\` serial primary key, + \`name\` text not null, + \`city_id\` int references \`cities\`(\`id\`) + ) + `, ); await ctx.db.execute( - sql`create table \`cities\` ( - \`id\` serial primary key, - \`name\` text not null - )`, + sql` + create table \`cities\` ( + \`id\` serial primary key, + \`name\` text not null + ) + `, ); }); test.serial('select all fields', async (t) => { const { db } = t.context; - const now = Date.now(); - await db.insert(usersTable).values({ name: 'John' }); const result = await db.select().from(usersTable); @@ -260,8 +264,6 @@ test.serial('update returning sql', async (t) => { test.serial('update with returning all fields', async (t) => { const { db } = t.context; - const now = Date.now(); - await db.insert(usersTable).values({ name: 'John' }); const updatedUsers = await db.update(usersTable).set({ name: 'Jane' }).where(eq(usersTable.name, 'John')); @@ -293,8 +295,6 @@ test.serial('update with returning partial', async (t) => { test.serial('delete with returning all fields', async (t) => { const { db } = t.context; - const now = Date.now(); - await db.insert(usersTable).values({ name: 'John' }); const deletedUser = await db.delete(usersTable).where(eq(usersTable.name, 'John')); @@ -449,7 +449,7 @@ test.serial('build query', async (t) => { .toSQL(); t.deepEqual(query, { - sql: 'select \`id\`, \`name\` from \`userstest\` group by \`userstest\`.\`id\`, \`userstest\`.\`name\`', + sql: `select \`id\`, \`name\` from \`userstest\` group by \`userstest\`.\`id\`, \`userstest\`.\`name\``, params: [], }); }); @@ -700,14 +700,16 @@ test.serial('insert + select all possible dates', async (t) => { await db.execute(sql`drop table if exists \`datestable\``); await db.execute( - sql`create table \`datestable\` ( - \`date\` date, - \`date_as_string\` date, - \`time\` time, - \`datetime\` datetime, - \`datetime_as_string\` datetime, - \`year\` year - )`, + sql` + create table \`datestable\` ( + \`date\` date, + \`date_as_string\` date, + \`time\` time, + \`datetime\` datetime, + \`datetime_as_string\` datetime, + \`year\` year + ) + `, ); const date = new Date('2022-11-11'); @@ -750,12 +752,14 @@ const tableWithEnums = mysqlTable('enums_test_case', { test.serial('Mysql enum test case #1', async (t) => { const { db } = t.context; - await db.execute(sql`create table \`enums_test_case\` ( - \`id\` serial primary key, - \`enum1\` ENUM('a', 'b', 'c') not null, - \`enum2\` ENUM('a', 'b', 'c') default 'a', - \`enum3\` ENUM('a', 'b', 'c') not null default 'b' - )`); + await db.execute(sql` + create table \`enums_test_case\` ( + \`id\` serial primary key, + \`enum1\` ENUM('a', 'b', 'c') not null, + \`enum2\` ENUM('a', 'b', 'c') default 'a', + \`enum3\` ENUM('a', 'b', 'c') not null default 'b' + ) + `); await db.insert(tableWithEnums).values( { id: 1, enum1: 'a', enum2: 'b', enum3: 'c' }, @@ -873,18 +877,22 @@ test.serial('join subquery', async (t) => { await db.execute(sql`drop table if exists \`course_categories\``); await db.execute( - sql`create table \`course_categories\` ( - \`id\` serial primary key, - \`name\` text not null - )`, + sql` + create table \`course_categories\` ( + \`id\` serial primary key, + \`name\` text not null + ) + `, ); await db.execute( - sql`create table \`courses\` ( - \`id\` serial primary key, - \`name\` text not null, - \`category_id\` int references \`course_categories\`(\`id\`) - )`, + sql` + create table \`courses\` ( + \`id\` serial primary key, + \`name\` text not null, + \`category_id\` int references \`course_categories\`(\`id\`) + ) + `, ); await db.insert(courseCategoriesTable).values( @@ -936,13 +944,15 @@ test.serial('with ... select', async (t) => { await db.execute(sql`drop table if exists \`orders\``); await db.execute( - sql`create table \`orders\` ( - \`id\` serial primary key, - \`region\` text not null, - \`product\` text not null, - \`amount\` int not null, - \`quantity\` int not null - )`, + sql` + create table \`orders\` ( + \`id\` serial primary key, + \`region\` text not null, + \`product\` text not null, + \`amount\` int not null, + \`quantity\` int not null + ) + `, ); await db.insert(orders).values( @@ -1326,7 +1336,7 @@ test.serial('timestamp timezone', async (t) => { const users = await db.select().from(usersTable); // check that the timestamps are set correctly for default times - t.assert(Math.abs(users[0]!.createdAt.getTime() - new Date().getTime()) < 2000); + t.assert(Math.abs(users[0]!.createdAt.getTime() - Date.now()) < 2000); // check that the timestamps are set correctly for non default times t.assert(Math.abs(users[1]!.createdAt.getTime() - date.getTime()) < 2000); diff --git a/integration-tests/tests/pg-schema.test.ts b/integration-tests/tests/pg-schema.test.ts index 1b4973c44..8a9e80b4c 100644 --- a/integration-tests/tests/pg-schema.test.ts +++ b/integration-tests/tests/pg-schema.test.ts @@ -96,7 +96,7 @@ test.before(async (t) => { const ctx = t.context; const connectionString = process.env['PG_CONNECTION_STRING'] ?? await createDockerDB(ctx); - let sleep = 250; + const sleep = 250; let timeLeft = 5000; let connected = false; let lastError: unknown | undefined; @@ -136,27 +136,33 @@ test.beforeEach(async (t) => { sql`create schema "mySchema"`, ); await ctx.db.execute( - sql`create table "mySchema".users ( - id serial primary key, - name text not null, - verified boolean not null default false, - jsonb jsonb, - created_at timestamptz not null default now() - )`, + sql` + create table "mySchema".users ( + id serial primary key, + name text not null, + verified boolean not null default false, + jsonb jsonb, + created_at timestamptz not null default now() + ) + `, ); await ctx.db.execute( - sql`create table "mySchema".cities ( - id serial primary key, - name text not null, - state char(2) - )`, + sql` + create table "mySchema".cities ( + id serial primary key, + name text not null, + state char(2) + ) + `, ); await ctx.db.execute( - sql`create table "mySchema".users2 ( - id serial primary key, - name text not null, - city_id integer references "mySchema".cities(id) - )`, + sql` + create table "mySchema".users2 ( + id serial primary key, + name text not null, + city_id integer references "mySchema".cities(id) + ) + `, ); }); @@ -712,13 +718,15 @@ test.serial('select from tables with same name from different schema using alias const { db } = t.context; await db.execute( - sql`create table users ( - id serial primary key, - name text not null, - verified boolean not null default false, - jsonb jsonb, - created_at timestamptz not null default now() - )`, + sql` + create table users ( + id serial primary key, + name text not null, + verified boolean not null default false, + jsonb jsonb, + created_at timestamptz not null default now() + ) + `, ); await db.insert(usersTable).values({ id: 10, name: 'Ivan' }); diff --git a/integration-tests/tests/pg.custom.test.ts b/integration-tests/tests/pg.custom.test.ts index ac50a8560..7e5d48935 100644 --- a/integration-tests/tests/pg.custom.test.ts +++ b/integration-tests/tests/pg.custom.test.ts @@ -46,7 +46,7 @@ const customTimestamp = customType< { data: Date; driverData: string; config: { withTimezone: boolean; precision?: number } } >({ dataType(config) { - const precision = typeof config?.precision !== 'undefined' ? ` (${config.precision})` : ''; + const precision = config?.precision === undefined ? '' : ` (${config.precision})`; return `timestamp${precision}${config?.withTimezone ? ' with time zone' : ''}`; }, fromDriver(value: string): Date { @@ -108,7 +108,7 @@ test.before(async (t) => { const ctx = t.context; const connectionString = process.env['PG_CONNECTION_STRING'] ?? await createDockerDB(ctx); - let sleep = 250; + const sleep = 250; let timeLeft = 5000; let connected = false; let lastError: unknown | undefined; @@ -144,13 +144,15 @@ test.beforeEach(async (t) => { await ctx.db.execute(sql`drop schema public cascade`); await ctx.db.execute(sql`create schema public`); await ctx.db.execute( - sql`create table users ( - id serial primary key, - name text not null, - verified boolean not null default false, - jsonb jsonb, - created_at timestamptz not null default now() - )`, + sql` + create table users ( + id serial primary key, + name text not null, + verified boolean not null default false, + jsonb jsonb, + created_at timestamptz not null default now() + ) + `, ); }); diff --git a/integration-tests/tests/pg.test.ts b/integration-tests/tests/pg.test.ts index 83bba3591..4fc0f1b70 100644 --- a/integration-tests/tests/pg.test.ts +++ b/integration-tests/tests/pg.test.ts @@ -103,7 +103,7 @@ const salEmp = pgTable('sal_emp', { schedule: text('schedule').array().array(), }); -const tictactoe = pgTable('tictactoe', { +const _tictactoe = pgTable('tictactoe', { squares: integer('squares').array(3).array(3), }); @@ -153,7 +153,7 @@ test.before(async (t) => { const ctx = t.context; const connectionString = process.env['PG_CONNECTION_STRING'] ?? (await createDockerDB(ctx)); - let sleep = 250; + const sleep = 250; let timeLeft = 5000; let connected = false; let lastError: unknown | undefined; @@ -189,69 +189,87 @@ test.beforeEach(async (t) => { await ctx.db.execute(sql`drop schema public cascade`); await ctx.db.execute(sql`create schema public`); await ctx.db.execute( - sql`create table users ( - id serial primary key, - name text not null, - verified boolean not null default false, - jsonb jsonb, - created_at timestamptz not null default now() - )`, + sql` + create table users ( + id serial primary key, + name text not null, + verified boolean not null default false, + jsonb jsonb, + created_at timestamptz not null default now() + ) + `, ); await ctx.db.execute( - sql`create table cities ( - id serial primary key, - name text not null, - state char(2) - )`, + sql` + create table cities ( + id serial primary key, + name text not null, + state char(2) + ) + `, ); await ctx.db.execute( - sql`create table users2 ( - id serial primary key, - name text not null, - city_id integer references cities(id) - )`, + sql` + create table users2 ( + id serial primary key, + name text not null, + city_id integer references cities(id) + ) + `, ); await ctx.db.execute( - sql`create table course_categories ( - id serial primary key, - name text not null - )`, + sql` + create table course_categories ( + id serial primary key, + name text not null + ) + `, ); await ctx.db.execute( - sql`create table courses ( - id serial primary key, - name text not null, - category_id integer references course_categories(id) - )`, + sql` + create table courses ( + id serial primary key, + name text not null, + category_id integer references course_categories(id) + ) + `, ); await ctx.db.execute( - sql`create table orders ( - id serial primary key, - region text not null, - product text not null, - amount integer not null, - quantity integer not null - )`, + sql` + create table orders ( + id serial primary key, + region text not null, + product text not null, + amount integer not null, + quantity integer not null + ) + `, ); await ctx.db.execute( - sql`create table network_table ( - inet inet not null, - cidr cidr not null, - macaddr macaddr not null, - macaddr8 macaddr8 not null - )`, + sql` + create table network_table ( + inet inet not null, + cidr cidr not null, + macaddr macaddr not null, + macaddr8 macaddr8 not null + ) + `, ); await ctx.db.execute( - sql`create table sal_emp ( - name text not null, - pay_by_quarter integer[] not null, - schedule text[][] not null - )`, + sql` + create table sal_emp ( + name text not null, + pay_by_quarter integer[] not null, + schedule text[][] not null + ) + `, ); await ctx.db.execute( - sql`create table tictactoe ( - squares integer[3][3] not null - )`, + sql` + create table tictactoe ( + squares integer[3][3] not null + ) + `, ); }); @@ -1217,7 +1235,7 @@ test.serial('select count w/ custom mapper', async (t) => { function count(value: AnyPgColumn | SQLWrapper): SQL; function count(value: AnyPgColumn | SQLWrapper, alias: string): SQL.Aliased; function count(value: AnyPgColumn | SQLWrapper, alias?: string): SQL | SQL.Aliased { - const result = sql`count(${value})`.mapWith((v) => parseInt(v, 10)); + const result = sql`count(${value})`.mapWith(Number); if (!alias) { return result; } @@ -1285,6 +1303,7 @@ test.serial('select for ...', (t) => { t.regex( query.sql, + // eslint-disable-next-line unicorn/better-regex / for update for no key update of "users2" for no key update of "users2" skip locked for share of "users2" no wait$/, ); }); @@ -1652,20 +1671,22 @@ test.serial('select from enum', async (t) => { } as enum ('barbell', 'dumbbell', 'bodyweight', 'machine', 'cable', 'kettlebell')`, ); await db.execute(sql`create type ${name(categoryEnum.enumName)} as enum ('upper_body', 'lower_body', 'full_body')`); - await db.execute(sql`create table ${exercises} ( - id serial primary key, - name varchar not null, - force force, - level level, - mechanic mechanic, - equipment equipment, - instructions text, - category category, - primary_muscles muscle[], - secondary_muscles muscle[], - created_at timestamp not null default now(), - updated_at timestamp not null default now() - )`); + await db.execute(sql` + create table ${exercises} ( + id serial primary key, + name varchar not null, + force force, + level level, + mechanic mechanic, + equipment equipment, + instructions text, + category category, + primary_muscles muscle[], + secondary_muscles muscle[], + created_at timestamp not null default now(), + updated_at timestamp not null default now() + ) + `); await db.insert(exercises).values({ name: 'Bench Press', @@ -1776,12 +1797,14 @@ test.serial('timestamp timezone', async (t) => { await db.execute(sql`drop table if exists ${usersTableWithAndWithoutTimezone}`); await db.execute( - sql`create table users_test_with_and_without_timezone ( - id serial not null primary key, - name text not null, - created_at timestamptz not null default now(), - updated_at timestamp not null default now() - )`, + sql` + create table users_test_with_and_without_timezone ( + id serial not null primary key, + name text not null, + created_at timestamptz not null default now(), + updated_at timestamp not null default now() + ) + `, ); const date = new Date(Date.parse('2020-01-01T00:00:00+04:00')); @@ -1795,8 +1818,8 @@ test.serial('timestamp timezone', async (t) => { const users = await db.select().from(usersTableWithAndWithoutTimezone); // check that the timestamps are set correctly for default times - t.assert(Math.abs(users[0]!.updatedAt.getTime() - new Date().getTime()) < 2000); - t.assert(Math.abs(users[0]!.createdAt.getTime() - new Date().getTime()) < 2000); + t.assert(Math.abs(users[0]!.updatedAt.getTime() - Date.now()) < 2000); + t.assert(Math.abs(users[0]!.createdAt.getTime() - Date.now()) < 2000); // check that the timestamps are set correctly for non default times t.assert(Math.abs(users[1]!.updatedAt.getTime() - date.getTime()) < 2000); @@ -2068,3 +2091,48 @@ test.serial('join view as subquery', async (t) => { await db.execute(sql`drop view ${newYorkers}`); await db.execute(sql`drop table ${users}`); }); + +test.serial('table selection with single table', async (t) => { + const { db } = t.context; + + const users = pgTable('users', { + id: serial('id').primaryKey(), + name: text('name').notNull(), + cityId: integer('city_id').notNull(), + }); + + await db.execute(sql`drop table if exists ${users}`); + + await db.execute( + sql`create table ${users} (id serial not null primary key, name text not null, city_id integer not null)`, + ); + + await db.insert(users).values({ name: 'John', cityId: 1 }); + + const result = await db.select({ users }).from(users); + + t.deepEqual(result, [{ users: { id: 1, name: 'John', cityId: 1 } }]); + + await db.execute(sql`drop table ${users}`); +}); + +test.serial.only('set null to jsonb field', async (t) => { + const { db } = t.context; + + const users = pgTable('users', { + id: serial('id').primaryKey(), + jsonb: jsonb('jsonb'), + }); + + await db.execute(sql`drop table if exists ${users}`); + + await db.execute( + sql`create table ${users} (id serial not null primary key, jsonb jsonb)`, + ); + + const result = await db.insert(users).values({ jsonb: null }).returning(); + + t.deepEqual(result, [{ id: 1, jsonb: null }]); + + await db.execute(sql`drop table ${users}`); +}); diff --git a/integration-tests/tests/planetscale-serverless/mysql.test.ts b/integration-tests/tests/planetscale-serverless/mysql.test.ts index ba144ac35..def1d4521 100644 --- a/integration-tests/tests/planetscale-serverless/mysql.test.ts +++ b/integration-tests/tests/planetscale-serverless/mysql.test.ts @@ -88,32 +88,34 @@ test.beforeEach(async (t) => { await ctx.db.execute(sql`drop table if exists ${datesTable}`); // await ctx.db.execute(sql`create schema public`); await ctx.db.execute( - sql`create table ${usersTable} ( - \`id\` serial primary key, - \`name\` text not null, - \`verified\` boolean not null default false, - \`jsonb\` json, - \`created_at\` timestamp not null default now() - )`, + sql` + create table ${usersTable} ( + \`id\` serial primary key, + \`name\` text not null, + \`verified\` boolean not null default false, + \`jsonb\` json, + \`created_at\` timestamp not null default now() + ) + `, ); await ctx.db.execute( - sql`create table ${datesTable} ( - \`date\` date, - \`date_as_string\` date, - \`time\` time, - \`datetime\` datetime, - \`datetime_as_string\` datetime, - \`year\` year - )`, + sql` + create table ${datesTable} ( + \`date\` date, + \`date_as_string\` date, + \`time\` time, + \`datetime\` datetime, + \`datetime_as_string\` datetime, + \`year\` year + ) + `, ); }); test.serial('select all fields', async (t) => { const { db } = t.context; - const now = Date.now(); - await db.insert(usersTable).values({ name: 'John' }); const result = await db.select().from(usersTable); @@ -176,8 +178,6 @@ test.serial('update returning sql', async (t) => { test.serial('update with returning all fields', async (t) => { const { db } = t.context; - const now = Date.now(); - await db.insert(usersTable).values({ name: 'John' }); const updatedUsers = await db.update(usersTable).set({ name: 'Jane' }).where(eq(usersTable.name, 'John')); @@ -209,8 +209,6 @@ test.serial('update with returning partial', async (t) => { test.serial('delete with returning all fields', async (t) => { const { db } = t.context; - const now = Date.now(); - await db.insert(usersTable).values({ name: 'John' }); const deletedUser = await db.delete(usersTable).where(eq(usersTable.name, 'John')); @@ -633,12 +631,14 @@ test.serial('Mysql enum test case #1', async (t) => { await db.execute(sql`drop table if exists ${tableWithEnums}`); - await db.execute(sql`create table ${tableWithEnums} ( - \`id\` serial primary key, - \`enum1\` ENUM('a', 'b', 'c') not null, - \`enum2\` ENUM('a', 'b', 'c') default 'a', - \`enum3\` ENUM('a', 'b', 'c') not null default 'b' - )`); + await db.execute(sql` + create table ${tableWithEnums} ( + \`id\` serial primary key, + \`enum1\` ENUM('a', 'b', 'c') not null, + \`enum2\` ENUM('a', 'b', 'c') default 'a', + \`enum3\` ENUM('a', 'b', 'c') not null default 'b' + ) + `); await db.insert(tableWithEnums).values([ { id: 1, enum1: 'a', enum2: 'b', enum3: 'c' }, diff --git a/integration-tests/tests/postgres.js.test.ts b/integration-tests/tests/postgres.js.test.ts index ba6150f7a..a7fd8f5dd 100644 --- a/integration-tests/tests/postgres.js.test.ts +++ b/integration-tests/tests/postgres.js.test.ts @@ -132,7 +132,7 @@ test.before(async (t) => { const ctx = t.context; const connectionString = process.env['PG_CONNECTION_STRING'] ?? await createDockerDB(ctx); - let sleep = 250; + const sleep = 250; let timeLeft = 5000; let connected = false; let lastError: unknown | undefined; @@ -140,7 +140,9 @@ test.before(async (t) => { try { ctx.client = postgres(connectionString, { max: 1, - onnotice: () => {}, + onnotice: () => { + // disable notices + }, }); await ctx.client`select 1`; connected = true; @@ -169,48 +171,60 @@ test.beforeEach(async (t) => { await ctx.db.execute(sql`drop schema public cascade`); await ctx.db.execute(sql`create schema public`); await ctx.db.execute( - sql`create table users ( - id serial primary key, - name text not null, - verified boolean not null default false, - jsonb jsonb, - created_at timestamptz not null default now() - )`, + sql` + create table users ( + id serial primary key, + name text not null, + verified boolean not null default false, + jsonb jsonb, + created_at timestamptz not null default now() + ) + `, ); await ctx.db.execute( - sql`create table cities ( - id serial primary key, - name text not null - )`, + sql` + create table cities ( + id serial primary key, + name text not null + ) + `, ); await ctx.db.execute( - sql`create table users2 ( - id serial primary key, - name text not null, - city_id integer references cities(id) - )`, + sql` + create table users2 ( + id serial primary key, + name text not null, + city_id integer references cities(id) + ) + `, ); await ctx.db.execute( - sql`create table course_categories ( - id serial primary key, - name text not null - )`, + sql` + create table course_categories ( + id serial primary key, + name text not null + ) + `, ); await ctx.db.execute( - sql`create table courses ( - id serial primary key, - name text not null, - category_id integer references course_categories(id) - )`, + sql` + create table courses ( + id serial primary key, + name text not null, + category_id integer references course_categories(id) + ) + `, ); await ctx.db.execute( - sql`create table orders ( - id serial primary key, - region text not null, - product text not null, - amount integer not null, - quantity integer not null - )`, + sql` + create table orders ( + id serial primary key, + region text not null, + product text not null, + amount integer not null, + quantity integer not null + ) + `, ); }); @@ -1045,7 +1059,7 @@ test.serial('select count w/ custom mapper', async (t) => { function count(value: AnyPgColumn | SQLWrapper): SQL; function count(value: AnyPgColumn | SQLWrapper, alias: string): SQL.Aliased; function count(value: AnyPgColumn | SQLWrapper, alias?: string): SQL | SQL.Aliased { - const result = sql`count(${value})`.mapWith((v) => parseInt(v, 10)); + const result = sql`count(${value})`.mapWith(Number); if (!alias) { return result; } @@ -1073,6 +1087,7 @@ test.serial('select for ...', (t) => { t.regex( query.sql, + // eslint-disable-next-line unicorn/better-regex /select ("(id|name|city_id)"(, )?){3} from "users2" for update for no key update of "users2" for no key update of "users2" skip locked for share of "users2" no wait/, ); }); @@ -1439,20 +1454,22 @@ test.serial('select from enum', async (t) => { } as enum ('barbell', 'dumbbell', 'bodyweight', 'machine', 'cable', 'kettlebell')`, ); await db.execute(sql`create type ${name(categoryEnum.enumName)} as enum ('upper_body', 'lower_body', 'full_body')`); - await db.execute(sql`create table ${exercises} ( - id serial primary key, - name varchar not null, - force force, - level level, - mechanic mechanic, - equipment equipment, - instructions text, - category category, - primary_muscles muscle[], - secondary_muscles muscle[], - created_at timestamp not null default now(), - updated_at timestamp not null default now() - )`); + await db.execute(sql` + create table ${exercises} ( + id serial primary key, + name varchar not null, + force force, + level level, + mechanic mechanic, + equipment equipment, + instructions text, + category category, + primary_muscles muscle[], + secondary_muscles muscle[], + created_at timestamp not null default now(), + updated_at timestamp not null default now() + ) + `); await db.insert(exercises).values({ name: 'Bench Press', diff --git a/integration-tests/tests/sql.js.test.ts b/integration-tests/tests/sql.js.test.ts index 661b211d3..d9d1da20e 100644 --- a/integration-tests/tests/sql.js.test.ts +++ b/integration-tests/tests/sql.js.test.ts @@ -76,7 +76,7 @@ const anotherUsersMigratorTable = sqliteTable('another_users', { email: text('email').notNull(), }); -const pkExample = sqliteTable('pk_example', { +const _pkExample = sqliteTable('pk_example', { id: integer('id').primaryKey(), name: text('name').notNull(), email: text('email').notNull(), @@ -121,29 +121,34 @@ test.beforeEach((t) => { verified integer not null default 0, json blob, created_at integer not null default (strftime('%s', 'now')) - )`); + ) + `); ctx.db.run(sql` create table ${users2Table} ( id integer primary key, name text not null, city_id integer references ${citiesTable}(${name(citiesTable.id.name)}) - )`); + ) + `); ctx.db.run(sql` create table ${citiesTable} ( id integer primary key, name text not null - )`); + ) + `); ctx.db.run(sql` - create table ${courseCategoriesTable} ( - id integer primary key, - name text not null - )`); + create table ${courseCategoriesTable} ( + id integer primary key, + name text not null + ) + `); ctx.db.run(sql` create table ${coursesTable} ( id integer primary key, name text not null, category_id integer references ${courseCategoriesTable}(${name(courseCategoriesTable.id.name)}) - )`); + ) + `); ctx.db.run(sql` create table ${orders} ( id integer primary key, @@ -151,7 +156,8 @@ test.beforeEach((t) => { product text not null, amount integer not null, quantity integer not null - )`); + ) + `); }); test.serial('select all fields', (t) => { @@ -1417,12 +1423,12 @@ test.serial('insert with onConflict do nothing', (t) => { .run(); const res = db - .select({ id: usersTable.id, name: usersTable.name}) + .select({ id: usersTable.id, name: usersTable.name }) .from(usersTable) .where(eq(usersTable.id, 1)) .all(); - t.deepEqual(res, [{ id: 1, name: 'John' }]); + t.deepEqual(res, [{ id: 1, name: 'John' }]); }); test.serial('insert with onConflict do nothing using target', (t) => { @@ -1437,12 +1443,12 @@ test.serial('insert with onConflict do nothing using target', (t) => { .run(); const res = db - .select({ id: usersTable.id, name: usersTable.name}) + .select({ id: usersTable.id, name: usersTable.name }) .from(usersTable) .where(eq(usersTable.id, 1)) .all(); - t.deepEqual(res, [{ id: 1, name: 'John' }]); + t.deepEqual(res, [{ id: 1, name: 'John' }]); }); test.serial('insert with onConflict do update', (t) => { @@ -1453,14 +1459,14 @@ test.serial('insert with onConflict do update', (t) => { db .insert(usersTable) .values({ id: 1, name: 'John' }) - .onConflictDoUpdate({ target: usersTable.id, set: { name: 'John1' }}) + .onConflictDoUpdate({ target: usersTable.id, set: { name: 'John1' } }) .run(); const res = db - .select({ id: usersTable.id, name: usersTable.name}) + .select({ id: usersTable.id, name: usersTable.name }) .from(usersTable) .where(eq(usersTable.id, 1)) .all(); - t.deepEqual(res, [{ id: 1, name: 'John1' }]); + t.deepEqual(res, [{ id: 1, name: 'John1' }]); }); diff --git a/integration-tests/tests/sqlite-proxy.test.ts b/integration-tests/tests/sqlite-proxy.test.ts index 6b52f4f78..4e160fc71 100644 --- a/integration-tests/tests/sqlite-proxy.test.ts +++ b/integration-tests/tests/sqlite-proxy.test.ts @@ -13,8 +13,7 @@ import { drizzle as proxyDrizzle } from 'drizzle-orm/sqlite-proxy'; import { migrate } from 'drizzle-orm/sqlite-proxy/migrator'; class ServerSimulator { - constructor(private db: BetterSqlite3.Database) { - } + constructor(private db: BetterSqlite3.Database) {} async query(sql: string, params: any[], method: string) { if (method === 'run') { @@ -36,7 +35,7 @@ class ServerSimulator { const row = this.db.prepare(sql).raw().get(params); return { data: row }; } catch (e: any) { - console.log('get row: ', e); + console.log('get row:', e); return { error: e.message }; } } else { @@ -51,7 +50,7 @@ class ServerSimulator { this.db.exec(query); } this.db.exec('COMMIT'); - } catch (e: any) { + } catch { this.db.exec('ROLLBACK'); } @@ -79,7 +78,7 @@ const anotherUsersMigratorTable = sqliteTable('another_users', { email: text('email').notNull(), }); -const pkExample = sqliteTable('pk_example', { +const _pkExample = sqliteTable('pk_example', { id: integer('id').primaryKey(), name: text('name').notNull(), email: text('email').notNull(), @@ -107,13 +106,13 @@ test.before((t) => { try { const rows = await ctx.serverSimulator.query(sql, params, method); - if (typeof rows.error !== 'undefined') { - throw Error(rows.error); + if (rows.error !== undefined) { + throw new Error(rows.error); } return { rows: rows.data }; } catch (e: any) { - console.error('Error from sqlite proxy server: ', e.response.data); + console.error('Error from sqlite proxy server:', e.response.data); return { rows: [] }; } }); @@ -129,7 +128,8 @@ test.beforeEach(async (t) => { verified integer not null default 0, json blob, created_at integer not null default (strftime('%s', 'now')) - )`); + ) + `); }); test.serial('select all fields', async (t) => { @@ -645,7 +645,7 @@ test.serial('migrator', async (t) => { serverSimulator.migrations(queries); } catch (e) { console.log(e); - throw Error('Proxy server cannot run migrations'); + throw new Error('Proxy server cannot run migrations'); } }, { migrationsFolder: 'drizzle2/sqlite' }); @@ -720,12 +720,12 @@ test.serial('insert with onConflict do nothing', async (t) => { .run(); const res = await db - .select({ id: usersTable.id, name: usersTable.name}) + .select({ id: usersTable.id, name: usersTable.name }) .from(usersTable) .where(eq(usersTable.id, 1)) .all(); - t.deepEqual(res, [{ id: 1, name: 'John' }]); + t.deepEqual(res, [{ id: 1, name: 'John' }]); }); test.serial('insert with onConflict do nothing using target', async (t) => { @@ -740,12 +740,12 @@ test.serial('insert with onConflict do nothing using target', async (t) => { .run(); const res = await db - .select({ id: usersTable.id, name: usersTable.name}) + .select({ id: usersTable.id, name: usersTable.name }) .from(usersTable) .where(eq(usersTable.id, 1)) .all(); - t.deepEqual(res, [{ id: 1, name: 'John' }]); + t.deepEqual(res, [{ id: 1, name: 'John' }]); }); test.serial('insert with onConflict do update', async (t) => { @@ -756,14 +756,14 @@ test.serial('insert with onConflict do update', async (t) => { await db .insert(usersTable) .values({ id: 1, name: 'John' }) - .onConflictDoUpdate({ target: usersTable.id, set: { name: 'John1' }}) + .onConflictDoUpdate({ target: usersTable.id, set: { name: 'John1' } }) .run(); const res = await db - .select({ id: usersTable.id, name: usersTable.name}) + .select({ id: usersTable.id, name: usersTable.name }) .from(usersTable) .where(eq(usersTable.id, 1)) .all(); - t.deepEqual(res, [{ id: 1, name: 'John1' }]); + t.deepEqual(res, [{ id: 1, name: 'John1' }]); }); diff --git a/integration-tests/tests/utils.ts b/integration-tests/tests/utils.ts index 5a350e642..199ed1a57 100644 --- a/integration-tests/tests/utils.ts +++ b/integration-tests/tests/utils.ts @@ -1,3 +1,5 @@ +// shut up eslint you cannot possibly comprehend what's happening here +// eslint-disable-next-line @typescript-eslint/no-empty-function, @typescript-eslint/no-unused-vars export function Expect() {} export type Equal = (() => T extends X ? 1 : 2) extends (() => T extends Y ? 1 : 2) ? true : false; diff --git a/package.json b/package.json index 48c0509ce..c642e32db 100755 --- a/package.json +++ b/package.json @@ -19,6 +19,7 @@ "dprint": "^0.35.3", "eslint": "^8.37.0", "eslint-plugin-import": "^2.27.5", + "eslint-plugin-unicorn": "^46.0.0", "eslint-plugin-unused-imports": "^2.0.0", "prettier": "^2.8.7", "resolve-tspaths": "^0.8.8", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6ef7cc7c9..397b7d4b3 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -33,6 +33,9 @@ importers: eslint-plugin-import: specifier: ^2.27.5 version: 2.27.5(@typescript-eslint/parser@5.57.0)(eslint@8.37.0) + eslint-plugin-unicorn: + specifier: ^46.0.0 + version: 46.0.0(eslint@8.37.0) eslint-plugin-unused-imports: specifier: ^2.0.0 version: 2.0.0(@typescript-eslint/eslint-plugin@5.57.0)(eslint@8.37.0) @@ -1612,6 +1615,10 @@ packages: /@types/node@18.15.11: resolution: {integrity: sha512-E5Kwq2n4SbMzQOn6wnmBjuK9ouqlURrcZDVfbo9ftDDTFt3nk7ZKK4GMOzoYgnpQJKcxwQw+lGaBvvlMo0qN/Q==} + /@types/normalize-package-data@2.4.1: + resolution: {integrity: sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==} + dev: true + /@types/pg@8.6.6: resolution: {integrity: sha512-O2xNmXebtwVekJDD+02udOncjVcMZQuTEQEMpKJ0ZRf5E7/9JJX3izhKUcUifBkyKpljyUM6BTgy2trmviKlpw==} dependencies: @@ -2218,6 +2225,11 @@ packages: dev: false optional: true + /builtin-modules@3.3.0: + resolution: {integrity: sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==} + engines: {node: '>=6'} + dev: true + /bun-types@0.5.8: resolution: {integrity: sha512-VHwD0MAHo3wraYAeqTWH2NDmXOdGfC3wWWOnZvK93ytI6yq/LkgsCjDudWNmN7MlfPvJb2zoLMnkzhjxNwLsLw==} dev: true @@ -2360,6 +2372,13 @@ packages: resolution: {integrity: sha512-uvzpYrpmidaoxvIQHM+rKSrigjOe9feHYbw4uOI2gdfe1C3xIlxO+kVXq83WQWNniTf8bAxVpy+cQeFQsMERKg==} dev: true + /clean-regexp@1.0.0: + resolution: {integrity: sha512-GfisEZEJvzKrmGWkvfhgzcz/BllN1USeqD2V6tg14OAOgaCD2Z/PUEuxnAZ/nPvmaHRG7a8y77p1T/IRQ4D1Hw==} + engines: {node: '>=4'} + dependencies: + escape-string-regexp: 1.0.5 + dev: true + /clean-stack@2.2.0: resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==} engines: {node: '>=6'} @@ -2813,6 +2832,12 @@ packages: resolution: {integrity: sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==} optional: true + /error-ex@1.3.2: + resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} + dependencies: + is-arrayish: 0.2.1 + dev: true + /es-abstract@1.21.1: resolution: {integrity: sha512-QudMsPOz86xYz/1dG1OuGBKOELjCh99IIWHLzy5znUB6j8xG2yMA7bfTV86VSqKF+Y/H08vQPR+9jyXpuC6hfg==} engines: {node: '>= 0.4'} @@ -3471,6 +3496,31 @@ packages: - supports-color dev: true + /eslint-plugin-unicorn@46.0.0(eslint@8.37.0): + resolution: {integrity: sha512-j07WkC+PFZwk8J33LYp6JMoHa1lXc1u6R45pbSAipjpfpb7KIGr17VE2D685zCxR5VL4cjrl65kTJflziQWMDA==} + engines: {node: '>=14.18'} + peerDependencies: + eslint: '>=8.28.0' + dependencies: + '@babel/helper-validator-identifier': 7.19.1 + '@eslint-community/eslint-utils': 4.4.0(eslint@8.37.0) + ci-info: 3.8.0 + clean-regexp: 1.0.0 + eslint: 8.37.0 + esquery: 1.5.0 + indent-string: 4.0.0 + is-builtin-module: 3.2.1 + jsesc: 3.0.2 + lodash: 4.17.21 + pluralize: 8.0.0 + read-pkg-up: 7.0.1 + regexp-tree: 0.1.25 + regjsparser: 0.9.1 + safe-regex: 2.1.1 + semver: 7.3.8 + strip-indent: 3.0.0 + dev: true + /eslint-plugin-unused-imports@2.0.0(@typescript-eslint/eslint-plugin@5.57.0)(eslint@8.37.0): resolution: {integrity: sha512-3APeS/tQlTrFa167ThtP0Zm0vctjr4M44HMpeg1P4bK6wItarumq0Ma82xorMKdFsWpphQBlRPzw/pxiVELX1A==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -3756,6 +3806,14 @@ packages: - supports-color dev: false + /find-up@4.1.0: + resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} + engines: {node: '>=8'} + dependencies: + locate-path: 5.0.0 + path-exists: 4.0.0 + dev: true + /find-up@5.0.0: resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} engines: {node: '>=10'} @@ -4092,6 +4150,10 @@ packages: resolution: {integrity: sha512-2bsegYkkHO+h/9MGbn6KWcE45cHZgPANo5LXF7EvWdT0yT2EguSVO1nDgU5c8+ZOPwp2vMNa7YFsJhVcDR9Sdg==} dev: true + /hosted-git-info@2.8.9: + resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} + dev: true + /http-cache-semantics@4.1.1: resolution: {integrity: sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==} optional: true @@ -4174,7 +4236,6 @@ packages: /indent-string@4.0.0: resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} engines: {node: '>=8'} - optional: true /indent-string@5.0.0: resolution: {integrity: sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==} @@ -4233,6 +4294,10 @@ packages: is-typed-array: 1.1.10 dev: true + /is-arrayish@0.2.1: + resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + dev: true + /is-bigint@1.0.4: resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==} dependencies: @@ -4254,6 +4319,13 @@ packages: has-tostringtag: 1.0.0 dev: true + /is-builtin-module@3.2.1: + resolution: {integrity: sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==} + engines: {node: '>=6'} + dependencies: + builtin-modules: 3.3.0 + dev: true + /is-callable@1.2.7: resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} engines: {node: '>= 0.4'} @@ -4437,12 +4509,23 @@ packages: argparse: 2.0.1 dev: true + /jsesc@0.5.0: + resolution: {integrity: sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==} + hasBin: true + dev: true + /jsesc@2.5.2: resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} engines: {node: '>=4'} hasBin: true dev: true + /jsesc@3.0.2: + resolution: {integrity: sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==} + engines: {node: '>=6'} + hasBin: true + dev: true + /json-diff@0.9.0: resolution: {integrity: sha512-cVnggDrVkAAA3OvFfHpFEhOnmcsUpleEKq4d4O8sQWWSH40MBrWstKigVB1kGrgLWzuom+7rRdaCsnBD6VyObQ==} hasBin: true @@ -4452,6 +4535,10 @@ packages: dreamopt: 0.8.0 dev: true + /json-parse-even-better-errors@2.3.1: + resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + dev: true + /json-schema-traverse@0.4.1: resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} dev: true @@ -4539,6 +4626,10 @@ packages: type-check: 0.4.0 dev: true + /lines-and-columns@1.2.4: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + dev: true + /load-json-file@7.0.1: resolution: {integrity: sha512-Gnxj3ev3mB5TkVBGad0JM6dmLiQL+o0t23JPBZ9sd+yvSLk05mFoqKBw5N8gbbkU4TNXyqCgIrl/VM17OgUIgQ==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -4549,6 +4640,13 @@ packages: engines: {node: '>=14'} dev: true + /locate-path@5.0.0: + resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} + engines: {node: '>=8'} + dependencies: + p-locate: 4.1.0 + dev: true + /locate-path@6.0.0: resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} engines: {node: '>=10'} @@ -4725,6 +4823,11 @@ packages: resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} engines: {node: '>=10'} + /min-indent@1.0.1: + resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} + engines: {node: '>=4'} + dev: true + /minimatch@3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} dependencies: @@ -4930,6 +5033,15 @@ packages: dependencies: abbrev: 1.1.1 + /normalize-package-data@2.5.0: + resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} + dependencies: + hosted-git-info: 2.8.9 + resolve: 1.22.1 + semver: 5.7.1 + validate-npm-package-license: 3.0.4 + dev: true + /normalize-path@3.0.0: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} engines: {node: '>=0.10.0'} @@ -5020,6 +5132,13 @@ packages: p-timeout: 5.1.0 dev: true + /p-limit@2.3.0: + resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} + engines: {node: '>=6'} + dependencies: + p-try: 2.2.0 + dev: true + /p-limit@3.1.0: resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} engines: {node: '>=10'} @@ -5034,6 +5153,13 @@ packages: yocto-queue: 1.0.0 dev: true + /p-locate@4.1.0: + resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} + engines: {node: '>=8'} + dependencies: + p-limit: 2.3.0 + dev: true + /p-locate@5.0.0: resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} engines: {node: '>=10'} @@ -5067,6 +5193,11 @@ packages: engines: {node: '>=12'} dev: true + /p-try@2.2.0: + resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} + engines: {node: '>=6'} + dev: true + /packet-reader@1.0.0: resolution: {integrity: sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ==} @@ -5077,6 +5208,16 @@ packages: callsites: 3.1.0 dev: true + /parse-json@5.2.0: + resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} + engines: {node: '>=8'} + dependencies: + '@babel/code-frame': 7.18.6 + error-ex: 1.3.2 + json-parse-even-better-errors: 2.3.1 + lines-and-columns: 1.2.4 + dev: true + /parse-ms@3.0.0: resolution: {integrity: sha512-Tpb8Z7r7XbbtBTrM9UhpkzzaMrqA2VXMT3YChzYltwV3P3pM6t8wl7TvpMnSTosz1aQAdVib7kdoys7vYOPerw==} engines: {node: '>=12'} @@ -5212,6 +5353,11 @@ packages: irregular-plurals: 3.5.0 dev: true + /pluralize@8.0.0: + resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==} + engines: {node: '>=4'} + dev: true + /postcss@8.4.21: resolution: {integrity: sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg==} engines: {node: ^10 || ^12 || >=14} @@ -5366,6 +5512,25 @@ packages: resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==} dev: true + /read-pkg-up@7.0.1: + resolution: {integrity: sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==} + engines: {node: '>=8'} + dependencies: + find-up: 4.1.0 + read-pkg: 5.2.0 + type-fest: 0.8.1 + dev: true + + /read-pkg@5.2.0: + resolution: {integrity: sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==} + engines: {node: '>=8'} + dependencies: + '@types/normalize-package-data': 2.4.1 + normalize-package-data: 2.5.0 + parse-json: 5.2.0 + type-fest: 0.6.0 + dev: true + /readable-stream@3.6.2: resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} engines: {node: '>= 6'} @@ -5388,6 +5553,11 @@ packages: resolve: 1.22.1 dev: true + /regexp-tree@0.1.25: + resolution: {integrity: sha512-szcL3aqw+vEeuxhL1AMYRyeMP+goYF5I/guaH10uJX5xbGyeQeNPPneaj3ZWVmGLCDxrVaaYekkr5R12gk4dJw==} + hasBin: true + dev: true + /regexp.prototype.flags@1.4.3: resolution: {integrity: sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==} engines: {node: '>= 0.4'} @@ -5397,6 +5567,13 @@ packages: functions-have-names: 1.2.3 dev: true + /regjsparser@0.9.1: + resolution: {integrity: sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==} + hasBin: true + dependencies: + jsesc: 0.5.0 + dev: true + /require-directory@2.1.1: resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} engines: {node: '>=0.10.0'} @@ -5494,9 +5671,20 @@ packages: is-regex: 1.1.4 dev: true + /safe-regex@2.1.1: + resolution: {integrity: sha512-rx+x8AMzKb5Q5lQ95Zoi6ZbJqwCLkqi3XuJXp5P3rT8OEc6sZCJG5AE5dU3lsgRr/F4Bs31jSlVN+j5KrsGu9A==} + dependencies: + regexp-tree: 0.1.25 + dev: true + /safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + /semver@5.7.1: + resolution: {integrity: sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==} + hasBin: true + dev: true + /semver@6.3.0: resolution: {integrity: sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==} hasBin: true @@ -5670,6 +5858,28 @@ packages: resolution: {integrity: sha512-n98l9E2RMSJ9ON1AKisHzz7V42VDiBQGY6PB1BwRglz99wpVsSuGzQ+jOi6lFXBGVTCrRpltvjm+/XA+tpeJrg==} dev: true + /spdx-correct@3.2.0: + resolution: {integrity: sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==} + dependencies: + spdx-expression-parse: 3.0.1 + spdx-license-ids: 3.0.13 + dev: true + + /spdx-exceptions@2.3.0: + resolution: {integrity: sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==} + dev: true + + /spdx-expression-parse@3.0.1: + resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==} + dependencies: + spdx-exceptions: 2.3.0 + spdx-license-ids: 3.0.13 + dev: true + + /spdx-license-ids@3.0.13: + resolution: {integrity: sha512-XkD+zwiqXHikFZm4AX/7JSCXA98U5Db4AFd5XUg/+9UNtnH75+Z9KxtpYiJZx36mUDVOwH83pl7yvCer6ewM3w==} + dev: true + /split-ca@1.0.1: resolution: {integrity: sha512-Q5thBSxp5t8WPTTJQS59LrGqOZqOsrhDGDVm8azCqIBjSBd7nd9o2PM+mDulQQkh8h//4U6hFZnc/mul8t5pWQ==} dev: false @@ -5801,6 +6011,13 @@ packages: engines: {node: '>=4'} dev: true + /strip-indent@3.0.0: + resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==} + engines: {node: '>=8'} + dependencies: + min-indent: 1.0.1 + dev: true + /strip-json-comments@2.0.1: resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} engines: {node: '>=0.10.0'} @@ -6104,6 +6321,16 @@ packages: engines: {node: '>=10'} dev: true + /type-fest@0.6.0: + resolution: {integrity: sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==} + engines: {node: '>=8'} + dev: true + + /type-fest@0.8.1: + resolution: {integrity: sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==} + engines: {node: '>=8'} + dev: true + /type-is@1.6.18: resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} engines: {node: '>= 0.6'} @@ -6199,6 +6426,13 @@ packages: sade: 1.8.1 dev: false + /validate-npm-package-license@3.0.4: + resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} + dependencies: + spdx-correct: 3.2.0 + spdx-expression-parse: 3.0.1 + dev: true + /vary@1.1.2: resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} engines: {node: '>= 0.8'}