diff --git a/.eslintrc.json b/.eslintrc.json deleted file mode 100644 index 711d631..0000000 --- a/.eslintrc.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "env": { - "es6": true, - "node": true - }, - "extends": "eslint:recommended", - "parserOptions": { - "ecmaVersion": 2017, - "sourceType": "module" - }, - "rules": { - "indent": [ - "error", - "tab", - { "SwitchCase": 1 } - ], - "linebreak-style": [ - "error", - "unix" - ], - "quotes": [ - "error", - "single" - ], - "semi": [ - "error", - "never" - ], - "no-console": [ - 0 - ] - } -} diff --git a/.gitignore b/.gitignore index 30bc162..85e9653 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,11 @@ -/node_modules \ No newline at end of file +# ignore build outputs +dist/ +coverage/ +build/ + +# ignore dependencies +node_modules/ + +# ignore package locks and logs +yarn.lock +*.log \ No newline at end of file diff --git a/README.md b/README.md index 644335c..340b33e 100644 --- a/README.md +++ b/README.md @@ -3,75 +3,107 @@ [![npm version](https://badge.fury.io/js/%40xivapi%2Fjs.svg)](https://badge.fury.io/js/%40xivapi%2Fjs) [![license](https://img.shields.io/github/license/xivapi/xivapi-js.svg)](LICENSE) -This is a pure JS wrapper for interacting with [XIVAPI](https://xivapi.com/) and handling all requests in a simple, promise-driven manner. +A JavaScript library for working with [XIVAPI v2](https://v2.xivapi.com/), providing a source of Final Fantasy XIV game data. It lets you fetch, search, and use FFXIV data easily in a promise-based manner. + +> [!WARNING] +> `@xivapi/js@0.4.5` (using XIVAPI v1) is now deprecated. Please use it at your own risk. We strongly recommend you update to the latest version. Migration guide and details: https://v2.xivapi.com/docs/migrate/. + +If you need help or run into any issues, please [open an issue](https://github.com/xivapi/xivapi-js/issues) on GitHub or join the [XIVAPI Discord server](https://discord.gg/MFFVHWC) for support. ## Installation -Simply add the module to your node project with `npm`: -``` -npm i @xivapi/js +```bash +npm install @xivapi/js@latest # or use yarn, pnpm, or bun ``` -## Usage +## Usage Examples + +#### 1. Importing and Initialization -Require and initialize the module in your code: ```js -const XIVAPI = require('@xivapi/js') -const xiv = new XIVAPI() -``` +import xivapi from '@xivapi/js'; -...and then check out the [wiki](https://github.com/xivapi/xivapi-js/wiki) for usage help! +// Basic instance +const xiv = new xivapi(); -If you get really stuck and need some help, or run into any problems/concerns, either open up an issue on github or join the [XIVAPI discord server](https://discord.gg/MFFVHWC) and ping/DM @kaimoe. +// With options +const xivCustom = new xivapi({ + version: "7.0", // specify game version + language: "jp", // specify language (jp, en, de, fr) + verbose: true // output more logging +}); +``` -### Examples: +#### 2. Get an Item -Find an item's ID: ```js -const getID = async () => { - //find item - let res = await xiv.search('Stuffed Khloe') +// Fetch the Gil item (item ID 1) +const item = await xiv.items.get(1); - //return item ID - return res.Results[0].ID -} +console.log(item.Name); // "Gil" (or equivalent in your language) ``` -Search for an FC and get an list of members: -```javascript -const getMembers = async () => { - //find the FC with its name and server - let res = await xiv.freecompany.search('My Fun FC', {server: 'Excalibur'}) +#### 3. Search Example - //get the FC ID - let id = res.Results[0].ID - - //get and return fc members - let fc = await xiv.freecompany.get('9231253336202687179', {data: FCM}) - return fc.FreeCompanyMembers +```js +// Find all items named "gil" +const params = { + query: 'Name~"gil"', + sheets: "Item" +}; + +const { results } = await xiv.search(params); +console.log(results[0]); + +/* +Output example: +{ + "score": 1, + "sheet": "Item", + "row_id": 1, + "fields": { + "Icon": { + "id": 65002, + "path": "ui/icon/065000/065002.tex", + "path_hr1": "ui/icon/065000/065002_hr1.tex" + }, + "Name": "Gil", + "Singular": "gil" + } } +*/ ``` -Check for character ownership using a token we generated and provided to the user: +#### 4. Using Raw XIVAPI v2 Endpoints + ```js -const verifyCharacter = async () => { - //find the character with their name and server - let res = await xiv.character.search('Kai Megumi', {server: 'excalibur'}) //case insensitive server names, btw ;) +// Fetch a raw asset file (e.g. icon image) +const asset = await xiv.data.assets.get({ + path: "ui/icon/051000/051474_hr1.tex", + format: "png" // jpg or webp also supported +}); + +// List all quests +const quests = await xiv.data.sheets.list("Quest"); +console.log(quests); + +// List available game versions +const versions = await xiv.data.versions(); +console.log(versions[0]); // e.g. "7.0" +``` - //get the character - let char = res.Results[0] +## Contributing - //return whether or not the character's lodestone bio matches our token - return char.Bio === 'example_token' -} -``` +We welcome all contributions! Whether you'd like to report a bug, suggest a feature, improve the documentation, or submit a pull request, your help is appreciated. -## Contribute +To get started, clone the repository with: `git clone https://github.com/xivapi/xivapi-js.git` -Feel free to open up issues/PRs or anything else. +Before opening a pull request, please: +- Make sure your code passes linting and all current tests (`npm run lint && npm test`). +- Clearly explain your changes and reference any relevant issues in your PR description. -Just `git clone https://github.com/xivapi/xivapi-js.git`, run `npm i`, and go to town! +If you have questions, suggestions, or want to discuss changes before contributing, feel free to open an issue! ## License -This project is open source, under the terms described in the [MIT License](LICENSE). +MIT License - see [LICENSE](LICENSE) file for details. \ No newline at end of file diff --git a/XIVAPI.js b/XIVAPI.js deleted file mode 100644 index c868c32..0000000 --- a/XIVAPI.js +++ /dev/null @@ -1,58 +0,0 @@ -const resources = require('./resources/'), - Search = require('./lib/search'), - Data = require('./lib/data'), - Character = require('./lib/character'), - FreeCompany = require('./lib/freecompany'), - Linkshell = require('./lib/linkshell'), - CWL = require('./lib/cwl'), - PvPTeam = require('./lib/pvpteam') - -class XIVAPI { - /*{ - private_key string undefined optional - language string 'en' optional - snake_case bool false optional - staging bool false optional - verbose bool false optional - } - */ - constructor(options = {}, legacyOptions = {}) { - //handle attempted use of old API key - if(typeof(options) === 'string') { - console.error('[xivapi-js] BREAKING CHANGE:\n\ -The previous API keys for XIVAPI have been phased out, and are no longer mandatory. \ -This means you\'ll have to define your key during initialization slightly differently. \ -See how in https://github.com/xivapi/xivapi-js/releases/tag/v0.1.3.\n\ -**This instance of xivapi-js will run WITHOUT an API key**') - options = legacyOptions - } - - this.endpoint = `https://${options.staging ? 'staging.' : ''}xivapi.com` - if(options.language && !resources.languages.includes(options.language)) - throw Error(`Invalid language given, must be one of: ${resources.languages}`) - - this.globalParams = {} - - for (let x of ['private_key', 'language']) { - if(typeof options[x] !== 'undefined') - this.globalParams[x] = options[x] - } - if(options.snake_case) - this.globalParams.snake_case = 1 - - this.verbose = options.verbose - - this.resources = resources - this.utils = require('./utils') - - this.search = Search.bind(this) - this.data = new Data(this) - this.character = new Character(this) - this.freecompany = new FreeCompany(this) - this.linkshell = new Linkshell(this) - this.cwl = new CWL(this) - this.pvpteam = new PvPTeam(this) - } -} - -module.exports = XIVAPI diff --git a/eslint.config.js b/eslint.config.js new file mode 100644 index 0000000..e28db0f --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,27 @@ +import js from "@eslint/js" +import globals from "globals" +import tseslint from "typescript-eslint" +import { defineConfig, globalIgnores } from "eslint/config" + +export default defineConfig([ + { + files: ["**/*.{js,mjs,cjs,ts,mts,cts}"], + plugins: { js }, + extends: ["js/recommended"], + languageOptions: { globals: globals.node }, + }, + { files: ["**/*.js"], languageOptions: { sourceType: "commonjs" } }, + globalIgnores(["tests/**/*.test.ts", "dist/**/*.js"]), + tseslint.configs.recommended, + { + rules: { + "@typescript-eslint/no-namespace": "off", + "consistent-return": 2, + "no-console": 0, + quotes: [2, "double"], + semi: [2, "never"], + "linebreak-style": [2, "unix"], + indent: [2, "tab", { SwitchCase: 1 }], + }, + }, +]) diff --git a/lib/Lib.js b/lib/Lib.js deleted file mode 100644 index 849b197..0000000 --- a/lib/Lib.js +++ /dev/null @@ -1,14 +0,0 @@ -const utils = require('../utils') - -class Lib { - constructor(parent) { - this.parent = parent - - this.req = utils.req.bind(parent) - this.reqJSON = utils.reqJSON.bind(parent) - this.makeCSV = utils.makeCSV - this.throwError = utils.throwError - } -} - -module.exports = Lib diff --git a/lib/character.js b/lib/character.js deleted file mode 100644 index 6bd18b3..0000000 --- a/lib/character.js +++ /dev/null @@ -1,35 +0,0 @@ -// https://xivapi.com/docs/Character -const Lib = require('./Lib') - -class Character extends Lib { - constructor(parent) { - super(parent) - } - - /* - { - server - page - } - */ - async search(name, params={}) { - if(!name) - throw this.throwError('character.search()', 'a name') - return this.req('/character/search', Object.assign(params, {name})) - } - - /* - { - extended - data - } - */ - async get(id, params={}) { - if(!id) - throw this.throwError('character.get()','an ID') - - return this.req(`/character/${id}`, params) - } -} - -module.exports = Character diff --git a/lib/cwl.js b/lib/cwl.js deleted file mode 100644 index d41b723..0000000 --- a/lib/cwl.js +++ /dev/null @@ -1,28 +0,0 @@ -// https://xivapi.com/docs/Linkshell -const Lib = require('./Lib') - -class CWL extends Lib { - constructor(parent) { - super(parent) - } - - /* - { - server string optional - page int optional - } - */ - async search(name, params={}) { - if(typeof(name) === 'undefined') - throw this.throwError('cwl.search()','a name') - return this.req('/linkshell/crossworld/search', Object.assign(params, {name})) - } - - async get(id) { - if(typeof(id) === 'undefined') - throw this.throwError('cwl.get()', 'an ID') - return this.req(`/linkshell/crossworld/${id}`) - } -} - -module.exports = CWL diff --git a/lib/data.js b/lib/data.js deleted file mode 100644 index a178f7a..0000000 --- a/lib/data.js +++ /dev/null @@ -1,52 +0,0 @@ -// https://xivapi.com/docs/Welcome#section-4 -const Lib = require('./Lib') - -class Content extends Lib { - constructor(parent) { - super(parent) - } - - async content() { - return this.req('/content') - } - - /* - { - limit - ids - } - */ - async list(name, params={}) { - if(typeof name==='undefined') - throw this.throwError('data.list()','a name') - - if(params.ids) - params.ids = this.parent.utils.makeCSV(params.ids) - - return this.req(`/${name}`, params) - } - - async get(name, id) { - const missing_params = [] - if(typeof name==='undefined') - missing_params.push('a name') - if(typeof id==='undefined') - missing_params.push('an ID') - if(missing_params.length>0) - throw this.throwError('data.get()', missing_params.join(',')) - - return this.req(`/${name}/${id}`) - } - - servers() { - return this.req('/servers') - } - - datacenters() { - return this.req('/servers/dc') - } - - -} - -module.exports = Content diff --git a/lib/freecompany.js b/lib/freecompany.js deleted file mode 100644 index fbe18e7..0000000 --- a/lib/freecompany.js +++ /dev/null @@ -1,37 +0,0 @@ -// https://xivapi.com/docs/Free-Company -const Lib = require('./Lib') - -class FreeCompany extends Lib { - constructor(parent) { - super(parent) - } - - /* - { - server string optional - page int optional - } - */ - async search(name, params={}) { - if(typeof(name) === 'undefined') - throw this.throwError('freecompany.search()','a name') - return this.req('/freecompany/search', Object.assign(params, {name})) - } - - /* - { - extended - data - } - */ - async get(id, params={}) { - if(typeof(id) === 'undefined') - throw this.throwError('freecompany.get()', 'an ID') - - params.data = this.makeCSV(params.data) - - return this.req(`/freecompany/${id}`, params) - } -} - -module.exports = FreeCompany diff --git a/lib/linkshell.js b/lib/linkshell.js deleted file mode 100644 index 0831f7b..0000000 --- a/lib/linkshell.js +++ /dev/null @@ -1,28 +0,0 @@ -// https://xivapi.com/docs/Linkshell -const Lib = require('./Lib') - -class Linkshell extends Lib { - constructor(parent) { - super(parent) - } - - /* - { - server string optional - page int optional - } - */ - async search(name, params={}) { - if(typeof(name) === 'undefined') - throw this.throwError('linkshell.search()','a name') - return this.req('/linkshell/search', Object.assign(params, {name})) - } - - async get(id) { - if(typeof(id) === 'undefined') - throw this.throwError('linkshell.get()', 'an ID') - return this.req(`/linkshell/${id}`) - } -} - -module.exports = Linkshell diff --git a/lib/pvpteam.js b/lib/pvpteam.js deleted file mode 100644 index 4ec4582..0000000 --- a/lib/pvpteam.js +++ /dev/null @@ -1,30 +0,0 @@ -// https://xivapi.com/docs/PVP-Team -const Lib = require('./Lib') - -class PvPTeam extends Lib { - constructor(parent) { - super(parent) - } - - /* - { - server string optional - page int optional - } - */ - async search(name, params={}) { - if(typeof name==='undefined') - throw this.throwError('pvpteam.search()', 'a name') - - return this.req('/pvpteam/search',Object.assign(params, {name})) - } - - async get(id) { - if(typeof id==='undefined') - throw this.throwError('pvpteam.get()', 'an ID') - - return this.req(`/pvpteam/${id}`) - } -} - -module.exports = PvPTeam diff --git a/lib/search.js b/lib/search.js deleted file mode 100644 index ed9d36b..0000000 --- a/lib/search.js +++ /dev/null @@ -1,37 +0,0 @@ -let { req, reqJSON, makeCSV, throwError } = require('../utils') - -/* -{ - filters - lore - - string_column - string_algo - limit -} -*/ -module.exports = async function(input, params = {}) { - req = req.bind(this) - reqJSON = reqJSON.bind(this) - - if(typeof(input) === 'undefined') - throw throwError('search()', 'any input') - - let path = params.lore ? '/lore' : '/search' - - switch(typeof(input)) { - // GET method - case 'string': - params.indexes = makeCSV(params.indexes) - return req(path, Object.assign(params, {'string': input})) - - // ElasticSearch JSON method - case 'object': - input.indexes = makeCSV(params.indexes) - input.columns = makeCSV(params.columns) - return reqJSON(path, input) - - default: - throw new Error(`Unexpected input type for search: '${typeof(input)}'`) - } -} diff --git a/package-lock.json b/package-lock.json index d68490c..ca2e894 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,29 +1,3334 @@ { "name": "@xivapi/js", "version": "0.4.5", - "lockfileVersion": 2, + "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@xivapi/js", "version": "0.4.5", "license": "MIT", + "devDependencies": { + "@eslint/js": "^9.38.0", + "@types/node": "^24.7.2", + "eslint": "^9.37.0", + "globals": "^16.4.0", + "ts-node": "^10.9.2", + "typescript": "^5.9.3", + "typescript-eslint": "^8.46.1", + "vitest": "^3.2.4" + } + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.10.tgz", + "integrity": "sha512-0NFWnA+7l41irNuaSVlLfgNT12caWJVLzp5eAVhZ0z1qpxbockccEt3s+149rE64VUI3Ml2zt8Nv5JVc4QXTsw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.10.tgz", + "integrity": "sha512-dQAxF1dW1C3zpeCDc5KqIYuZ1tgAdRXNoZP7vkBIRtKZPYe2xVr/d3SkirklCHudW1B45tGiUlz2pUWDfbDD4w==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.10.tgz", + "integrity": "sha512-LSQa7eDahypv/VO6WKohZGPSJDq5OVOo3UoFR1E4t4Gj1W7zEQMUhI+lo81H+DtB+kP+tDgBp+M4oNCwp6kffg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.10.tgz", + "integrity": "sha512-MiC9CWdPrfhibcXwr39p9ha1x0lZJ9KaVfvzA0Wxwz9ETX4v5CHfF09bx935nHlhi+MxhA63dKRRQLiVgSUtEg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.10.tgz", + "integrity": "sha512-JC74bdXcQEpW9KkV326WpZZjLguSZ3DfS8wrrvPMHgQOIEIG/sPXEN/V8IssoJhbefLRcRqw6RQH2NnpdprtMA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.10.tgz", + "integrity": "sha512-tguWg1olF6DGqzws97pKZ8G2L7Ig1vjDmGTwcTuYHbuU6TTjJe5FXbgs5C1BBzHbJ2bo1m3WkQDbWO2PvamRcg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.10.tgz", + "integrity": "sha512-3ZioSQSg1HT2N05YxeJWYR+Libe3bREVSdWhEEgExWaDtyFbbXWb49QgPvFH8u03vUPX10JhJPcz7s9t9+boWg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.10.tgz", + "integrity": "sha512-LLgJfHJk014Aa4anGDbh8bmI5Lk+QidDmGzuC2D+vP7mv/GeSN+H39zOf7pN5N8p059FcOfs2bVlrRr4SK9WxA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.10.tgz", + "integrity": "sha512-oR31GtBTFYCqEBALI9r6WxoU/ZofZl962pouZRTEYECvNF/dtXKku8YXcJkhgK/beU+zedXfIzHijSRapJY3vg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.10.tgz", + "integrity": "sha512-5luJWN6YKBsawd5f9i4+c+geYiVEw20FVW5x0v1kEMWNq8UctFjDiMATBxLvmmHA4bf7F6hTRaJgtghFr9iziQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.10.tgz", + "integrity": "sha512-NrSCx2Kim3EnnWgS4Txn0QGt0Xipoumb6z6sUtl5bOEZIVKhzfyp/Lyw4C1DIYvzeW/5mWYPBFJU3a/8Yr75DQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.10.tgz", + "integrity": "sha512-xoSphrd4AZda8+rUDDfD9J6FUMjrkTz8itpTITM4/xgerAZZcFW7Dv+sun7333IfKxGG8gAq+3NbfEMJfiY+Eg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.10.tgz", + "integrity": "sha512-ab6eiuCwoMmYDyTnyptoKkVS3k8fy/1Uvq7Dj5czXI6DF2GqD2ToInBI0SHOp5/X1BdZ26RKc5+qjQNGRBelRA==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.10.tgz", + "integrity": "sha512-NLinzzOgZQsGpsTkEbdJTCanwA5/wozN9dSgEl12haXJBzMTpssebuXR42bthOF3z7zXFWH1AmvWunUCkBE4EA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.10.tgz", + "integrity": "sha512-FE557XdZDrtX8NMIeA8LBJX3dC2M8VGXwfrQWU7LB5SLOajfJIxmSdyL/gU1m64Zs9CBKvm4UAuBp5aJ8OgnrA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.10.tgz", + "integrity": "sha512-3BBSbgzuB9ajLoVZk0mGu+EHlBwkusRmeNYdqmznmMc9zGASFjSsxgkNsqmXugpPk00gJ0JNKh/97nxmjctdew==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.10.tgz", + "integrity": "sha512-QSX81KhFoZGwenVyPoberggdW1nrQZSvfVDAIUXr3WqLRZGZqWk/P4T8p2SP+de2Sr5HPcvjhcJzEiulKgnxtA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.10.tgz", + "integrity": "sha512-AKQM3gfYfSW8XRk8DdMCzaLUFB15dTrZfnX8WXQoOUpUBQ+NaAFCP1kPS/ykbbGYz7rxn0WS48/81l9hFl3u4A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.10.tgz", + "integrity": "sha512-7RTytDPGU6fek/hWuN9qQpeGPBZFfB4zZgcz2VK2Z5VpdUxEI8JKYsg3JfO0n/Z1E/6l05n0unDCNc4HnhQGig==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.10.tgz", + "integrity": "sha512-5Se0VM9Wtq797YFn+dLimf2Zx6McttsH2olUBsDml+lm0GOCRVebRWUvDtkY4BWYv/3NgzS8b/UM3jQNh5hYyw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.10.tgz", + "integrity": "sha512-XkA4frq1TLj4bEMB+2HnI0+4RnjbuGZfet2gs/LNs5Hc7D89ZQBHQ0gL2ND6Lzu1+QVkjp3x1gIcPKzRNP8bXw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.10.tgz", + "integrity": "sha512-AVTSBhTX8Y/Fz6OmIVBip9tJzZEUcY8WLh7I59+upa5/GPhh2/aM6bvOMQySspnCCHvFi79kMtdJS1w0DXAeag==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.10.tgz", + "integrity": "sha512-fswk3XT0Uf2pGJmOpDB7yknqhVkJQkAQOcW/ccVOtfx05LkbWOaRAtn5SaqXypeKQra1QaEa841PgrSL9ubSPQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.10.tgz", + "integrity": "sha512-ah+9b59KDTSfpaCg6VdJoOQvKjI33nTaQr4UluQwW7aEwZQsbMCfTmfEO4VyewOxx4RaDT/xCy9ra2GPWmO7Kw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.10.tgz", + "integrity": "sha512-QHPDbKkrGO8/cz9LKVnJU22HOi4pxZnZhhA2HYHez5Pz4JeffhDjf85E57Oyco163GnzNCVkZK0b/n4Y0UHcSw==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.10.tgz", + "integrity": "sha512-9KpxSVFCu0iK1owoez6aC/s/EdUQLDN3adTxGCqxMVhrPDj6bt5dbrHDXUuq+Bs2vATFBBrQS5vdQ/Ed2P+nbw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz", + "integrity": "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", + "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.21.1", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.1.tgz", + "integrity": "sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^2.1.7", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/config-helpers": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.1.tgz", + "integrity": "sha512-csZAzkNhsgwb0I/UAV6/RGFTbiakPCf0ZrGmrIxQpYvGZ00PhTkSnyKNolphgIvmnJeGw6rcGVEXfTzUnFuEvw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.16.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/core": { + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.16.0.tgz", + "integrity": "sha512-nmC8/totwobIiFcGkDza3GIKfAw1+hLiYVrh3I1nIomQ8PEr5cxg34jnkmGawul/ep52wGRAcyeDCNtWKSOj4Q==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz", + "integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/js": { + "version": "9.38.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.38.0.tgz", + "integrity": "sha512-UZ1VpFvXf9J06YG9xQBdnzU+kthors6KjhMAl6f4gH4usHyh31rUf2DLGInT8RFYIReYXNSydgPY0V2LuWgl7A==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz", + "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.0.tgz", + "integrity": "sha512-sB5uyeq+dwCWyPi31B2gQlVlo+j5brPlWx4yZBrEaRo/nhdDE8Xke1gsGgtiBdaBTxuTkceLVuVt/pclrasb0A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.16.0", + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@humanfs/core": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.7", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz", + "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.4.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.52.4.tgz", + "integrity": "sha512-BTm2qKNnWIQ5auf4deoetINJm2JzvihvGb9R6K/ETwKLql/Bb3Eg2H1FBp1gUb4YGbydMA3jcmQTR73q7J+GAA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.52.4.tgz", + "integrity": "sha512-P9LDQiC5vpgGFgz7GSM6dKPCiqR3XYN1WwJKA4/BUVDjHpYsf3iBEmVz62uyq20NGYbiGPR5cNHI7T1HqxNs2w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.52.4.tgz", + "integrity": "sha512-QRWSW+bVccAvZF6cbNZBJwAehmvG9NwfWHwMy4GbWi/BQIA/laTIktebT2ipVjNncqE6GLPxOok5hsECgAxGZg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.52.4.tgz", + "integrity": "sha512-hZgP05pResAkRJxL1b+7yxCnXPGsXU0fG9Yfd6dUaoGk+FhdPKCJ5L1Sumyxn8kvw8Qi5PvQ8ulenUbRjzeCTw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.52.4.tgz", + "integrity": "sha512-xmc30VshuBNUd58Xk4TKAEcRZHaXlV+tCxIXELiE9sQuK3kG8ZFgSPi57UBJt8/ogfhAF5Oz4ZSUBN77weM+mQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.52.4.tgz", + "integrity": "sha512-WdSLpZFjOEqNZGmHflxyifolwAiZmDQzuOzIq9L27ButpCVpD7KzTRtEG1I0wMPFyiyUdOO+4t8GvrnBLQSwpw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.52.4.tgz", + "integrity": "sha512-xRiOu9Of1FZ4SxVbB0iEDXc4ddIcjCv2aj03dmW8UrZIW7aIQ9jVJdLBIhxBI+MaTnGAKyvMwPwQnoOEvP7FgQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.52.4.tgz", + "integrity": "sha512-FbhM2p9TJAmEIEhIgzR4soUcsW49e9veAQCziwbR+XWB2zqJ12b4i/+hel9yLiD8pLncDH4fKIPIbt5238341Q==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.52.4.tgz", + "integrity": "sha512-4n4gVwhPHR9q/g8lKCyz0yuaD0MvDf7dV4f9tHt0C73Mp8h38UCtSCSE6R9iBlTbXlmA8CjpsZoujhszefqueg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.52.4.tgz", + "integrity": "sha512-u0n17nGA0nvi/11gcZKsjkLj1QIpAuPFQbR48Subo7SmZJnGxDpspyw2kbpuoQnyK+9pwf3pAoEXerJs/8Mi9g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.52.4.tgz", + "integrity": "sha512-0G2c2lpYtbTuXo8KEJkDkClE/+/2AFPdPAbmaHoE870foRFs4pBrDehilMcrSScrN/fB/1HTaWO4bqw+ewBzMQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.52.4.tgz", + "integrity": "sha512-teSACug1GyZHmPDv14VNbvZFX779UqWTsd7KtTM9JIZRDI5NUwYSIS30kzI8m06gOPB//jtpqlhmraQ68b5X2g==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.52.4.tgz", + "integrity": "sha512-/MOEW3aHjjs1p4Pw1Xk4+3egRevx8Ji9N6HUIA1Ifh8Q+cg9dremvFCUbOX2Zebz80BwJIgCBUemjqhU5XI5Eg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.52.4.tgz", + "integrity": "sha512-1HHmsRyh845QDpEWzOFtMCph5Ts+9+yllCrREuBR/vg2RogAQGGBRC8lDPrPOMnrdOJ+mt1WLMOC2Kao/UwcvA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.52.4.tgz", + "integrity": "sha512-seoeZp4L/6D1MUyjWkOMRU6/iLmCU2EjbMTyAG4oIOs1/I82Y5lTeaxW0KBfkUdHAWN7j25bpkt0rjnOgAcQcA==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.52.4.tgz", + "integrity": "sha512-Wi6AXf0k0L7E2gteNsNHUs7UMwCIhsCTs6+tqQ5GPwVRWMaflqGec4Sd8n6+FNFDw9vGcReqk2KzBDhCa1DLYg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.52.4.tgz", + "integrity": "sha512-dtBZYjDmCQ9hW+WgEkaffvRRCKm767wWhxsFW3Lw86VXz/uJRuD438/XvbZT//B96Vs8oTA8Q4A0AfHbrxP9zw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.52.4.tgz", + "integrity": "sha512-1ox+GqgRWqaB1RnyZXL8PD6E5f7YyRUJYnCqKpNzxzP0TkaUh112NDrR9Tt+C8rJ4x5G9Mk8PQR3o7Ku2RKqKA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.52.4.tgz", + "integrity": "sha512-8GKr640PdFNXwzIE0IrkMWUNUomILLkfeHjXBi/nUvFlpZP+FA8BKGKpacjW6OUUHaNI6sUURxR2U2g78FOHWQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.52.4.tgz", + "integrity": "sha512-AIy/jdJ7WtJ/F6EcfOb2GjR9UweO0n43jNObQMb6oGxkYTfLcnN7vYYpG+CN3lLxrQkzWnMOoNSHTW54pgbVxw==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.52.4.tgz", + "integrity": "sha512-UF9KfsH9yEam0UjTwAgdK0anlQ7c8/pWPU2yVjyWcF1I1thABt6WXE47cI71pGiZ8wGvxohBoLnxM04L/wj8mQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.52.4.tgz", + "integrity": "sha512-bf9PtUa0u8IXDVxzRToFQKsNCRz9qLYfR/MpECxl4mRoWYjAeFjgxj1XdZr2M/GNVpT05p+LgQOHopYDlUu6/w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@tsconfig/node10": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", + "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/chai": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.2.tgz", + "integrity": "sha512-8kB30R7Hwqf40JPiKhVzodJs2Qc1ZJ5zuT3uzw5Hq/dhNCl3G3l83jfpdI1e20BP348+fV7VIL/+FxaXkqBmWg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/deep-eql": "*" + } + }, + "node_modules/@types/deep-eql": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", + "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "24.7.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.7.2.tgz", + "integrity": "sha512-/NbVmcGTP+lj5oa4yiYxxeBjRivKQ5Ns1eSZeB99ExsEQ6rX5XYU1Zy/gGxY/ilqtD4Etx9mKyrPxZRetiahhA==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~7.14.0" + } + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "8.46.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.46.1.tgz", + "integrity": "sha512-rUsLh8PXmBjdiPY+Emjz9NX2yHvhS11v0SR6xNJkm5GM1MO9ea/1GoDKlHHZGrOJclL/cZ2i/vRUYVtjRhrHVQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "8.46.1", + "@typescript-eslint/type-utils": "8.46.1", + "@typescript-eslint/utils": "8.46.1", + "@typescript-eslint/visitor-keys": "8.46.1", + "graphemer": "^1.4.0", + "ignore": "^7.0.0", + "natural-compare": "^1.4.0", + "ts-api-utils": "^2.1.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^8.46.1", + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "8.46.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.46.1.tgz", + "integrity": "sha512-6JSSaBZmsKvEkbRUkf7Zj7dru/8ZCrJxAqArcLaVMee5907JdtEbKGsZ7zNiIm/UAkpGUkaSMZEXShnN2D1HZA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/scope-manager": "8.46.1", + "@typescript-eslint/types": "8.46.1", + "@typescript-eslint/typescript-estree": "8.46.1", + "@typescript-eslint/visitor-keys": "8.46.1", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/project-service": { + "version": "8.46.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.46.1.tgz", + "integrity": "sha512-FOIaFVMHzRskXr5J4Jp8lFVV0gz5ngv3RHmn+E4HYxSJ3DgDzU7fVI1/M7Ijh1zf6S7HIoaIOtln1H5y8V+9Zg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.46.1", + "@typescript-eslint/types": "^8.46.1", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.46.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.46.1.tgz", + "integrity": "sha512-weL9Gg3/5F0pVQKiF8eOXFZp8emqWzZsOJuWRUNtHT+UNV2xSJegmpCNQHy37aEQIbToTq7RHKhWvOsmbM680A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.46.1", + "@typescript-eslint/visitor-keys": "8.46.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.46.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.46.1.tgz", + "integrity": "sha512-X88+J/CwFvlJB+mK09VFqx5FE4H5cXD+H/Bdza2aEWkSb8hnWIQorNcscRl4IEo1Cz9VI/+/r/jnGWkbWPx54g==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "8.46.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.46.1.tgz", + "integrity": "sha512-+BlmiHIiqufBxkVnOtFwjah/vrkF4MtKKvpXrKSPLCkCtAp8H01/VV43sfqA98Od7nJpDcFnkwgyfQbOG0AMvw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.46.1", + "@typescript-eslint/typescript-estree": "8.46.1", + "@typescript-eslint/utils": "8.46.1", + "debug": "^4.3.4", + "ts-api-utils": "^2.1.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "8.46.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.46.1.tgz", + "integrity": "sha512-C+soprGBHwWBdkDpbaRC4paGBrkIXxVlNohadL5o0kfhsXqOC6GYH2S/Obmig+I0HTDl8wMaRySwrfrXVP8/pQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "8.46.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.46.1.tgz", + "integrity": "sha512-uIifjT4s8cQKFQ8ZBXXyoUODtRoAd7F7+G8MKmtzj17+1UbdzFl52AzRyZRyKqPHhgzvXunnSckVu36flGy8cg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/project-service": "8.46.1", + "@typescript-eslint/tsconfig-utils": "8.46.1", + "@typescript-eslint/types": "8.46.1", + "@typescript-eslint/visitor-keys": "8.46.1", + "debug": "^4.3.4", + "fast-glob": "^3.3.2", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^2.1.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "8.46.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.46.1.tgz", + "integrity": "sha512-vkYUy6LdZS7q1v/Gxb2Zs7zziuXN0wxqsetJdeZdRe/f5dwJFglmuvZBfTUivCtjH725C1jWCDfpadadD95EDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.7.0", + "@typescript-eslint/scope-manager": "8.46.1", + "@typescript-eslint/types": "8.46.1", + "@typescript-eslint/typescript-estree": "8.46.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.46.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.46.1.tgz", + "integrity": "sha512-ptkmIf2iDkNUjdeu2bQqhFPV1m6qTnFFjg7PPDjxKWaMaP0Z6I9l30Jr3g5QqbZGdw8YdYvLp+XnqnWWZOg/NA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.46.1", + "eslint-visitor-keys": "^4.2.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@vitest/expect": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.2.4.tgz", + "integrity": "sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/chai": "^5.2.2", + "@vitest/spy": "3.2.4", + "@vitest/utils": "3.2.4", + "chai": "^5.2.0", + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/mocker": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.2.4.tgz", + "integrity": "sha512-46ryTE9RZO/rfDd7pEqFl7etuyzekzEhUbTW3BvmeO/BcCMEgq59BKhek3dXDWgAj4oMK6OZi+vRr1wPW6qjEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "3.2.4", + "estree-walker": "^3.0.3", + "magic-string": "^0.30.17" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "msw": "^2.4.9", + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" + }, + "peerDependenciesMeta": { + "msw": { + "optional": true + }, + "vite": { + "optional": true + } + } + }, + "node_modules/@vitest/pretty-format": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.2.4.tgz", + "integrity": "sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.2.4.tgz", + "integrity": "sha512-oukfKT9Mk41LreEW09vt45f8wx7DordoWUZMYdY/cyAk7w5TWkTRCNZYF7sX7n2wB7jyGAl74OxgwhPgKaqDMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/utils": "3.2.4", + "pathe": "^2.0.3", + "strip-literal": "^3.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/snapshot": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.2.4.tgz", + "integrity": "sha512-dEYtS7qQP2CjU27QBC5oUOxLE/v5eLkGqPE0ZKEIDGMs4vKWe7IjgLOeauHsR0D5YuuycGRO5oSRXnwnmA78fQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "3.2.4", + "magic-string": "^0.30.17", + "pathe": "^2.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/spy": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.2.4.tgz", + "integrity": "sha512-vAfasCOe6AIK70iP5UD11Ac4siNUNJ9i/9PZ3NKx07sG6sUxeag1LWdNrMWeKKYBLlzuK+Gn65Yd5nyL6ds+nw==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyspy": "^4.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/utils": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.2.4.tgz", + "integrity": "sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "3.2.4", + "loupe": "^3.1.4", + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/acorn": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", + "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^8.11.0" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true, + "license": "MIT" + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/assertion-error": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cac": { + "version": "6.7.14", + "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", + "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/chai": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/chai/-/chai-5.3.3.tgz", + "integrity": "sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==", + "dev": true, + "license": "MIT", + "dependencies": { + "assertion-error": "^2.0.1", + "check-error": "^2.1.1", + "deep-eql": "^5.0.1", + "loupe": "^3.1.0", + "pathval": "^2.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/check-error": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz", + "integrity": "sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 16" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-eql": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", + "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/es-module-lexer": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", + "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", + "dev": true, + "license": "MIT" + }, + "node_modules/esbuild": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.10.tgz", + "integrity": "sha512-9RiGKvCwaqxO2owP61uQ4BgNborAQskMR6QusfWzQqv7AZOg5oGehdY2pRJMTKuwxd1IDBP4rSbI5lHzU7SMsQ==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.10", + "@esbuild/android-arm": "0.25.10", + "@esbuild/android-arm64": "0.25.10", + "@esbuild/android-x64": "0.25.10", + "@esbuild/darwin-arm64": "0.25.10", + "@esbuild/darwin-x64": "0.25.10", + "@esbuild/freebsd-arm64": "0.25.10", + "@esbuild/freebsd-x64": "0.25.10", + "@esbuild/linux-arm": "0.25.10", + "@esbuild/linux-arm64": "0.25.10", + "@esbuild/linux-ia32": "0.25.10", + "@esbuild/linux-loong64": "0.25.10", + "@esbuild/linux-mips64el": "0.25.10", + "@esbuild/linux-ppc64": "0.25.10", + "@esbuild/linux-riscv64": "0.25.10", + "@esbuild/linux-s390x": "0.25.10", + "@esbuild/linux-x64": "0.25.10", + "@esbuild/netbsd-arm64": "0.25.10", + "@esbuild/netbsd-x64": "0.25.10", + "@esbuild/openbsd-arm64": "0.25.10", + "@esbuild/openbsd-x64": "0.25.10", + "@esbuild/openharmony-arm64": "0.25.10", + "@esbuild/sunos-x64": "0.25.10", + "@esbuild/win32-arm64": "0.25.10", + "@esbuild/win32-ia32": "0.25.10", + "@esbuild/win32-x64": "0.25.10" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "9.37.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.37.0.tgz", + "integrity": "sha512-XyLmROnACWqSxiGYArdef1fItQd47weqB7iwtfr9JHwRrqIXZdcFMvvEcL9xHCmL0SNsOvF0c42lWyM1U5dgig==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.8.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.21.0", + "@eslint/config-helpers": "^0.4.0", + "@eslint/core": "^0.16.0", + "@eslint/eslintrc": "^3.3.1", + "@eslint/js": "9.37.0", + "@eslint/plugin-kit": "^0.4.0", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "@types/json-schema": "^7.0.15", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.6", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^8.4.0", + "eslint-visitor-keys": "^4.2.1", + "espree": "^10.4.0", + "esquery": "^1.5.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "node_modules/eslint-scope": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", + "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/@eslint/js": { + "version": "9.37.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.37.0.tgz", + "integrity": "sha512-jaS+NJ+hximswBG6pjNX0uEJZkrT0zwpVi3BA3vX22aFGjJjmgSTSmPpZCRKmoBL5VY/M6p0xsSJx7rk7sy5gg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + } + }, + "node_modules/espree": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", + "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.15.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expect-type": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.2.2.tgz", + "integrity": "sha512-JhFGDVJ7tmDJItKhYgJCGLOWjuK9vPxiXoUFLwLDc99NlmklilbiQJwoctZtt13+xMw91MCk/REan6MWHqDjyA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "dev": true, + "license": "MIT", "dependencies": { - "@root/request": "^1.9.2" + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" }, - "devDependencies": {} + "engines": { + "node": ">=8.6.0" + } }, - "node_modules/@root/request": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/@root/request/-/request-1.9.2.tgz", - "integrity": "sha512-wVaL9yVV9oDR9UNbPZa20qgY+4Ch6YN8JUkaE4el/uuS5dmhD8Lusm/ku8qJVNtmQA56XLzEDCRS6/vfpiHK2A==" - } - }, - "dependencies": { - "@root/request": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/@root/request/-/request-1.9.2.tgz", - "integrity": "sha512-wVaL9yVV9oDR9UNbPZa20qgY+4Ch6YN8JUkaE4el/uuS5dmhD8Lusm/ku8qJVNtmQA56XLzEDCRS6/vfpiHK2A==" + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fastq": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", + "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/flatted": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", + "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", + "dev": true, + "license": "ISC" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/globals": { + "version": "16.4.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-16.4.0.tgz", + "integrity": "sha512-ob/2LcVVaVGCYN+r14cnwnoDPUufjiYgSqRhiFD0Q1iI4Odora5RE8Iv1D24hAz5oMophRGkGz+yuvQmmUMnMw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true, + "license": "MIT" + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/js-tokens": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.1.tgz", + "integrity": "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/loupe": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.2.1.tgz", + "integrity": "sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/magic-string": { + "version": "0.30.19", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.19.tgz", + "integrity": "sha512-2N21sPY9Ws53PZvsEpVtNuSW+ScYbQdp4b9qUaL+9QkHUrGFKo56Lg9Emg5s9V/qrtNBmiR01sYhUOwu3H+VOw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true, + "license": "ISC" + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/micromatch/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "dev": true, + "license": "MIT" + }, + "node_modules/pathval": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.1.tgz", + "integrity": "sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.16" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss": { + "version": "8.5.6", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", + "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rollup": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.52.4.tgz", + "integrity": "sha512-CLEVl+MnPAiKh5pl4dEWSyMTpuflgNQiLGhMv8ezD5W/qP8AKvmYpCOKRRNOh7oRKnauBZ4SyeYkMS+1VSyKwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.8" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.52.4", + "@rollup/rollup-android-arm64": "4.52.4", + "@rollup/rollup-darwin-arm64": "4.52.4", + "@rollup/rollup-darwin-x64": "4.52.4", + "@rollup/rollup-freebsd-arm64": "4.52.4", + "@rollup/rollup-freebsd-x64": "4.52.4", + "@rollup/rollup-linux-arm-gnueabihf": "4.52.4", + "@rollup/rollup-linux-arm-musleabihf": "4.52.4", + "@rollup/rollup-linux-arm64-gnu": "4.52.4", + "@rollup/rollup-linux-arm64-musl": "4.52.4", + "@rollup/rollup-linux-loong64-gnu": "4.52.4", + "@rollup/rollup-linux-ppc64-gnu": "4.52.4", + "@rollup/rollup-linux-riscv64-gnu": "4.52.4", + "@rollup/rollup-linux-riscv64-musl": "4.52.4", + "@rollup/rollup-linux-s390x-gnu": "4.52.4", + "@rollup/rollup-linux-x64-gnu": "4.52.4", + "@rollup/rollup-linux-x64-musl": "4.52.4", + "@rollup/rollup-openharmony-arm64": "4.52.4", + "@rollup/rollup-win32-arm64-msvc": "4.52.4", + "@rollup/rollup-win32-ia32-msvc": "4.52.4", + "@rollup/rollup-win32-x64-gnu": "4.52.4", + "@rollup/rollup-win32-x64-msvc": "4.52.4", + "fsevents": "~2.3.2" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/siginfo": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", + "dev": true, + "license": "ISC" + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stackback": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", + "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", + "dev": true, + "license": "MIT" + }, + "node_modules/std-env": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.9.0.tgz", + "integrity": "sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==", + "dev": true, + "license": "MIT" + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strip-literal": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-3.1.0.tgz", + "integrity": "sha512-8r3mkIM/2+PpjHoOtiAW8Rg3jJLHaV7xPwG+YRGrv6FP0wwk/toTpATxWYOW0BKdWwl82VT2tFYi5DlROa0Mxg==", + "dev": true, + "license": "MIT", + "dependencies": { + "js-tokens": "^9.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tinybench": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", + "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyexec": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz", + "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyglobby": { + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinypool": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.1.1.tgz", + "integrity": "sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.0.0 || >=20.0.0" + } + }, + "node_modules/tinyrainbow": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-2.0.0.tgz", + "integrity": "sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tinyspy": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-4.0.4.tgz", + "integrity": "sha512-azl+t0z7pw/z958Gy9svOTuzqIk6xq+NSheJzn5MMWtWTFywIacg2wUlzKFGtt3cthx0r2SxMK0yzJOR0IES7Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/ts-api-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz", + "integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.12" + }, + "peerDependencies": { + "typescript": ">=4.8.4" + } + }, + "node_modules/ts-node": { + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", + "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/typescript-eslint": { + "version": "8.46.1", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.46.1.tgz", + "integrity": "sha512-VHgijW803JafdSsDO8I761r3SHrgk4T00IdyQ+/UsthtgPRsBWQLqoSxOolxTpxRKi1kGXK0bSz4CoAc9ObqJA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/eslint-plugin": "8.46.1", + "@typescript-eslint/parser": "8.46.1", + "@typescript-eslint/typescript-estree": "8.46.1", + "@typescript-eslint/utils": "8.46.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/undici-types": { + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.14.0.tgz", + "integrity": "sha512-QQiYxHuyZ9gQUIrmPo3IA+hUl4KYk8uSA7cHrcKd/l3p1OTpZcM0Tbp9x7FAtXdAYhlasd60ncPpgu6ihG6TOA==", + "dev": true, + "license": "MIT" + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true, + "license": "MIT" + }, + "node_modules/vite": { + "version": "7.1.9", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.1.9.tgz", + "integrity": "sha512-4nVGliEpxmhCL8DslSAUdxlB6+SMrhB0a1v5ijlh1xB1nEPuy1mxaHxysVucLHuWryAxLWg6a5ei+U4TLn/rFg==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.25.0", + "fdir": "^6.5.0", + "picomatch": "^4.0.3", + "postcss": "^8.5.6", + "rollup": "^4.43.0", + "tinyglobby": "^0.2.15" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^20.19.0 || >=22.12.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", + "lightningcss": "^1.21.0", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/vite-node": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.2.4.tgz", + "integrity": "sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cac": "^6.7.14", + "debug": "^4.4.1", + "es-module-lexer": "^1.7.0", + "pathe": "^2.0.3", + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" + }, + "bin": { + "vite-node": "vite-node.mjs" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/vitest": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.2.4.tgz", + "integrity": "sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/chai": "^5.2.2", + "@vitest/expect": "3.2.4", + "@vitest/mocker": "3.2.4", + "@vitest/pretty-format": "^3.2.4", + "@vitest/runner": "3.2.4", + "@vitest/snapshot": "3.2.4", + "@vitest/spy": "3.2.4", + "@vitest/utils": "3.2.4", + "chai": "^5.2.0", + "debug": "^4.4.1", + "expect-type": "^1.2.1", + "magic-string": "^0.30.17", + "pathe": "^2.0.3", + "picomatch": "^4.0.2", + "std-env": "^3.9.0", + "tinybench": "^2.9.0", + "tinyexec": "^0.3.2", + "tinyglobby": "^0.2.14", + "tinypool": "^1.1.1", + "tinyrainbow": "^2.0.0", + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0", + "vite-node": "3.2.4", + "why-is-node-running": "^2.3.0" + }, + "bin": { + "vitest": "vitest.mjs" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@types/debug": "^4.1.12", + "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", + "@vitest/browser": "3.2.4", + "@vitest/ui": "3.2.4", + "happy-dom": "*", + "jsdom": "*" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@types/debug": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@vitest/browser": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + } + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/why-is-node-running": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", + "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", + "dev": true, + "license": "MIT", + "dependencies": { + "siginfo": "^2.0.0", + "stackback": "0.0.2" + }, + "bin": { + "why-is-node-running": "cli.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } } } } diff --git a/package.json b/package.json index 1e16cd7..20cfa02 100644 --- a/package.json +++ b/package.json @@ -1,4 +1,5 @@ { + "type": "module", "name": "@xivapi/js", "version": "0.4.5", "description": "A Node.JS wrapper for xivapi.com", @@ -6,12 +7,20 @@ "directories": { "lib": "lib" }, - "dependencies": { - "@root/request": "^1.9.2" + "devDependencies": { + "@eslint/js": "^9.38.0", + "@types/node": "^24.7.2", + "eslint": "^9.37.0", + "globals": "^16.4.0", + "ts-node": "^10.9.2", + "typescript": "^5.9.3", + "typescript-eslint": "^8.46.1", + "vitest": "^3.2.4" }, - "devDependencies": {}, "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" + "build": "tsc", + "test": "vitest", + "lint": "eslint --fix" }, "repository": { "type": "git", diff --git a/resources/index.js b/resources/index.js deleted file mode 100644 index 910f1f1..0000000 --- a/resources/index.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - languages: ['en', 'ja', 'de', 'fr', 'cn', 'kr'] -} diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..5ffa5c1 --- /dev/null +++ b/src/index.ts @@ -0,0 +1,473 @@ +import { Assets, Sheet, Sheets, Versions } from "./lib" +import { CustomError, request } from "./utils" + +export default class XIVAPI { + private readonly options: XIVAPI.Options + + /** + * A wrapper for the XIVAPI v2 API. + * @param {XIVAPI.Options} [options] The client options to fetch with. + * @see https://v2.xivapi.com/api/docs + * @since 0.5.0 + */ + constructor( + options: XIVAPI.Options = { + version: "latest", + language: "en", + verbose: false, + } + ) { + this.options = options + } + + /** + * @since 0.5.0 + */ + public get achievements() { + return new Sheet("Achievement") + } + + /** + * @since 0.5.0 + */ + public get minions() { + return new Sheet("Companion") + } + + /** + * @since 0.5.0 + */ + public get mounts() { + return new Sheet("Mount") + } + + /** + * @since 0.5.0 + */ + public get items() { + return new Sheet("Item") + } + + /** + * Fetch information about rows and their related data that match the provided search query. + * @param {Models.SearchQuery} params Query paramters accepted by the search endpoint. + * @returns {Promise} Response structure for the search endpoint. + * @see https://v2.xivapi.com/api/docs#tag/search/get/search + * @since 0.5.0 + */ + public async search(params: XIVAPI.SearchParams): Promise { + const { data, errors } = await request({ + path: "/search", + params: params as Record, + }) + if (errors) throw new CustomError(errors[0].message) + return data as Models.SearchResponse + } + + /** + * Raw endpoints for the API. Please consider using the typed endpoints instead. + * @see https://v2.xivapi.com/api/docs + * @since 0.5.0 + */ + public data = { + /** + * @see https://v2.xivapi.com/api/docs#tag/assets + * @since 0.5.0 + */ + assets: () => new Assets(), + + /** + * @see https://v2.xivapi.com/api/docs#tag/sheets + * @since 0.5.0 + */ + sheets: () => new Sheets(this.options), + + /** + * @see https://v2.xivapi.com/api/docs#tag/versions + * @since 0.5.0 + */ + versions: () => + new Versions().all().then((versions) => versions.versions.map((version) => version.names[0])), + } +} + +export namespace XIVAPI { + export interface Options { + /** + * The supported version of the game to use for the API. + * @default "latest" + */ + version?: string; + /** + * Language to use for the API. + */ + language?: keyof typeof Models.SchemaLanguage; + /** + * Whether to enable verbose logging. + * @default false + */ + verbose?: boolean; + } + + /** + * Query parameters accepted by the search endpoint. + * @see https://v2.xivapi.com/api/docs#tag/search/get/search + */ + export type SearchParams = Models.SearchQuery & + Models.VersionQuery & + Models.RowReaderQuery & { verbose?: boolean }; +} + +/** + * Models are used to define the structure of the data returned by the API. + * @see https://v2.xivapi.com/api/docs#models + */ +export namespace Models { + /** + * Query parameters accepted by endpoints that interact with versioned game data. + * @see https://v2.xivapi.com/api/docs#model/versionquery + */ + export interface VersionQuery { + /** + * Game version to utilise for this query. + */ + version?: string | null; + } + + /** + * Query parameters accepted by the asset endpoint. + * @see https://v2.xivapi.com/api/docs#model/assetquery + */ + export interface AssetQuery { + format: string | SchemaFormat; + /** + * Game path of the asset to retrieve. + * @example "ui/icon/051000/051474_hr1.tex" + */ + path: string; + } + + /** + * @see https://v2.xivapi.com/api/docs#model/schemaformat + */ + export enum SchemaFormat { + jpg = "jpg", + png = "png", + webp = "webp", + } + + /** + * General purpose error response structure. + * @see https://v2.xivapi.com/api/docs#model/errorresponse + */ + export interface ErrorResponse { + code: number; + /** + * Description of what went wrong. + */ + message: string; + } + + /** + * @see https://v2.xivapi.com/api/docs#model/statuscode + */ + export type StatusCode = number; + + /** + * Path segments expected by the asset map endpoint. + * @see https://v2.xivapi.com/api/docs#model/mappath + */ + export interface MapPath { + /** + * Index of the map within the territory. This invariably takes the form of a two-digit zero-padded number. See Map's Id field for examples of possible combinations of `territory` and `index`. + * @example "00" + */ + index: string; + /** + * Territory of the map to be retrieved. This typically takes the form of 4 characters, [letter][number][letter][number]. See Map's Id field for examples of possible combinations of `territory` and `index`. + * @example "s1d1" + */ + territory: string; + } + + /** + * Query paramters accepted by the search endpoint. + * @see https://v2.xivapi.com/api/docs#model/searchquery + */ + export interface SearchQuery { + /** + * Continuation token to retrieve further results from a prior search request. If specified, takes priority over query. + */ + cursor?: string | null; + /** + * Maximum number of rows to return. To paginate, provide the cursor token provided in `next` to the `cursor` parameter. + */ + limit?: number | null; + /** + * A query string for searching excel data. + * Queries are formed of clauses, which take the basic form of `[specifier][operation][value]`, i.e. `Name="Example"`. Multiple clauses may be specified by seperating them with whitespace, i.e. `Foo=1 Bar=2`. + * @see https://v2.xivapi.com/docs/guides/search/#query + */ + query?: QueryString; + /** + * List of excel sheets that the query should be run against. At least one must be specified if not querying a cursor. + */ + sheets?: string | null; + } + + /** + * A query string for searching excel data. + * Queries are formed of clauses, which take the basic form of `[specifier][operation][value]`, i.e. `Name="Example"`. Multiple clauses may be specified by seperating them with whitespace, i.e. `Foo=1 Bar=2`. + * @see https://v2.xivapi.com/api/docs#model/querystring + */ + export type QueryString = + | string + | string[] + | Record + | URLSearchParams + | null; + + /** + * Query parameters accepted by endpoints that retrieve excel row data. + * @see https://v2.xivapi.com/api/docs#model/rowreaderquery + */ + export interface RowReaderQuery { + /** + * A filter string for selecting fields within a row. + * Filters are comprised of a comma-seperated list of field paths, i.e. `a,b` will select the fields `a` and `b`. + */ + fields?: FilterString | null; + /** + * Known languages supported by the game data format. **NOTE:** Not all languages that are supported by the format are valid for all editions of the game. For example, the global game client acknowledges the existence of `chs` and `kr`, however does not provide any data for them. + */ + language?: string | SchemaLanguage | null; + /** + * Schema that row data should be read with. + */ + schema?: SchemaSpecifier | null; + /** + * A filter string for selecting fields within a row. + * Filters are comprised of a comma-seperated list of field paths, i.e. `a,b` will select the fields `a` and `b`. + */ + transient?: FilterString | null; + } + + /** + * Known languages supported by the game data format. **NOTE:** Not all languages that are supported by the format are valid for all editions of the game. For example, the global game client acknowledges the existence of `chs` and `kr`, however does not provide any data for them. + * @see https://v2.xivapi.com/api/docs#model/schemalanguage + */ + export enum SchemaLanguage { + none = "none", + en = "en", + ja = "ja", + de = "de", + fr = "fr", + chs = "chs", + cht = "cht", + kr = "kr", + } + + /** + * @see https://v2.xivapi.com/api/docs#model/schemaspecifier + */ + export type SchemaSpecifier = string; // `^.+(@.+)?$` + + /** + * A filter string for selecting fields within a row. + * Filters are comprised of a comma-seperated list of field paths, i.e. `a,b` will select the fields `a` and `b`. + * @see https://v2.xivapi.com/api/docs#model/filterstring + */ + export type FilterString = string | string[]; + + /** + * Response structure for the search endpoint. + * @see https://v2.xivapi.com/api/docs#model/searchresponse + */ + export interface SearchResponse { + results: SearchResult[]; + schema: SchemaSpecifier; + next?: string | null; + } + + /** + * Result found by a search query, hydrated with data from the underlying excel row the result represents. + * @see https://v2.xivapi.com/api/docs#model/searchresult + */ + export interface SearchResult { + fields: object; + /** + * ID of this row. + */ + row_id: number; + /** + * Relevance score for this entry. + * These values only loosely represent the relevance of an entry to the search query. No guarantee is given that the discrete values, nor resulting sort order, will remain stable. + */ + score: number; + /** + * Excel sheet this result was found in. + */ + sheet: SchemaSpecifier; + /** + * Subrow ID of this row, when relevant. + */ + subrow_id?: number; + /** + * Field values for this row's transient row, if any is present, according to the current schema and transient filter. + */ + transient?: object; + } + + /** + * Response structure for the list endpoint. + * @see https://v2.xivapi.com/api/docs#model/listresponse + */ + export interface ListResponse { + /** + * Array of sheets known to the API. + * Metadata about a single sheet. + */ + sheets: SheetMetadata[]; + } + + /** + * Metadata about a single sheet. + * @see https://v2.xivapi.com/api/docs#model/sheetmetadata + */ + export interface SheetMetadata { + /** + * The name of the sheet. + */ + name: string; + } + + /** + * Path variables accepted by the sheet endpoint. + * @see https://v2.xivapi.com/api/docs#model/sheetpath + */ + export interface SheetPath { + /** + * Name of the sheet to read. + */ + sheet: SchemaSpecifier; + } + + /** + * Query parameters accepted by the sheet endpoint. + * @see https://v2.xivapi.com/api/docs#model/sheetquery + */ + export interface SheetQuery { + /** + * Fetch rows after the specified row. Behavior is undefined if both `rows` and `after` are provided. + */ + after?: SchemaSpecifier | null; + /** + * Maximum number of rows to return. To paginate, provide the last returned row to the next request's `after` parameter. + */ + limit?: number | null; + /** + * Rows to fetch from the sheet, as a comma-separated list. Behavior is undefined if both `rows` and `after` are provided. + */ + rows?: string; // `^\d+(:\d+)?(,\d+(:\d+)?)*$` + } + + /** + * @see https://v2.xivapi.com/api/docs#model/rowspecifier + */ + export type RowSpecifier = string; // `^\d+(:\d+)?$` + + /** + * Response structure for the sheet endpoint. + * @see https://v2.xivapi.com/api/docs#model/sheetresponse + */ + export interface SheetResponse { + /** + * Array of rows retrieved by the query. + * @see https://v2.xivapi.com/api/docs#model/rowresult + */ + rows: RowResult[]; + /** + * The canonical specifier for the schema used in this response. + */ + schema: SchemaSpecifier; + } + + /** + * Row retrieved by the query. + * @see https://v2.xivapi.com/api/docs#model/rowresult + */ + export interface RowResult { + fields: object; + /** + * ID of this row. + */ + row_id: number; + /** + * Subrow ID of this row, when relevant. + */ + subrow_id?: number | null; + /** + * Field values for this row's transient row, if any is present, according to the current schema and transient filter. + */ + transient?: object; + } + + /** + * Path variables accepted by the row endpoint. + * @see https://v2.xivapi.com/api/docs#model/rowpath + */ + export interface RowPath { + row: RowSpecifier; + /** + * Name of the sheet to read. + */ + sheet: SchemaSpecifier; + } + + /** + * Response structure for the row endpoint. + * @see https://v2.xivapi.com/api/docs#model/rowresponse + */ + export interface RowResponse { + fields: object; + /** + * ID of this row. + */ + row_id: number; + /** + * The canonical specifier for the schema used in this response. + */ + schema: SchemaSpecifier; + /** + * Subrow ID of this row, when relevant. + */ + subrow_id?: number | null; + /** + * Field values for this row's transient row, if any is present, according to the current schema and transient filter. + */ + transient?: object; + } + + /** + * Response structure for the versions endpoint. + * @see https://v2.xivapi.com/api/docs#model/versionsresponse + */ + export interface VersionsResponse { + /** + * Array of versions available in the API. + * Metadata about a single version supported by the API. + */ + versions: VersionMetadata[]; + } + + /** + * Metadata about a single version supported by the API. + * @see https://v2.xivapi.com/api/docs#model/versionmetadata + */ + export interface VersionMetadata { + /** + * Names associated with this version. Version names specified here are accepted by the `version` query parameter throughout the API. + */ + names: string[]; + } +} diff --git a/src/lib/assets.ts b/src/lib/assets.ts new file mode 100644 index 0000000..f1973b4 --- /dev/null +++ b/src/lib/assets.ts @@ -0,0 +1,34 @@ +import type { Models } from ".." +import { CustomError, request } from "../utils" + +/** + * Endpoints for accessing game data on a file-by-file basis. Commonly useful for fetching icons or other textures to display on the web. + * @see https://v2.xivapi.com/api/docs#tag/assets + */ +export class Assets { + /** + * Read an asset from the game at the specified path, converting it into a usable format. If no valid conversion between the game file type and specified format exists, an error will be returned. + * @param {Models.AssetQuery} params Query parameters accepted by the asset endpoint. + * @returns {Promise} An image of the asset. + * @see https://v2.xivapi.com/api/docs#tag/assets/get/asset + */ + async get(params: Models.AssetQuery): Promise { + const { data, errors } = await request({ path: "/asset", params }) + if (errors) throw new CustomError(errors[0].message) + return data as Buffer + } + + /** + * Retrieve the specified map, composing it from split source files if necessary. + * @param {Models.MapPath & Models.VersionQuery & Models.AssetQuery} params + * @returns {Promise} An image of the map. + * @see https://v2.xivapi.com/api/docs#tag/assets/get/asset/map/{territory}/{index} + */ + async map( + params: Models.MapPath & Models.VersionQuery & Pick + ): Promise { + const { data, errors } = await request({ path: "/asset/map", params }) + if (errors) throw new CustomError(errors[0].message) + return data as Buffer + } +} diff --git a/src/lib/index.ts b/src/lib/index.ts new file mode 100644 index 0000000..bbd2841 --- /dev/null +++ b/src/lib/index.ts @@ -0,0 +1,3 @@ +export * from "./assets" +export * from "./sheets" +export * from "./versions" \ No newline at end of file diff --git a/src/lib/sheets.ts b/src/lib/sheets.ts new file mode 100644 index 0000000..2bed1f5 --- /dev/null +++ b/src/lib/sheets.ts @@ -0,0 +1,113 @@ +import type { Models, XIVAPI } from ".." +import { CustomError, request } from "../utils" + +export class Sheet { + private readonly type: T + + constructor(sheet: T) { + this.type = sheet + } + + /** + * Gets a single row from the sheet. + * @param {string | number} id The row to fetch. + * @param {Models.RowReaderQuery} [params] The parameters to fetch the row with. + * @returns {Promise} A single row with typed fields. + * @see https://v2.xivapi.com/api/docs#tag/sheets/get/sheet/{sheet}/{row} + */ + public get( + id: string | number, + params: Models.RowReaderQuery = {} + ): Promise { + try { + if (typeof id !== "string") id = id.toString() + return new Sheets().get(this.type, id, params) + } catch (error) { + throw new CustomError(error instanceof Error ? error.message : "Unknown error") + } + } + + /** + * Gets a list of rows from the sheet. + * @param {Models.SheetQuery} [params] The parameters to fetch the rows with. + * @returns {Promise} A list of rows with typed fields. + * @see https://v2.xivapi.com/api/docs#tag/sheets/get/sheet/{sheet} + */ + public list(params: Models.SheetQuery = {}): Promise { + try { + return new Sheets().list(this.type, params) + } catch (error) { + throw new CustomError(error instanceof Error ? error.message : "Unknown error") + } + } +} + +export class Sheets { + private readonly options: XIVAPI.Options + + /** + * Endpoints for reading data from the game's static relational data store. + * @param {XIVAPI.Options} [options] The options to fetch the sheets with. + * @see https://v2.xivapi.com/api/docs#tag/sheets + */ + public constructor( + options: XIVAPI.Options = { + language: "en", + verbose: false, + } + ) { + this.options = options + } + + /** + * List known excel sheets that can be read by the API. + * @returns {Promise} Response structure for the list endpoint. + * @see https://v2.xivapi.com/api/docs#tag/sheets/get/sheet + */ + async all(): Promise { + const { data, errors } = await request({ path: "/sheet", params: {}, options: this.options }) + if (errors) throw new CustomError(errors[0].message) + return data as Models.ListResponse + } + + /** + * Read information about one or more rows and their related data. + * @param {Models.SchemaSpecifier} sheet The sheet to fetch the rows from. + * @param {Models.SheetQuery} [params] The parameters to fetch the rows with. + * @returns {Promise} A list of rows with typed fields. + * @see https://v2.xivapi.com/api/docs#tag/sheets/get/sheet/{sheet} + */ + async list( + sheet: Models.SchemaSpecifier, + params: Models.SheetQuery = {} + ): Promise { + const { data, errors } = await request({ + path: `/sheet/${sheet}`, + params: params as Record, + options: this.options, + }) + if (errors) throw new CustomError(errors[0].message) + return data as Models.SheetResponse + } + + /** + * Read detailed, filterable information from a single sheet row and its related data. + * @param {Models.SchemaSpecifier} sheet Name of the sheet to read. + * @param {Models.RowSpecifier} row Row to read. + * @returns {Promise} A list of rows with typed fields. + * @see https://v2.xivapi.com/api/docs#tag/sheets/get/sheet/{sheet}/{id} + */ + async get( + sheet: Models.SchemaSpecifier, + row: Models.RowSpecifier, + params: Models.RowReaderQuery = {} + ): Promise { + const { data, errors } = await request({ + path: `/sheet/${sheet}/${row}`, + params: params as Record, + options: this.options, + }) + if (errors) throw new CustomError(errors[0].message) + return data as Models.RowResponse + } +} diff --git a/src/lib/versions.ts b/src/lib/versions.ts new file mode 100644 index 0000000..82b1105 --- /dev/null +++ b/src/lib/versions.ts @@ -0,0 +1,18 @@ +import type { Models } from ".." +import { CustomError, request } from "../utils" + +/** + * Endpoints for querying metadata about the versions recorded by the boilmaster system. + * @see https://v2.xivapi.com/api/docs#tag/versions + */ +export class Versions { + /** + * List versions understood by the API. + * @see https://v2.xivapi.com/api/docs#tag/versions/get/version + */ + async all(): Promise { + const { data, errors } = await request({ path: "/version", params: {} }) + if (errors) throw new CustomError(errors[0].message) + return data as Models.VersionsResponse + } +} diff --git a/src/utils.ts b/src/utils.ts new file mode 100644 index 0000000..67d060c --- /dev/null +++ b/src/utils.ts @@ -0,0 +1,68 @@ +import type { Models, XIVAPI } from "." + +export const endpoint = "https://v2.xivapi.com/api/" + +export class CustomError extends Error { + constructor(message: string, name: string | null = null) { + super() + Error.captureStackTrace(this, this.constructor) + this.name = name || "XIVAPIError" + this.message = message + } +} + +export interface RequestPayload { + path: string | URL; + data?: unknown; + params?: Record; + errors?: Models.ErrorResponse[]; + options?: XIVAPI.Options; +} + +export const request = async (payload: RequestPayload): Promise => { + const { path, params, options } = payload + + if (!options?.verbose && params?.verbose !== undefined) { + options!.verbose = Boolean(params?.verbose) + delete params?.verbose + } + + const url = new URL(path instanceof URL ? path.toString() : path.replace(/^\/+/, ""), endpoint) + if (params) { + const array: Record = { query: " ", fields: ",", transient: "," } + for (const key in array) { + if (Object.prototype.hasOwnProperty.call(params, key) && Array.isArray(params[key])) { + params[key] = (params[key] as string[]).join(array[key]) + } + } + + url.search = new URLSearchParams(params as Record).toString() + + if (!params.language) { + if (options && options.language) url.searchParams.set("language", options.language) + } + + if (!params.version) { + if (options && options.version) url.searchParams.set("version", options.version) + } + } + + const response = await fetch(url) + if (options && options.verbose) console.debug(`Requesting ${path} with params:`, params) + + if (response.ok) { + const contentType = response.headers.get("content-type") + if (contentType && contentType.includes("application/json")) { + payload.data = await response.json() + } else { + payload.data = Buffer.from(await response.arrayBuffer()) + } + } else { + payload.errors = [(await response.json()) as Models.ErrorResponse] + } + + if (options && options.verbose) + console.debug(`${response.ok ? "Success" : "Error"} on ${path} with params:`, params) + + return payload +} diff --git a/test.js b/test.js deleted file mode 100644 index 8ff04c6..0000000 --- a/test.js +++ /dev/null @@ -1,15 +0,0 @@ -const XIVAPI = require('./XIVAPI'), - readline = require('readline') - -const xiv = new XIVAPI({ - //snake_case: true, - verbose: true -}) - -let rl = readline.createInterface({ - input: process.stdin, - output: process.stdout, - terminal: false -}).on('line', function (cmd) { - console.log(eval(cmd)) -}) diff --git a/tests/xivapi-js.test.ts b/tests/xivapi-js.test.ts new file mode 100644 index 0000000..7f98888 --- /dev/null +++ b/tests/xivapi-js.test.ts @@ -0,0 +1,829 @@ +import { describe, it, expect } from "vitest"; +import xivapiClient from "../src/index"; + +describe("@xivapi/js", () => { + const API_TIMEOUT = 10000; + const xivapi = new xivapiClient(); + + const validateSearchResponse = (result: any) => { + expect(result).toBeDefined(); + expect(result.results).toBeDefined(); + expect(Array.isArray(result.results)).toBe(true); + expect(result.schema).toBeDefined(); + + if (result.results.length > 0) { + const firstResult = result.results[0]; + expect(firstResult.row_id).toBeDefined(); + expect(typeof firstResult.row_id).toBe("number"); + expect(firstResult.score).toBeDefined(); + expect(typeof firstResult.score).toBe("number"); + expect(firstResult.sheet).toBeDefined(); + expect(firstResult.fields).toBeDefined(); + } + }; + + const validateItemData = (result: any, expectedSheet: string = "Item") => { + expect(result.results.length).toBeGreaterThan(0); + + result.results.forEach((item: any) => { + expect(item.sheet).toBe(expectedSheet); + expect(item.fields).toBeDefined(); + expect(typeof item.fields).toBe("object"); + + if (item.fields.Name) { + expect(typeof item.fields.Name).toBe("string"); + expect(item.fields.Name.length).toBeGreaterThan(0); + } + + if (item.fields.ID) { + expect(typeof item.fields.ID).toBe("number"); + expect(item.fields.ID).toBeGreaterThan(0); + } + + if (item.fields.LevelItem) { + expect(typeof item.fields.LevelItem).toBe("number"); + expect(item.fields.LevelItem).toBeGreaterThanOrEqual(0); + } + }); + }; + + const validateActionData = (result: any) => { + expect(result.results.length).toBeGreaterThan(0); + + result.results.forEach((action: any) => { + expect(action.sheet).toBe("Action"); + expect(action.fields).toBeDefined(); + expect(typeof action.fields).toBe("object"); + + if (action.fields.Name) { + expect(typeof action.fields.Name).toBe("string"); + expect(action.fields.Name.length).toBeGreaterThan(0); + } + + if (action.fields.ID) { + expect(typeof action.fields.ID).toBe("number"); + expect(action.fields.ID).toBeGreaterThan(0); + } + }); + }; + + describe("versions", () => { + it( + "should fetch all versions successfully", + async () => { + const result = await xivapi.data.versions(); + + expect(result).toBeDefined(); + expect(Array.isArray(result)).toBe(true); + expect(result.length).toBeGreaterThan(0); + + result.forEach((version) => { + expect(typeof version).toBe("string"); + expect(version.length).toBeGreaterThan(0); + }); + }, + API_TIMEOUT + ); + }); + + describe("assets", () => { + it( + "should fetch asset successfully", + async () => { + const assetParams = { + path: "ui/icon/051000/051474_hr1.tex", + format: "png", + }; + + const assets = xivapi.data.assets(); + const result = await assets.get(assetParams); + + expect(result).toBeDefined(); + expect(Buffer.isBuffer(result)).toBe(true); + expect(result.length).toBeGreaterThan(0); + }, + API_TIMEOUT + ); + + it( + "should handle map requests correctly", + async () => { + const mapParams = { + territory: "invalid", + index: "00", + version: "latest", + format: "png", + }; + + const assets = xivapi.data.assets(); + + await expect(assets.map(mapParams)).rejects.toThrow(); + }, + API_TIMEOUT + ); + + it( + "should throw CustomError when asset fetch fails", + async () => { + const assets = xivapi.data.assets(); + + await expect( + assets.get({ + path: "invalid/path/that/does/not/exist.tex", + format: "png", + }) + ).rejects.toThrow(); + }, + API_TIMEOUT + ); + }); + + describe("search", () => { + describe("basic search operations", () => { + it( + "can find items by exact name match", + async () => { + const result = await xivapi.search({ + query: 'Name="Iron War Axe"', + sheets: "Item", + limit: 5, + }); + + validateSearchResponse(result); + validateItemData(result); + + const ironWarAxe = result.results.find( + (item: any) => item.fields.Name === "Iron War Axe" + ); + expect(ironWarAxe).toBeDefined(); + if (ironWarAxe) { + expect((ironWarAxe.fields as any).Name).toBe("Iron War Axe"); + } + }, + API_TIMEOUT + ); + + it( + "can find items using partial text search", + async () => { + const result = await xivapi.search({ + query: 'Name~"sword"', + sheets: "Item", + limit: 5, + }); + + validateSearchResponse(result); + validateItemData(result); + + result.results.forEach((item: any) => { + if (item.fields.Name) { + expect(item.fields.Name.toLowerCase()).toContain("sword"); + } + }); + }, + API_TIMEOUT + ); + + it( + "can search actions by numeric properties", + async () => { + const result = await xivapi.search({ + query: "Recast100ms>3000", + sheets: "Action", + limit: 5, + }); + + validateSearchResponse(result); + validateActionData(result); + + result.results.forEach((action: any) => { + if (action.fields.Recast100ms) { + expect(action.fields.Recast100ms).toBeGreaterThan(3000); + } + }); + }, + API_TIMEOUT + ); + }); + + describe("numeric comparisons", () => { + it( + "can find high-level items (>=50)", + async () => { + const result = await xivapi.search({ + query: "LevelItem>=50", + sheets: "Item", + limit: 5, + }); + + validateSearchResponse(result); + validateItemData(result); + + result.results.forEach((item: any) => { + if (item.fields.LevelItem) { + expect(item.fields.LevelItem).toBeGreaterThanOrEqual(50); + } + }); + }, + API_TIMEOUT + ); + + it( + "can find low-level items (<10)", + async () => { + const result = await xivapi.search({ + query: "LevelItem<10", + sheets: "Item", + limit: 5, + }); + + validateSearchResponse(result); + validateItemData(result); + + result.results.forEach((item: any) => { + if (item.fields.LevelItem) { + expect(item.fields.LevelItem).toBeLessThan(10); + } + }); + }, + API_TIMEOUT + ); + + it( + "can find items in a level range", + async () => { + const result = await xivapi.search({ + query: "LevelItem>=90 LevelItem<=99", + sheets: "Item", + limit: 5, + }); + + validateSearchResponse(result); + validateItemData(result); + + result.results.forEach((item: any) => { + if (item.fields.LevelItem) { + expect(item.fields.LevelItem).toBeGreaterThanOrEqual(90); + expect(item.fields.LevelItem).toBeLessThanOrEqual(99); + } + }); + }, + API_TIMEOUT + ); + }); + + describe("boolean and complex queries", () => { + it( + "can filter by boolean properties", + async () => { + const result = await xivapi.search({ + query: "IsUntradable=true", + sheets: "Item", + limit: 5, + }); + + validateSearchResponse(result); + validateItemData(result); + + result.results.forEach((item: any) => { + if (item.fields.IsUntradable !== undefined) { + expect(item.fields.IsUntradable).toBe(true); + } + }); + }, + API_TIMEOUT + ); + + it( + "can combine multiple search criteria", + async () => { + const result = await xivapi.search({ + query: 'Name~"sword" LevelItem>=10 LevelItem<=50', + sheets: "Item", + limit: 5, + }); + + validateSearchResponse(result); + validateItemData(result); + + result.results.forEach((item: any) => { + if (item.fields.Name) { + expect(item.fields.Name.toLowerCase()).toContain("sword"); + } + if (item.fields.LevelItem) { + expect(item.fields.LevelItem).toBeGreaterThanOrEqual(10); + expect(item.fields.LevelItem).toBeLessThanOrEqual(50); + } + }); + }, + API_TIMEOUT + ); + }); + + describe("multi-sheet searches", () => { + it( + "can search across multiple sheets simultaneously", + async () => { + const result = await xivapi.search({ + query: 'Name~"rainbow"', + sheets: "Action,Item", + limit: 5, + }); + + validateSearchResponse(result); + + if (result.results.length > 0) { + const sheets = new Set(result.results.map((r) => r.sheet)); + expect(sheets.size).toBeGreaterThanOrEqual(1); + } + }, + API_TIMEOUT + ); + }); + + describe("pagination", () => { + it( + "can limit results and get pagination cursor", + async () => { + const result = await xivapi.search({ + query: 'Name~"rainbow"', + sheets: "Item", + limit: 2, + }); + + expect(result).toBeDefined(); + expect(result.results).toBeDefined(); + expect(Array.isArray(result.results)).toBe(true); + expect(result.results.length).toBeLessThanOrEqual(2); + expect(result.schema).toBeDefined(); + + if (result.next) { + expect(typeof result.next).toBe("string"); + expect(result.next.length).toBeGreaterThan(0); + } + }, + API_TIMEOUT + ); + + it( + "can paginate through results using cursor", + async () => { + const firstPage = await xivapi.search({ + query: 'Name~"sword"', + sheets: "Item", + limit: 2, + }); + + expect(firstPage).toBeDefined(); + expect(firstPage.results).toBeDefined(); + expect(Array.isArray(firstPage.results)).toBe(true); + + if (firstPage.next) { + const secondPage = await xivapi.search({ + cursor: firstPage.next, + limit: 2, + }); + + expect(secondPage).toBeDefined(); + expect(secondPage.results).toBeDefined(); + expect(Array.isArray(secondPage.results)).toBe(true); + expect(secondPage.schema).toBeDefined(); + } + }, + API_TIMEOUT + ); + }); + + describe("customization", () => { + it( + "can use custom language and verbose options", + async () => { + const result = await xivapi.search({ + query: 'Name~"sword"', + sheets: "Item", + limit: 3, + }); + + validateSearchResponse(result); + + expect(result.results.length).toBeLessThanOrEqual(3); + expect(result.schema).toBeDefined(); + }, + API_TIMEOUT + ); + }); + + describe("array-based queries", () => { + it( + "can use string arrays for complex queries", + async () => { + const result = await xivapi.search({ + query: ['Name~"sword"', "LevelItem>=10", "LevelItem<=50"], + sheets: "Item", + limit: 5, + }); + + validateSearchResponse(result); + validateItemData(result); + + result.results.forEach((item: any) => { + if (item.fields.Name) { + expect(item.fields.Name.toLowerCase()).toContain("sword"); + } + if (item.fields.LevelItem) { + expect(item.fields.LevelItem).toBeGreaterThanOrEqual(10); + expect(item.fields.LevelItem).toBeLessThanOrEqual(50); + } + }); + }, + API_TIMEOUT + ); + + it( + "can use string arrays for simple queries", + async () => { + const result = await xivapi.search({ + query: ['Name~"sword"'], + sheets: "Item", + limit: 5, + }); + + validateSearchResponse(result); + validateItemData(result); + + result.results.forEach((item: any) => { + if (item.fields.Name) { + expect(item.fields.Name.toLowerCase()).toContain("sword"); + } + }); + }, + API_TIMEOUT + ); + }); + + describe("error handling", () => { + it( + "throws error for invalid query syntax", + async () => { + await expect( + xivapi.search({ + query: "invalid query syntax that should fail", + sheets: "Item", + }) + ).rejects.toThrow(); + }, + API_TIMEOUT + ); + }); + }); + + describe("sheets", () => { + describe("listing sheets", () => { + it( + "can list all available sheets", + async () => { + const sheets = xivapi.data.sheets(); + const result = await sheets.all(); + + expect(result).toBeDefined(); + expect(result.sheets).toBeDefined(); + expect(Array.isArray(result.sheets)).toBe(true); + expect(result.sheets.length).toBeGreaterThan(0); + + result.sheets.forEach((sheet) => { + expect(sheet.name).toBeDefined(); + expect(typeof sheet.name).toBe("string"); + }); + }, + API_TIMEOUT + ); + + it( + "can list sheets with custom language options", + async () => { + const client = new xivapiClient({ + language: "fr" as const, + verbose: true, + }); + const sheets = client.data.sheets(); + const result = await sheets.all(); + + expect(result).toBeDefined(); + expect(result.sheets).toBeDefined(); + expect(Array.isArray(result.sheets)).toBe(true); + expect(result.sheets.length).toBeGreaterThan(0); + }, + API_TIMEOUT + ); + }); + + describe("reading sheet data", () => { + it( + "can list rows from a specific sheet", + async () => { + const sheets = xivapi.data.sheets(); + const result = await sheets.list("Item", { limit: 5 }); + + expect(result).toBeDefined(); + expect(result.rows).toBeDefined(); + expect(Array.isArray(result.rows)).toBe(true); + expect(result.schema).toBeDefined(); + expect(result.rows.length).toBeGreaterThan(0); + + result.rows.forEach((row: any) => { + expect(row.row_id).toBeDefined(); + expect(typeof row.row_id).toBe("number"); + expect(row.fields).toBeDefined(); + expect(typeof row.fields).toBe("object"); + + if (row.fields.Name) { + expect(typeof row.fields.Name).toBe("string"); + expect(row.fields.Name.length).toBeGreaterThan(0); + } + + if (row.fields.ID) { + expect(typeof row.fields.ID).toBe("number"); + expect(row.fields.ID).toBeGreaterThan(0); + } + }); + }, + API_TIMEOUT + ); + + it( + "can get a specific row with field filtering", + async () => { + const sheets = xivapi.data.sheets(); + const result = await sheets.get("Item", "1", { + fields: "Name", + language: "en", + }); + + expect(result).toBeDefined(); + expect(result.row_id).toBeDefined(); + expect(typeof result.row_id).toBe("number"); + expect(result.schema).toBeDefined(); + expect(result.fields).toBeDefined(); + expect(result.row_id).toBe(1); + + expect((result.fields as any).Name).toBeDefined(); + expect((result.fields as any).Name).toBe("Gil"); + }, + API_TIMEOUT + ); + + it( + "can get a specific row with array-based field filtering", + async () => { + const sheets = xivapi.data.sheets(); + const result = await sheets.get("Item", "1", { + fields: ["Name", "LevelItem"], + language: "en", + }); + + expect(result).toBeDefined(); + expect(result.row_id).toBeDefined(); + expect(typeof result.row_id).toBe("number"); + expect(result.schema).toBeDefined(); + expect(result.fields).toBeDefined(); + expect(result.row_id).toBe(1); + + expect(result.fields).toBeDefined(); + expect(typeof result.fields).toBe("object"); + expect(Object.keys(result.fields).length).toBe(2); + expect((result.fields as any).Name).toBeDefined(); + expect((result.fields as any).Name).toBe("Gil"); + }, + API_TIMEOUT + ); + + it( + "can list rows with default parameters", + async () => { + const sheets = xivapi.data.sheets(); + const result = await sheets.list("Item"); + + expect(result).toBeDefined(); + expect(result.rows).toBeDefined(); + expect(Array.isArray(result.rows)).toBe(true); + expect(result.schema).toBeDefined(); + }, + API_TIMEOUT + ); + }); + + describe("error handling", () => { + it( + "throws error for non-existent sheets", + async () => { + const sheets = xivapi.data.sheets(); + + await expect(sheets.list("NonExistentSheetThatDoesNotExist")).rejects.toThrow(); + }, + API_TIMEOUT + ); + }); + }); + + describe("typed sheet accessors", () => { + describe("items", () => { + it( + "can get a specific item by ID", + async () => { + const result = await xivapi.items.get(1, { + fields: "Name", + language: "en", + }); + + expect(result).toBeDefined(); + expect(result.row_id).toBeDefined(); + expect(typeof result.row_id).toBe("number"); + expect(result.schema).toBeDefined(); + expect(result.fields).toBeDefined(); + expect(result.row_id).toBe(1); + expect((result.fields as any).Name).toBe("Gil"); + }, + API_TIMEOUT + ); + + it( + "can list items with parameters", + async () => { + const result = await xivapi.items.list({ limit: 3 }); + + expect(result).toBeDefined(); + expect(result.rows).toBeDefined(); + expect(Array.isArray(result.rows)).toBe(true); + expect(result.schema).toBeDefined(); + expect(result.rows.length).toBeLessThanOrEqual(3); + + result.rows.forEach((row: any) => { + expect(row.row_id).toBeDefined(); + expect(typeof row.row_id).toBe("number"); + expect(row.fields).toBeDefined(); + expect(typeof row.fields).toBe("object"); + }); + }, + API_TIMEOUT + ); + }); + + describe("achievements", () => { + it( + "can get a specific achievement by ID", + async () => { + const result = await xivapi.achievements.get(1, { + fields: "Name", + language: "en", + }); + + expect(result).toBeDefined(); + expect(result.row_id).toBeDefined(); + expect(typeof result.row_id).toBe("number"); + expect(result.schema).toBeDefined(); + expect(result.fields).toBeDefined(); + expect(result.row_id).toBe(1); + expect((result.fields as any).Name).toBe("To Crush Your Enemies I"); + }, + API_TIMEOUT + ); + + it( + "can list achievements with parameters", + async () => { + const result = await xivapi.achievements.list({ limit: 3 }); + + expect(result).toBeDefined(); + expect(result.rows).toBeDefined(); + expect(Array.isArray(result.rows)).toBe(true); + expect(result.schema).toBeDefined(); + expect(result.rows.length).toBeLessThanOrEqual(3); + + result.rows.forEach((row: any) => { + expect(row.row_id).toBeDefined(); + expect(typeof row.row_id).toBe("number"); + expect(row.fields).toBeDefined(); + expect(typeof row.fields).toBe("object"); + }); + }, + API_TIMEOUT + ); + }); + + describe("minions", () => { + it( + "can get a specific minion by ID", + async () => { + const result = await xivapi.minions.get(1, { + fields: "Singular", + language: "en", + }); + + expect(result).toBeDefined(); + expect(result.row_id).toBeDefined(); + expect(typeof result.row_id).toBe("number"); + expect(result.schema).toBeDefined(); + expect(result.fields).toBeDefined(); + expect(result.row_id).toBe(1); + expect((result.fields as any).Singular).toBe("cherry bomb") + }, + API_TIMEOUT + ); + + it( + "can list minions with parameters", + async () => { + const result = await xivapi.minions.list({ limit: 3 }); + + expect(result).toBeDefined(); + expect(result.rows).toBeDefined(); + expect(Array.isArray(result.rows)).toBe(true); + expect(result.schema).toBeDefined(); + expect(result.rows.length).toBeLessThanOrEqual(3); + + result.rows.forEach((row: any) => { + expect(row.row_id).toBeDefined(); + expect(typeof row.row_id).toBe("number"); + expect(row.fields).toBeDefined(); + expect(typeof row.fields).toBe("object"); + + if (row.fields.Singular) { + expect(typeof row.fields.Singular).toBe("string"); + expect(row.fields.Singular.length).toBeGreaterThan(0); + } + }); + }, + API_TIMEOUT + ); + }); + + describe("mounts", () => { + it( + "can get a specific mount by ID", + async () => { + const result = await xivapi.mounts.get(1, { + fields: "Singular", + language: "en", + }); + + expect(result).toBeDefined(); + expect(result.row_id).toBeDefined(); + expect(typeof result.row_id).toBe("number"); + expect(result.schema).toBeDefined(); + expect(result.fields).toBeDefined(); + expect(result.row_id).toBe(1); + expect((result.fields as any).Singular).toBe("company chocobo") + }, + API_TIMEOUT + ); + + it( + "can list mounts with parameters", + async () => { + const result = await xivapi.mounts.list({ limit: 3 }); + + expect(result).toBeDefined(); + expect(result.rows).toBeDefined(); + expect(Array.isArray(result.rows)).toBe(true); + expect(result.schema).toBeDefined(); + expect(result.rows.length).toBeLessThanOrEqual(3); + + result.rows.forEach((row: any) => { + expect(row.row_id).toBeDefined(); + expect(typeof row.row_id).toBe("number"); + expect(row.fields).toBeDefined(); + expect(typeof row.fields).toBe("object"); + + if (row.fields.Name) { + expect(typeof row.fields.Name).toBe("string"); + expect(row.fields.Name.length).toBeGreaterThan(0); + } + }); + }, + API_TIMEOUT + ); + }); + + describe("client options", () => { + it( + "can create client with custom options", + async () => { + const client = new xivapiClient({ + language: "ja" as const, + verbose: true, + version: "latest", + }); + + const result = await client.items.get(1, { + fields: "Name", + }); + + expect(result).toBeDefined(); + expect(result.row_id).toBe(1); + expect((result.fields as any).Name).toBe("Gil"); + }, + API_TIMEOUT + ); + }); + }); +}); diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..167a608 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,12 @@ +{ + "extends": "@tsconfig/node16/tsconfig.json", + "compilerOptions": { + "module": "ESNext", + "target": "ES2022", + "declaration": true, + "preserveConstEnums": true, + "outDir": "dist" + }, + "include": ["src/**/*"], + "exclude": ["**/*.spec.ts"] +} diff --git a/typings/index.d.ts b/typings/index.d.ts deleted file mode 100644 index 5b66f75..0000000 --- a/typings/index.d.ts +++ /dev/null @@ -1,220 +0,0 @@ -import { - CharacterGetParams, - CharacterGetResult, - CharacterSearchParams, - CharacterSearchResult, - FreeCompanyGetParams, - FreeCompanyGetResult, - FreeCompanySearchParams, - FreeCompanySearchResult, - LinkshellGetResult, - LinkshellSearchParams, - LinkshellSearchResult, - CWLGetResult, - CWLSearchParams, - CWLSearchResult, - PvPTeamGetResult, - PvPTeamSearchParams, - PvPTeamSearchResult, - SearchIndexResult, - SearchIndexes, - SearchResult, -} from "./utils"; -export * from "./utils"; - -declare module "@xivapi/js" { - type StringAlgo = - | "custom" - | "wildcard" - | "wildcard_plus" - | "fuzzy" - | "term" - | "prefix" - | "match" - | "match_phrase" - | "match_phrase_prefix" - | "multi_match" - | "query_string"; - - interface XIVAPIOptions { - private_key?: string; - language?: "en" | "de" | "fr" | "ja" | "cn" | "ko"; - snake_case?: boolean; - staging?: boolean; - verbose?: boolean; - } - - interface DataSearchParams { - /** - * Search a specific series of indexes separated by commas. - */ - indexes: SearchIndexes[]; - - /** - * Search for lore! This is a special built search endpoint which searches a string through various lore specific content. - * @see https://xivapi.com/docs/Search#lore - */ - lore?: boolean; - - /** - * The column to use in string searches. - * @see https://xivapi.com/docs/Search#filters - */ - filters?: string | string[]; - - /** - * The search algorithm to use for string matching. - * @default "wildcard" - * @see https://xivapi.com/docs/Search - */ - string_algo?: StringAlgo; - - /** - * The column to use in string searches. - */ - string_column?: string; - - /** - * Limit the number of results to show. (from 1 to 100) - */ - limit?: number; - } - - export default class XIVAPI { - private readonly options: XIVAPIOptions; - private readonly endpoint: string; - private readonly globalParams: { [key: string]: string | number }; - - constructor(options: string | XIVAPIOptions); - constructor(options: string | XIVAPIOptions, legacyOptions?: XIVAPIOptions); - - /** - * XIVAPI provides the ability to quickly search all game content via Elasticsearch. - * This search endpoint only searches game content and not: characters, free companies, linkshells or pvp teams. - * Those have their own dedicated search endpoints as they relay to Lodestone. - * @since 0.4.2 - * @see https://xivapi.com/docs/Search - * @example - * ```ts - * const xiv = new XIVAPI(); - * await xiv.search("aiming"); // without params - * await xiv.search("aiming", { indexes: ["Item", "Recipe"] }); // with params - * ``` - */ - public search( - input: string, - params?: DataSearchParams - ): Promise; - - /** - * Obtain game content data of Final Fantasy XIV. - * @since 0.4.2 - * @see https://xivapi.com/docs/Game-Data - */ - public data: { - /** - * Returns information about a specific object including extended information. - * @since 0.4.2 - * @see https://xivapi.com/docs/Game-Data - * @example - * ```ts - * const xiv = new XIVAPI(); - * await xiv.data.get("Item", 1673); - * ``` - */ - get: (name: string, id: string | number) => Promise<{ [key: string]: any }>; - - /** - * Obtain game content data of Final Fantasy XIV. - * @since 0.4.2 - * @see https://xivapi.com/docs/Game-Data - * @example - * ```ts - * const xiv = new XIVAPI(); - * await xiv.data.list("Item", { limit: 100 }); // with limit param - * await xiv.data.list("Item", { ids: [1673, 1674] }); // with ids param - * ``` - */ - list: ( - name: keyof typeof SearchIndexes, - params?: { - /** - * Limit the number of items returned by the API. - * @min 100 - * @max 3000 - */ - limit?: number; - - /** - * Filter the ids down if you want data for a specific series of items. - */ - ids?: number[]; - } - ) => Promise; - - /** - * Returns information about a specific object including extended information. - * @since 0.4.2 - * @see https://xivapi.com/docs/Game-Data#servers - */ - servers: () => Promise; - - /** - * Another list of servers grouped by their data center. - * @since 0.4.2 - * @see https://xivapi.com/docs/Game-Data#data-center - */ - datacenters: () => Promise<{ [key: string]: string[] }>; - }; - - /** - * Search and retrieve character data from The Lodestone. Providing useful information such as character profile data, minions and mounts obtained, achievements obtained and their relative dates. Character friends, their free company, pvp team and much more! - * @since 0.4.2 - * @see https://xivapi.com/docs/Character - */ - public character: { - search: (name: string, params?: CharacterSearchParams) => Promise; - get: (id: string | number, params?: CharacterGetParams) => Promise; - }; - - /** - * Search and retrieve Free Company data from The Lodestone, provides useful information such as profile information and member lists. - * @since 0.4.2 - * @see https://xivapi.com/docs/Free-Company - */ - public freecompany: { - search: (name: string, params?: FreeCompanySearchParams) => Promise; - get: (id: string | number, params?: FreeCompanyGetParams) => Promise; - }; - - /** - * Search and retrieve Linkshell data from The Lodestone. - * @since 0.4.2 - * @see https://xivapi.com/docs/Linkshell - */ - public linkshell: { - search: (name: string, params?: LinkshellSearchParams) => Promise; - get: (id: string | number) => Promise; - }; - - /** - * Search and retrieve CWL data from The Lodestone. - * @since 0.4.4 - * @see https://xivapi.com/docs/Linkshell - */ - public cwl: { - search: (name: string, params?: CWLSearchParams) => Promise; - get: (id: string | number) => Promise; - }; - - /** - * Search and retrieve PVP Team data from The Lodestone. - * @since 0.4.2 - * @see https://xivapi.com/docs/PvP-Team - */ - public pvpteam: { - search: (name: string, params?: PvPTeamSearchParams) => Promise; - get: (id: string | number) => Promise; - }; - } -} diff --git a/typings/utils/achievements.d.ts b/typings/utils/achievements.d.ts deleted file mode 100644 index 48a5e69..0000000 --- a/typings/utils/achievements.d.ts +++ /dev/null @@ -1,82 +0,0 @@ -import { GamePatchData, ItemData, TitleData } from "./item"; -import { SearchResult } from "./search"; - -export interface AchievementsData { - List: { Date: number; ID: number }[]; - Points: number; -} - -export interface AchievementCategoryData { - AchievementsKind: { - ID: number; - Name: string; - Name_de: string; - Name_en: string; - Name_fr: string; - Name_ja: string; - Order: number; - }; - AchievementKindTarget: string; - AchievementKindTargetID: number; - HideCategory: number; - ID: number; - Name: string; - Name_de: string; - Name_en: string; - Name_fr: string; - Name_ja: string; - Order: number; - ShowComplete: number; -} - -export interface AchievementGetResult { - AchievementCategory: AchievementCategoryData; - AchievementCategoryTarget: string; - AchievementCategoryTargetID: number; - AchievementHideCondition: string | null; - AchievementHideConditionTarget: string; - AchievementHideConditionTargetID: number; - AchievementTarget: { ID: number; Type: 1; Value: number } | null; - AchievementTargetID: number | null; - ClassJobRequirements: {}[]; - Data0: number; - Data1: number; - Data2: number; - Data3: number; - Data4: number; - Data5: number; - Data6: number; - Data7: number; - Description: string; - Description_de: string; - Description_en: string; - Description_fr: string; - Description_ja: string; - GameContentLinks: []; - GamePatch: GamePatchData; - ID: number; - Icon: string; - IconHD: string; - ItemID: number; - Item: ItemData | null; - ItemTarget: string; - ItemTargetID: number; - Key: number; - Name: string; - Name_de: string; - Name_en: string; - Name_fr: string; - Name_ja: string; - Order: number; - Patch: number | null; - Points: number; - PostAchievements: []; - PreAchievements: []; - QuestRequirements: {}[]; - QuestRequirementsAll: boolean; - Title: TitleData | null; - TitleTarget: string; - TitleTargetID: number; - Type: number; - Url: string; -} diff --git a/typings/utils/character.d.ts b/typings/utils/character.d.ts deleted file mode 100644 index b2bcb91..0000000 --- a/typings/utils/character.d.ts +++ /dev/null @@ -1,130 +0,0 @@ -import { SearchParams, SearchResult } from "./search"; -import { AchievementsData } from "./achievements"; -import { FreeCompanyGetResult } from "./freecompany"; - -type Omit = Pick>; -export interface CharacterSearchParams extends Omit {} -export interface CharacterGetParams { - /** - * If set to 1, the API will return more data in the response by extending out the data IDs to useful objects. - */ - extended?: 1; - - /** - * By default the `Character`, `ClassJobs`, `Minion` and `Mount` data will return, you can request more data using the `data` query. - * @see https://xivapi.com/docs/Character#character - */ - data?: ("AC" | "FR" | "FC" | "FC" | "FCM" | "MIMO" | "PVP")[]; -} - -export interface BasicCharacterData { - Avatar: string; - FeastMatches: number; - ID: number; - Lang: string | null; - Name: string; - Rank: number | null; - RankIcon: string | null; - Server: string; -} - -export interface CharacterSearchResult extends SearchResult { - Results: BasicCharacterData[]; -} - -export interface ClassJobData { - ClassID: number; - ExpLevel: number; - ExpLevelMax: number; - ExpLevelTogo: number; - IsSpecialised: boolean; - JobID: number; - Level: number; - Name: string; - UnlockedState: { - ID: number; - Name: string; - }; -} - -export interface GearData { - Creator: string | null; - Dye: number | null; - ID: number | null; - Materia: number[]; - Mirage: number | null; -} - -export interface GearsetData { - Attributes: { [key: string]: number }; - ClassID: number; - Gear: { - Body: GearData | undefined; - Bracelets: GearData | undefined; - Earrings: GearData | undefined; - Feet: GearData | undefined; - Hands: GearData | undefined; - Head: GearData | undefined; - Legs: GearData | undefined; - MainHand: GearData | undefined; - Necklace: GearData | undefined; - OffHand: GearData | undefined; - Ring1: GearData | undefined; - Ring2: GearData | undefined; - SoulCrystal: GearData | undefined; - }; - GearKey: string; - JobID: number; - Level: number; -} - -export interface CharacterData { - ActiveClassJob: ClassJobData; - Avatar: string; - Bio: string; - ClassJobs: ClassJobData[]; - ClassJobsBozjan: { Level: number | null; Mettle: number | null; Name: string }; - ClassJobsElemental: { - ExpLevel: number; - ExpLevelMax: number; - ExpLevelTogo: number; - Level: number; - Name: string; - }[]; - DC: string; - FreeCompanyId: string | null; - FreeCompanyName: string | null; - GearSet: GearsetData; - Gender: 1 | 2; - GrandCompany: { - NameID: number; - RankID: number; - }; - GuardianDeity: number; - ID: number; - Lang: string | null; - Name: string; - Nameday: string; - ParseDate: number; - Portrait: string; - PvPTeamId: number | null; - Race: number; - Server: string; - Title: number; - TitleTop: boolean; - Town: number; - Tribe: number; -} - -export interface CharacterGetResult { - Achievements: AchievementsData | null; - AchievementsPublic: boolean | null; - Character: CharacterData; - FreeCompany: FreeCompanyGetResult | null; - FreeCompanyMembers: BasicCharacterData[] | null; - Friends: BasicCharacterData[] | null; - FriendsPublic: boolean | null; - Minions: { Icon: string; Name: string }[] | null; - Mounts: { Icon: string; Name: string }[] | null; - PvPTeam: null; -} diff --git a/typings/utils/cwl.ts b/typings/utils/cwl.ts deleted file mode 100644 index 3aa79ae..0000000 --- a/typings/utils/cwl.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { CharacterSearchResult } from "./character"; -import { SearchParams, SearchResult } from "./search"; - -export interface CWLSearchParams extends SearchParams {} - -export interface CWLSearchResult extends SearchResult { - Results: { - Crest: string[]; - ID: string; - Name: string; - Server: string; - }[]; -} - -export interface CWLGetResult { - CWL: { - ID: string; - Pagination: SearchResult["Pagination"]; - Profile: { - Name: string; - }; - Results: CharacterSearchResult["Results"]; - }; -} diff --git a/typings/utils/freecompany.d.ts b/typings/utils/freecompany.d.ts deleted file mode 100644 index 746cbe6..0000000 --- a/typings/utils/freecompany.d.ts +++ /dev/null @@ -1,57 +0,0 @@ -import { SearchParams, SearchResult } from "./search"; - -export interface FreeCompanySearchParams extends SearchParams {} -export interface FreeCompanyGetParams { - /** - * If set to 1, the API will return more data in the response by extending out the data IDs to useful objects. - */ - extended?: 1; - - /** - * By default the `Character`, `ClassJobs`, `Minion` and `Mount` data will return, you can request more data using the `data` query. - * @see https://xivapi.com/docs/Character#character - */ - data?: ["FCM"]; -} - -export interface FreeCompanySearchResult extends SearchResult { - Results: { - Crest: string[]; - ID: string; - Name: string; - Server: string; - }[]; -} - -export interface FreeCompanyGetResult { - Active: string; - ActiveMemberCount: number; - Crest: string[]; - DC: string; - Estate: { - Greeting: string; - Name: string; - Plot: string; - }; - Focus: { Icon: string; Name: string; Status: boolean }[]; - Formed: number; - GrandCompany: "Maelstrom" | "Order of the Twin Adder" | "Immortal Flames"; - ID: string; - Name: string; - ParseDate: number; - Rank: string; - Rankings: { - Monthly: number; - Weekly: number; - }; - Recruitment: string; - Reputation: [ - { Name: string; Progress: number; Rank: number }, - { Name: string; Progress: number; Rank: number }, - { Name: string; Progress: number; Rank: number } - ]; - Seeking: { Icon: string; Name: string; Status: boolean }[]; - Server: string; - Slogan: string; - Tag: string; -} diff --git a/typings/utils/index.d.ts b/typings/utils/index.d.ts deleted file mode 100644 index 18abed1..0000000 --- a/typings/utils/index.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -export * from "./character"; -export * from "./freecompany"; -export * from "./linkshell"; -export * from "./cwl"; -export * from "./pvpteam"; -export * from "./search"; diff --git a/typings/utils/item.d.ts b/typings/utils/item.d.ts deleted file mode 100644 index fcf2c6a..0000000 --- a/typings/utils/item.d.ts +++ /dev/null @@ -1,231 +0,0 @@ -export interface GamePatchData { - Banner: string; - ExName: string; - ExVersion: number; - ID: number; - Name: string; - Name_de: string; - Name_en: string; - Name_fr: string; - Name_ja: string; - Name_kr: string; - ReleaseDate: string; - Version: string; -} - -export interface TitleData { - ID: number; - Icon: string; - IsPrefix: number; - Name: string; - NameFemale: string; - NameFemale_de: string; - NameFemale_en: string; - NameFemale_fr: string; - NameFemale_ja: string; - Name_de: string; - Name_en: string; - Name_fr: string; - Name_ja: string; - Order: number; -} - -export interface ItemActionData { - CondBattle: number; - CondLv: number; - CondPVP: number; - CondPVPOnly: number; - Data0: number; - Data1: number; - Data2: number; - Data3: number; - Data4: number; - Data5: number; - Data6: number; - Data7: number; - Data8: number; - DataHQ0: number; - DataHQ1: number; - DataHQ2: number; - DataHQ3: number; - DataHQ4: number; - DataHQ5: number; - DataHQ6: number; - DataHQ7: number; - DataHQ8: number; - ID: number; - Type: number; -} - -export interface ItemData { - AdditionalData: number; - Adjective: number; - AetherialReduce: number; - AlwaysCollectable: number; - Article: number; - BaseParam0: null; - BaseParam0Target: string; - BaseParam0TargetID: number; - BaseParam1: null; - BaseParam1Target: string; - BaseParam1TargetID: number; - BaseParam2: null; - BaseParam2Target: string; - BaseParam2TargetID: number; - BaseParam3: null; - BaseParam3Target: string; - BaseParam3TargetID: number; - BaseParam4: null; - BaseParam4Target: string; - BaseParam4TargetID: number; - BaseParam5: null; - BaseParam5Target: string; - BaseParam5TargetID: number; - BaseParamModifier: number; - BaseParamSpecial0: null; - BaseParamSpecial0Target: string; - BaseParamSpecial0TargetID: number; - BaseParamSpecial1: null; - BaseParamSpecial1Target: string; - BaseParamSpecial1TargetID: number; - BaseParamSpecial2: null; - BaseParamSpecial2Target: string; - BaseParamSpecial2TargetID: number; - BaseParamSpecial3: null; - BaseParamSpecial3Target: string; - BaseParamSpecial3TargetID: number; - BaseParamSpecial4: null; - BaseParamSpecial4Target: string; - BaseParamSpecial4TargetID: number; - BaseParamSpecial5: null; - BaseParamSpecial5Target: string; - BaseParamSpecial5TargetID: number; - BaseParamValue0: number; - BaseParamValue1: number; - BaseParamValue2: number; - BaseParamValue3: number; - BaseParamValue4: number; - BaseParamValue5: number; - BaseParamValueSpecial0: number; - BaseParamValueSpecial1: number; - BaseParamValueSpecial2: number; - BaseParamValueSpecial3: number; - BaseParamValueSpecial4: number; - BaseParamValueSpecial5: number; - Block: number; - BlockRate: number; - CanBeHq: number; - CastTimeS: number; - ClassJobCategory: null; - ClassJobCategoryTarget: string; - ClassJobCategoryTargetID: number; - ClassJobRepair: null; - ClassJobRepairTarget: string; - ClassJobRepairTargetID: number; - ClassJobUse: null; - ClassJobUseTarget: string; - ClassJobUseTargetID: number; - CooldownS: number; - DamageMag: number; - DamagePhys: number; - DefenseMag: number; - DefensePhys: number; - DelayMs: number; - Description: string; - Description_de: string; - Description_en: string; - Description_fr: string; - Description_ja: string; - Desynth: number; - EquipRestriction: number; - EquipSlotCategory: null; - EquipSlotCategoryTarget: string; - EquipSlotCategoryTargetID: number; - FilterGroup: number; - GrandCompany: null; - GrandCompanyTarget: string; - GrandCompanyTargetID: number; - ID: number; - Icon: string; - IconHD: string; - IconID: number; - IsAdvancedMeldingPermitted: number; - IsCollectable: number; - IsCrestWorthy: number; - IsDyeable: number; - IsGlamourous: number; - IsIndisposable: number; - IsPvP: number; - IsUnique: number; - IsUntradable: number; - ItemAction: ItemActionData; - ItemActionTarget: string; - ItemActionTargetID: string; - ItemGlamour: null; - ItemGlamourTarget: string; - ItemGlamourTargetID: number; - ItemRepair: null; - ItemRepairTarget: string; - ItemRepairTargetID: number; - ItemSearchCategory: null; - ItemSearchCategoryTarget: string; - ItemSearchCategoryTargetID: number; - ItemSeries: null; - ItemSeriesTarget: string; - ItemSeriesTargetID: number; - ItemSortCategory: { - ID: number; - Param: number; - }; - ItemSortCategoryTarget: string; - ItemSortCategoryTargetID: number; - ItemSpecialBonus: null; - ItemSpecialBonusParam: number; - ItemSpecialBonusTarget: string; - ItemSpecialBonusTargetID: number; - ItemUICategory: { - ID: number; - Icon: string; - IconHD: string; - IconID: number; - Name: string; - Name_de: string; - Name_en: string; - Name_fr: string; - Name_ja: string; - OrderMajor: number; - OrderMinor: number; - }; - ItemUICategoryTarget: string; - ItemUICategoryTargetID: number; - LevelEquip: number; - LevelItem: number; - Lot: number; - MateriaSlotCount: number; - MaterializeType: number; - ModelMain: string; - ModelSub: string; - Name: string; - Name_de: string; - Name_en: string; - Name_fr: string; - Name_ja: string; - Plural: string; - Plural_de: string; - Plural_en: string; - Plural_fr: string; - Plural_ja: string; - PossessivePronoun: number; - PriceLow: number; - PriceMid: number; - Pronoun: number; - Rarity: number; - Singular: string; - Singular_de: string; - Singular_en: string; - Singular_fr: string; - Singular_ja: string; - StackSize: number; - StartsWithVowel: number; - SubStatCategory: number; -} diff --git a/typings/utils/linkshell.ts b/typings/utils/linkshell.ts deleted file mode 100644 index d8f7ef3..0000000 --- a/typings/utils/linkshell.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { CharacterSearchResult } from "./character"; -import { SearchParams, SearchResult } from "./search"; - -export interface LinkshellSearchParams extends SearchParams {} - -export interface LinkshellSearchResult extends SearchResult { - Results: { - Crest: string[]; - ID: string; - Name: string; - Server: string; - }[]; -} - -export interface LinkshellGetResult { - Linkshell: { - ID: string; - Pagination: SearchResult["Pagination"]; - Profile: { - Name: string; - Server: string; - }; - Results: CharacterSearchResult["Results"]; - }; -} diff --git a/typings/utils/pvpteam.ts b/typings/utils/pvpteam.ts deleted file mode 100644 index 38e9191..0000000 --- a/typings/utils/pvpteam.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { CharacterSearchResult } from "./character"; -import { SearchParams, SearchResult } from "./search"; - -export interface PvPTeamSearchParams extends SearchParams {} - -export interface PvPTeamSearchResult extends SearchResult { - Results: { - Crest: string[]; - ID: string; - Name: string; - Server: string; - }[]; -} - -export interface PvPTeamGetResult { - PvPTeam: { - ID: string; - Pagination: SearchResult["Pagination"]; - Profile: { - Crest: string[]; - Name: string; - Server: string; - }; - Results: CharacterSearchResult["Results"]; - }; -} diff --git a/typings/utils/search.d.ts b/typings/utils/search.d.ts deleted file mode 100644 index 90de0b2..0000000 --- a/typings/utils/search.d.ts +++ /dev/null @@ -1,72 +0,0 @@ -export enum SearchIndexes { - "Achievement", - "Title", - "Action", - "CraftAction", - "Trait", - "PvPAction", - "PvPTrait", - "Status", - "BNpcName", - "ENpcResident", - "Companion", - "Mount", - "Leve", - "Emote", - "InstanceContent", - "Item", - "Recipe", - "Fate", - "Quest", - "ContentFinderCondition", - "Balloon", - "BuddyEquip", - "Orchestrion", - "PlaceName", - "Weather", - "World", - "Map", - "lore_finder", -} - -export interface SearchResult { - /** - * The pagination data for the search. - */ - Pagination: { - Page: number; - PageNext: number | null; - PagePrev: number | null; - PageTotal: number; - Results: number; - ResultsPerPage: number; - ResultsTotal: number; - }; - - /** - * The results obtained from the search. - */ - Results: unknown[]; -} - -export interface SearchIndexResult extends SearchResult { - Results: { ID: number; Icon: string | null; Name: string | null; Url: string }[]; -} - -interface SearchParams { - /**- - * The name to search for, you can use `+` for spaces or let the API handle it for you. - */ - name?: string; - - /** - * The server to search against, this is case sensitive. - * @see https://xivapi.com/servers - */ - server?: string; - - /** - * Search or move to a specific page. - */ - page?: number; -} diff --git a/utils.js b/utils.js deleted file mode 100644 index f3e6c4d..0000000 --- a/utils.js +++ /dev/null @@ -1,51 +0,0 @@ -const request = require('@root/request') - -module.exports = { - //standard request function - async req(path, params={}) { - let convs = ['snake_case', 'extended'] - for (const c of convs) { - if(typeof params[c] !== 'undefined') - params[c] = params[c] ? 1 : 0 - } - - - params = Object.assign({}, this.globalParams, params) - - if(this.verbose) - console.log(`Requesting ${path} with params: `, params) - - return (await request({ - url: `${this.endpoint + path}${Object.keys(params).length > 0 ? `?${new URLSearchParams(params).toString()}` : ''}`, - json: true - })).body - }, - - //JSON request function - async reqJSON(path, body) { - if(this.verbose) - console.log(`Requesting ${path} with body: `, body) - - return (await request({ - method: 'POST', - url: this.endpoint + path, - body: body, - json: true - })).body - }, - - //handle both comma-separated strings, and string arrays, for CSV params - makeCSV(x) { - if(typeof(x) === 'undefined') - return - - if(Array.isArray(x)) - return x.join(',') - if(typeof(x) === 'string') - return x - }, - - throwError(method, param) { - return Error(`xivapi-js: Can't use ${method} without providing ${param}.`) - } -}