diff --git a/.github/workflows/npm-publish.yml b/.github/workflows/npm-publish.yml index e1abe0b..d904994 100644 --- a/.github/workflows/npm-publish.yml +++ b/.github/workflows/npm-publish.yml @@ -10,21 +10,21 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - with: - persist-credentials: false + - uses: actions/checkout@v4 + with: + persist-credentials: false - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: 22 - registry-url: 'https://registry.npmjs.org' + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: 22 + registry-url: 'https://registry.npmjs.org' - - run: npm ci - - run: npm run build - - run: npm run build:types + - run: npm ci + - run: npm run build + - run: npm run build:types - - name: Publish to NPM - run: npm publish - env: - NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + - name: Publish to NPM + run: npm publish + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index e0069c2..c28469b 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -15,37 +15,37 @@ jobs: node: [18, 20, 22] steps: - - uses: actions/checkout@v4 - with: - persist-credentials: false - - - name: Setup Node.js ${{ matrix.node }} - uses: actions/setup-node@v4 - with: - node-version: ${{ matrix.node }} - cache: 'npm' - - - run: npm ci - - run: npm run lint - - run: npm run build - - run: npm run coverage - - - name: Coveralls Parallel - uses: coverallsapp/github-action@v2 - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - flag-name: ${{ matrix.node }} - parallel: true - - - run: npm publish --dry-run + - uses: actions/checkout@v4 + with: + persist-credentials: false + + - name: Setup Node.js ${{ matrix.node }} + uses: actions/setup-node@v4 + with: + node-version: ${{ matrix.node }} + cache: 'npm' + + - run: npm ci + - run: npm run lint + - run: npm run build + - run: npm run coverage + + - name: Coveralls Parallel + uses: coverallsapp/github-action@v2 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + flag-name: ${{ matrix.node }} + parallel: true + + - run: npm publish --dry-run finish: needs: build runs-on: ubuntu-latest steps: - - name: Coveralls Finished - uses: coverallsapp/github-action@v2 - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - parallel-finished: true - carryforward: "18,20,22" + - name: Coveralls Finished + uses: coverallsapp/github-action@v2 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + parallel-finished: true + carryforward: '18,20,22' diff --git a/.gitignore b/.gitignore index 8a6ff74..98fdb7e 100644 --- a/.gitignore +++ b/.gitignore @@ -63,7 +63,10 @@ typings/ .env # next.js build output -.next +.next/ # VSCode project config -.vscode +.vscode/ + +# JSDoc +docs/ diff --git a/bench.js b/bench.js index 4ec29c9..118bbb8 100644 --- a/bench.js +++ b/bench.js @@ -1,5 +1,5 @@ import Benchmark from 'benchmark'; -import * as fs from 'node:fs'; +import { existsSync, readdirSync } from 'node:fs'; import chalk from 'chalk'; const suite = new Benchmark.Suite(); @@ -24,23 +24,23 @@ for (let index = 1; index < arguments_.length; index++) { // If language is defined if (i18n) { // Check if language file exists - if (fs.existsSync('./lib/i18n/' + i18n + '.js')) { + if (existsSync('./lib/i18n/' + i18n + '.js')) { // Queue specific language benchmark - await benchLanguage(i18n); + await benchFile('i18n/' + i18n); } else { // Log error to console console.error(chalk.red('\ni18n language file does not exist: ' + i18n + '.js\n')); } } else { // Load all files in language directory - const files = fs.readdirSync('./lib/i18n'); + const files = readdirSync('./lib/i18n'); // Loop through files for (const file of files) { // Make sure file is JavaScript if (file.includes('.js')) { // Queue language file benchmark - await benchLanguage(file.replace('.js', '')); + await benchFile('i18n/' + file.replace('.js', '')); } } } @@ -55,12 +55,13 @@ suite /** * Queue language test file for benchmarking. - * @param {string} i18n Language identifier. + * @param {string} file Library file. + * @param {object} options Options for language file. */ -async function benchLanguage(i18n) { - const { default: language } = await import('./lib/i18n/' + i18n + '.js'); +async function benchFile(file, options) { + const { default: n2words } = await import('./lib/' + file + '.js'); - suite.add(i18n, () => { - language(value); + suite.add(file, async () => { + n2words(value, options); }); } diff --git a/conf.json b/conf.json new file mode 100644 index 0000000..cc9e228 --- /dev/null +++ b/conf.json @@ -0,0 +1,16 @@ +{ + "plugins": [ + "plugins/markdown" + ], + "source": { + "include": [ + "./README.md", + "./lib" + ], + "includePattern": ".+\\.js(doc|x)?$" + }, + "opts": { + "destination": "./docs/", + "recurse": true + } +} diff --git a/examples/node.js b/examples/node.js index af7ba4f..ea3ce6e 100644 --- a/examples/node.js +++ b/examples/node.js @@ -15,9 +15,7 @@ if (fs.existsSync('./lib/i18n/' + lang + '.js')) { const { default: n2words } = await import('../lib/i18n/' + lang + '.js'); - const result = n2words(value, { - lang: lang - }); + const result = n2words(value); console.log('\n' + chalk.bold(result) + '\n'); } else { diff --git a/lib/classes/abstract-language.js b/lib/classes/abstract-language.js index e6ab007..8f8a799 100644 --- a/lib/classes/abstract-language.js +++ b/lib/classes/abstract-language.js @@ -1,8 +1,8 @@ /** - * Creates new language class that processes decimals separately. + * Creates new common language class that processes decimals separately. * Requires implementing `toCardinal`. */ -export default class AbstractLanguage { +class AbstractLanguage { #negativeWord; #separatorWord; #zero; @@ -156,3 +156,5 @@ export default class AbstractLanguage { return words.join(this.spaceSeparator); } } + +export default AbstractLanguage; diff --git a/lib/classes/base-language.js b/lib/classes/base-language.js index 77057e0..5d8f6b7 100644 --- a/lib/classes/base-language.js +++ b/lib/classes/base-language.js @@ -4,9 +4,8 @@ import AbstractLanguage from './abstract-language.js'; * Creates new common language class that uses a highest matching word value algorithm. * Number matching word {@link cards} must be provided for this to work. * See {@link AbstractLanguage} for further requirements. - * @classdesc Common class for (mostly european) languages. */ -export default class BaseLanguage extends AbstractLanguage { +class BaseLanguage extends AbstractLanguage { #cards; /** @@ -24,15 +23,7 @@ export default class BaseLanguage extends AbstractLanguage { } /** - * Get array of number matching "cards" from highest-to-lowest. - * @returns {Array} Array of number matching "cards" from highest-to-lowest. - */ - get cards() { - return this.#cards; - } - - /** - * Set array of number matching "cards" from highest-to-lowest. + * Array of number matching "cards" from highest-to-lowest. * First element in card array is the number to match while the second is the word to use. * @example * [ @@ -41,7 +32,12 @@ export default class BaseLanguage extends AbstractLanguage { * ... * [1, 'one'], * ] + * @type {Array} */ + get cards() { + return this.#cards; + } + set cards(value) { this.#cards = value; } @@ -172,3 +168,5 @@ export default class BaseLanguage extends AbstractLanguage { return this.postClean(preWords); } } + +export default BaseLanguage; diff --git a/lib/n2words.js b/lib/n2words.js index 93c3de3..f71c6de 100644 --- a/lib/n2words.js +++ b/lib/n2words.js @@ -1,3 +1,7 @@ +/** + * @module n2words + */ + import n2wordsAR from './i18n/ar.js'; import n2wordsAZ from './i18n/az.js'; import n2wordsCZ from './i18n/cz.js'; @@ -66,7 +70,7 @@ const dict = { * TODO [2024-06] Migrate to object destructing for parameters */ // eslint-disable-next-line unicorn/no-object-as-default-parameter -export default function floatToCardinal(value, options = { lang: 'en' }) { +function floatToCardinal(value, options = { lang: 'en' }) { const function_ = dict[options.lang]; if (function_ != undefined) return function_(value, options); @@ -77,3 +81,5 @@ export default function floatToCardinal(value, options = { lang: 'en' }) { throw new Error('Unsupported language: ' + value + '.'); } + +export default floatToCardinal; diff --git a/package-lock.json b/package-lock.json index 43e4f34..16bea0f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22,9 +22,10 @@ "core-js": "^3.37.1", "eslint": "^9.6.0", "eslint-plugin-ava": "^15.0.1", - "eslint-plugin-jsdoc": "^48.5.0", + "eslint-plugin-jsdoc": "^48.5.2", "eslint-plugin-n": "^17.9.0", "eslint-plugin-unicorn": "^54.0.0", + "jsdoc": "^4.0.3", "markdownlint-cli2": "^0.13.0", "microtime": "^3.1.1", "selenium-webdriver": "^4.22.0", @@ -2206,6 +2207,19 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@jsdoc/salty": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/@jsdoc/salty/-/salty-0.2.8.tgz", + "integrity": "sha512-5e+SFVavj1ORKlKaKr2BmTOekmXbelU7dC0cDkQLqag7xfuTPuGMUFx7KWJuv4bYZrTsoL2Z18VVCOKYxzoHcg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "lodash": "^4.17.21" + }, + "engines": { + "node": ">=v12.0.0" + } + }, "node_modules/@mapbox/node-pre-gyp": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.11.tgz", @@ -2418,10 +2432,35 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/linkify-it": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-5.0.0.tgz", + "integrity": "sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/markdown-it": { + "version": "14.1.1", + "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-14.1.1.tgz", + "integrity": "sha512-4NpsnpYl2Gt1ljyBGrKMxFYAYvpqbnnkgP/i/g+NLpjEUa3obn1XJCur9YbEXKDAkaXqsR1LbDnGEJ0MmKFxfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/linkify-it": "^5", + "@types/mdurl": "^2" + } + }, + "node_modules/@types/mdurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-2.0.0.tgz", + "integrity": "sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/node": { - "version": "20.14.9", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.9.tgz", - "integrity": "sha512-06OCtnTXtWOZBJlRApleWndH4JsRVs1pDCc8dLSQp+7PpUpX3ePdHyeNSFTeSe7FtKyQkrlPvHwJOW3SLd8Oyg==", + "version": "20.14.10", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.10.tgz", + "integrity": "sha512-MdiXf+nDuMvY0gJKxyfZ7/6UFsETO7mGKF54MVD/ekJS6HdFtpZFBgrh6Pseu64XTb2MLyFPlbW6hj8HYRQNOQ==", "dev": true, "license": "MIT", "dependencies": { @@ -3142,6 +3181,13 @@ "file-uri-to-path": "1.0.0" } }, + "node_modules/bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true, + "license": "MIT" + }, "node_modules/blueimp-md5": { "version": "2.19.0", "resolved": "https://registry.npmjs.org/blueimp-md5/-/blueimp-md5-2.19.0.tgz", @@ -3304,6 +3350,19 @@ ], "license": "CC-BY-4.0" }, + "node_modules/catharsis": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/catharsis/-/catharsis-0.9.0.tgz", + "integrity": "sha512-prMTQVpcns/tzFgFVkVp6ak6RykZyWb3gu8ckUpd6YkTlacOd3DXGJjIpD4Q6zJirizvaiAjSSHlOsA+6sNh2A==", + "dev": true, + "license": "MIT", + "dependencies": { + "lodash": "^4.17.15" + }, + "engines": { + "node": ">= 10" + } + }, "node_modules/cbor": { "version": "9.0.2", "resolved": "https://registry.npmjs.org/cbor/-/cbor-9.0.2.tgz", @@ -3862,9 +3921,9 @@ "license": "MIT" }, "node_modules/electron-to-chromium": { - "version": "1.4.816", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.816.tgz", - "integrity": "sha512-EKH5X5oqC6hLmiS7/vYtZHZFTNdhsYG5NVPRN6Yn0kQHNBlT59+xSM8HBy66P5fxWpKgZbPqb+diC64ng295Jw==", + "version": "1.4.818", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.818.tgz", + "integrity": "sha512-eGvIk2V0dGImV9gWLq8fDfTTsCAeMDwZqEPMr+jMInxZdnp9Us8UpovYpRCf9NQ7VOFgrN2doNSgvISbsbNpxA==", "dev": true, "license": "ISC" }, @@ -4171,16 +4230,16 @@ } }, "node_modules/eslint-plugin-jsdoc": { - "version": "48.5.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-48.5.0.tgz", - "integrity": "sha512-ukXPNpGby3KjCveCizIS8t1EbuJEHYEu/tBg8GCbn/YbHcXwphyvYCdvRZ/oMRfTscGSSzfsWoZ+ZkAP0/6YMQ==", + "version": "48.5.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-48.5.2.tgz", + "integrity": "sha512-VXBJFviQz30rynlOEQ+dNWLmeopjoAgutUVrWOZwm6Ki4EVDm4XkyIqAV/Zhf7FcDr0AG0aGmRn5FxxCtAF0tA==", "dev": true, "license": "BSD-3-Clause", "dependencies": { "@es-joy/jsdoccomment": "~0.43.1", "are-docs-informative": "^0.0.2", "comment-parser": "1.4.1", - "debug": "^4.3.4", + "debug": "^4.3.5", "escape-string-regexp": "^4.0.0", "esquery": "^1.5.0", "parse-imports": "^2.1.0", @@ -5860,16 +5919,16 @@ } }, "node_modules/jackspeak": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.0.tgz", - "integrity": "sha512-JVYhQnN59LVPFCEcVa2C3CrEKYacvjRfqIQl+h8oi91aLYQVWRYbxjPcv1bUiUy/kLmQaANrYfNMCO3kuEDHfw==", + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.1.tgz", + "integrity": "sha512-U23pQPDnmYybVkYjObcuYMk43VRlMLLqLI+RdZy8s8WV8WsxO9SnqSroKaluuvcNOdCAlauKszDwd+umbot5Mg==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { "@isaacs/cliui": "^8.0.2" }, "engines": { - "node": ">=14" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -5939,6 +5998,16 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/js2xmlparser": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/js2xmlparser/-/js2xmlparser-4.0.2.tgz", + "integrity": "sha512-6n4D8gLlLf1n5mNLQPRfViYzu9RATblzPEtm1SthMX1Pjao0r9YI9nw7ZIfRxQMERS87mcswrg+r/OYrPRX6jA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "xmlcreate": "^2.0.4" + } + }, "node_modules/jsbn": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz", @@ -5946,6 +6015,36 @@ "dev": true, "license": "MIT" }, + "node_modules/jsdoc": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-4.0.3.tgz", + "integrity": "sha512-Nu7Sf35kXJ1MWDZIMAuATRQTg1iIPdzh7tqJ6jjvaU/GfDf+qi5UV8zJR3Mo+/pYFvm8mzay4+6O5EWigaQBQw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@babel/parser": "^7.20.15", + "@jsdoc/salty": "^0.2.1", + "@types/markdown-it": "^14.1.1", + "bluebird": "^3.7.2", + "catharsis": "^0.9.0", + "escape-string-regexp": "^2.0.0", + "js2xmlparser": "^4.0.2", + "klaw": "^3.0.0", + "markdown-it": "^14.1.0", + "markdown-it-anchor": "^8.6.7", + "marked": "^4.0.10", + "mkdirp": "^1.0.4", + "requizzle": "^0.2.3", + "strip-json-comments": "^3.1.0", + "underscore": "~1.13.2" + }, + "bin": { + "jsdoc": "jsdoc.js" + }, + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/jsdoc-type-pratt-parser": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-4.0.0.tgz", @@ -5956,6 +6055,16 @@ "node": ">=12.0.0" } }, + "node_modules/jsdoc/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", @@ -6096,6 +6205,16 @@ "node": ">=0.10.0" } }, + "node_modules/klaw": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/klaw/-/klaw-3.0.0.tgz", + "integrity": "sha512-0Fo5oir+O9jnXu5EefYbVK+mHMBeEVEy2cmctR1O1NECcCkPRreJKrS6Qt/j3KC2C148Dfo9i3pCmCMsdqGr0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.9" + } + }, "node_modules/levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -6241,6 +6360,17 @@ "markdown-it": "bin/markdown-it.mjs" } }, + "node_modules/markdown-it-anchor": { + "version": "8.6.7", + "resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-8.6.7.tgz", + "integrity": "sha512-FlCHFwNnutLgVTflOYHPW2pPcl2AACqVzExlkGQNsi4CJgqOHN7YTgDd4LuhgN1BFO3TS0vLAruV1Td6dwWPJA==", + "dev": true, + "license": "Unlicense", + "peerDependencies": { + "@types/markdown-it": "*", + "markdown-it": "*" + } + }, "node_modules/markdownlint": { "version": "0.34.0", "resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.34.0.tgz", @@ -6353,6 +6483,19 @@ "url": "https://github.com/sponsors/DavidAnson" } }, + "node_modules/marked": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/marked/-/marked-4.3.0.tgz", + "integrity": "sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==", + "dev": true, + "license": "MIT", + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 12" + } + }, "node_modules/matcher": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/matcher/-/matcher-5.0.0.tgz", @@ -7050,13 +7193,13 @@ } }, "node_modules/path-scurry/node_modules/lru-cache": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.3.0.tgz", - "integrity": "sha512-CQl19J/g+Hbjbv4Y3mFNNXFEL/5t/KCg8POCuUqd4rMKjGG+j1ybER83hxV58zL+dFI1PTkt3GNFSHRt+d8qEQ==", + "version": "10.3.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.3.1.tgz", + "integrity": "sha512-9/8QXrtbGeMB6LxwQd4x1tIMnsmUxMvIH/qWGsccz6bt9Uln3S+sgAaqfQNhbGA8ufzs2fHuP/yqapGgP9Hh2g==", "dev": true, "license": "ISC", "engines": { - "node": "14 || >=16.14" + "node": ">=18" } }, "node_modules/path-type": { @@ -7561,6 +7704,16 @@ "node": ">=0.10.0" } }, + "node_modules/requizzle": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/requizzle/-/requizzle-0.2.4.tgz", + "integrity": "sha512-JRrFk1D4OQ4SqovXOgdav+K8EAhSB/LJZqCz8tbX0KObcdeM15Ss59ozWMBWmmINMagCwmqn4ZNryUGpBsl6Jw==", + "dev": true, + "license": "MIT", + "dependencies": { + "lodash": "^4.17.21" + } + }, "node_modules/resolve": { "version": "1.22.8", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", @@ -8478,9 +8631,9 @@ } }, "node_modules/test-exclude/node_modules/glob": { - "version": "10.4.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.2.tgz", - "integrity": "sha512-GwMlUF6PkPo3Gk21UxkCohOv0PLcIXVtKyLlpEI28R/cO/4eNOdmLk3CMW1wROV/WR/EsZOWAfBbBOqYvs88/w==", + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.3.tgz", + "integrity": "sha512-Q38SGlYRpVtDBPSWEylRyctn7uDeTp4NQERTLiCT1FqA9JXPYWqAVmQU6qh4r/zMM5ehxTcbaO8EjhWnvEhmyg==", "dev": true, "license": "ISC", "dependencies": { @@ -8495,7 +8648,7 @@ "glob": "dist/esm/bin.mjs" }, "engines": { - "node": ">=16 || 14 >=14.18" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -8621,6 +8774,13 @@ "dev": true, "license": "MIT" }, + "node_modules/underscore": { + "version": "1.13.6", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.6.tgz", + "integrity": "sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==", + "dev": true, + "license": "MIT" + }, "node_modules/undici-types": { "version": "5.26.5", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", @@ -9354,6 +9514,13 @@ } } }, + "node_modules/xmlcreate": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/xmlcreate/-/xmlcreate-2.0.4.tgz", + "integrity": "sha512-nquOebG4sngPmGPICTS5EnxqhKbCmz5Ox5hsszI2T6U5qdrJizBc+0ilYSEjTSzU0yZcmvppztXe/5Al5fUwdg==", + "dev": true, + "license": "Apache-2.0" + }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", diff --git a/package.json b/package.json index 1a09c4e..777b6a2 100644 --- a/package.json +++ b/package.json @@ -69,6 +69,7 @@ "build": "webpack --progress", "build:types": "npx -p typescript tsc lib/n2words.js dist/n2words.js --target es6 --module nodenext --allowJs --declaration --emitDeclarationOnly", "coverage": "c8 ava", + "docs": "jsdoc -c ./conf.json", "lint": "npm run lint:js && npm run lint:md", "lint:js": "eslint lib/ test/ examples/ *.js", "lint:md": "markdownlint-cli2 *.md", @@ -108,9 +109,10 @@ "core-js": "^3.37.1", "eslint": "^9.6.0", "eslint-plugin-ava": "^15.0.1", - "eslint-plugin-jsdoc": "^48.5.0", + "eslint-plugin-jsdoc": "^48.5.2", "eslint-plugin-n": "^17.9.0", "eslint-plugin-unicorn": "^54.0.0", + "jsdoc": "^4.0.3", "markdownlint-cli2": "^0.13.0", "microtime": "^3.1.1", "selenium-webdriver": "^4.22.0", diff --git a/test/i18n.js b/test/i18n.js index d53687f..89cf088 100644 --- a/test/i18n.js +++ b/test/i18n.js @@ -3,9 +3,9 @@ import test from 'ava'; import n2words from '../lib/n2words.js'; //// eslint-disable-next-line import/no-nodejs-modules -import * as fs from 'node:fs'; +import { readdirSync } from 'node:fs'; -const files = fs.readdirSync('./test/i18n'); +const files = readdirSync('./test/i18n'); for (const file of files) { if (file.includes('.js')) { @@ -21,9 +21,9 @@ async function testLanguage(file) { const language = file.replace('.js', ''); test(language, async t => { - const testFile = await import('./i18n/' + file); + const { default: testFile } = await import('./i18n/' + file); - for (const test of testFile.default) { + for (const test of testFile) { t.is( n2words(test[0], Object.assign({ lang: language }, test[2])), test[1] diff --git a/test/import.cjs b/test/import.cjs index 353db03..6b46eec 100644 --- a/test/import.cjs +++ b/test/import.cjs @@ -2,7 +2,7 @@ const test = require('ava'); test('CommonJS', async t => { - const { default: n2words } = await import('../lib/i18n/en.js'); + const { default: n2words } = await import('../lib/n2words.js'); t.plan(2); diff --git a/test/web.js b/test/web.js index a5fdc8f..cfc49b2 100644 --- a/test/web.js +++ b/test/web.js @@ -4,10 +4,10 @@ import test from 'ava'; import { Browser, Builder, By, until } from 'selenium-webdriver'; //// eslint-disable-next-line import/no-unassigned-import import 'chromedriver'; -import * as process from 'node:process'; -import fs from 'node:fs'; +import { cwd } from 'node:process'; +import { existsSync } from 'node:fs'; -if (fs.existsSync('./dist/n2words.js')) { +if (existsSync('./dist/n2words.js')) { await testBrowser(Browser.CHROME); } else { console.error('ERROR: You must run "npm run build" first.'); @@ -21,10 +21,22 @@ if (fs.existsSync('./dist/n2words.js')) { async function testBrowser(browser) { test(browser, async t => { const driver = new Builder().forBrowser(browser).build(); - await driver.get('file://' + process.cwd() + '/test/web/index.html'); - await driver.wait(until.elementTextContains(driver.findElement(By.css('#result')), 'Result:')); + + console.log(`file://${cwd()}/test/web/index.html`); + + await driver.get(`file://${cwd()}/test/web/index.html`); + + await driver.wait( + until.elementTextContains( + driver.findElement(By.css('#result')), + 'Result:' + ) + ); + const result = await driver.findElement(By.css('#result')); - t.true(await result.getText() == 'Result: Success'); + + t.true((await result.getText()) == 'Result: Success'); + await driver.close(); }); } diff --git a/test/web/index.html b/test/web/index.html index 777fc3e..eaa29bf 100644 --- a/test/web/index.html +++ b/test/web/index.html @@ -1,19 +1,18 @@ +
+ +