diff --git a/.eslintrc.json b/.eslintrc.json deleted file mode 100644 index adb96ba..0000000 --- a/.eslintrc.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "env": { - "mocha": true, - "node": true, - "commonjs": true, - "es2021": true - }, - "extends": "eslint:recommended", - "rules": { - "indent": [ - "error", - 2, - { - "ArrayExpression": "first", - "CallExpression": {"arguments": "first"}, - "FunctionDeclaration": {"body": 1, "parameters": "first"}, - "MemberExpression": 0, - "ObjectExpression": 1 - } - ], - "linebreak-style": [ - "error", - "unix" - ], - "no-unused-vars": [ - "error", - { "vars": "all", "args": "after-used", "ignoreRestSiblings": false } - ], - "quotes": [ - "error", - "single" - ], - "semi": [ - "error", - "always" - ] - } -} diff --git a/.github/workflows/node.js.yml b/.github/workflows/node.js.yml index c304495..2587723 100644 --- a/.github/workflows/node.js.yml +++ b/.github/workflows/node.js.yml @@ -1,37 +1,47 @@ -# This workflow will do a clean installation of node dependencies, cache/restore them, build the source code and run tests across different versions of node -# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-nodejs - -name: Node.js CI +name: CI on: - push: - branches: [ "master" ] pull_request: - branches: [ "master" ] -env: - MYSQL_PASSWORD: rootpassword +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true jobs: - build: - + lint: + name: Lint runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version-file: .nvmrc + cache: npm + - run: npm ci + - run: npm run eslint - strategy: - matrix: - node-version: [20.x] - # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ - + test: + name: Tests + runs-on: ubuntu-latest + services: + mysql: + image: mysql:8 + env: + MYSQL_ALLOW_EMPTY_PASSWORD: "yes" + MYSQL_DATABASE: test + ports: + - 3306:3306 + options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3 + redis: + image: redis + ports: + - 6379:6379 + options: --health-cmd="redis-cli ping" --health-interval=10s --health-timeout=5s --health-retries=3 steps: - - uses: actions/checkout@v3 - - uses: mirromutth/mysql-action@v1.1 - with: - mysql root password: 'rootpassword' - - uses: supercharge/redis-github-action@1.7.0 - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v3 - with: - node-version: ${{ matrix.node-version }} - cache: 'npm' - - run: npm ci - - run: npm test + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version-file: .nvmrc + cache: npm + - run: npm ci + - run: npm test diff --git a/.husky/pre-commit b/.husky/pre-commit new file mode 100644 index 0000000..2312dc5 --- /dev/null +++ b/.husky/pre-commit @@ -0,0 +1 @@ +npx lint-staged diff --git a/cli/create.js b/cli/create.js index 5f7d57c..131531d 100644 --- a/cli/create.js +++ b/cli/create.js @@ -23,7 +23,7 @@ const renameUnderscoreFiles = async (dir) => { await fse.move(srcPath, destPath, { overwrite: true }); } } -} +}; // replace all occurrences of a regexp in files in a directory const replaceInDirectory = async (dir, replacements) => { @@ -64,10 +64,10 @@ module.exports = async function (argv) { const directory = './' + args[1]; const model = args.length === 3 ? args[2] : 'tailwind'; - await fs.mkdir(directory) + await fs.mkdir(directory); // recursive copy from skel to project directory - await fse.copy(path.join(__dirname, '../skel', model), directory, { overwrite: false }) + await fse.copy(path.join(__dirname, '../skel', model), directory, { overwrite: false }); await renameUnderscoreFiles(directory); diff --git a/cli/db.js b/cli/db.js index 6cb29b9..fee9632 100644 --- a/cli/db.js +++ b/cli/db.js @@ -10,7 +10,7 @@ const migrations = require('../src/db/migrations'); const verbs = { // igo db migrate - migrate: async (args) => { + migrate: async (_args) => { for (const database of config.databases) { const db = dbs[database]; db.config.debugsql = false; @@ -22,7 +22,7 @@ const verbs = { }, // igo db migrations - migrations: async (args) => { + migrations: async (_args) => { for (const database of config.databases) { const db = dbs[database]; @@ -90,7 +90,7 @@ const verbs = { }); }, - reverse: async (args) => { + reverse: async (_args) => { const db = dbs.main; const tables = await db.query('show tables'); for (const table of tables) { @@ -143,7 +143,7 @@ module.exports = async (argv) => { await dbs.init(); if (args.length > 1 && verbs[args[1]]) { - await verbs[args[1]](args) + await verbs[args[1]](args); console.log('Done.'); process.exit(0); } else { diff --git a/cli/i18n.js b/cli/i18n.js index 4b1a5a2..b66ee65 100644 --- a/cli/i18n.js +++ b/cli/i18n.js @@ -7,7 +7,7 @@ const csvWriter = require('csv-write-stream'); const config = require('../src/config'); const readJson = async(path) => { - const data = await fs.readFile(path) + const data = await fs.readFile(path); return JSON.parse(data); }; @@ -63,7 +63,7 @@ const writeTranslationFiles = async (translations) => { const verbs = { // igo i18n update - update: async function(args) { + update: async function(_args) { if (!config.i18n.spreadsheet_id) { return console.error('Missing config.i18n.spreadsheet_id'); } @@ -86,11 +86,11 @@ const verbs = { const translations = parseJson(json); await writeTranslationFiles(translations); }); - }) + }); }, // igo i18n csv - csv: async function(args) { + csv: async function(_args) { const langs = config.i18n.whitelist; const translations = []; @@ -138,7 +138,7 @@ module.exports = function(argv) { config.init(); if (args.length > 1 && verbs[args[1]]) { - verbs[args[1]](args) + verbs[args[1]](args); // process.exit(0); } else { console.error('ERROR: Wrong options'); diff --git a/eslint.config.js b/eslint.config.js new file mode 100644 index 0000000..8450d4a --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,37 @@ +const js = require('@eslint/js'); +const globals = require('globals'); + +module.exports = [ + js.configs.recommended, + { + languageOptions: { + ecmaVersion: 2021, + sourceType: 'commonjs', + globals: { + ...globals.node, + ...globals.mocha, + }, + }, + rules: { + 'indent': ['error', 2, { + 'ArrayExpression': 'first', + 'CallExpression': { 'arguments': 'first' }, + 'FunctionDeclaration': { 'body': 1, 'parameters': 'first' }, + 'MemberExpression': 0, + 'ObjectExpression': 1, + }], + 'linebreak-style': ['error', 'unix'], + 'no-unused-vars': ['error', { + 'vars': 'all', + 'args': 'after-used', + 'ignoreRestSiblings': false, + 'argsIgnorePattern': '^_', + 'varsIgnorePattern': '^_', + 'destructuredArrayIgnorePattern': '^_', + 'caughtErrorsIgnorePattern': '^_', + }], + 'quotes': ['error', 'single'], + 'semi': ['error', 'always'], + }, + }, +]; diff --git a/package-lock.json b/package-lock.json index 60f890f..459ffc9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -52,6 +52,12 @@ }, "bin": { "igo": "cli/igo.js" + }, + "devDependencies": { + "@eslint/js": "^9.39.4", + "globals": "^17.4.0", + "husky": "^9.1.7", + "lint-staged": "^16.4.0" } }, "node_modules/@babel/code-frame": { @@ -255,6 +261,18 @@ } } }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/@eslint/eslintrc/node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -262,9 +280,10 @@ "license": "MIT" }, "node_modules/@eslint/js": { - "version": "9.39.1", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.1.tgz", - "integrity": "sha512-S26Stp4zCy88tH94QbBv3XCuzRQiZ9yXofEILmglYTh/Ug/a9/umqvgFtYBAo3Lp0nsI/5/qH1CCrbdK3AP1Tw==", + "version": "9.39.4", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.4.tgz", + "integrity": "sha512-nE7DEIchvtiFTwBw4Lfbu59PG+kCofhjsKaCWzxTpt4lfRjRMqG6uMBzKXuEcyXhOHoUp9riAm7/aWYGhXZ9cw==", + "dev": true, "license": "MIT", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1544,6 +1563,22 @@ "node": ">=6" } }, + "node_modules/ansi-escapes": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.3.0.tgz", + "integrity": "sha512-BvU8nYgGQBxcmMuEeUEmNTvrMVjJNSH7RgW24vXexN4Ven6qCvy4TntnvlnwnMLTVlcRQQdbRY8NKnaIoeWDNg==", + "dev": true, + "license": "MIT", + "dependencies": { + "environment": "^1.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/ansi-html-community": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", @@ -2089,6 +2124,56 @@ "node": ">= 10.0" } }, + "node_modules/cli-cursor": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz", + "integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==", + "dev": true, + "license": "MIT", + "dependencies": { + "restore-cursor": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-truncate": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-5.2.0.tgz", + "integrity": "sha512-xRwvIOMGrfOAnM1JYtqQImuaNtDEv9v6oIYAs4LIHwTiKee8uwvIi363igssOC0O5U04i4AlENs79LQLu9tEMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "slice-ansi": "^8.0.0", + "string-width": "^8.2.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-truncate/node_modules/string-width": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-8.2.0.tgz", + "integrity": "sha512-6hJPQ8N0V0P3SNmP6h2J99RLuzrWz2gvT7VnK5tKvrNqJoyS9W4/Fb8mo31UiPvy00z7DQXkP2hnKBVav76thw==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-east-asian-width": "^1.5.0", + "strip-ansi": "^7.1.2" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/cliui": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", @@ -3115,6 +3200,19 @@ "node": ">=4" } }, + "node_modules/environment": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/environment/-/environment-1.1.0.tgz", + "integrity": "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/error-ex": { "version": "1.3.4", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz", @@ -3286,6 +3384,18 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/eslint/node_modules/@eslint/js": { + "version": "9.39.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.1.tgz", + "integrity": "sha512-S26Stp4zCy88tH94QbBv3XCuzRQiZ9yXofEILmglYTh/Ug/a9/umqvgFtYBAo3Lp0nsI/5/qH1CCrbdK3AP1Tw==", + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + } + }, "node_modules/eslint/node_modules/debug": { "version": "4.4.3", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", @@ -3746,6 +3856,19 @@ "node": "6.* || 8.* || >= 10.*" } }, + "node_modules/get-east-asian-width": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.5.0.tgz", + "integrity": "sha512-CQ+bEO+Tva/qlmw24dCejulK5pMzVnUOFOijVogd3KQs07HnRIgp8TGipvCCRT06xeYEbpbgwaCxglFyiuIcmA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/get-intrinsic": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", @@ -3862,9 +3985,10 @@ } }, "node_modules/globals": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", - "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "version": "17.4.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-17.4.0.tgz", + "integrity": "sha512-hjrNztw/VajQwOLsMNT1cbJiH2muO3OROCHnbehc8eY5JyD2gqz4AcMHPqgaOR59DjgUjYAYLeH699g/eWi2jw==", + "dev": true, "license": "MIT", "engines": { "node": ">=18" @@ -4057,6 +4181,22 @@ } } }, + "node_modules/husky": { + "version": "9.1.7", + "resolved": "https://registry.npmjs.org/husky/-/husky-9.1.7.tgz", + "integrity": "sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA==", + "dev": true, + "license": "MIT", + "bin": { + "husky": "bin.js" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/typicode" + } + }, "node_modules/hyperdyperid": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/hyperdyperid/-/hyperdyperid-1.2.0.tgz", @@ -4729,6 +4869,134 @@ "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", "license": "MIT" }, + "node_modules/lint-staged": { + "version": "16.4.0", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-16.4.0.tgz", + "integrity": "sha512-lBWt8hujh/Cjysw5GYVmZpFHXDCgZzhrOm8vbcUdobADZNOK/bRshr2kM3DfgrrtR1DQhfupW9gnIXOfiFi+bw==", + "dev": true, + "license": "MIT", + "dependencies": { + "commander": "^14.0.3", + "listr2": "^9.0.5", + "picomatch": "^4.0.3", + "string-argv": "^0.3.2", + "tinyexec": "^1.0.4", + "yaml": "^2.8.2" + }, + "bin": { + "lint-staged": "bin/lint-staged.js" + }, + "engines": { + "node": ">=20.17" + }, + "funding": { + "url": "https://opencollective.com/lint-staged" + } + }, + "node_modules/lint-staged/node_modules/commander": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.3.tgz", + "integrity": "sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20" + } + }, + "node_modules/lint-staged/node_modules/picomatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/listr2": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-9.0.5.tgz", + "integrity": "sha512-ME4Fb83LgEgwNw96RKNvKV4VTLuXfoKudAmm2lP8Kk87KaMK0/Xrx/aAkMWmT8mDb+3MlFDspfbCs7adjRxA2g==", + "dev": true, + "license": "MIT", + "dependencies": { + "cli-truncate": "^5.0.0", + "colorette": "^2.0.20", + "eventemitter3": "^5.0.1", + "log-update": "^6.1.0", + "rfdc": "^1.4.1", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/listr2/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/listr2/node_modules/emoji-regex": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", + "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", + "dev": true, + "license": "MIT" + }, + "node_modules/listr2/node_modules/eventemitter3": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.4.tgz", + "integrity": "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==", + "dev": true, + "license": "MIT" + }, + "node_modules/listr2/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/listr2/node_modules/wrap-ansi": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", + "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/loader-runner": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.1.tgz", @@ -4797,6 +5065,115 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/log-update": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-6.1.0.tgz", + "integrity": "sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-escapes": "^7.0.0", + "cli-cursor": "^5.0.0", + "slice-ansi": "^7.1.0", + "strip-ansi": "^7.1.0", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/log-update/node_modules/emoji-regex": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", + "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", + "dev": true, + "license": "MIT" + }, + "node_modules/log-update/node_modules/is-fullwidth-code-point": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.1.0.tgz", + "integrity": "sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-east-asian-width": "^1.3.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/slice-ansi": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.2.tgz", + "integrity": "sha512-iOBWFgUX7caIZiuutICxVgX1SdxwAVFFKwt1EvMYYec/NWO5meOJ6K5uQxhrYBdQJne4KxiqZc+KptFOWFSI9w==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "is-fullwidth-code-point": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/log-update/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/wrap-ansi": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", + "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/logform": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/logform/-/logform-2.7.0.tgz", @@ -4986,6 +5363,19 @@ "node": ">= 0.6" } }, + "node_modules/mimic-function": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz", + "integrity": "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/mini-css-extract-plugin": { "version": "2.9.4", "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.9.4.tgz", @@ -6005,6 +6395,22 @@ "fn.name": "1.x.x" } }, + "node_modules/onetime": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz", + "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-function": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/open": { "version": "10.2.0", "resolved": "https://registry.npmjs.org/open/-/open-10.2.0.tgz", @@ -7267,6 +7673,23 @@ "node": ">=4" } }, + "node_modules/restore-cursor": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz", + "integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==", + "dev": true, + "license": "MIT", + "dependencies": { + "onetime": "^7.0.0", + "signal-exit": "^4.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/retry": { "version": "0.13.1", "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", @@ -7276,6 +7699,13 @@ "node": ">= 4" } }, + "node_modules/rfdc": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", + "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", + "dev": true, + "license": "MIT" + }, "node_modules/run-applescript": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.1.0.tgz", @@ -7788,6 +8218,52 @@ "node": ">=10" } }, + "node_modules/slice-ansi": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-8.0.0.tgz", + "integrity": "sha512-stxByr12oeeOyY2BlviTNQlYV5xOj47GirPr4yA1hE9JCtxfQN0+tVbkxwCtYDQWhEKWFHsEK48ORg5jrouCAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.3", + "is-fullwidth-code-point": "^5.1.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/slice-ansi/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/slice-ansi/node_modules/is-fullwidth-code-point": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.1.0.tgz", + "integrity": "sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-east-asian-width": "^1.3.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/slick": { "version": "1.12.2", "resolved": "https://registry.npmjs.org/slick/-/slick-1.12.2.tgz", @@ -7992,6 +8468,16 @@ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "license": "MIT" }, + "node_modules/string-argv": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz", + "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.6.19" + } + }, "node_modules/string-width": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", @@ -8316,6 +8802,16 @@ "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", "license": "MIT" }, + "node_modules/tinyexec": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.0.4.tgz", + "integrity": "sha512-u9r3uZC0bdpGOXtlxUIdwf9pkmvhqJdrVCH9fapQtgy/OeTTMZ1nqH7agtvEfmGui6e1XxjcdrlxvxJvc3sMqw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -9229,6 +9725,22 @@ "node": ">=10" } }, + "node_modules/yaml": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.3.tgz", + "integrity": "sha512-AvbaCLOO2Otw/lW5bmh9d/WEdcDFdQp2Z2ZUH3pX9U2ihyUY0nvLv7J6TrWowklRGPYbB/IuIMfYgxaCPg5Bpg==", + "dev": true, + "license": "ISC", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14.6" + }, + "funding": { + "url": "https://github.com/sponsors/eemeli" + } + }, "node_modules/yargs": { "version": "17.7.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", diff --git a/package.json b/package.json index b271210..762c1d3 100644 --- a/package.json +++ b/package.json @@ -6,8 +6,9 @@ "main": "index.js", "scripts": { "test": "mocha --exit", - "eslint": "eslint ./src ./test ./app ./cli", - "compress": "npx @squoosh/cli --resize '{\"enabled\":false}' -d public public/**/*.{jpg,jpeg,png}" + "eslint": "eslint ./src ./test ./cli", + "compress": "npx @squoosh/cli --resize '{\"enabled\":false}' -d public public/**/*.{jpg,jpeg,png}", + "prepare": "husky" }, "bin": { "igo": "./cli/igo.js" @@ -64,5 +65,14 @@ "webpack-cli": "^6.0.1", "webpack-dev-server": "^5.2.2", "winston": "^3.19.0" + }, + "devDependencies": { + "@eslint/js": "^9.39.4", + "globals": "^17.4.0", + "husky": "^9.1.7", + "lint-staged": "^16.4.0" + }, + "lint-staged": { + "*.js": "eslint" } } diff --git a/src/connect/errorhandler.js b/src/connect/errorhandler.js index 7db1304..4065f2c 100644 --- a/src/connect/errorhandler.js +++ b/src/connect/errorhandler.js @@ -55,7 +55,7 @@ const loadThrottleData = () => { if (fs.existsSync(THROTTLE_FILE)) { return JSON.parse(fs.readFileSync(THROTTLE_FILE, 'utf8')); } - } catch (e) { + } catch (_e) { // Ignore read errors, start fresh } return { emails: [], blocked: {} }; @@ -65,7 +65,7 @@ const loadThrottleData = () => { const saveThrottleData = (data) => { try { fs.writeFileSync(THROTTLE_FILE, JSON.stringify(data), 'utf8'); - } catch (e) { + } catch (_e) { // Ignore write errors } }; diff --git a/src/connect/locals.js b/src/connect/locals.js index 719c77a..f02044c 100644 --- a/src/connect/locals.js +++ b/src/connect/locals.js @@ -27,7 +27,7 @@ const getWebpackAssets = () => { }); } - } catch (err) { + } catch (_err) { // ignored } return assets; diff --git a/src/db/Db.js b/src/db/Db.js index 7fd7715..a12026c 100644 --- a/src/db/Db.js +++ b/src/db/Db.js @@ -1,6 +1,4 @@ -const _ = require('lodash'); - const config = require('../config'); const logger = require('../logger'); @@ -22,7 +20,7 @@ const logQuery = (sql, params, err) => { if (err) { errorhandler.errorSQL(err); } -} +}; // diff --git a/src/db/Model.js b/src/db/Model.js index 3e21967..f998bb7 100644 --- a/src/db/Model.js +++ b/src/db/Model.js @@ -4,7 +4,6 @@ const CachedQuery = require('./CachedQuery'); const Query = require('./Query'); const PaginatedOptimizedQuery = require('./PaginatedOptimizedQuery'); const Schema = require('./Schema'); -const { error } = require('../connect/errorhandler'); const newQuery = (constructor, verb) => { @@ -50,8 +49,8 @@ module.exports = function(schema) { await cache.del('_cached.' + this.constructor.schema.table); } - this.assignValues(values); - return this; + this.assignValues(values); + return this; } // reload @@ -75,7 +74,7 @@ module.exports = function(schema) { } async beforeCreate() { } - async beforeUpdate(values) { } + async beforeUpdate(_values) { } // find by id @@ -191,11 +190,6 @@ module.exports = function(schema) { return newQuery(this).count(); } - // join - static join(association, columns, type, name) { - return newQuery(this).join(association, columns, type, name); - } - // delete static delete(id, ) { return newQuery(this, 'delete').unscoped().where({ id: id }).execute(); @@ -228,7 +222,7 @@ module.exports = function(schema) { return newQuery(this).includes(includes); } - // includes + // join static join(associationName, columns, type='LEFT') { const query = newQuery(this); if (_.isString(associationName)) { diff --git a/src/db/PaginatedOptimizedSql.js b/src/db/PaginatedOptimizedSql.js index 0aa0a82..99f1e8c 100644 --- a/src/db/PaginatedOptimizedSql.js +++ b/src/db/PaginatedOptimizedSql.js @@ -543,7 +543,7 @@ module.exports = class PaginatedOptimizedSql extends Sql { // Chercher dans les associations directes (belongs_to uniquement pour les blocks) for (const assoc of associations) { - const [assocType, assocName, AssociatedModel, src_column, ref_column] = assoc; + const [assocType, _assocName, AssociatedModel, _src_column, _ref_column] = assoc; // On cherche uniquement dans les belongs_to if (assocType !== 'belongs_to' || !AssociatedModel || !AssociatedModel.schema) { @@ -633,7 +633,7 @@ module.exports = class PaginatedOptimizedSql extends Sql { // Chercher dans les associations directes for (const assoc of associations) { - const [, assocName, AssociatedModel, src_column, ref_column] = assoc; + const [, assocName, AssociatedModel, _src_column, _ref_column] = assoc; if (!AssociatedModel || !AssociatedModel.schema) { continue; @@ -712,7 +712,7 @@ module.exports = class PaginatedOptimizedSql extends Sql { return; } - const [, , AssociatedModel, src_column, ref_column, extraWhere] = association; + const [, , _AssociatedModel, src_column, ref_column, extraWhere] = association; // Générer le LEFT JOIN (pour préserver toutes les lignes, même celles avec NULL) let joinSql = `LEFT JOIN ${esc}${currentTableName}${esc} `; @@ -751,7 +751,7 @@ module.exports = class PaginatedOptimizedSql extends Sql { * - Pour chaque filterJoin nested : créer des EXISTS vraiment imbriqués */ addFilterJoinsAsExists(params) { - const { query, dialect } = this; + const { query, dialect: _dialect } = this; if (!query.filterJoins || query.filterJoins.length === 0) { return ''; @@ -1150,7 +1150,7 @@ module.exports = class PaginatedOptimizedSql extends Sql { * @returns {string} Clause transformée (ex: "formation_natures.name DESC" ou "COALESCE(beneficiaries.name, applicants.name)") */ _transformOrderClause(orderClause) { - const { query } = this; + const { query: _query } = this; // Parser la clause ORDER BY pour extraire ASC/DESC const cleanedClause = orderClause.replace(/`/g, '').trim(); @@ -1202,7 +1202,7 @@ module.exports = class PaginatedOptimizedSql extends Sql { // Groupe 1: paths avec points (sans backticks) comme table.column // Groupe 2: colonnes simples avec backticks comme `column` // Groupe 3: identificateurs simples (sans backticks, sans points) - const combinedPattern = /(\b[a-zA-Z_][a-zA-Z0-9_]*(?:\.[a-zA-Z_][a-zA-Z0-9_]*)+\b)|(`[a-zA-Z_][a-zA-Z0-9_]*`)(?!\s*\.)|(\b[a-zA-Z_][a-zA-Z0-9_]*\b)(?!\s*[\.\(])/g; + const combinedPattern = /(\b[a-zA-Z_][a-zA-Z0-9_]*(?:\.[a-zA-Z_][a-zA-Z0-9_]*)+\b)|(`[a-zA-Z_][a-zA-Z0-9_]*`)(?!\s*\.)|(\b[a-zA-Z_][a-zA-Z0-9_]*\b)(?!\s*[.(])/g; return expression.replace(combinedPattern, (match, plainPath, backtickColumn, plainIdentifier) => { // Cas 1: Chemins avec points (ex: table.column, table1.table2.column) diff --git a/src/db/Query.js b/src/db/Query.js index 13c2e0a..5ef8ed7 100644 --- a/src/db/Query.js +++ b/src/db/Query.js @@ -537,8 +537,8 @@ module.exports = class Query { // parse joins values _.forEach(this.query.joins, (join) => { - const { src_schema, association } = join; - const [assoc_type, name, Obj, src_column, column] = association; + const { src_schema: _src_schema, association } = join; + const [_assoc_type, name, Obj, _src_column, _column] = association; Obj.schema.parseTypes(row, `${name}__`); }); }); @@ -547,17 +547,17 @@ module.exports = class Query { if (query.verb === 'select') { rows = _.map(rows, row => { const instance = this.newInstance(row); - + if (this.query.joins.length === 0) { return instance; } - + const createdInstances = new Map(); createdInstances.set(this.schema, instance); _.forEach(this.query.joins, (join) => { const { src_schema, association } = join; - const [assoc_type, name, Obj, src_column, column] = association; + const [_assoc_type, name, Obj, _src_column, _column] = association; const table_alias = name; const params = {}; diff --git a/src/db/Sql.js b/src/db/Sql.js index fb63cc6..148ca45 100644 --- a/src/db/Sql.js +++ b/src/db/Sql.js @@ -24,7 +24,7 @@ module.exports = class Sql { } else if (query.select) { let select_sql = query.select; _.each(query.joins, join => { - const [assoc_type, name, Obj] = join.association; + const [_assoc_type, name, Obj] = join.association; select_sql = select_sql.replace(new RegExp(`\\b${Obj.schema.table}\\b`, 'g'), name); }); sql += select_sql + ' '; @@ -32,8 +32,8 @@ module.exports = class Sql { sql += `${esc}${query.table}${esc}.*`; _.each(query.joins, join => { - const { src_schema, association } = join; - const [ assoc_type, name, Obj, src_column, column] = association; + const { src_schema: _src_schema, association } = join; + const [ _assoc_type, name, Obj, _src_column, _column] = association; const table_alias = name; sql += ', '; if (join.columns) { @@ -126,7 +126,7 @@ module.exports = class Sql { let sql = ''; _.each(query.joins, join => { const { src_schema, type, association, src_alias } = join; - const [ assoc_type, name, Obj, src_column, column, extraWhere] = association; + const [ _assoc_type, name, Obj, src_column, column, extraWhere] = association; const src_table_alias = src_alias || src_schema.table; const table = Obj.schema.table; let joinSql = `${type.toUpperCase()} JOIN ${esc}${table}${esc} AS ${esc}${name}${esc} ON ${esc}${name}${esc}.${esc}${column}${esc} = ${esc}${src_table_alias}${esc}.${esc}${src_column}${esc}`; @@ -144,7 +144,7 @@ module.exports = class Sql { // WHERE whereSQL(params, not) { const { query, dialect } = this; - const { esc } = dialect; + const { esc: _esc } = dialect; const sqlwhere = []; const wheres = not ? query.whereNot : query.where; diff --git a/src/db/dbs.js b/src/db/dbs.js index 5d7eea4..7ccfd0c 100644 --- a/src/db/dbs.js +++ b/src/db/dbs.js @@ -1,7 +1,5 @@ -const _ = require('lodash'); - const Db = require('./Db'); const config = require('../config'); const migrations = require('./migrations'); diff --git a/src/db/migrations.js b/src/db/migrations.js index 0231daa..a68eaec 100644 --- a/src/db/migrations.js +++ b/src/db/migrations.js @@ -6,7 +6,6 @@ const path = require('path'); const config = require('../config'); const logger = require('../logger'); -const utils = require('../utils'); // module.exports.init = async (db) => { @@ -115,13 +114,13 @@ module.exports.migrate = async (db, rootDir = '.') => { logger.error('SQL error in file %s', file.path); throw err; } - } + }; let files = []; const filenames = await fs.readdir(sqldir); _.forEach(filenames, (filename) => { files.push({ filename, path: path.join(sqldir, filename) }); - }) + }); files = _.sortBy(files, 'filename'); await module.exports.initmigrations(db); diff --git a/src/utils.js b/src/utils.js index 80372c0..c43131c 100644 --- a/src/utils.js +++ b/src/utils.js @@ -3,7 +3,7 @@ module.exports.toJSON = (s) => { try { return JSON.stringify(s); - } catch(err) { + } catch(_err) { return null; } }; @@ -12,7 +12,7 @@ module.exports.toJSON = (s) => { module.exports.fromJSON = (json) => { try { return JSON.parse(json); - } catch(err) { + } catch(_err) { return null; } }; diff --git a/test/db/AssociationsTest.js b/test/db/AssociationsTest.js index de3ef39..5f7401b 100644 --- a/test/db/AssociationsTest.js +++ b/test/db/AssociationsTest.js @@ -160,8 +160,8 @@ describe('includes', () => { }); it('should return an empty array if ref null', async () => { - const book1 = await Book.create(); - const book2 = await Book.create(); + const _book1 = await Book.create(); + const _book2 = await Book.create(); const library = await Library.create({ books_ids: null }); const foundLibrary = await Library.includes('books').find(library.id); assert(Array.isArray(foundLibrary.books)); @@ -169,8 +169,8 @@ describe('includes', () => { }); it('should return an empty array if wrong id', async () => { - const book1 = await Book.create(); - const book2 = await Book.create(); + const _book1 = await Book.create(); + const _book2 = await Book.create(); const library = await Library.create({ books_ids: [99999] }); const foundLibrary = await Library.includes('books').find(library.id); assert(Array.isArray(foundLibrary.books)); diff --git a/test/db/JoinTest.js b/test/db/JoinTest.js index 8a77354..8aebb61 100644 --- a/test/db/JoinTest.js +++ b/test/db/JoinTest.js @@ -242,9 +242,9 @@ describe('includes', () => { const book = await Book.create({ library_id: library.id }); const books = await Book.paginatedOptimized() - .join('library') - .limit(10) - .list(); + .join('library') + .limit(10) + .list(); assert.strictEqual(books.length, 1); assert.strictEqual(books[0].id, book.id); @@ -255,12 +255,12 @@ describe('includes', () => { it('should attach nested joined data in selectFull phase', async () => { const city = await City.create({ name: 'Lyon' }); const library = await Library.create({ title: 'Municipale', city_id: city.id }); - const book = await Book.create({ library_id: library.id }); + const _book = await Book.create({ library_id: library.id }); const books = await Book.paginatedOptimized() - .join({ library: 'city' }) - .limit(10) - .list(); + .join({ library: 'city' }) + .limit(10) + .list(); assert.strictEqual(books.length, 1); assert.strictEqual(books[0].library.id, library.id); @@ -277,10 +277,10 @@ describe('includes', () => { await Book.create({ title: 'Book C' }); // no library const result = await Book - .where({ library_id: library.id }) - .join('library') - .page(1, 10) - .list(); + .where({ library_id: library.id }) + .join('library') + .page(1, 10) + .list(); assert.ok(result.pagination, 'should return pagination object'); assert.strictEqual(result.pagination.count, 2); diff --git a/test/db/PaginatedOptimizedQueryTest.js b/test/db/PaginatedOptimizedQueryTest.js index fde7ac2..6acf43c 100644 --- a/test/db/PaginatedOptimizedQueryTest.js +++ b/test/db/PaginatedOptimizedQueryTest.js @@ -9,10 +9,10 @@ const mockGetDb = (query) => { driver: { dialect: { esc: '`', - param: (i) => '?', + param: (_i) => '?', in: 'IN', notin: 'NOT IN', - limit: (offsetParam, limitParam) => `LIMIT ?, ?` + limit: (_offsetParam, _limitParam) => 'LIMIT ?, ?' } } }); @@ -464,8 +464,8 @@ describe('db.PaginatedOptimizedQuery', function() { const query = mockGetDb(new PaginatedOptimizedQuery(Folder)); query.query.verb = 'count'; query.where({ type: 'agp', 'applicant.last_name': { $like: 'Dupont%' } }) - .order('applicants.last_name ASC') - .join('applicant'); + .order('applicants.last_name ASC') + .join('applicant'); const { sql, params } = query.toSQL(); assert.strictEqual(sql, 'SELECT COUNT(0) as `count` FROM `folders` WHERE `folders`.`type` = ? AND EXISTS (SELECT 1 FROM `applicants` WHERE `applicants`.`id` = `folders`.`applicant_id` AND `applicants`.`last_name` LIKE ? )'); @@ -476,8 +476,8 @@ describe('db.PaginatedOptimizedQuery', function() { const query = mockGetDb(new PaginatedOptimizedQuery(Folder)); query.query.verb = 'select_ids'; query.where({ type: 'agp', 'applicant.last_name': { $like: 'Dupont%' } }) - .order('folders.created_at DESC') - .limit(50); + .order('folders.created_at DESC') + .limit(50); const { sql, params } = query.toSQL(); assert.strictEqual(sql, 'SELECT `folders`.`id` FROM `folders` WHERE `folders`.`type` = ? AND EXISTS (SELECT 1 FROM `applicants` WHERE `applicants`.`id` = `folders`.`applicant_id` AND `applicants`.`last_name` LIKE ? ) ORDER BY folders.created_at DESC LIMIT ?, ?'); @@ -533,8 +533,8 @@ describe('db.PaginatedOptimizedQuery', function() { const query = mockGetDb(new PaginatedOptimizedQuery(Folder)); query.query.verb = 'select_ids'; query.where({ type: 'agp' }).join('applicant') - .order('COALESCE(`applicant`.`last_name`, `applicant`.`first_name`) ASC') - .limit(50); + .order('COALESCE(`applicant`.`last_name`, `applicant`.`first_name`) ASC') + .limit(50); const { sql, params } = query.toSQL(); assert.strictEqual(sql, 'SELECT `folders`.`id` FROM `folders` LEFT JOIN `applicants` ON `applicants`.`id` = `folders`.`applicant_id` WHERE `folders`.`type` = ? ORDER BY COALESCE(applicants.last_name, applicants.first_name) ASC LIMIT ?, ?'); diff --git a/test/db/SqlTest.js b/test/db/SqlTest.js index b7a64d2..1390d8e 100644 --- a/test/db/SqlTest.js +++ b/test/db/SqlTest.js @@ -240,7 +240,7 @@ describe('db.Sql', function() { var params = []; var query = freshQuery({ where: [{ status: 'active' }], whereNot: [{ type: 'draft' }] }); // First generate the where SQL - var whereSql = new Sql(query, dialect).whereSQL(params); + var _whereSql = new Sql(query, dialect).whereSQL(params); // Then generate whereNot - needs a fresh Sql instance var params2 = []; var whereNotSql = new Sql(query, dialect).whereNotSQL(params2);