├── .editorconfig ├── .eslintrc.json ├── .gitignore ├── JavaScript ├── 0-contract.js ├── 1-callbacks.js ├── 2-promise.js ├── 3-promisify.js ├── 4-catch.js ├── 5-finally.js ├── 6-fetch.js ├── 7-http.js ├── 8-all.js ├── 9-race.js ├── Tasks │ ├── 1-adapter.js │ ├── 2-promise.js │ ├── 3-chain.js │ ├── 4-iterate.js │ └── 5-reject.js ├── a-any.js ├── b-thenable.js ├── c-expirable.js ├── d-resolvers.js ├── e-try.js ├── file1.txt ├── file2.txt ├── file3.txt └── server.js ├── LICENSE ├── README.md ├── eslint.config.js ├── package-lock.json ├── package.json └── prettier.config.js /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | end_of_line = lf 6 | charset = utf-8 7 | insert_final_newline = true 8 | trim_trailing_whitespace = true 9 | 10 | [{*.js,*.mjs,*.ts,*.json,*.yml}] 11 | indent_size = 2 12 | indent_style = space 13 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": true, 4 | "es6": true, 5 | "node": true 6 | }, 7 | "extends": "eslint:recommended", 8 | "parserOptions": { 9 | "ecmaVersion": "latest" 10 | }, 11 | "globals": { 12 | "BigInt": true 13 | }, 14 | "rules": { 15 | "indent": [ 16 | "error", 17 | 2 18 | ], 19 | "linebreak-style": [ 20 | "error", 21 | "unix" 22 | ], 23 | "quotes": [ 24 | "error", 25 | "single" 26 | ], 27 | "semi": [ 28 | "error", 29 | "always" 30 | ], 31 | "no-loop-func": [ 32 | "error" 33 | ], 34 | "block-spacing": [ 35 | "error", 36 | "always" 37 | ], 38 | "camelcase": [ 39 | "error" 40 | ], 41 | "eqeqeq": [ 42 | "error", 43 | "always" 44 | ], 45 | "strict": [ 46 | "error", 47 | "global" 48 | ], 49 | "brace-style": [ 50 | "error", 51 | "1tbs", 52 | { 53 | "allowSingleLine": true 54 | } 55 | ], 56 | "comma-style": [ 57 | "error", 58 | "last" 59 | ], 60 | "comma-spacing": [ 61 | "error", 62 | { 63 | "before": false, 64 | "after": true 65 | } 66 | ], 67 | "eol-last": [ 68 | "error" 69 | ], 70 | "func-call-spacing": [ 71 | "error", 72 | "never" 73 | ], 74 | "key-spacing": [ 75 | "error", 76 | { 77 | "beforeColon": false, 78 | "afterColon": true, 79 | "mode": "minimum" 80 | } 81 | ], 82 | "keyword-spacing": [ 83 | "error", 84 | { 85 | "before": true, 86 | "after": true, 87 | "overrides": { 88 | "function": { 89 | "after": false 90 | } 91 | } 92 | } 93 | ], 94 | "max-len": [ 95 | "error", 96 | { 97 | "code": 80, 98 | "ignoreUrls": true 99 | } 100 | ], 101 | "max-nested-callbacks": [ 102 | "error", 103 | { 104 | "max": 7 105 | } 106 | ], 107 | "new-cap": [ 108 | "error", 109 | { 110 | "newIsCap": true, 111 | "capIsNew": false, 112 | "properties": true 113 | } 114 | ], 115 | "new-parens": [ 116 | "error" 117 | ], 118 | "no-lonely-if": [ 119 | "error" 120 | ], 121 | "no-trailing-spaces": [ 122 | "error" 123 | ], 124 | "no-unneeded-ternary": [ 125 | "error" 126 | ], 127 | "no-whitespace-before-property": [ 128 | "error" 129 | ], 130 | "object-curly-spacing": [ 131 | "error", 132 | "always" 133 | ], 134 | "operator-assignment": [ 135 | "error", 136 | "always" 137 | ], 138 | "operator-linebreak": [ 139 | "error", 140 | "after" 141 | ], 142 | "semi-spacing": [ 143 | "error", 144 | { 145 | "before": false, 146 | "after": true 147 | } 148 | ], 149 | "space-before-blocks": [ 150 | "error", 151 | "always" 152 | ], 153 | "space-before-function-paren": [ 154 | "error", 155 | { 156 | "anonymous": "never", 157 | "named": "never", 158 | "asyncArrow": "always" 159 | } 160 | ], 161 | "space-in-parens": [ 162 | "error", 163 | "never" 164 | ], 165 | "space-infix-ops": [ 166 | "error" 167 | ], 168 | "space-unary-ops": [ 169 | "error", 170 | { 171 | "words": true, 172 | "nonwords": false, 173 | "overrides": { 174 | "typeof": false 175 | } 176 | } 177 | ], 178 | "no-unreachable": [ 179 | "error" 180 | ], 181 | "no-global-assign": [ 182 | "error" 183 | ], 184 | "no-self-compare": [ 185 | "error" 186 | ], 187 | "no-unmodified-loop-condition": [ 188 | "error" 189 | ], 190 | "no-constant-condition": [ 191 | "error", 192 | { 193 | "checkLoops": false 194 | } 195 | ], 196 | "no-console": [ 197 | "off" 198 | ], 199 | "no-useless-concat": [ 200 | "error" 201 | ], 202 | "no-useless-escape": [ 203 | "error" 204 | ], 205 | "no-shadow-restricted-names": [ 206 | "error" 207 | ], 208 | "no-use-before-define": [ 209 | "error", 210 | { 211 | "functions": false 212 | } 213 | ], 214 | "arrow-parens": [ 215 | "error", 216 | "always" 217 | ], 218 | "arrow-body-style": [ 219 | "error", 220 | "as-needed" 221 | ], 222 | "arrow-spacing": [ 223 | "error" 224 | ], 225 | "no-confusing-arrow": [ 226 | "error", 227 | { 228 | "allowParens": true 229 | } 230 | ], 231 | "no-useless-computed-key": [ 232 | "error" 233 | ], 234 | "no-useless-rename": [ 235 | "error" 236 | ], 237 | "no-var": [ 238 | "error" 239 | ], 240 | "object-shorthand": [ 241 | "error", 242 | "always" 243 | ], 244 | "prefer-arrow-callback": [ 245 | "error" 246 | ], 247 | "prefer-const": [ 248 | "error" 249 | ], 250 | "prefer-numeric-literals": [ 251 | "error" 252 | ], 253 | "prefer-rest-params": [ 254 | "error" 255 | ], 256 | "prefer-spread": [ 257 | "error" 258 | ], 259 | "rest-spread-spacing": [ 260 | "error", 261 | "never" 262 | ], 263 | "template-curly-spacing": [ 264 | "error", 265 | "never" 266 | ], 267 | "consistent-return": [ 268 | "error", 269 | { "treatUndefinedAsUnspecified": true } 270 | ] 271 | } 272 | } 273 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | *.log 3 | .DS_Store 4 | -------------------------------------------------------------------------------- /JavaScript/0-contract.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const promise = new Promise((resolve, reject) => { 4 | setTimeout(() => { 5 | resolve(100); 6 | //reject(new Error('Custom error')); 7 | }, 0); 8 | }); 9 | 10 | console.dir(promise); // Promise { } 11 | 12 | promise.then( 13 | (value) => { 14 | console.log({ value }); 15 | }, 16 | (error) => { 17 | console.error(error); 18 | }, 19 | ); 20 | -------------------------------------------------------------------------------- /JavaScript/1-callbacks.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const fs = require('node:fs'); 4 | 5 | fs.readFile('file1.txt', 'utf8', (err, data) => { 6 | if (err) console.error(err); 7 | else console.log({ data }); 8 | fs.readFile('file2.txt', 'utf8', (err, data) => { 9 | if (err) console.error(err); 10 | else console.log({ data }); 11 | fs.readFile('file3.txt', 'utf8', (err, data) => { 12 | if (err) console.error(err); 13 | else console.log({ data }); 14 | }); 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /JavaScript/2-promise.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // Pending 4 | 5 | const promise1 = new Promise((resolve) => { 6 | setTimeout(() => { 7 | resolve('value1'); 8 | }, 0); 9 | }); 10 | console.dir({ promise1 }); // Promise { } 11 | promise1.then(console.log); // 'value1' (delayed) 12 | 13 | // Immediate resolve 14 | 15 | const promise2 = new Promise((resolve) => resolve('value2')); 16 | console.dir({ promise2 }); // Promise { 'value2' } 17 | promise2.then(console.log); // 'value2' 18 | 19 | // Immediate reject 20 | 21 | const promise3 = new Promise((resolve, reject) => { 22 | reject(new Error('I have no value for you')); 23 | }); 24 | console.dir({ promise3 }); // Promise { Error... } 25 | promise3.then(console.log).catch(console.log); // Error... 26 | 27 | // Promise.resolve 28 | 29 | const promise4 = Promise.resolve('value4'); 30 | console.log({ promise4 }); // Promise { 'value4' } 31 | promise4.then(console.log); // 'value4' 32 | 33 | // Promise.reject 34 | 35 | const promise5 = Promise.reject(new Error('I have no value for you')); 36 | console.dir({ promise5 }); // Promise { Error... } 37 | promise5.then(console.log).catch(console.log); // Error... 38 | 39 | // Example with I/O 40 | 41 | const fs = require('node:fs'); 42 | 43 | const readFile = (filename, encoding) => 44 | new Promise((resolve, reject) => 45 | fs.readFile(filename, encoding, (err, data) => { 46 | if (err) reject(err); 47 | else resolve(data.toString()); 48 | }), 49 | ); 50 | 51 | readFile('file1.txt', 'utf8') 52 | .then((data) => { 53 | console.log(data); 54 | return readFile('file2.txt', 'utf8'); 55 | }) 56 | .then((data) => { 57 | console.log(data); 58 | return readFile('file3.txt', 'utf8'); 59 | }) 60 | .then((data) => { 61 | console.log(data); 62 | }); 63 | -------------------------------------------------------------------------------- /JavaScript/3-promisify.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const promisify = 4 | (fn) => 5 | (...args) => 6 | new Promise((resolve, reject) => { 7 | args.push((err, result) => { 8 | if (err) reject(err); 9 | else resolve(result); 10 | }); 11 | fn(...args); 12 | }); 13 | 14 | const fs = require('node:fs'); 15 | 16 | const readFile1 = promisify(fs.readFile); 17 | 18 | readFile1('file1.txt', 'utf8') 19 | .then((data) => { 20 | console.log(data.toString()); 21 | return readFile1('file2.txt', 'utf8'); 22 | }) 23 | .then((data) => { 24 | console.log(data.toString()); 25 | return readFile1('file3.txt', 'utf8'); 26 | }) 27 | .then((data) => { 28 | console.log(data.toString()); 29 | }) 30 | .catch((err) => { 31 | console.log(err); 32 | }); 33 | 34 | const util = require('node:util'); 35 | 36 | const readFile2 = util.promisify(fs.readFile); 37 | 38 | readFile2('file1.txt', 'utf8') 39 | .then((data) => { 40 | console.log(data.toString()); 41 | return readFile2('file2.txt', 'utf8'); 42 | }) 43 | .then((data) => { 44 | console.log(data.toString()); 45 | return readFile2('file3.txt', 'utf8'); 46 | }) 47 | .then((data) => { 48 | console.log(data.toString()); 49 | }) 50 | .catch((err) => { 51 | console.log(err); 52 | }); 53 | -------------------------------------------------------------------------------- /JavaScript/4-catch.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const { readFile } = require('node:fs/promises'); 4 | 5 | readFile('file1.txt', 'utf8') 6 | .then( 7 | (data) => { 8 | console.dir({ file1: data }); 9 | return readFile('file2.txt', 'utf8'); 10 | }, 11 | (reason) => { 12 | console.log('1: Cannot read file1.txt'); 13 | console.log(reason); 14 | }, 15 | ) 16 | .catch((reason) => { 17 | console.log('2: Cannot read file1.txt'); 18 | console.log(reason); 19 | }) 20 | .then((data) => { 21 | console.dir({ file2: data }); 22 | return readFile('file3.txt', 'utf8'); 23 | }) 24 | .catch((reason) => { 25 | console.log('Cannot read file2.txt'); 26 | console.log(reason); 27 | }) 28 | .then((data) => { 29 | console.dir({ file3: data }); 30 | }) 31 | .catch((reason) => { 32 | console.log('Cannot read file'); 33 | console.log(reason); 34 | }); 35 | -------------------------------------------------------------------------------- /JavaScript/5-finally.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const { readFile } = require('node:fs/promises'); 4 | 5 | readFile('file1.txt', 'utf8') 6 | .then((data) => { 7 | console.dir({ file1: data }); 8 | }) 9 | .catch((reason) => { 10 | console.log('Cannot read file1.txt'); 11 | console.log(reason); 12 | }) 13 | .finally(() => { 14 | console.log('finally'); 15 | }); 16 | -------------------------------------------------------------------------------- /JavaScript/6-fetch.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const http = require('node:http'); 4 | 5 | const fetch = (url) => 6 | new Promise((resolve, reject) => { 7 | http.get(url, async (res) => { 8 | const code = res.statusCode; 9 | if (code !== 200) { 10 | const err = new Error(`HTTP status code ${code}`); 11 | return void reject(err); 12 | } 13 | const chunks = []; 14 | for await (const chunk of res) chunks.push(chunk); 15 | const data = Buffer.concat(chunks).toString(); 16 | resolve(JSON.parse(data)); 17 | }); 18 | }); 19 | 20 | module.exports = fetch; 21 | -------------------------------------------------------------------------------- /JavaScript/7-http.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const fetch = require('./6-fetch.js'); 4 | 5 | fetch('http://localhost:3000/person') 6 | .then((data) => { 7 | console.log(data); 8 | }) 9 | .catch((err) => { 10 | console.error(err); 11 | }); 12 | -------------------------------------------------------------------------------- /JavaScript/8-all.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const baseUrl = 'http://localhost:3000'; 4 | 5 | const promises = [ 6 | fetch(baseUrl + '/person'), 7 | fetch(baseUrl + '/'), 8 | fetch(baseUrl + '/city'), 9 | ]; 10 | 11 | Promise.allSettled(promises) 12 | //Promise.all(promises) 13 | .then((values) => { 14 | console.log(values); 15 | }) 16 | .catch((err) => { 17 | console.log(err); 18 | }); 19 | -------------------------------------------------------------------------------- /JavaScript/9-race.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const baseUrl = 'http://localhost:3000'; 4 | 5 | const promises = [ 6 | fetch(baseUrl + '/person'), 7 | fetch(baseUrl + '/'), 8 | fetch(baseUrl + '/city'), 9 | ]; 10 | 11 | Promise.race(promises) 12 | .then((res) => { 13 | console.log(res); 14 | }) 15 | .catch((err) => { 16 | console.log(err); 17 | }); 18 | -------------------------------------------------------------------------------- /JavaScript/Tasks/1-adapter.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // Task: create Promise-returning adapter function `totalAsync` 4 | // Do not change function `total` contract, just call `total` from 5 | // `totalAsync` and convert contracts 6 | 7 | // Should not be changed 8 | const total = (items, callback) => { 9 | let result = 0; 10 | for (const item of items) { 11 | if (item.price < 0) { 12 | callback(new Error('Negative price is not allowed')); 13 | return; 14 | } 15 | result += item.price; 16 | } 17 | callback(null, result); 18 | }; 19 | 20 | // const totalAsync = (items) => new Promise... 21 | 22 | const electronics = [ 23 | { name: 'Laptop', price: 1500 }, 24 | { name: 'Keyboard', price: 100 }, 25 | { name: 'HDMI cable', price: 10 }, 26 | ]; 27 | 28 | // Also rewrite call, use .then instead of callback 29 | total(electronics, (error, money) => { 30 | if (error) console.error({ error }); 31 | else console.log({ money }); 32 | }); 33 | -------------------------------------------------------------------------------- /JavaScript/Tasks/2-promise.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // Task: rewrite `total` from callbacks contract to promises 4 | // Hint: do not use `async () =>` syntax 5 | 6 | const total = (items, callback) => { 7 | let result = 0; 8 | for (const item of items) { 9 | if (item.price < 0) { 10 | callback(new Error('Negative price is not allowed')); 11 | return; 12 | } 13 | result += item.price; 14 | } 15 | callback(null, result); 16 | }; 17 | 18 | const electronics = [ 19 | { name: 'Laptop', price: 1500 }, 20 | { name: 'Keyboard', price: 100 }, 21 | { name: 'HDMI cable', price: 10 }, 22 | ]; 23 | 24 | total(electronics, (error, money) => { 25 | if (error) console.error({ error }); 26 | else console.log({ money }); 27 | }); 28 | -------------------------------------------------------------------------------- /JavaScript/Tasks/3-chain.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // Task: here is given code you can't touch but you need to 4 | // write solution below to sum given prices (wrapped in promises). 5 | // Use Promise.all to resolve promises. 6 | // Use functions: `formatMoney` and `sum` as utilities. 7 | // Additional task: add .catch and .finally blocks in chain 8 | 9 | // Do not touch following code 10 | 11 | const CURRENCY_RATE = 1.09; 12 | 13 | const convert = ({ price }) => Promise.resolve(price * CURRENCY_RATE); 14 | 15 | const electronics = [ 16 | { name: 'Laptop', price: 1500 }, 17 | { name: 'Keyboard', price: 100 }, 18 | { name: 'HDMI cable', price: 10 }, 19 | ]; 20 | 21 | const prices = electronics.map(convert); 22 | 23 | const formatMoney = (x) => parseFloat(x.toFixed(2)); 24 | 25 | const sum = (a, b) => a + b; 26 | 27 | // Write solution below 28 | -------------------------------------------------------------------------------- /JavaScript/Tasks/4-iterate.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // Task: change `iterate` contract from chainable callbacks 4 | // to Promise (chainable or you can call it with await syntax) 5 | 6 | const iterate = (items) => { 7 | let index = 0; 8 | const chain = { 9 | next: (callback) => { 10 | if (index < items.length) { 11 | callback(items[index++]); 12 | } 13 | return chain; 14 | }, 15 | }; 16 | return chain; 17 | }; 18 | 19 | const electronics = [ 20 | { name: 'Laptop', price: 1500 }, 21 | { name: 'Keyboard', price: 100 }, 22 | { name: 'HDMI cable', price: 10 }, 23 | ]; 24 | 25 | // Use await syntax to get items 26 | iterate(electronics) 27 | .next((item) => { 28 | console.log(item); 29 | }) 30 | .next((item) => { 31 | console.log(item); 32 | }) 33 | .next((item) => { 34 | console.log(item); 35 | }); 36 | -------------------------------------------------------------------------------- /JavaScript/Tasks/5-reject.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // Task: support rejection with an error, if no more items in 4 | // `items` array are available to return with `.next()` 5 | // Change throwing error to returning rejected Promise. 6 | // Catch error with `.catch` or `try/catch` to handle it. 7 | 8 | const iterate = (items) => { 9 | let index = 0; 10 | return { 11 | next: () => 12 | new Promise((fulfill) => { 13 | if (index < items.length) { 14 | return fulfill(items[index++]); 15 | } 16 | throw new Error('No more items to iterate'); 17 | }), 18 | }; 19 | }; 20 | 21 | const electronics = [ 22 | { name: 'Laptop', price: 1500 }, 23 | { name: 'Keyboard', price: 100 }, 24 | { name: 'HDMI cable', price: 10 }, 25 | ]; 26 | 27 | const main = async () => { 28 | const items = iterate(electronics); 29 | const item1 = await items.next(); 30 | console.log(item1); 31 | const item2 = await items.next(); 32 | console.log(item2); 33 | const item3 = await items.next(); 34 | console.log(item3); 35 | const item4 = await items.next(); 36 | console.log(item4); 37 | }; 38 | 39 | main(); 40 | -------------------------------------------------------------------------------- /JavaScript/a-any.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const baseUrl = 'http://localhost:3000'; 4 | 5 | const promises = [ 6 | fetch(baseUrl + '/person'), 7 | fetch(baseUrl + '/'), 8 | fetch(baseUrl + '/city'), 9 | ]; 10 | 11 | Promise.any(promises) 12 | .then((res) => { 13 | console.log(res); 14 | }) 15 | .catch((err) => { 16 | console.log(err); 17 | }); 18 | -------------------------------------------------------------------------------- /JavaScript/b-thenable.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const fs = require('node:fs'); 4 | 5 | class Thenable { 6 | next = null; 7 | 8 | then(fn) { 9 | this.fn = fn; 10 | this.next = new Thenable(); 11 | return this.next; 12 | } 13 | 14 | resolve(value) { 15 | if (!this.fn) return; 16 | const next = this.fn(value); 17 | if (!next) return; 18 | next.then((value) => { 19 | this.next.resolve(value); 20 | }); 21 | } 22 | } 23 | 24 | // Usage 25 | 26 | const readFile = (filename) => { 27 | const thenable = new Thenable(); 28 | fs.readFile(filename, 'utf8', (err, data) => { 29 | if (err) throw err; 30 | thenable.resolve(data); 31 | }); 32 | return thenable; 33 | }; 34 | 35 | readFile('file1.txt') 36 | .then((data) => { 37 | console.dir({ file1: data }); 38 | return readFile('file2.txt'); 39 | }) 40 | .then((data) => { 41 | console.dir({ file2: data }); 42 | return readFile('file3.txt'); 43 | }) 44 | .then((data) => { 45 | console.dir({ file3: data }); 46 | }); 47 | -------------------------------------------------------------------------------- /JavaScript/c-expirable.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const PROMISE_TIMEOUT = 1000; 4 | 5 | class Expirable { 6 | constructor(executor) { 7 | const promise = new Promise((resolve, reject) => { 8 | executor( 9 | (val) => { 10 | if (this.expired) return; 11 | clearTimeout(this.timer); 12 | resolve(val); 13 | }, 14 | (err) => { 15 | if (this.expired) return; 16 | clearTimeout(this.timer); 17 | reject(err); 18 | }, 19 | ); 20 | this.timer = setTimeout(() => { 21 | this.expired = true; 22 | reject(new Error('Expired')); 23 | }, PROMISE_TIMEOUT); 24 | }); 25 | this.promise = promise; 26 | this.expired = false; 27 | this.timer = null; 28 | return this.promise; 29 | } 30 | } 31 | 32 | // Usage 33 | 34 | new Expirable((resolve) => { 35 | setTimeout(() => { 36 | resolve('Resolved before timeout'); 37 | }, 100); 38 | }) 39 | .then((data) => { 40 | console.dir({ data }); 41 | }) 42 | .catch((error) => { 43 | console.dir({ error: error.message }); 44 | }); 45 | 46 | new Expirable((resolve, reject) => { 47 | setTimeout(() => { 48 | reject(new Error('Something went wrong')); 49 | }, 100); 50 | }) 51 | .then((data) => { 52 | console.dir({ data }); 53 | }) 54 | .catch((error) => { 55 | console.dir({ error: error.message }); 56 | }); 57 | 58 | new Expirable((resolve) => { 59 | setTimeout(() => { 60 | resolve('Never resolved before timeout'); 61 | }, 2000); 62 | }) 63 | .then((data) => { 64 | console.dir({ data }); 65 | }) 66 | .catch((error) => { 67 | console.dir({ error: error.message }); 68 | }); 69 | 70 | new Expirable((resolve, reject) => { 71 | setTimeout(() => { 72 | reject(new Error('Never rejected before timeout')); 73 | }, 2000); 74 | }) 75 | .then((data) => { 76 | console.dir({ data }); 77 | }) 78 | .catch((error) => { 79 | console.dir({ error: error.message }); 80 | }); 81 | -------------------------------------------------------------------------------- /JavaScript/d-resolvers.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // Need node.js 22 4 | 5 | const sumAsync = (a, b, callback) => { 6 | if (typeof a !== 'number') return; 7 | if (typeof b !== 'number') return; 8 | setImmediate(() => { 9 | callback(a + b); 10 | }); 11 | }; 12 | 13 | // Old approach 14 | 15 | const old = async () => { 16 | let resolve, reject; 17 | const promise = new Promise((resolved, rejected) => { 18 | resolve = resolved; 19 | reject = rejected; 20 | }); 21 | setTimeout(reject, 1000, new Error('Timed out')); 22 | sumAsync(2, 3, resolve); 23 | const result = await promise; 24 | console.log({ result }); 25 | }; 26 | 27 | old(); 28 | 29 | // Alternative approach 30 | 31 | const alternative = async () => { 32 | const promise = new Promise((resolve, reject) => { 33 | sumAsync(4, 5, resolve); 34 | setTimeout(reject, 1000, new Error('Timed out')); 35 | }); 36 | const result = await promise; 37 | console.log({ result }); 38 | }; 39 | 40 | alternative(); 41 | 42 | // New approach 43 | 44 | const modern = async () => { 45 | const { promise, resolve, reject } = Promise.withResolvers(); 46 | setTimeout(reject, 1000, new Error('Timed out')); 47 | sumAsync(6, 7, resolve); 48 | const result = await promise; 49 | console.log({ result }); 50 | }; 51 | 52 | modern(); 53 | -------------------------------------------------------------------------------- /JavaScript/e-try.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // Need node.js 23 4 | 5 | const sumSync = (a, b) => { 6 | if (typeof a !== 'number') throw Error('Expected a: number'); 7 | if (typeof b !== 'number') throw Error('Expected b: number'); 8 | return a + b; 9 | }; 10 | 11 | const sumAsync = async (a, b) => { 12 | if (typeof a !== 'number') throw Error('Expected a: number'); 13 | if (typeof b !== 'number') throw Error('Expected b: number'); 14 | return a + b; 15 | }; 16 | 17 | // Call sync, expected 5 18 | 19 | Promise.try(sumSync, 2, 3) 20 | .then((result) => { 21 | console.log({ result }); 22 | }) 23 | .catch((error) => { 24 | console.error({ error: error.message }); 25 | }) 26 | .finally(() => { 27 | console.log({ finally: '2+3=5' }); 28 | }); 29 | 30 | // Call sync, expected error 31 | 32 | Promise.try(sumSync, '4', 5) 33 | .then((result) => { 34 | console.log({ result }); 35 | }) 36 | .catch((error) => { 37 | console.error({ error: error.message }); 38 | }) 39 | .finally(() => { 40 | console.log({ finally: 'Wrong type: a' }); 41 | }); 42 | 43 | // Call async, expected 13 44 | 45 | Promise.try(sumAsync, 6, 7) 46 | .then((result) => { 47 | console.log({ result }); 48 | }) 49 | .catch((error) => { 50 | console.error({ error: error.message }); 51 | }) 52 | .finally(() => { 53 | console.log({ finally: '6+7=13' }); 54 | }); 55 | 56 | // Call async, expected error 57 | 58 | Promise.try(sumAsync, 8, '9') 59 | .then((result) => { 60 | console.log({ result }); 61 | }) 62 | .catch((error) => { 63 | console.error({ error: error.message }); 64 | }) 65 | .finally(() => { 66 | console.log({ finally: 'Wrong type: b' }); 67 | }); 68 | -------------------------------------------------------------------------------- /JavaScript/file1.txt: -------------------------------------------------------------------------------- 1 | Text in the first file 2 | -------------------------------------------------------------------------------- /JavaScript/file2.txt: -------------------------------------------------------------------------------- 1 | Text in the second file 2 | -------------------------------------------------------------------------------- /JavaScript/file3.txt: -------------------------------------------------------------------------------- 1 | Text in the third file 2 | -------------------------------------------------------------------------------- /JavaScript/server.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const http = require('node:http'); 4 | 5 | const routes = { 6 | '/': (request, callback) => { 7 | callback({ 8 | apiVersion: '1.0', 9 | resources: ['person', 'city'], 10 | }); 11 | }, 12 | 13 | '/person': (request, callback) => { 14 | callback({ 15 | name: 'Alex', 16 | age: 19, 17 | }); 18 | }, 19 | 20 | '/city': (request, callback) => { 21 | callback({ 22 | name: 'Kyiv', 23 | country: 'Ukraine', 24 | }); 25 | }, 26 | }; 27 | 28 | const server = http.createServer((req, res) => { 29 | const handler = routes[req.url]; 30 | if (!handler) { 31 | res.writeHead(404); 32 | res.end('Not found'); 33 | return; 34 | } 35 | handler(req, (result) => { 36 | const json = JSON.stringify(result); 37 | res.writeHead(200, { 'Content-Type': 'application/json' }); 38 | res.end(json); 39 | }); 40 | }); 41 | 42 | server.listen(3000); 43 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017-2025 How.Programming.Works contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Asynchronity with Promise 2 | 3 | [👉 Оглавление курса Async 2024](https://github.com/HowProgrammingWorks/Index/blob/master/Courses/Async-2024.md) 4 | 5 | [![Асинхронность на промисах, Promise, all, then, catch, race](https://img.youtube.com/vi/RMl4r6s1Y8M/0.jpg)](https://www.youtube.com/watch?v=RMl4r6s1Y8M) 6 | -------------------------------------------------------------------------------- /eslint.config.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const init = require('eslint-config-metarhia'); 4 | 5 | init[0].rules['no-unused-vars'] = 'off'; 6 | 7 | module.exports = init; 8 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "patterns", 3 | "version": "1.0.0", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "patterns", 9 | "version": "1.0.0", 10 | "dependencies": { 11 | "eslint": "^9.12.0", 12 | "eslint-config-metarhia": "^9.1.1", 13 | "prettier": "^3.3.3" 14 | } 15 | }, 16 | "node_modules/@eslint-community/eslint-utils": { 17 | "version": "4.7.0", 18 | "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.7.0.tgz", 19 | "integrity": "sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==", 20 | "dependencies": { 21 | "eslint-visitor-keys": "^3.4.3" 22 | }, 23 | "engines": { 24 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0" 25 | }, 26 | "funding": { 27 | "url": "https://opencollective.com/eslint" 28 | }, 29 | "peerDependencies": { 30 | "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" 31 | } 32 | }, 33 | "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { 34 | "version": "3.4.3", 35 | "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", 36 | "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", 37 | "engines": { 38 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0" 39 | }, 40 | "funding": { 41 | "url": "https://opencollective.com/eslint" 42 | } 43 | }, 44 | "node_modules/@eslint-community/regexpp": { 45 | "version": "4.12.1", 46 | "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", 47 | "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", 48 | "engines": { 49 | "node": "^12.0.0 || ^14.0.0 || >=16.0.0" 50 | } 51 | }, 52 | "node_modules/@eslint/config-array": { 53 | "version": "0.20.0", 54 | "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.20.0.tgz", 55 | "integrity": "sha512-fxlS1kkIjx8+vy2SjuCB94q3htSNrufYTXubwiBFeaQHbH6Ipi43gFJq2zCMt6PHhImH3Xmr0NksKDvchWlpQQ==", 56 | "dependencies": { 57 | "@eslint/object-schema": "^2.1.6", 58 | "debug": "^4.3.1", 59 | "minimatch": "^3.1.2" 60 | }, 61 | "engines": { 62 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 63 | } 64 | }, 65 | "node_modules/@eslint/config-helpers": { 66 | "version": "0.2.2", 67 | "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.2.2.tgz", 68 | "integrity": "sha512-+GPzk8PlG0sPpzdU5ZvIRMPidzAnZDl/s9L+y13iodqvb8leL53bTannOrQ/Im7UkpsmFU5Ily5U60LWixnmLg==", 69 | "engines": { 70 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 71 | } 72 | }, 73 | "node_modules/@eslint/core": { 74 | "version": "0.13.0", 75 | "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.13.0.tgz", 76 | "integrity": "sha512-yfkgDw1KR66rkT5A8ci4irzDysN7FRpq3ttJolR88OqQikAWqwA8j5VZyas+vjyBNFIJ7MfybJ9plMILI2UrCw==", 77 | "dependencies": { 78 | "@types/json-schema": "^7.0.15" 79 | }, 80 | "engines": { 81 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 82 | } 83 | }, 84 | "node_modules/@eslint/eslintrc": { 85 | "version": "3.3.1", 86 | "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz", 87 | "integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==", 88 | "dependencies": { 89 | "ajv": "^6.12.4", 90 | "debug": "^4.3.2", 91 | "espree": "^10.0.1", 92 | "globals": "^14.0.0", 93 | "ignore": "^5.2.0", 94 | "import-fresh": "^3.2.1", 95 | "js-yaml": "^4.1.0", 96 | "minimatch": "^3.1.2", 97 | "strip-json-comments": "^3.1.1" 98 | }, 99 | "engines": { 100 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 101 | }, 102 | "funding": { 103 | "url": "https://opencollective.com/eslint" 104 | } 105 | }, 106 | "node_modules/@eslint/js": { 107 | "version": "9.26.0", 108 | "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.26.0.tgz", 109 | "integrity": "sha512-I9XlJawFdSMvWjDt6wksMCrgns5ggLNfFwFvnShsleWruvXM514Qxk8V246efTw+eo9JABvVz+u3q2RiAowKxQ==", 110 | "engines": { 111 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 112 | } 113 | }, 114 | "node_modules/@eslint/object-schema": { 115 | "version": "2.1.6", 116 | "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.6.tgz", 117 | "integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==", 118 | "engines": { 119 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 120 | } 121 | }, 122 | "node_modules/@eslint/plugin-kit": { 123 | "version": "0.2.8", 124 | "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.8.tgz", 125 | "integrity": "sha512-ZAoA40rNMPwSm+AeHpCq8STiNAwzWLJuP8Xv4CHIc9wv/PSuExjMrmjfYNj682vW0OOiZ1HKxzvjQr9XZIisQA==", 126 | "dependencies": { 127 | "@eslint/core": "^0.13.0", 128 | "levn": "^0.4.1" 129 | }, 130 | "engines": { 131 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 132 | } 133 | }, 134 | "node_modules/@humanfs/core": { 135 | "version": "0.19.1", 136 | "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", 137 | "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", 138 | "engines": { 139 | "node": ">=18.18.0" 140 | } 141 | }, 142 | "node_modules/@humanfs/node": { 143 | "version": "0.16.6", 144 | "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz", 145 | "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==", 146 | "dependencies": { 147 | "@humanfs/core": "^0.19.1", 148 | "@humanwhocodes/retry": "^0.3.0" 149 | }, 150 | "engines": { 151 | "node": ">=18.18.0" 152 | } 153 | }, 154 | "node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": { 155 | "version": "0.3.1", 156 | "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", 157 | "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", 158 | "engines": { 159 | "node": ">=18.18" 160 | }, 161 | "funding": { 162 | "type": "github", 163 | "url": "https://github.com/sponsors/nzakas" 164 | } 165 | }, 166 | "node_modules/@humanwhocodes/module-importer": { 167 | "version": "1.0.1", 168 | "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", 169 | "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", 170 | "engines": { 171 | "node": ">=12.22" 172 | }, 173 | "funding": { 174 | "type": "github", 175 | "url": "https://github.com/sponsors/nzakas" 176 | } 177 | }, 178 | "node_modules/@humanwhocodes/retry": { 179 | "version": "0.4.3", 180 | "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", 181 | "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", 182 | "engines": { 183 | "node": ">=18.18" 184 | }, 185 | "funding": { 186 | "type": "github", 187 | "url": "https://github.com/sponsors/nzakas" 188 | } 189 | }, 190 | "node_modules/@modelcontextprotocol/sdk": { 191 | "version": "1.11.1", 192 | "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.11.1.tgz", 193 | "integrity": "sha512-9LfmxKTb1v+vUS1/emSk1f5ePmTLkb9Le9AxOB5T0XM59EUumwcS45z05h7aiZx3GI0Bl7mjb3FMEglYj+acuQ==", 194 | "dependencies": { 195 | "content-type": "^1.0.5", 196 | "cors": "^2.8.5", 197 | "cross-spawn": "^7.0.3", 198 | "eventsource": "^3.0.2", 199 | "express": "^5.0.1", 200 | "express-rate-limit": "^7.5.0", 201 | "pkce-challenge": "^5.0.0", 202 | "raw-body": "^3.0.0", 203 | "zod": "^3.23.8", 204 | "zod-to-json-schema": "^3.24.1" 205 | }, 206 | "engines": { 207 | "node": ">=18" 208 | } 209 | }, 210 | "node_modules/@pkgr/core": { 211 | "version": "0.2.4", 212 | "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.2.4.tgz", 213 | "integrity": "sha512-ROFF39F6ZrnzSUEmQQZUar0Jt4xVoP9WnDRdWwF4NNcXs3xBTLgBUDoOwW141y1jP+S8nahIbdxbFC7IShw9Iw==", 214 | "engines": { 215 | "node": "^12.20.0 || ^14.18.0 || >=16.0.0" 216 | }, 217 | "funding": { 218 | "url": "https://opencollective.com/pkgr" 219 | } 220 | }, 221 | "node_modules/@types/estree": { 222 | "version": "1.0.7", 223 | "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz", 224 | "integrity": "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==" 225 | }, 226 | "node_modules/@types/json-schema": { 227 | "version": "7.0.15", 228 | "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", 229 | "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==" 230 | }, 231 | "node_modules/accepts": { 232 | "version": "2.0.0", 233 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz", 234 | "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==", 235 | "dependencies": { 236 | "mime-types": "^3.0.0", 237 | "negotiator": "^1.0.0" 238 | }, 239 | "engines": { 240 | "node": ">= 0.6" 241 | } 242 | }, 243 | "node_modules/acorn": { 244 | "version": "8.14.1", 245 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz", 246 | "integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==", 247 | "bin": { 248 | "acorn": "bin/acorn" 249 | }, 250 | "engines": { 251 | "node": ">=0.4.0" 252 | } 253 | }, 254 | "node_modules/acorn-jsx": { 255 | "version": "5.3.2", 256 | "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", 257 | "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", 258 | "peerDependencies": { 259 | "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" 260 | } 261 | }, 262 | "node_modules/ajv": { 263 | "version": "6.12.6", 264 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", 265 | "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", 266 | "dependencies": { 267 | "fast-deep-equal": "^3.1.1", 268 | "fast-json-stable-stringify": "^2.0.0", 269 | "json-schema-traverse": "^0.4.1", 270 | "uri-js": "^4.2.2" 271 | }, 272 | "funding": { 273 | "type": "github", 274 | "url": "https://github.com/sponsors/epoberezkin" 275 | } 276 | }, 277 | "node_modules/ansi-styles": { 278 | "version": "4.3.0", 279 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", 280 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", 281 | "dependencies": { 282 | "color-convert": "^2.0.1" 283 | }, 284 | "engines": { 285 | "node": ">=8" 286 | }, 287 | "funding": { 288 | "url": "https://github.com/chalk/ansi-styles?sponsor=1" 289 | } 290 | }, 291 | "node_modules/argparse": { 292 | "version": "2.0.1", 293 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", 294 | "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" 295 | }, 296 | "node_modules/balanced-match": { 297 | "version": "1.0.2", 298 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", 299 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" 300 | }, 301 | "node_modules/body-parser": { 302 | "version": "2.2.0", 303 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.0.tgz", 304 | "integrity": "sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg==", 305 | "dependencies": { 306 | "bytes": "^3.1.2", 307 | "content-type": "^1.0.5", 308 | "debug": "^4.4.0", 309 | "http-errors": "^2.0.0", 310 | "iconv-lite": "^0.6.3", 311 | "on-finished": "^2.4.1", 312 | "qs": "^6.14.0", 313 | "raw-body": "^3.0.0", 314 | "type-is": "^2.0.0" 315 | }, 316 | "engines": { 317 | "node": ">=18" 318 | } 319 | }, 320 | "node_modules/brace-expansion": { 321 | "version": "1.1.11", 322 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 323 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 324 | "dependencies": { 325 | "balanced-match": "^1.0.0", 326 | "concat-map": "0.0.1" 327 | } 328 | }, 329 | "node_modules/bytes": { 330 | "version": "3.1.2", 331 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", 332 | "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", 333 | "engines": { 334 | "node": ">= 0.8" 335 | } 336 | }, 337 | "node_modules/call-bind-apply-helpers": { 338 | "version": "1.0.2", 339 | "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", 340 | "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", 341 | "dependencies": { 342 | "es-errors": "^1.3.0", 343 | "function-bind": "^1.1.2" 344 | }, 345 | "engines": { 346 | "node": ">= 0.4" 347 | } 348 | }, 349 | "node_modules/call-bound": { 350 | "version": "1.0.4", 351 | "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", 352 | "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", 353 | "dependencies": { 354 | "call-bind-apply-helpers": "^1.0.2", 355 | "get-intrinsic": "^1.3.0" 356 | }, 357 | "engines": { 358 | "node": ">= 0.4" 359 | }, 360 | "funding": { 361 | "url": "https://github.com/sponsors/ljharb" 362 | } 363 | }, 364 | "node_modules/callsites": { 365 | "version": "3.1.0", 366 | "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", 367 | "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", 368 | "engines": { 369 | "node": ">=6" 370 | } 371 | }, 372 | "node_modules/chalk": { 373 | "version": "4.1.2", 374 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", 375 | "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", 376 | "dependencies": { 377 | "ansi-styles": "^4.1.0", 378 | "supports-color": "^7.1.0" 379 | }, 380 | "engines": { 381 | "node": ">=10" 382 | }, 383 | "funding": { 384 | "url": "https://github.com/chalk/chalk?sponsor=1" 385 | } 386 | }, 387 | "node_modules/color-convert": { 388 | "version": "2.0.1", 389 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", 390 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", 391 | "dependencies": { 392 | "color-name": "~1.1.4" 393 | }, 394 | "engines": { 395 | "node": ">=7.0.0" 396 | } 397 | }, 398 | "node_modules/color-name": { 399 | "version": "1.1.4", 400 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", 401 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" 402 | }, 403 | "node_modules/concat-map": { 404 | "version": "0.0.1", 405 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 406 | "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" 407 | }, 408 | "node_modules/content-disposition": { 409 | "version": "1.0.0", 410 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.0.tgz", 411 | "integrity": "sha512-Au9nRL8VNUut/XSzbQA38+M78dzP4D+eqg3gfJHMIHHYa3bg067xj1KxMUWj+VULbiZMowKngFFbKczUrNJ1mg==", 412 | "dependencies": { 413 | "safe-buffer": "5.2.1" 414 | }, 415 | "engines": { 416 | "node": ">= 0.6" 417 | } 418 | }, 419 | "node_modules/content-type": { 420 | "version": "1.0.5", 421 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", 422 | "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", 423 | "engines": { 424 | "node": ">= 0.6" 425 | } 426 | }, 427 | "node_modules/cookie": { 428 | "version": "0.7.2", 429 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", 430 | "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", 431 | "engines": { 432 | "node": ">= 0.6" 433 | } 434 | }, 435 | "node_modules/cookie-signature": { 436 | "version": "1.2.2", 437 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz", 438 | "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==", 439 | "engines": { 440 | "node": ">=6.6.0" 441 | } 442 | }, 443 | "node_modules/cors": { 444 | "version": "2.8.5", 445 | "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", 446 | "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", 447 | "dependencies": { 448 | "object-assign": "^4", 449 | "vary": "^1" 450 | }, 451 | "engines": { 452 | "node": ">= 0.10" 453 | } 454 | }, 455 | "node_modules/cross-spawn": { 456 | "version": "7.0.6", 457 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", 458 | "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", 459 | "dependencies": { 460 | "path-key": "^3.1.0", 461 | "shebang-command": "^2.0.0", 462 | "which": "^2.0.1" 463 | }, 464 | "engines": { 465 | "node": ">= 8" 466 | } 467 | }, 468 | "node_modules/debug": { 469 | "version": "4.4.0", 470 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", 471 | "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", 472 | "dependencies": { 473 | "ms": "^2.1.3" 474 | }, 475 | "engines": { 476 | "node": ">=6.0" 477 | }, 478 | "peerDependenciesMeta": { 479 | "supports-color": { 480 | "optional": true 481 | } 482 | } 483 | }, 484 | "node_modules/deep-is": { 485 | "version": "0.1.4", 486 | "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", 487 | "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==" 488 | }, 489 | "node_modules/depd": { 490 | "version": "2.0.0", 491 | "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", 492 | "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", 493 | "engines": { 494 | "node": ">= 0.8" 495 | } 496 | }, 497 | "node_modules/dunder-proto": { 498 | "version": "1.0.1", 499 | "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", 500 | "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", 501 | "dependencies": { 502 | "call-bind-apply-helpers": "^1.0.1", 503 | "es-errors": "^1.3.0", 504 | "gopd": "^1.2.0" 505 | }, 506 | "engines": { 507 | "node": ">= 0.4" 508 | } 509 | }, 510 | "node_modules/ee-first": { 511 | "version": "1.1.1", 512 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", 513 | "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" 514 | }, 515 | "node_modules/encodeurl": { 516 | "version": "2.0.0", 517 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", 518 | "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", 519 | "engines": { 520 | "node": ">= 0.8" 521 | } 522 | }, 523 | "node_modules/es-define-property": { 524 | "version": "1.0.1", 525 | "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", 526 | "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", 527 | "engines": { 528 | "node": ">= 0.4" 529 | } 530 | }, 531 | "node_modules/es-errors": { 532 | "version": "1.3.0", 533 | "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", 534 | "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", 535 | "engines": { 536 | "node": ">= 0.4" 537 | } 538 | }, 539 | "node_modules/es-object-atoms": { 540 | "version": "1.1.1", 541 | "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", 542 | "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", 543 | "dependencies": { 544 | "es-errors": "^1.3.0" 545 | }, 546 | "engines": { 547 | "node": ">= 0.4" 548 | } 549 | }, 550 | "node_modules/escape-html": { 551 | "version": "1.0.3", 552 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", 553 | "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" 554 | }, 555 | "node_modules/escape-string-regexp": { 556 | "version": "4.0.0", 557 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", 558 | "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", 559 | "engines": { 560 | "node": ">=10" 561 | }, 562 | "funding": { 563 | "url": "https://github.com/sponsors/sindresorhus" 564 | } 565 | }, 566 | "node_modules/eslint": { 567 | "version": "9.26.0", 568 | "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.26.0.tgz", 569 | "integrity": "sha512-Hx0MOjPh6uK9oq9nVsATZKE/Wlbai7KFjfCuw9UHaguDW3x+HF0O5nIi3ud39TWgrTjTO5nHxmL3R1eANinWHQ==", 570 | "dependencies": { 571 | "@eslint-community/eslint-utils": "^4.2.0", 572 | "@eslint-community/regexpp": "^4.12.1", 573 | "@eslint/config-array": "^0.20.0", 574 | "@eslint/config-helpers": "^0.2.1", 575 | "@eslint/core": "^0.13.0", 576 | "@eslint/eslintrc": "^3.3.1", 577 | "@eslint/js": "9.26.0", 578 | "@eslint/plugin-kit": "^0.2.8", 579 | "@humanfs/node": "^0.16.6", 580 | "@humanwhocodes/module-importer": "^1.0.1", 581 | "@humanwhocodes/retry": "^0.4.2", 582 | "@modelcontextprotocol/sdk": "^1.8.0", 583 | "@types/estree": "^1.0.6", 584 | "@types/json-schema": "^7.0.15", 585 | "ajv": "^6.12.4", 586 | "chalk": "^4.0.0", 587 | "cross-spawn": "^7.0.6", 588 | "debug": "^4.3.2", 589 | "escape-string-regexp": "^4.0.0", 590 | "eslint-scope": "^8.3.0", 591 | "eslint-visitor-keys": "^4.2.0", 592 | "espree": "^10.3.0", 593 | "esquery": "^1.5.0", 594 | "esutils": "^2.0.2", 595 | "fast-deep-equal": "^3.1.3", 596 | "file-entry-cache": "^8.0.0", 597 | "find-up": "^5.0.0", 598 | "glob-parent": "^6.0.2", 599 | "ignore": "^5.2.0", 600 | "imurmurhash": "^0.1.4", 601 | "is-glob": "^4.0.0", 602 | "json-stable-stringify-without-jsonify": "^1.0.1", 603 | "lodash.merge": "^4.6.2", 604 | "minimatch": "^3.1.2", 605 | "natural-compare": "^1.4.0", 606 | "optionator": "^0.9.3", 607 | "zod": "^3.24.2" 608 | }, 609 | "bin": { 610 | "eslint": "bin/eslint.js" 611 | }, 612 | "engines": { 613 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 614 | }, 615 | "funding": { 616 | "url": "https://eslint.org/donate" 617 | }, 618 | "peerDependencies": { 619 | "jiti": "*" 620 | }, 621 | "peerDependenciesMeta": { 622 | "jiti": { 623 | "optional": true 624 | } 625 | } 626 | }, 627 | "node_modules/eslint-config-metarhia": { 628 | "version": "9.1.1", 629 | "resolved": "https://registry.npmjs.org/eslint-config-metarhia/-/eslint-config-metarhia-9.1.1.tgz", 630 | "integrity": "sha512-PPJBiv+kFg7+0kkjHWp1k37TovG5prxIwiryiX8vQ6m2Jt4u4yIBjEjDd3P/RGXK7yrbMiiSyI2Z/GTWDS0C/Q==", 631 | "dependencies": { 632 | "eslint": "^9.10.0", 633 | "eslint-config-prettier": "^9.1.0", 634 | "eslint-plugin-prettier": "^5.2.1", 635 | "prettier": "^3.3.3" 636 | }, 637 | "engines": { 638 | "node": "18 || 20 || 21 || 22 || 23" 639 | }, 640 | "funding": { 641 | "type": "patreon", 642 | "url": "https://www.patreon.com/tshemsedinov" 643 | } 644 | }, 645 | "node_modules/eslint-config-prettier": { 646 | "version": "9.1.0", 647 | "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz", 648 | "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==", 649 | "bin": { 650 | "eslint-config-prettier": "bin/cli.js" 651 | }, 652 | "peerDependencies": { 653 | "eslint": ">=7.0.0" 654 | } 655 | }, 656 | "node_modules/eslint-plugin-prettier": { 657 | "version": "5.4.0", 658 | "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.4.0.tgz", 659 | "integrity": "sha512-BvQOvUhkVQM1i63iMETK9Hjud9QhqBnbtT1Zc642p9ynzBuCe5pybkOnvqZIBypXmMlsGcnU4HZ8sCTPfpAexA==", 660 | "dependencies": { 661 | "prettier-linter-helpers": "^1.0.0", 662 | "synckit": "^0.11.0" 663 | }, 664 | "engines": { 665 | "node": "^14.18.0 || >=16.0.0" 666 | }, 667 | "funding": { 668 | "url": "https://opencollective.com/eslint-plugin-prettier" 669 | }, 670 | "peerDependencies": { 671 | "@types/eslint": ">=8.0.0", 672 | "eslint": ">=8.0.0", 673 | "eslint-config-prettier": ">= 7.0.0 <10.0.0 || >=10.1.0", 674 | "prettier": ">=3.0.0" 675 | }, 676 | "peerDependenciesMeta": { 677 | "@types/eslint": { 678 | "optional": true 679 | }, 680 | "eslint-config-prettier": { 681 | "optional": true 682 | } 683 | } 684 | }, 685 | "node_modules/eslint-scope": { 686 | "version": "8.3.0", 687 | "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.3.0.tgz", 688 | "integrity": "sha512-pUNxi75F8MJ/GdeKtVLSbYg4ZI34J6C0C7sbL4YOp2exGwen7ZsuBqKzUhXd0qMQ362yET3z+uPwKeg/0C2XCQ==", 689 | "dependencies": { 690 | "esrecurse": "^4.3.0", 691 | "estraverse": "^5.2.0" 692 | }, 693 | "engines": { 694 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 695 | }, 696 | "funding": { 697 | "url": "https://opencollective.com/eslint" 698 | } 699 | }, 700 | "node_modules/eslint-visitor-keys": { 701 | "version": "4.2.0", 702 | "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", 703 | "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", 704 | "engines": { 705 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 706 | }, 707 | "funding": { 708 | "url": "https://opencollective.com/eslint" 709 | } 710 | }, 711 | "node_modules/espree": { 712 | "version": "10.3.0", 713 | "resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz", 714 | "integrity": "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==", 715 | "dependencies": { 716 | "acorn": "^8.14.0", 717 | "acorn-jsx": "^5.3.2", 718 | "eslint-visitor-keys": "^4.2.0" 719 | }, 720 | "engines": { 721 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 722 | }, 723 | "funding": { 724 | "url": "https://opencollective.com/eslint" 725 | } 726 | }, 727 | "node_modules/esquery": { 728 | "version": "1.6.0", 729 | "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", 730 | "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", 731 | "dependencies": { 732 | "estraverse": "^5.1.0" 733 | }, 734 | "engines": { 735 | "node": ">=0.10" 736 | } 737 | }, 738 | "node_modules/esrecurse": { 739 | "version": "4.3.0", 740 | "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", 741 | "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", 742 | "dependencies": { 743 | "estraverse": "^5.2.0" 744 | }, 745 | "engines": { 746 | "node": ">=4.0" 747 | } 748 | }, 749 | "node_modules/estraverse": { 750 | "version": "5.3.0", 751 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", 752 | "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", 753 | "engines": { 754 | "node": ">=4.0" 755 | } 756 | }, 757 | "node_modules/esutils": { 758 | "version": "2.0.3", 759 | "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", 760 | "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", 761 | "engines": { 762 | "node": ">=0.10.0" 763 | } 764 | }, 765 | "node_modules/etag": { 766 | "version": "1.8.1", 767 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", 768 | "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", 769 | "engines": { 770 | "node": ">= 0.6" 771 | } 772 | }, 773 | "node_modules/eventsource": { 774 | "version": "3.0.7", 775 | "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-3.0.7.tgz", 776 | "integrity": "sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==", 777 | "dependencies": { 778 | "eventsource-parser": "^3.0.1" 779 | }, 780 | "engines": { 781 | "node": ">=18.0.0" 782 | } 783 | }, 784 | "node_modules/eventsource-parser": { 785 | "version": "3.0.1", 786 | "resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.0.1.tgz", 787 | "integrity": "sha512-VARTJ9CYeuQYb0pZEPbzi740OWFgpHe7AYJ2WFZVnUDUQp5Dk2yJUgF36YsZ81cOyxT0QxmXD2EQpapAouzWVA==", 788 | "engines": { 789 | "node": ">=18.0.0" 790 | } 791 | }, 792 | "node_modules/express": { 793 | "version": "5.1.0", 794 | "resolved": "https://registry.npmjs.org/express/-/express-5.1.0.tgz", 795 | "integrity": "sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA==", 796 | "dependencies": { 797 | "accepts": "^2.0.0", 798 | "body-parser": "^2.2.0", 799 | "content-disposition": "^1.0.0", 800 | "content-type": "^1.0.5", 801 | "cookie": "^0.7.1", 802 | "cookie-signature": "^1.2.1", 803 | "debug": "^4.4.0", 804 | "encodeurl": "^2.0.0", 805 | "escape-html": "^1.0.3", 806 | "etag": "^1.8.1", 807 | "finalhandler": "^2.1.0", 808 | "fresh": "^2.0.0", 809 | "http-errors": "^2.0.0", 810 | "merge-descriptors": "^2.0.0", 811 | "mime-types": "^3.0.0", 812 | "on-finished": "^2.4.1", 813 | "once": "^1.4.0", 814 | "parseurl": "^1.3.3", 815 | "proxy-addr": "^2.0.7", 816 | "qs": "^6.14.0", 817 | "range-parser": "^1.2.1", 818 | "router": "^2.2.0", 819 | "send": "^1.1.0", 820 | "serve-static": "^2.2.0", 821 | "statuses": "^2.0.1", 822 | "type-is": "^2.0.1", 823 | "vary": "^1.1.2" 824 | }, 825 | "engines": { 826 | "node": ">= 18" 827 | }, 828 | "funding": { 829 | "type": "opencollective", 830 | "url": "https://opencollective.com/express" 831 | } 832 | }, 833 | "node_modules/express-rate-limit": { 834 | "version": "7.5.0", 835 | "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-7.5.0.tgz", 836 | "integrity": "sha512-eB5zbQh5h+VenMPM3fh+nw1YExi5nMr6HUCR62ELSP11huvxm/Uir1H1QEyTkk5QX6A58pX6NmaTMceKZ0Eodg==", 837 | "engines": { 838 | "node": ">= 16" 839 | }, 840 | "funding": { 841 | "url": "https://github.com/sponsors/express-rate-limit" 842 | }, 843 | "peerDependencies": { 844 | "express": "^4.11 || 5 || ^5.0.0-beta.1" 845 | } 846 | }, 847 | "node_modules/fast-deep-equal": { 848 | "version": "3.1.3", 849 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", 850 | "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" 851 | }, 852 | "node_modules/fast-diff": { 853 | "version": "1.3.0", 854 | "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", 855 | "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==" 856 | }, 857 | "node_modules/fast-json-stable-stringify": { 858 | "version": "2.1.0", 859 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", 860 | "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" 861 | }, 862 | "node_modules/fast-levenshtein": { 863 | "version": "2.0.6", 864 | "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", 865 | "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==" 866 | }, 867 | "node_modules/file-entry-cache": { 868 | "version": "8.0.0", 869 | "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", 870 | "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", 871 | "dependencies": { 872 | "flat-cache": "^4.0.0" 873 | }, 874 | "engines": { 875 | "node": ">=16.0.0" 876 | } 877 | }, 878 | "node_modules/finalhandler": { 879 | "version": "2.1.0", 880 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.0.tgz", 881 | "integrity": "sha512-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q==", 882 | "dependencies": { 883 | "debug": "^4.4.0", 884 | "encodeurl": "^2.0.0", 885 | "escape-html": "^1.0.3", 886 | "on-finished": "^2.4.1", 887 | "parseurl": "^1.3.3", 888 | "statuses": "^2.0.1" 889 | }, 890 | "engines": { 891 | "node": ">= 0.8" 892 | } 893 | }, 894 | "node_modules/find-up": { 895 | "version": "5.0.0", 896 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", 897 | "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", 898 | "dependencies": { 899 | "locate-path": "^6.0.0", 900 | "path-exists": "^4.0.0" 901 | }, 902 | "engines": { 903 | "node": ">=10" 904 | }, 905 | "funding": { 906 | "url": "https://github.com/sponsors/sindresorhus" 907 | } 908 | }, 909 | "node_modules/flat-cache": { 910 | "version": "4.0.1", 911 | "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", 912 | "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", 913 | "dependencies": { 914 | "flatted": "^3.2.9", 915 | "keyv": "^4.5.4" 916 | }, 917 | "engines": { 918 | "node": ">=16" 919 | } 920 | }, 921 | "node_modules/flatted": { 922 | "version": "3.3.3", 923 | "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", 924 | "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==" 925 | }, 926 | "node_modules/forwarded": { 927 | "version": "0.2.0", 928 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", 929 | "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", 930 | "engines": { 931 | "node": ">= 0.6" 932 | } 933 | }, 934 | "node_modules/fresh": { 935 | "version": "2.0.0", 936 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz", 937 | "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==", 938 | "engines": { 939 | "node": ">= 0.8" 940 | } 941 | }, 942 | "node_modules/function-bind": { 943 | "version": "1.1.2", 944 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", 945 | "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", 946 | "funding": { 947 | "url": "https://github.com/sponsors/ljharb" 948 | } 949 | }, 950 | "node_modules/get-intrinsic": { 951 | "version": "1.3.0", 952 | "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", 953 | "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", 954 | "dependencies": { 955 | "call-bind-apply-helpers": "^1.0.2", 956 | "es-define-property": "^1.0.1", 957 | "es-errors": "^1.3.0", 958 | "es-object-atoms": "^1.1.1", 959 | "function-bind": "^1.1.2", 960 | "get-proto": "^1.0.1", 961 | "gopd": "^1.2.0", 962 | "has-symbols": "^1.1.0", 963 | "hasown": "^2.0.2", 964 | "math-intrinsics": "^1.1.0" 965 | }, 966 | "engines": { 967 | "node": ">= 0.4" 968 | }, 969 | "funding": { 970 | "url": "https://github.com/sponsors/ljharb" 971 | } 972 | }, 973 | "node_modules/get-proto": { 974 | "version": "1.0.1", 975 | "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", 976 | "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", 977 | "dependencies": { 978 | "dunder-proto": "^1.0.1", 979 | "es-object-atoms": "^1.0.0" 980 | }, 981 | "engines": { 982 | "node": ">= 0.4" 983 | } 984 | }, 985 | "node_modules/glob-parent": { 986 | "version": "6.0.2", 987 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", 988 | "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", 989 | "dependencies": { 990 | "is-glob": "^4.0.3" 991 | }, 992 | "engines": { 993 | "node": ">=10.13.0" 994 | } 995 | }, 996 | "node_modules/globals": { 997 | "version": "14.0.0", 998 | "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", 999 | "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", 1000 | "engines": { 1001 | "node": ">=18" 1002 | }, 1003 | "funding": { 1004 | "url": "https://github.com/sponsors/sindresorhus" 1005 | } 1006 | }, 1007 | "node_modules/gopd": { 1008 | "version": "1.2.0", 1009 | "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", 1010 | "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", 1011 | "engines": { 1012 | "node": ">= 0.4" 1013 | }, 1014 | "funding": { 1015 | "url": "https://github.com/sponsors/ljharb" 1016 | } 1017 | }, 1018 | "node_modules/has-flag": { 1019 | "version": "4.0.0", 1020 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", 1021 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", 1022 | "engines": { 1023 | "node": ">=8" 1024 | } 1025 | }, 1026 | "node_modules/has-symbols": { 1027 | "version": "1.1.0", 1028 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", 1029 | "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", 1030 | "engines": { 1031 | "node": ">= 0.4" 1032 | }, 1033 | "funding": { 1034 | "url": "https://github.com/sponsors/ljharb" 1035 | } 1036 | }, 1037 | "node_modules/hasown": { 1038 | "version": "2.0.2", 1039 | "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", 1040 | "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", 1041 | "dependencies": { 1042 | "function-bind": "^1.1.2" 1043 | }, 1044 | "engines": { 1045 | "node": ">= 0.4" 1046 | } 1047 | }, 1048 | "node_modules/http-errors": { 1049 | "version": "2.0.0", 1050 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", 1051 | "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", 1052 | "dependencies": { 1053 | "depd": "2.0.0", 1054 | "inherits": "2.0.4", 1055 | "setprototypeof": "1.2.0", 1056 | "statuses": "2.0.1", 1057 | "toidentifier": "1.0.1" 1058 | }, 1059 | "engines": { 1060 | "node": ">= 0.8" 1061 | } 1062 | }, 1063 | "node_modules/iconv-lite": { 1064 | "version": "0.6.3", 1065 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", 1066 | "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", 1067 | "dependencies": { 1068 | "safer-buffer": ">= 2.1.2 < 3.0.0" 1069 | }, 1070 | "engines": { 1071 | "node": ">=0.10.0" 1072 | } 1073 | }, 1074 | "node_modules/ignore": { 1075 | "version": "5.3.2", 1076 | "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", 1077 | "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", 1078 | "engines": { 1079 | "node": ">= 4" 1080 | } 1081 | }, 1082 | "node_modules/import-fresh": { 1083 | "version": "3.3.1", 1084 | "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", 1085 | "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", 1086 | "dependencies": { 1087 | "parent-module": "^1.0.0", 1088 | "resolve-from": "^4.0.0" 1089 | }, 1090 | "engines": { 1091 | "node": ">=6" 1092 | }, 1093 | "funding": { 1094 | "url": "https://github.com/sponsors/sindresorhus" 1095 | } 1096 | }, 1097 | "node_modules/imurmurhash": { 1098 | "version": "0.1.4", 1099 | "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", 1100 | "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", 1101 | "engines": { 1102 | "node": ">=0.8.19" 1103 | } 1104 | }, 1105 | "node_modules/inherits": { 1106 | "version": "2.0.4", 1107 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 1108 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" 1109 | }, 1110 | "node_modules/ipaddr.js": { 1111 | "version": "1.9.1", 1112 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", 1113 | "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", 1114 | "engines": { 1115 | "node": ">= 0.10" 1116 | } 1117 | }, 1118 | "node_modules/is-extglob": { 1119 | "version": "2.1.1", 1120 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", 1121 | "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", 1122 | "engines": { 1123 | "node": ">=0.10.0" 1124 | } 1125 | }, 1126 | "node_modules/is-glob": { 1127 | "version": "4.0.3", 1128 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", 1129 | "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", 1130 | "dependencies": { 1131 | "is-extglob": "^2.1.1" 1132 | }, 1133 | "engines": { 1134 | "node": ">=0.10.0" 1135 | } 1136 | }, 1137 | "node_modules/is-promise": { 1138 | "version": "4.0.0", 1139 | "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", 1140 | "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==" 1141 | }, 1142 | "node_modules/isexe": { 1143 | "version": "2.0.0", 1144 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", 1145 | "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" 1146 | }, 1147 | "node_modules/js-yaml": { 1148 | "version": "4.1.0", 1149 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", 1150 | "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", 1151 | "dependencies": { 1152 | "argparse": "^2.0.1" 1153 | }, 1154 | "bin": { 1155 | "js-yaml": "bin/js-yaml.js" 1156 | } 1157 | }, 1158 | "node_modules/json-buffer": { 1159 | "version": "3.0.1", 1160 | "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", 1161 | "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==" 1162 | }, 1163 | "node_modules/json-schema-traverse": { 1164 | "version": "0.4.1", 1165 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", 1166 | "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" 1167 | }, 1168 | "node_modules/json-stable-stringify-without-jsonify": { 1169 | "version": "1.0.1", 1170 | "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", 1171 | "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==" 1172 | }, 1173 | "node_modules/keyv": { 1174 | "version": "4.5.4", 1175 | "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", 1176 | "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", 1177 | "dependencies": { 1178 | "json-buffer": "3.0.1" 1179 | } 1180 | }, 1181 | "node_modules/levn": { 1182 | "version": "0.4.1", 1183 | "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", 1184 | "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", 1185 | "dependencies": { 1186 | "prelude-ls": "^1.2.1", 1187 | "type-check": "~0.4.0" 1188 | }, 1189 | "engines": { 1190 | "node": ">= 0.8.0" 1191 | } 1192 | }, 1193 | "node_modules/locate-path": { 1194 | "version": "6.0.0", 1195 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", 1196 | "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", 1197 | "dependencies": { 1198 | "p-locate": "^5.0.0" 1199 | }, 1200 | "engines": { 1201 | "node": ">=10" 1202 | }, 1203 | "funding": { 1204 | "url": "https://github.com/sponsors/sindresorhus" 1205 | } 1206 | }, 1207 | "node_modules/lodash.merge": { 1208 | "version": "4.6.2", 1209 | "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", 1210 | "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" 1211 | }, 1212 | "node_modules/math-intrinsics": { 1213 | "version": "1.1.0", 1214 | "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", 1215 | "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", 1216 | "engines": { 1217 | "node": ">= 0.4" 1218 | } 1219 | }, 1220 | "node_modules/media-typer": { 1221 | "version": "1.1.0", 1222 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz", 1223 | "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==", 1224 | "engines": { 1225 | "node": ">= 0.8" 1226 | } 1227 | }, 1228 | "node_modules/merge-descriptors": { 1229 | "version": "2.0.0", 1230 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz", 1231 | "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==", 1232 | "engines": { 1233 | "node": ">=18" 1234 | }, 1235 | "funding": { 1236 | "url": "https://github.com/sponsors/sindresorhus" 1237 | } 1238 | }, 1239 | "node_modules/mime-db": { 1240 | "version": "1.54.0", 1241 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", 1242 | "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", 1243 | "engines": { 1244 | "node": ">= 0.6" 1245 | } 1246 | }, 1247 | "node_modules/mime-types": { 1248 | "version": "3.0.1", 1249 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz", 1250 | "integrity": "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==", 1251 | "dependencies": { 1252 | "mime-db": "^1.54.0" 1253 | }, 1254 | "engines": { 1255 | "node": ">= 0.6" 1256 | } 1257 | }, 1258 | "node_modules/minimatch": { 1259 | "version": "3.1.2", 1260 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", 1261 | "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", 1262 | "dependencies": { 1263 | "brace-expansion": "^1.1.7" 1264 | }, 1265 | "engines": { 1266 | "node": "*" 1267 | } 1268 | }, 1269 | "node_modules/ms": { 1270 | "version": "2.1.3", 1271 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 1272 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" 1273 | }, 1274 | "node_modules/natural-compare": { 1275 | "version": "1.4.0", 1276 | "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", 1277 | "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==" 1278 | }, 1279 | "node_modules/negotiator": { 1280 | "version": "1.0.0", 1281 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", 1282 | "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", 1283 | "engines": { 1284 | "node": ">= 0.6" 1285 | } 1286 | }, 1287 | "node_modules/object-assign": { 1288 | "version": "4.1.1", 1289 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", 1290 | "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", 1291 | "engines": { 1292 | "node": ">=0.10.0" 1293 | } 1294 | }, 1295 | "node_modules/object-inspect": { 1296 | "version": "1.13.4", 1297 | "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", 1298 | "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", 1299 | "engines": { 1300 | "node": ">= 0.4" 1301 | }, 1302 | "funding": { 1303 | "url": "https://github.com/sponsors/ljharb" 1304 | } 1305 | }, 1306 | "node_modules/on-finished": { 1307 | "version": "2.4.1", 1308 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", 1309 | "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", 1310 | "dependencies": { 1311 | "ee-first": "1.1.1" 1312 | }, 1313 | "engines": { 1314 | "node": ">= 0.8" 1315 | } 1316 | }, 1317 | "node_modules/once": { 1318 | "version": "1.4.0", 1319 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 1320 | "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", 1321 | "dependencies": { 1322 | "wrappy": "1" 1323 | } 1324 | }, 1325 | "node_modules/optionator": { 1326 | "version": "0.9.4", 1327 | "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", 1328 | "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", 1329 | "dependencies": { 1330 | "deep-is": "^0.1.3", 1331 | "fast-levenshtein": "^2.0.6", 1332 | "levn": "^0.4.1", 1333 | "prelude-ls": "^1.2.1", 1334 | "type-check": "^0.4.0", 1335 | "word-wrap": "^1.2.5" 1336 | }, 1337 | "engines": { 1338 | "node": ">= 0.8.0" 1339 | } 1340 | }, 1341 | "node_modules/p-limit": { 1342 | "version": "3.1.0", 1343 | "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", 1344 | "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", 1345 | "dependencies": { 1346 | "yocto-queue": "^0.1.0" 1347 | }, 1348 | "engines": { 1349 | "node": ">=10" 1350 | }, 1351 | "funding": { 1352 | "url": "https://github.com/sponsors/sindresorhus" 1353 | } 1354 | }, 1355 | "node_modules/p-locate": { 1356 | "version": "5.0.0", 1357 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", 1358 | "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", 1359 | "dependencies": { 1360 | "p-limit": "^3.0.2" 1361 | }, 1362 | "engines": { 1363 | "node": ">=10" 1364 | }, 1365 | "funding": { 1366 | "url": "https://github.com/sponsors/sindresorhus" 1367 | } 1368 | }, 1369 | "node_modules/parent-module": { 1370 | "version": "1.0.1", 1371 | "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", 1372 | "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", 1373 | "dependencies": { 1374 | "callsites": "^3.0.0" 1375 | }, 1376 | "engines": { 1377 | "node": ">=6" 1378 | } 1379 | }, 1380 | "node_modules/parseurl": { 1381 | "version": "1.3.3", 1382 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", 1383 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", 1384 | "engines": { 1385 | "node": ">= 0.8" 1386 | } 1387 | }, 1388 | "node_modules/path-exists": { 1389 | "version": "4.0.0", 1390 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", 1391 | "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", 1392 | "engines": { 1393 | "node": ">=8" 1394 | } 1395 | }, 1396 | "node_modules/path-key": { 1397 | "version": "3.1.1", 1398 | "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", 1399 | "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", 1400 | "engines": { 1401 | "node": ">=8" 1402 | } 1403 | }, 1404 | "node_modules/path-to-regexp": { 1405 | "version": "8.2.0", 1406 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.2.0.tgz", 1407 | "integrity": "sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ==", 1408 | "engines": { 1409 | "node": ">=16" 1410 | } 1411 | }, 1412 | "node_modules/pkce-challenge": { 1413 | "version": "5.0.0", 1414 | "resolved": "https://registry.npmjs.org/pkce-challenge/-/pkce-challenge-5.0.0.tgz", 1415 | "integrity": "sha512-ueGLflrrnvwB3xuo/uGob5pd5FN7l0MsLf0Z87o/UQmRtwjvfylfc9MurIxRAWywCYTgrvpXBcqjV4OfCYGCIQ==", 1416 | "engines": { 1417 | "node": ">=16.20.0" 1418 | } 1419 | }, 1420 | "node_modules/prelude-ls": { 1421 | "version": "1.2.1", 1422 | "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", 1423 | "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", 1424 | "engines": { 1425 | "node": ">= 0.8.0" 1426 | } 1427 | }, 1428 | "node_modules/prettier": { 1429 | "version": "3.5.3", 1430 | "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.5.3.tgz", 1431 | "integrity": "sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw==", 1432 | "bin": { 1433 | "prettier": "bin/prettier.cjs" 1434 | }, 1435 | "engines": { 1436 | "node": ">=14" 1437 | }, 1438 | "funding": { 1439 | "url": "https://github.com/prettier/prettier?sponsor=1" 1440 | } 1441 | }, 1442 | "node_modules/prettier-linter-helpers": { 1443 | "version": "1.0.0", 1444 | "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", 1445 | "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", 1446 | "dependencies": { 1447 | "fast-diff": "^1.1.2" 1448 | }, 1449 | "engines": { 1450 | "node": ">=6.0.0" 1451 | } 1452 | }, 1453 | "node_modules/proxy-addr": { 1454 | "version": "2.0.7", 1455 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", 1456 | "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", 1457 | "dependencies": { 1458 | "forwarded": "0.2.0", 1459 | "ipaddr.js": "1.9.1" 1460 | }, 1461 | "engines": { 1462 | "node": ">= 0.10" 1463 | } 1464 | }, 1465 | "node_modules/punycode": { 1466 | "version": "2.3.1", 1467 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", 1468 | "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", 1469 | "engines": { 1470 | "node": ">=6" 1471 | } 1472 | }, 1473 | "node_modules/qs": { 1474 | "version": "6.14.0", 1475 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz", 1476 | "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==", 1477 | "dependencies": { 1478 | "side-channel": "^1.1.0" 1479 | }, 1480 | "engines": { 1481 | "node": ">=0.6" 1482 | }, 1483 | "funding": { 1484 | "url": "https://github.com/sponsors/ljharb" 1485 | } 1486 | }, 1487 | "node_modules/range-parser": { 1488 | "version": "1.2.1", 1489 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", 1490 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", 1491 | "engines": { 1492 | "node": ">= 0.6" 1493 | } 1494 | }, 1495 | "node_modules/raw-body": { 1496 | "version": "3.0.0", 1497 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.0.tgz", 1498 | "integrity": "sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g==", 1499 | "dependencies": { 1500 | "bytes": "3.1.2", 1501 | "http-errors": "2.0.0", 1502 | "iconv-lite": "0.6.3", 1503 | "unpipe": "1.0.0" 1504 | }, 1505 | "engines": { 1506 | "node": ">= 0.8" 1507 | } 1508 | }, 1509 | "node_modules/resolve-from": { 1510 | "version": "4.0.0", 1511 | "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", 1512 | "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", 1513 | "engines": { 1514 | "node": ">=4" 1515 | } 1516 | }, 1517 | "node_modules/router": { 1518 | "version": "2.2.0", 1519 | "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz", 1520 | "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==", 1521 | "dependencies": { 1522 | "debug": "^4.4.0", 1523 | "depd": "^2.0.0", 1524 | "is-promise": "^4.0.0", 1525 | "parseurl": "^1.3.3", 1526 | "path-to-regexp": "^8.0.0" 1527 | }, 1528 | "engines": { 1529 | "node": ">= 18" 1530 | } 1531 | }, 1532 | "node_modules/safe-buffer": { 1533 | "version": "5.2.1", 1534 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 1535 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", 1536 | "funding": [ 1537 | { 1538 | "type": "github", 1539 | "url": "https://github.com/sponsors/feross" 1540 | }, 1541 | { 1542 | "type": "patreon", 1543 | "url": "https://www.patreon.com/feross" 1544 | }, 1545 | { 1546 | "type": "consulting", 1547 | "url": "https://feross.org/support" 1548 | } 1549 | ] 1550 | }, 1551 | "node_modules/safer-buffer": { 1552 | "version": "2.1.2", 1553 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 1554 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" 1555 | }, 1556 | "node_modules/send": { 1557 | "version": "1.2.0", 1558 | "resolved": "https://registry.npmjs.org/send/-/send-1.2.0.tgz", 1559 | "integrity": "sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==", 1560 | "dependencies": { 1561 | "debug": "^4.3.5", 1562 | "encodeurl": "^2.0.0", 1563 | "escape-html": "^1.0.3", 1564 | "etag": "^1.8.1", 1565 | "fresh": "^2.0.0", 1566 | "http-errors": "^2.0.0", 1567 | "mime-types": "^3.0.1", 1568 | "ms": "^2.1.3", 1569 | "on-finished": "^2.4.1", 1570 | "range-parser": "^1.2.1", 1571 | "statuses": "^2.0.1" 1572 | }, 1573 | "engines": { 1574 | "node": ">= 18" 1575 | } 1576 | }, 1577 | "node_modules/serve-static": { 1578 | "version": "2.2.0", 1579 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.0.tgz", 1580 | "integrity": "sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==", 1581 | "dependencies": { 1582 | "encodeurl": "^2.0.0", 1583 | "escape-html": "^1.0.3", 1584 | "parseurl": "^1.3.3", 1585 | "send": "^1.2.0" 1586 | }, 1587 | "engines": { 1588 | "node": ">= 18" 1589 | } 1590 | }, 1591 | "node_modules/setprototypeof": { 1592 | "version": "1.2.0", 1593 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", 1594 | "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" 1595 | }, 1596 | "node_modules/shebang-command": { 1597 | "version": "2.0.0", 1598 | "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", 1599 | "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", 1600 | "dependencies": { 1601 | "shebang-regex": "^3.0.0" 1602 | }, 1603 | "engines": { 1604 | "node": ">=8" 1605 | } 1606 | }, 1607 | "node_modules/shebang-regex": { 1608 | "version": "3.0.0", 1609 | "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", 1610 | "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", 1611 | "engines": { 1612 | "node": ">=8" 1613 | } 1614 | }, 1615 | "node_modules/side-channel": { 1616 | "version": "1.1.0", 1617 | "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", 1618 | "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", 1619 | "dependencies": { 1620 | "es-errors": "^1.3.0", 1621 | "object-inspect": "^1.13.3", 1622 | "side-channel-list": "^1.0.0", 1623 | "side-channel-map": "^1.0.1", 1624 | "side-channel-weakmap": "^1.0.2" 1625 | }, 1626 | "engines": { 1627 | "node": ">= 0.4" 1628 | }, 1629 | "funding": { 1630 | "url": "https://github.com/sponsors/ljharb" 1631 | } 1632 | }, 1633 | "node_modules/side-channel-list": { 1634 | "version": "1.0.0", 1635 | "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", 1636 | "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", 1637 | "dependencies": { 1638 | "es-errors": "^1.3.0", 1639 | "object-inspect": "^1.13.3" 1640 | }, 1641 | "engines": { 1642 | "node": ">= 0.4" 1643 | }, 1644 | "funding": { 1645 | "url": "https://github.com/sponsors/ljharb" 1646 | } 1647 | }, 1648 | "node_modules/side-channel-map": { 1649 | "version": "1.0.1", 1650 | "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", 1651 | "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", 1652 | "dependencies": { 1653 | "call-bound": "^1.0.2", 1654 | "es-errors": "^1.3.0", 1655 | "get-intrinsic": "^1.2.5", 1656 | "object-inspect": "^1.13.3" 1657 | }, 1658 | "engines": { 1659 | "node": ">= 0.4" 1660 | }, 1661 | "funding": { 1662 | "url": "https://github.com/sponsors/ljharb" 1663 | } 1664 | }, 1665 | "node_modules/side-channel-weakmap": { 1666 | "version": "1.0.2", 1667 | "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", 1668 | "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", 1669 | "dependencies": { 1670 | "call-bound": "^1.0.2", 1671 | "es-errors": "^1.3.0", 1672 | "get-intrinsic": "^1.2.5", 1673 | "object-inspect": "^1.13.3", 1674 | "side-channel-map": "^1.0.1" 1675 | }, 1676 | "engines": { 1677 | "node": ">= 0.4" 1678 | }, 1679 | "funding": { 1680 | "url": "https://github.com/sponsors/ljharb" 1681 | } 1682 | }, 1683 | "node_modules/statuses": { 1684 | "version": "2.0.1", 1685 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", 1686 | "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", 1687 | "engines": { 1688 | "node": ">= 0.8" 1689 | } 1690 | }, 1691 | "node_modules/strip-json-comments": { 1692 | "version": "3.1.1", 1693 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", 1694 | "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", 1695 | "engines": { 1696 | "node": ">=8" 1697 | }, 1698 | "funding": { 1699 | "url": "https://github.com/sponsors/sindresorhus" 1700 | } 1701 | }, 1702 | "node_modules/supports-color": { 1703 | "version": "7.2.0", 1704 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", 1705 | "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", 1706 | "dependencies": { 1707 | "has-flag": "^4.0.0" 1708 | }, 1709 | "engines": { 1710 | "node": ">=8" 1711 | } 1712 | }, 1713 | "node_modules/synckit": { 1714 | "version": "0.11.4", 1715 | "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.11.4.tgz", 1716 | "integrity": "sha512-Q/XQKRaJiLiFIBNN+mndW7S/RHxvwzuZS6ZwmRzUBqJBv/5QIKCEwkBC8GBf8EQJKYnaFs0wOZbKTXBPj8L9oQ==", 1717 | "dependencies": { 1718 | "@pkgr/core": "^0.2.3", 1719 | "tslib": "^2.8.1" 1720 | }, 1721 | "engines": { 1722 | "node": "^14.18.0 || >=16.0.0" 1723 | }, 1724 | "funding": { 1725 | "url": "https://opencollective.com/synckit" 1726 | } 1727 | }, 1728 | "node_modules/toidentifier": { 1729 | "version": "1.0.1", 1730 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", 1731 | "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", 1732 | "engines": { 1733 | "node": ">=0.6" 1734 | } 1735 | }, 1736 | "node_modules/tslib": { 1737 | "version": "2.8.1", 1738 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", 1739 | "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" 1740 | }, 1741 | "node_modules/type-check": { 1742 | "version": "0.4.0", 1743 | "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", 1744 | "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", 1745 | "dependencies": { 1746 | "prelude-ls": "^1.2.1" 1747 | }, 1748 | "engines": { 1749 | "node": ">= 0.8.0" 1750 | } 1751 | }, 1752 | "node_modules/type-is": { 1753 | "version": "2.0.1", 1754 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz", 1755 | "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==", 1756 | "dependencies": { 1757 | "content-type": "^1.0.5", 1758 | "media-typer": "^1.1.0", 1759 | "mime-types": "^3.0.0" 1760 | }, 1761 | "engines": { 1762 | "node": ">= 0.6" 1763 | } 1764 | }, 1765 | "node_modules/unpipe": { 1766 | "version": "1.0.0", 1767 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", 1768 | "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", 1769 | "engines": { 1770 | "node": ">= 0.8" 1771 | } 1772 | }, 1773 | "node_modules/uri-js": { 1774 | "version": "4.4.1", 1775 | "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", 1776 | "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", 1777 | "dependencies": { 1778 | "punycode": "^2.1.0" 1779 | } 1780 | }, 1781 | "node_modules/vary": { 1782 | "version": "1.1.2", 1783 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", 1784 | "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", 1785 | "engines": { 1786 | "node": ">= 0.8" 1787 | } 1788 | }, 1789 | "node_modules/which": { 1790 | "version": "2.0.2", 1791 | "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", 1792 | "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", 1793 | "dependencies": { 1794 | "isexe": "^2.0.0" 1795 | }, 1796 | "bin": { 1797 | "node-which": "bin/node-which" 1798 | }, 1799 | "engines": { 1800 | "node": ">= 8" 1801 | } 1802 | }, 1803 | "node_modules/word-wrap": { 1804 | "version": "1.2.5", 1805 | "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", 1806 | "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", 1807 | "engines": { 1808 | "node": ">=0.10.0" 1809 | } 1810 | }, 1811 | "node_modules/wrappy": { 1812 | "version": "1.0.2", 1813 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 1814 | "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" 1815 | }, 1816 | "node_modules/yocto-queue": { 1817 | "version": "0.1.0", 1818 | "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", 1819 | "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", 1820 | "engines": { 1821 | "node": ">=10" 1822 | }, 1823 | "funding": { 1824 | "url": "https://github.com/sponsors/sindresorhus" 1825 | } 1826 | }, 1827 | "node_modules/zod": { 1828 | "version": "3.24.4", 1829 | "resolved": "https://registry.npmjs.org/zod/-/zod-3.24.4.tgz", 1830 | "integrity": "sha512-OdqJE9UDRPwWsrHjLN2F8bPxvwJBK22EHLWtanu0LSYr5YqzsaaW3RMgmjwr8Rypg5k+meEJdSPXJZXE/yqOMg==", 1831 | "funding": { 1832 | "url": "https://github.com/sponsors/colinhacks" 1833 | } 1834 | }, 1835 | "node_modules/zod-to-json-schema": { 1836 | "version": "3.24.5", 1837 | "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.24.5.tgz", 1838 | "integrity": "sha512-/AuWwMP+YqiPbsJx5D6TfgRTc4kTLjsh5SOcd4bLsfUg2RcEXrFMJl1DGgdHy2aCfsIA/cr/1JM0xcB2GZji8g==", 1839 | "peerDependencies": { 1840 | "zod": "^3.24.1" 1841 | } 1842 | } 1843 | } 1844 | } 1845 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "patterns", 3 | "version": "1.0.0", 4 | "scripts": { 5 | "lint": "eslint . && prettier -c \"**/*.js\"", 6 | "fix": "eslint . --fix && prettier --write \"**/*.js\"" 7 | }, 8 | "author": "Timur Shemsedinov", 9 | "private": true, 10 | "dependencies": { 11 | "eslint": "^9.12.0", 12 | "eslint-config-metarhia": "^9.1.1", 13 | "prettier": "^3.3.3" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /prettier.config.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = { 4 | printWidth: 80, 5 | singleQuote: true, 6 | trailingComma: 'all', 7 | tabWidth: 2, 8 | useTabs: false, 9 | semi: true, 10 | }; 11 | --------------------------------------------------------------------------------