diff --git a/biome.jsonc b/biome.jsonc new file mode 100644 index 00000000..96ac51ab --- /dev/null +++ b/biome.jsonc @@ -0,0 +1,35 @@ +{ + "$schema": "https://biomejs.dev/schemas/1.9.1/schema.json", + "vcs": { + "enabled": false, + "clientKind": "git", + "useIgnoreFile": false + }, + "files": { + "ignoreUnknown": false, + "ignore": [] + }, + "formatter": { + "enabled": true, + "indentStyle": "space", + "indentWidth": 4 + }, + "organizeImports": { + "enabled": true + }, + "linter": { + "enabled": true, + "rules": { + "recommended": true, + "suspicious": { + "noExplicitAny": "off", + "noImplicitAnyLet": "off" + } + } + }, + "javascript": { + "formatter": { + "quoteStyle": "double" + } + } +} diff --git a/package.json b/package.json index 15a2f83d..707b6015 100644 --- a/package.json +++ b/package.json @@ -19,13 +19,14 @@ "test:integration": "c8 --src src --all --reporter text --reporter cobertura mocha -r tsx './src/**/*.integration.test.ts'", "test:code": "c8 --src src --all --reporter text --reporter cobertura mocha -r tsx './src/**/*.test.ts'", "test:all": "yarn test:types && yarn test:code", - "lint:code": "eslint *.js lib/ --ext .js --cache", + "lint:code": "biome lint src", "lint": "yarn lint:code" }, "files": [ "src" ], "devDependencies": { + "@biomejs/biome": "1.9.1", "@cucumber/cucumber": "10.8.0", "@types/mocha": "10.0.7", "@types/node": "20.12.12", diff --git a/src/app.ts b/src/app.ts index 7519f4ee..d24ef3e1 100644 --- a/src/app.ts +++ b/src/app.ts @@ -6,7 +6,7 @@ import { createFederation, Follow, KvKey, - KvStore, + type KvStore, MemoryKvStore, Create, Note, @@ -16,12 +16,12 @@ import { Service, Update, Announce, - Context, + type Context, Like, Undo, } from '@fedify/fedify'; import { federation } from '@fedify/fedify/x/hono'; -import { Hono, Context as HonoContext } from 'hono'; +import { Hono, type Context as HonoContext } from 'hono'; import { cors } from 'hono/cors'; import { behindProxy } from 'x-forwarded-fetch'; import { configure, getConsoleSink } from '@logtape/logtape'; @@ -90,7 +90,7 @@ export const db = await KnexKvStore.create(client, 'key_value'); * for example in the context of the Inbox Queue - so we need to wrap handlers with this. */ function ensureCorrectContext(fn: (ctx: Context, b: B) => Promise) { - return async function (ctx: Context, b: B) { + return async (ctx: Context, b: B) => { const host = ctx.host; if (!ctx.data) { (ctx as any).data = {}; @@ -157,42 +157,42 @@ fedify fedify.setObjectDispatcher( Article, - `/.ghost/activitypub/article/{id}`, + '/.ghost/activitypub/article/{id}', articleDispatcher, ); fedify.setObjectDispatcher( Note, - `/.ghost/activitypub/note/{id}`, + '/.ghost/activitypub/note/{id}', noteDispatcher, ); fedify.setObjectDispatcher( Follow, - `/.ghost/activitypub/follow/{id}`, + '/.ghost/activitypub/follow/{id}', followDispatcher, ); fedify.setObjectDispatcher( Accept, - `/.ghost/activitypub/accept/{id}`, + '/.ghost/activitypub/accept/{id}', acceptDispatcher, ); fedify.setObjectDispatcher( Create, - `/.ghost/activitypub/create/{id}`, + '/.ghost/activitypub/create/{id}', createDispatcher, ); fedify.setObjectDispatcher( Update, - `/.ghost/activitypub/update/{id}`, + '/.ghost/activitypub/update/{id}', updateDispatcher, ); fedify.setObjectDispatcher( Like, - `/.ghost/activitypub/like/{id}`, + '/.ghost/activitypub/like/{id}', likeDispatcher, ); fedify.setObjectDispatcher( Undo, - `/.ghost/activitypub/undo/{id}`, + '/.ghost/activitypub/undo/{id}', undoDispatcher, ); @@ -298,7 +298,7 @@ app.use( ); function forceAcceptHeader(fn: (req: Request) => unknown) { - return function (request: Request) { + return (request: Request) => { request.headers.set('accept', 'application/activity+json'); return fn(request); }; @@ -307,9 +307,9 @@ function forceAcceptHeader(fn: (req: Request) => unknown) { serve( { fetch: forceAcceptHeader(behindProxy(app.fetch)), - port: parseInt(process.env.PORT || '8080'), + port: Number.parseInt(process.env.PORT || '8080'), }, - function (info) { + (info) => { console.log(`listening on ${info.address}:${info.port}`); }, ); diff --git a/src/db.ts b/src/db.ts index 471d58fe..67132396 100644 --- a/src/db.ts +++ b/src/db.ts @@ -4,14 +4,14 @@ export const client = Knex({ client: 'mysql2', connection: { host: process.env.MYSQL_HOST, - port: parseInt(process.env.MYSQL_PORT!), + port: Number.parseInt(process.env.MYSQL_PORT!), user: process.env.MYSQL_USER, password: process.env.MYSQL_PASSWORD, database: process.env.MYSQL_DATABASE, }, }); -await client.schema.createTableIfNotExists('key_value', function (table) { +await client.schema.createTableIfNotExists('key_value', (table) => { table.increments('id').primary(); table.string('key', 2048); table.json('value').notNullable(); diff --git a/src/dispatchers.ts b/src/dispatchers.ts index 296c879b..3718fa88 100644 --- a/src/dispatchers.ts +++ b/src/dispatchers.ts @@ -3,23 +3,23 @@ import { Accept, Follow, Person, - RequestContext, + type RequestContext, Create, Note, Activity, Update, - Context, - Announce, + type Context, + type Announce, isActor, - Actor, + type Actor, Object as APObject, - Recipient, + type Recipient, Like, Undo, } from '@fedify/fedify'; import { v4 as uuidv4 } from 'uuid'; import { addToList } from './kv-helpers'; -import { ContextData } from './app'; +import type { ContextData } from './app'; import { ACTOR_DEFAULT_HANDLE } from './constants'; import { getUserData, getUserKeypair } from './user'; import { lookupActor } from './lookup-helpers'; @@ -66,7 +66,7 @@ export async function handleFollow( } const currentFollowers = await ctx.data.db.get(['followers']) ?? []; - let shouldRecordFollower = currentFollowers.includes(sender.id.href) === false; + const shouldRecordFollower = currentFollowers.includes(sender.id.href) === false; // Add follow activity to inbox const followJson = await follow.toJsonLd(); @@ -108,10 +108,7 @@ export async function handleAccept( console.log('Handling Accept'); const parsed = (ctx as any).parseUri(accept.objectId); console.log(parsed); - if (false && parsed?.type !== 'follow') { - console.log('Not accepting a follow - exit'); - return; - } + if (!accept.id) { console.log('Accept missing id - exit'); return; @@ -140,10 +137,7 @@ export async function handleCreate( console.log('Handling Create'); const parsed = (ctx as any).parseUri(create.objectId); console.log(parsed); - if (false && parsed?.type !== 'article') { - console.log('Not accepting a follow - exit'); - return; - } + if (!create.id) { console.log('Accept missing id - exit'); return; @@ -188,7 +182,7 @@ export async function handleAnnounce( // Lookup announced object - If not found in globalDb, perform network lookup let object = null; - let existing = await ctx.data.globaldb.get([announce.objectId.href]) ?? null; + const existing = await ctx.data.globaldb.get([announce.objectId.href]) ?? null; if (!existing) { console.log('Object not found in globalDb, performing network lookup'); @@ -257,7 +251,7 @@ export async function handleLike( // Lookup liked object - If not found in globalDb, perform network lookup let object = null; - let existing = await ctx.data.globaldb.get([like.objectId.href]) ?? null; + const existing = await ctx.data.globaldb.get([like.objectId.href]) ?? null; if (!existing) { console.log('Object not found in globalDb, performing network lookup'); @@ -349,7 +343,7 @@ export async function followingDispatcher( console.log('Following Dispatcher'); const results = (await ctx.data.db.get(['following'])) || []; console.log(results); - let items: Person[] = []; + const items: Person[] = []; for (const result of results) { try { const thing = await lookupActor(ctx, result); @@ -386,7 +380,7 @@ export async function outboxDispatcher( const results = filterOutboxActivityUris((await ctx.data.db.get(['outbox'])) || []); console.log(results); - let items: Activity[] = []; + const items: Activity[] = []; for (const result of results) { try { const thing = await ctx.data.globaldb.get([result]); @@ -418,7 +412,7 @@ export async function likedDispatcher( const results = (await ctx.data.db.get(['liked'])) || []; console.log(results); - let items: Like[] = []; + const items: Like[] = []; for (const result of results) { try { const thing = await ctx.data.globaldb.get([result]); diff --git a/src/dispatchers.unit.test.ts b/src/dispatchers.unit.test.ts index ff3678a8..95fcaf36 100644 --- a/src/dispatchers.unit.test.ts +++ b/src/dispatchers.unit.test.ts @@ -1,4 +1,4 @@ -import assert from 'assert'; +import assert from 'node:assert'; import sinon from 'sinon'; import { actorDispatcher, @@ -19,12 +19,12 @@ import { acceptDispatcher, createDispatcher, } from './dispatchers'; -import { Activity, RequestContext } from '@fedify/fedify'; +import { Activity, type RequestContext } from '@fedify/fedify'; import { ACTOR_DEFAULT_HANDLE } from './constants'; -describe('dispatchers', function () { - describe('actorDispatcher', function () { - it(`returns null if the handle is not "${ACTOR_DEFAULT_HANDLE}"`, async function () { +describe('dispatchers', () => { + describe('actorDispatcher', () => { + it(`returns null if the handle is not "${ACTOR_DEFAULT_HANDLE}"`, async () => { const ctx = {} as RequestContext; const handle = 'anything'; @@ -34,10 +34,10 @@ describe('dispatchers', function () { assert.equal(actual, expected); }); }); - describe('keypairDispatcher', function () {}); - describe('handleFollow', function () {}); + describe('keypairDispatcher', () => {}); + describe('handleFollow', () => {}); - describe('outboxDispatcher', function () { + describe('outboxDispatcher', () => { const outboxActivities: Record = { 'https://example.com/create/123': { '@context': [ @@ -84,15 +84,15 @@ describe('dispatchers', function () { }, } as RequestContext; - beforeEach(function () { + beforeEach(() => { ctx.data.db.get.withArgs(['outbox']).resolves(Object.keys(outboxActivities)); - Object.keys(outboxActivities).forEach(key => { + for (const key of Object.keys(outboxActivities)) { ctx.data.globaldb.get.withArgs([key]).resolves(outboxActivities[key]); - }); + } }); - it('returns relevant items from the outbox in the correct order', async function () { + it('returns relevant items from the outbox in the correct order', async () => { const result = await outboxDispatcher(ctx, ACTOR_DEFAULT_HANDLE); // Check items exist diff --git a/src/example.unit.test.ts b/src/example.unit.test.ts index 119cf011..1ac67ac9 100644 --- a/src/example.unit.test.ts +++ b/src/example.unit.test.ts @@ -1,7 +1,7 @@ -import assert from 'assert'; +import assert from 'node:assert'; -describe('Sanity', function () { - it('1 + 1 = 2', function () { +describe('Sanity', () => { + it('1 + 1 = 2', () => { assert.equal(1 + 1, 2, '1 + 1 should equal 2'); }); }); diff --git a/src/ghost.unit.test.ts b/src/ghost.unit.test.ts index ec8a0e42..d920b49f 100644 --- a/src/ghost.unit.test.ts +++ b/src/ghost.unit.test.ts @@ -1,4 +1,4 @@ -import assert from 'assert'; +import assert from 'node:assert'; import sinon from 'sinon'; import ky from 'ky'; import { getSiteSettings } from './ghost'; @@ -8,20 +8,20 @@ import { ACTOR_DEFAULT_SUMMARY } from './constants'; -describe('getSiteSettings', function () { +describe('getSiteSettings', () => { const host = 'example.com'; let kyGetStub: sinon.SinonStub; - beforeEach(function () { + beforeEach(() => { kyGetStub = sinon.stub(ky, 'get'); }); - afterEach(function () { + afterEach(() => { sinon.restore(); }); - it('should retrieve settings from Ghost', async function () { + it('should retrieve settings from Ghost', async () => { const settings = { site: { description: 'foo', @@ -41,7 +41,7 @@ describe('getSiteSettings', function () { assert.strictEqual(kyGetStub.firstCall.args[0], `https://${host}/ghost/api/admin/site/`); }); - it('should use defaults for missing settings', async function () { + it('should use defaults for missing settings', async () => { let result; // Missing description diff --git a/src/handlers.ts b/src/handlers.ts index eb429fb3..3ef04f0d 100644 --- a/src/handlers.ts +++ b/src/handlers.ts @@ -3,20 +3,20 @@ import { Follow, Like, Undo, - RequestContext, + type RequestContext, isActor, Create, Note, Update, - Actor, + type Actor, PUBLIC_COLLECTION } from '@fedify/fedify'; -import { Context, Next } from 'hono'; +import type { Context, Next } from 'hono'; import sanitizeHtml from 'sanitize-html'; import { v4 as uuidv4 } from 'uuid'; import { addToList, removeFromList } from './kv-helpers'; import { toURL } from './toURL'; -import { ContextData, HonoContextVariables, fedify } from './app'; +import { type ContextData, type HonoContextVariables, fedify } from './app'; import { getSiteSettings } from './ghost'; import type { PersonData } from './user'; import { ACTOR_DEFAULT_HANDLE } from './constants'; @@ -385,7 +385,7 @@ export async function inboxHandler( db: ctx.get('db'), globaldb: ctx.get('globaldb'), }); - let items: unknown[] = []; + const items: unknown[] = []; for (const result of results) { try { const db = ctx.get('globaldb'); @@ -412,7 +412,7 @@ export async function inboxHandler( }); } - let objectId: string = ''; + let objectId = ''; if (typeof thing.object === 'string') { objectId = thing.object; } else if (typeof thing.object.id === 'string') { diff --git a/src/knex.kvstore.integration.test.ts b/src/knex.kvstore.integration.test.ts index 11c2f31d..50808ea5 100644 --- a/src/knex.kvstore.integration.test.ts +++ b/src/knex.kvstore.integration.test.ts @@ -1,69 +1,57 @@ -import assert from 'assert'; +import assert from 'node:assert'; import { KnexKvStore } from './knex.kvstore'; import { Knex } from 'knex'; import { client } from './db'; -after(async function () { +after(async () => { await client.destroy(); }); -describe('KnexKvStore', function () { - it('Implements a basic KvStore', async function () { +describe('KnexKvStore', () => { + it('Implements a basic KvStore', async () => { const table = 'key_value'; const store = await KnexKvStore.create(client, table); - checkReadingUnsetKey: { - const actual = await store.get(['unsetkey']); - const expected = null; - assert.equal(actual, expected); - break checkReadingUnsetKey; - } - - checkReadingSetKey: { - await store.set(['setkey'], { hello: 'world' }); - const actual = await store.get(['setkey']); - const expected = { hello: 'world' }; - assert.deepEqual(actual, expected); - break checkReadingSetKey; - } - - checkUpdatingKey: { - await store.set(['updated'], { initial: 'value' }); - await store.set(['updated'], { updated: 'value' }); - const actual = await store.get(['updated']); - const expected = { updated: 'value' }; - assert.deepEqual(actual, expected); - break checkUpdatingKey; - } - - checkDeletingKey: { - await store.set(['deleted'], { initial: 'value' }); - await store.delete(['deleted']); - const actual = await store.get(['deleted']); - const expected = null; - assert.deepEqual(actual, expected); - break checkDeletingKey; - } + // Check reading an unset key + const actualUnsetKey = await store.get(['unsetkey']); + const expectedUnsetKey = null; + assert.equal(actualUnsetKey, expectedUnsetKey); + + // Check reading a set key + await store.set(['setkey'], { hello: 'world' }); + const actualSetKey = await store.get(['setkey']); + const expectedSetKey = { hello: 'world' }; + assert.deepEqual(actualSetKey, expectedSetKey); + + // Check updating a key + await store.set(['updated'], { initial: 'value' }); + await store.set(['updated'], { updated: 'value' }); + const actualUpdatedKey = await store.get(['updated']); + const expectedUpdatedKey = { updated: 'value' }; + assert.deepEqual(actualUpdatedKey, expectedUpdatedKey); + + // Check deleting a key + await store.set(['deleted'], { initial: 'value' }); + await store.delete(['deleted']); + const actualDeletedKey = await store.get(['deleted']); + const expectedDeletedKey = null; + assert.deepEqual(actualDeletedKey, expectedDeletedKey); }); - it('Can store boolean values', async function () { + it('Can store boolean values', async () => { const table = 'key_value'; const store = await KnexKvStore.create(client, table); - checkTrue: { - await store.set(['boolean_true'], true); - const actual = await store.get(['boolean_true']); - const expected = true; - assert.equal(actual, expected); - break checkTrue; - } - - checkFalse: { - await store.set(['boolean_false'], false); - const actual = await store.get(['boolean_false']); - const expected = false; - assert.equal(actual, expected); - break checkFalse; - } + // Check storing true + await store.set(['boolean_true'], true); + const actualTrue = await store.get(['boolean_true']); + const expectedTrue = true; + assert.equal(actualTrue, expectedTrue); + + // Check storing false + await store.set(['boolean_false'], false); + const actualFalse = await store.get(['boolean_false']); + const expectedFalse = false; + assert.equal(actualFalse, expectedFalse); }); }); diff --git a/src/knex.kvstore.ts b/src/knex.kvstore.ts index 5a7f6c06..281d3927 100644 --- a/src/knex.kvstore.ts +++ b/src/knex.kvstore.ts @@ -1,5 +1,5 @@ -import { KvKey, KvStore, KvStoreSetOptions } from '@fedify/fedify'; -import Knex from 'knex'; +import type { KvKey, KvStore, KvStoreSetOptions } from '@fedify/fedify'; +import type Knex from 'knex'; export class KnexKvStore implements KvStore { private constructor( diff --git a/src/kv-helpers.ts b/src/kv-helpers.ts index 53e65e53..c29a9794 100644 --- a/src/kv-helpers.ts +++ b/src/kv-helpers.ts @@ -1,4 +1,4 @@ -import { KvKey, KvStore } from '@fedify/fedify'; +import type { KvKey, KvStore } from '@fedify/fedify'; export function scopeKvKey(scope: KvKey, key: KvKey): KvKey { const [first, ...rest] = scope; diff --git a/src/kv-helpers.unit.test.ts b/src/kv-helpers.unit.test.ts index bfa60f41..7698f5b3 100644 --- a/src/kv-helpers.unit.test.ts +++ b/src/kv-helpers.unit.test.ts @@ -1,29 +1,28 @@ -import assert from 'assert'; +import assert from 'node:assert'; import { MemoryKvStore } from '@fedify/fedify'; import { addToList, removeFromList, scopeKvStore } from './kv-helpers'; -describe('Kv Helpers', function () { - describe('scopeKvStore', function () { - it('Returns a scoped KvStore', async function () { +describe('Kv Helpers', () => { + describe('scopeKvStore', () => { + it('Returns a scoped KvStore', async () => { const store = new MemoryKvStore(); const scopedStore = scopeKvStore(store, ['scoped']); await scopedStore.set(['key'], { value: 'da value' }); - checkIsScoped: { + { const actual = await store.get(['key']); const expected = null; assert.equal(actual, expected); - break checkIsScoped; } - checkIsSet: { + { const actual = await scopedStore.get(['key']); const expected = { value: 'da value' }; assert.deepEqual(actual, expected); } - checkDeletes: { + { await scopedStore.delete(['key']); const actual = await scopedStore.get(['key']); const expected = null; @@ -32,18 +31,18 @@ describe('Kv Helpers', function () { }); }); - describe('addToList', function () { - it('Appends items to a key, whether it exists or not', async function () { + describe('addToList', () => { + it('Appends items to a key, whether it exists or not', async () => { const store = new MemoryKvStore(); - checkNonExisting: { + { await addToList(store, ['not-existing'], 'first'); const actual = await store.get(['not-existing']); const expected = ['first']; assert.deepEqual(actual, expected); } - checkExisting: { + { await store.set(['existing'], ['first']); await addToList(store, ['existing'], 'second'); const actual = await store.get(['existing']); @@ -53,18 +52,18 @@ describe('Kv Helpers', function () { }); }); - describe('removeFromList', function () { - it('Removes an item from a key, whether it exists or not', async function () { + describe('removeFromList', () => { + it('Removes an item from a key, whether it exists or not', async () => { const store = new MemoryKvStore(); - checkNonExisting: { + { await removeFromList(store, ['not-existing'], 'first'); const actual = await store.get(['not-existing']); const expected: never[] = []; assert.deepEqual(actual, expected); } - checkExisting: { + { await store.set(['existing'], ['first']); await removeFromList(store, ['existing'], 'first'); const actual = await store.get(['existing']); diff --git a/src/lookup-helpers.ts b/src/lookup-helpers.ts index 29363dab..f7a32284 100644 --- a/src/lookup-helpers.ts +++ b/src/lookup-helpers.ts @@ -1,10 +1,10 @@ import { isActor, - Actor, - Context, + type Actor, + type Context, Object as APObject, } from '@fedify/fedify'; -import { ContextData } from './app'; +import type { ContextData } from './app'; export async function lookupActor(ctx: Context, url: string): Promise { try { diff --git a/src/user.ts b/src/user.ts index 4846d232..1ff244f1 100644 --- a/src/user.ts +++ b/src/user.ts @@ -1,12 +1,12 @@ import { Image, - RequestContext, + type RequestContext, generateCryptoKeyPair, exportJwk, importJwk, - Context, + type Context, } from '@fedify/fedify'; -import { ContextData } from './app'; +import type { ContextData } from './app'; import { ACTOR_DEFAULT_ICON, ACTOR_DEFAULT_NAME, diff --git a/src/user.unit.test.ts b/src/user.unit.test.ts index b659e1ad..93948a36 100644 --- a/src/user.unit.test.ts +++ b/src/user.unit.test.ts @@ -1,5 +1,5 @@ import { Image, RequestContext } from '@fedify/fedify'; -import assert from 'assert'; +import assert from 'node:assert'; import sinon from 'sinon'; import { @@ -51,8 +51,8 @@ function getCtx() { return ctx as any; } -describe('getUserData', function () { - it('persists a user to the database if it does not exist', async function () { +describe('getUserData', () => { + it('persists a user to the database if it does not exist', async () => { const ctx = getCtx(); ctx.data.db.get.resolves(null); @@ -92,7 +92,7 @@ describe('getUserData', function () { assert.deepStrictEqual(result, expectedUserData); }); - it('retrieves a user from the database', async function () { + it('retrieves a user from the database', async () => { const ctx = getCtx(); const persistedUser = { @@ -132,7 +132,7 @@ describe('getUserData', function () { assert.deepStrictEqual(result, expectedUserData); }); - it('handles retrieving a user with an invalid icon', async function () { + it('handles retrieving a user with an invalid icon', async () => { const ctx = getCtx(); const persistedUser = { @@ -171,7 +171,7 @@ describe('getUserData', function () { assert.deepStrictEqual(result, expectedUserData); }); - it('handles retrieving a user with an invalid URL', async function () { + it('handles retrieving a user with an invalid URL', async () => { const ctx = getCtx(); const persistedUser = { diff --git a/yarn.lock b/yarn.lock index ffe093ca..e224db12 100644 --- a/yarn.lock +++ b/yarn.lock @@ -30,6 +30,60 @@ resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== +"@biomejs/biome@1.9.1": + version "1.9.1" + resolved "https://registry.yarnpkg.com/@biomejs/biome/-/biome-1.9.1.tgz#93866252fb441687fdbed0a1b4e146e76ef7495e" + integrity sha512-Ps0Rg0zg3B1zpx+zQHMz5b0n0PBNCAaXttHEDTVrJD5YXR6Uj3T+abTDgeS3wsu4z5i2whqcE1lZxGyWH4bZYg== + optionalDependencies: + "@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": + version "1.9.1" + resolved "https://registry.yarnpkg.com/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-1.9.1.tgz#efa26ae2302350d3b00720cdda15576dfcf9cddd" + integrity sha512-js0brHswq/BoeKgfSEUJYOjUOlML6p65Nantti+PsoQ61u9+YVGIZ7325LK7iUpDH8KVJT+Bx7K2b/6Q//W1Pw== + +"@biomejs/cli-darwin-x64@1.9.1": + version "1.9.1" + resolved "https://registry.yarnpkg.com/@biomejs/cli-darwin-x64/-/cli-darwin-x64-1.9.1.tgz#a597b28d681483110c6aa7d28dcdefa0772b5450" + integrity sha512-2zVyjUg5rN0k8XrytkubQWLbp2r/AS5wPhXs4vgVjvqbLnzo32EGX8p61gzroF2dH9DCUCfskdrigCGqNdEbpg== + +"@biomejs/cli-linux-arm64-musl@1.9.1": + version "1.9.1" + resolved "https://registry.yarnpkg.com/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-1.9.1.tgz#d3d744c16060d09129b3e7c67697d54915c84342" + integrity sha512-L/JmXKvhsZ1lTgqOr3tWkzuY/NRppdIscHeC9aaiR72WjnBgJS94mawl9BWmGB3aWBc0q6oSDWnBS7617EMMmA== + +"@biomejs/cli-linux-arm64@1.9.1": + version "1.9.1" + resolved "https://registry.yarnpkg.com/@biomejs/cli-linux-arm64/-/cli-linux-arm64-1.9.1.tgz#aeece1d7842ae0389df14bc18ec7eeddffcb989c" + integrity sha512-QgxwfnG+r2aer5RNGR67Ey91Tv7xXW8E9YckHhwuyWjdLEvKWkrSJrhVG/6ub0kVvTSNkYOuT/7/jMOFBuUbRA== + +"@biomejs/cli-linux-x64-musl@1.9.1": + version "1.9.1" + resolved "https://registry.yarnpkg.com/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-1.9.1.tgz#e7ac315a22344394db5ec3385235d88a1449f649" + integrity sha512-gY+eFLIAW45v3WicQHicvjRfA0ntMZHx7h937bXwBMFNFoKmB6rMi6+fKQ6/hiS6juhsFxZdZIz20m15s49J6A== + +"@biomejs/cli-linux-x64@1.9.1": + version "1.9.1" + resolved "https://registry.yarnpkg.com/@biomejs/cli-linux-x64/-/cli-linux-x64-1.9.1.tgz#40f8c7aa55b95f3f74e3e4f57a07a3cc6dee2fef" + integrity sha512-F0INygtzI2L2n2R1KtYHGr3YWDt9Up1zrUluwembM+iJ1dXN3qzlSb7deFUsSJm4FaIPriqs6Xa56ukdQW6UeQ== + +"@biomejs/cli-win32-arm64@1.9.1": + version "1.9.1" + resolved "https://registry.yarnpkg.com/@biomejs/cli-win32-arm64/-/cli-win32-arm64-1.9.1.tgz#599f562fccbc9fd7e00dc3f43fb93ff3091f98e9" + integrity sha512-7Jahxar3OB+aTPOgXisMJmMKMsjcK+UmdlG3UIOQjzN/ZFEsPV+GT3bfrVjZDQaCw/zes0Cqd7VTWFjFTC/+MQ== + +"@biomejs/cli-win32-x64@1.9.1": + version "1.9.1" + resolved "https://registry.yarnpkg.com/@biomejs/cli-win32-x64/-/cli-win32-x64-1.9.1.tgz#f754bb8a94f2dab6311eff39dc30c4a6aa0f5628" + integrity sha512-liSRWjWzFhyG7s1jg/Bbv9FL+ha/CEd5tFO3+dFIJNplL4TnvAivtyfRVi/tu/pNjISbV1k9JwdBewtAKAgA0w== + "@colors/colors@1.5.0": version "1.5.0" resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.5.0.tgz#bb504579c1cae923e6576a4f5da43d25f97bdbd9" @@ -2765,16 +2819,7 @@ string-argv@0.3.1: resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.3.1.tgz#95e2fbec0427ae19184935f816d74aaa4c5c19da" integrity sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg== -"string-width-cjs@npm:string-width@^4.2.0": - version "4.2.3" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - -string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: +"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -2792,14 +2837,7 @@ string-width@^5.0.1, string-width@^5.1.2: emoji-regex "^9.2.2" strip-ansi "^7.0.1" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1": - version "6.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - -strip-ansi@6.0.1, strip-ansi@^6.0.0, strip-ansi@^6.0.1: +"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@6.0.1, strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== @@ -3063,16 +3101,7 @@ workerpool@6.2.1: resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.1.tgz#46fc150c17d826b86a008e5a4508656777e9c343" integrity sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw== -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - -wrap-ansi@^7.0.0: +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==