diff --git a/application/api/auth/provider.js b/application/api/auth/provider.js index 6b26357e..7232dfe2 100644 --- a/application/api/auth/provider.js +++ b/application/api/auth/provider.js @@ -6,15 +6,20 @@ async saveSession(token, data) { console.log({ saveSession: { token, data } }); + const payload = { data: JSON.stringify(data) }; try { - await db.pg.update('Session', { data: JSON.stringify(data) }, { token }); + await db.pg.update('Session', payload, { token }); } catch (error) { console.error(error); } }, async createSession(token, data, fields = {}) { - const record = { token, data: JSON.stringify(data), ...fields }; + const record = { + token, + data: JSON.stringify(data), + ...fields, + }; console.log({ createSession: record }); return db.pg.insert('Session', record); }, @@ -22,7 +27,7 @@ async readSession(token) { const record = await db.pg.row('Session', ['data'], { token }); console.log({ readSession: { token, record } }); - if (record && record.data) return record.data; + if (record?.data) return record.data; return null; }, diff --git a/application/api/auth/restore.js b/application/api/auth/restore.js index cf1fe759..9a159827 100644 --- a/application/api/auth/restore.js +++ b/application/api/auth/restore.js @@ -4,6 +4,7 @@ const restored = context.client.restoreSession(token); if (restored) return { status: 'logged' }; const data = await api.auth.provider.readSession(token); - return { status: data ? 'logged' : 'not logged' }; + const status = data ? 'logged' : 'not logged'; + return { status }; }, }); diff --git a/application/api/auth/signin.js b/application/api/auth/signin.js index 742ce384..93629afe 100644 --- a/application/api/auth/signin.js +++ b/application/api/auth/signin.js @@ -8,7 +8,7 @@ if (!valid) throw new Error('Incorrect login or password'); console.log(`Logged user: ${login}`); const token = api.auth.provider.generateToken(); - const data = { accountId: user.accountId }; + const data = { accountId }; context.client.startSession(token, data); const { ip } = context.client; await api.auth.provider.createSession(token, data, { ip, accountId }); diff --git a/application/api/console/content.js b/application/api/console/content.js index 74073a6f..87c1ec9b 100644 --- a/application/api/console/content.js +++ b/application/api/console/content.js @@ -2,7 +2,6 @@ access: 'public', async method({ name }) { - // Try type: new api.console.content.CustomError('EPARSE'); const filePath = `/content/${name}.md`; const file = application.resources.get(filePath); if (!file) return new Error('Content is not found'); diff --git a/application/api/example/counter.js b/application/api/example/counter.js index 870b657c..bb50fe3f 100644 --- a/application/api/example/counter.js +++ b/application/api/example/counter.js @@ -1,5 +1,5 @@ async () => { - if (!context.session.counter) context.session.counter = 1; - else context.session.counter++; - return { result: context.session.counter }; + const { session = { counter: 0 } } = context; + session.counter++; + return { result: session.counter }; }; diff --git a/application/api/example/getClientInfo.js b/application/api/example/getClientInfo.js index 2c538d59..d1833f6f 100644 --- a/application/api/example/getClientInfo.js +++ b/application/api/example/getClientInfo.js @@ -4,6 +4,7 @@ const { uuid, session, client } = context; const { ip } = client; const { token, accountId } = session; - return { result: { ip, token, accountId, uuid } }; + const result = { ip, token, accountId, uuid }; + return { result }; }, }); diff --git a/application/api/example/remoteMethod.js b/application/api/example/remoteMethod.js index 39dc3345..68c575e5 100644 --- a/application/api/example/remoteMethod.js +++ b/application/api/example/remoteMethod.js @@ -1,6 +1,6 @@ ({ access: 'public', - method: async ({ ...args }) => { + method: async (args) => { console.debug({ remoteMethod: args }); return { result: 'success' }; }, diff --git a/application/api/example/subscribe.js b/application/api/example/subscribe.js index 69ec65b6..8bafa6a3 100644 --- a/application/api/example/subscribe.js +++ b/application/api/example/subscribe.js @@ -2,10 +2,11 @@ access: 'public', method: async () => { + const { interval } = config.resmon; setInterval(async () => { const stats = await lib.resmon.getStatistics(); context.client.emit('example/resmon', stats); - }, config.resmon.interval); + }, interval); return { subscribed: 'resmon' }; }, }); diff --git a/application/api/example/uploadFile.js b/application/api/example/uploadFile.js index e2eb89b5..afc7d987 100644 --- a/application/api/example/uploadFile.js +++ b/application/api/example/uploadFile.js @@ -2,7 +2,8 @@ async ({ name, data }) => { const buffer = Buffer.from(data, 'base64'); const tmpPath = 'application/tmp'; const filePath = node.path.join(tmpPath, name); - if (filePath.startsWith(tmpPath)) { + const isInsideTmp = filePath.startsWith(tmpPath); + if (isInsideTmp) { await node.fsp.writeFile(filePath, buffer); } return { uploaded: data.length }; diff --git a/application/api/example/wait.js b/application/api/example/wait.js index ee2c122a..ada8b5c2 100644 --- a/application/api/example/wait.js +++ b/application/api/example/wait.js @@ -1,4 +1,6 @@ -async ({ delay }) => - new Promise((resolve) => { - setTimeout(resolve, delay, 'done'); +async ({ delay }) => { + await new Promise((resolve) => { + setTimeout(resolve, delay); }); + return 'done'; +}; diff --git a/application/api/files/download.js b/application/api/files/download.js index 6b87665b..b149b2fb 100644 --- a/application/api/files/download.js +++ b/application/api/files/download.js @@ -1,12 +1,8 @@ async ({ name, type }) => { const filePath = `./application/resources/${name}`; - // Create nodejs readable stream to read a file const readable = node.fs.createReadStream(filePath); - // Get file size const { size } = await node.fsp.stat(filePath); - // Create metacom writable stream const writable = context.client.createStream(name, size); - // Pipe nodejs readable to metacom writable readable.pipe(writable); return { streamId: writable.id, type }; }; diff --git a/application/api/files/upload.js b/application/api/files/upload.js index 888a272c..81417f73 100644 --- a/application/api/files/upload.js +++ b/application/api/files/upload.js @@ -1,10 +1,7 @@ async ({ streamId, name }) => { const filePath = `./application/resources/${name}`; - // Get incoming stream by streamId sent from client const readable = context.client.getStream(streamId); - // Create nodejs stream to write file on server const writable = node.fs.createWriteStream(filePath); - // Pipe metacom readable to nodejs writable readable.pipe(writable); return { result: 'Stream initialized' }; }; diff --git a/application/bus/worldTime/currentTime.js b/application/bus/worldTime/currentTime.js index f62766bb..abe5a945 100644 --- a/application/bus/worldTime/currentTime.js +++ b/application/bus/worldTime/currentTime.js @@ -11,19 +11,19 @@ returns: { abbreviation: 'string', - [`client_ip`]: 'string', + client_ip: 'string', datetime: 'string', - [`day_of_week`]: 'number', - [`day_of_year`]: 'number', + day_of_week: 'number', + day_of_year: 'number', dst: 'boolean', - [`dst_from`]: 'string', - [`dst_offset`]: 'number', - [`dst_until`]: 'string', - [`raw_offset`]: 'number', + dst_from: 'string', + dst_offset: 'number', + dst_until: 'string', + raw_offset: 'number', timezone: 'string', unixtime: 'number', - [`utc_datetime`]: 'string', - [`utc_offset`]: 'string', - [`week_number`]: 'number', + utc_datetime: 'string', + utc_offset: 'string', + week_number: 'number', }, }); diff --git a/application/db/pg/start.js b/application/db/pg/start.js index 43b60982..37629f22 100644 --- a/application/db/pg/start.js +++ b/application/db/pg/start.js @@ -1,7 +1,6 @@ async () => { - if (application.worker.id === 'W1') { - console.debug('Connect to pg'); - } + const isPrimary = application.worker.id === 'W1'; + if (isPrimary) console.debug('Connect to pg'); const options = { ...config.database, console }; db.pg = new metarhia.metasql.Database(options); }; diff --git a/application/db/redis/start.js b/application/db/redis/start.js index d86a0391..ad9634e0 100644 --- a/application/db/redis/start.js +++ b/application/db/redis/start.js @@ -1,16 +1,16 @@ async () => { - if (application.worker.id === 'W1') { + const isPrimary = application.worker.id === 'W1'; + if (isPrimary) { console.debug('Connect to redis'); } const client = npm.redis.createClient(config.redis); db.redis.client = client; client.on('error', async (error) => { - if (application.worker.id === 'W1') { - console.warn('No redis service detected, so quit client'); - const err = new Error('No redis', { cause: error }); - console.error(err); - await client.disconnect(); - } + if (!isPrimary) return; + console.warn('No redis service detected, so quit client'); + const err = new Error('No redis', { cause: error }); + console.error(err); + await client.disconnect(); }); await client.connect(); }; diff --git a/application/domain/chat.js b/application/domain/chat.js index 94aa7dc6..fc89d88d 100644 --- a/application/domain/chat.js +++ b/application/domain/chat.js @@ -2,9 +2,9 @@ rooms: new Map(), getRoom(name) { - let room = domain.chat.rooms.get(name); - if (room) return room; - room = new Set(); + const existing = domain.chat.rooms.get(name); + if (existing) return existing; + const room = new Set(); domain.chat.rooms.set(name, room); return room; }, diff --git a/application/domain/tests/api.js b/application/domain/tests/api.js index b82015ce..d891eca1 100644 --- a/application/domain/tests/api.js +++ b/application/domain/tests/api.js @@ -1,16 +1,14 @@ ({ async cases(t, metacom) { if (t) return; - const res = await metacom.api.auth.signin({ - login: 'marcus', - password: 'marcus', - }); + const credentials = { login: 'marcus', password: 'marcus' }; + const res = await metacom.api.auth.signin(credentials); node.assert.strictEqual(res.status, 'logged'); node.assert.strictEqual(typeof res.token, 'string'); await t.test(`Call example.add({ a, b })`, async () => { - const res = await metacom.api.example.add({ a: 10, b: 20 }); - node.assert.strictEqual(res, 30); + const sum = await metacom.api.example.add({ a: 10, b: 20 }); + node.assert.strictEqual(sum, 30); }); }, }); diff --git a/application/domain/tests/static.test.js b/application/domain/tests/static.test.js index a61d57e8..efb42630 100644 --- a/application/domain/tests/static.test.js +++ b/application/domain/tests/static.test.js @@ -18,7 +18,7 @@ const tasks = [ { url: '/', size: 2099 }, - { url: '/console.js', size: 14360 }, + { url: '/console.js', size: 13862 }, { url: '/unknown', status: 404, size: 113 }, { url: '/unknown.png', status: 404, size: 113 }, { url: '/unknown/unknown', status: 404 }, diff --git a/application/domain/time/start.js b/application/domain/time/start.js index 46278568..c1f2aee2 100644 --- a/application/domain/time/start.js +++ b/application/domain/time/start.js @@ -6,7 +6,8 @@ async () => { area: 'Europe', location: 'Rome', }); - console.log(`${time.timezone} - ${time.datetime}`); + const { timezone, datetime } = time; + console.log(`${timezone} - ${datetime}`); } catch { console.log('Can not access time server'); } diff --git a/application/lib/example/cache.js b/application/lib/example/cache.js index be403144..19498f56 100644 --- a/application/lib/example/cache.js +++ b/application/lib/example/cache.js @@ -7,8 +7,8 @@ }, get({ key }) { - const res = this.values.get(key); - console.debug({ get: key, return: res }); - return res; + const value = this.values.get(key); + console.debug({ get: key, return: value }); + return value; }, }); diff --git a/application/lib/example/storage/set.js b/application/lib/example/storage/set.js index 38f06c83..5ba085d5 100644 --- a/application/lib/example/storage/set.js +++ b/application/lib/example/storage/set.js @@ -3,11 +3,9 @@ method({ key, val }) { console.log({ key, val }); - if (val) { - return this.values.set(key, val); - } - const res = this.values.get(key); - console.log({ return: { res } }); - return res; + if (val) return this.values.set(key, val); + const value = this.values.get(key); + console.log({ return: { res: value } }); + return value; }, }); diff --git a/application/lib/resmon/getStatistics.js b/application/lib/resmon/getStatistics.js index 693a7339..d0f7f8d9 100644 --- a/application/lib/resmon/getStatistics.js +++ b/application/lib/resmon/getStatistics.js @@ -1,7 +1,7 @@ async () => { const { heapTotal, heapUsed, external } = process.memoryUsage(); - const hs = node.v8.getHeapStatistics(); - const contexts = hs.number_of_native_contexts; - const detached = hs.number_of_detached_contexts; + const heapStats = node.v8.getHeapStatistics(); + const contexts = heapStats.number_of_native_contexts; + const detached = heapStats.number_of_detached_contexts; return { heapTotal, heapUsed, external, contexts, detached }; }; diff --git a/application/lib/task1/start.js b/application/lib/task1/start.js index 74849857..cdbccb29 100644 --- a/application/lib/task1/start.js +++ b/application/lib/task1/start.js @@ -1,11 +1,12 @@ async () => { if (!config.examples.scheduler) return; if (application.worker.id !== 'W1') return; - const res = await application.scheduler.add({ + const task = { name: 'name', every: 'Oct 19th 10s', args: { i: 2 }, run: 'lib.task1.f1', - }); + }; + const res = await application.scheduler.add(task); console.log('Add task', res); }; diff --git a/application/lib/utils.js b/application/lib/utils.js index 41a47190..5e15698a 100644 --- a/application/lib/utils.js +++ b/application/lib/utils.js @@ -3,11 +3,12 @@ bytesToSize(bytes) { if (bytes === 0) return '0'; - const exp = Math.floor(Math.log(bytes) / Math.log(1000)); - const size = bytes / 1000 ** exp; - const short = Math.round(size, 2); + const base = 1000; + const exp = Math.floor(Math.log(bytes) / Math.log(base)); + const size = bytes / base ** exp; + const short = Math.round(size); const unit = this.UNITS[exp]; - return short + unit; + return `${short}${unit}`; }, UNIT_SIZES: { diff --git a/application/static/console.js b/application/static/console.js index 183de78e..a7ccbc16 100644 --- a/application/static/console.js +++ b/application/static/console.js @@ -47,35 +47,29 @@ const KEYBOARD_LAYOUT = [ ]; const KEY_NAME = {}; -for (const keyName in KEY_CODE) KEY_NAME[KEY_CODE[keyName]] = keyName; +for (const [keyName, code] of Object.entries(KEY_CODE)) { + KEY_NAME[code] = keyName; +} -const pad = (padChar, length) => new Array(length + 1).join(padChar); +const pad = (padChar, length) => padChar.repeat(length); const { userAgent } = navigator; -const isMobile = () => - userAgent.match(/Android/i) || - userAgent.match(/webOS/i) || - userAgent.match(/iPhone/i) || - userAgent.match(/iPad/i) || - userAgent.match(/iPod/i) || - userAgent.match(/BlackBerry/i) || - userAgent.match(/Windows Phone/i); +const MOBILE_UA = /Android|webOS|iPhone|iPad|iPod|BlackBerry|Windows Phone/i; + +const isMobile = () => MOBILE_UA.test(userAgent); const sleep = (msec) => new Promise((resolve) => { - setTimeout(() => { - resolve(); - }, msec); + setTimeout(resolve, msec); }); const urlKind = (url) => { if (url.startsWith('mailto:')) return 'mail'; - if (url.startsWith('http:')) return 'web'; - if (url.startsWith('https:')) return 'web'; - const k = url.indexOf('/'); - if (k === -1) return 'base'; - return url.substring(0, k); + if (url.startsWith('http:') || url.startsWith('https:')) return 'web'; + const slashIndex = url.indexOf('/'); + if (slashIndex === -1) return 'base'; + return url.substring(0, slashIndex); }; const followLink = async (event) => { @@ -93,7 +87,8 @@ const followLink = async (event) => { const followLastMore = () => { const mores = document.querySelectorAll('#panelConsole a.more'); if (mores.length === 0) return; - const text = mores[mores.length - 1].getAttribute('data-text'); + const lastMore = mores.at(-1); + const text = lastMore.getAttribute('data-text'); for (const more of mores) more.parentElement.remove(); application.print(text); }; @@ -118,56 +113,51 @@ const inputKeyboardEvents = { followLastMore(); }, BACKSPACE() { - application.inputSetValue(application.controlInput.inputValue.slice(0, -1)); + const value = application.controlInput.inputValue; + application.inputSetValue(value.slice(0, -1)); }, ENTER() { - let value = application.controlInput.inputValue; - if (application.controlInput.inputType === 'masked') { + const input = application.controlInput; + let value = input.inputValue; + if (input.inputType === 'masked') { value = pad('*', value.length); } - application.print(application.controlInput.inputPrompt + value); - application.controlInput.style.display = 'none'; - application.controlInput.inputActive = false; - application.controlInput.inputCallback(null, value); + application.print(input.inputPrompt + value); + input.style.display = 'none'; + input.inputActive = false; + input.inputCallback(null, value); }, CAPS() { - if (application.keyboard.controlKeyboard.className === 'caps') { - application.keyboard.controlKeyboard.className = ''; - } else { - application.keyboard.controlKeyboard.className = 'caps'; - } + const keyboard = application.keyboard.controlKeyboard; + const isCaps = keyboard.className === 'caps'; + keyboard.className = isCaps ? '' : 'caps'; }, KEY(char) { - // Alpha or Digit - if (application.keyboard.controlKeyboard.className === 'caps') { + const keyboard = application.keyboard.controlKeyboard; + if (keyboard.className === 'caps') { char = char.toUpperCase(); } - application.inputSetValue(application.controlInput.inputValue + char); + const value = application.controlInput.inputValue + char; + application.inputSetValue(value); }, }; document.onkeydown = (event) => { - if (application.controlInput.inputActive) { - const keyName = KEY_NAME[event.keyCode]; - const fn = inputKeyboardEvents[keyName]; - if (fn) { - fn(); - return false; - } - } - return true; + if (!application.controlInput.inputActive) return true; + const keyName = KEY_NAME[event.keyCode]; + const fn = inputKeyboardEvents[keyName]; + if (!fn) return true; + fn(); + return false; }; document.onkeypress = (event) => { - if (application.controlInput.inputActive) { - const fn = inputKeyboardEvents['KEY']; - const char = String.fromCharCode(event.keyCode); - if (CHARS.includes(char) && fn) { - fn(char); - return false; - } - } - return true; + if (!application.controlInput.inputActive) return true; + const fn = inputKeyboardEvents.KEY; + const char = String.fromCharCode(event.keyCode); + if (!CHARS.includes(char) || !fn) return true; + fn(char); + return false; }; const keyboardClick = (e) => { @@ -184,58 +174,52 @@ const keyboardClick = (e) => { }; const uploadFile = async (file) => { - // createBlobUploader creates streamId and inits file reader for convenience const uploader = application.metacom.createBlobUploader(file); - // Prepare backend file consumer await api.files.upload({ streamId: uploader.id, name: file.name, }); - // Start uploading stream and wait for its end await uploader.upload(); return { uploadedFile: file }; }; const downloadFile = async (name, type) => { - // Init backend file producer to get streamId const { streamId } = await api.files.download({ name }); - // Get metacom readable stream const readable = await application.metacom.getStream(streamId); - // Convert stream to blob to make a file on the client const blob = await readable.toBlob(type); return new File([blob], name); }; const saveFile = (fileName, blob) => { - const a = document.createElement('a'); - a.style.display = 'none'; - document.body.appendChild(a); + const link = document.createElement('a'); + link.style.display = 'none'; + document.body.appendChild(link); const url = window.URL.createObjectURL(blob); - a.href = url; - a.download = fileName; - a.click(); + link.href = url; + link.download = fileName; + link.click(); URL.revokeObjectURL(url); }; const upload = () => { - const element = document.createElement('form'); - element.style.visibility = 'hidden'; - element.innerHTML = ''; - document.body.appendChild(element); + const form = document.createElement('form'); + form.style.visibility = 'hidden'; + form.innerHTML = ''; + document.body.appendChild(form); const fileSelect = document.getElementById('fileSelect'); fileSelect.click(); fileSelect.onchange = () => { const files = Array.from(fileSelect.files); - application.print('Uploading ' + files.length + ' file(s)'); + application.print(`Uploading ${files.length} file(s)`); files.sort((a, b) => a.size - b.size); - let i = 0; + let index = 0; const uploadNext = async () => { - const file = files[i]; + const file = files[index]; await uploadFile(file); application.print(`name: ${file.name}, size: ${file.size} done`); - i++; - if (i < files.length) return uploadNext(); - document.body.removeChild(element); + index++; + if (index < files.length) return uploadNext(); + document.body.removeChild(form); commandLoop(); return null; }; @@ -268,8 +252,8 @@ class Keyboard { show() { this.controlKeyboard.style.display = 'block'; - const down = this.controlKeyboard.offsetHeight + 'px'; - application.controlBrowse.style.bottom = down; + const bottom = `${this.controlKeyboard.offsetHeight}px`; + application.controlBrowse.style.bottom = bottom; } hide() { @@ -301,15 +285,16 @@ class Scroller { } refreshScroll() { - this.viewportHeight = application.controlBrowse.offsetHeight; - this.contentHeight = application.controlBrowse.scrollHeight; + const browse = application.controlBrowse; + this.viewportHeight = browse.offsetHeight; + this.contentHeight = browse.scrollHeight; this.viewableRatio = this.viewportHeight / this.contentHeight; this.scrollHeight = this.panelScroll.offsetHeight; this.thumbHeight = this.scrollHeight * this.viewableRatio; - const top = application.controlBrowse.scrollTop; + const top = browse.scrollTop; this.thumbPosition = (top * this.thumbHeight) / this.viewportHeight; - this.controlScroll.style.top = this.thumbPosition + 'px'; - this.controlScroll.style.height = this.thumbHeight + 'px'; + this.controlScroll.style.top = `${this.thumbPosition}px`; + this.controlScroll.style.height = `${this.thumbHeight}px`; } scrollBottom() { @@ -354,8 +339,9 @@ class Application { value = pad('*', value.length); } value = value.replace(/ /g, ' '); - const html = this.controlInput.inputPrompt + value + ''; - this.controlInput.innerHTML = html; + const prompt = this.controlInput.inputPrompt; + const cursor = ''; + this.controlInput.innerHTML = prompt + value + cursor; } input(type, prompt, callback) { @@ -385,6 +371,12 @@ class Application { this.scroller.scrollBottom(); } + scrollToEnd() { + const top = this.controlBrowse.scrollHeight; + this.controlBrowse.scrollTop = top; + this.scroller.scrollBottom(); + } + async print(text = '') { removeMores(); const element = document.createElement('div'); @@ -433,15 +425,11 @@ class Application { } else { word += char; } - const top = this.controlBrowse.scrollHeight; - this.controlBrowse.scrollTop = top; - this.scroller.scrollBottom(); + this.scrollToEnd(); } if (i >= text.length) { element.innerHTML += '
'; - const top = this.controlBrowse.scrollHeight; - this.controlBrowse.scrollTop = top; - this.scroller.scrollBottom(); + this.scrollToEnd(); } const links = element.querySelectorAll('a'); for (const link of links) { @@ -450,15 +438,15 @@ class Application { } async exec(line) { - const args = line.split(' '); - if (args[0] === 'upload') { + const [command] = line.split(' '); + if (command === 'upload') { upload(); - } else if (args[0] === 'download') { + } else if (command === 'download') { const fileName = 'content/home.md'; const file = await downloadFile(fileName, 'txt/plain'); console.log({ file }); saveFile('home.md', file); - } else if (args[0] === 'counter') { + } else if (command === 'counter') { const packet = await api.example.counter(); this.print(`counter: ${packet.result}`); } @@ -475,7 +463,8 @@ window.addEventListener('load', async () => { application.logged = res.status === 'logged'; } if (!application.logged) { - const res = await api.auth.signin({ login: 'marcus', password: 'marcus' }); + const credentials = { login: 'marcus', password: 'marcus' }; + const res = await api.auth.signin(credentials); if (res.token) { localStorage.setItem('metarhia.session.token', res.token); } diff --git a/application/static/metacom.js b/application/static/metacom.js index b82c2968..316ad73c 100644 --- a/application/static/metacom.js +++ b/application/static/metacom.js @@ -169,8 +169,8 @@ class Metacom extends EventEmitter { return (method) => async (args = {}) => { const id = ++this.callId; - const unitName = unit + (ver ? '.' + ver : ''); - const target = unitName + '/' + method; + const unitName = unit + (ver ? `.${ver}` : ''); + const target = `${unitName}/${method}`; if (this.opening) await this.opening; if (!this.connected) await this.open(); return new Promise((resolve, reject) => { diff --git a/application/static/worker.js b/application/static/worker.js index ca62b75b..7b1ca398 100644 --- a/application/static/worker.js +++ b/application/static/worker.js @@ -11,7 +11,11 @@ const files = [ ]; self.addEventListener('install', (event) => { - event.waitUntil(caches.open('metarhia').then((cache) => cache.addAll(files))); + const populateCache = async () => { + const cache = await caches.open('metarhia'); + await cache.addAll(files); + }; + event.waitUntil(populateCache()); }); self.addEventListener('fetch', async ({ request }) => { diff --git a/eslint.config.js b/eslint.config.js index d67d3395..87629473 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -34,4 +34,10 @@ module.exports = [ }, }, }, + { + files: ['application/bus/worldTime/currentTime.js'], + rules: { + camelcase: ['error', { properties: 'never' }], + }, + }, ]; diff --git a/package-lock.json b/package-lock.json index 04c534d2..be5ecc3c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,16 +11,16 @@ "dependencies": { "impress": "^3.1.2", "metasql": "^3.0.0-alpha.4", - "pg": "^8.20.0", - "redis": "^5.11.0" + "pg": "^8.22.0", + "redis": "^5.12.1" }, "devDependencies": { - "@types/node": "^24.12.0", - "@types/pg": "^8.20.0", + "@types/node": "^24.13.3", + "@types/pg": "^8.20.4", "@types/ws": "^8.18.1", - "eslint": "^9.39.4", - "eslint-config-metarhia": "^9.1.8", - "prettier": "^3.8.1", + "eslint": "^9.39.5", + "eslint-config-metarhia": "^9.1.9", + "prettier": "^3.9.6", "typescript": "^5.9.3" }, "engines": { @@ -111,9 +111,9 @@ } }, "node_modules/@eslint/eslintrc": { - "version": "3.3.5", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.5.tgz", - "integrity": "sha512-4IlJx0X0qftVsN5E+/vGujTRIFtwuLbNsVUe7TO6zYPDR1O6nFwvwhIKEKSrl6dZchmYBITazxKoUYOjdtjlRg==", + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.6.tgz", + "integrity": "sha512-l2Ul9PrHsPCKcEY/ac7VgFj9D80C7S68sOKc618SyHDPK36s1XcFebXY0iTzUVn4Yq+YbwvSnDmCz9yxjX+QrA==", "dev": true, "license": "MIT", "dependencies": { @@ -123,7 +123,7 @@ "globals": "^14.0.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", - "js-yaml": "^4.1.1", + "js-yaml": "^4.3.0", "minimatch": "^3.1.5", "strip-json-comments": "^3.1.1" }, @@ -135,9 +135,9 @@ } }, "node_modules/@eslint/js": { - "version": "9.39.4", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.4.tgz", - "integrity": "sha512-nE7DEIchvtiFTwBw4Lfbu59PG+kCofhjsKaCWzxTpt4lfRjRMqG6uMBzKXuEcyXhOHoUp9riAm7/aWYGhXZ9cw==", + "version": "9.39.5", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.5.tgz", + "integrity": "sha512-QywQuszQh77pIXCsq998c8hbhSTI/azTty1Z6N53dmAudKHhy573j3yvRLsX2BSp8YpLtoCEG8E9DJe+8zUh4A==", "dev": true, "license": "MIT", "engines": { @@ -237,71 +237,75 @@ } }, "node_modules/@redis/bloom": { - "version": "5.11.0", - "resolved": "https://registry.npmjs.org/@redis/bloom/-/bloom-5.11.0.tgz", - "integrity": "sha512-KYiVilAhAFN3057afUb/tfYJpsEyTkQB+tQcn5gVVA7DgcNOAj8lLxe4j8ov8BF6I9C1Fe/kwlbuAICcTMX8Lw==", + "version": "5.12.1", + "resolved": "https://registry.npmjs.org/@redis/bloom/-/bloom-5.12.1.tgz", + "integrity": "sha512-PUUfv+ms7jgPSBVoo/DN4AkPHj4D5TZSd6SbJX7egzBplkYUcKmHRE8RKia7UtZ8bSQbLguLvxVO+asKtQfZWA==", "license": "MIT", "engines": { - "node": ">= 18" + "node": ">= 18.19.0" }, "peerDependencies": { - "@redis/client": "^5.11.0" + "@redis/client": "^5.12.1" } }, "node_modules/@redis/client": { - "version": "5.11.0", - "resolved": "https://registry.npmjs.org/@redis/client/-/client-5.11.0.tgz", - "integrity": "sha512-GHoprlNQD51Xq2Ztd94HHV94MdFZQ3CVrpA04Fz8MVoHM0B7SlbmPEVIjwTbcv58z8QyjnrOuikS0rWF03k5dQ==", + "version": "5.12.1", + "resolved": "https://registry.npmjs.org/@redis/client/-/client-5.12.1.tgz", + "integrity": "sha512-7aPGWeqA3uFm43o19umzdl16CEjK/JQGtSXVPevplTaOU3VJA/rseBC1QvYUz9lLDIMBimc4SW/zrW4S89BaCA==", "license": "MIT", "dependencies": { "cluster-key-slot": "1.1.2" }, "engines": { - "node": ">= 18" + "node": ">= 18.19.0" }, "peerDependencies": { - "@node-rs/xxhash": "^1.1.0" + "@node-rs/xxhash": "^1.1.0", + "@opentelemetry/api": ">=1 <2" }, "peerDependenciesMeta": { "@node-rs/xxhash": { "optional": true + }, + "@opentelemetry/api": { + "optional": true } } }, "node_modules/@redis/json": { - "version": "5.11.0", - "resolved": "https://registry.npmjs.org/@redis/json/-/json-5.11.0.tgz", - "integrity": "sha512-1iAy9kAtcD0quB21RbPTbUqqy+T2Uu2JxucwE+B4A+VaDbIRvpZR6DMqV8Iqaws2YxJYB3GC5JVNzPYio2ErUg==", + "version": "5.12.1", + "resolved": "https://registry.npmjs.org/@redis/json/-/json-5.12.1.tgz", + "integrity": "sha512-eOze75esLve4vfqDel7aMX08CNaiLLQS2fV8mpRN9NxPe1rVR4vQyYiW/OgtGUysF6QOr9ANhfxABKNOJfXdKg==", "license": "MIT", "engines": { - "node": ">= 18" + "node": ">= 18.19.0" }, "peerDependencies": { - "@redis/client": "^5.11.0" + "@redis/client": "^5.12.1" } }, "node_modules/@redis/search": { - "version": "5.11.0", - "resolved": "https://registry.npmjs.org/@redis/search/-/search-5.11.0.tgz", - "integrity": "sha512-g1l7f3Rnyk/xI99oGHIgWHSKFl45Re5YTIcO8j/JE8olz389yUFyz2+A6nqVy/Zi031VgPDWscbbgOk8hlhZ3g==", + "version": "5.12.1", + "resolved": "https://registry.npmjs.org/@redis/search/-/search-5.12.1.tgz", + "integrity": "sha512-ItlxbxC9cKI6IU1TLWoczwJCRb6TdmkEpWv05UrPawqaAnWGRu3rcIqsc5vN483T2fSociuyV1UkWIL5I4//2w==", "license": "MIT", "engines": { - "node": ">= 18" + "node": ">= 18.19.0" }, "peerDependencies": { - "@redis/client": "^5.11.0" + "@redis/client": "^5.12.1" } }, "node_modules/@redis/time-series": { - "version": "5.11.0", - "resolved": "https://registry.npmjs.org/@redis/time-series/-/time-series-5.11.0.tgz", - "integrity": "sha512-TWFeOcU4xkj0DkndnOyhtxvX1KWD+78UHT3XX3x3XRBUGWeQrKo3jqzDsZwxbggUgf9yLJr/akFHXru66X5UQA==", + "version": "5.12.1", + "resolved": "https://registry.npmjs.org/@redis/time-series/-/time-series-5.12.1.tgz", + "integrity": "sha512-c6JL6E3EcZJuNqKFz+KM+l9l5mpcQiKvTwgA3blt5glWJ8hjDk0yeHN3beE/MpqYIQ8UEX44ItQzgkE/gCBELQ==", "license": "MIT", "engines": { - "node": ">= 18" + "node": ">= 18.19.0" }, "peerDependencies": { - "@redis/client": "^5.11.0" + "@redis/client": "^5.12.1" } }, "node_modules/@types/estree": { @@ -319,19 +323,19 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "24.12.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-24.12.0.tgz", - "integrity": "sha512-GYDxsZi3ChgmckRT9HPU0WEhKLP08ev/Yfcq2AstjrDASOYCSXeyjDsHg4v5t4jOj7cyDX3vmprafKlWIG9MXQ==", + "version": "24.13.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.13.3.tgz", + "integrity": "sha512-Dh8vAsV36ig5wa9OX4pXvMc9D3Veibfw2wix0CUwYODLD8nkj9UsLjASr49nPg+2eKzxhBV+v7L8pXvT4e639Q==", "dev": true, "license": "MIT", "dependencies": { - "undici-types": "~7.16.0" + "undici-types": "~7.18.0" } }, "node_modules/@types/pg": { - "version": "8.20.0", - "resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.20.0.tgz", - "integrity": "sha512-bEPFOaMAHTEP1EzpvHTbmwR8UsFyHSKsRisLIHVMXnpNefSbGA1bD6CVy+qKjGSqmZqNqBDV2azOBo8TgkcVow==", + "version": "8.20.4", + "resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.20.4.tgz", + "integrity": "sha512-Jz7UDOlIiFJuacC0TlBoLyNtmwlA/wpIyPDd3tvUqlRM+HzkWy2xUgpFpaXtbfTAFF6sIGq5lsCDBdJnhky1Xg==", "dev": true, "license": "MIT", "dependencies": { @@ -351,9 +355,9 @@ } }, "node_modules/acorn": { - "version": "8.16.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", - "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.18.0.tgz", + "integrity": "sha512-lGq+9yr1/GuAWaVYIHRjvvySG5/4VfKIvC8EWxStPdcDh/Ka7FG3twP6v4d5BkravUilhIAsG4Qj83t02LWUPQ==", "dev": true, "license": "MIT", "bin": { @@ -374,9 +378,9 @@ } }, "node_modules/ajv": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz", - "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==", + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", + "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", "dev": true, "license": "MIT", "dependencies": { @@ -421,9 +425,9 @@ "license": "MIT" }, "node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "version": "1.1.18", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.18.tgz", + "integrity": "sha512-Edep/X9fGqVNmzKBVsDYIOtD+z1tuezV70LBjdCst9Tqu76lsnvRiZ6oTic1n+/BIwX6QDGAO94PN4N2SADvtw==", "dev": true, "license": "MIT", "dependencies": { @@ -561,9 +565,9 @@ } }, "node_modules/eslint": { - "version": "9.39.4", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.4.tgz", - "integrity": "sha512-XoMjdBOwe/esVgEvLmNsD3IRHkm7fbKIUGvrleloJXUZgDHig2IPWNniv+GwjyJXzuNqVjlr5+4yVUZjycJwfQ==", + "version": "9.39.5", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.5.tgz", + "integrity": "sha512-DgZS62aPLXKlnxILS/AYCoRvHaZeXceIzlXPkkGGzJWSow1aEk0lbTlxUSlyjC8jcaKxAdOnTDz+o1JFSBsyjw==", "dev": true, "license": "MIT", "dependencies": { @@ -572,8 +576,8 @@ "@eslint/config-array": "^0.21.2", "@eslint/config-helpers": "^0.4.2", "@eslint/core": "^0.17.0", - "@eslint/eslintrc": "^3.3.5", - "@eslint/js": "9.39.4", + "@eslint/eslintrc": "^3.3.6", + "@eslint/js": "9.39.5", "@eslint/plugin-kit": "^0.4.1", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", @@ -621,25 +625,42 @@ } }, "node_modules/eslint-config-metarhia": { - "version": "9.1.8", - "resolved": "https://registry.npmjs.org/eslint-config-metarhia/-/eslint-config-metarhia-9.1.8.tgz", - "integrity": "sha512-AV8JtJyfPWFggGffzeFBR0P+6yEBdNvthAyAMwagj65M6pbNh2Pc/FpX9Obw1G7xcuD1ShZYOvSf3BbI/YRefg==", + "version": "9.1.9", + "resolved": "https://registry.npmjs.org/eslint-config-metarhia/-/eslint-config-metarhia-9.1.9.tgz", + "integrity": "sha512-M/KVtu9cVeyyLpIseTzmAz3/qraugFaVw6SSnwmvrpKwTgtWz6UowZfK3wSpj1+x0DMIyese65YGfLxETt44Wg==", "dev": true, "license": "MIT", "dependencies": { - "eslint": "^9.39.3", + "@eslint/js": "^9.39.4", + "eslint": "^9.39.4", "eslint-config-prettier": "^10.1.8", "eslint-plugin-prettier": "^5.5.5", - "prettier": "^3.8.1" + "prettier": "3.8.2" }, "engines": { - "node": ">= 18" + "node": ">= 20.19" }, "funding": { "type": "patreon", "url": "https://www.patreon.com/tshemsedinov" } }, + "node_modules/eslint-config-metarhia/node_modules/prettier": { + "version": "3.8.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.8.2.tgz", + "integrity": "sha512-8c3mgTe0ASwWAJK+78dpviD+A8EqhndQPUBpNUIPt6+xWlIigCwfN01lWr9MAede4uqXGTEKeQWTvzb3vjia0Q==", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, "node_modules/eslint-config-prettier": { "version": "10.1.8", "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-10.1.8.tgz", @@ -854,9 +875,9 @@ } }, "node_modules/flatted": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", - "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", + "version": "3.4.4", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.4.tgz", + "integrity": "sha512-5+ybhBZANEJxaH3X5evAFatUxLfEHSr7n6kYJ+1Qd0mUqr4eu9gIf6GDbWHf8RJijHrjjO8G+la14SlL2SeS1Q==", "dev": true, "license": "ISC" }, @@ -986,10 +1007,20 @@ "license": "ISC" }, "node_modules/js-yaml": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", - "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", - "dev": true, + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.1.tgz", + "integrity": "sha512-CY6crGq313MX8GkwvB7tzgp99vjQxY1++5y10/BKN/GUfHqWaOGQMNZkBvqSzsZKWk/ijwHlWzzkLulsGHhjWQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/puzrin" + }, + { + "type": "github", + "url": "https://github.com/sponsors/nodeca" + } + ], "license": "MIT", "dependencies": { "argparse": "^2.0.1" @@ -1317,14 +1348,14 @@ } }, "node_modules/pg": { - "version": "8.20.0", - "resolved": "https://registry.npmjs.org/pg/-/pg-8.20.0.tgz", - "integrity": "sha512-ldhMxz2r8fl/6QkXnBD3CR9/xg694oT6DZQ2s6c/RI28OjtSOpxnPrUCGOBJ46RCUxcWdx3p6kw/xnDHjKvaRA==", + "version": "8.22.0", + "resolved": "https://registry.npmjs.org/pg/-/pg-8.22.0.tgz", + "integrity": "sha512-8wih1vVIBMxoUM2oB4soJsD9tDnDpLv4OXBJ+EJzFsvycD+lfyIreC2gGHq78f8jbLLt+bvlPTFdFZfJkOuzAA==", "license": "MIT", "dependencies": { - "pg-connection-string": "^2.12.0", - "pg-pool": "^3.13.0", - "pg-protocol": "^1.13.0", + "pg-connection-string": "^2.14.0", + "pg-pool": "^3.14.0", + "pg-protocol": "^1.15.0", "pg-types": "2.2.0", "pgpass": "1.0.5" }, @@ -1332,7 +1363,7 @@ "node": ">= 16.0.0" }, "optionalDependencies": { - "pg-cloudflare": "^1.3.0" + "pg-cloudflare": "^1.4.0" }, "peerDependencies": { "pg-native": ">=3.0.1" @@ -1344,16 +1375,16 @@ } }, "node_modules/pg-cloudflare": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.3.0.tgz", - "integrity": "sha512-6lswVVSztmHiRtD6I8hw4qP/nDm1EJbKMRhf3HCYaqud7frGysPv7FYJ5noZQdhQtN2xJnimfMtvQq21pdbzyQ==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.4.0.tgz", + "integrity": "sha512-Vo7z/6rrQYxpNRylp4Tlob2elzbh+N/MOQbxFVWCxS7oEx6jF53GTJFxK2WWpKuBRkmiin4Mt+xofFDjx09R0A==", "license": "MIT", "optional": true }, "node_modules/pg-connection-string": { - "version": "2.12.0", - "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.12.0.tgz", - "integrity": "sha512-U7qg+bpswf3Cs5xLzRqbXbQl85ng0mfSV/J0nnA31MCLgvEaAo7CIhmeyrmJpOr7o+zm0rXK+hNnT5l9RHkCkQ==", + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.14.0.tgz", + "integrity": "sha512-XwWDGcLRGCXAR8F/AM5bG7Q+A3Wm2s6QeEjlOKZLlH3UYcguiqCWKyWXVag5TLTIjR7oOJUY8kcADaZgWPyLeg==", "license": "MIT" }, "node_modules/pg-int8": { @@ -1366,18 +1397,18 @@ } }, "node_modules/pg-pool": { - "version": "3.13.0", - "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.13.0.tgz", - "integrity": "sha512-gB+R+Xud1gLFuRD/QgOIgGOBE2KCQPaPwkzBBGC9oG69pHTkhQeIuejVIk3/cnDyX39av2AxomQiyPT13WKHQA==", + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.14.0.tgz", + "integrity": "sha512-gKtPkFdQPU3DksooVLi9LsjZxrsBUZIpa+7aVx+LV5pNh0KzP4Zleud2po+ConrxbuXGBJ6Hfer6hdgpIBpBaw==", "license": "MIT", "peerDependencies": { "pg": ">=8.0" } }, "node_modules/pg-protocol": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.13.0.tgz", - "integrity": "sha512-zzdvXfS6v89r6v7OcFCHfHlyG/wvry1ALxZo4LqgUoy7W9xhBDMaqOuMiF3qEV45VqsN6rdlcehHrfDtlCPc8w==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.15.0.tgz", + "integrity": "sha512-cq9sECI5s0+uPUXjbz8ioyPJni6RzsRib0US67i5IoTZKw8fNeYlVE7u8F4dG7vEJJtc5wdD1K189lCCUwqWTQ==", "license": "MIT" }, "node_modules/pg-types": { @@ -1455,9 +1486,9 @@ } }, "node_modules/prettier": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.8.1.tgz", - "integrity": "sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg==", + "version": "3.9.6", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.9.6.tgz", + "integrity": "sha512-OpN0zzVdiaiAhxpuuj5efpIS4sY9j7bY6uR5mnj5yPzGkdkjNKSJeUThPb60Jw29QuAZgA4o+/iB49kFiaBX6g==", "dev": true, "license": "MIT", "bin": { @@ -1494,19 +1525,19 @@ } }, "node_modules/redis": { - "version": "5.11.0", - "resolved": "https://registry.npmjs.org/redis/-/redis-5.11.0.tgz", - "integrity": "sha512-YwXjATVDT+AuxcyfOwZn046aml9jMlQPvU1VXIlLDVAExe0u93aTfPYSeRgG4p9Q/Jlkj+LXJ1XEoFV+j2JKcQ==", + "version": "5.12.1", + "resolved": "https://registry.npmjs.org/redis/-/redis-5.12.1.tgz", + "integrity": "sha512-LDsoVvb/CpoV9EN3FXvgvSHNJWuCIzl9MiO3ppOevuGLpSGJhwfQjpEwfFJcQvNSddHADDdZaWx0HnmMxRXG7g==", "license": "MIT", "dependencies": { - "@redis/bloom": "5.11.0", - "@redis/client": "5.11.0", - "@redis/json": "5.11.0", - "@redis/search": "5.11.0", - "@redis/time-series": "5.11.0" + "@redis/bloom": "5.12.1", + "@redis/client": "5.12.1", + "@redis/json": "5.12.1", + "@redis/search": "5.12.1", + "@redis/time-series": "5.12.1" }, "engines": { - "node": ">= 18" + "node": ">= 18.19.0" } }, "node_modules/resolve-from": { @@ -1621,9 +1652,9 @@ } }, "node_modules/undici-types": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", - "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", + "version": "7.18.2", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.18.2.tgz", + "integrity": "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==", "dev": true, "license": "MIT" }, @@ -1664,9 +1695,9 @@ } }, "node_modules/ws": { - "version": "8.18.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz", - "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==", + "version": "8.21.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.2.tgz", + "integrity": "sha512-54dMVAo4WIe6SKy3vBgN+9bJZqqQ8IMRevAkOLQALhi49qkkQDQfWdAZ8KQlXiEabw88ARXXdUrlvtbKQX+aKw==", "license": "MIT", "engines": { "node": ">=10.0.0" diff --git a/package.json b/package.json index d6757081..3b680083 100644 --- a/package.json +++ b/package.json @@ -55,18 +55,18 @@ "node": ">=18" }, "devDependencies": { - "@types/node": "^24.12.0", - "@types/pg": "^8.20.0", + "@types/node": "^24.13.3", + "@types/pg": "^8.20.4", "@types/ws": "^8.18.1", - "eslint": "^9.39.4", - "eslint-config-metarhia": "^9.1.8", - "prettier": "^3.8.1", + "eslint": "^9.39.5", + "eslint-config-metarhia": "^9.1.9", + "prettier": "^3.9.6", "typescript": "^5.9.3" }, "dependencies": { "impress": "^3.1.2", "metasql": "^3.0.0-alpha.4", - "pg": "^8.20.0", - "redis": "^5.11.0" + "pg": "^8.22.0", + "redis": "^5.12.1" } }