From f3807acc3c6ff9514d83b4bf12a9956b882dcff0 Mon Sep 17 00:00:00 2001 From: Shinigami Date: Thu, 29 Feb 2024 21:29:53 +0100 Subject: [PATCH] infra: upgrade eslint (#973) --- .eslintignore | 4 - .eslintrc.cjs | 103 ++++ .eslintrc.js | 39 -- .gitignore | 99 +++- bin/node-pg-migrate | 5 - mocha.bootstrap.js | 2 - package.json | 19 +- pnpm-lock.yaml | 560 ++++++------------ src/db.ts | 3 + src/migration-builder.ts | 4 +- src/migration.ts | 8 +- src/operations/PgLiteral.ts | 1 - src/operations/domains.ts | 9 + src/operations/extensions.ts | 2 + src/operations/extensionsTypes.ts | 4 +- src/operations/functions.ts | 9 +- src/operations/generalTypes.ts | 1 - src/operations/indexes.ts | 8 +- src/operations/indexesTypes.ts | 4 +- src/operations/operators.ts | 20 + src/operations/other.ts | 1 + src/operations/policies.ts | 7 + src/operations/roles.ts | 16 + src/operations/schemas.ts | 3 + src/operations/sequences.ts | 12 + src/operations/tables.ts | 43 +- src/operations/triggers.ts | 7 + src/operations/types.ts | 10 + src/operations/views.ts | 8 + src/operations/viewsMaterialized.ts | 10 + src/runner.ts | 9 +- src/sqlMigration.ts | 2 +- src/utils.ts | 19 +- templates/migration-template.js | 2 - templates/migration-template.ts | 1 - test/db-test.ts | 2 - test/migration-test.ts | 6 +- test/migrations/001_noop.js | 1 - test/migrations/005_table_test.js | 6 +- test/migrations/010_column_test.js | 6 +- test/migrations/013_column_alter_test.js | 3 +- test/migrations/015_add_constraint_test.js | 3 +- .../migrations/026_set_type_attribute_test.js | 3 +- .../032_drop_type_attribute_test.js | 3 +- test/migrations/034_drop_type_test.js | 3 +- test/migrations/047_domain_check.js | 3 +- test/migrations/058_policy_test.js | 2 + ...80_create_table_generated_column_take_2.js | 2 + test/migrations/081_temporary_table.js | 3 +- test/sqlMigration-test.ts | 2 - test/ts/customRunner.ts | 4 +- tsconfig.lint.json | 16 + 52 files changed, 646 insertions(+), 476 deletions(-) delete mode 100644 .eslintignore create mode 100644 .eslintrc.cjs delete mode 100644 .eslintrc.js create mode 100644 tsconfig.lint.json diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index d719407a..00000000 --- a/.eslintignore +++ /dev/null @@ -1,4 +0,0 @@ -node_modules -dist -templates -*.d.ts diff --git a/.eslintrc.cjs b/.eslintrc.cjs new file mode 100644 index 00000000..a9851bbf --- /dev/null +++ b/.eslintrc.cjs @@ -0,0 +1,103 @@ +// @ts-check +const { defineConfig } = require('eslint-define-config'); +const { readGitignoreFiles } = require('eslint-gitignore'); + +/// +/// + +module.exports = defineConfig({ + ignorePatterns: [ + ...readGitignoreFiles(), + 'templates', + '.eslintrc.cjs', // Skip self linting + ], + root: true, + env: { + node: true, + }, + reportUnusedDisableDirectives: true, + extends: [ + 'eslint:recommended', + 'plugin:@typescript-eslint/strict-type-checked', + 'plugin:prettier/recommended', + ], + parserOptions: { + project: ['./tsconfig.lint.json'], + warnOnUnsupportedTypeScriptVersion: false, + }, + rules: { + eqeqeq: ['error', 'always', { null: 'ignore' }], + 'no-else-return': 'error', + 'prefer-exponentiation-operator': 'error', + 'prefer-template': 'error', + + '@typescript-eslint/array-type': [ + 'error', + { default: 'array-simple', readonly: 'generic' }, + ], + // TODO @Shinigami92 2024-02-29: Enable consistent-type-imports later + // '@typescript-eslint/consistent-type-imports': 'error', + // TODO @Shinigami92 2024-02-29: Enable consistent-type-imports later + // '@typescript-eslint/explicit-module-boundary-types': 'error', + // TODO @Shinigami92 2024-02-29: Enable consistent-type-imports later + // '@typescript-eslint/naming-convention': [ + // 'error', + // { + // format: ['PascalCase'], + // selector: ['class', 'interface', 'typeAlias', 'enumMember'], + // leadingUnderscore: 'forbid', + // trailingUnderscore: 'forbid', + // }, + // { + // format: ['PascalCase'], + // selector: ['typeParameter'], + // prefix: ['T'], + // leadingUnderscore: 'forbid', + // trailingUnderscore: 'forbid', + // }, + // ], + '@typescript-eslint/no-inferrable-types': [ + 'error', + { ignoreParameters: true }, + ], + '@typescript-eslint/no-unnecessary-condition': 'off', // requires `strictNullChecks` to be enabled + '@typescript-eslint/no-unsafe-assignment': 'off', + '@typescript-eslint/no-unsafe-call': 'off', + '@typescript-eslint/no-unsafe-member-access': 'off', + '@typescript-eslint/padding-line-between-statements': [ + 'error', + { blankLine: 'always', prev: 'block-like', next: '*' }, + ], + '@typescript-eslint/prefer-regexp-exec': 'error', + // TODO @Shinigami92 2024-02-29: Enable consistent-type-imports later + // '@typescript-eslint/restrict-template-expressions': [ + // 'error', + // { allowNumber: true, allowBoolean: true }, + // ], + '@typescript-eslint/switch-exhaustiveness-check': [ + 'error', + { requireDefaultForNonUnion: true }, + ], + '@typescript-eslint/unbound-method': 'off', + + // TODO @Shinigami92 2024-02-29: Remove these later + '@typescript-eslint/naming-convention': 'off', + '@typescript-eslint/no-base-to-string': 'off', + '@typescript-eslint/no-confusing-void-expression': 'off', + '@typescript-eslint/no-floating-promises': 'off', + '@typescript-eslint/no-implied-eval': 'off', + '@typescript-eslint/no-redundant-type-constituents': 'off', + '@typescript-eslint/no-throw-literal': 'off', + '@typescript-eslint/no-unnecessary-boolean-literal-compare': 'off', + '@typescript-eslint/no-unnecessary-type-assertion': 'off', + '@typescript-eslint/no-unsafe-argument': 'off', + '@typescript-eslint/no-unsafe-return': 'off', + '@typescript-eslint/no-unused-vars': 'off', + '@typescript-eslint/no-var-requires': 'off', + '@typescript-eslint/prefer-includes': 'off', + '@typescript-eslint/prefer-promise-reject-errors': 'off', + '@typescript-eslint/require-await': 'off', + '@typescript-eslint/restrict-template-expressions': 'off', + '@typescript-eslint/unified-signatures': 'off', + }, +}); diff --git a/.eslintrc.js b/.eslintrc.js deleted file mode 100644 index 8d75d872..00000000 --- a/.eslintrc.js +++ /dev/null @@ -1,39 +0,0 @@ -module.exports = { - extends: [ - 'eslint:recommended', - 'eslint-config-airbnb-base', - 'plugin:@typescript-eslint/recommended', - 'plugin:import/errors', - 'plugin:import/warnings', - 'plugin:security/recommended', - 'plugin:prettier/recommended', - ], - parser: '@typescript-eslint/parser', - parserOptions: { - ecmaVersion: 2020, - sourceType: 'module', - }, - settings: { - 'import/resolver': { - typescript: {}, - }, - }, - rules: { - 'no-shadow': 'off', - '@typescript-eslint/no-shadow': 'error', - 'no-underscore-dangle': 'off', - 'security/detect-object-injection': 'off', - '@typescript-eslint/explicit-function-return-type': 'off', - '@typescript-eslint/explicit-module-boundary-types': 'off', - 'import/extensions': ['error', 'never', { json: 'always' }], - }, - overrides: [ - { - files: ['*.js', 'node-pg-migrate'], - rules: { - '@typescript-eslint/no-var-requires': 'off', - '@typescript-eslint/camelcase': 'off', - }, - }, - ], -}; diff --git a/.gitignore b/.gitignore index af55a89f..582d97ef 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,98 @@ -.idea -.env +# Logs +logs *.log -/migrations -/node_modules +npm-debug.log* + +# Diagnostic reports (https://nodejs.org/api/report.html) +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json +reports/ + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage +*.lcov + +# nyc test coverage +.nyc_output + +# Dependency directories +node_modules/ +.pnpm-store/ + +# TypeScript cache +*.tsbuildinfo + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Microbundle cache +.rpt2_cache/ +.rts2_cache_cjs/ +.rts2_cache_es/ +.rts2_cache_umd/ + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variable files +.env +.env.development.local +.env.test.local +.env.production.local +.env.local + +# parcel-bundler cache (https://parceljs.org/) +.cache +.parcel-cache + +# Docusaurus cache and generated files +.docusaurus + +# Stores VSCode versions used for testing VSCode extensions +.vscode-test + +# Transpiled JS script files for GitHub Actions +.github/workflows/*.js + +# IDE +/.idea +/nbproject + +# Meteor build and version +.build* +versions.json + +# Dist /dist +/docs/.vitepress/cache +/docs/.vitepress/dist /lib + +/migrations + +TAGS +REVISION +*.tmproj +*~ +.DS_Store +.settings +.project +.tasks-cache +*DONOTVERSION* +.history + +# Unwanted package managers +.yarn/ +package-lock.json +yarn.lock diff --git a/bin/node-pg-migrate b/bin/node-pg-migrate index 959f262a..ce79cd9e 100755 --- a/bin/node-pg-migrate +++ b/bin/node-pg-migrate @@ -1,5 +1,4 @@ #!/usr/bin/env node -/* eslint-disable strict, no-console */ 'use strict'; @@ -17,7 +16,6 @@ process.on('uncaughtException', (err) => { function tryRequire(moduleName) { try { - // eslint-disable-next-line import/no-dynamic-require,global-require,security/detect-non-literal-require return require(moduleName); } catch (err) { if (err.code !== 'MODULE_NOT_FOUND') { @@ -260,7 +258,6 @@ function readTsconfig() { const json5 = tryRequire('json5'); try { - // eslint-disable-next-line security/detect-non-literal-fs-filename const config = fs.readFileSync( path.resolve(process.cwd(), tsconfigPath), { encoding: 'utf-8' } @@ -368,7 +365,6 @@ process.env.SUPPRESS_NO_CONFIG_WARNING = oldSuppressWarning; const configFileName = argv[configFileArg]; if (configFileName) { - // eslint-disable-next-line global-require,import/no-dynamic-require,security/detect-non-literal-require const jsonConfig = require(path.resolve(configFileName)); readJson(jsonConfig); } @@ -449,7 +445,6 @@ if (action === 'create') { let migrationName; if (updownArg !== null) { - // eslint-disable-next-line eqeqeq if (parseInt(updownArg, 10) == updownArg) { numMigrations = parseInt(updownArg, 10); } else { diff --git a/mocha.bootstrap.js b/mocha.bootstrap.js index bcc07973..70a72111 100644 --- a/mocha.bootstrap.js +++ b/mocha.bootstrap.js @@ -1,4 +1,3 @@ -/* eslint import/no-extraneous-dependencies: ["error", {"devDependencies": true}] */ const chai = require('chai'); const sinonChai = require('sinon-chai'); const chaiAsPromised = require('chai-as-promised'); @@ -8,7 +7,6 @@ const config = require('./tsconfig-test.json'); config.compilerOptions.module = 'commonjs'; config.transpileOnly = true; -// eslint-disable-next-line import/no-extraneous-dependencies require('ts-node').register(config); chai.use(sinonChai); diff --git a/package.json b/package.json index b4c0a6ae..2eed2d30 100644 --- a/package.json +++ b/package.json @@ -9,8 +9,7 @@ "build:types": "tsc --declaration --emitDeclarationOnly", "build": "run-s build:clean build:code build:types", "format": "prettier --cache --write .", - "lint": "eslint . bin/* --ext .js,.ts", - "lint:fix": "npm run lint -- --fix && prettier --write *.json *.md docs/*.md", + "lint": "eslint --cache --cache-strategy content --report-unused-disable-directives .", "test": "cross-env NODE_ENV=test mocha --require ./mocha.bootstrap.js \"test/*.ts\"", "docs:dev": "docsify serve docs", "migrate": "node bin/node-pg-migrate", @@ -64,6 +63,8 @@ "yargs": "~17.3.0" }, "devDependencies": { + "@eslint-types/prettier": "5.1.3", + "@eslint-types/typescript-eslint": "7.0.2", "@types/chai": "4.3.0", "@types/chai-as-promised": "7.1.4", "@types/mkdirp": "1.0.2", @@ -72,8 +73,8 @@ "@types/proxyquire": "1.3.28", "@types/sinon": "10.0.6", "@types/sinon-chai": "3.2.6", - "@typescript-eslint/eslint-plugin": "5.7.0", - "@typescript-eslint/parser": "5.7.0", + "@typescript-eslint/eslint-plugin": "7.1.0", + "@typescript-eslint/parser": "7.1.0", "chai": "4.3.4", "chai-as-promised": "7.1.1", "config": "3.3.6", @@ -81,13 +82,11 @@ "docsify-cli": "4.4.3", "dotenv": "16.0.1", "dotenv-expand": "8.0.3", - "eslint": "8.4.1", - "eslint-config-airbnb-base": "15.0.0", - "eslint-config-prettier": "8.3.0", - "eslint-import-resolver-typescript": "2.5.0", - "eslint-plugin-import": "2.25.3", + "eslint": "8.57.0", + "eslint-config-prettier": "9.1.0", + "eslint-define-config": "2.1.0", + "eslint-gitignore": "0.1.0", "eslint-plugin-prettier": "5.1.3", - "eslint-plugin-security": "1.4.0", "json5": "2.2.0", "mocha": "9.1.3", "npm-run-all2": "6.1.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index baae6afc..a23c2185 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -19,6 +19,12 @@ dependencies: version: 17.3.1 devDependencies: + '@eslint-types/prettier': + specifier: 5.1.3 + version: 5.1.3 + '@eslint-types/typescript-eslint': + specifier: 7.0.2 + version: 7.0.2 '@types/chai': specifier: 4.3.0 version: 4.3.0 @@ -44,11 +50,11 @@ devDependencies: specifier: 3.2.6 version: 3.2.6 '@typescript-eslint/eslint-plugin': - specifier: 5.7.0 - version: 5.7.0(@typescript-eslint/parser@5.7.0)(eslint@8.4.1)(typescript@4.5.4) + specifier: 7.1.0 + version: 7.1.0(@typescript-eslint/parser@7.1.0)(eslint@8.57.0)(typescript@4.5.4) '@typescript-eslint/parser': - specifier: 5.7.0 - version: 5.7.0(eslint@8.4.1)(typescript@4.5.4) + specifier: 7.1.0 + version: 7.1.0(eslint@8.57.0)(typescript@4.5.4) chai: specifier: 4.3.4 version: 4.3.4 @@ -71,26 +77,20 @@ devDependencies: specifier: 8.0.3 version: 8.0.3 eslint: - specifier: 8.4.1 - version: 8.4.1 - eslint-config-airbnb-base: - specifier: 15.0.0 - version: 15.0.0(eslint-plugin-import@2.25.3)(eslint@8.4.1) + specifier: 8.57.0 + version: 8.57.0 eslint-config-prettier: - specifier: 8.3.0 - version: 8.3.0(eslint@8.4.1) - eslint-import-resolver-typescript: - specifier: 2.5.0 - version: 2.5.0(eslint-plugin-import@2.25.3)(eslint@8.4.1) - eslint-plugin-import: - specifier: 2.25.3 - version: 2.25.3(@typescript-eslint/parser@5.7.0)(eslint-import-resolver-typescript@2.5.0)(eslint@8.4.1) + specifier: 9.1.0 + version: 9.1.0(eslint@8.57.0) + eslint-define-config: + specifier: 2.1.0 + version: 2.1.0 + eslint-gitignore: + specifier: 0.1.0 + version: 0.1.0(eslint@8.57.0) eslint-plugin-prettier: specifier: 5.1.3 - version: 5.1.3(eslint-config-prettier@8.3.0)(eslint@8.4.1)(prettier@3.2.5) - eslint-plugin-security: - specifier: 1.4.0 - version: 1.4.0 + version: 5.1.3(eslint-config-prettier@9.1.0)(eslint@8.57.0)(prettier@3.2.5) json5: specifier: 2.2.0 version: 2.2.0 @@ -147,8 +147,31 @@ packages: '@cspotcode/source-map-consumer': 0.8.0 dev: true - /@eslint/eslintrc@1.4.1: - resolution: {integrity: sha512-XXrH9Uarn0stsyldqDYq8r++mROmWRI1xKMXa640Bb//SY1+ECYX6VzT6Lcx5frD0V30XieqJ0oX9I2Xj5aoMA==} + /@eslint-community/eslint-utils@4.4.0(eslint@8.57.0): + resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + dependencies: + eslint: 8.57.0 + eslint-visitor-keys: 3.4.3 + dev: true + + /@eslint-community/regexpp@4.10.0: + resolution: {integrity: sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + dev: true + + /@eslint-types/prettier@5.1.3: + resolution: {integrity: sha512-jJHwCAdqj+iw2ahrFrA9FSDrYJSAEShWS6s/X/6fmD8xpdaKUpFqG/ecTnUlO6Iyxhkt3lj79Nfu4MWUpo7k6Q==} + dev: true + + /@eslint-types/typescript-eslint@7.0.2: + resolution: {integrity: sha512-2F67MVKhkJ2rSwoYvNJzJULqZwR5rNYI/eWoIrKDQ14lMzfqzbpzCBvnHrivBYWTN+Az7MVX00TzDTrjOc+YNA==} + dev: true + + /@eslint/eslintrc@2.1.4: + resolution: {integrity: sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: ajv: 6.12.6 @@ -164,19 +187,29 @@ packages: - supports-color dev: true - /@humanwhocodes/config-array@0.9.5: - resolution: {integrity: sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw==} + /@eslint/js@8.57.0: + resolution: {integrity: sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dev: true + + /@humanwhocodes/config-array@0.11.14: + resolution: {integrity: sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==} engines: {node: '>=10.10.0'} dependencies: - '@humanwhocodes/object-schema': 1.2.1 + '@humanwhocodes/object-schema': 2.0.2 debug: 4.3.4 minimatch: 3.1.2 transitivePeerDependencies: - supports-color dev: true - /@humanwhocodes/object-schema@1.2.1: - resolution: {integrity: sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==} + /@humanwhocodes/module-importer@1.0.1: + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} + engines: {node: '>=12.22'} + dev: true + + /@humanwhocodes/object-schema@2.0.2: + resolution: {integrity: sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==} dev: true /@isaacs/cliui@8.0.2: @@ -308,10 +341,6 @@ packages: resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} dev: true - /@types/json5@0.0.29: - resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} - dev: true - /@types/keyv@3.1.4: resolution: {integrity: sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==} dependencies: @@ -349,6 +378,10 @@ packages: '@types/node': 14.14.9 dev: true + /@types/semver@7.5.8: + resolution: {integrity: sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==} + dev: true + /@types/sinon-chai@3.2.6: resolution: {integrity: sha512-Z57LprQ+yOQNu9d6mWdHNvnmncPXzDWGSeLj+8L075/QahToapC4Q13zAFRVKV4clyBmdJ5gz4xBfVkOso5lXw==} dependencies: @@ -362,109 +395,135 @@ packages: '@sinonjs/fake-timers': 7.1.2 dev: true - /@typescript-eslint/eslint-plugin@5.7.0(@typescript-eslint/parser@5.7.0)(eslint@8.4.1)(typescript@4.5.4): - resolution: {integrity: sha512-8RTGBpNn5a9M628wBPrCbJ+v3YTEOE2qeZb7TDkGKTDXSj36KGRg92SpFFaR/0S3rSXQxM0Og/kV9EyadsYSBg==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + /@typescript-eslint/eslint-plugin@7.1.0(@typescript-eslint/parser@7.1.0)(eslint@8.57.0)(typescript@4.5.4): + resolution: {integrity: sha512-j6vT/kCulhG5wBmGtstKeiVr1rdXE4nk+DT1k6trYkwlrvW9eOF5ZbgKnd/YR6PcM4uTEXa0h6Fcvf6X7Dxl0w==} + engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: - '@typescript-eslint/parser': ^5.0.0 - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + '@typescript-eslint/parser': ^7.0.0 + eslint: ^8.56.0 typescript: '*' peerDependenciesMeta: typescript: optional: true dependencies: - '@typescript-eslint/experimental-utils': 5.7.0(eslint@8.4.1)(typescript@4.5.4) - '@typescript-eslint/parser': 5.7.0(eslint@8.4.1)(typescript@4.5.4) - '@typescript-eslint/scope-manager': 5.7.0 + '@eslint-community/regexpp': 4.10.0 + '@typescript-eslint/parser': 7.1.0(eslint@8.57.0)(typescript@4.5.4) + '@typescript-eslint/scope-manager': 7.1.0 + '@typescript-eslint/type-utils': 7.1.0(eslint@8.57.0)(typescript@4.5.4) + '@typescript-eslint/utils': 7.1.0(eslint@8.57.0)(typescript@4.5.4) + '@typescript-eslint/visitor-keys': 7.1.0 debug: 4.3.4 - eslint: 8.4.1 - functional-red-black-tree: 1.0.1 + eslint: 8.57.0 + graphemer: 1.4.0 ignore: 5.3.1 - regexpp: 3.2.0 + natural-compare: 1.4.0 semver: 7.6.0 - tsutils: 3.21.0(typescript@4.5.4) + ts-api-utils: 1.2.1(typescript@4.5.4) typescript: 4.5.4 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/experimental-utils@5.7.0(eslint@8.4.1)(typescript@4.5.4): - resolution: {integrity: sha512-u57eZ5FbEpzN5kSjmVrSesovWslH2ZyNPnaXQMXWgH57d5+EVHEt76W75vVuI9qKZ5BMDKNfRN+pxcPEjQjb2A==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + /@typescript-eslint/parser@7.1.0(eslint@8.57.0)(typescript@4.5.4): + resolution: {integrity: sha512-V1EknKUubZ1gWFjiOZhDSNToOjs63/9O0puCgGS8aDOgpZY326fzFu15QAUjwaXzRZjf/qdsdBrckYdv9YxB8w==} + engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: - eslint: '*' + eslint: ^8.56.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true dependencies: - '@types/json-schema': 7.0.15 - '@typescript-eslint/scope-manager': 5.7.0 - '@typescript-eslint/types': 5.7.0 - '@typescript-eslint/typescript-estree': 5.7.0(typescript@4.5.4) - eslint: 8.4.1 - eslint-scope: 5.1.1 - eslint-utils: 3.0.0(eslint@8.4.1) + '@typescript-eslint/scope-manager': 7.1.0 + '@typescript-eslint/types': 7.1.0 + '@typescript-eslint/typescript-estree': 7.1.0(typescript@4.5.4) + '@typescript-eslint/visitor-keys': 7.1.0 + debug: 4.3.4 + eslint: 8.57.0 + typescript: 4.5.4 transitivePeerDependencies: - supports-color - - typescript dev: true - /@typescript-eslint/parser@5.7.0(eslint@8.4.1)(typescript@4.5.4): - resolution: {integrity: sha512-m/gWCCcS4jXw6vkrPQ1BjZ1vomP01PArgzvauBqzsoZ3urLbsRChexB8/YV8z9HwE3qlJM35FxfKZ1nfP/4x8g==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + /@typescript-eslint/scope-manager@7.1.0: + resolution: {integrity: sha512-6TmN4OJiohHfoOdGZ3huuLhpiUgOGTpgXNUPJgeZOZR3DnIpdSgtt83RS35OYNNXxM4TScVlpVKC9jyQSETR1A==} + engines: {node: ^16.0.0 || >=18.0.0} + dependencies: + '@typescript-eslint/types': 7.1.0 + '@typescript-eslint/visitor-keys': 7.1.0 + dev: true + + /@typescript-eslint/type-utils@7.1.0(eslint@8.57.0)(typescript@4.5.4): + resolution: {integrity: sha512-UZIhv8G+5b5skkcuhgvxYWHjk7FW7/JP5lPASMEUoliAPwIH/rxoUSQPia2cuOj9AmDZmwUl1usKm85t5VUMew==} + engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + eslint: ^8.56.0 typescript: '*' peerDependenciesMeta: typescript: optional: true dependencies: - '@typescript-eslint/scope-manager': 5.7.0 - '@typescript-eslint/types': 5.7.0 - '@typescript-eslint/typescript-estree': 5.7.0(typescript@4.5.4) + '@typescript-eslint/typescript-estree': 7.1.0(typescript@4.5.4) + '@typescript-eslint/utils': 7.1.0(eslint@8.57.0)(typescript@4.5.4) debug: 4.3.4 - eslint: 8.4.1 + eslint: 8.57.0 + ts-api-utils: 1.2.1(typescript@4.5.4) typescript: 4.5.4 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/scope-manager@5.7.0: - resolution: {integrity: sha512-7mxR520DGq5F7sSSgM0HSSMJ+TFUymOeFRMfUfGFAVBv8BR+Jv1vHgAouYUvWRZeszVBJlLcc9fDdktxb5kmxA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - dependencies: - '@typescript-eslint/types': 5.7.0 - '@typescript-eslint/visitor-keys': 5.7.0 + /@typescript-eslint/types@7.1.0: + resolution: {integrity: sha512-qTWjWieJ1tRJkxgZYXx6WUYtWlBc48YRxgY2JN1aGeVpkhmnopq+SUC8UEVGNXIvWH7XyuTjwALfG6bFEgCkQA==} + engines: {node: ^16.0.0 || >=18.0.0} dev: true - /@typescript-eslint/types@5.7.0: - resolution: {integrity: sha512-5AeYIF5p2kAneIpnLFve8g50VyAjq7udM7ApZZ9JYjdPjkz0LvODfuSHIDUVnIuUoxafoWzpFyU7Sqbxgi79mA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - dev: true - - /@typescript-eslint/typescript-estree@5.7.0(typescript@4.5.4): - resolution: {integrity: sha512-aO1Ql+izMrTnPj5aFFlEJkpD4jRqC4Gwhygu2oHK2wfVQpmOPbyDSveJ+r/NQo+PWV43M6uEAeLVbTi09dFLhg==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + /@typescript-eslint/typescript-estree@7.1.0(typescript@4.5.4): + resolution: {integrity: sha512-k7MyrbD6E463CBbSpcOnwa8oXRdHzH1WiVzOipK3L5KSML92ZKgUBrTlehdi7PEIMT8k0bQixHUGXggPAlKnOQ==} + engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: typescript: '*' peerDependenciesMeta: typescript: optional: true dependencies: - '@typescript-eslint/types': 5.7.0 - '@typescript-eslint/visitor-keys': 5.7.0 + '@typescript-eslint/types': 7.1.0 + '@typescript-eslint/visitor-keys': 7.1.0 debug: 4.3.4 globby: 11.1.0 is-glob: 4.0.3 + minimatch: 9.0.3 semver: 7.6.0 - tsutils: 3.21.0(typescript@4.5.4) + ts-api-utils: 1.2.1(typescript@4.5.4) typescript: 4.5.4 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/visitor-keys@5.7.0: - resolution: {integrity: sha512-hdohahZ4lTFcglZSJ3DGdzxQHBSxsLVqHzkiOmKi7xVAWC4y2c1bIMKmPJSrA4aOEoRUPOKQ87Y/taC7yVHpFg==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + /@typescript-eslint/utils@7.1.0(eslint@8.57.0)(typescript@4.5.4): + resolution: {integrity: sha512-WUFba6PZC5OCGEmbweGpnNJytJiLG7ZvDBJJoUcX4qZYf1mGZ97mO2Mps6O2efxJcJdRNpqweCistDbZMwIVHw==} + engines: {node: ^16.0.0 || >=18.0.0} + peerDependencies: + eslint: ^8.56.0 + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) + '@types/json-schema': 7.0.15 + '@types/semver': 7.5.8 + '@typescript-eslint/scope-manager': 7.1.0 + '@typescript-eslint/types': 7.1.0 + '@typescript-eslint/typescript-estree': 7.1.0(typescript@4.5.4) + eslint: 8.57.0 + semver: 7.6.0 + transitivePeerDependencies: + - supports-color + - typescript + dev: true + + /@typescript-eslint/visitor-keys@7.1.0: + resolution: {integrity: sha512-FhUqNWluiGNzlvnDZiXad4mZRhtghdoKW6e98GoEOYSu5cND+E39rG5KwJMUzeENwm1ztYBRqof8wMLP+wNPIA==} + engines: {node: ^16.0.0 || >=18.0.0} dependencies: - '@typescript-eslint/types': 5.7.0 + '@typescript-eslint/types': 7.1.0 eslint-visitor-keys: 3.4.3 dev: true @@ -472,6 +531,10 @@ packages: resolution: {integrity: sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==} dev: true + /@ungap/structured-clone@1.2.0: + resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} + dev: true + /acorn-jsx@5.3.2(acorn@8.11.3): resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: @@ -582,24 +645,13 @@ packages: is-array-buffer: 3.0.4 dev: true - /array-includes@3.1.7: - resolution: {integrity: sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.7 - define-properties: 1.2.1 - es-abstract: 1.22.5 - get-intrinsic: 1.2.4 - is-string: 1.0.7 - dev: true - /array-union@2.1.0: resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} engines: {node: '>=8'} dev: true - /array.prototype.flat@1.3.2: - resolution: {integrity: sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==} + /array.prototype.flatmap@1.3.2: + resolution: {integrity: sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==} engines: {node: '>= 0.4'} dependencies: call-bind: 1.0.7 @@ -889,10 +941,6 @@ packages: xdg-basedir: 4.0.0 dev: true - /confusing-browser-globals@1.0.11: - resolution: {integrity: sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==} - dev: true - /connect-livereload@0.6.1: resolution: {integrity: sha512-3R0kMOdL7CjJpU66fzAkCe6HNtd3AavCS4m+uW4KtJjrdGPT0SQEZieAYd+cm+lJoBznNQ4lqipYWkhBMgk00g==} dev: true @@ -956,17 +1004,6 @@ packages: ms: 2.0.0 dev: true - /debug@3.2.7: - resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - dependencies: - ms: 2.1.3 - dev: true - /debug@4.3.2(supports-color@8.1.1): resolution: {integrity: sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==} engines: {node: '>=6.0'} @@ -1137,13 +1174,6 @@ packages: tweezer.js: 1.5.0 dev: true - /doctrine@2.1.0: - resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} - engines: {node: '>=0.10.0'} - dependencies: - esutils: 2.0.3 - dev: true - /doctrine@3.0.0: resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} engines: {node: '>=6.0.0'} @@ -1316,120 +1346,35 @@ packages: engines: {node: '>=10'} dev: true - /eslint-config-airbnb-base@15.0.0(eslint-plugin-import@2.25.3)(eslint@8.4.1): - resolution: {integrity: sha512-xaX3z4ZZIcFLvh2oUNvcX5oEofXda7giYmuplVxoOg5A7EXJMrUyqRgR+mhDhPK8LZ4PttFOBvCYDbX3sUoUig==} - engines: {node: ^10.12.0 || >=12.0.0} - peerDependencies: - eslint: ^7.32.0 || ^8.2.0 - eslint-plugin-import: ^2.25.2 - dependencies: - confusing-browser-globals: 1.0.11 - eslint: 8.4.1 - eslint-plugin-import: 2.25.3(@typescript-eslint/parser@5.7.0)(eslint-import-resolver-typescript@2.5.0)(eslint@8.4.1) - object.assign: 4.1.5 - object.entries: 1.1.7 - semver: 6.3.1 - dev: true - - /eslint-config-prettier@8.3.0(eslint@8.4.1): - resolution: {integrity: sha512-BgZuLUSeKzvlL/VUjx/Yb787VQ26RU3gGjA3iiFvdsp/2bMfVIWUVP7tjxtjS0e+HP409cPlPvNkQloz8C91ew==} + /eslint-config-prettier@9.1.0(eslint@8.57.0): + resolution: {integrity: sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==} hasBin: true peerDependencies: eslint: '>=7.0.0' dependencies: - eslint: 8.4.1 + eslint: 8.57.0 dev: true - /eslint-import-resolver-node@0.3.9: - resolution: {integrity: sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==} - dependencies: - debug: 3.2.7 - is-core-module: 2.13.1 - resolve: 1.22.8 - transitivePeerDependencies: - - supports-color + /eslint-define-config@2.1.0: + resolution: {integrity: sha512-QUp6pM9pjKEVannNAbSJNeRuYwW3LshejfyBBpjeMGaJjaDUpVps4C6KVR8R7dWZnD3i0synmrE36znjTkJvdQ==} + engines: {node: '>=18.0.0', npm: '>=9.0.0', pnpm: '>=8.6.0'} dev: true - /eslint-import-resolver-typescript@2.5.0(eslint-plugin-import@2.25.3)(eslint@8.4.1): - resolution: {integrity: sha512-qZ6e5CFr+I7K4VVhQu3M/9xGv9/YmwsEXrsm3nimw8vWaVHRDrQRp26BgCypTxBp3vUp4o5aVEJRiy0F2DFddQ==} - engines: {node: '>=4'} + /eslint-gitignore@0.1.0(eslint@8.57.0): + resolution: {integrity: sha512-VFvY5Wyjuz5xXDC/NeONHzsh4YQNok2Gzg4SftAAuhkbrdHv5CChjfiFyLKhRlgOdCJr5kBquaLXHtuDBTW2/Q==} + engines: {node: ^10.12.0 || >=12.0.0} peerDependencies: - eslint: '*' - eslint-plugin-import: '*' + eslint: '>=6.7.0' dependencies: + array.prototype.flatmap: 1.3.2 debug: 4.3.4 - eslint: 8.4.1 - eslint-plugin-import: 2.25.3(@typescript-eslint/parser@5.7.0)(eslint-import-resolver-typescript@2.5.0)(eslint@8.4.1) - glob: 7.2.3 - is-glob: 4.0.3 - resolve: 1.22.8 - tsconfig-paths: 3.15.0 - transitivePeerDependencies: - - supports-color - dev: true - - /eslint-module-utils@2.8.1(@typescript-eslint/parser@5.7.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@2.5.0)(eslint@8.4.1): - resolution: {integrity: sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q==} - engines: {node: '>=4'} - peerDependencies: - '@typescript-eslint/parser': '*' - eslint: '*' - eslint-import-resolver-node: '*' - eslint-import-resolver-typescript: '*' - eslint-import-resolver-webpack: '*' - peerDependenciesMeta: - '@typescript-eslint/parser': - optional: true - eslint: - optional: true - eslint-import-resolver-node: - optional: true - eslint-import-resolver-typescript: - optional: true - eslint-import-resolver-webpack: - optional: true - dependencies: - '@typescript-eslint/parser': 5.7.0(eslint@8.4.1)(typescript@4.5.4) - debug: 3.2.7 - eslint: 8.4.1 - eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 2.5.0(eslint-plugin-import@2.25.3)(eslint@8.4.1) - transitivePeerDependencies: - - supports-color - dev: true - - /eslint-plugin-import@2.25.3(@typescript-eslint/parser@5.7.0)(eslint-import-resolver-typescript@2.5.0)(eslint@8.4.1): - resolution: {integrity: sha512-RzAVbby+72IB3iOEL8clzPLzL3wpDrlwjsTBAQXgyp5SeTqqY+0bFubwuo+y/HLhNZcXV4XqTBO4LGsfyHIDXg==} - engines: {node: '>=4'} - peerDependencies: - '@typescript-eslint/parser': '*' - eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 - peerDependenciesMeta: - '@typescript-eslint/parser': - optional: true - dependencies: - '@typescript-eslint/parser': 5.7.0(eslint@8.4.1)(typescript@4.5.4) - array-includes: 3.1.7 - array.prototype.flat: 1.3.2 - debug: 2.6.9 - doctrine: 2.1.0 - eslint: 8.4.1 - eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.8.1(@typescript-eslint/parser@5.7.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@2.5.0)(eslint@8.4.1) - has: 1.0.4 - is-core-module: 2.13.1 - is-glob: 4.0.3 - minimatch: 3.1.2 - object.values: 1.1.7 - resolve: 1.22.8 - tsconfig-paths: 3.15.0 + eslint: 8.57.0 + fast-glob: 3.3.2 transitivePeerDependencies: - - eslint-import-resolver-typescript - - eslint-import-resolver-webpack - supports-color dev: true - /eslint-plugin-prettier@5.1.3(eslint-config-prettier@8.3.0)(eslint@8.4.1)(prettier@3.2.5): + /eslint-plugin-prettier@5.1.3(eslint-config-prettier@9.1.0)(eslint@8.57.0)(prettier@3.2.5): resolution: {integrity: sha512-C9GCVAs4Eq7ZC/XFQHITLiHJxQngdtraXaM+LoUFoFp/lHNl2Zn8f3WQbe9HvTBBQ9YnKFB0/2Ajdqwo5D1EAw==} engines: {node: ^14.18.0 || >=16.0.0} peerDependencies: @@ -1443,27 +1388,13 @@ packages: eslint-config-prettier: optional: true dependencies: - eslint: 8.4.1 - eslint-config-prettier: 8.3.0(eslint@8.4.1) + eslint: 8.57.0 + eslint-config-prettier: 9.1.0(eslint@8.57.0) prettier: 3.2.5 prettier-linter-helpers: 1.0.0 synckit: 0.8.8 dev: true - /eslint-plugin-security@1.4.0: - resolution: {integrity: sha512-xlS7P2PLMXeqfhyf3NpqbvbnW04kN8M9NtmhpR3XGyOvt/vNKS7XPXT5EDbwKW9vCjWH4PpfQvgD/+JgN0VJKA==} - dependencies: - safe-regex: 1.1.0 - dev: true - - /eslint-scope@5.1.1: - resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} - engines: {node: '>=8.0.0'} - dependencies: - esrecurse: 4.3.0 - estraverse: 4.3.0 - dev: true - /eslint-scope@7.2.2: resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -1472,55 +1403,45 @@ packages: estraverse: 5.3.0 dev: true - /eslint-utils@3.0.0(eslint@8.4.1): - resolution: {integrity: sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==} - engines: {node: ^10.0.0 || ^12.0.0 || >= 14.0.0} - peerDependencies: - eslint: '>=5' - dependencies: - eslint: 8.4.1 - eslint-visitor-keys: 2.1.0 - dev: true - - /eslint-visitor-keys@2.1.0: - resolution: {integrity: sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==} - engines: {node: '>=10'} - dev: true - /eslint-visitor-keys@3.4.3: resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true - /eslint@8.4.1: - resolution: {integrity: sha512-TxU/p7LB1KxQ6+7aztTnO7K0i+h0tDi81YRY9VzB6Id71kNz+fFYnf5HD5UOQmxkzcoa0TlVZf9dpMtUv0GpWg==} + /eslint@8.57.0: + resolution: {integrity: sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} hasBin: true dependencies: - '@eslint/eslintrc': 1.4.1 - '@humanwhocodes/config-array': 0.9.5 + '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) + '@eslint-community/regexpp': 4.10.0 + '@eslint/eslintrc': 2.1.4 + '@eslint/js': 8.57.0 + '@humanwhocodes/config-array': 0.11.14 + '@humanwhocodes/module-importer': 1.0.1 + '@nodelib/fs.walk': 1.2.8 + '@ungap/structured-clone': 1.2.0 ajv: 6.12.6 chalk: 4.1.2 cross-spawn: 7.0.3 debug: 4.3.4 doctrine: 3.0.0 - enquirer: 2.4.1 escape-string-regexp: 4.0.0 eslint-scope: 7.2.2 - eslint-utils: 3.0.0(eslint@8.4.1) eslint-visitor-keys: 3.4.3 espree: 9.6.1 esquery: 1.5.0 esutils: 2.0.3 fast-deep-equal: 3.1.3 file-entry-cache: 6.0.1 - functional-red-black-tree: 1.0.1 + find-up: 5.0.0 glob-parent: 6.0.2 globals: 13.24.0 - ignore: 4.0.6 - import-fresh: 3.3.0 + graphemer: 1.4.0 + ignore: 5.3.1 imurmurhash: 0.1.4 is-glob: 4.0.3 + is-path-inside: 3.0.3 js-yaml: 4.1.0 json-stable-stringify-without-jsonify: 1.0.1 levn: 0.4.1 @@ -1528,13 +1449,8 @@ packages: minimatch: 3.1.2 natural-compare: 1.4.0 optionator: 0.9.3 - progress: 2.0.3 - regexpp: 3.2.0 - semver: 7.6.0 strip-ansi: 6.0.1 - strip-json-comments: 3.1.1 text-table: 0.2.0 - v8-compile-cache: 2.4.0 transitivePeerDependencies: - supports-color dev: true @@ -1562,11 +1478,6 @@ packages: estraverse: 5.3.0 dev: true - /estraverse@4.3.0: - resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==} - engines: {node: '>=4.0'} - dev: true - /estraverse@5.3.0: resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} engines: {node: '>=4.0'} @@ -1745,10 +1656,6 @@ packages: functions-have-names: 1.2.3 dev: true - /functional-red-black-tree@1.0.1: - resolution: {integrity: sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==} - dev: true - /functions-have-names@1.2.3: resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} dev: true @@ -1910,6 +1817,10 @@ packages: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} dev: true + /graphemer@1.4.0: + resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} + dev: true + /growl@1.10.5: resolution: {integrity: sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==} engines: {node: '>=4.x'} @@ -1964,11 +1875,6 @@ packages: engines: {node: '>=8'} dev: true - /has@1.0.4: - resolution: {integrity: sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ==} - engines: {node: '>= 0.4.0'} - dev: true - /hasown@2.0.1: resolution: {integrity: sha512-1/th4MHjnwncwXsIW6QMzlvYL9kG5e/CpVvLRZe4XPa8TOUNbCELqmvhDmnkNsAjwaG4+I8gJJL0JBvTTLO9qA==} engines: {node: '>= 0.4'} @@ -1996,11 +1902,6 @@ packages: toidentifier: 1.0.1 dev: true - /ignore@4.0.6: - resolution: {integrity: sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==} - engines: {node: '>= 4'} - dev: true - /ignore@5.3.1: resolution: {integrity: sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==} engines: {node: '>= 4'} @@ -2049,7 +1950,7 @@ packages: dependencies: es-errors: 1.3.0 hasown: 2.0.1 - side-channel: 1.0.5 + side-channel: 1.0.6 dev: true /is-array-buffer@3.0.4: @@ -2281,13 +2182,6 @@ packages: resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} dev: true - /json5@1.0.2: - resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==} - hasBin: true - dependencies: - minimist: 1.2.8 - dev: true - /json5@2.2.0: resolution: {integrity: sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==} engines: {node: '>=6'} @@ -2634,24 +2528,6 @@ packages: object-keys: 1.1.1 dev: true - /object.entries@1.1.7: - resolution: {integrity: sha512-jCBs/0plmPsOnrKAfFQXRG2NFjlhZgjjcBLSmTnEhU8U6vVTsVe8ANeQJCHTl3gSsI4J+0emOoCgoKlmQPMgmA==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.7 - define-properties: 1.2.1 - es-abstract: 1.22.5 - dev: true - - /object.values@1.1.7: - resolution: {integrity: sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.7 - define-properties: 1.2.1 - es-abstract: 1.22.5 - dev: true - /obuf@1.1.2: resolution: {integrity: sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==} dev: false @@ -3018,11 +2894,6 @@ packages: engines: {node: '>=6'} dev: true - /progress@2.0.3: - resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==} - engines: {node: '>=0.4.0'} - dev: true - /proxyquire@2.1.3: resolution: {integrity: sha512-BQWfCqYM+QINd+yawJz23tbBM40VIGXOdDw3X344KcclI/gtBbdWF6SlQ4nK/bYhF9d27KYug9WzljHC6B9Ysg==} dependencies: @@ -3100,11 +2971,6 @@ packages: set-function-name: 2.0.2 dev: true - /regexpp@3.2.0: - resolution: {integrity: sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==} - engines: {node: '>=8'} - dev: true - /registry-auth-token@4.2.2: resolution: {integrity: sha512-PC5ZysNb42zpFME6D/XlIgtNGdTl8bBOCw90xQLVMpzuuubJKYDWFAEuUNc+Cn8Z8724tg2SDhDRrkVEsqfDMg==} engines: {node: '>=6.0.0'} @@ -3151,11 +3017,6 @@ packages: lowercase-keys: 1.0.1 dev: true - /ret@0.1.15: - resolution: {integrity: sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==} - engines: {node: '>=0.12'} - dev: true - /reusify@1.0.4: resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} @@ -3205,12 +3066,6 @@ packages: is-regex: 1.1.4 dev: true - /safe-regex@1.1.0: - resolution: {integrity: sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg==} - dependencies: - ret: 0.1.15 - dev: true - /semver-diff@3.1.1: resolution: {integrity: sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg==} engines: {node: '>=8'} @@ -3316,8 +3171,8 @@ packages: resolution: {integrity: sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==} dev: true - /side-channel@1.0.5: - resolution: {integrity: sha512-QcgiIWV4WV7qWExbN5llt6frQB/lBven9pqliLXfGPB+K9ZYXxDozp0wLkHS24kWCm+6YXH/f0HhnObZnZOBnQ==} + /side-channel@1.0.6: + resolution: {integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==} engines: {node: '>= 0.4'} dependencies: call-bind: 1.0.7 @@ -3454,11 +3309,6 @@ packages: ansi-regex: 6.0.1 dev: true - /strip-bom@3.0.0: - resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} - engines: {node: '>=4'} - dev: true - /strip-indent@3.0.0: resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==} engines: {node: '>=8'} @@ -3550,6 +3400,15 @@ packages: resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} dev: true + /ts-api-utils@1.2.1(typescript@4.5.4): + resolution: {integrity: sha512-RIYA36cJn2WiH9Hy77hdF9r7oEwxAtB/TS9/S4Qd90Ap4z5FSiin5zEiTL44OII1Y3IIlEvxwxFUVgrHSZ/UpA==} + engines: {node: '>=16'} + peerDependencies: + typescript: '>=4.2.0' + dependencies: + typescript: 4.5.4 + dev: true + /ts-node@10.4.0(@types/node@14.14.9)(typescript@4.5.4): resolution: {integrity: sha512-g0FlPvvCXSIO1JDF6S232P5jPYqBkRL9qly81ZgAOSU7rwI0stphCgd2kLiCrU9DjQCrJMWEqcNSjQL02s6d8A==} hasBin: true @@ -3580,33 +3439,10 @@ packages: yn: 3.1.1 dev: true - /tsconfig-paths@3.15.0: - resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==} - dependencies: - '@types/json5': 0.0.29 - json5: 1.0.2 - minimist: 1.2.8 - strip-bom: 3.0.0 - dev: true - - /tslib@1.14.1: - resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} - dev: true - /tslib@2.6.2: resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} dev: true - /tsutils@3.21.0(typescript@4.5.4): - resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} - engines: {node: '>= 6'} - peerDependencies: - typescript: '>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta' - dependencies: - tslib: 1.14.1 - typescript: 4.5.4 - dev: true - /tweezer.js@1.5.0: resolution: {integrity: sha512-aSiJz7rGWNAQq7hjMK9ZYDuEawXupcCWgl3woQQSoDP2Oh8O4srWb/uO1PzzHIsrPEOqrjJ2sUb9FERfzuBabQ==} dev: true @@ -3752,10 +3588,6 @@ packages: engines: {node: '>= 0.4.0'} dev: true - /v8-compile-cache@2.4.0: - resolution: {integrity: sha512-ocyWc3bAHBB/guyqJQVI5o4BZkPhznPYUG2ea80Gond/BgNWpap8TOmLSeeQG7bnh2KMISxskdADG59j7zruhw==} - dev: true - /webidl-conversions@3.0.1: resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} dev: true diff --git a/src/db.ts b/src/db.ts index e9d5a341..36b9e349 100644 --- a/src/db.ts +++ b/src/db.ts @@ -71,6 +71,7 @@ const db = ( logger.error(`could not connect to postgres: ${inspect(err)}`); return reject(err); } + connectionStatus = ConnectionStatus.CONNECTED; return resolve(); }); @@ -110,6 +111,7 @@ ${string} ${err} `); } + throw err; } }; @@ -121,6 +123,7 @@ ${err} const { rows } = await query(queryTextOrConfig, values); return rows; }; + const column: DBConnection['column'] = async ( columnName: string, queryTextOrConfig: string | QueryConfig | QueryArrayConfig, diff --git a/src/migration-builder.ts b/src/migration-builder.ts index ab18ffcf..8d947ac2 100644 --- a/src/migration-builder.ts +++ b/src/migration-builder.ts @@ -332,6 +332,7 @@ export default class MigrationBuilderImpl implements MigrationBuilder { `Impossible to automatically infer down migration for "${name}"` ); } + this._steps = this._steps.concat(operation.reverse(...args)); } else { this._steps = this._steps.concat(operation(...args)); @@ -460,8 +461,10 @@ export default class MigrationBuilderImpl implements MigrationBuilder { if (this._REVERSE_MODE) { throw new Error('Impossible to automatically infer down migration'); } + return operation(...args); }; + /* eslint-enable @typescript-eslint/no-explicit-any */ this.db = { query: wrapDB(db.query), @@ -492,4 +495,3 @@ export default class MigrationBuilderImpl implements MigrationBuilder { return this._REVERSE_MODE ? this._steps.slice().reverse() : this._steps; } } -/* eslint-enable security/detect-non-literal-fs-filename */ diff --git a/src/migration.ts b/src/migration.ts index ef07e144..85c5ad6c 100644 --- a/src/migration.ts +++ b/src/migration.ts @@ -58,7 +58,7 @@ export const loadMigrationFiles = async ( .map((file) => (file.isFile() || file.isSymbolicLink() ? file.name : null)) .filter((file): file is string => Boolean(file)) .sort(); - const filter = new RegExp(`^(${ignorePattern})$`); // eslint-disable-line security/detect-non-literal-regexp + const filter = new RegExp(`^(${ignorePattern})$`); return ignorePattern === undefined ? files : files.filter((i) => !filter.test(i)); @@ -85,6 +85,7 @@ export const getTimestamp = (logger: Logger, filename: string): number => { // timestamp: 1391877300255 return Number(prefix); } + if (prefix && prefix.length === 17) { // utc: 20200513070724505 const year = prefix.substr(0, 4); @@ -99,6 +100,7 @@ export const getTimestamp = (logger: Logger, filename: string): number => { ).valueOf(); } } + logger.error(`Can't determine timestamp for ${prefix}`); return Number(prefix) || 0; }; @@ -118,11 +120,11 @@ export class Migration implements RunMigration { _filenameFormat?: FilenameFormat ) { if (typeof _language === 'string') { - // eslint-disable-next-line no-console console.warn( 'This usage is deprecated. Please use this method with options object argument' ); } + const options = typeof _language === 'object' ? _language @@ -156,9 +158,7 @@ export class Migration implements RunMigration { // copy the default migration template to the new file location await new Promise((resolve, reject) => { - // eslint-disable-next-line security/detect-non-literal-fs-filename fs.createReadStream(templateFileName) - // eslint-disable-next-line security/detect-non-literal-fs-filename .pipe(fs.createWriteStream(newFile)) .on('close', resolve) .on('error', reject); diff --git a/src/operations/PgLiteral.ts b/src/operations/PgLiteral.ts index 9cbb1d7c..21adae57 100644 --- a/src/operations/PgLiteral.ts +++ b/src/operations/PgLiteral.ts @@ -7,7 +7,6 @@ export default class PgLiteral { public readonly literal = true; - // eslint-disable-next-line no-useless-constructor constructor(public readonly value: string) {} toString(): string { diff --git a/src/operations/domains.ts b/src/operations/domains.ts index 8888c04e..8728791d 100644 --- a/src/operations/domains.ts +++ b/src/operations/domains.ts @@ -17,6 +17,7 @@ export function dropDomain(mOptions: MigrationOptions) { const domainNameStr = mOptions.literal(domainName); return `DROP DOMAIN${ifExistsStr} ${domainNameStr}${cascadeStr};`; }; + return _drop; } @@ -33,15 +34,18 @@ export function createDomain(mOptions: MigrationOptions) { if (collation) { constraints.push(`COLLATE ${collation}`); } + if (defaultValue !== undefined) { constraints.push(`DEFAULT ${escapeValue(defaultValue)}`); } + if (notNull && check) { throw new Error('"notNull" and "check" can\'t be specified together'); } else if (notNull || check) { if (constraintName) { constraints.push(`CONSTRAINT ${mOptions.literal(constraintName)}`); } + if (notNull) { constraints.push('NOT NULL'); } else if (check) { @@ -58,6 +62,7 @@ export function createDomain(mOptions: MigrationOptions) { return `CREATE DOMAIN ${domainNameStr} AS ${typeStr}${constraintsStr};`; }; + _create.reverse = (domainName, type, options) => dropDomain(mOptions)(domainName, options); return _create; @@ -78,11 +83,13 @@ export function alterDomain(mOptions: MigrationOptions) { } else if (defaultValue !== undefined) { actions.push(`SET DEFAULT ${escapeValue(defaultValue)}`); } + if (notNull) { actions.push('SET NOT NULL'); } else if (notNull === false || allowNull) { actions.push('DROP NOT NULL'); } + if (check) { actions.push( `${constraintName ? `CONSTRAINT ${mOptions.literal(constraintName)} ` : ''}CHECK (${check})` @@ -91,6 +98,7 @@ export function alterDomain(mOptions: MigrationOptions) { return `${actions.map((action) => `ALTER DOMAIN ${mOptions.literal(domainName)} ${action}`).join(';\n')};`; }; + return _alter; } @@ -100,6 +108,7 @@ export function renameDomain(mOptions: MigrationOptions) { const newDomainNameStr = mOptions.literal(newDomainName); return `ALTER DOMAIN ${domainNameStr} RENAME TO ${newDomainNameStr};`; }; + _rename.reverse = (domainName, newDomainName) => _rename(newDomainName, domainName); return _rename; diff --git a/src/operations/extensions.ts b/src/operations/extensions.ts index 378e8b79..4932f361 100644 --- a/src/operations/extensions.ts +++ b/src/operations/extensions.ts @@ -14,6 +14,7 @@ export function dropExtension(mOptions: MigrationOptions) { return `DROP EXTENSION${ifExistsStr} ${extensionStr}${cascadeStr};`; }); }; + return _drop; } @@ -28,6 +29,7 @@ export function createExtension(mOptions: MigrationOptions) { return `CREATE EXTENSION${ifNotExistsStr} ${extensionStr}${schemaStr};`; }); }; + _create.reverse = dropExtension(mOptions); return _create; } diff --git a/src/operations/extensionsTypes.ts b/src/operations/extensionsTypes.ts index a5b333e2..d36e2b50 100644 --- a/src/operations/extensionsTypes.ts +++ b/src/operations/extensionsTypes.ts @@ -53,13 +53,13 @@ export interface CreateExtensionOptions extends IfNotExistsOption { type StringExtension = LiteralUnion; type CreateExtensionFn = ( - extension: StringExtension | Array, + extension: StringExtension | StringExtension[], options?: CreateExtensionOptions & DropOptions ) => string | string[]; export type CreateExtension = CreateExtensionFn & { reverse: CreateExtensionFn; }; export type DropExtension = ( - extension: StringExtension | Array, + extension: StringExtension | StringExtension[], dropOptions?: DropOptions ) => string | string[]; diff --git a/src/operations/functions.ts b/src/operations/functions.ts index 4a5a9cb0..8ae1660a 100644 --- a/src/operations/functions.ts +++ b/src/operations/functions.ts @@ -17,13 +17,13 @@ export function dropFunction(mOptions: MigrationOptions) { const functionNameStr = mOptions.literal(functionName); return `DROP FUNCTION${ifExistsStr} ${functionNameStr}${paramsStr}${cascadeStr};`; }; + return _drop; } export function createFunction(mOptions: MigrationOptions) { const _create: CreateFunction = ( functionName, - // eslint-disable-next-line default-param-last functionParams = [], functionOptions, definition @@ -41,6 +41,7 @@ export function createFunction(mOptions: MigrationOptions) { if (behavior) { options.push(behavior); } + if (language) { options.push(`LANGUAGE ${language}`); } else { @@ -48,12 +49,15 @@ export function createFunction(mOptions: MigrationOptions) { `Language for function ${functionName} have to be specified` ); } + if (window) { options.push('WINDOW'); } + if (onNull) { options.push('RETURNS NULL ON NULL INPUT'); } + if (parallel) { options.push(`PARALLEL ${parallel}`); } @@ -67,6 +71,7 @@ export function createFunction(mOptions: MigrationOptions) { AS ${escapeValue(definition)} ${options.join('\n ')};`; }; + _create.reverse = dropFunction(mOptions); return _create; } @@ -74,7 +79,6 @@ export function createFunction(mOptions: MigrationOptions) { export function renameFunction(mOptions: MigrationOptions) { const _rename: RenameFunction = ( oldFunctionName, - // eslint-disable-next-line default-param-last functionParams = [], newFunctionName ) => { @@ -83,6 +87,7 @@ export function renameFunction(mOptions: MigrationOptions) { const newFunctionNameStr = mOptions.literal(newFunctionName); return `ALTER FUNCTION ${oldFunctionNameStr}${paramsStr} RENAME TO ${newFunctionNameStr};`; }; + _rename.reverse = (oldFunctionName, functionParams, newFunctionName) => _rename(newFunctionName, functionParams, oldFunctionName); return _rename; diff --git a/src/operations/generalTypes.ts b/src/operations/generalTypes.ts index 69d2b6a9..f715c96b 100644 --- a/src/operations/generalTypes.ts +++ b/src/operations/generalTypes.ts @@ -1,6 +1,5 @@ import PgLiteral from './PgLiteral'; -// eslint-disable-next-line camelcase export type LiteralUnion = | T | (string & { zz_IGNORE_ME?: never }); diff --git a/src/operations/indexes.ts b/src/operations/indexes.ts index b0fe0a67..1649af49 100644 --- a/src/operations/indexes.ts +++ b/src/operations/indexes.ts @@ -12,7 +12,7 @@ export { CreateIndex, DropIndex }; function generateIndexName( table: Name, - columns: (string | IndexColumn)[], + columns: Array, options: CreateIndexOptions | DropIndexOptions, schemalize: Literal ) { @@ -21,6 +21,7 @@ function generateIndexName( ? { schema: table.schema, name: options.name } : options.name; } + const cols = columns .map((col) => schemalize(typeof col === 'string' ? col : col.name)) .join('_'); @@ -42,7 +43,7 @@ function generateColumnString(column: Name, mOptions: MigrationOptions) { } function generateColumnsString( - columns: (string | IndexColumn)[], + columns: Array, mOptions: MigrationOptions ) { return columns @@ -79,6 +80,7 @@ export function dropIndex(mOptions: MigrationOptions) { return `DROP INDEX${concurrentlyStr}${ifExistsStr} ${indexNameStr}${cascadeStr};`; }; + return _drop; } @@ -114,6 +116,7 @@ export function createIndex(mOptions: MigrationOptions) { columns[lastIndex] = { ...lastColumn, opclass: options.opclass }; } } + const indexName = generateIndexName( typeof tableName === 'object' ? tableName.name : tableName, columns, @@ -139,6 +142,7 @@ export function createIndex(mOptions: MigrationOptions) { return `CREATE${unique} INDEX${concurrently}${ifNotExistsStr} ${indexNameStr} ON ${tableNameStr}${method} (${columnsString})${include}${where};`; }; + _create.reverse = dropIndex(mOptions); return _create; } diff --git a/src/operations/indexesTypes.ts b/src/operations/indexesTypes.ts index 414e2694..865b9123 100644 --- a/src/operations/indexesTypes.ts +++ b/src/operations/indexesTypes.ts @@ -28,12 +28,12 @@ export interface DropIndexOptions extends DropOptions { type CreateIndexFn = ( tableName: Name, - columns: string | (string | IndexColumn)[], + columns: string | Array, options?: CreateIndexOptions & DropIndexOptions ) => string | string[]; export type CreateIndex = CreateIndexFn & { reverse: CreateIndexFn }; export type DropIndex = ( tableName: Name, - columns: string | (string | IndexColumn)[], + columns: string | Array, options?: DropIndexOptions ) => string | string[]; diff --git a/src/operations/operators.ts b/src/operations/operators.ts index 4d9cd1a7..6f44ecde 100644 --- a/src/operations/operators.ts +++ b/src/operations/operators.ts @@ -40,6 +40,7 @@ export function dropOperator(mOptions: MigrationOptions) { return `DROP OPERATOR${ifExistsStr} ${operatorNameStr}(${leftStr}, ${rightStr})${cascadeStr};`; }; + return _drop; } @@ -62,30 +63,39 @@ export function createOperator(mOptions: MigrationOptions) { if (left) { defs.push(`LEFTARG = ${mOptions.literal(left)}`); } + if (right) { defs.push(`RIGHTARG = ${mOptions.literal(right)}`); } + if (commutator) { defs.push(`COMMUTATOR = ${mOptions.schemalize(commutator)}`); } + if (negator) { defs.push(`NEGATOR = ${mOptions.schemalize(negator)}`); } + if (restrict) { defs.push(`RESTRICT = ${mOptions.literal(restrict)}`); } + if (join) { defs.push(`JOIN = ${mOptions.literal(join)}`); } + if (hashes) { defs.push('HASHES'); } + if (merges) { defs.push('MERGES'); } + const operatorNameStr = mOptions.schemalize(operatorName); return `CREATE OPERATOR ${operatorNameStr} (${defs.join(', ')});`; }; + _create.reverse = dropOperator(mOptions); return _create; } @@ -102,6 +112,7 @@ export function dropOperatorFamily(mOptions: MigrationOptions) { const cascadeStr = cascade ? ' CASCADE' : ''; return `DROP OPERATOR FAMILY ${ifExistsStr} ${operatorFamilyNameStr} USING ${indexMethod}${cascadeStr};`; }; + return _drop; } @@ -110,6 +121,7 @@ export function createOperatorFamily(mOptions: MigrationOptions) { const operatorFamilyNameStr = mOptions.literal(operatorFamilyName); return `CREATE OPERATOR FAMILY ${operatorFamilyNameStr} USING ${indexMethod};`; }; + _create.reverse = dropOperatorFamily(mOptions); return _create; } @@ -122,6 +134,7 @@ const operatorMap = if (params.length > 2) { throw new Error("Operator can't have more than 2 parameters"); } + const paramsStr = params.length > 0 ? formatParams(params, mOptions) : ''; return `OPERATOR ${number} ${nameStr}${paramsStr}`; @@ -149,8 +162,10 @@ export const removeFromOperatorFamily = (mOptions: MigrationOptions) => { return `ALTER OPERATOR FAMILY ${operatorFamilyNameStr} USING ${indexMethod} DROP ${operatorListStr};`; }; + return method; }; + export const addToOperatorFamily = (mOptions: MigrationOptions) => { const method: AddToOperatorFamily = ( operatorFamilyName, @@ -165,6 +180,7 @@ export const addToOperatorFamily = (mOptions: MigrationOptions) => { return `ALTER OPERATOR FAMILY ${operatorFamilyNameStr} USING ${indexMethod} ADD ${operatorListStr};`; }; + method.reverse = removeFromOperatorFamily(mOptions); return method; }; @@ -180,6 +196,7 @@ export function renameOperatorFamily(mOptions: MigrationOptions) { return `ALTER OPERATOR FAMILY ${oldOperatorFamilyNameStr} USING ${indexMethod} RENAME TO ${newOperatorFamilyNameStr};`; }; + _rename.reverse = ( oldOperatorFamilyName, indexMethod, @@ -201,6 +218,7 @@ export function dropOperatorClass(mOptions: MigrationOptions) { return `DROP OPERATOR CLASS ${ifExistsStr} ${operatorClassNameStr} USING ${indexMethod}${cascadeStr};`; }; + return _drop; } @@ -225,6 +243,7 @@ export function createOperatorClass(mOptions: MigrationOptions) { return `CREATE OPERATOR CLASS ${operatorClassNameStr}${defaultStr} FOR TYPE ${typeStr} USING ${indexMethodStr} ${familyStr} AS ${operatorListStr};`; }; + _create.reverse = ( operatorClassName, type, @@ -246,6 +265,7 @@ export function renameOperatorClass(mOptions: MigrationOptions) { return `ALTER OPERATOR CLASS ${oldOperatorClassNameStr} USING ${indexMethod} RENAME TO ${newOperatorClassNameStr};`; }; + _rename.reverse = (oldOperatorClassName, indexMethod, newOperatorClassName) => _rename(newOperatorClassName, indexMethod, oldOperatorClassName); return _rename; diff --git a/src/operations/other.ts b/src/operations/other.ts index ae27add0..c32b2b2d 100644 --- a/src/operations/other.ts +++ b/src/operations/other.ts @@ -13,6 +13,7 @@ export function sql(mOptions: MigrationOptions): Sql { if (s.lastIndexOf(';') !== s.length - 1) { s += ';'; } + return s; }; } diff --git a/src/operations/policies.ts b/src/operations/policies.ts index 6aabf655..03c7a6f7 100644 --- a/src/operations/policies.ts +++ b/src/operations/policies.ts @@ -15,12 +15,15 @@ const makeClauses = ({ role, using, check }: PolicyOptions) => { if (roles) { clauses.push(`TO ${roles}`); } + if (using) { clauses.push(`USING (${using})`); } + if (check) { clauses.push(`WITH CHECK (${check})`); } + return clauses; }; @@ -32,6 +35,7 @@ export function dropPolicy(mOptions: MigrationOptions) { const tableNameStr = mOptions.literal(tableName); return `DROP POLICY${ifExistsStr} ${policyNameStr} ON ${tableNameStr};`; }; + return _drop; } @@ -50,6 +54,7 @@ export function createPolicy(mOptions: MigrationOptions) { const tableNameStr = mOptions.literal(tableName); return `CREATE POLICY ${policyNameStr} ON ${tableNameStr} ${clausesStr};`; }; + _create.reverse = dropPolicy(mOptions); return _create; } @@ -61,6 +66,7 @@ export function alterPolicy(mOptions: MigrationOptions) { const tableNameStr = mOptions.literal(tableName); return `ALTER POLICY ${policyNameStr} ON ${tableNameStr} ${clausesStr};`; }; + return _alter; } @@ -71,6 +77,7 @@ export function renamePolicy(mOptions: MigrationOptions) { const tableNameStr = mOptions.literal(tableName); return `ALTER POLICY ${policyNameStr} ON ${tableNameStr} RENAME TO ${newPolicyNameStr};`; }; + _rename.reverse = (tableName, policyName, newPolicyName) => _rename(tableName, newPolicyName, policyName); return _rename; diff --git a/src/operations/roles.ts b/src/operations/roles.ts index 3e91229f..b562f1a0 100644 --- a/src/operations/roles.ts +++ b/src/operations/roles.ts @@ -15,50 +15,62 @@ const formatRoleOptions = (roleOptions: RoleOptions = {}) => { if (roleOptions.superuser !== undefined) { options.push(roleOptions.superuser ? 'SUPERUSER' : 'NOSUPERUSER'); } + if (roleOptions.createdb !== undefined) { options.push(roleOptions.createdb ? 'CREATEDB' : 'NOCREATEDB'); } + if (roleOptions.createrole !== undefined) { options.push(roleOptions.createrole ? 'CREATEROLE' : 'NOCREATEROLE'); } + if (roleOptions.inherit !== undefined) { options.push(roleOptions.inherit ? 'INHERIT' : 'NOINHERIT'); } + if (roleOptions.login !== undefined) { options.push(roleOptions.login ? 'LOGIN' : 'NOLOGIN'); } + if (roleOptions.replication !== undefined) { options.push(roleOptions.replication ? 'REPLICATION' : 'NOREPLICATION'); } + if (roleOptions.bypassrls !== undefined) { options.push(roleOptions.bypassrls ? 'BYPASSRLS' : 'NOBYPASSRLS'); } + if (roleOptions.limit) { options.push(`CONNECTION LIMIT ${Number(roleOptions.limit)}`); } + if (roleOptions.password !== undefined) { const encrypted = roleOptions.encrypted === false ? 'UNENCRYPTED' : 'ENCRYPTED'; options.push(`${encrypted} PASSWORD ${escapeValue(roleOptions.password)}`); } + if (roleOptions.valid !== undefined) { const valid = roleOptions.valid ? escapeValue(roleOptions.valid) : "'infinity'"; options.push(`VALID UNTIL ${valid}`); } + if (roleOptions.inRole) { const inRole = Array.isArray(roleOptions.inRole) ? roleOptions.inRole.join(',') : roleOptions.inRole; options.push(`IN ROLE ${inRole}`); } + if (roleOptions.role) { const role = Array.isArray(roleOptions.role) ? roleOptions.role.join(',') : roleOptions.role; options.push(`ROLE ${role}`); } + if (roleOptions.admin) { const admin = Array.isArray(roleOptions.admin) ? roleOptions.admin.join(',') @@ -76,6 +88,7 @@ export function dropRole(mOptions: MigrationOptions) { const roleNameStr = mOptions.literal(roleName); return `DROP ROLE${ifExistsStr} ${roleNameStr};`; }; + return _drop; } @@ -93,6 +106,7 @@ export function createRole(mOptions: MigrationOptions) { const optionsStr = options ? ` WITH ${options}` : ''; return `CREATE ROLE ${mOptions.literal(roleName)}${optionsStr};`; }; + _create.reverse = dropRole(mOptions); return _create; } @@ -104,6 +118,7 @@ export function alterRole(mOptions: MigrationOptions) { ? `ALTER ROLE ${mOptions.literal(roleName)} WITH ${options};` : ''; }; + return _alter; } @@ -113,6 +128,7 @@ export function renameRole(mOptions: MigrationOptions) { const newRoleNameStr = mOptions.literal(newRoleName); return `ALTER ROLE ${oldRoleNameStr} RENAME TO ${newRoleNameStr};`; }; + _rename.reverse = (oldRoleName, newRoleName) => _rename(newRoleName, oldRoleName); return _rename; diff --git a/src/operations/schemas.ts b/src/operations/schemas.ts index 84951bb3..3ec4d9f5 100644 --- a/src/operations/schemas.ts +++ b/src/operations/schemas.ts @@ -11,6 +11,7 @@ export function dropSchema(mOptions: MigrationOptions) { const schemaNameStr = mOptions.literal(schemaName); return `DROP SCHEMA${ifExistsStr} ${schemaNameStr}${cascadeStr};`; }; + return _drop; } @@ -24,6 +25,7 @@ export function createSchema(mOptions: MigrationOptions) { : ''; return `CREATE SCHEMA${ifNotExistsStr} ${schemaNameStr}${authorizationStr};`; }; + _create.reverse = dropSchema(mOptions); return _create; } @@ -34,6 +36,7 @@ export function renameSchema(mOptions: MigrationOptions) { const newSchemaNameStr = mOptions.literal(newSchemaName); return `ALTER SCHEMA ${schemaNameStr} RENAME TO ${newSchemaNameStr};`; }; + _rename.reverse = (schemaName, newSchemaName) => _rename(newSchemaName, schemaName); return _rename; diff --git a/src/operations/sequences.ts b/src/operations/sequences.ts index 14a94a76..4e8bbd12 100644 --- a/src/operations/sequences.ts +++ b/src/operations/sequences.ts @@ -21,35 +21,43 @@ export const parseSequenceOptions = ( if (type) { clauses.push(`AS ${applyType(type, typeShorthands).type}`); } + if (increment) { clauses.push(`INCREMENT BY ${increment}`); } + if (minvalue) { clauses.push(`MINVALUE ${minvalue}`); } else if (minvalue === null || minvalue === false) { clauses.push('NO MINVALUE'); } + if (maxvalue) { clauses.push(`MAXVALUE ${maxvalue}`); } else if (maxvalue === null || maxvalue === false) { clauses.push('NO MAXVALUE'); } + if (start) { clauses.push(`START WITH ${start}`); } + if (cache) { clauses.push(`CACHE ${cache}`); } + if (cycle) { clauses.push('CYCLE'); } else if (cycle === false) { clauses.push('NO CYCLE'); } + if (owner) { clauses.push(`OWNED BY ${owner}`); } else if (owner === null || owner === false) { clauses.push('OWNED BY NONE'); } + return clauses; }; @@ -61,6 +69,7 @@ export function dropSequence(mOptions: MigrationOptions) { const sequenceNameStr = mOptions.literal(sequenceName); return `DROP SEQUENCE${ifExistsStr} ${sequenceNameStr}${cascadeStr};`; }; + return _drop; } @@ -77,6 +86,7 @@ export function createSequence(mOptions: MigrationOptions) { return `CREATE${temporaryStr} SEQUENCE${ifNotExistsStr} ${sequenceNameStr} ${clausesStr};`; }; + _create.reverse = dropSequence(mOptions); return _create; } @@ -92,6 +102,7 @@ export function alterSequence(mOptions: MigrationOptions): AlterSequence { clauses.push(`RESTART WITH ${restart}`); } } + return `ALTER SEQUENCE ${mOptions.literal(sequenceName)} ${clauses.join('\n ')};`; }; @@ -103,6 +114,7 @@ export function renameSequence(mOptions: MigrationOptions) { const newSequenceNameStr = mOptions.literal(newSequenceName); return `ALTER SEQUENCE ${sequenceNameStr} RENAME TO ${newSequenceNameStr};`; }; + _rename.reverse = (sequenceName, newSequenceName) => _rename(newSequenceName, sequenceName); return _rename; diff --git a/src/operations/tables.ts b/src/operations/tables.ts index faae9475..2a6b69fe 100644 --- a/src/operations/tables.ts +++ b/src/operations/tables.ts @@ -56,12 +56,15 @@ const parseReferences = (options: ReferencesOptions, literal: Literal) => { if (match) { clauses.push(`MATCH ${match}`); } + if (onDelete) { clauses.push(`ON DELETE ${onDelete}`); } + if (onUpdate) { clauses.push(`ON UPDATE ${onUpdate}`); } + return clauses.join(' '); }; @@ -143,21 +146,27 @@ const parseColumns = ( if (collation) { constraints.push(`COLLATE ${collation}`); } + if (defaultValue !== undefined) { constraints.push(`DEFAULT ${escapeValue(defaultValue)}`); } + if (unique) { constraints.push('UNIQUE'); } + if (primaryKey) { constraints.push('PRIMARY KEY'); } + if (notNull) { constraints.push('NOT NULL'); } + if (check) { constraints.push(`CHECK (${check})`); } + if (references) { const name = referencesConstraintName || @@ -178,9 +187,11 @@ const parseColumns = ( ); } } + if (deferrable) { constraints.push(parseDeferrable(options)); } + if (sequenceGenerated) { const sequenceOptions = parseSequenceOptions( extendingTypeShorthands, @@ -190,6 +201,7 @@ const parseColumns = ( `GENERATED ${sequenceGenerated.precedence} AS IDENTITY${sequenceOptions ? ` (${sequenceOptions})` : ''}` ); } + if (expressionGenerated) { constraints.push(`GENERATED ALWAYS AS (${expressionGenerated}) STORED`); } @@ -236,6 +248,7 @@ const parseConstraints = ( constraints.push(`CONSTRAINT ${name} CHECK (${check})`); } } + if (unique) { const uniqueArray: Array = Array.isArray(unique) ? unique @@ -253,6 +266,7 @@ const parseConstraints = ( ); }); } + if (primaryKey) { const name = literal(optionName || `${tableName}_pkey`); const key = (Array.isArray(primaryKey) ? primaryKey : [primaryKey]) @@ -260,6 +274,7 @@ const parseConstraints = ( .join(', '); constraints.push(`CONSTRAINT ${name} PRIMARY KEY (${key})`); } + if (foreignKeys) { (Array.isArray(foreignKeys) ? foreignKeys : [foreignKeys]).forEach((fk) => { const { columns, referencesConstraintName, referencesConstraintComment } = @@ -286,6 +301,7 @@ const parseConstraints = ( } }); } + if (exclude) { const name = literal(optionName || `${tableName}_excl`); constraints.push(`CONSTRAINT ${name} EXCLUDE ${exclude}`); @@ -296,6 +312,7 @@ const parseConstraints = ( (constraint) => `${constraint} ${parseDeferrable(options)}` ); } + if (comment) { if (!optionName) throw new Error('cannot comment on unspecified constraints'); @@ -307,6 +324,7 @@ const parseConstraints = ( ) ); } + return { constraints, comments, @@ -349,6 +367,7 @@ export function dropTable(mOptions: MigrationOptions) { const tableNameStr = mOptions.literal(tableName); return `DROP TABLE${ifExistsStr} ${tableNameStr}${cascadeStr};`; }; + return _drop; } @@ -402,8 +421,10 @@ ${formatLines(tableDefinition)} if (typeof comment !== 'undefined') { comments.push(makeComment('TABLE', mOptions.literal(tableName), comment)); } + return `${createTableQuery}${comments.length > 0 ? `\n${comments.join('\n')}` : ''}`; }; + _create.reverse = dropTable(mOptions); return _create; } @@ -414,9 +435,11 @@ export function alterTable(mOptions: MigrationOptions) { if (options.levelSecurity) { alterDefinition.push(`${options.levelSecurity} ROW LEVEL SECURITY`); } + return `ALTER TABLE ${mOptions.literal(tableName)} ${formatLines(alterDefinition)};`; }; + return _alter; } @@ -426,10 +449,11 @@ export function dropColumns(mOptions: MigrationOptions) { const _drop: DropColumns = (tableName, columns, options = {}) => { const { ifExists, cascade } = options; if (typeof columns === 'string') { - columns = [columns]; // eslint-disable-line no-param-reassign + columns = [columns]; } else if (!Array.isArray(columns) && typeof columns === 'object') { - columns = Object.keys(columns); // eslint-disable-line no-param-reassign + columns = Object.keys(columns); } + const columnsStr = formatLines( columns.map(mOptions.literal), ` DROP ${ifExists ? ' IF EXISTS' : ''}`, @@ -438,6 +462,7 @@ export function dropColumns(mOptions: MigrationOptions) { return `ALTER TABLE ${mOptions.literal(tableName)} ${columnsStr};`; }; + return _drop; } @@ -456,6 +481,7 @@ export function addColumns(mOptions: MigrationOptions) { columnComments.length > 0 ? `\n${columnComments.join('\n')}` : ''; return `${alterTableQuery}${columnCommentsStr}`; }; + _add.reverse = dropColumns(mOptions); return _add; } @@ -481,17 +507,20 @@ export function alterColumn(mOptions: MigrationOptions): AlterColumn { } else if (defaultValue !== undefined) { actions.push(`SET DEFAULT ${escapeValue(defaultValue)}`); } + if (type) { const typeStr = applyTypeAdapters(type); const collationStr = collation ? ` COLLATE ${collation}` : ''; const usingStr = using ? ` USING ${using}` : ''; actions.push(`SET DATA TYPE ${typeStr}${collationStr}${usingStr}`); } + if (notNull) { actions.push('SET NOT NULL'); } else if (notNull === false || allowNull) { actions.push('DROP NOT NULL'); } + if (sequenceGenerated !== undefined) { if (!sequenceGenerated) { actions.push('DROP IDENTITY'); @@ -516,6 +545,7 @@ export function alterColumn(mOptions: MigrationOptions): AlterColumn { `ALTER TABLE ${mOptions.literal(tableName)}\n${columnsStr};` ); } + if (typeof comment !== 'undefined') { queries.push( makeComment( @@ -525,6 +555,7 @@ export function alterColumn(mOptions: MigrationOptions): AlterColumn { ) ); } + return queries.join('\n'); }; } @@ -535,6 +566,7 @@ export function renameTable(mOptions: MigrationOptions) { const newNameStr = mOptions.literal(newName); return `ALTER TABLE ${tableNameStr} RENAME TO ${newNameStr};`; }; + _rename.reverse = (tableName, newName) => _rename(newName, tableName); return _rename; } @@ -546,6 +578,7 @@ export function renameColumn(mOptions: MigrationOptions) { const newNameStr = mOptions.literal(newName); return `ALTER TABLE ${tableNameStr} RENAME ${columnNameStr} TO ${newNameStr};`; }; + _rename.reverse = (tableName, columnName, newName) => _rename(tableName, newName, columnName); return _rename; @@ -558,6 +591,7 @@ export function renameConstraint(mOptions: MigrationOptions) { const newNameStr = mOptions.literal(newName); return `ALTER TABLE ${tableNameStr} RENAME CONSTRAINT ${constraintNameStr} TO ${newNameStr};`; }; + _rename.reverse = (tableName, constraintName, newName) => _rename(tableName, newName, constraintName); return _rename; @@ -572,8 +606,10 @@ export function dropConstraint(mOptions: MigrationOptions) { const constraintNameStr = mOptions.literal(constraintName); return `ALTER TABLE ${tableNameStr} DROP CONSTRAINT${ifExistsStr} ${constraintNameStr}${cascadeStr};`; }; + return _drop; } + export function addConstraint(mOptions: MigrationOptions) { const _add: CreateConstraint = (tableName, constraintName, expression) => { const { constraints, comments } = @@ -596,13 +632,16 @@ export function addConstraint(mOptions: MigrationOptions) { ...comments, ].join('\n'); }; + _add.reverse = (tableName, constraintName, options) => { if (constraintName === null) { throw new Error( `Impossible to automatically infer down migration for addConstraint without naming constraint` ); } + return dropConstraint(mOptions)(tableName, constraintName, options); }; + return _add; } diff --git a/src/operations/triggers.ts b/src/operations/triggers.ts index 5b81d0aa..e9f155ba 100644 --- a/src/operations/triggers.ts +++ b/src/operations/triggers.ts @@ -21,6 +21,7 @@ export function dropTrigger(mOptions: MigrationOptions) { const tableNameStr = mOptions.literal(tableName); return `DROP TRIGGER${ifExistsStr} ${triggerNameStr} ON ${tableNameStr}${cascadeStr};`; }; + return _drop; } @@ -48,13 +49,16 @@ export function createTrigger(mOptions: MigrationOptions) { if (constraint) { when = 'AFTER'; } + if (!when) { throw new Error('"when" (BEFORE/AFTER/INSTEAD OF) have to be specified'); } + const isInsteadOf = /instead\s+of/i.test(when); if (isInsteadOf) { level = 'ROW'; } + if (definition) { functionName = functionName === undefined ? triggerName : functionName; } @@ -62,9 +66,11 @@ export function createTrigger(mOptions: MigrationOptions) { if (!functionName) { throw new Error("Can't determine function name"); } + if (isInsteadOf && condition) { throw new Error("INSTEAD OF trigger can't have condition specified"); } + if (!operations) { throw new Error( '"operation" (INSERT/UPDATE[ OF ...]/DELETE/TRUNCATE) have to be specified' @@ -128,6 +134,7 @@ export function renameTrigger(mOptions: MigrationOptions) { const newTriggerNameStr = mOptions.literal(newTriggerName); return `ALTER TRIGGER ${oldTriggerNameStr} ON ${tableNameStr} RENAME TO ${newTriggerNameStr};`; }; + _rename.reverse = (tableName, oldTriggerName, newTriggerName) => _rename(tableName, newTriggerName, oldTriggerName); return _rename; diff --git a/src/operations/types.ts b/src/operations/types.ts index 1daf5100..c8009186 100644 --- a/src/operations/types.ts +++ b/src/operations/types.ts @@ -32,6 +32,7 @@ export function dropType(mOptions: MigrationOptions) { const typeNameStr = mOptions.literal(typeName); return `DROP TYPE${ifExistsStr} ${typeNameStr}${cascadeStr};`; }; + return _drop; } @@ -42,6 +43,7 @@ export function createType(mOptions: MigrationOptions) { const typeNameStr = mOptions.literal(typeName); return `CREATE TYPE ${typeNameStr} AS ENUM (${optionsStr});`; } + const attributes = Object.entries(options) .map(([attributeName, attribute]) => { const typeStr = applyType(attribute, mOptions.typeShorthands).type; @@ -50,6 +52,7 @@ export function createType(mOptions: MigrationOptions) { .join(',\n'); return `CREATE TYPE ${mOptions.literal(typeName)} AS (\n${attributes}\n);`; }; + _create.reverse = dropType(mOptions); return _create; } @@ -65,6 +68,7 @@ export function dropTypeAttribute(mOptions: MigrationOptions) { const attributeNameStr = mOptions.literal(attributeName); return `ALTER TYPE ${typeNameStr} DROP ATTRIBUTE ${attributeNameStr}${ifExistsStr};`; }; + return _drop; } @@ -80,6 +84,7 @@ export function addTypeAttribute(mOptions: MigrationOptions) { return `ALTER TYPE ${typeNameStr} ADD ATTRIBUTE ${attributeNameStr} ${typeStr};`; }; + _alterAttributeAdd.reverse = dropTypeAttribute(mOptions); return _alterAttributeAdd; } @@ -101,6 +106,7 @@ export function addTypeValue(mOptions: MigrationOptions) { if (before && after) { throw new Error('"before" and "after" can\'t be specified together'); } + const beforeStr = before ? ` BEFORE ${escapeValue(before)}` : ''; const afterStr = after ? ` AFTER ${escapeValue(after)}` : ''; const ifNotExistsStr = ifNotExists ? ' IF NOT EXISTS' : ''; @@ -109,6 +115,7 @@ export function addTypeValue(mOptions: MigrationOptions) { return `ALTER TYPE ${typeNameStr} ADD VALUE${ifNotExistsStr} ${valueStr}${beforeStr}${afterStr};`; }; + return _add; } @@ -118,6 +125,7 @@ export function renameType(mOptions: MigrationOptions) { const newTypeNameStr = mOptions.literal(newTypeName); return `ALTER TYPE ${typeNameStr} RENAME TO ${newTypeNameStr};`; }; + _rename.reverse = (typeName, newTypeName) => _rename(newTypeName, typeName); return _rename; } @@ -133,6 +141,7 @@ export function renameTypeAttribute(mOptions: MigrationOptions) { const newAttributeNameStr = mOptions.literal(newAttributeName); return `ALTER TYPE ${typeNameStr} RENAME ATTRIBUTE ${attributeNameStr} TO ${newAttributeNameStr};`; }; + _rename.reverse = (typeName, attributeName, newAttributeName) => _rename(typeName, newAttributeName, attributeName); return _rename; @@ -145,6 +154,7 @@ export function renameTypeValue(mOptions: MigrationOptions) { const typeNameStr = mOptions.literal(typeName); return `ALTER TYPE ${typeNameStr} RENAME VALUE ${valueStr} TO ${newValueStr};`; }; + _rename.reverse = (typeName, value, newValue) => _rename(typeName, newValue, value); return _rename; diff --git a/src/operations/views.ts b/src/operations/views.ts index ba6e201a..ac12c8f2 100644 --- a/src/operations/views.ts +++ b/src/operations/views.ts @@ -34,6 +34,7 @@ export function dropView(mOptions: MigrationOptions) { const viewNameStr = mOptions.literal(viewName); return `DROP VIEW${ifExistsStr} ${viewNameStr}${cascadeStr};`; }; + return _drop; } @@ -66,6 +67,7 @@ export function createView(mOptions: MigrationOptions) { return `CREATE${replaceStr}${temporaryStr}${recursiveStr} VIEW ${viewNameStr}${columnStr}${withOptionsStr} AS ${definition}${checkOptionStr};`; }; + _create.reverse = dropView(mOptions); return _create; } @@ -82,6 +84,7 @@ export function alterView(mOptions: MigrationOptions) { ); } } + const clauses = []; const withOptions = Object.keys(options) .filter((key) => options[key] !== null) @@ -90,6 +93,7 @@ export function alterView(mOptions: MigrationOptions) { if (withOptions) { clauses.push(`SET (${withOptions})`); } + const resetOptions = Object.keys(options) .filter((key) => options[key] === null) .join(', '); @@ -101,6 +105,7 @@ export function alterView(mOptions: MigrationOptions) { .map((clause) => `ALTER VIEW ${mOptions.literal(viewName)} ${clause};`) .join('\n'); }; + return _alter; } @@ -113,6 +118,7 @@ export function alterViewColumn(mOptions: MigrationOptions) { } else if (defaultValue !== undefined) { actions.push(`SET DEFAULT ${escapeValue(defaultValue)}`); } + const viewNameStr = mOptions.literal(viewName); const columnNameStr = mOptions.literal(columnName); return actions @@ -122,6 +128,7 @@ export function alterViewColumn(mOptions: MigrationOptions) { ) .join('\n'); }; + return _alter; } @@ -131,6 +138,7 @@ export function renameView(mOptions: MigrationOptions) { const newViewNameStr = mOptions.literal(newViewName); return `ALTER VIEW ${viewNameStr} RENAME TO ${newViewNameStr};`; }; + _rename.reverse = (viewName, newViewName) => _rename(newViewName, viewName); return _rename; } diff --git a/src/operations/viewsMaterialized.ts b/src/operations/viewsMaterialized.ts index e42c8513..2da36a79 100644 --- a/src/operations/viewsMaterialized.ts +++ b/src/operations/viewsMaterialized.ts @@ -40,6 +40,7 @@ export function dropMaterializedView(mOptions: MigrationOptions) { const viewNameStr = mOptions.literal(viewName); return `DROP MATERIALIZED VIEW${ifExistsStr} ${viewNameStr}${cascadeStr};`; }; + return _drop; } @@ -70,6 +71,7 @@ export function createMaterializedView(mOptions: MigrationOptions) { return `CREATE MATERIALIZED VIEW${ifNotExistsStr} ${viewNameStr}${columnsStr}${withOptionsStr}${tablespaceStr} AS ${definition}${dataStr};`; }; + _create.reverse = dropMaterializedView(mOptions); return _create; } @@ -85,9 +87,11 @@ export function alterMaterializedView(mOptions: MigrationOptions) { clauses.push(`SET WITHOUT CLUSTER`); } } + if (extension) { clauses.push(`DEPENDS ON EXTENSION ${mOptions.literal(extension)}`); } + const withOptions = Object.keys(storageParameters) .filter((key) => storageParameters[key] !== null) .map(storageParameterStr(storageParameters)) @@ -95,16 +99,19 @@ export function alterMaterializedView(mOptions: MigrationOptions) { if (withOptions) { clauses.push(`SET (${withOptions})`); } + const resetOptions = Object.keys(storageParameters) .filter((key) => storageParameters[key] === null) .join(', '); if (resetOptions) { clauses.push(`RESET (${resetOptions})`); } + const clausesStr = formatLines(clauses); const viewNameStr = mOptions.literal(viewName); return `ALTER MATERIALIZED VIEW ${viewNameStr}\n${clausesStr};`; }; + return _alter; } @@ -114,6 +121,7 @@ export function renameMaterializedView(mOptions: MigrationOptions) { const newViewNameStr = mOptions.literal(newViewName); return `ALTER MATERIALIZED VIEW ${viewNameStr} RENAME TO ${newViewNameStr};`; }; + _rename.reverse = (viewName, newViewName) => _rename(newViewName, viewName); return _rename; } @@ -129,6 +137,7 @@ export function renameMaterializedViewColumn(mOptions: MigrationOptions) { const newColumnNameStr = mOptions.literal(newColumnName); return `ALTER MATERIALIZED VIEW ${viewNameStr} RENAME COLUMN ${columnNameStr} TO ${newColumnNameStr};`; }; + _rename.reverse = (viewName, columnName, newColumnName) => _rename(viewName, newColumnName, columnName); return _rename; @@ -142,6 +151,7 @@ export function refreshMaterializedView(mOptions: MigrationOptions) { const viewNameStr = mOptions.literal(viewName); return `REFRESH MATERIALIZED VIEW${concurrentlyStr} ${viewNameStr}${dataStr};`; }; + _refresh.reverse = _refresh; return _refresh; } diff --git a/src/runner.ts b/src/runner.ts index 5a91edf8..1fc34bad 100644 --- a/src/runner.ts +++ b/src/runner.ts @@ -35,8 +35,7 @@ const loadMigrations = async ( const actions: MigrationBuilderActions = path.extname(filePath) === '.sql' ? await migrateSqlFile(filePath) - : // eslint-disable-next-line global-require,import/no-dynamic-require,security/detect-non-literal-require - require(path.relative(__dirname, filePath)); + : require(path.relative(__dirname, filePath)); shorthands = { ...shorthands, ...actions.shorthands }; return new Migration( db, @@ -167,8 +166,10 @@ const getMigrationsToRun = ( `Definitions of migrations ${deletedMigrationsStr} have been deleted.` ); } + return toRun as Migration[]; } + const upMigrations = migrations.filter( ({ name }) => runNames.indexOf(name) < 0 && (!options.file || options.file === name) @@ -210,6 +211,7 @@ const getLogger = ({ log, logger, verbose }: RunnerOption): Logger => { } else if (typeof log === 'function') { loggerObject = { debug: log, info: log, warn: log, error: log }; } + return verbose ? loggerObject : { @@ -243,10 +245,12 @@ export default async (options: RunnerOption): Promise => { ) ); } + await db.query( `SET search_path TO ${schemas.map((s) => `"${s}"`).join(', ')}` ); } + if (options.migrationsSchema && options.createMigrationsSchema) { await db.query( `CREATE SCHEMA IF NOT EXISTS "${options.migrationsSchema}"` @@ -307,6 +311,7 @@ export default async (options: RunnerOption): Promise => { if (!options.noLock) { await unlock(db).catch((error) => logger.warn(error.message)); } + db.close(); } } diff --git a/src/sqlMigration.ts b/src/sqlMigration.ts index 83161134..fdb9b3d7 100644 --- a/src/sqlMigration.ts +++ b/src/sqlMigration.ts @@ -4,7 +4,7 @@ import { MigrationBuilderActions } from './types'; const { readFile } = fs.promises; const createMigrationCommentRegex = (direction: 'up' | 'down') => - new RegExp(`^\\s*--[\\s-]*${direction}\\s+migration`, 'im'); // eslint-disable-line security/detect-non-literal-regexp + new RegExp(`^\\s*--[\\s-]*${direction}\\s+migration`, 'im'); export const getActions = (content: string): MigrationBuilderActions => { const upMigrationCommentRegex = createMigrationCommentRegex('up'); diff --git a/src/utils.ts b/src/utils.ts index 30e6d960..d886f31b 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -21,6 +21,7 @@ export const createSchemalize = ( const { schema, name } = v; return (schema ? `${transform(schema)}.` : '') + transform(name); } + return transform(v); }; }; @@ -29,7 +30,6 @@ export const createSchemalize = ( export class StringIdGenerator { private ids: number[] = [0]; - // eslint-disable-next-line no-useless-constructor constructor(private readonly chars = 'abcdefghijklmnopqrstuvwxyz') {} next() { @@ -44,8 +44,10 @@ export class StringIdGenerator { if (this.ids[i] < this.chars.length) { return; } + this.ids[i] = 0; } + this.ids.unshift(0); } } @@ -60,9 +62,11 @@ export const escapeValue = (val: Value): string | number => { if (val === null) { return 'NULL'; } + if (typeof val === 'boolean') { return val.toString(); } + if (typeof val === 'string') { let dollars: string; const ids = new StringIdGenerator(); @@ -71,18 +75,23 @@ export const escapeValue = (val: Value): string | number => { index = ids.next(); dollars = `$pg${index}$`; } while (val.indexOf(dollars) >= 0); + return `${dollars}${val}${dollars}`; } + if (typeof val === 'number') { return val; } + if (Array.isArray(val)) { const arrayStr = val.map(escapeValue).join(',').replace(/ARRAY/g, ''); return `ARRAY[${arrayStr}]`; } + if (isPgLiteral(val)) { return val.value; } + return ''; }; @@ -91,9 +100,7 @@ export const createTransformer = Object.keys(d || {}).reduce((str: string, p) => { const v = d?.[p]; return str.replace( - // eslint-disable-next-line security/detect-non-literal-regexp new RegExp(`{${p}}`, 'g'), - // eslint-disable-next-line no-nested-ternary v === undefined ? '' : typeof v === 'string' || @@ -135,7 +142,6 @@ export const applyTypeAdapters = (type: string): string => const toType = (type: string | ColumnDefinition): ColumnDefinition => typeof type === 'string' ? { type } : type; -// eslint-disable-next-line @typescript-eslint/no-unused-vars const removeType = ({ type, ...rest }: Partial) => rest; export const applyType = ( @@ -162,6 +168,7 @@ export const applyType = ( types.push(ext.type); } } + return { ...ext, ...options, @@ -180,15 +187,19 @@ const formatParam = (mOptions: MigrationOptions) => (param: FunctionParam) => { if (mode) { options.push(mode); } + if (name) { options.push(mOptions.literal(name)); } + if (type) { options.push(type); } + if (defaultValue) { options.push(`DEFAULT ${escapeValue(defaultValue)}`); } + return options.join(' '); }; diff --git a/templates/migration-template.js b/templates/migration-template.js index fbce4d40..b8825d4a 100644 --- a/templates/migration-template.js +++ b/templates/migration-template.js @@ -1,5 +1,3 @@ -/* eslint-disable camelcase */ - exports.shorthands = undefined; exports.up = pgm => {}; diff --git a/templates/migration-template.ts b/templates/migration-template.ts index 247fbed8..2c358095 100644 --- a/templates/migration-template.ts +++ b/templates/migration-template.ts @@ -1,4 +1,3 @@ -/* eslint-disable @typescript-eslint/naming-convention */ import { MigrationBuilder, ColumnDefinitions } from 'node-pg-migrate'; export const shorthands: ColumnDefinitions | undefined = undefined; diff --git a/test/db-test.ts b/test/db-test.ts index 0b021f84..6e770491 100644 --- a/test/db-test.ts +++ b/test/db-test.ts @@ -14,8 +14,6 @@ class Client { /* eslint-enable */ } -/* eslint-disable no-unused-expressions */ - const pgMock = { Client, }; diff --git a/test/migration-test.ts b/test/migration-test.ts index 510662a2..7ddfc7c4 100644 --- a/test/migration-test.ts +++ b/test/migration-test.ts @@ -1,4 +1,3 @@ -/* eslint-disable no-unused-expressions */ import { expect } from 'chai'; import sinon, { SinonSpy } from 'sinon'; import { DBConnection } from '../src/db'; @@ -9,8 +8,8 @@ const callbackMigration = '1414549381268_names.js'; const promiseMigration = '1414549381268_names_promise.js'; const migrationsTable = 'pgmigrations'; -const actionsCallback = require(`./${callbackMigration}`); // eslint-disable-line import/no-dynamic-require,security/detect-non-literal-require,@typescript-eslint/no-var-requires -const actionsPromise = require(`./${promiseMigration}`); // eslint-disable-line import/no-dynamic-require,security/detect-non-literal-require,@typescript-eslint/no-var-requires +const actionsCallback = require(`./${callbackMigration}`); +const actionsPromise = require(`./${promiseMigration}`); describe('lib/migration', () => { const dbMock = {} as DBConnection; @@ -122,6 +121,7 @@ describe('lib/migration', () => { } catch (err) { error = err; } + // expecting outside the catch block ensures that the test will fail if the // an exception is not caught expect(error.toString()).to.include( diff --git a/test/migrations/001_noop.js b/test/migrations/001_noop.js index e2e22bbd..fcb02f0c 100644 --- a/test/migrations/001_noop.js +++ b/test/migrations/001_noop.js @@ -1,2 +1 @@ -// eslint-disable-next-line @typescript-eslint/no-empty-function exports.up = () => {}; diff --git a/test/migrations/005_table_test.js b/test/migrations/005_table_test.js index 530338c2..7ccfe504 100644 --- a/test/migrations/005_table_test.js +++ b/test/migrations/005_table_test.js @@ -15,22 +15,24 @@ exports.up = async (pgm) => { await pgm.db.query('SAVEPOINT sp_reference;'); try { await pgm.db.query('INSERT INTO t2(id2) VALUES (1);'); - throw 1; // eslint-disable-line no-throw-literal + throw 1; } catch (err) { if (err === 1) { throw new Error('Missing reference clause'); } + await pgm.db.query('ROLLBACK TO SAVEPOINT sp_reference;'); } await pgm.db.query('SAVEPOINT sp_not_null;'); try { await pgm.db.query('INSERT INTO t1(created) VALUES (current_timestamp); '); - throw 1; // eslint-disable-line no-throw-literal + throw 1; } catch (err) { if (err === 1) { throw new Error('Missing not null clause'); } + await pgm.db.query('ROLLBACK TO SAVEPOINT sp_not_null;'); } diff --git a/test/migrations/010_column_test.js b/test/migrations/010_column_test.js index 088f3b2e..a9896e7c 100644 --- a/test/migrations/010_column_test.js +++ b/test/migrations/010_column_test.js @@ -2,11 +2,12 @@ exports.up = async (pgm) => { await pgm.db.query('SAVEPOINT sp_check;'); try { await pgm.db.query('INSERT INTO t1(nr) VALUES (1);'); - throw 1; // eslint-disable-line no-throw-literal + throw 1; } catch (err) { if (err === 1) { throw new Error('Missing check clause'); } + await pgm.db.query('ROLLBACK TO SAVEPOINT sp_check;'); } @@ -15,11 +16,12 @@ exports.up = async (pgm) => { await pgm.db.query('SAVEPOINT sp_unique;'); try { await pgm.db.query('INSERT INTO t1(nr) VALUES (20);'); - throw 1; // eslint-disable-line no-throw-literal + throw 1; } catch (err) { if (err === 1) { throw new Error('Missing not unique clause'); } + await pgm.db.query('ROLLBACK TO SAVEPOINT sp_unique;'); } }; diff --git a/test/migrations/013_column_alter_test.js b/test/migrations/013_column_alter_test.js index 28c51903..d9b53b20 100644 --- a/test/migrations/013_column_alter_test.js +++ b/test/migrations/013_column_alter_test.js @@ -2,11 +2,12 @@ exports.up = async (pgm) => { await pgm.db.query('SAVEPOINT sp_smallint;'); try { await pgm.db.query('INSERT INTO t1(nmbr) VALUES (2147483647);'); - throw 1; // eslint-disable-line no-throw-literal + throw 1; } catch (err) { if (err === 1) { throw new Error('Type not updated'); } + await pgm.db.query('ROLLBACK TO SAVEPOINT sp_smallint;'); } }; diff --git a/test/migrations/015_add_constraint_test.js b/test/migrations/015_add_constraint_test.js index c475bde2..4c1d7249 100644 --- a/test/migrations/015_add_constraint_test.js +++ b/test/migrations/015_add_constraint_test.js @@ -2,11 +2,12 @@ exports.up = async (pgm) => { await pgm.db.query('SAVEPOINT sp_check;'); try { await pgm.db.query('INSERT INTO t1(nmbr) VALUES (30);'); - throw 1; // eslint-disable-line no-throw-literal + throw 1; } catch (err) { if (err === 1) { throw new Error('Missing check clause'); } + await pgm.db.query('ROLLBACK TO SAVEPOINT sp_check;'); } diff --git a/test/migrations/026_set_type_attribute_test.js b/test/migrations/026_set_type_attribute_test.js index 7af6462d..c6d7188f 100644 --- a/test/migrations/026_set_type_attribute_test.js +++ b/test/migrations/026_set_type_attribute_test.js @@ -2,11 +2,12 @@ exports.up = async (pgm) => { await pgm.db.query('SAVEPOINT sp_smallint;'); try { await pgm.db.query("select (ROW(2147483647, 'x')::obj).id;"); - throw 1; // eslint-disable-line no-throw-literal + throw 1; } catch (err) { if (err === 1) { throw new Error('Type not updated'); } + await pgm.db.query('ROLLBACK TO SAVEPOINT sp_smallint;'); } }; diff --git a/test/migrations/032_drop_type_attribute_test.js b/test/migrations/032_drop_type_attribute_test.js index cfc90fec..5d63ba29 100644 --- a/test/migrations/032_drop_type_attribute_test.js +++ b/test/migrations/032_drop_type_attribute_test.js @@ -2,11 +2,12 @@ exports.up = async (pgm) => { await pgm.db.query('SAVEPOINT sp_attr;'); try { await pgm.db.query("select (ROW(1, 'x')::obj).str;"); - throw 1; // eslint-disable-line no-throw-literal + throw 1; } catch (err) { if (err === 1) { throw new Error('Attribute was not removed'); } + await pgm.db.query('ROLLBACK TO SAVEPOINT sp_attr;'); } }; diff --git a/test/migrations/034_drop_type_test.js b/test/migrations/034_drop_type_test.js index 5d2d548c..b5839e66 100644 --- a/test/migrations/034_drop_type_test.js +++ b/test/migrations/034_drop_type_test.js @@ -2,11 +2,12 @@ exports.up = async (pgm) => { await pgm.db.query('SAVEPOINT sp_drop;'); try { await pgm.db.query('CREATE TEMPORARY TABLE t_list_3 (l list_for_drop);'); - throw 1; // eslint-disable-line no-throw-literal + throw 1; } catch (err) { if (err === 1) { throw new Error('Type was not removed'); } + await pgm.db.query('ROLLBACK TO SAVEPOINT sp_drop;'); } }; diff --git a/test/migrations/047_domain_check.js b/test/migrations/047_domain_check.js index 77036138..e3697a6d 100644 --- a/test/migrations/047_domain_check.js +++ b/test/migrations/047_domain_check.js @@ -2,11 +2,12 @@ exports.up = async (pgm) => { await pgm.db.query('SAVEPOINT sp_check;'); try { await pgm.db.query('INSERT INTO td (d) VALUES (11);'); - throw 1; // eslint-disable-line no-throw-literal + throw 1; } catch (err) { if (err === 1) { throw new Error('Check on domain was not set'); } + await pgm.db.query('ROLLBACK TO SAVEPOINT sp_check;'); } }; diff --git a/test/migrations/058_policy_test.js b/test/migrations/058_policy_test.js index 35559a59..bd7a4403 100644 --- a/test/migrations/058_policy_test.js +++ b/test/migrations/058_policy_test.js @@ -9,11 +9,13 @@ exports.up = async (pgm) => { if (adminLength !== 3) { throw new Error('Policy is not enforced'); } + await pgm.db.query('set role alice;'); const { length: aliceLength } = await pgm.db.select('SELECT * FROM tp;'); if (aliceLength !== 1) { throw new Error('Policy is not enforced'); } + await pgm.db.query('reset role;'); }; diff --git a/test/migrations/080_create_table_generated_column_take_2.js b/test/migrations/080_create_table_generated_column_take_2.js index ca96a407..632a519b 100644 --- a/test/migrations/080_create_table_generated_column_take_2.js +++ b/test/migrations/080_create_table_generated_column_take_2.js @@ -25,6 +25,7 @@ exports.up = async (pgm) => { }); pgm.sql('INSERT INTO "t_sequenceGenerated" DEFAULT VALUES'); } + if (isSupportedExpressionGeneratedVersion(major)) { pgm.createTable('t_expressionGenerated', { id: 'id', @@ -43,6 +44,7 @@ exports.down = async (pgm) => { if (isSupportedSequenceGeneratedVersion(major)) { pgm.dropTable('t_sequenceGenerated'); } + if (isSupportedExpressionGeneratedVersion(major)) { pgm.dropTable('t_expressionGenerated'); } diff --git a/test/migrations/081_temporary_table.js b/test/migrations/081_temporary_table.js index 87e30ffe..686252e4 100644 --- a/test/migrations/081_temporary_table.js +++ b/test/migrations/081_temporary_table.js @@ -8,11 +8,12 @@ exports.down = async (pgm) => { await pgm.db.query('SAVEPOINT sp_temp_table;'); try { await pgm.db.query('DROP TABLE "tmp"'); - throw 1; // eslint-disable-line no-throw-literal + throw 1; } catch (err) { if (err === 1) { throw new Error('Missing TEMPORARY clause'); } + await pgm.db.query('ROLLBACK TO SAVEPOINT sp_temp_table;'); } }; diff --git a/test/sqlMigration-test.ts b/test/sqlMigration-test.ts index faf4fa07..d22759db 100644 --- a/test/sqlMigration-test.ts +++ b/test/sqlMigration-test.ts @@ -2,8 +2,6 @@ import { expect } from 'chai'; import sinon from 'sinon'; import { getActions } from '../src/sqlMigration'; -/* eslint-disable no-unused-expressions */ - describe('lib/sqlMigration', () => { describe('getActions', () => { it('without comments', () => { diff --git a/test/ts/customRunner.ts b/test/ts/customRunner.ts index 07ed5916..62a9ae14 100644 --- a/test/ts/customRunner.ts +++ b/test/ts/customRunner.ts @@ -12,8 +12,6 @@ type Options = | ({ databaseUrl: string } & TestOptions) | ({ dbClient: Client } & TestOptions); -/* eslint-disable no-console */ -// eslint-disable-next-line import/prefer-default-export export const run = async (options: Options): Promise => { const opts: Omit & Options = { migrationsTable: 'migrations', @@ -33,6 +31,7 @@ export const run = async (options: Options): Promise => { ); return false; } + console.log('Up success'); console.log(upResult); const downResult = await runner({ @@ -45,6 +44,7 @@ export const run = async (options: Options): Promise => { ); return false; } + console.log('Down success'); console.log(downResult); return true; diff --git a/tsconfig.lint.json b/tsconfig.lint.json new file mode 100644 index 00000000..9829d894 --- /dev/null +++ b/tsconfig.lint.json @@ -0,0 +1,16 @@ +{ + "compilerOptions": { + "target": "ES2017", + "moduleResolution": "Node", + "module": "CommonJS", + "strict": true, + "noEmit": true, + "lib": ["ES2019"], + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "noImplicitAny": true, + "noUnusedLocals": true, + "noImplicitOverride": true, + "allowJs": true + } +}