diff --git a/biome.json b/biome.json index 3517fbd..179bda2 100644 --- a/biome.json +++ b/biome.json @@ -1,101 +1,85 @@ -{ - "$schema": "https://biomejs.dev/schemas/1.8.1/schema.json", - "linter": { - "enabled": true, - "rules": { - "all": true, - "security": { - "noGlobalEval": "off" - }, - "suspicious": { - "noExplicitAny": "off", - "noAssignInExpressions": "off", - "noUnsafeDeclarationMerging": "off", - "noEmptyInterface": "off", - "noConfusingVoidType": "off", - "noImplicitAnyLet": "off", - "noEmptyBlockStatements": "off", - "useAwait": "off", - "noConsoleLog": "off", - "noAsyncPromiseExecutor": "off", - "noThenProperty": "off" - }, - "style": { - "noNonNullAssertion": "off", - "noParameterAssign": "off", - "useExportType": "error", - "useImportType": "error", - "useNodejsImportProtocol": "error", - "useNamingConvention": "off", - "noParameterProperties": "off", - "useFilenamingConvention": "off", - "noNamespaceImport": "off", - "useSingleCaseStatement": "off", - "useBlockStatements": "off", - "useEnumInitializers": "off", - "noArguments": "off", - "useForOf": "off" - }, - "correctness": { - "noUnusedVariables": "off", - "noNodejsModules": "off" - }, - "nursery": { - "useImportRestrictions": "off" - }, - "complexity": { - "noUselessLoneBlockStatements": "warn", - "noBannedTypes": "off", - "noForEach": "off", - "noUselessConstructor": "off", - "noExcessiveCognitiveComplexity": "off", - "noStaticOnlyClass": "off" - }, - "a11y": { - "all": false - }, - "performance": { - "noDelete": "off", - "noBarrelFile": "off", - "noReExportAll": "off" - } - } - }, - "json": { - "formatter": { - "enabled": true, - "indentWidth": 2, - "lineWidth": 80 - } - }, - "formatter": { - "enabled": true, - "indentWidth": 2, - "indentStyle": "tab", - "lineWidth": 120, - "lineEnding": "crlf", - "formatWithErrors": true - }, - "javascript": { - "formatter": { - "quoteStyle": "single", - "arrowParentheses": "asNeeded", - "bracketSameLine": true, - "semicolons": "always" - } - }, - "files": { - "ignoreUnknown": true, - "ignore": [ - "node_modules/", - "build", - "lib", - "__test__", - "package.json", - "tsconfig.json" - ] - }, - "organizeImports": { - "enabled": false - } -} \ No newline at end of file +{ + "$schema": "https://biomejs.dev/schemas/1.9.0/schema.json", + "vcs": { + "enabled": true, + "clientKind": "git", + "useIgnoreFile": true, + "defaultBranch": "main" + }, + "files": { + "ignoreUnknown": true, + "ignore": ["node_modules/", "build", "lib", "__test__", "package.json", "tsconfig.json", ".vscode"] + }, + "formatter": { + "enabled": true, + "indentStyle": "tab", + "indentWidth": 2, + "lineWidth": 120, + "lineEnding": "crlf", + "formatWithErrors": true + }, + "organizeImports": { + "enabled": true + }, + "linter": { + "enabled": true, + "rules": { + "recommended": false, + "all": true, + "security": { + "noGlobalEval": "off" + }, + "suspicious": { + "noExplicitAny": "off", + "noAssignInExpressions": "off", + "useAwait": "off", + "noConfusingVoidType": "off", + "noAsyncPromiseExecutor": "off", + "noUnsafeDeclarationMerging": "off", + "noEmptyInterface": "off", + "noThenProperty": "off" + }, + "correctness": { + "noNodejsModules": "off", + "useImportExtensions": "off", + "noUnusedFunctionParameters": "off", + "noUnusedVariables": "off", + "noUndeclaredDependencies": "off" + }, + "style": { + "noDefaultExport": "off", + "useBlockStatements": "off", + "noParameterProperties": "off", + "useNamingConvention": "off", + "noNonNullAssertion": "off", + "useForOf": "off", + "useDefaultSwitchClause": "off", + "noParameterAssign": "off", + "useFilenamingConvention": "off", + "useEnumInitializers": "off", + "useExplicitLengthCheck": "off", + "noNamespaceImport": "off" + }, + "complexity": { + "noForEach": "off", + "noExcessiveCognitiveComplexity": "off", + "noUselessConstructor": "off", + "noBannedTypes": "off" + }, + "performance": { + "noBarrelFile": "off", + "noDelete": "off", + "noReExportAll": "off", + "useTopLevelRegex": "off" + } + } + }, + "javascript": { + "formatter": { + "quoteStyle": "single", + "semicolons": "always", + "arrowParentheses": "asNeeded", + "bracketSameLine": true + } + } +} diff --git a/package.json b/package.json index b575435..2b17288 100644 --- a/package.json +++ b/package.json @@ -1,21 +1,23 @@ -{ - "name": "seyfert", - "private": true, - "workspaces": ["packages/*"], - "scripts": { - "build": "turbo build", - "dev": "turbo dev", - "lint": "turbo lint", - "format": "turbo format", - "test": "turbo test", - "check": "turbo run lint format build test" - }, - "devDependencies": { - "@biomejs/biome": "1.8.3", - "turbo": "^2.0.13" - }, - "packageManager": "pnpm@9.7.0", - "engines": { - "node": ">=18" - } -} \ No newline at end of file +{ + "name": "seyfert", + "private": true, + "workspaces": [ + "packages/*" + ], + "scripts": { + "build": "turbo build", + "dev": "turbo dev", + "lint": "turbo lint", + "format": "turbo format", + "test": "turbo test", + "check": "turbo run --concurrency 32 lint format build test checkb" + }, + "devDependencies": { + "@biomejs/biome": "1.9.1", + "turbo": "^2.0.13" + }, + "packageManager": "pnpm@9.7.0", + "engines": { + "node": ">=18" + } +} diff --git a/packages/chartjs/biome.json b/packages/chartjs/biome.json new file mode 100644 index 0000000..10d60de --- /dev/null +++ b/packages/chartjs/biome.json @@ -0,0 +1,4 @@ +{ + "$schema": "https://biomejs.dev/schemas/1.9.0/schema.json", + "extends": ["../../biome.json"] +} diff --git a/packages/chartjs/package.json b/packages/chartjs/package.json index 67cd424..7ac5ce6 100644 --- a/packages/chartjs/package.json +++ b/packages/chartjs/package.json @@ -1,29 +1,30 @@ -{ - "name": "@slipher/chartjs", - "version": "0.0.1", - "private": false, - "license": "MIT", - "publishConfig": { - "access": "public" - }, - "files": [ - "lib/**" - ], - "main": "./lib/index.js", - "module": "./lib/index.js", - "types": "./lib/index.d.ts", - "scripts": { - "dev": "tsc --watch", - "build": "tsc", - "lint": "biome lint --write ./src", - "format": "biome format --write ./src" - }, - "devDependencies": { - "@types/node": "^22.3.0", - "typescript": "^5.5.4" - }, - "dependencies": { - "@napi-rs/canvas": "^0.1.54", - "chart.js": "^4.4.4" - } -} +{ + "name": "@slipher/chartjs", + "version": "0.0.1", + "private": false, + "license": "MIT", + "publishConfig": { + "access": "public" + }, + "files": [ + "lib/**" + ], + "main": "./lib/index.js", + "module": "./lib/index.js", + "types": "./lib/index.d.ts", + "scripts": { + "dev": "tsc --watch", + "build": "tsc", + "lint": "biome lint --write ./src", + "format": "biome format --write ./src", + "checkb": "biome check --write --no-errors-on-unmatched ./src" + }, + "devDependencies": { + "@types/node": "^22.3.0", + "typescript": "^5.5.4" + }, + "dependencies": { + "@napi-rs/canvas": "^0.1.54", + "chart.js": "^4.4.4" + } +} diff --git a/packages/chartjs/src/backgroundcolorplugin.ts b/packages/chartjs/src/backgroundcolorplugin.ts index 12e2dc6..d63accf 100644 --- a/packages/chartjs/src/backgroundcolorplugin.ts +++ b/packages/chartjs/src/backgroundcolorplugin.ts @@ -1,4 +1,4 @@ -import type { Plugin as ChartJSPlugin, Chart as ChartJS } from 'chart.js'; +import type { Chart as ChartJS, Plugin as ChartJSPlugin } from 'chart.js'; export class BackgroundColourPlugin implements ChartJSPlugin { public readonly id: string = 'chartjs-plugin-chartjs-napirs-canvas-background-colour'; diff --git a/packages/chartjs/src/napichart.ts b/packages/chartjs/src/napichart.ts index 101ea11..660dbf3 100644 --- a/packages/chartjs/src/napichart.ts +++ b/packages/chartjs/src/napichart.ts @@ -1,7 +1,7 @@ -import type { ChartConfiguration, Chart as ChartJS } from 'chart.js/auto'; import { type Canvas, createCanvas } from '@napi-rs/canvas'; -import { freshRequire } from './freshRequire'; +import type { ChartConfiguration, Chart as ChartJS } from 'chart.js/auto'; import { BackgroundColourPlugin } from './backgroundcolorplugin'; +import { freshRequire } from './freshRequire'; import type { ChartJSNapiRSCanvasOptions } from './options'; export class NapiChartjsCanvas { diff --git a/packages/chartjs/src/options.ts b/packages/chartjs/src/options.ts index cf40d16..bf312a6 100644 --- a/packages/chartjs/src/options.ts +++ b/packages/chartjs/src/options.ts @@ -1,4 +1,4 @@ -import type { Chart as ChartJS, ChartComponentLike } from 'chart.js'; +import type { ChartComponentLike, Chart as ChartJS } from 'chart.js'; export type ChartCallback = (chartJS: typeof ChartJS) => void | Promise; @@ -38,13 +38,13 @@ export type ChartJSNapiRSCanvasPlugins = { /** * This will work for plugins that `require` ChartJS themselves. */ - readonly requireChartJSLegacy?: ReadonlyArray; + readonly requireChartJSLegacy?: readonly string[]; /** * This should work for any plugin that expects a global Chart variable. */ - readonly globalVariableLegacy?: ReadonlyArray; + readonly globalVariableLegacy?: readonly string[]; /** * This will work with plugins that just return a plugin object and do no specific loading themselves. */ - readonly requireLegacy?: ReadonlyArray; + readonly requireLegacy?: readonly string[]; }; diff --git a/packages/cooldown/biome.json b/packages/cooldown/biome.json new file mode 100644 index 0000000..10d60de --- /dev/null +++ b/packages/cooldown/biome.json @@ -0,0 +1,4 @@ +{ + "$schema": "https://biomejs.dev/schemas/1.9.0/schema.json", + "extends": ["../../biome.json"] +} diff --git a/packages/cooldown/package.json b/packages/cooldown/package.json index 857ffc2..9e62f54 100644 --- a/packages/cooldown/package.json +++ b/packages/cooldown/package.json @@ -1,29 +1,30 @@ -{ - "name": "@slipher/cooldown", - "version": "0.0.1", - "private": false, - "license": "MIT", - "publishConfig": { - "access": "public" - }, - "files": [ - "lib/**" - ], - "main": "./lib/index.js", - "module": "./lib/index.js", - "types": "./lib/index.d.ts", - "scripts": { - "dev": "tsc --watch", - "build": "tsc", - "lint": "biome lint --write ./src", - "format": "biome format --write ./src", - "test": "node --test ./test/*" - }, - "devDependencies": { - "@types/node": "^22.4.0", - "typescript": "^5.5.4" - }, - "dependencies": { - "seyfert": "^2.1.0" - } -} +{ + "name": "@slipher/cooldown", + "version": "0.0.1", + "private": false, + "license": "MIT", + "publishConfig": { + "access": "public" + }, + "files": [ + "lib/**" + ], + "main": "./lib/index.js", + "module": "./lib/index.js", + "types": "./lib/index.d.ts", + "scripts": { + "dev": "tsc --watch", + "build": "tsc", + "lint": "biome lint --write ./src", + "format": "biome format --write ./src", + "checkb": "biome check --write --no-errors-on-unmatched ./src", + "test": "node --test ./test/*" + }, + "devDependencies": { + "@types/node": "^22.4.0", + "typescript": "^5.5.4" + }, + "dependencies": { + "seyfert": "^2.1.0" + } +} diff --git a/packages/cooldown/src/manager.ts b/packages/cooldown/src/manager.ts index eee2f6c..58aa010 100644 --- a/packages/cooldown/src/manager.ts +++ b/packages/cooldown/src/manager.ts @@ -1,8 +1,8 @@ +import type { AnyContext } from 'seyfert'; import type { ReturnCache } from 'seyfert/lib/cache'; -import { type CooldownData, CooldownResource, type CooldownType } from './resource'; import type { BaseClient } from 'seyfert/lib/client/base'; -import { fakePromise, type MakePartial } from 'seyfert/lib/common'; -import type { AnyContext } from 'seyfert'; +import { type MakePartial, fakePromise } from 'seyfert/lib/common'; +import { type CooldownData, CooldownResource, type CooldownType } from './resource'; export class CooldownManager { resource: CooldownResource; @@ -48,7 +48,7 @@ export class CooldownManager { target: string, { type, ...data }: MakePartial & { type: `${CooldownType}` }, ) { - return fakePromise(this.resource.set(`${name}:${type}:${target}`, data)).then(() => {}); + return this.resource.set(`${name}:${type}:${target}`, data); } context(context: AnyContext) { diff --git a/packages/cooldown/test/manager.test.js b/packages/cooldown/test/manager.test.js index 017993f..9f3352f 100644 --- a/packages/cooldown/test/manager.test.js +++ b/packages/cooldown/test/manager.test.js @@ -1,98 +1,105 @@ -const { strict: assert } = require("node:assert/strict"); -const { test, describe, beforeEach } = require('node:test'); -const { Client, Cache, MemoryAdapter, Logger } = require('seyfert'); -const { CommandHandler } = require('seyfert/lib/commands/handler.js'); -const { CooldownManager } = require('../lib/manager.js'); -const { CooldownType } = require('../lib/resource.js'); - - -describe('CooldownManager', async () => { - let client; - let cooldownManager; - let cooldownData; - - beforeEach(() => { - client = new Client({ getRC: () => ({ debug: true }) }); - - const handler = new CommandHandler(new Logger({ active: true }), client); - cooldownData = { - type: CooldownType.User, - interval: 1000, - uses: 3 - } - handler.values = [ - // @ts-expect-error - { - name: 'testCommand', - cooldown: cooldownData - } - ] - - client.commands = handler; - - - client.cache = new Cache(0, new MemoryAdapter(), {}, client); - cooldownManager = new CooldownManager(client); - }); - - await test('Data should return cooldown data for a command', () => { - const data = cooldownManager.getCommandData('testCommand'); - assert.deepEqual(data, { - type: CooldownType.User, - interval: 1000, - uses: 3 - }); - }); - - await test('Data should return undefined for non-existent command', () => { - const data = cooldownManager.getCommandData('nonExistentCommand'); - assert.equal(data, undefined); - }); - - await test('has should return false for a new cooldown', () => { - const result = cooldownManager.has('testCommand', 'user1'); - assert.equal(result, false); - }); - - await test('has should return true when cooldown is active', () => { - for (let i = 0; i < cooldownData.uses; i++) { - cooldownManager.use('testCommand', 'user1'); - } - const result = cooldownManager.has('testCommand', 'user1'); - assert.equal(result, true); - }); - - await test('use should set cooldown when used for the first time', () => { - const result = cooldownManager.use('testCommand', 'user2'); - assert.equal(result, true); - }); - - await test('use should return time left when cooldown is active', () => { - for (let i = 0; i < cooldownData.uses; i++) { - cooldownManager.use('testCommand', 'user3'); - } - const result = cooldownManager.use('testCommand', 'user3'); - assert.ok(typeof result === 'number'); - }); - - await test('refill should refill the cooldown', () => { - cooldownManager.use('testCommand', 'user1'); - const result = cooldownManager.refill('testCommand', 'user1'); - assert.equal(result, true); - assert.equal(cooldownManager.has('testCommand', 'user1'), false); - }); - - await test('drip should drip the cooldown over time', async () => { - cooldownManager.use('testCommand', 'user1'); - - // Simulate time passing - await new Promise(resolve => setTimeout(resolve, 1000)); - - const data = cooldownManager.resource.get('testCommand:user:user1'); - const props = cooldownManager.getCommandData('testCommand'); - await cooldownManager.drip('testCommand', 'user1', props, data); - const getter = cooldownManager.resource.get('testCommand:user:user1'); - assert.ok(getter.remaining === 2); - }); -}); - +const { strict: assert } = require('node:assert/strict'); +const { test, describe, beforeEach } = require('node:test'); +const { Client, Cache, MemoryAdapter, Logger } = require('seyfert'); +const { CommandHandler } = require('seyfert/lib/commands/handler.js'); +const { CooldownManager } = require('../lib/manager.js'); +const { CooldownType } = require('../lib/resource.js'); + +describe('CooldownManager', async () => { + let client; + let cooldownManager; + let cooldownData; + + beforeEach(() => { + client = new Client({ + getRC: () => ({ + debug: true, + intents: 0, + token: '', + locations: { + base: '', + output: '', + }, + }), + }); + + const handler = new CommandHandler(new Logger({ active: true }), client); + cooldownData = { + type: CooldownType.User, + interval: 1000, + uses: 3, + }; + handler.values = [ + // @ts-expect-error + { + name: 'testCommand', + cooldown: cooldownData, + }, + ]; + + client.commands = handler; + + client.cache = new Cache(0, new MemoryAdapter(), {}, client); + cooldownManager = new CooldownManager(client); + }); + + await test('Data should return cooldown data for a command', () => { + const data = cooldownManager.getCommandData('testCommand'); + assert.deepEqual(data, { + type: CooldownType.User, + interval: 1000, + uses: 3, + }); + }); + + await test('Data should return undefined for non-existent command', () => { + const data = cooldownManager.getCommandData('nonExistentCommand'); + assert.equal(data, undefined); + }); + + await test('has should return false for a new cooldown', () => { + const result = cooldownManager.has('testCommand', 'user1'); + assert.equal(result, false); + }); + + await test('has should return true when cooldown is active', () => { + for (let i = 0; i < cooldownData.uses; i++) { + cooldownManager.use('testCommand', 'user1'); + } + const result = cooldownManager.has('testCommand', 'user1'); + assert.equal(result, true); + }); + + await test('use should set cooldown when used for the first time', () => { + const result = cooldownManager.use('testCommand', 'user2'); + assert.equal(result, true); + }); + + await test('use should return time left when cooldown is active', () => { + for (let i = 0; i < cooldownData.uses; i++) { + cooldownManager.use('testCommand', 'user3'); + } + const result = cooldownManager.use('testCommand', 'user3'); + assert.ok(typeof result === 'number'); + }); + + await test('refill should refill the cooldown', () => { + cooldownManager.use('testCommand', 'user1'); + const result = cooldownManager.refill('testCommand', 'user1'); + assert.equal(result, true); + assert.equal(cooldownManager.has('testCommand', 'user1'), false); + }); + + await test('drip should drip the cooldown over time', async () => { + cooldownManager.use('testCommand', 'user1'); + + // Simulate time passing + await new Promise(resolve => setTimeout(resolve, 1000)); + + const data = cooldownManager.resource.get('testCommand:user:user1'); + const props = cooldownManager.getCommandData('testCommand'); + await cooldownManager.drip('testCommand', 'user1', props, data); + const getter = cooldownManager.resource.get('testCommand:user:user1'); + assert.ok(getter.remaining === 2); + }); +}); diff --git a/packages/generic-adapter/biome.json b/packages/generic-adapter/biome.json new file mode 100644 index 0000000..10d60de --- /dev/null +++ b/packages/generic-adapter/biome.json @@ -0,0 +1,4 @@ +{ + "$schema": "https://biomejs.dev/schemas/1.9.0/schema.json", + "extends": ["../../biome.json"] +} diff --git a/packages/generic-adapter/package.json b/packages/generic-adapter/package.json index e9c3380..9fa323d 100644 --- a/packages/generic-adapter/package.json +++ b/packages/generic-adapter/package.json @@ -1,29 +1,30 @@ -{ - "name": "@slipher/generic-adapter", - "version": "0.0.1", - "private": false, - "license": "MIT", - "publishConfig": { - "access": "public" - }, - "files": [ - "lib/**" - ], - "main": "./lib/index.js", - "module": "./lib/index.js", - "types": "./lib/index.d.ts", - "scripts": { - "dev": "tsc --watch", - "build": "tsc", - "lint": "biome lint --write ./src", - "format": "biome format --write ./src" - }, - "dependencies": { - "seyfert": "^2.1.0", - "tweetnacl": "^1.0.3" - }, - "devDependencies": { - "@types/node": "^22.3.0", - "typescript": "^5.5.4" - } -} \ No newline at end of file +{ + "name": "@slipher/generic-adapter", + "version": "0.0.1", + "private": false, + "license": "MIT", + "publishConfig": { + "access": "public" + }, + "files": [ + "lib/**" + ], + "main": "./lib/index.js", + "module": "./lib/index.js", + "types": "./lib/index.d.ts", + "scripts": { + "dev": "tsc --watch", + "build": "tsc", + "lint": "biome lint --write ./src", + "format": "biome format --write ./src", + "checkb": "biome check --write --no-errors-on-unmatched ./src" + }, + "dependencies": { + "seyfert": "^2.1.0", + "tweetnacl": "^1.0.3" + }, + "devDependencies": { + "@types/node": "^22.3.0", + "typescript": "^5.5.4" + } +} diff --git a/packages/generic-adapter/src/adapter.ts b/packages/generic-adapter/src/adapter.ts index 274e9b1..8e168df 100644 --- a/packages/generic-adapter/src/adapter.ts +++ b/packages/generic-adapter/src/adapter.ts @@ -1,10 +1,10 @@ import type { HttpClient, Logger } from 'seyfert'; import type { InternalRuntimeConfigHTTP } from 'seyfert/lib/client/base'; -import { type APIInteraction, InteractionResponseType, InteractionType } from 'seyfert/lib/types'; import type { HttpServerAdapter } from 'seyfert/lib/client/types'; +import { type APIInteraction, InteractionResponseType, InteractionType } from 'seyfert/lib/types'; -import nacl from 'tweetnacl'; import { isCloudfareWorker } from 'seyfert/lib/common'; +import nacl from 'tweetnacl'; export class GenericAdapter implements HttpServerAdapter { publicKeyHex!: Buffer; @@ -55,7 +55,7 @@ export class GenericAdapter implements HttpServerAdapter { return new Response('', { status: 418 }); } switch (rawBody.type) { - case InteractionType.Ping: + case InteractionType.Ping: { this.debugger?.debug('Ping interaction received, responding.'); return Response.json( { type: InteractionResponseType.Pong }, @@ -65,7 +65,8 @@ export class GenericAdapter implements HttpServerAdapter { }, }, ); - default: + } + default: { if (isCloudfareWorker()) { // you can not do more net requests after responding. // so we use discord api instead @@ -84,6 +85,7 @@ export class GenericAdapter implements HttpServerAdapter { }), ); }); + } } } } diff --git a/packages/redis-adapter/biome.json b/packages/redis-adapter/biome.json new file mode 100644 index 0000000..10d60de --- /dev/null +++ b/packages/redis-adapter/biome.json @@ -0,0 +1,4 @@ +{ + "$schema": "https://biomejs.dev/schemas/1.9.0/schema.json", + "extends": ["../../biome.json"] +} diff --git a/packages/redis-adapter/package.json b/packages/redis-adapter/package.json index 85ca5d5..d3cabe4 100644 --- a/packages/redis-adapter/package.json +++ b/packages/redis-adapter/package.json @@ -18,8 +18,11 @@ "lint": "biome lint --write ./src", "format": "biome format --write ./src", "test": "node --test ./test/*", + "checkb": "biome check --write --no-errors-on-unmatched ./src", "test:adapter": "node --test ./test/adapter.test.js", - "test:cache": "node --test ./test/cache.test.js" + "test:cache": "node --test ./test/cache.test.js", + "test:expirableadapter": "node --test ./test/expirableadapter.test.js", + "test:expirablecache": "node --test ./test/expirablecache.test.js" }, "dependencies": { "@redis/client": "^1.6.0", diff --git a/packages/redis-adapter/src/adapter.ts b/packages/redis-adapter/src/adapter.ts index 3962210..3579768 100644 --- a/packages/redis-adapter/src/adapter.ts +++ b/packages/redis-adapter/src/adapter.ts @@ -1,7 +1,7 @@ +import { type RedisClientOptions, createClient } from '@redis/client'; import type { Adapter } from 'seyfert/lib/cache'; -import { createClient, type RedisClientOptions } from '@redis/client'; -interface RedisAdapterOptions { +export interface RedisAdapterOptions { namespace?: string; } @@ -22,9 +22,9 @@ export class RedisAdapter implements Adapter { await this.client.connect(); } - private async __scanSets(query: string, returnKeys?: false): Promise; - private async __scanSets(query: string, returnKeys: true): Promise; - private async __scanSets(query: string, returnKeys = false) { + async __scanSets(query: string, returnKeys?: false): Promise; + async __scanSets(query: string, returnKeys: true): Promise; + async __scanSets(query: string, returnKeys = false) { const match = this.buildKey(query); const keys: any[] = []; @@ -42,7 +42,7 @@ export class RedisAdapter implements Adapter { async scan(query: string, returnKeys: true): Promise; async scan(query: string, returnKeys = false) { const match = this.buildKey(query); - const values = []; + const values: string[] = []; for await (const i of this.client.scanIterator({ MATCH: match, TYPE: 'hash', @@ -55,7 +55,6 @@ export class RedisAdapter implements Adapter { async bulkGet(keys: string[]) { const promises: Promise[] = []; - for (const key of keys) { promises.push(this.client.hGetAll(this.buildKey(key))); } @@ -91,23 +90,9 @@ export class RedisAdapter implements Adapter { async bulkPatch(updateOnly: boolean, data: [string, any][]) { const promises: Promise[] = []; + for (const [k, v] of data) { - if (updateOnly) { - promises.push( - this.client.eval( - `if redis.call('exists',KEYS[1]) == 1 then redis.call('hset', KEYS[1], ${Array.from( - { length: Object.keys(v).length * 2 }, - (_, i) => `ARGV[${i + 1}]`, - )}) end`, - { - arguments: Object.entries(toDb(v)).flat(), - keys: [this.buildKey(k)], - }, - ), - ); - } else { - promises.push(this.client.hSet(this.buildKey(k), toDb(v))); - } + promises.push(this.patch(updateOnly, k, v)); } await Promise.all(promises); @@ -207,11 +192,11 @@ export class RedisAdapter implements Adapter { } } -const isObject = (o: unknown) => { +export const isObject = (o: unknown) => { return !!o && typeof o === 'object' && !Array.isArray(o); }; -function toNormal(target: Record): undefined | Record | Record[] { +export function toNormal(target: Record): undefined | Record | Record[] { if (typeof target.ARRAY_OF === 'string') return JSON.parse(target.ARRAY_OF as string).map(toNormal); if (!Object.keys(target).length) return undefined; const result: Record = {}; @@ -229,7 +214,7 @@ function toNormal(target: Record): undefined | Record return result; } -function toDb(target: Record | Record[]): Record | { ARRAY_OF: string } { +export function toDb(target: Record | Record[]): Record | { ARRAY_OF: string } { if (Array.isArray(target)) return { ARRAY_OF: JSON.stringify(target.map(toDb)) }; const result: Record = {}; for (const [key, value] of Object.entries(target)) { @@ -240,7 +225,7 @@ function toDb(target: Record | Record[]): Record | Record[]): Record; + constructor( + data: ({ client: ReturnType } | { redisOptions: RedisClientOptions }) & RedisAdapterOptions, + options: ExpirableRedisAdapterOptions = {}, + ) { + super(data); + this.options = MergeOptions( + { + default: { + expire: undefined, + }, + } satisfies ExpirableRedisAdapterOptions, + options, + ); + } + + async __scanString(query: string, returnKeys?: false): Promise; + async __scanString(query: string, returnKeys: true): Promise; + async __scanString(query: string, returnKeys = false) { + const match = this.buildKey(query); + const keys: any[] = []; + + for await (const i of this.client.scanIterator({ + MATCH: match, + TYPE: 'string', + })) { + keys.push(i); + } + + return returnKeys ? keys.map(x => this.buildKey(x)) : this.bulkGet(keys); + } + + async getToRelationship(to: string): Promise { + const keys = await this.__scanString(`${to}.uset.*`, true); + return keys.map(x => x.replace(`${this.namespace}:${to}.uset.`, '')); + } + + async bulkAddToRelationShip(data: Record): Promise { + const promises: Promise[] = []; + + for (const [key, value] of Object.entries(data)) { + const cacheType = key.split('.')[0] as keyof ExpirableRedisAdapterOptions; + const expire = this.options[cacheType]?.expire ?? this.options.default.expire!; + if (expire > 0) { + promises.push(this.client.set(`${this.buildKey(key)}.uset.${value}`, 's', { EX: expire })); + } else { + promises.push(this.client.set(`${this.buildKey(key)}.uset.${value}`, 's')); + } + } + + await Promise.all(promises); + } + + async addToRelationship(to: string, keys: string | string[]): Promise { + await this.bulkAddToRelationShip({ + [to]: Array.isArray(keys) ? keys : [keys], + }); + } + + async removeToRelationship(to: string, keys: string | string[]): Promise { + const promises: Promise[] = []; + + for (const i of Array.isArray(keys) ? keys : [keys]) { + promises.push(this.client.del(`${this.buildKey(to)}.uset.${i}`)); + } + + await Promise.all(promises); + } + + async removeRelationship(to: string | string[]): Promise { + const promisesScan: Promise[] = []; + + for (const i of Array.isArray(to) ? to : [to]) { + await this.scan(`${this.buildKey(i)}.uset.*`); + } + + await this.client.del(await Promise.all(promisesScan)); + } + + async count(to: string): Promise { + return (await this.keys(to)).length; + } + + async flush(): Promise { + const keys = await Promise.all([ + this.scan(this.buildKey('*'), true), + this.__scanString(this.buildKey('*'), true), + ]).then(x => x.flat()); + if (!keys.length) return; + await this.bulkRemove(keys); + } + + async bulkSet(data: [string, any][]) { + const promises: Promise[] = []; + + for (const [k, v] of data) { + promises.push(this.set(this.buildKey(k), v)); + } + + await Promise.all(promises); + } + + async set(id: string, data: any) { + const promises: Promise[] = []; + promises.push(this.client.hSet(this.buildKey(id), toDb(data))); + const cacheType = id.split('.')[0] as keyof ExpirableRedisAdapterOptions; + + const expire = this.options[cacheType]?.expire ?? this.options.default.expire!; + if (expire > 0) { + promises.push(this.client.expire(this.buildKey(id), expire)); + } + + await Promise.all(promises); + } + + async patch(updateOnly: boolean, id: string, data: any): Promise { + const promises: Promise[] = []; + + if (updateOnly) { + promises.push( + this.client.eval( + `if redis.call('exists',KEYS[1]) == 1 then redis.call('hset', KEYS[1], ${Array.from( + { length: Object.keys(data).length * 2 }, + (_, i) => `ARGV[${i + 1}]`, + )}) end`, + { + keys: [this.buildKey(id)], + arguments: Object.entries(toDb(data)).flat(), + }, + ), + ); + } else { + promises.push(this.client.hSet(this.buildKey(id), toDb(data))); + } + + const cacheType = id.split('.')[0] as keyof ExpirableRedisAdapterOptions; + const expire = this.options[cacheType]?.expire ?? this.options.default.expire!; + if (expire > 0) { + promises.push(this.client.expire(this.buildKey(id), expire)); + } + + await Promise.all(promises); + } +} diff --git a/packages/redis-adapter/src/index.ts b/packages/redis-adapter/src/index.ts index 4a3abe5..9c0009c 100644 --- a/packages/redis-adapter/src/index.ts +++ b/packages/redis-adapter/src/index.ts @@ -1 +1,2 @@ export * from './adapter'; +export * from './expirableAdapter'; diff --git a/packages/redis-adapter/test/adapter.test.js b/packages/redis-adapter/test/adapter.test.js index 88afa94..700e977 100644 --- a/packages/redis-adapter/test/adapter.test.js +++ b/packages/redis-adapter/test/adapter.test.js @@ -1,9 +1,12 @@ -const { strict } = require("node:assert/strict"); +const { strict } = require('node:assert/strict'); const { test, describe, after, before } = require('node:test'); -const { RedisAdapter } = require('../lib/adapter'); +const { RedisAdapter } = require('../lib/index'); describe('RedisAdapter', async () => { - const bulk = [['key1', { value: 'value1' }], ['key2', { value: 'value2' }]] + const bulk = [ + ['key1', { value: 'value1' }], + ['key2', { value: 'value2' }], + ]; const adapter = new RedisAdapter({ redisOptions: {}, @@ -42,11 +45,12 @@ describe('RedisAdapter', async () => { await test('bulkGet', async () => { const result = await adapter.bulkGet(['key1', 'key2']); - strict.deepStrictEqual(result, bulk.map(x => x[1])); + strict.deepStrictEqual( + result, + bulk.map(x => x[1]), + ); }); - - await test('patch', async () => { await strict.doesNotReject(async () => { await adapter.patch(false, 'test_key', { newValue: 'updatedValue' }); @@ -55,7 +59,10 @@ describe('RedisAdapter', async () => { await test('bulkPatch', async () => { await strict.doesNotReject(async () => { - await adapter.bulkPatch(false, [['key1', { newValue: 'updatedValue1' }], ['key2', { newValue: 'updatedValue2' }]]); + await adapter.bulkPatch(false, [ + ['key1', { newValue: 'updatedValue1' }], + ['key2', { newValue: 'updatedValue2' }], + ]); }); }); diff --git a/packages/redis-adapter/test/cache.test.js b/packages/redis-adapter/test/cache.test.js index 20876b1..e6a57b0 100644 --- a/packages/redis-adapter/test/cache.test.js +++ b/packages/redis-adapter/test/cache.test.js @@ -1,7 +1,6 @@ const { describe, test } = require('node:test'); const { Client } = require('seyfert'); const { RedisAdapter } = require('../lib/index'); -const { doesNotThrow } = require('node:assert/strict'); // all intents const intents = 53608447; @@ -15,25 +14,22 @@ describe('Test Adapter cache', async t => { await adapter.start(); test('discord cache', async () => { - doesNotThrow(async () => { - const client = new Client({ - getRC: async () => ({ - locations: { - base: '', - output: '' - }, - intents, - token: '' - }) - }); - client.setServices({ - cache: { - adapter, - } - }) - await client.cache.testAdapter(); - - await adapter.client.quit(); + const client = new Client({ + getRC: async () => ({ + locations: { + base: '', + output: '', + }, + intents, + token: '', + }), + }); + client.setServices({ + cache: { + adapter, + }, }); + await client.cache.testAdapter(); + await adapter.client.quit(); }); }); diff --git a/packages/redis-adapter/test/expirableadapter.test.js b/packages/redis-adapter/test/expirableadapter.test.js new file mode 100644 index 0000000..99b69e4 --- /dev/null +++ b/packages/redis-adapter/test/expirableadapter.test.js @@ -0,0 +1,78 @@ +const { strict } = require('node:assert/strict'); +const { test, describe, after, before } = require('node:test'); +const { ExpirableRedisAdapter } = require('../lib/index'); + +describe('ExpirableRedisAdapter', async () => { + const bulk = [ + ['key1', { value: 'value1' }], + ['key2', { value: 'value2' }], + ]; + + const adapter = new ExpirableRedisAdapter({ + redisOptions: {}, + namespace: 'ex_custom_namespace', + }); + + await adapter.start(); + + before(async () => { + await adapter.flush(); + // Clean the Redis instance before each test + }); + + await test('constructor', () => { + strict.strictEqual(adapter.isAsync, true); + strict.strictEqual(adapter.namespace, 'ex_custom_namespace'); + }); + + await test('get', async () => { + const result = await adapter.get('test_key'); + strict.deepStrictEqual(result, undefined); + }); + + await test('set', async () => { + await strict.doesNotReject(async () => { + await adapter.set('test_key', { value: 'testValue' }); + }); + }); + + await test('bulkSet', async () => { + await strict.doesNotReject(async () => { + //@ts-expect-error + await adapter.bulkSet(bulk); + }); + }); + + await test('bulkGet', async () => { + const result = await adapter.bulkGet(['key1', 'key2']); + strict.deepStrictEqual( + result, + bulk.map(x => x[1]), + ); + }); + + await test('patch', async () => { + await strict.doesNotReject(async () => { + await adapter.patch(false, 'test_key', { newValue: 'updatedValue' }); + }); + }); + + await test('bulkPatch', async () => { + await strict.doesNotReject(async () => { + await adapter.bulkPatch(false, [ + ['key1', { newValue: 'updatedValue1' }], + ['key2', { newValue: 'updatedValue2' }], + ]); + }); + }); + + await test('scan', async () => { + const result = await adapter.scan('*'); + strict.strictEqual(result.length, 3); + }); + + after(async () => { + await adapter.flush(); + await adapter.client.quit(); + }); +}); diff --git a/packages/redis-adapter/test/expirablecache.test.js b/packages/redis-adapter/test/expirablecache.test.js new file mode 100644 index 0000000..104efa0 --- /dev/null +++ b/packages/redis-adapter/test/expirablecache.test.js @@ -0,0 +1,42 @@ +const { describe, test } = require('node:test'); +const { Client } = require('seyfert'); +const { ExpirableRedisAdapter } = require('../lib/index'); + +// all intents +const intents = 53608447; + +describe('Test Adapter cache', async t => { + const adapter = new ExpirableRedisAdapter( + { + redisOptions: {}, + namespace: 'ex_test_cache', + }, + { + default: { + expire: 2, + }, + }, + ); + + await adapter.start(); + + test('discord cache', async () => { + const client = new Client({ + getRC: async () => ({ + locations: { + base: '', + output: '', + }, + intents, + token: '', + }), + }); + client.setServices({ + cache: { + adapter, + }, + }); + await client.cache.testAdapter(); + await adapter.client.quit(); + }); +}); diff --git a/packages/uws-adapter/biome.json b/packages/uws-adapter/biome.json new file mode 100644 index 0000000..10d60de --- /dev/null +++ b/packages/uws-adapter/biome.json @@ -0,0 +1,4 @@ +{ + "$schema": "https://biomejs.dev/schemas/1.9.0/schema.json", + "extends": ["../../biome.json"] +} diff --git a/packages/uws-adapter/package.json b/packages/uws-adapter/package.json index 6febfaa..665f59c 100644 --- a/packages/uws-adapter/package.json +++ b/packages/uws-adapter/package.json @@ -1,30 +1,31 @@ -{ - "name": "@slipher/uws-adapter", - "version": "0.0.1", - "private": false, - "license": "MIT", - "publishConfig": { - "access": "public" - }, - "files": [ - "lib/**" - ], - "main": "./lib/index.js", - "module": "./lib/index.js", - "types": "./lib/index.d.ts", - "scripts": { - "dev": "tsc --watch", - "build": "tsc", - "lint": "biome lint --write ./src", - "format": "biome format --write ./src" - }, - "dependencies": { - "seyfert": "^2.1.0", - "tweetnacl": "^1.0.3", - "uWebSockets.js": "github:uNetworking/uWebSockets.js#v20.47.0" - }, - "devDependencies": { - "@types/node": "^22.3.0", - "typescript": "^5.5.4" - } -} \ No newline at end of file +{ + "name": "@slipher/uws-adapter", + "version": "0.0.1", + "private": false, + "license": "MIT", + "publishConfig": { + "access": "public" + }, + "files": [ + "lib/**" + ], + "main": "./lib/index.js", + "module": "./lib/index.js", + "types": "./lib/index.d.ts", + "scripts": { + "dev": "tsc --watch", + "build": "tsc", + "lint": "biome lint --write ./src", + "format": "biome format --write ./src", + "checkb": "biome check --write --no-errors-on-unmatched ./src" + }, + "dependencies": { + "seyfert": "^2.1.0", + "tweetnacl": "^1.0.3", + "uWebSockets.js": "github:uNetworking/uWebSockets.js#v20.47.0" + }, + "devDependencies": { + "@types/node": "^22.3.0", + "typescript": "^5.5.4" + } +} diff --git a/packages/uws-adapter/src/adapter.ts b/packages/uws-adapter/src/adapter.ts index 430b043..713c914 100644 --- a/packages/uws-adapter/src/adapter.ts +++ b/packages/uws-adapter/src/adapter.ts @@ -1,7 +1,7 @@ import type { HttpClient, Logger } from 'seyfert'; import type { InternalRuntimeConfigHTTP } from 'seyfert/lib/client/base'; -import { type APIInteraction, InteractionResponseType, InteractionType } from 'seyfert/lib/types'; import type { HttpServerAdapter } from 'seyfert/lib/client/types'; +import { type APIInteraction, InteractionResponseType, InteractionType } from 'seyfert/lib/types'; import nacl from 'tweetnacl'; import { App, type HttpRequest, type HttpResponse, type TemplatedApp } from 'uWebSockets.js'; @@ -70,10 +70,11 @@ export class UwsAdapter implements HttpServerAdapter { return; } switch (rawBody.type) { - case InteractionType.Ping: + case InteractionType.Ping: { this.debugger?.debug('Ping interaction received, responding.'); res.writeHeader('Content-Type', 'application/json').end(JSON.stringify({ type: InteractionResponseType.Pong })); break; + } default: res.cork(async () => { const { headers, response } = await this.client.onPacket(rawBody); @@ -82,7 +83,7 @@ export class UwsAdapter implements HttpServerAdapter { } res.end(JSON.stringify(response)); }); - return; + break; } } diff --git a/packages/watcher/biome.json b/packages/watcher/biome.json new file mode 100644 index 0000000..10d60de --- /dev/null +++ b/packages/watcher/biome.json @@ -0,0 +1,4 @@ +{ + "$schema": "https://biomejs.dev/schemas/1.9.0/schema.json", + "extends": ["../../biome.json"] +} diff --git a/packages/watcher/package.json b/packages/watcher/package.json index 1e4ffba..f77afab 100644 --- a/packages/watcher/package.json +++ b/packages/watcher/package.json @@ -1,30 +1,31 @@ -{ - "name": "@slipher/watcher", - "version": "0.0.1", - "private": false, - "license": "MIT", - "publishConfig": { - "access": "public" - }, - "files": [ - "lib/**" - ], - "main": "./lib/index.js", - "module": "./lib/index.js", - "types": "./lib/index.d.ts", - "scripts": { - "dev": "tsc --watch", - "build": "tsc", - "lint": "biome lint --write ./src", - "format": "biome format --write ./src" - }, - "dependencies": { - "chokidar": "^3.6.0", - "seyfert": "^2.1.0", - "tweetnacl": "^1.0.3" - }, - "devDependencies": { - "@types/node": "^22.3.0", - "typescript": "^5.5.4" - } -} \ No newline at end of file +{ + "name": "@slipher/watcher", + "version": "0.0.1", + "private": false, + "license": "MIT", + "publishConfig": { + "access": "public" + }, + "files": [ + "lib/**" + ], + "main": "./lib/index.js", + "module": "./lib/index.js", + "types": "./lib/index.d.ts", + "scripts": { + "dev": "tsc --watch", + "build": "tsc", + "lint": "biome lint --write ./src", + "format": "biome format --write ./src", + "checkb": "biome check --write --no-errors-on-unmatched ./src" + }, + "dependencies": { + "chokidar": "^3.6.0", + "seyfert": "^2.1.0", + "tweetnacl": "^1.0.3" + }, + "devDependencies": { + "@types/node": "^22.3.0", + "typescript": "^5.5.4" + } +} diff --git a/packages/watcher/src/watcher.ts b/packages/watcher/src/watcher.ts index a8f0339..af9b783 100644 --- a/packages/watcher/src/watcher.ts +++ b/packages/watcher/src/watcher.ts @@ -1,16 +1,16 @@ import { execSync } from 'node:child_process'; -import { ShardManager, Logger, ApiHandler, Router } from 'seyfert'; +import { Worker } from 'node:worker_threads'; +import { watch } from 'chokidar'; +import { ApiHandler, Logger, Router, ShardManager } from 'seyfert'; import { BaseClient, type InternalRuntimeConfig } from 'seyfert/lib/client/base'; -import type { MakeRequired, MakePartial } from 'seyfert/lib/common'; +import type { MakePartial, MakeRequired } from 'seyfert/lib/common'; import { GatewayDispatchEvents, - type GatewayReadyDispatch, type GatewayDispatchPayload, + type GatewayReadyDispatch, type GatewaySendPayload, } from 'seyfert/lib/types'; import type { ShardManagerDefaults, ShardManagerOptions } from 'seyfert/lib/websocket'; -import { Worker } from 'node:worker_threads'; -import { watch } from 'chokidar'; /** * Represents a watcher class that extends the ShardManager. @@ -31,7 +31,9 @@ export class Watcher extends ShardManager { */ constructor(options: WatcherOptions) { super({ - handlePayload() {}, + handlePayload() { + // + }, token: '', intents: 0, info: { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5781f56..ce77e03 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,27 +9,27 @@ importers: .: devDependencies: '@biomejs/biome': - specifier: 1.8.3 - version: 1.8.3 + specifier: 1.9.1 + version: 1.9.1 turbo: specifier: ^2.0.13 - version: 2.0.14 + version: 2.1.2 packages/chartjs: dependencies: '@napi-rs/canvas': specifier: ^0.1.54 - version: 0.1.54 + version: 0.1.55 chart.js: specifier: ^4.4.4 version: 4.4.4 devDependencies: '@types/node': specifier: ^22.3.0 - version: 22.4.0 + version: 22.5.5 typescript: specifier: ^5.5.4 - version: 5.5.4 + version: 5.6.2 packages/cooldown: dependencies: @@ -39,10 +39,10 @@ importers: devDependencies: '@types/node': specifier: ^22.4.0 - version: 22.4.0 + version: 22.5.5 typescript: specifier: ^5.5.4 - version: 5.5.4 + version: 5.6.2 packages/generic-adapter: dependencies: @@ -55,10 +55,10 @@ importers: devDependencies: '@types/node': specifier: ^22.3.0 - version: 22.4.0 + version: 22.5.5 typescript: specifier: ^5.5.4 - version: 5.5.4 + version: 5.6.2 packages/redis-adapter: dependencies: @@ -71,10 +71,10 @@ importers: devDependencies: '@types/node': specifier: ^22.3.0 - version: 22.4.0 + version: 22.5.5 typescript: specifier: ^5.5.4 - version: 5.5.4 + version: 5.6.2 packages/uws-adapter: dependencies: @@ -90,16 +90,16 @@ importers: devDependencies: '@types/node': specifier: ^22.3.0 - version: 22.4.0 + version: 22.5.5 typescript: specifier: ^5.5.4 - version: 5.5.4 + version: 5.6.2 packages/watcher: dependencies: chokidar: specifier: ^3.6.0 - version: 3.6.0 + version: 4.0.0 seyfert: specifier: ^2.1.0 version: 2.1.0 @@ -109,62 +109,62 @@ importers: devDependencies: '@types/node': specifier: ^22.3.0 - version: 22.4.0 + version: 22.5.5 typescript: specifier: ^5.5.4 - version: 5.5.4 + version: 5.6.2 packages: - '@biomejs/biome@1.8.3': - resolution: {integrity: sha512-/uUV3MV+vyAczO+vKrPdOW0Iaet7UnJMU4bNMinggGJTAnBPjCoLEYcyYtYHNnUNYlv4xZMH6hVIQCAozq8d5w==} + '@biomejs/biome@1.9.1': + resolution: {integrity: sha512-Ps0Rg0zg3B1zpx+zQHMz5b0n0PBNCAaXttHEDTVrJD5YXR6Uj3T+abTDgeS3wsu4z5i2whqcE1lZxGyWH4bZYg==} engines: {node: '>=14.21.3'} hasBin: true - '@biomejs/cli-darwin-arm64@1.8.3': - resolution: {integrity: sha512-9DYOjclFpKrH/m1Oz75SSExR8VKvNSSsLnVIqdnKexj6NwmiMlKk94Wa1kZEdv6MCOHGHgyyoV57Cw8WzL5n3A==} + '@biomejs/cli-darwin-arm64@1.9.1': + resolution: {integrity: sha512-js0brHswq/BoeKgfSEUJYOjUOlML6p65Nantti+PsoQ61u9+YVGIZ7325LK7iUpDH8KVJT+Bx7K2b/6Q//W1Pw==} engines: {node: '>=14.21.3'} cpu: [arm64] os: [darwin] - '@biomejs/cli-darwin-x64@1.8.3': - resolution: {integrity: sha512-UeW44L/AtbmOF7KXLCoM+9PSgPo0IDcyEUfIoOXYeANaNXXf9mLUwV1GeF2OWjyic5zj6CnAJ9uzk2LT3v/wAw==} + '@biomejs/cli-darwin-x64@1.9.1': + resolution: {integrity: sha512-2zVyjUg5rN0k8XrytkubQWLbp2r/AS5wPhXs4vgVjvqbLnzo32EGX8p61gzroF2dH9DCUCfskdrigCGqNdEbpg==} engines: {node: '>=14.21.3'} cpu: [x64] os: [darwin] - '@biomejs/cli-linux-arm64-musl@1.8.3': - resolution: {integrity: sha512-9yjUfOFN7wrYsXt/T/gEWfvVxKlnh3yBpnScw98IF+oOeCYb5/b/+K7YNqKROV2i1DlMjg9g/EcN9wvj+NkMuQ==} + '@biomejs/cli-linux-arm64-musl@1.9.1': + resolution: {integrity: sha512-L/JmXKvhsZ1lTgqOr3tWkzuY/NRppdIscHeC9aaiR72WjnBgJS94mawl9BWmGB3aWBc0q6oSDWnBS7617EMMmA==} engines: {node: '>=14.21.3'} cpu: [arm64] os: [linux] - '@biomejs/cli-linux-arm64@1.8.3': - resolution: {integrity: sha512-fed2ji8s+I/m8upWpTJGanqiJ0rnlHOK3DdxsyVLZQ8ClY6qLuPc9uehCREBifRJLl/iJyQpHIRufLDeotsPtw==} + '@biomejs/cli-linux-arm64@1.9.1': + resolution: {integrity: sha512-QgxwfnG+r2aer5RNGR67Ey91Tv7xXW8E9YckHhwuyWjdLEvKWkrSJrhVG/6ub0kVvTSNkYOuT/7/jMOFBuUbRA==} engines: {node: '>=14.21.3'} cpu: [arm64] os: [linux] - '@biomejs/cli-linux-x64-musl@1.8.3': - resolution: {integrity: sha512-UHrGJX7PrKMKzPGoEsooKC9jXJMa28TUSMjcIlbDnIO4EAavCoVmNQaIuUSH0Ls2mpGMwUIf+aZJv657zfWWjA==} + '@biomejs/cli-linux-x64-musl@1.9.1': + resolution: {integrity: sha512-gY+eFLIAW45v3WicQHicvjRfA0ntMZHx7h937bXwBMFNFoKmB6rMi6+fKQ6/hiS6juhsFxZdZIz20m15s49J6A==} engines: {node: '>=14.21.3'} cpu: [x64] os: [linux] - '@biomejs/cli-linux-x64@1.8.3': - resolution: {integrity: sha512-I8G2QmuE1teISyT8ie1HXsjFRz9L1m5n83U1O6m30Kw+kPMPSKjag6QGUn+sXT8V+XWIZxFFBoTDEDZW2KPDDw==} + '@biomejs/cli-linux-x64@1.9.1': + resolution: {integrity: sha512-F0INygtzI2L2n2R1KtYHGr3YWDt9Up1zrUluwembM+iJ1dXN3qzlSb7deFUsSJm4FaIPriqs6Xa56ukdQW6UeQ==} engines: {node: '>=14.21.3'} cpu: [x64] os: [linux] - '@biomejs/cli-win32-arm64@1.8.3': - resolution: {integrity: sha512-J+Hu9WvrBevfy06eU1Na0lpc7uR9tibm9maHynLIoAjLZpQU3IW+OKHUtyL8p6/3pT2Ju5t5emReeIS2SAxhkQ==} + '@biomejs/cli-win32-arm64@1.9.1': + resolution: {integrity: sha512-7Jahxar3OB+aTPOgXisMJmMKMsjcK+UmdlG3UIOQjzN/ZFEsPV+GT3bfrVjZDQaCw/zes0Cqd7VTWFjFTC/+MQ==} engines: {node: '>=14.21.3'} cpu: [arm64] os: [win32] - '@biomejs/cli-win32-x64@1.8.3': - resolution: {integrity: sha512-/PJ59vA1pnQeKahemaQf4Nyj7IKUvGQSc3Ze1uIGi+Wvr1xF7rGobSrAAG01T/gUDG21vkDsZYM03NAmPiVkqg==} + '@biomejs/cli-win32-x64@1.9.1': + resolution: {integrity: sha512-liSRWjWzFhyG7s1jg/Bbv9FL+ha/CEd5tFO3+dFIJNplL4TnvAivtyfRVi/tu/pNjISbV1k9JwdBewtAKAgA0w==} engines: {node: '>=14.21.3'} cpu: [x64] os: [win32] @@ -172,186 +172,133 @@ packages: '@kurkle/color@0.3.2': resolution: {integrity: sha512-fuscdXJ9G1qb7W8VdHi+IwRqij3lBkosAm4ydQtEmbY58OzHXqQhvlxqEkoz0yssNVn38bcpRWgA9PP+OGoisw==} - '@napi-rs/canvas-android-arm64@0.1.54': - resolution: {integrity: sha512-oYG+tnr0Zl1DgMcT+c7hLmPbB1RlYNAdRMkWSioxPg0F1Bc2D4nfyFBxal4M3JvY3GkuIBJoiDw5k3jjPeQzEA==} + '@napi-rs/canvas-android-arm64@0.1.55': + resolution: {integrity: sha512-zsc170uSA+mGTXiSpnXaTsBKzi/f2NATKLrCt5qp0ihR0YLSIGsNhNpYLQYSF6qvi2Uzjd9CyKEs+TKdj8oj3w==} engines: {node: '>= 10'} cpu: [arm64] os: [android] - '@napi-rs/canvas-darwin-arm64@0.1.54': - resolution: {integrity: sha512-F1JC05DEbsSVNlSEFyPxPS7a1kvNo+twyhE+QVx3XWTkMsoBgwkYaLEr7dkh+K7HTFQ0I0tF4TiFFbX+UpheKA==} + '@napi-rs/canvas-darwin-arm64@0.1.55': + resolution: {integrity: sha512-KMlL+O7viWsZ+c4qDoXUXyVEVXDcGrWuHuvt1VvUBcRjfsz/2of7i2rfClTzltX0nMKxU8JVKVrFSZOpPOZn4g==} engines: {node: '>= 10'} cpu: [arm64] os: [darwin] - '@napi-rs/canvas-darwin-x64@0.1.54': - resolution: {integrity: sha512-bQt1ySHxQaeAb9esRlgS8gTC2ZUvPdKdTv1l1bAPQ1iiBGKNQlKqb8NVCs+7hVjIbgGsNBa8RbmFNtUZStIMMQ==} + '@napi-rs/canvas-darwin-x64@0.1.55': + resolution: {integrity: sha512-ZiiK+tOGHD7GxAhq7F+gVYpWDQJ9Lr/eOI9gMXlnavmR14nVf3a8eYk3CX32yelurf6hMaMTjWISO9uAZDyRbA==} engines: {node: '>= 10'} cpu: [x64] os: [darwin] - '@napi-rs/canvas-linux-arm-gnueabihf@0.1.54': - resolution: {integrity: sha512-Wek0w+CyegFRXI+B1d+TzzWg3XlJBe5V0EnQjCOEhDPfRm3uOFp/MULXnXX9uPXXVvlVBlxDXa64HFWmyHvr3g==} + '@napi-rs/canvas-linux-arm-gnueabihf@0.1.55': + resolution: {integrity: sha512-HxthhRQoayfjG3Z7bAJ7r9Zq/L0gAxj26xjZTcjBYokr14/gtjL+Q+tsvW5PvH3SuL2sqnNXHy/TqvXcI+iyIw==} engines: {node: '>= 10'} cpu: [arm] os: [linux] - '@napi-rs/canvas-linux-arm64-gnu@0.1.54': - resolution: {integrity: sha512-9nNIodomr2++bj6pL2MAC72SNIUlCVA5J4rjxrSIcSIJH9R9inAzG5nhEQNCAebCSQxPTcKYijn/zHIAb8aYqw==} + '@napi-rs/canvas-linux-arm64-gnu@0.1.55': + resolution: {integrity: sha512-b6PSk6923c6kyHMiluPUJVVHc7CJI7SfYb5MZetyeINtYGNIVj8a80pWgiMs3LJDrUePh+WC00zgDCRkFttKlg==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] - '@napi-rs/canvas-linux-arm64-musl@0.1.54': - resolution: {integrity: sha512-BZ67nMQAvrCDmD6j2FvKdpy9xU22PoNqXDR2zswaKRcWg/cJWrjTYsbe9HfT9HELUID97M01aAtHNYmeiTA0+A==} + '@napi-rs/canvas-linux-arm64-musl@0.1.55': + resolution: {integrity: sha512-DHPR7F7Th9x0qkfSBojAgh7mPqInrj+IEJHvrKEsq8p0YTLBY8OUw8Va4OI7Z2zpiDsb2HVXq78Ws7KaekouFw==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] - '@napi-rs/canvas-linux-x64-gnu@0.1.54': - resolution: {integrity: sha512-XmeRMnklzUnl7FwJc1Sph0Na1+4AFaQb1er97SMCUwqSy4x2caDuKZ2ac5Dj6tTDmbs/ph1NrJu2nCY5SjorKw==} + '@napi-rs/canvas-linux-x64-gnu@0.1.55': + resolution: {integrity: sha512-znEwyWCHtoAIQerxEQ30DRnVJQ1X8a0zQqOuylEPI1AKCH57ZiWQzFam4IUiFNoYhQyzron5v5cEteVbBkYGpg==} engines: {node: '>= 10'} cpu: [x64] os: [linux] - '@napi-rs/canvas-linux-x64-musl@0.1.54': - resolution: {integrity: sha512-IST4w/WZCYZWt4/RxeHJITI7WX1wllVQx0HDGrcQu+KUMQ1x0J+ANiuZO3B37EuDEyR0zDpMatn7/oaYWr2q/Q==} + '@napi-rs/canvas-linux-x64-musl@0.1.55': + resolution: {integrity: sha512-mNWBiILhykehKlOzmbdTp8Fr25pnkHiC/01Ck9YjNWfV6Z3kBgJPWvG5J+WvkNnsPPu/K0JxTCryngj4h9Denw==} engines: {node: '>= 10'} cpu: [x64] os: [linux] - '@napi-rs/canvas-win32-x64-msvc@0.1.54': - resolution: {integrity: sha512-rGxzWfvxjCWPGRzi21qlaqJzrpWC2wWqAHS/MsQQD89KiKhfz9x4oVGTHz8348w8zjEHAvXg2F25Se3L9jEiJw==} + '@napi-rs/canvas-win32-x64-msvc@0.1.55': + resolution: {integrity: sha512-e6K83IchwQUbG9JSS4QK88qWJpwDbDC+tm1ugjVwSRWBdnicB5TwbUruOGjc1umgfGUq3qnQBs3yO1ZLB6N2uA==} engines: {node: '>= 10'} cpu: [x64] os: [win32] - '@napi-rs/canvas@0.1.54': - resolution: {integrity: sha512-/EbmJYc4Y/tumic2Ha9HwGH5jo/q0EEmAYuNwRDeCInfYdittrJKFPFmdWJ24AM+gZiC7IqfpxZOlw1GDSvzWw==} + '@napi-rs/canvas@0.1.55': + resolution: {integrity: sha512-Jw5ewjXboNSrEVXbUrj/l6800Stn1hHeMV4R/HbDkRGSMW3DLMOZAFGbd+d0174OpsjYFqc5SB3Q3wcatWsuMQ==} engines: {node: '>= 10'} '@redis/client@1.6.0': resolution: {integrity: sha512-aR0uffYI700OEEH4gYnitAnv3vzVGXCFvYfdpu/CJKvk4pHfLPEy/JSZyrpQ+15WhXe1yJRXLtfQ84s4mEXnPg==} engines: {node: '>=14'} - '@types/node@22.4.0': - resolution: {integrity: sha512-49AbMDwYUz7EXxKU/r7mXOsxwFr4BYbvB7tWYxVuLdb2ibd30ijjXINSMAHiEEZk5PCRBmW1gUeisn2VMKt3cQ==} - - anymatch@3.1.3: - resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} - engines: {node: '>= 8'} - - binary-extensions@2.3.0: - resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} - engines: {node: '>=8'} - - braces@3.0.3: - resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} - engines: {node: '>=8'} + '@types/node@22.5.5': + resolution: {integrity: sha512-Xjs4y5UPO/CLdzpgR6GirZJx36yScjh73+2NlLlkFRSoQN8B0DpfXPdZGnvVmLRLOsqDpOfTNv7D9trgGhmOIA==} chart.js@4.4.4: resolution: {integrity: sha512-emICKGBABnxhMjUjlYRR12PmOXhJ2eJjEHL2/dZlWjxRAZT1D8xplLFq5M0tMQK8ja+wBS/tuVEJB5C6r7VxJA==} engines: {pnpm: '>=8'} - chokidar@3.6.0: - resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} - engines: {node: '>= 8.10.0'} + chokidar@4.0.0: + resolution: {integrity: sha512-mxIojEAQcuEvT/lyXq+jf/3cO/KoA6z4CeNDGGevTybECPOMFCnQy3OPahluUkbqgPNGw5Bi78UC7Po6Lhy+NA==} + engines: {node: '>= 14.16.0'} cluster-key-slot@1.1.2: resolution: {integrity: sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==} engines: {node: '>=0.10.0'} - fill-range@7.1.1: - resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} - engines: {node: '>=8'} - - fsevents@2.3.3: - resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} - engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} - os: [darwin] - generic-pool@3.9.0: resolution: {integrity: sha512-hymDOu5B53XvN4QT9dBmZxPX4CWhBPPLguTZ9MMFeFa/Kg0xWVfylOVNlJji/E7yTZWFd/q9GO5TxDLq156D7g==} engines: {node: '>= 4'} - glob-parent@5.1.2: - resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} - engines: {node: '>= 6'} - - is-binary-path@2.1.0: - resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} - engines: {node: '>=8'} - - is-extglob@2.1.1: - resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} - engines: {node: '>=0.10.0'} - - is-glob@4.0.3: - resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} - engines: {node: '>=0.10.0'} - - is-number@7.0.0: - resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} - engines: {node: '>=0.12.0'} - - normalize-path@3.0.0: - resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} - engines: {node: '>=0.10.0'} - - picomatch@2.3.1: - resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} - engines: {node: '>=8.6'} - - readdirp@3.6.0: - resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} - engines: {node: '>=8.10.0'} + readdirp@4.0.1: + resolution: {integrity: sha512-GkMg9uOTpIWWKbSsgwb5fA4EavTR+SG/PMPoAY8hkhHfEEY0/vqljY+XHqtDf2cr2IJtoNRDbrrEpZUiZCkYRw==} + engines: {node: '>= 14.16.0'} seyfert@2.1.0: resolution: {integrity: sha512-L5AoUVACw1HDosUj0an9oA9ORICaGzU99mTs9yX2siT8SPe2LP3eoJ+MhRWrNULAV50qKKVzXMbiXyCzkY0jeA==} - to-regex-range@5.0.1: - resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} - engines: {node: '>=8.0'} - - turbo-darwin-64@2.0.14: - resolution: {integrity: sha512-kwfDmjNwlNfvtrvT29+ZBg5n1Wvxl891bFHchMJyzMoR0HOE9N1NSNdSZb9wG3e7sYNIu4uDkNk+VBEqJW0HzQ==} + turbo-darwin-64@2.1.2: + resolution: {integrity: sha512-3TEBxHWh99h2yIzkuIigMEOXt/ItYQp0aPiJjPd1xN4oDcsKK5AxiFKPH9pdtfIBzYsY59kQhZiFj0ELnSP7Bw==} cpu: [x64] os: [darwin] - turbo-darwin-arm64@2.0.14: - resolution: {integrity: sha512-m3LXYEshCx3wc4ZClM6gb01KYpFmtjQ9IBF3A7ofjb6ahux3xlYZJZ3uFCLAGHuvGLuJ3htfiPbwlDPTdknqqw==} + turbo-darwin-arm64@2.1.2: + resolution: {integrity: sha512-he0miWNq2WxJzsH82jS2Z4MXpnkzn9SH8a79iPXiJkq25QREImucscM4RPasXm8wARp91pyysJMq6aasD45CeA==} cpu: [arm64] os: [darwin] - turbo-linux-64@2.0.14: - resolution: {integrity: sha512-7vBzCPdoTtR92SNn2JMgj1FlMmyonGmpMaQdgAB1OVYtuQ6NVGoh7/lODfaILqXjpvmFSVbpBIDrKOT6EvcprQ==} + turbo-linux-64@2.1.2: + resolution: {integrity: sha512-fKUBcc0rK8Vdqv5a/E3CSpMBLG1bzwv+Q0Q83F8fG2ZfNCNKGbcEYABdonNZkkx141Rj03cZQFCgxu3MVEGU+A==} cpu: [x64] os: [linux] - turbo-linux-arm64@2.0.14: - resolution: {integrity: sha512-jwH+c0bfjpBf26K/tdEFatmnYyXwGROjbr6bZmNcL8R+IkGAc/cglL+OToqJnQZTgZvH7uDGbeSyUo7IsHyjuA==} + turbo-linux-arm64@2.1.2: + resolution: {integrity: sha512-sV8Bpmm0WiuxgbhxymcC7wSsuxfBBieI98GegSwbr/bs1ANAgzCg93urIrdKdQ3/b31zZxQwcaP4FBF1wx1Qdg==} cpu: [arm64] os: [linux] - turbo-windows-64@2.0.14: - resolution: {integrity: sha512-w9/XwkHSzvLjmioo6cl3S1yRfI6swxsV1j1eJwtl66JM4/pn0H2rBa855R0n7hZnmI6H5ywLt/nLt6Ae8RTDmw==} + turbo-windows-64@2.1.2: + resolution: {integrity: sha512-wcmIJZI9ORT9ykHGliFE6kWRQrlH930QGSjSgWC8uFChFFuOyUlvC7ttcxuSvU9VqC7NF4C+GVAcFJQ8lTjN7g==} cpu: [x64] os: [win32] - turbo-windows-arm64@2.0.14: - resolution: {integrity: sha512-XaQlyYk+Rf4xS5XWCo8XCMIpssgGGy8blzLfolN6YBp4baElIWMlkLZHDbGyiFmCbNf9I9gJI64XGRG+LVyyjA==} + turbo-windows-arm64@2.1.2: + resolution: {integrity: sha512-zdnXjrhk7YO6CP+Q5wPueEvOCLH4lDa6C4rrwiakcWcPgcQGbVozJlo4uaQ6awo8HLWQEvOwu84RkWTdLAc/Hw==} cpu: [arm64] os: [win32] - turbo@2.0.14: - resolution: {integrity: sha512-00JjdCMD/cpsjP0Izkjcm8Oaor5yUCfDwODtaLb+WyblyadkaDEisGhy3Dbd5az9n+5iLSPiUgf+WjPbns6MRg==} + turbo@2.1.2: + resolution: {integrity: sha512-Jb0rbU4iHEVQ18An/YfakdIv9rKnd3zUfSE117EngrfWXFHo3RndVH96US3GsT8VHpwTncPePDBT2t06PaFLrw==} hasBin: true tweetnacl@1.0.3: resolution: {integrity: sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==} - typescript@5.5.4: - resolution: {integrity: sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==} + typescript@5.6.2: + resolution: {integrity: sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw==} engines: {node: '>=14.17'} hasBin: true @@ -367,81 +314,81 @@ packages: snapshots: - '@biomejs/biome@1.8.3': + '@biomejs/biome@1.9.1': optionalDependencies: - '@biomejs/cli-darwin-arm64': 1.8.3 - '@biomejs/cli-darwin-x64': 1.8.3 - '@biomejs/cli-linux-arm64': 1.8.3 - '@biomejs/cli-linux-arm64-musl': 1.8.3 - '@biomejs/cli-linux-x64': 1.8.3 - '@biomejs/cli-linux-x64-musl': 1.8.3 - '@biomejs/cli-win32-arm64': 1.8.3 - '@biomejs/cli-win32-x64': 1.8.3 - - '@biomejs/cli-darwin-arm64@1.8.3': + '@biomejs/cli-darwin-arm64': 1.9.1 + '@biomejs/cli-darwin-x64': 1.9.1 + '@biomejs/cli-linux-arm64': 1.9.1 + '@biomejs/cli-linux-arm64-musl': 1.9.1 + '@biomejs/cli-linux-x64': 1.9.1 + '@biomejs/cli-linux-x64-musl': 1.9.1 + '@biomejs/cli-win32-arm64': 1.9.1 + '@biomejs/cli-win32-x64': 1.9.1 + + '@biomejs/cli-darwin-arm64@1.9.1': optional: true - '@biomejs/cli-darwin-x64@1.8.3': + '@biomejs/cli-darwin-x64@1.9.1': optional: true - '@biomejs/cli-linux-arm64-musl@1.8.3': + '@biomejs/cli-linux-arm64-musl@1.9.1': optional: true - '@biomejs/cli-linux-arm64@1.8.3': + '@biomejs/cli-linux-arm64@1.9.1': optional: true - '@biomejs/cli-linux-x64-musl@1.8.3': + '@biomejs/cli-linux-x64-musl@1.9.1': optional: true - '@biomejs/cli-linux-x64@1.8.3': + '@biomejs/cli-linux-x64@1.9.1': optional: true - '@biomejs/cli-win32-arm64@1.8.3': + '@biomejs/cli-win32-arm64@1.9.1': optional: true - '@biomejs/cli-win32-x64@1.8.3': + '@biomejs/cli-win32-x64@1.9.1': optional: true '@kurkle/color@0.3.2': {} - '@napi-rs/canvas-android-arm64@0.1.54': + '@napi-rs/canvas-android-arm64@0.1.55': optional: true - '@napi-rs/canvas-darwin-arm64@0.1.54': + '@napi-rs/canvas-darwin-arm64@0.1.55': optional: true - '@napi-rs/canvas-darwin-x64@0.1.54': + '@napi-rs/canvas-darwin-x64@0.1.55': optional: true - '@napi-rs/canvas-linux-arm-gnueabihf@0.1.54': + '@napi-rs/canvas-linux-arm-gnueabihf@0.1.55': optional: true - '@napi-rs/canvas-linux-arm64-gnu@0.1.54': + '@napi-rs/canvas-linux-arm64-gnu@0.1.55': optional: true - '@napi-rs/canvas-linux-arm64-musl@0.1.54': + '@napi-rs/canvas-linux-arm64-musl@0.1.55': optional: true - '@napi-rs/canvas-linux-x64-gnu@0.1.54': + '@napi-rs/canvas-linux-x64-gnu@0.1.55': optional: true - '@napi-rs/canvas-linux-x64-musl@0.1.54': + '@napi-rs/canvas-linux-x64-musl@0.1.55': optional: true - '@napi-rs/canvas-win32-x64-msvc@0.1.54': + '@napi-rs/canvas-win32-x64-msvc@0.1.55': optional: true - '@napi-rs/canvas@0.1.54': + '@napi-rs/canvas@0.1.55': optionalDependencies: - '@napi-rs/canvas-android-arm64': 0.1.54 - '@napi-rs/canvas-darwin-arm64': 0.1.54 - '@napi-rs/canvas-darwin-x64': 0.1.54 - '@napi-rs/canvas-linux-arm-gnueabihf': 0.1.54 - '@napi-rs/canvas-linux-arm64-gnu': 0.1.54 - '@napi-rs/canvas-linux-arm64-musl': 0.1.54 - '@napi-rs/canvas-linux-x64-gnu': 0.1.54 - '@napi-rs/canvas-linux-x64-musl': 0.1.54 - '@napi-rs/canvas-win32-x64-msvc': 0.1.54 + '@napi-rs/canvas-android-arm64': 0.1.55 + '@napi-rs/canvas-darwin-arm64': 0.1.55 + '@napi-rs/canvas-darwin-x64': 0.1.55 + '@napi-rs/canvas-linux-arm-gnueabihf': 0.1.55 + '@napi-rs/canvas-linux-arm64-gnu': 0.1.55 + '@napi-rs/canvas-linux-arm64-musl': 0.1.55 + '@napi-rs/canvas-linux-x64-gnu': 0.1.55 + '@napi-rs/canvas-linux-x64-musl': 0.1.55 + '@napi-rs/canvas-win32-x64-msvc': 0.1.55 '@redis/client@1.6.0': dependencies: @@ -449,108 +396,56 @@ snapshots: generic-pool: 3.9.0 yallist: 4.0.0 - '@types/node@22.4.0': + '@types/node@22.5.5': dependencies: undici-types: 6.19.6 - anymatch@3.1.3: - dependencies: - normalize-path: 3.0.0 - picomatch: 2.3.1 - - binary-extensions@2.3.0: {} - - braces@3.0.3: - dependencies: - fill-range: 7.1.1 - chart.js@4.4.4: dependencies: '@kurkle/color': 0.3.2 - chokidar@3.6.0: + chokidar@4.0.0: dependencies: - anymatch: 3.1.3 - braces: 3.0.3 - glob-parent: 5.1.2 - is-binary-path: 2.1.0 - is-glob: 4.0.3 - normalize-path: 3.0.0 - readdirp: 3.6.0 - optionalDependencies: - fsevents: 2.3.3 + readdirp: 4.0.1 cluster-key-slot@1.1.2: {} - fill-range@7.1.1: - dependencies: - to-regex-range: 5.0.1 - - fsevents@2.3.3: - optional: true - generic-pool@3.9.0: {} - glob-parent@5.1.2: - dependencies: - is-glob: 4.0.3 - - is-binary-path@2.1.0: - dependencies: - binary-extensions: 2.3.0 - - is-extglob@2.1.1: {} - - is-glob@4.0.3: - dependencies: - is-extglob: 2.1.1 - - is-number@7.0.0: {} - - normalize-path@3.0.0: {} - - picomatch@2.3.1: {} - - readdirp@3.6.0: - dependencies: - picomatch: 2.3.1 + readdirp@4.0.1: {} seyfert@2.1.0: {} - to-regex-range@5.0.1: - dependencies: - is-number: 7.0.0 - - turbo-darwin-64@2.0.14: + turbo-darwin-64@2.1.2: optional: true - turbo-darwin-arm64@2.0.14: + turbo-darwin-arm64@2.1.2: optional: true - turbo-linux-64@2.0.14: + turbo-linux-64@2.1.2: optional: true - turbo-linux-arm64@2.0.14: + turbo-linux-arm64@2.1.2: optional: true - turbo-windows-64@2.0.14: + turbo-windows-64@2.1.2: optional: true - turbo-windows-arm64@2.0.14: + turbo-windows-arm64@2.1.2: optional: true - turbo@2.0.14: + turbo@2.1.2: optionalDependencies: - turbo-darwin-64: 2.0.14 - turbo-darwin-arm64: 2.0.14 - turbo-linux-64: 2.0.14 - turbo-linux-arm64: 2.0.14 - turbo-windows-64: 2.0.14 - turbo-windows-arm64: 2.0.14 + turbo-darwin-64: 2.1.2 + turbo-darwin-arm64: 2.1.2 + turbo-linux-64: 2.1.2 + turbo-linux-arm64: 2.1.2 + turbo-windows-64: 2.1.2 + turbo-windows-arm64: 2.1.2 tweetnacl@1.0.3: {} - typescript@5.5.4: {} + typescript@5.6.2: {} uWebSockets.js@https://codeload.github.com/uNetworking/uWebSockets.js/tar.gz/6f4b450fc642abba540535f0755c990b42a16026: {} diff --git a/turbo.json b/turbo.json index 4c91f50..4da00f7 100644 --- a/turbo.json +++ b/turbo.json @@ -1,23 +1,30 @@ -{ - "$schema": "https://turbo.build/schema.json", - "ui": "tui", - "tasks": { - "build": { - "dependsOn": ["^build"], - "outputs": ["lib/**"] - }, - "lint": { - "dependsOn": ["^lint"] - }, - "format": { - "dependsOn": ["^format"] - }, - "test": { - "dependsOn": ["^test"] - }, - "dev": { - "cache": false, - "persistent": true - } - } -} +{ + "$schema": "https://turbo.build/schema.json", + "ui": "tui", + "tasks": { + "build": { + "dependsOn": ["^build"], + "outputs": ["lib/**"] + }, + "test": { + "cache": false, + "persistent": true + }, + "dev": { + "cache": false, + "persistent": true + }, + "lint": { + "cache": false, + "persistent": true + }, + "format": { + "cache": false, + "persistent": true + }, + "checkb": { + "cache": false, + "persistent": true + } + } +}