From 465813128f7c71d542650ad6c0b1514ad568571b Mon Sep 17 00:00:00 2001 From: Nicolas Bouvrette Date: Tue, 9 Aug 2022 17:32:10 -0400 Subject: [PATCH] refactor: add `eslint-plugin-unicorn` to help increase code quality BREAKING CHANGE: Using the `node:` scheme to better identify Node.js modules requires more recent Node.js versions --- .eslintrc.yaml | 131 +++- jest.config.js | 4 - jest.config.json | 3 + package-lock.json | 609 +++++++++++++----- package.json | 21 +- ...add-import-type.js => add-import-type.mjs} | 2 +- src/content/index.ts | 2 +- src/file/index.ts | 6 +- src/properties.ts | 30 +- src/property-line.ts | 12 +- src/property.ts | 132 ++-- tests/properties-file.test.ts | 4 +- 12 files changed, 699 insertions(+), 257 deletions(-) delete mode 100644 jest.config.js create mode 100644 jest.config.json rename src/{add-import-type.js => add-import-type.mjs} (96%) diff --git a/.eslintrc.yaml b/.eslintrc.yaml index c12c03b..bcc9b71 100644 --- a/.eslintrc.yaml +++ b/.eslintrc.yaml @@ -7,6 +7,7 @@ env: extends: - eslint:recommended - plugin:import/recommended + - plugin:unicorn/recommended - plugin:prettier/recommended settings: import/resolver: @@ -22,12 +23,32 @@ settings: alwaysTryTypes: true rules: # Increase the level to 'error' for unused variables (the default is set to 'warning') - # @see https://typescript-eslint.io/rules/no-unused-vars/ - '@typescript-eslint/no-unused-vars': + # @see https://eslint.org/docs/latest/rules/no-unused-vars + no-unused-vars: - error - # This check will only be enabled for TypeScript (the real configuration is in the 'overrides') - # @see https://typescript-eslint.io/rules/explicit-function-return-type/#configuring-in-a-mixed-jsts-codebase - '@typescript-eslint/explicit-function-return-type': 'off' + - args: all + # Checks all variable declaration blocks and verifies that all variables are sorted. + # @see https://eslint.org/docs/latest/rules/sort-vars + sort-vars: + - error + - ignoreCase: true + # Checks all property definitions of object expressions and verifies that all variables are sorted. + # @see https://eslint.org/docs/latest/rules/sort-keys + sort-keys: + - error + - asc + - caseSensitive: false + natural: true + # The Unicorn plugin comes with opinionated checks, including some that we prefer disabling. + 'unicorn/no-array-for-each': + # Performance is no longer an issue - we prefer `forEach` for readability. + - off + 'unicorn/numeric-separators-style': + # Doesn't add a lot of value and makes numbers look odd. + - off + 'unicorn/prefer-type-error': + # Not really applicable when using TypeScript (mostly triggers false positives). + - off overrides: # TypeScript configurations - files: @@ -44,11 +65,111 @@ overrides: - plugin:@typescript-eslint/recommended - plugin:@typescript-eslint/recommended-requiring-type-checking rules: + # Increase the level to 'error' for unused variables (the default is set to 'warning') + # @see https://typescript-eslint.io/rules/no-unused-vars/ + no-unused-vars: off + '@typescript-eslint/no-unused-vars': + - error # Show errors when missing return types are missing on relevant functions '@typescript-eslint/explicit-function-return-type': - error - allowExpressions: true allowConciseArrowFunctionExpressionsStartingWithVoid: true + # Checks members (classes, interfaces, types) and applies consistent ordering. + # @see https://typescript-eslint.io/rules/member-ordering/ + '@typescript-eslint/member-ordering': + - error + - default: + # There is no way to use the default configuration without copy/pasting it. + # @see https://github.com/typescript-eslint/typescript-eslint/issues/5452 + memberTypes: + - signature + - public-static-field + - protected-static-field + - private-static-field + - public-decorated-field + - protected-decorated-field + - private-decorated-field + - public-instance-field + - protected-instance-field + - private-instance-field + - public-abstract-field + - protected-abstract-field + - private-abstract-field + - public-field + - protected-field + - private-field + - static-field + - instance-field + - abstract-field + - decorated-field + - field + - static-initialization + - public-constructor + - protected-constructor + - private-constructor + - constructor + - public-static-get + - protected-static-get + - private-static-get + - public-decorated-get + - protected-decorated-get + - private-decorated-get + - public-instance-get + - protected-instance-get + - private-instance-get + - public-abstract-get + - protected-abstract-get + - private-abstract-get + - public-get + - protected-get + - private-get + - static-get + - instance-get + - abstract-get + - decorated-get + - get + - public-static-set + - protected-static-set + - private-static-set + - public-decorated-set + - protected-decorated-set + - private-decorated-set + - public-instance-set + - protected-instance-set + - private-instance-set + - public-abstract-set + - protected-abstract-set + - private-abstract-set + - public-set + - protected-set + - private-set + - static-set + - instance-set + - abstract-set + - decorated-set + - set + - public-static-method + - protected-static-method + - private-static-method + - public-decorated-method + - protected-decorated-method + - private-decorated-method + - public-instance-method + - protected-instance-method + - private-instance-method + - public-abstract-method + - protected-abstract-method + - private-abstract-method + - public-method + - protected-method + - private-method + - static-method + - instance-method + - abstract-method + - decorated-method + - method + order: alphabetically-case-insensitive # Jest configurations - files: - tests/** diff --git a/jest.config.js b/jest.config.js deleted file mode 100644 index 87c30aa..0000000 --- a/jest.config.js +++ /dev/null @@ -1,4 +0,0 @@ -module.exports = { - preset: 'ts-jest', - testEnvironment: 'node', -} diff --git a/jest.config.json b/jest.config.json new file mode 100644 index 0000000..9a9ab7c --- /dev/null +++ b/jest.config.json @@ -0,0 +1,3 @@ +{ + "preset": "ts-jest" +} diff --git a/package-lock.json b/package-lock.json index ce91865..99bba8b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,21 +11,22 @@ "devDependencies": { "@release-it/conventional-changelog": "^5.0.0", "@types/jest": "^28.1.6", - "@typescript-eslint/eslint-plugin": "^5.32.0", - "@typescript-eslint/parser": "^5.32.0", + "@typescript-eslint/eslint-plugin": "^5.33.0", + "@typescript-eslint/parser": "^5.33.0", "dotenv-cli": "^6.0.0", "eslint": "^8.21.0", "eslint-config-prettier": "^8.5.0", "eslint-import-resolver-node": "^0.3.6", "eslint-import-resolver-typescript": "^3.4.0", "eslint-plugin-import": "^2.26.0", - "eslint-plugin-jest": "^26.7.0", + "eslint-plugin-jest": "^26.8.2", "eslint-plugin-prettier": "^4.2.1", + "eslint-plugin-unicorn": "^43.0.2", "jest": "^28.1.3", "prettier": "^2.7.1", - "prettier-plugin-organize-imports": "^3.0.1", + "prettier-plugin-organize-imports": "^3.0.3", "prettier-plugin-sh": "^0.12.8", - "release-it": "^15.2.0", + "release-it": "^15.3.0", "ts-jest": "^28.0.7", "ts-node": "^10.9.1", "typescript": "^4.7.4" @@ -247,9 +248,9 @@ } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz", - "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.18.6.tgz", + "integrity": "sha512-MmetCkz9ej86nJQV+sFCxoGGrUbU3q02kgLciwkrt9QqEB7cP39oKEY0PakknEO0Gu20SskMRi+AYZ3b1TpN9g==", "dev": true, "engines": { "node": ">=6.9.0" @@ -1613,14 +1614,14 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.32.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.32.0.tgz", - "integrity": "sha512-CHLuz5Uz7bHP2WgVlvoZGhf0BvFakBJKAD/43Ty0emn4wXWv5k01ND0C0fHcl/Im8Td2y/7h44E9pca9qAu2ew==", + "version": "5.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.33.0.tgz", + "integrity": "sha512-jHvZNSW2WZ31OPJ3enhLrEKvAZNyAFWZ6rx9tUwaessTc4sx9KmgMNhVcqVAl1ETnT5rU5fpXTLmY9YvC1DCNg==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "5.32.0", - "@typescript-eslint/type-utils": "5.32.0", - "@typescript-eslint/utils": "5.32.0", + "@typescript-eslint/scope-manager": "5.33.0", + "@typescript-eslint/type-utils": "5.33.0", + "@typescript-eslint/utils": "5.33.0", "debug": "^4.3.4", "functional-red-black-tree": "^1.0.1", "ignore": "^5.2.0", @@ -1646,14 +1647,14 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "5.32.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.32.0.tgz", - "integrity": "sha512-IxRtsehdGV9GFQ35IGm5oKKR2OGcazUoiNBxhRV160iF9FoyuXxjY+rIqs1gfnd+4eL98OjeGnMpE7RF/NBb3A==", + "version": "5.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.33.0.tgz", + "integrity": "sha512-cgM5cJrWmrDV2KpvlcSkelTBASAs1mgqq+IUGKJvFxWrapHpaRy5EXPQz9YaKF3nZ8KY18ILTiVpUtbIac86/w==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "5.32.0", - "@typescript-eslint/types": "5.32.0", - "@typescript-eslint/typescript-estree": "5.32.0", + "@typescript-eslint/scope-manager": "5.33.0", + "@typescript-eslint/types": "5.33.0", + "@typescript-eslint/typescript-estree": "5.33.0", "debug": "^4.3.4" }, "engines": { @@ -1673,13 +1674,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "5.32.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.32.0.tgz", - "integrity": "sha512-KyAE+tUON0D7tNz92p1uetRqVJiiAkeluvwvZOqBmW9z2XApmk5WSMV9FrzOroAcVxJZB3GfUwVKr98Dr/OjOg==", + "version": "5.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.33.0.tgz", + "integrity": "sha512-/Jta8yMNpXYpRDl8EwF/M8It2A9sFJTubDo0ATZefGXmOqlaBffEw0ZbkbQ7TNDK6q55NPHFshGBPAZvZkE8Pw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.32.0", - "@typescript-eslint/visitor-keys": "5.32.0" + "@typescript-eslint/types": "5.33.0", + "@typescript-eslint/visitor-keys": "5.33.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -1690,12 +1691,12 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "5.32.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.32.0.tgz", - "integrity": "sha512-0gSsIhFDduBz3QcHJIp3qRCvVYbqzHg8D6bHFsDMrm0rURYDj+skBK2zmYebdCp+4nrd9VWd13egvhYFJj/wZg==", + "version": "5.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.33.0.tgz", + "integrity": "sha512-2zB8uEn7hEH2pBeyk3NpzX1p3lF9dKrEbnXq1F7YkpZ6hlyqb2yZujqgRGqXgRBTHWIUG3NGx/WeZk224UKlIA==", "dev": true, "dependencies": { - "@typescript-eslint/utils": "5.32.0", + "@typescript-eslint/utils": "5.33.0", "debug": "^4.3.4", "tsutils": "^3.21.0" }, @@ -1716,9 +1717,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "5.32.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.32.0.tgz", - "integrity": "sha512-EBUKs68DOcT/EjGfzywp+f8wG9Zw6gj6BjWu7KV/IYllqKJFPlZlLSYw/PTvVyiRw50t6wVbgv4p9uE2h6sZrQ==", + "version": "5.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.33.0.tgz", + "integrity": "sha512-nIMt96JngB4MYFYXpZ/3ZNU4GWPNdBbcB5w2rDOCpXOVUkhtNlG2mmm8uXhubhidRZdwMaMBap7Uk8SZMU/ppw==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -1729,13 +1730,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.32.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.32.0.tgz", - "integrity": "sha512-ZVAUkvPk3ITGtCLU5J4atCw9RTxK+SRc6hXqLtllC2sGSeMFWN+YwbiJR9CFrSFJ3w4SJfcWtDwNb/DmUIHdhg==", + "version": "5.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.33.0.tgz", + "integrity": "sha512-tqq3MRLlggkJKJUrzM6wltk8NckKyyorCSGMq4eVkyL5sDYzJJcMgZATqmF8fLdsWrW7OjjIZ1m9v81vKcaqwQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.32.0", - "@typescript-eslint/visitor-keys": "5.32.0", + "@typescript-eslint/types": "5.33.0", + "@typescript-eslint/visitor-keys": "5.33.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -1756,15 +1757,15 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "5.32.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.32.0.tgz", - "integrity": "sha512-W7lYIAI5Zlc5K082dGR27Fczjb3Q57ECcXefKU/f0ajM5ToM0P+N9NmJWip8GmGu/g6QISNT+K6KYB+iSHjXCQ==", + "version": "5.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.33.0.tgz", + "integrity": "sha512-JxOAnXt9oZjXLIiXb5ZIcZXiwVHCkqZgof0O8KPgz7C7y0HS42gi75PdPlqh1Tf109M0fyUw45Ao6JLo7S5AHw==", "dev": true, "dependencies": { "@types/json-schema": "^7.0.9", - "@typescript-eslint/scope-manager": "5.32.0", - "@typescript-eslint/types": "5.32.0", - "@typescript-eslint/typescript-estree": "5.32.0", + "@typescript-eslint/scope-manager": "5.33.0", + "@typescript-eslint/types": "5.33.0", + "@typescript-eslint/typescript-estree": "5.33.0", "eslint-scope": "^5.1.1", "eslint-utils": "^3.0.0" }, @@ -1780,12 +1781,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.32.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.32.0.tgz", - "integrity": "sha512-S54xOHZgfThiZ38/ZGTgB2rqx51CMJ5MCfVT2IplK4Q7hgzGfe0nLzLCcenDnc/cSjP568hdeKfeDcBgqNHD/g==", + "version": "5.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.33.0.tgz", + "integrity": "sha512-/XsqCzD4t+Y9p5wd9HZiptuGKBlaZO5showwqODii5C0nZawxWLF+Q6k5wYHBrQv96h6GYKyqqMHCSTqta8Kiw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.32.0", + "@typescript-eslint/types": "5.33.0", "eslint-visitor-keys": "^3.3.0" }, "engines": { @@ -2431,6 +2432,18 @@ "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", "dev": true }, + "node_modules/builtin-modules": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", + "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", + "dev": true, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/bytes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", @@ -2596,9 +2609,9 @@ "dev": true }, "node_modules/ci-info": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.3.0.tgz", - "integrity": "sha512-riT/3vI5YpVH6/qomlDnJow6TBee2PBKSEpx3O32EGPYbWGIRsIlGRms3Sm74wYE1JMo8RnO04Hb12+v1J5ICw==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.3.2.tgz", + "integrity": "sha512-xmDt/QIAdeZ9+nfdPsaBCpMvHNLFiLdjj59qjqn+6iPe6YmHGQ35sBnQ8uslRBXFmXkiZQOJRjvQeoGppoTjjg==", "dev": true }, "node_modules/cjs-module-lexer": { @@ -2607,6 +2620,18 @@ "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==", "dev": true }, + "node_modules/clean-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/clean-regexp/-/clean-regexp-1.0.0.tgz", + "integrity": "sha512-GfisEZEJvzKrmGWkvfhgzcz/BllN1USeqD2V6tg14OAOgaCD2Z/PUEuxnAZ/nPvmaHRG7a8y77p1T/IRQ4D1Hw==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/cli-boxes": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-3.0.0.tgz", @@ -2635,9 +2660,9 @@ } }, "node_modules/cli-spinners": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.6.1.tgz", - "integrity": "sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.7.0.tgz", + "integrity": "sha512-qu3pN8Y3qHNgE2AFweciB1IfMnmZ/fsNTEE+NOFjmGB2F/7rLhnhzppvpCnN4FovtP26k8lHyy9ptEbNwWFLzw==", "dev": true, "engines": { "node": ">=6" @@ -4019,9 +4044,9 @@ "dev": true }, "node_modules/eslint-plugin-jest": { - "version": "26.7.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-26.7.0.tgz", - "integrity": "sha512-/YNitdfG3o3cC6juZziAdkk6nfJt01jXVfj4AgaYVLs7bupHzRDL5K+eipdzhDXtQsiqaX1TzfwSuRlEgeln1A==", + "version": "26.8.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-26.8.2.tgz", + "integrity": "sha512-67oh0FKaku9y48OpLzL3uK9ckrgLb83Sp5gxxTbtOGDw9lq6D8jw/Psj/9CipkbK406I2M7mvx1q+pv/MdbvxA==", "dev": true, "dependencies": { "@typescript-eslint/utils": "^5.10.0" @@ -4063,6 +4088,114 @@ } } }, + "node_modules/eslint-plugin-unicorn": { + "version": "43.0.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-43.0.2.tgz", + "integrity": "sha512-DtqZ5mf/GMlfWoz1abIjq5jZfaFuHzGBZYIeuJfEoKKGWRHr2JiJR+ea+BF7Wx2N1PPRoT/2fwgiK1NnmNE3Hg==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.18.6", + "ci-info": "^3.3.2", + "clean-regexp": "^1.0.0", + "eslint-utils": "^3.0.0", + "esquery": "^1.4.0", + "indent-string": "^4.0.0", + "is-builtin-module": "^3.1.0", + "lodash": "^4.17.21", + "pluralize": "^8.0.0", + "read-pkg-up": "^7.0.1", + "regexp-tree": "^0.1.24", + "safe-regex": "^2.1.1", + "semver": "^7.3.7", + "strip-indent": "^3.0.0" + }, + "engines": { + "node": ">=14.18" + }, + "funding": { + "url": "https://github.com/sindresorhus/eslint-plugin-unicorn?sponsor=1" + }, + "peerDependencies": { + "eslint": ">=8.18.0" + } + }, + "node_modules/eslint-plugin-unicorn/node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, + "node_modules/eslint-plugin-unicorn/node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/eslint-plugin-unicorn/node_modules/normalize-package-data/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/eslint-plugin-unicorn/node_modules/read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "dependencies": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint-plugin-unicorn/node_modules/read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "dependencies": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint-plugin-unicorn/node_modules/read-pkg/node_modules/type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint-plugin-unicorn/node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/eslint-scope": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", @@ -5026,9 +5159,9 @@ "dev": true }, "node_modules/got": { - "version": "12.2.0", - "resolved": "https://registry.npmjs.org/got/-/got-12.2.0.tgz", - "integrity": "sha512-A81ll5Z8wzeCmSdIlWVMDWFKDo82v2nmOaMZDQNHKGInNqDBcle+CSb6BBiZcn/Aiefz/kSpo520WBKi9QAO/A==", + "version": "12.3.1", + "resolved": "https://registry.npmjs.org/got/-/got-12.3.1.tgz", + "integrity": "sha512-tS6+JMhBh4iXMSXF6KkIsRxmloPln31QHDlcb6Ec3bzxjjFJFr/8aXdpyuLmVc9I4i2HyBHYw1QU5K1ruUdpkw==", "dev": true, "dependencies": { "@sindresorhus/is": "^5.2.0", @@ -5390,9 +5523,9 @@ "dev": true }, "node_modules/inquirer": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-9.0.2.tgz", - "integrity": "sha512-AqmDHmz3bIe573OiM4svTZzajBzff1xpuzYAimW8gjzW5ncuPllWB8t/GKl+NSuKRJaKyIF2bU2RCx8H1dwqyQ==", + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-9.1.0.tgz", + "integrity": "sha512-eukdjrBljg9t55ZnvJjvGi1OyYEzVBFsO/8o5d2MV3mc28u3x4X2kS4eJ/+9U10KiREfPkEBSeCrU/S2G/uRtw==", "dev": true, "dependencies": { "ansi-escapes": "^5.0.0", @@ -5612,6 +5745,21 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-builtin-module": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.0.tgz", + "integrity": "sha512-phDA4oSGt7vl1n5tJvTWooWWAsXLY+2xCnxNqvKhGEzujg+A43wPlPOyDg3C8XQHN+6k/JTQWJ/j0dQh/qr+Hw==", + "dev": true, + "dependencies": { + "builtin-modules": "^3.3.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-callable": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", @@ -7422,9 +7570,9 @@ } }, "node_modules/node-fetch": { - "version": "3.2.9", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.2.9.tgz", - "integrity": "sha512-/2lI+DBecVvVm9tDhjziTVjo2wmTsSxSk58saUYP0P/fRJ3xxtfMDY24+CKTkfm0Dlhyn3CSXNL0SoRiCZ8Rzg==", + "version": "3.2.10", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.2.10.tgz", + "integrity": "sha512-MhuzNwdURnZ1Cp4XTazr69K0BTizsBroX7Zx3UgDSVcZYKF/6p0CBe4EUb/hLqmzVhl0UpYfgRljQ4yxE+iCxA==", "dev": true, "dependencies": { "data-uri-to-buffer": "^4.0.0", @@ -7944,6 +8092,15 @@ "node": ">=8" } }, + "node_modules/pluralize": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", + "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -7981,9 +8138,9 @@ } }, "node_modules/prettier-plugin-organize-imports": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/prettier-plugin-organize-imports/-/prettier-plugin-organize-imports-3.0.1.tgz", - "integrity": "sha512-pdMWKtoHRQ+9y1WB3mA1wzMkjzJzB4ycfOPlfZpmzq+YFZQIpkszJJQQHQ8EYVyULlLohlOnAxSmXfaKWpRAAw==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/prettier-plugin-organize-imports/-/prettier-plugin-organize-imports-3.0.3.tgz", + "integrity": "sha512-eu8PhJR39UZamhRdLEBJhUKG/sg0s+bnjwnN5Lc1TByZUHBtMuS9tBstnyaKGTSiMLhhftRPr0yIWG+PmJ13MA==", "dev": true, "peerDependencies": { "@volar/vue-typescript": ">=0.39.0", @@ -8436,6 +8593,15 @@ "node": ">=8" } }, + "node_modules/regexp-tree": { + "version": "0.1.24", + "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.24.tgz", + "integrity": "sha512-s2aEVuLhvnVJW6s/iPgEGK6R+/xngd2jNQ+xy4bXNDKxZKJH6jpPHY6kVeVv1IeLCHgswRj+Kl3ELaDjG6V1iw==", + "dev": true, + "bin": { + "regexp-tree": "bin/regexp-tree" + } + }, "node_modules/regexp.prototype.flags": { "version": "1.4.3", "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", @@ -8493,9 +8659,9 @@ } }, "node_modules/release-it": { - "version": "15.2.0", - "resolved": "https://registry.npmjs.org/release-it/-/release-it-15.2.0.tgz", - "integrity": "sha512-zVtk/+BSX941e9lR2dhWGQhOIVdr98Fifgel4xUnsJVycU0uTtalOUhjoZM2jyDgcD22idmuDVgvgOTl9IyJ/g==", + "version": "15.3.0", + "resolved": "https://registry.npmjs.org/release-it/-/release-it-15.3.0.tgz", + "integrity": "sha512-MI4EBGca+y4SskgBkWNIakFp/GvXfpZEMWkmqmsysPcou/L+E+sKd0oy33ovGCyLic+9SI2rv/lQ3ACgonmqdQ==", "dev": true, "dependencies": { "@iarna/toml": "2.2.5", @@ -8507,13 +8673,13 @@ "form-data": "4.0.0", "git-url-parse": "12.0.0", "globby": "13.1.2", - "got": "12.2.0", - "inquirer": "9.0.2", + "got": "12.3.1", + "inquirer": "9.1.0", "is-ci": "3.0.1", "lodash": "4.17.21", "mime-types": "2.1.35", "new-github-release-url": "2.0.0", - "node-fetch": "3.2.9", + "node-fetch": "3.2.10", "open": "8.4.0", "ora": "6.1.2", "os-name": "5.0.1", @@ -8524,7 +8690,7 @@ "update-notifier": "6.0.2", "url-join": "5.0.0", "wildcard-match": "5.1.2", - "yargs-parser": "21.0.1" + "yargs-parser": "21.1.1" }, "bin": { "release-it": "bin/release-it.js" @@ -8687,9 +8853,9 @@ } }, "node_modules/release-it/node_modules/yargs-parser": { - "version": "21.0.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.0.1.tgz", - "integrity": "sha512-9BK1jFpLzJROCI5TzwZL/TU4gqjK5xiHV/RfWLOahrjAko/e4DJkRDZQXfvqAsiZzzYhgAzbgz6lg48jcm4GLg==", + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", "dev": true, "engines": { "node": ">=12" @@ -8887,6 +9053,15 @@ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "dev": true }, + "node_modules/safe-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-2.1.1.tgz", + "integrity": "sha512-rx+x8AMzKb5Q5lQ95Zoi6ZbJqwCLkqi3XuJXp5P3rT8OEc6sZCJG5AE5dU3lsgRr/F4Bs31jSlVN+j5KrsGu9A==", + "dev": true, + "dependencies": { + "regexp-tree": "~0.1.1" + } + }, "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", @@ -10390,9 +10565,9 @@ } }, "@babel/helper-validator-identifier": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz", - "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.18.6.tgz", + "integrity": "sha512-MmetCkz9ej86nJQV+sFCxoGGrUbU3q02kgLciwkrt9QqEB7cP39oKEY0PakknEO0Gu20SskMRi+AYZ3b1TpN9g==", "dev": true }, "@babel/helper-validator-option": { @@ -11501,14 +11676,14 @@ "dev": true }, "@typescript-eslint/eslint-plugin": { - "version": "5.32.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.32.0.tgz", - "integrity": "sha512-CHLuz5Uz7bHP2WgVlvoZGhf0BvFakBJKAD/43Ty0emn4wXWv5k01ND0C0fHcl/Im8Td2y/7h44E9pca9qAu2ew==", + "version": "5.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.33.0.tgz", + "integrity": "sha512-jHvZNSW2WZ31OPJ3enhLrEKvAZNyAFWZ6rx9tUwaessTc4sx9KmgMNhVcqVAl1ETnT5rU5fpXTLmY9YvC1DCNg==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "5.32.0", - "@typescript-eslint/type-utils": "5.32.0", - "@typescript-eslint/utils": "5.32.0", + "@typescript-eslint/scope-manager": "5.33.0", + "@typescript-eslint/type-utils": "5.33.0", + "@typescript-eslint/utils": "5.33.0", "debug": "^4.3.4", "functional-red-black-tree": "^1.0.1", "ignore": "^5.2.0", @@ -11518,52 +11693,52 @@ } }, "@typescript-eslint/parser": { - "version": "5.32.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.32.0.tgz", - "integrity": "sha512-IxRtsehdGV9GFQ35IGm5oKKR2OGcazUoiNBxhRV160iF9FoyuXxjY+rIqs1gfnd+4eL98OjeGnMpE7RF/NBb3A==", + "version": "5.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.33.0.tgz", + "integrity": "sha512-cgM5cJrWmrDV2KpvlcSkelTBASAs1mgqq+IUGKJvFxWrapHpaRy5EXPQz9YaKF3nZ8KY18ILTiVpUtbIac86/w==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "5.32.0", - "@typescript-eslint/types": "5.32.0", - "@typescript-eslint/typescript-estree": "5.32.0", + "@typescript-eslint/scope-manager": "5.33.0", + "@typescript-eslint/types": "5.33.0", + "@typescript-eslint/typescript-estree": "5.33.0", "debug": "^4.3.4" } }, "@typescript-eslint/scope-manager": { - "version": "5.32.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.32.0.tgz", - "integrity": "sha512-KyAE+tUON0D7tNz92p1uetRqVJiiAkeluvwvZOqBmW9z2XApmk5WSMV9FrzOroAcVxJZB3GfUwVKr98Dr/OjOg==", + "version": "5.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.33.0.tgz", + "integrity": "sha512-/Jta8yMNpXYpRDl8EwF/M8It2A9sFJTubDo0ATZefGXmOqlaBffEw0ZbkbQ7TNDK6q55NPHFshGBPAZvZkE8Pw==", "dev": true, "requires": { - "@typescript-eslint/types": "5.32.0", - "@typescript-eslint/visitor-keys": "5.32.0" + "@typescript-eslint/types": "5.33.0", + "@typescript-eslint/visitor-keys": "5.33.0" } }, "@typescript-eslint/type-utils": { - "version": "5.32.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.32.0.tgz", - "integrity": "sha512-0gSsIhFDduBz3QcHJIp3qRCvVYbqzHg8D6bHFsDMrm0rURYDj+skBK2zmYebdCp+4nrd9VWd13egvhYFJj/wZg==", + "version": "5.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.33.0.tgz", + "integrity": "sha512-2zB8uEn7hEH2pBeyk3NpzX1p3lF9dKrEbnXq1F7YkpZ6hlyqb2yZujqgRGqXgRBTHWIUG3NGx/WeZk224UKlIA==", "dev": true, "requires": { - "@typescript-eslint/utils": "5.32.0", + "@typescript-eslint/utils": "5.33.0", "debug": "^4.3.4", "tsutils": "^3.21.0" } }, "@typescript-eslint/types": { - "version": "5.32.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.32.0.tgz", - "integrity": "sha512-EBUKs68DOcT/EjGfzywp+f8wG9Zw6gj6BjWu7KV/IYllqKJFPlZlLSYw/PTvVyiRw50t6wVbgv4p9uE2h6sZrQ==", + "version": "5.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.33.0.tgz", + "integrity": "sha512-nIMt96JngB4MYFYXpZ/3ZNU4GWPNdBbcB5w2rDOCpXOVUkhtNlG2mmm8uXhubhidRZdwMaMBap7Uk8SZMU/ppw==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "5.32.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.32.0.tgz", - "integrity": "sha512-ZVAUkvPk3ITGtCLU5J4atCw9RTxK+SRc6hXqLtllC2sGSeMFWN+YwbiJR9CFrSFJ3w4SJfcWtDwNb/DmUIHdhg==", + "version": "5.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.33.0.tgz", + "integrity": "sha512-tqq3MRLlggkJKJUrzM6wltk8NckKyyorCSGMq4eVkyL5sDYzJJcMgZATqmF8fLdsWrW7OjjIZ1m9v81vKcaqwQ==", "dev": true, "requires": { - "@typescript-eslint/types": "5.32.0", - "@typescript-eslint/visitor-keys": "5.32.0", + "@typescript-eslint/types": "5.33.0", + "@typescript-eslint/visitor-keys": "5.33.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -11572,26 +11747,26 @@ } }, "@typescript-eslint/utils": { - "version": "5.32.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.32.0.tgz", - "integrity": "sha512-W7lYIAI5Zlc5K082dGR27Fczjb3Q57ECcXefKU/f0ajM5ToM0P+N9NmJWip8GmGu/g6QISNT+K6KYB+iSHjXCQ==", + "version": "5.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.33.0.tgz", + "integrity": "sha512-JxOAnXt9oZjXLIiXb5ZIcZXiwVHCkqZgof0O8KPgz7C7y0HS42gi75PdPlqh1Tf109M0fyUw45Ao6JLo7S5AHw==", "dev": true, "requires": { "@types/json-schema": "^7.0.9", - "@typescript-eslint/scope-manager": "5.32.0", - "@typescript-eslint/types": "5.32.0", - "@typescript-eslint/typescript-estree": "5.32.0", + "@typescript-eslint/scope-manager": "5.33.0", + "@typescript-eslint/types": "5.33.0", + "@typescript-eslint/typescript-estree": "5.33.0", "eslint-scope": "^5.1.1", "eslint-utils": "^3.0.0" } }, "@typescript-eslint/visitor-keys": { - "version": "5.32.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.32.0.tgz", - "integrity": "sha512-S54xOHZgfThiZ38/ZGTgB2rqx51CMJ5MCfVT2IplK4Q7hgzGfe0nLzLCcenDnc/cSjP568hdeKfeDcBgqNHD/g==", + "version": "5.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.33.0.tgz", + "integrity": "sha512-/XsqCzD4t+Y9p5wd9HZiptuGKBlaZO5showwqODii5C0nZawxWLF+Q6k5wYHBrQv96h6GYKyqqMHCSTqta8Kiw==", "dev": true, "requires": { - "@typescript-eslint/types": "5.32.0", + "@typescript-eslint/types": "5.33.0", "eslint-visitor-keys": "^3.3.0" } }, @@ -12042,6 +12217,12 @@ "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", "dev": true }, + "builtin-modules": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", + "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", + "dev": true + }, "bytes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", @@ -12156,9 +12337,9 @@ "dev": true }, "ci-info": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.3.0.tgz", - "integrity": "sha512-riT/3vI5YpVH6/qomlDnJow6TBee2PBKSEpx3O32EGPYbWGIRsIlGRms3Sm74wYE1JMo8RnO04Hb12+v1J5ICw==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.3.2.tgz", + "integrity": "sha512-xmDt/QIAdeZ9+nfdPsaBCpMvHNLFiLdjj59qjqn+6iPe6YmHGQ35sBnQ8uslRBXFmXkiZQOJRjvQeoGppoTjjg==", "dev": true }, "cjs-module-lexer": { @@ -12167,6 +12348,15 @@ "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==", "dev": true }, + "clean-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/clean-regexp/-/clean-regexp-1.0.0.tgz", + "integrity": "sha512-GfisEZEJvzKrmGWkvfhgzcz/BllN1USeqD2V6tg14OAOgaCD2Z/PUEuxnAZ/nPvmaHRG7a8y77p1T/IRQ4D1Hw==", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, "cli-boxes": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-3.0.0.tgz", @@ -12183,9 +12373,9 @@ } }, "cli-spinners": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.6.1.tgz", - "integrity": "sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.7.0.tgz", + "integrity": "sha512-qu3pN8Y3qHNgE2AFweciB1IfMnmZ/fsNTEE+NOFjmGB2F/7rLhnhzppvpCnN4FovtP26k8lHyy9ptEbNwWFLzw==", "dev": true }, "cli-width": { @@ -13326,9 +13516,9 @@ } }, "eslint-plugin-jest": { - "version": "26.7.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-26.7.0.tgz", - "integrity": "sha512-/YNitdfG3o3cC6juZziAdkk6nfJt01jXVfj4AgaYVLs7bupHzRDL5K+eipdzhDXtQsiqaX1TzfwSuRlEgeln1A==", + "version": "26.8.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-26.8.2.tgz", + "integrity": "sha512-67oh0FKaku9y48OpLzL3uK9ckrgLb83Sp5gxxTbtOGDw9lq6D8jw/Psj/9CipkbK406I2M7mvx1q+pv/MdbvxA==", "dev": true, "requires": { "@typescript-eslint/utils": "^5.10.0" @@ -13343,6 +13533,93 @@ "prettier-linter-helpers": "^1.0.0" } }, + "eslint-plugin-unicorn": { + "version": "43.0.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-43.0.2.tgz", + "integrity": "sha512-DtqZ5mf/GMlfWoz1abIjq5jZfaFuHzGBZYIeuJfEoKKGWRHr2JiJR+ea+BF7Wx2N1PPRoT/2fwgiK1NnmNE3Hg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.18.6", + "ci-info": "^3.3.2", + "clean-regexp": "^1.0.0", + "eslint-utils": "^3.0.0", + "esquery": "^1.4.0", + "indent-string": "^4.0.0", + "is-builtin-module": "^3.1.0", + "lodash": "^4.17.21", + "pluralize": "^8.0.0", + "read-pkg-up": "^7.0.1", + "regexp-tree": "^0.1.24", + "safe-regex": "^2.1.1", + "semver": "^7.3.7", + "strip-indent": "^3.0.0" + }, + "dependencies": { + "hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "requires": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "dependencies": { + "type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true + } + } + }, + "read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "requires": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + } + }, + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true + } + } + }, "eslint-scope": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", @@ -13993,9 +14270,9 @@ "dev": true }, "got": { - "version": "12.2.0", - "resolved": "https://registry.npmjs.org/got/-/got-12.2.0.tgz", - "integrity": "sha512-A81ll5Z8wzeCmSdIlWVMDWFKDo82v2nmOaMZDQNHKGInNqDBcle+CSb6BBiZcn/Aiefz/kSpo520WBKi9QAO/A==", + "version": "12.3.1", + "resolved": "https://registry.npmjs.org/got/-/got-12.3.1.tgz", + "integrity": "sha512-tS6+JMhBh4iXMSXF6KkIsRxmloPln31QHDlcb6Ec3bzxjjFJFr/8aXdpyuLmVc9I4i2HyBHYw1QU5K1ruUdpkw==", "dev": true, "requires": { "@sindresorhus/is": "^5.2.0", @@ -14248,9 +14525,9 @@ "dev": true }, "inquirer": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-9.0.2.tgz", - "integrity": "sha512-AqmDHmz3bIe573OiM4svTZzajBzff1xpuzYAimW8gjzW5ncuPllWB8t/GKl+NSuKRJaKyIF2bU2RCx8H1dwqyQ==", + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-9.1.0.tgz", + "integrity": "sha512-eukdjrBljg9t55ZnvJjvGi1OyYEzVBFsO/8o5d2MV3mc28u3x4X2kS4eJ/+9U10KiREfPkEBSeCrU/S2G/uRtw==", "dev": true, "requires": { "ansi-escapes": "^5.0.0", @@ -14400,6 +14677,15 @@ "has-tostringtag": "^1.0.0" } }, + "is-builtin-module": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.0.tgz", + "integrity": "sha512-phDA4oSGt7vl1n5tJvTWooWWAsXLY+2xCnxNqvKhGEzujg+A43wPlPOyDg3C8XQHN+6k/JTQWJ/j0dQh/qr+Hw==", + "dev": true, + "requires": { + "builtin-modules": "^3.3.0" + } + }, "is-callable": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", @@ -15735,9 +16021,9 @@ "dev": true }, "node-fetch": { - "version": "3.2.9", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.2.9.tgz", - "integrity": "sha512-/2lI+DBecVvVm9tDhjziTVjo2wmTsSxSk58saUYP0P/fRJ3xxtfMDY24+CKTkfm0Dlhyn3CSXNL0SoRiCZ8Rzg==", + "version": "3.2.10", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.2.10.tgz", + "integrity": "sha512-MhuzNwdURnZ1Cp4XTazr69K0BTizsBroX7Zx3UgDSVcZYKF/6p0CBe4EUb/hLqmzVhl0UpYfgRljQ4yxE+iCxA==", "dev": true, "requires": { "data-uri-to-buffer": "^4.0.0", @@ -16107,6 +16393,12 @@ "find-up": "^4.0.0" } }, + "pluralize": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", + "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==", + "dev": true + }, "prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -16129,9 +16421,9 @@ } }, "prettier-plugin-organize-imports": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/prettier-plugin-organize-imports/-/prettier-plugin-organize-imports-3.0.1.tgz", - "integrity": "sha512-pdMWKtoHRQ+9y1WB3mA1wzMkjzJzB4ycfOPlfZpmzq+YFZQIpkszJJQQHQ8EYVyULlLohlOnAxSmXfaKWpRAAw==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/prettier-plugin-organize-imports/-/prettier-plugin-organize-imports-3.0.3.tgz", + "integrity": "sha512-eu8PhJR39UZamhRdLEBJhUKG/sg0s+bnjwnN5Lc1TByZUHBtMuS9tBstnyaKGTSiMLhhftRPr0yIWG+PmJ13MA==", "dev": true, "requires": {} }, @@ -16471,6 +16763,12 @@ "strip-indent": "^3.0.0" } }, + "regexp-tree": { + "version": "0.1.24", + "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.24.tgz", + "integrity": "sha512-s2aEVuLhvnVJW6s/iPgEGK6R+/xngd2jNQ+xy4bXNDKxZKJH6jpPHY6kVeVv1IeLCHgswRj+Kl3ELaDjG6V1iw==", + "dev": true + }, "regexp.prototype.flags": { "version": "1.4.3", "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", @@ -16507,9 +16805,9 @@ } }, "release-it": { - "version": "15.2.0", - "resolved": "https://registry.npmjs.org/release-it/-/release-it-15.2.0.tgz", - "integrity": "sha512-zVtk/+BSX941e9lR2dhWGQhOIVdr98Fifgel4xUnsJVycU0uTtalOUhjoZM2jyDgcD22idmuDVgvgOTl9IyJ/g==", + "version": "15.3.0", + "resolved": "https://registry.npmjs.org/release-it/-/release-it-15.3.0.tgz", + "integrity": "sha512-MI4EBGca+y4SskgBkWNIakFp/GvXfpZEMWkmqmsysPcou/L+E+sKd0oy33ovGCyLic+9SI2rv/lQ3ACgonmqdQ==", "dev": true, "requires": { "@iarna/toml": "2.2.5", @@ -16521,13 +16819,13 @@ "form-data": "4.0.0", "git-url-parse": "12.0.0", "globby": "13.1.2", - "got": "12.2.0", - "inquirer": "9.0.2", + "got": "12.3.1", + "inquirer": "9.1.0", "is-ci": "3.0.1", "lodash": "4.17.21", "mime-types": "2.1.35", "new-github-release-url": "2.0.0", - "node-fetch": "3.2.9", + "node-fetch": "3.2.10", "open": "8.4.0", "ora": "6.1.2", "os-name": "5.0.1", @@ -16538,7 +16836,7 @@ "update-notifier": "6.0.2", "url-join": "5.0.0", "wildcard-match": "5.1.2", - "yargs-parser": "21.0.1" + "yargs-parser": "21.1.1" }, "dependencies": { "chalk": { @@ -16632,9 +16930,9 @@ "dev": true }, "yargs-parser": { - "version": "21.0.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.0.1.tgz", - "integrity": "sha512-9BK1jFpLzJROCI5TzwZL/TU4gqjK5xiHV/RfWLOahrjAko/e4DJkRDZQXfvqAsiZzzYhgAzbgz6lg48jcm4GLg==", + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", "dev": true } } @@ -16777,6 +17075,15 @@ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "dev": true }, + "safe-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-2.1.1.tgz", + "integrity": "sha512-rx+x8AMzKb5Q5lQ95Zoi6ZbJqwCLkqi3XuJXp5P3rT8OEc6sZCJG5AE5dU3lsgRr/F4Bs31jSlVN+j5KrsGu9A==", + "dev": true, + "requires": { + "regexp-tree": "~0.1.1" + } + }, "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", diff --git a/package.json b/package.json index a88c27a..3adc664 100644 --- a/package.json +++ b/package.json @@ -42,34 +42,39 @@ "internationalization" ], "scripts": { - "build": "npm run prettier && npm run lint && rm -Rf ./lib && tsc && npm run add-import-type && npm test", - "lint": "eslint --ext .js --ext .jsx --ext .ts --ext .tsx --fix .", + "build": "npm run prettier && npm run lint-fix && rm -Rf ./lib && tsc && npm run add-import-type && npm test", + "lint-fix": "eslint --ext .js --ext .jsx --ext .ts --ext .tsx --fix .", + "lint-check": "eslint --ext .js --ext .jsx --ext .ts --ext .tsx .", "lint-print-config": "eslint --print-config ./eslintrc.yaml", "prettier": "prettier --write .", - "add-import-type": "node ./src/add-import-type", + "add-import-type": "node ./src/add-import-type.mjs", "test": "jest --coverage", "release": "dotenv -- release-it --only-version" }, "devDependencies": { "@release-it/conventional-changelog": "^5.0.0", "@types/jest": "^28.1.6", - "@typescript-eslint/eslint-plugin": "^5.32.0", - "@typescript-eslint/parser": "^5.32.0", + "@typescript-eslint/eslint-plugin": "^5.33.0", + "@typescript-eslint/parser": "^5.33.0", "dotenv-cli": "^6.0.0", "eslint": "^8.21.0", "eslint-config-prettier": "^8.5.0", "eslint-import-resolver-node": "^0.3.6", "eslint-import-resolver-typescript": "^3.4.0", "eslint-plugin-import": "^2.26.0", - "eslint-plugin-jest": "^26.7.0", + "eslint-plugin-jest": "^26.8.2", "eslint-plugin-prettier": "^4.2.1", + "eslint-plugin-unicorn": "^43.0.2", "jest": "^28.1.3", "prettier": "^2.7.1", - "prettier-plugin-organize-imports": "^3.0.1", + "prettier-plugin-organize-imports": "^3.0.3", "prettier-plugin-sh": "^0.12.8", - "release-it": "^15.2.0", + "release-it": "^15.3.0", "ts-jest": "^28.0.7", "ts-node": "^10.9.1", "typescript": "^4.7.4" + }, + "engines": { + "node": "^14.18.1 || ^16.0.0" } } diff --git a/src/add-import-type.js b/src/add-import-type.mjs similarity index 96% rename from src/add-import-type.js rename to src/add-import-type.mjs index 472b245..b8d7625 100644 --- a/src/add-import-type.js +++ b/src/add-import-type.mjs @@ -1,7 +1,7 @@ /** * These extra steps are required after the build to pass the correct type when importing `.properties` file directly. */ -const { readFileSync, writeFileSync, readdirSync } = require('fs') +import { readdirSync, readFileSync, writeFileSync } from 'node:fs' /** * Add a type reference to another type file. diff --git a/src/content/index.ts b/src/content/index.ts index 43aab92..f79cbc5 100644 --- a/src/content/index.ts +++ b/src/content/index.ts @@ -12,7 +12,7 @@ import { PropertyLine } from '../property-line' */ export function getProperties(content: string): Properties { // Remove BOM character if present and create an array from lines. - const lines = (content.charCodeAt(0) === 0xfeff ? content.slice(1) : content).split(/\r?\n/) + const lines = (content.codePointAt(0) === 0xfeff ? content.slice(1) : content).split(/\r?\n/) /** Line number while parsing properties file content. */ let lineNumber = 0 diff --git a/src/file/index.ts b/src/file/index.ts index dcd5bed..27eaca0 100644 --- a/src/file/index.ts +++ b/src/file/index.ts @@ -1,4 +1,4 @@ -import { existsSync, readFileSync } from 'fs' +import { existsSync, readFileSync } from 'node:fs' import { KeyValueObject, Properties } from '../' import { getProperties as getPropertiesFromContent } from '../content/' @@ -15,10 +15,10 @@ export { KeyValueObject } from '../' */ export function getProperties(filePath: string, encoding?: BufferEncoding): Properties { if (!existsSync(filePath)) { - throw Error(`file not found at ${filePath}`) + throw new Error(`file not found at ${filePath}`) } - return getPropertiesFromContent(readFileSync(filePath, encoding ? encoding : 'utf-8')) + return getPropertiesFromContent(readFileSync(filePath, encoding ?? 'utf8')) } /** diff --git a/src/properties.ts b/src/properties.ts index 4a256b9..ed25e2c 100644 --- a/src/properties.ts +++ b/src/properties.ts @@ -5,10 +5,10 @@ import { Property } from './property' * A class representing the content of a .properties file. */ export class Properties { - /** Object associating keys with their starting line numbers. */ - public keyLineNumbers: KeyLineNumbers = {} /** The collection of property object. */ public collection: Property[] = [] + /** Object associating keys with their starting line numbers. */ + public keyLineNumbers: KeyLineNumbers = {} /** * Add a property object into a properties object collection. @@ -42,19 +42,6 @@ export class Properties { return undefined } - /** - * Get the JSON (key/value) representation of the properties. - * - * @returns A key/value representing the properties of the object. - */ - public toJson(): KeyValueObject { - const keyValueObject: KeyValueObject = {} - this.collection.forEach((property) => { - keyValueObject[property.key] = property.value - }) - return keyValueObject - } - /** * Get keys that have collisions (more than one occurrence). */ @@ -67,6 +54,19 @@ export class Properties { } return keyCollisions } + + /** + * Get the JSON (key/value) representation of the properties. + * + * @returns A key/value representing the properties of the object. + */ + public toJson(): KeyValueObject { + const keyValueObject: KeyValueObject = {} + this.collection.forEach((property) => { + keyValueObject[property.key] = property.value + }) + return keyValueObject + } } /** diff --git a/src/property-line.ts b/src/property-line.ts index 04025b6..b693665 100644 --- a/src/property-line.ts +++ b/src/property-line.ts @@ -4,14 +4,14 @@ export class PropertyLine { /** The line content, minus the trailing \ that identifies that the line continues. */ public content: string - /** Is the line object a continuation from a previous line? */ - public isMultiline: boolean /** True if the line continues, otherwise false. */ public continues = false - /** True if the line is a comment, otherwise false. */ - public isComment = false /** True if the line is blank, otherwise false. */ public isBlank = false + /** True if the line is a comment, otherwise false. */ + public isComment = false + /** Is the line object a continuation from a previous line? */ + public isMultiline: boolean /** * Create a new line object. @@ -23,13 +23,13 @@ export class PropertyLine { this.content = line.trimStart() this.isMultiline = isMultiline - if (!this.content.length) { + if (this.content.length === 0) { // Line is blank. this.isBlank = true } else { if (!this.isMultiline) { // Line is a comment. - this.isComment = !!this.content.match(/^[!#]/) + this.isComment = !!/^[!#]/.test(this.content) } if (!this.isComment) { // Otherwise, check if the line continues on the next line. diff --git a/src/property.ts b/src/property.ts index 8b63916..ce1ecb8 100644 --- a/src/property.ts +++ b/src/property.ts @@ -4,31 +4,29 @@ import { PropertyLine } from './property-line' * Object representing a property (key/value). */ export class Property { - /** The line number at which the property starts. */ - public startingLineNumber: number - /** The content of one or multiple lines when applicable. */ - public linesContent: string - /** Positions of the newline characters if any. */ - public newlinePositions: number[] = [] - /** Starting line numbers of property objects with the same key. */ - public keyCollisionLines: number[] = [] - /** The starting position of the delimiter separating the key from the value. */ - public delimiterPosition: number | undefined /** The length of the delimiter, including its whitespace characters. */ public delimiterLength: number | undefined - + /** The starting position of the delimiter separating the key from the value. */ + public delimiterPosition: number | undefined /** The property key, including its escaped characters. */ public escapedKey = '' /** The property value, including its escaped characters. */ public escapedValue = '' - + /** Was the property's key used more than once? */ + public hasKeyCollisions = false /** The property key (unescaped). */ public key = '' + /** Starting line numbers of property objects with the same key. */ + public keyCollisionLines: number[] = [] + /** The content of one or multiple lines when applicable. */ + public linesContent: string + /** Positions of the newline characters if any. */ + public newlinePositions: number[] = [] + /** The line number at which the property starts. */ + public startingLineNumber: number /** The property value (unescaped). */ public value = '' - /** Was the property's key used more than once? */ - public hasKeyCollisions = false /** Does the key definition spread across multiple lines? */ private hasMultilineKey = false /** Is the key empty? */ @@ -53,7 +51,7 @@ export class Property { * @param propertyLine - A property line object. */ public addLine(propertyLine: PropertyLine): void { - if (this.linesContent.length) { + if (this.linesContent.length > 0) { this.newlinePositions.push(this.linesContent.length) } this.linesContent += propertyLine.content @@ -68,15 +66,13 @@ export class Property { if (this.delimiterPosition !== undefined && this.delimiterLength !== undefined) { // Set key if present. if (!this.hasNoKey) { - this.escapedKey = this.linesContent.substring(0, this.delimiterPosition) + this.escapedKey = this.linesContent.slice(0, this.delimiterPosition) this.key = this.unescape(this.escapedKey, this.startingLineNumber) } // Set value if present. if (!this.hasNoValue) { - this.escapedValue = this.linesContent.substring( - this.delimiterPosition + this.delimiterLength - ) + this.escapedValue = this.linesContent.slice(this.delimiterPosition + this.delimiterLength) this.value = this.unescape(this.escapedValue, this.startingLineNumber) } } else if (this.hasNoValue) { @@ -97,44 +93,56 @@ export class Property { public unescape(escapedContent: string, startingLineNumber: number): string { let unescapedContent = '' for ( - let position = 0, character = escapedContent[0]; + let character = escapedContent[0], position = 0; position < escapedContent.length; position++, character = escapedContent[position] ) { if (character === '\\') { const nextCharacter = escapedContent[position + 1] - if (nextCharacter === 'f') { - // Formfeed/ - unescapedContent += '\f' - position++ - } else if (nextCharacter === 'n') { - // Newline. - unescapedContent += '\n' - position++ - } else if (nextCharacter === 'r') { - // Carriage return. - unescapedContent += '\r' - position++ - } else if (nextCharacter === 't') { - // Tab. - unescapedContent += '\t' - position++ - } else if (nextCharacter === 'u') { - // Unicode character. - const codePoint = escapedContent.substring(position + 2, position + 6) - if (!/[0-9a-f]{4}/i.test(codePoint)) { - // Code point can only be within Unicode's Multilingual Plane (BMP). - throw new Error( - `malformed escaped unicode characters '\\u${codePoint}' in property starting at line ${startingLineNumber}` - ) + switch (nextCharacter) { + case 'f': { + // Formfeed/ + unescapedContent += '\f' + position++ + break + } + case 'n': { + // Newline. + unescapedContent += '\n' + position++ + break + } + case 'r': { + // Carriage return. + unescapedContent += '\r' + position++ + break + } + case 't': { + // Tab. + unescapedContent += '\t' + position++ + break + } + case 'u': { + // Unicode character. + const codePoint = escapedContent.slice(position + 2, position + 6) + if (!/[\da-f]{4}/i.test(codePoint)) { + // Code point can only be within Unicode's Multilingual Plane (BMP). + throw new Error( + `malformed escaped unicode characters '\\u${codePoint}' in property starting at line ${startingLineNumber}` + ) + } + unescapedContent += String.fromCodePoint(Number.parseInt(codePoint, 16)) + position += 5 + break + } + default: { + // Otherwise the escape character is not required. + unescapedContent += nextCharacter + position++ } - unescapedContent += String.fromCharCode(parseInt(codePoint, 16)) - position += 5 - } else { - // Otherwise the escape character is not required. - unescapedContent += nextCharacter - position++ } } else { // When there is \, simply add the character. @@ -155,19 +163,19 @@ export class Property { } for ( - let position = 0, character = this.linesContent[0]; + let character = this.linesContent[0], position = 0; position < this.linesContent.length; position++, character = this.linesContent[position] ) { // If the character is not a delimiter, check the next one. - if (!/[ \t\f=:]/.test(character)) { + if (!/[\t\f :=]/.test(character)) { continue } // Check if the delimiter might be escaped. - const prefix = !position ? '' : this.linesContent.substring(0, position) + const prefix = !position ? '' : this.linesContent.slice(0, position) - if (prefix.length) { + if (prefix.length > 0) { const backslashMatch = prefix.match(/(?\\+)$/) if (backslashMatch?.groups) { const delimiterIsEscaped = !!(backslashMatch.groups.backslashes.length % 2) @@ -180,23 +188,25 @@ export class Property { let delimiter = '' this.delimiterPosition = position - this.hasMultilineKey = !!(this.newlinePositions.length && this.newlinePositions[0] > position) + this.hasMultilineKey = !!( + this.newlinePositions.length > 0 && this.newlinePositions[0] > position + ) // Check if the delimiter starts with a whitespace. - let nextContent = this.linesContent.substring(position) + let nextContent = this.linesContent.slice(position) const leadingWhitespaceMatch = nextContent.match(/^(?\s+)/) const leadingWhitespace = leadingWhitespaceMatch?.groups?.whitespace || '' // If there is a whitespace, move to the next character. - if (leadingWhitespace.length) { + if (leadingWhitespace.length > 0) { delimiter += leadingWhitespace - nextContent = nextContent.substring(leadingWhitespace.length) + nextContent = nextContent.slice(leadingWhitespace.length) } // Check if there is an equal or colon character. - if (/[=:]/.test(nextContent[0])) { + if (/[:=]/.test(nextContent[0])) { delimiter += nextContent[0] - nextContent = nextContent.substring(1) + nextContent = nextContent.slice(1) // If an equal or colon character was found, try to get trailing whitespace. const trailingWhitespaceMatch = nextContent.match(/^(?\s+)/) const trailingWhitespace = trailingWhitespaceMatch?.groups?.whitespace || '' @@ -218,7 +228,7 @@ export class Property { this.hasNoValue = true } else { // If the delimiter is after the first newline, mark the key as multiline. - if (this.newlinePositions.length) { + if (this.newlinePositions.length > 0) { const firstLinePosition = this.newlinePositions[0] if (firstLinePosition > this.delimiterPosition) { this.hasMultilineKey = true diff --git a/tests/properties-file.test.ts b/tests/properties-file.test.ts index 07912dc..bf836ad 100644 --- a/tests/properties-file.test.ts +++ b/tests/properties-file.test.ts @@ -1,4 +1,4 @@ -import { readFileSync } from 'fs' +import { readFileSync } from 'node:fs' import { getProperties, Properties, propertiesToJson, Property, PropertyLine } from '../src' import { @@ -16,7 +16,7 @@ describe('The test properties file', () => { let output = '' for (const property of properties.collection) { - output += `${output.length ? '\r\n' : ''}${property.key} => '${property.value}'` + output += `${output.length > 0 ? '\r\n' : ''}${property.key} => '${property.value}'` } const javaOutput = readFileSync('assets/tests/test-all-java-console-output', 'utf8')