From 5215c73166505ba458916f2bf09231b74e6fc90f Mon Sep 17 00:00:00 2001 From: donqu1xotevincent Date: Thu, 26 Feb 2026 19:49:50 +0800 Subject: [PATCH 01/49] chore(ios): update description (#14522) --- .../apps/ios/App/App/AffineViewController+AIButton.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/frontend/apps/ios/App/App/AffineViewController+AIButton.swift b/packages/frontend/apps/ios/App/App/AffineViewController+AIButton.swift index 938b580b6f..5edf6cfd53 100644 --- a/packages/frontend/apps/ios/App/App/AffineViewController+AIButton.swift +++ b/packages/frontend/apps/ios/App/App/AffineViewController+AIButton.swift @@ -31,7 +31,7 @@ extension AFFiNEViewController: IntelligentsButtonDelegate { private func showAIConsentAlert() { let alert = UIAlertController( title: "AI Feature Data Usage", - message: "To provide AI-powered features, your input (such as document content and conversation messages) will be sent to a third-party AI service for processing. This data is used solely to generate responses and is not used for any other purpose.\n\nBy continuing, you agree to share this data with the AI service.", + message: "To provide AI-powered features, your input (such as document content and conversation messages) will be sent to our third-party AI service providers (Google Gemini, Anthropic Claude, or OpenAI) for processing. This data is used solely to generate responses and is not used for any other purpose.\n\nBy continuing, you agree to share this data with these AI services.", preferredStyle: .alert ) alert.addAction(UIAlertAction(title: "Cancel", style: .cancel)) From 11cf1928b5ca856829bff0cfca638a3c4dc42477 Mon Sep 17 00:00:00 2001 From: DarkSky <25152247+darkskygit@users.noreply.github.com> Date: Thu, 26 Feb 2026 19:53:22 +0800 Subject: [PATCH 02/49] fix(server): transaction error (#14518) ## Summary by CodeRabbit * **New Features** * Events can be dispatched in a detached context to avoid inheriting the current transaction. * **Bug Fixes** * Improved resilience and error handling for event processing (graceful handling of deleted workspaces and ignorable DB errors). * More reliable owner assignment flow when changing document owners. * **Tests** * Added tests for doc content staleness with deleted workspaces. * Added permission event tests for missing workspace/editor scenarios. --- .../src/__tests__/mocks/eventbus.mock.ts | 1 + .../backend/server/src/base/event/eventbus.ts | 31 ++++++-- .../src/core/doc/__tests__/event.spec.ts | 21 ++++- .../server/src/core/doc/adapters/workspace.ts | 4 +- packages/backend/server/src/core/doc/event.ts | 59 +++++++++++--- .../core/permission/__tests__/event.spec.ts | 77 +++++++++++++++++++ .../server/src/core/permission/event.ts | 48 +++++++++++- .../backend/server/src/models/doc-user.ts | 37 +++------ 8 files changed, 228 insertions(+), 50 deletions(-) create mode 100644 packages/backend/server/src/core/permission/__tests__/event.spec.ts diff --git a/packages/backend/server/src/__tests__/mocks/eventbus.mock.ts b/packages/backend/server/src/__tests__/mocks/eventbus.mock.ts index c9f887b22f..9a09b59fc5 100644 --- a/packages/backend/server/src/__tests__/mocks/eventbus.mock.ts +++ b/packages/backend/server/src/__tests__/mocks/eventbus.mock.ts @@ -8,6 +8,7 @@ export class MockEventBus { emit = this.stub.emitAsync; emitAsync = this.stub.emitAsync; + emitDetached = this.stub.emitAsync; broadcast = this.stub.broadcast; last( diff --git a/packages/backend/server/src/base/event/eventbus.ts b/packages/backend/server/src/base/event/eventbus.ts index 7d8c46ff61..cb90ba3ad5 100644 --- a/packages/backend/server/src/base/event/eventbus.ts +++ b/packages/backend/server/src/base/event/eventbus.ts @@ -88,12 +88,21 @@ export class EventBus emit(event: T, payload: Events[T]) { this.logger.debug(`Dispatch event: ${event}`); - // NOTE(@forehalo): - // Because all event handlers are wrapped in promisified metrics and cls context, they will always run in standalone tick. - // In which way, if handler throws, an unhandled rejection will be triggered and end up with process exiting. - // So we catch it here with `emitAsync` - this.emitter.emitAsync(event, payload).catch(e => { - this.emitter.emit('error', { event, payload, error: e }); + this.dispatchAsync(event, payload); + + return true; + } + + /** + * Emit event in detached cls context to avoid inheriting current transaction. + */ + emitDetached(event: T, payload: Events[T]) { + this.logger.debug(`Dispatch event: ${event} (detached)`); + + const requestId = this.cls.getId(); + this.cls.run({ ifNested: 'override' }, () => { + this.cls.set(CLS_ID, requestId ?? genRequestId('event')); + this.dispatchAsync(event, payload); }); return true; @@ -166,6 +175,16 @@ export class EventBus return this.emitter.waitFor(name, timeout); } + private dispatchAsync(event: T, payload: Events[T]) { + // NOTE: + // Because all event handlers are wrapped in promisified metrics and cls context, they will always run in standalone tick. + // In which way, if handler throws, an unhandled rejection will be triggered and end up with process exiting. + // So we catch it here with `emitAsync` + this.emitter.emitAsync(event, payload).catch(e => { + this.emitter.emit('error', { event, payload, error: e }); + }); + } + private readonly bindEventHandlers = once(() => { this.scanner.scan().forEach(({ event, handler, opts }) => { this.on(event, handler, opts); diff --git a/packages/backend/server/src/core/doc/__tests__/event.spec.ts b/packages/backend/server/src/core/doc/__tests__/event.spec.ts index d1483b90c1..eea4402b55 100644 --- a/packages/backend/server/src/core/doc/__tests__/event.spec.ts +++ b/packages/backend/server/src/core/doc/__tests__/event.spec.ts @@ -68,7 +68,7 @@ test('should update doc content to database when doc is updated', async t => { const docId = randomUUID(); await adapter.pushDocUpdates(workspace.id, docId, updates); - await adapter.getDoc(workspace.id, docId); + await adapter.getDocBinNative(workspace.id, docId); mock.method(docReader, 'parseDocContent', () => { return { @@ -181,3 +181,22 @@ test('should ignore update workspace content to database when parse workspace co t.is(content!.name, null); t.is(content!.avatarKey, null); }); + +test('should ignore stale workspace when updating doc meta from snapshot event', async t => { + const { docReader, listener, models } = t.context; + const docId = randomUUID(); + mock.method(docReader, 'parseDocContent', () => ({ + title: 'test title', + summary: 'test summary', + })); + + await models.workspace.delete(workspace.id); + + await t.notThrowsAsync(async () => { + await listener.markDocContentCacheStale({ + workspaceId: workspace.id, + docId, + blob: Buffer.from([0x01]), + }); + }); +}); diff --git a/packages/backend/server/src/core/doc/adapters/workspace.ts b/packages/backend/server/src/core/doc/adapters/workspace.ts index 6e8ce11af9..ae00fb5986 100644 --- a/packages/backend/server/src/core/doc/adapters/workspace.ts +++ b/packages/backend/server/src/core/doc/adapters/workspace.ts @@ -110,7 +110,7 @@ export class PgWorkspaceDocStorageAdapter extends DocStorageAdapter { }); if (isNewDoc) { - this.event.emit('doc.created', { + this.event.emitDetached('doc.created', { workspaceId, docId, editor: editorId, @@ -334,7 +334,7 @@ export class PgWorkspaceDocStorageAdapter extends DocStorageAdapter { }); if (updatedSnapshot) { - this.event.emit('doc.snapshot.updated', { + this.event.emitDetached('doc.snapshot.updated', { workspaceId: snapshot.spaceId, docId: snapshot.docId, blob, diff --git a/packages/backend/server/src/core/doc/event.ts b/packages/backend/server/src/core/doc/event.ts index a9982fa954..c3d42c068d 100644 --- a/packages/backend/server/src/core/doc/event.ts +++ b/packages/backend/server/src/core/doc/event.ts @@ -1,12 +1,29 @@ -import { Injectable } from '@nestjs/common'; +import { Injectable, Logger } from '@nestjs/common'; +import { Prisma } from '@prisma/client'; import { OnEvent } from '../../base'; import { Models } from '../../models'; import { PgWorkspaceDocStorageAdapter } from './adapters/workspace'; import { DocReader } from './reader'; +const IGNORED_PRISMA_CODES = new Set(['P2003', 'P2025', 'P2028']); + +function isIgnorableDocEventError(error: unknown) { + if (error instanceof Prisma.PrismaClientKnownRequestError) { + return IGNORED_PRISMA_CODES.has(error.code); + } + if (error instanceof Prisma.PrismaClientUnknownRequestError) { + return /transaction is aborted|transaction already closed/i.test( + error.message + ); + } + return false; +} + @Injectable() export class DocEventsListener { + private readonly logger = new Logger(DocEventsListener.name); + constructor( private readonly docReader: DocReader, private readonly models: Models, @@ -20,21 +37,39 @@ export class DocEventsListener { blob, }: Events['doc.snapshot.updated']) { await this.docReader.markDocContentCacheStale(workspaceId, docId); + const workspace = await this.models.workspace.get(workspaceId); + if (!workspace) { + this.logger.warn( + `Skip stale doc snapshot event for missing workspace ${workspaceId}/${docId}` + ); + return; + } const isDoc = workspaceId !== docId; // update doc content to database - if (isDoc) { - const content = this.docReader.parseDocContent(blob); - if (!content) { + try { + if (isDoc) { + const content = this.docReader.parseDocContent(blob); + if (!content) { + return; + } + await this.models.doc.upsertMeta(workspaceId, docId, content); + } else { + // update workspace content to database + const content = this.docReader.parseWorkspaceContent(blob); + if (!content) { + return; + } + await this.models.workspace.update(workspaceId, content); + } + } catch (error) { + if (isIgnorableDocEventError(error)) { + const message = error instanceof Error ? error.message : String(error); + this.logger.warn( + `Ignore stale doc snapshot event for ${workspaceId}/${docId}: ${message}` + ); return; } - await this.models.doc.upsertMeta(workspaceId, docId, content); - } else { - // update workspace content to database - const content = this.docReader.parseWorkspaceContent(blob); - if (!content) { - return; - } - await this.models.workspace.update(workspaceId, content); + throw error; } } diff --git a/packages/backend/server/src/core/permission/__tests__/event.spec.ts b/packages/backend/server/src/core/permission/__tests__/event.spec.ts new file mode 100644 index 0000000000..21803c0532 --- /dev/null +++ b/packages/backend/server/src/core/permission/__tests__/event.spec.ts @@ -0,0 +1,77 @@ +import { randomUUID } from 'node:crypto'; + +import ava, { TestFn } from 'ava'; + +import { + createTestingModule, + type TestingModule, +} from '../../../__tests__/utils'; +import { DocRole, Models, User, Workspace } from '../../../models'; +import { EventsListener } from '../event'; +import { PermissionModule } from '../index'; + +interface Context { + module: TestingModule; + models: Models; + listener: EventsListener; +} + +const test = ava as TestFn; + +let owner: User; +let workspace: Workspace; + +test.before(async t => { + const module = await createTestingModule({ imports: [PermissionModule] }); + t.context.module = module; + t.context.models = module.get(Models); + t.context.listener = module.get(EventsListener); +}); + +test.beforeEach(async t => { + await t.context.module.initTestingDB(); + owner = await t.context.models.user.create({ + email: `${randomUUID()}@affine.pro`, + }); + workspace = await t.context.models.workspace.create(owner.id); +}); + +test.after.always(async t => { + await t.context.module.close(); +}); + +test('should ignore default owner event when workspace does not exist', async t => { + await t.notThrowsAsync(async () => { + await t.context.listener.setDefaultPageOwner({ + workspaceId: randomUUID(), + docId: randomUUID(), + editor: owner.id, + }); + }); +}); + +test('should ignore default owner event when editor does not exist', async t => { + await t.notThrowsAsync(async () => { + await t.context.listener.setDefaultPageOwner({ + workspaceId: workspace.id, + docId: randomUUID(), + editor: randomUUID(), + }); + }); +}); + +test('should set owner when workspace and editor exist', async t => { + const docId = randomUUID(); + await t.context.listener.setDefaultPageOwner({ + workspaceId: workspace.id, + docId, + editor: owner.id, + }); + + const role = await t.context.models.docUser.get( + workspace.id, + docId, + owner.id + ); + t.is(role?.type, DocRole.Owner); +}); diff --git a/packages/backend/server/src/core/permission/event.ts b/packages/backend/server/src/core/permission/event.ts index 4e6651a145..442fd6877a 100644 --- a/packages/backend/server/src/core/permission/event.ts +++ b/packages/backend/server/src/core/permission/event.ts @@ -1,10 +1,27 @@ -import { Injectable } from '@nestjs/common'; +import { Injectable, Logger } from '@nestjs/common'; +import { Prisma } from '@prisma/client'; import { OnEvent } from '../../base'; import { Models } from '../../models'; +const IGNORED_PRISMA_CODES = new Set(['P2003', 'P2025', 'P2028']); + +function isIgnorablePermissionEventError(error: unknown) { + if (error instanceof Prisma.PrismaClientKnownRequestError) { + return IGNORED_PRISMA_CODES.has(error.code); + } + if (error instanceof Prisma.PrismaClientUnknownRequestError) { + return /transaction is aborted|transaction already closed/i.test( + error.message + ); + } + return false; +} + @Injectable() export class EventsListener { + private readonly logger = new Logger(EventsListener.name); + constructor(private readonly models: Models) {} @OnEvent('doc.created') @@ -15,6 +32,33 @@ export class EventsListener { return; } - await this.models.docUser.setOwner(workspaceId, docId, editor); + const workspace = await this.models.workspace.get(workspaceId); + if (!workspace) { + this.logger.warn( + `Skip default doc owner event for missing workspace ${workspaceId}/${docId}` + ); + return; + } + + const user = await this.models.user.get(editor); + if (!user) { + this.logger.warn( + `Skip default doc owner event for missing editor ${workspaceId}/${docId}/${editor}` + ); + return; + } + + try { + await this.models.docUser.setOwner(workspaceId, docId, editor); + } catch (error) { + if (isIgnorablePermissionEventError(error)) { + const message = error instanceof Error ? error.message : String(error); + this.logger.warn( + `Ignore stale doc owner event for ${workspaceId}/${docId}/${editor}: ${message}` + ); + return; + } + throw error; + } } } diff --git a/packages/backend/server/src/models/doc-user.ts b/packages/backend/server/src/models/doc-user.ts index d8a71e3bda..f189fd5d01 100644 --- a/packages/backend/server/src/models/doc-user.ts +++ b/packages/backend/server/src/models/doc-user.ts @@ -2,6 +2,7 @@ import assert from 'node:assert'; import { Injectable } from '@nestjs/common'; import { Transactional } from '@nestjs-cls/transactional'; +import type { TransactionalAdapterPrisma } from '@nestjs-cls/transactional-adapter-prisma'; import { WorkspaceDocUserRole } from '@prisma/client'; import { CanNotBatchGrantDocOwnerPermissions, PaginationInput } from '../base'; @@ -14,31 +15,20 @@ export class DocUserModel extends BaseModel { * Set or update the [Owner] of a doc. * The old [Owner] will be changed to [Manager] if there is already an [Owner]. */ - @Transactional() + @Transactional({ timeout: 15000 }) async setOwner(workspaceId: string, docId: string, userId: string) { - const oldOwner = await this.db.workspaceDocUserRole.findFirst({ + await this.db.workspaceDocUserRole.updateMany({ where: { workspaceId, docId, type: DocRole.Owner, + userId: { not: userId }, + }, + data: { + type: DocRole.Manager, }, }); - if (oldOwner) { - await this.db.workspaceDocUserRole.update({ - where: { - workspaceId_docId_userId: { - workspaceId, - docId, - userId: oldOwner.userId, - }, - }, - data: { - type: DocRole.Manager, - }, - }); - } - await this.db.workspaceDocUserRole.upsert({ where: { workspaceId_docId_userId: { @@ -57,16 +47,9 @@ export class DocUserModel extends BaseModel { type: DocRole.Owner, }, }); - - if (oldOwner) { - this.logger.log( - `Transfer doc owner of [${workspaceId}/${docId}] from [${oldOwner.userId}] to [${userId}]` - ); - } else { - this.logger.log( - `Set doc owner of [${workspaceId}/${docId}] to [${userId}]` - ); - } + this.logger.log( + `Set doc owner of [${workspaceId}/${docId}] to [${userId}]` + ); } /** From bdccf4e9fd9a20807676d5e8ded59d5731a80ecd Mon Sep 17 00:00:00 2001 From: DarkSky Date: Fri, 27 Feb 2026 10:20:35 +0800 Subject: [PATCH 03/49] fix: typo --- .../apps/ios/App/App/AffineViewController+AIButton.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/frontend/apps/ios/App/App/AffineViewController+AIButton.swift b/packages/frontend/apps/ios/App/App/AffineViewController+AIButton.swift index 5edf6cfd53..49d4fbb35b 100644 --- a/packages/frontend/apps/ios/App/App/AffineViewController+AIButton.swift +++ b/packages/frontend/apps/ios/App/App/AffineViewController+AIButton.swift @@ -31,7 +31,7 @@ extension AFFiNEViewController: IntelligentsButtonDelegate { private func showAIConsentAlert() { let alert = UIAlertController( title: "AI Feature Data Usage", - message: "To provide AI-powered features, your input (such as document content and conversation messages) will be sent to our third-party AI service providers (Google Gemini, Anthropic Claude, or OpenAI) for processing. This data is used solely to generate responses and is not used for any other purpose.\n\nBy continuing, you agree to share this data with these AI services.", + message: "To provide AI-powered features, your input (such as document content and conversation messages) will be sent to our third-party AI service providers (Google, Anthropic, or OpenAI, based on your choice) for processing. This data is used solely to generate responses and is not used for any other purpose.\n\nBy continuing, you agree to share this data with these AI services.", preferredStyle: .alert ) alert.addAction(UIAlertAction(title: "Cancel", style: .cancel)) From e1e0ac234561e82fb8e88f370555fa4ecd5e55af Mon Sep 17 00:00:00 2001 From: DarkSky <25152247+darkskygit@users.noreply.github.com> Date: Fri, 27 Feb 2026 11:56:54 +0800 Subject: [PATCH 04/49] chore: cleanup deps (#14525) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #### PR Dependency Tree * **PR #14525** 👈 This tree was auto-generated by [Charcoal](https://github.com/danerwilliams/charcoal) ## Summary by CodeRabbit * **Chores** * Removed an unused development dependency. * Updated dotLottie/Lottie-related dependency versions across packages and replaced a removed player dependency with the new package. * **Refactor** * AI animated icons now re-export from a shared component and are loaded only in the browser, reducing upfront bundle weight and centralizing icon assets. --- blocksuite/affine/components/package.json | 2 +- blocksuite/integration-test/package.json | 2 +- packages/backend/server/package.json | 1 - packages/frontend/core/package.json | 2 +- .../core/src/blocksuite/ai/_common/icons.ts | 56 +- yarn.lock | 2080 ++--------------- 6 files changed, 181 insertions(+), 1962 deletions(-) diff --git a/blocksuite/affine/components/package.json b/blocksuite/affine/components/package.json index f8ff653f24..e7fdcfb021 100644 --- a/blocksuite/affine/components/package.json +++ b/blocksuite/affine/components/package.json @@ -19,7 +19,7 @@ "@blocksuite/sync": "workspace:*", "@floating-ui/dom": "^1.6.13", "@lit/context": "^1.1.2", - "@lottiefiles/dotlottie-wc": "^0.5.0", + "@lottiefiles/dotlottie-wc": "^0.9.4", "@preact/signals-core": "^1.8.0", "@toeverything/theme": "^1.1.23", "@types/hast": "^3.0.4", diff --git a/blocksuite/integration-test/package.json b/blocksuite/integration-test/package.json index b010902722..d131b8e20d 100644 --- a/blocksuite/integration-test/package.json +++ b/blocksuite/integration-test/package.json @@ -17,7 +17,7 @@ "@blocksuite/icons": "^2.2.17", "@floating-ui/dom": "^1.6.13", "@lit/context": "^1.1.3", - "@lottiefiles/dotlottie-wc": "^0.5.0", + "@lottiefiles/dotlottie-wc": "^0.9.4", "@preact/signals-core": "^1.8.0", "@toeverything/theme": "^1.1.23", "@vanilla-extract/css": "^1.17.0", diff --git a/packages/backend/server/package.json b/packages/backend/server/package.json index 60f9343ae5..9c6d6cf9f9 100644 --- a/packages/backend/server/package.json +++ b/packages/backend/server/package.json @@ -126,7 +126,6 @@ "@faker-js/faker": "^10.1.0", "@nestjs/swagger": "^11.2.0", "@nestjs/testing": "patch:@nestjs/testing@npm%3A10.4.15#~/.yarn/patches/@nestjs-testing-npm-10.4.15-d591a1705a.patch", - "@react-email/preview-server": "^4.3.2", "@types/cookie-parser": "^1.4.8", "@types/express": "^5.0.1", "@types/express-serve-static-core": "^5.0.6", diff --git a/packages/frontend/core/package.json b/packages/frontend/core/package.json index 359bfbfcad..8bb8fc4ee9 100644 --- a/packages/frontend/core/package.json +++ b/packages/frontend/core/package.json @@ -26,13 +26,13 @@ "@blocksuite/global": "workspace:*", "@blocksuite/icons": "^2.2.17", "@blocksuite/std": "workspace:*", - "@dotlottie/player-component": "^2.7.12", "@emotion/cache": "^11.14.0", "@emotion/css": "^11.13.5", "@emotion/react": "^11.14.0", "@floating-ui/dom": "^1.6.13", "@juggle/resize-observer": "^3.4.0", "@lit/context": "^1.1.4", + "@lottiefiles/dotlottie-wc": "^0.9.4", "@marsidev/react-turnstile": "^1.1.0", "@myriaddreamin/typst-ts-renderer": "^0.7.0-rc2", "@myriaddreamin/typst-ts-web-compiler": "^0.7.0-rc2", diff --git a/packages/frontend/core/src/blocksuite/ai/_common/icons.ts b/packages/frontend/core/src/blocksuite/ai/_common/icons.ts index ad3035e78e..892564642d 100644 --- a/packages/frontend/core/src/blocksuite/ai/_common/icons.ts +++ b/packages/frontend/core/src/blocksuite/ai/_common/icons.ts @@ -1,15 +1,11 @@ -import '@dotlottie/player-component'; - import { html } from 'lit'; -export const AIStarIconWithAnimation = html``; +export { AIStarIconWithAnimation } from '@blocksuite/affine/components/icons'; + +// dotlottie-wc can only be used in the browser +if (typeof window !== 'undefined') { + import('@lottiefiles/dotlottie-wc').catch(console.error); +} export const AffineIcon = (color: string) => html` `; -export const AIPenIconWithAnimation = html``; +>`; -export const AIPresentationIconWithAnimation = html``; +>`; -export const AIMindMapIconWithAnimation = html``; +>`; -export const AIImageIconWithAnimation = html``; +>`; -export const MakeItRealIconWithAnimation = html``; +>`; diff --git a/yarn.lock b/yarn.lock index 20bf7bf969..c8389b4b5c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -418,13 +418,13 @@ __metadata: "@blocksuite/global": "workspace:*" "@blocksuite/icons": "npm:^2.2.17" "@blocksuite/std": "workspace:*" - "@dotlottie/player-component": "npm:^2.7.12" "@emotion/cache": "npm:^11.14.0" "@emotion/css": "npm:^11.13.5" "@emotion/react": "npm:^11.14.0" "@floating-ui/dom": "npm:^1.6.13" "@juggle/resize-observer": "npm:^3.4.0" "@lit/context": "npm:^1.1.4" + "@lottiefiles/dotlottie-wc": "npm:^0.9.4" "@marsidev/react-turnstile": "npm:^1.1.0" "@myriaddreamin/typst-ts-renderer": "npm:^0.7.0-rc2" "@myriaddreamin/typst-ts-web-compiler": "npm:^0.7.0-rc2" @@ -1021,7 +1021,6 @@ __metadata: "@prisma/instrumentation": "npm:^6.7.0" "@queuedash/api": "npm:^3.16.0" "@react-email/components": "npm:^0.5.7" - "@react-email/preview-server": "npm:^4.3.2" "@socket.io/redis-adapter": "npm:^8.3.0" "@types/cookie-parser": "npm:^1.4.8" "@types/express": "npm:^5.0.1" @@ -1258,16 +1257,6 @@ __metadata: languageName: node linkType: hard -"@ampproject/remapping@npm:^2.2.0": - version: 2.3.0 - resolution: "@ampproject/remapping@npm:2.3.0" - dependencies: - "@jridgewell/gen-mapping": "npm:^0.3.5" - "@jridgewell/trace-mapping": "npm:^0.3.24" - checksum: 10/f3451525379c68a73eb0a1e65247fbf28c0cccd126d93af21c75fceff77773d43c0d4a2d51978fb131aff25b5f2cb41a9fe48cc296e61ae65e679c4f6918b0ab - languageName: node - linkType: hard - "@antfu/install-pkg@npm:^1.1.0": version: 1.1.0 resolution: "@antfu/install-pkg@npm:1.1.0" @@ -1588,7 +1577,7 @@ __metadata: languageName: node linkType: hard -"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.10.4, @babel/code-frame@npm:^7.26.2, @babel/code-frame@npm:^7.28.6, @babel/code-frame@npm:^7.29.0": +"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.10.4, @babel/code-frame@npm:^7.28.6, @babel/code-frame@npm:^7.29.0": version: 7.29.0 resolution: "@babel/code-frame@npm:7.29.0" dependencies: @@ -1606,29 +1595,6 @@ __metadata: languageName: node linkType: hard -"@babel/core@npm:7.26.10": - version: 7.26.10 - resolution: "@babel/core@npm:7.26.10" - dependencies: - "@ampproject/remapping": "npm:^2.2.0" - "@babel/code-frame": "npm:^7.26.2" - "@babel/generator": "npm:^7.26.10" - "@babel/helper-compilation-targets": "npm:^7.26.5" - "@babel/helper-module-transforms": "npm:^7.26.0" - "@babel/helpers": "npm:^7.26.10" - "@babel/parser": "npm:^7.26.10" - "@babel/template": "npm:^7.26.9" - "@babel/traverse": "npm:^7.26.10" - "@babel/types": "npm:^7.26.10" - convert-source-map: "npm:^2.0.0" - debug: "npm:^4.1.0" - gensync: "npm:^1.0.0-beta.2" - json5: "npm:^2.2.3" - semver: "npm:^6.3.1" - checksum: 10/68f6707eebd6bb8beed7ceccf5153e35b86c323e40d11d796d75c626ac8f1cc4e1f795584c5ab5f886bc64150c22d5088123d68c069c63f29984c4fc054d1dab - languageName: node - linkType: hard - "@babel/core@npm:^7.12.3, @babel/core@npm:^7.18.5, @babel/core@npm:^7.23.9, @babel/core@npm:^7.24.4, @babel/core@npm:^7.26.10, @babel/core@npm:^7.28.0, @babel/core@npm:^7.28.5": version: 7.29.0 resolution: "@babel/core@npm:7.29.0" @@ -1652,7 +1618,7 @@ __metadata: languageName: node linkType: hard -"@babel/generator@npm:^7.18.13, @babel/generator@npm:^7.26.10, @babel/generator@npm:^7.27.0, @babel/generator@npm:^7.28.0, @babel/generator@npm:^7.29.0": +"@babel/generator@npm:^7.18.13, @babel/generator@npm:^7.26.10, @babel/generator@npm:^7.28.0, @babel/generator@npm:^7.29.0": version: 7.29.1 resolution: "@babel/generator@npm:7.29.1" dependencies: @@ -1665,7 +1631,7 @@ __metadata: languageName: node linkType: hard -"@babel/helper-compilation-targets@npm:^7.26.5, @babel/helper-compilation-targets@npm:^7.28.6": +"@babel/helper-compilation-targets@npm:^7.28.6": version: 7.28.6 resolution: "@babel/helper-compilation-targets@npm:7.28.6" dependencies: @@ -1695,7 +1661,7 @@ __metadata: languageName: node linkType: hard -"@babel/helper-module-transforms@npm:^7.26.0, @babel/helper-module-transforms@npm:^7.28.6": +"@babel/helper-module-transforms@npm:^7.28.6": version: 7.28.6 resolution: "@babel/helper-module-transforms@npm:7.28.6" dependencies: @@ -1736,7 +1702,7 @@ __metadata: languageName: node linkType: hard -"@babel/helpers@npm:^7.26.10, @babel/helpers@npm:^7.28.6": +"@babel/helpers@npm:^7.28.6": version: 7.28.6 resolution: "@babel/helpers@npm:7.28.6" dependencies: @@ -1746,17 +1712,6 @@ __metadata: languageName: node linkType: hard -"@babel/parser@npm:7.27.0": - version: 7.27.0 - resolution: "@babel/parser@npm:7.27.0" - dependencies: - "@babel/types": "npm:^7.27.0" - bin: - parser: ./bin/babel-parser.js - checksum: 10/0fee9f05c6db753882ca9d10958301493443da9f6986d7020ebd7a696b35886240016899bc0b47d871aea2abcafd64632343719742e87432c8145e0ec2af2a03 - languageName: node - linkType: hard - "@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.20.7, @babel/parser@npm:^7.23.9, @babel/parser@npm:^7.24.4, @babel/parser@npm:^7.25.4, @babel/parser@npm:^7.26.10, @babel/parser@npm:^7.27.0, @babel/parser@npm:^7.28.6, @babel/parser@npm:^7.29.0": version: 7.29.0 resolution: "@babel/parser@npm:7.29.0" @@ -1841,7 +1796,7 @@ __metadata: languageName: node linkType: hard -"@babel/template@npm:^7.18.10, @babel/template@npm:^7.20.7, @babel/template@npm:^7.26.9, @babel/template@npm:^7.27.0, @babel/template@npm:^7.28.6": +"@babel/template@npm:^7.18.10, @babel/template@npm:^7.20.7, @babel/template@npm:^7.28.6": version: 7.28.6 resolution: "@babel/template@npm:7.28.6" dependencies: @@ -1852,21 +1807,6 @@ __metadata: languageName: node linkType: hard -"@babel/traverse@npm:7.27.0": - version: 7.27.0 - resolution: "@babel/traverse@npm:7.27.0" - dependencies: - "@babel/code-frame": "npm:^7.26.2" - "@babel/generator": "npm:^7.27.0" - "@babel/parser": "npm:^7.27.0" - "@babel/template": "npm:^7.27.0" - "@babel/types": "npm:^7.27.0" - debug: "npm:^4.3.1" - globals: "npm:^11.1.0" - checksum: 10/b0675bc16bd87187e8b090557b0650135de56a621692ad8614b20f32621350ae0fc2e1129b73b780d64a9ed4beab46849a17f90d5267b6ae6ce09ec8412a12c7 - languageName: node - linkType: hard - "@babel/traverse@npm:^7.26.10, @babel/traverse@npm:^7.27.0, @babel/traverse@npm:^7.28.0, @babel/traverse@npm:^7.28.6, @babel/traverse@npm:^7.29.0": version: 7.29.0 resolution: "@babel/traverse@npm:7.29.0" @@ -1882,7 +1822,7 @@ __metadata: languageName: node linkType: hard -"@babel/types@npm:^7.0.0, @babel/types@npm:^7.18.13, @babel/types@npm:^7.20.7, @babel/types@npm:^7.25.4, @babel/types@npm:^7.26.10, @babel/types@npm:^7.27.0, @babel/types@npm:^7.28.2, @babel/types@npm:^7.28.6, @babel/types@npm:^7.29.0": +"@babel/types@npm:^7.0.0, @babel/types@npm:^7.18.13, @babel/types@npm:^7.20.7, @babel/types@npm:^7.25.4, @babel/types@npm:^7.26.10, @babel/types@npm:^7.28.2, @babel/types@npm:^7.28.6, @babel/types@npm:^7.29.0": version: 7.29.0 resolution: "@babel/types@npm:7.29.0" dependencies: @@ -2499,7 +2439,7 @@ __metadata: "@blocksuite/sync": "workspace:*" "@floating-ui/dom": "npm:^1.6.13" "@lit/context": "npm:^1.1.2" - "@lottiefiles/dotlottie-wc": "npm:^0.5.0" + "@lottiefiles/dotlottie-wc": "npm:^0.9.4" "@preact/signals-core": "npm:^1.8.0" "@toeverything/theme": "npm:^1.1.23" "@types/hast": "npm:^3.0.4" @@ -3810,7 +3750,7 @@ __metadata: "@blocksuite/icons": "npm:^2.2.17" "@floating-ui/dom": "npm:^1.6.13" "@lit/context": "npm:^1.1.3" - "@lottiefiles/dotlottie-wc": "npm:^0.5.0" + "@lottiefiles/dotlottie-wc": "npm:^0.9.4" "@preact/signals-core": "npm:^1.8.0" "@toeverything/theme": "npm:^1.1.23" "@vanilla-extract/css": "npm:^1.17.0" @@ -4350,42 +4290,6 @@ __metadata: languageName: node linkType: hard -"@dotlottie/common@npm:0.7.11": - version: 0.7.11 - resolution: "@dotlottie/common@npm:0.7.11" - dependencies: - "@dotlottie/dotlottie-js": "npm:^0.7.0" - "@preact/signals-core": "npm:^1.2.3" - howler: "npm:^2.2.3" - lottie-web: "npm:^5.12.2" - xstate: "npm:^4.38.1" - checksum: 10/b82030323b237629e9dfb906f3aec4f148390aebe748201adaa6fc66c569d6da885814ac00b177948c9e5fd9ace123bc04eadd42368a59110dc0abac72888b24 - languageName: node - linkType: hard - -"@dotlottie/dotlottie-js@npm:^0.7.0": - version: 0.7.2 - resolution: "@dotlottie/dotlottie-js@npm:0.7.2" - dependencies: - browser-image-hash: "npm:^0.0.5" - fflate: "npm:^0.8.1" - sharp: "npm:^0.33.2" - sharp-phash: "npm:^2.1.0" - valibot: "npm:^0.13.1" - checksum: 10/349f2e2cfb67dcd918ba6f8fc755c7505a9700528c2f06622da5a9dbd6c5bf6565c04979e8bf925e29c93c82c456b5b9b3bb64e55ec6567c0c5fff461be17563 - languageName: node - linkType: hard - -"@dotlottie/player-component@npm:^2.7.12": - version: 2.7.12 - resolution: "@dotlottie/player-component@npm:2.7.12" - dependencies: - "@dotlottie/common": "npm:0.7.11" - lit: "npm:^2.7.5" - checksum: 10/d34652776090bba7982bcdd7371d20fca2c0c8f74c4a13319db730953703af38bd706265d60b6f7cacffe085079d9e4a7912522ed255fad2159175e199339455 - languageName: node - linkType: hard - "@electron-forge/cli@npm:^7.10.2": version: 7.10.2 resolution: "@electron-forge/cli@npm:7.10.2" @@ -4940,7 +4844,7 @@ __metadata: languageName: node linkType: hard -"@emnapi/runtime@npm:^1.2.0, @emnapi/runtime@npm:^1.4.3, @emnapi/runtime@npm:^1.5.0, @emnapi/runtime@npm:^1.7.0, @emnapi/runtime@npm:^1.7.1": +"@emnapi/runtime@npm:^1.4.3, @emnapi/runtime@npm:^1.5.0, @emnapi/runtime@npm:^1.7.1": version: 1.8.1 resolution: "@emnapi/runtime@npm:1.8.1" dependencies: @@ -6679,609 +6583,6 @@ __metadata: languageName: node linkType: hard -"@img/colour@npm:^1.0.0": - version: 1.0.0 - resolution: "@img/colour@npm:1.0.0" - checksum: 10/bd248d7c4b8ba99a72b22a005a63f1d3309ee8343a74b6d0d1314bae300a3096919991a09e9a9243cf6ca50e393b4c5a7e065488ed616c3b58d052473240b812 - languageName: node - linkType: hard - -"@img/sharp-darwin-arm64@npm:0.33.5": - version: 0.33.5 - resolution: "@img/sharp-darwin-arm64@npm:0.33.5" - dependencies: - "@img/sharp-libvips-darwin-arm64": "npm:1.0.4" - dependenciesMeta: - "@img/sharp-libvips-darwin-arm64": - optional: true - conditions: os=darwin & cpu=arm64 - languageName: node - linkType: hard - -"@img/sharp-darwin-arm64@npm:0.34.4": - version: 0.34.4 - resolution: "@img/sharp-darwin-arm64@npm:0.34.4" - dependencies: - "@img/sharp-libvips-darwin-arm64": "npm:1.2.3" - dependenciesMeta: - "@img/sharp-libvips-darwin-arm64": - optional: true - conditions: os=darwin & cpu=arm64 - languageName: node - linkType: hard - -"@img/sharp-darwin-arm64@npm:0.34.5": - version: 0.34.5 - resolution: "@img/sharp-darwin-arm64@npm:0.34.5" - dependencies: - "@img/sharp-libvips-darwin-arm64": "npm:1.2.4" - dependenciesMeta: - "@img/sharp-libvips-darwin-arm64": - optional: true - conditions: os=darwin & cpu=arm64 - languageName: node - linkType: hard - -"@img/sharp-darwin-x64@npm:0.33.5": - version: 0.33.5 - resolution: "@img/sharp-darwin-x64@npm:0.33.5" - dependencies: - "@img/sharp-libvips-darwin-x64": "npm:1.0.4" - dependenciesMeta: - "@img/sharp-libvips-darwin-x64": - optional: true - conditions: os=darwin & cpu=x64 - languageName: node - linkType: hard - -"@img/sharp-darwin-x64@npm:0.34.4": - version: 0.34.4 - resolution: "@img/sharp-darwin-x64@npm:0.34.4" - dependencies: - "@img/sharp-libvips-darwin-x64": "npm:1.2.3" - dependenciesMeta: - "@img/sharp-libvips-darwin-x64": - optional: true - conditions: os=darwin & cpu=x64 - languageName: node - linkType: hard - -"@img/sharp-darwin-x64@npm:0.34.5": - version: 0.34.5 - resolution: "@img/sharp-darwin-x64@npm:0.34.5" - dependencies: - "@img/sharp-libvips-darwin-x64": "npm:1.2.4" - dependenciesMeta: - "@img/sharp-libvips-darwin-x64": - optional: true - conditions: os=darwin & cpu=x64 - languageName: node - linkType: hard - -"@img/sharp-libvips-darwin-arm64@npm:1.0.4": - version: 1.0.4 - resolution: "@img/sharp-libvips-darwin-arm64@npm:1.0.4" - conditions: os=darwin & cpu=arm64 - languageName: node - linkType: hard - -"@img/sharp-libvips-darwin-arm64@npm:1.2.3": - version: 1.2.3 - resolution: "@img/sharp-libvips-darwin-arm64@npm:1.2.3" - conditions: os=darwin & cpu=arm64 - languageName: node - linkType: hard - -"@img/sharp-libvips-darwin-arm64@npm:1.2.4": - version: 1.2.4 - resolution: "@img/sharp-libvips-darwin-arm64@npm:1.2.4" - conditions: os=darwin & cpu=arm64 - languageName: node - linkType: hard - -"@img/sharp-libvips-darwin-x64@npm:1.0.4": - version: 1.0.4 - resolution: "@img/sharp-libvips-darwin-x64@npm:1.0.4" - conditions: os=darwin & cpu=x64 - languageName: node - linkType: hard - -"@img/sharp-libvips-darwin-x64@npm:1.2.3": - version: 1.2.3 - resolution: "@img/sharp-libvips-darwin-x64@npm:1.2.3" - conditions: os=darwin & cpu=x64 - languageName: node - linkType: hard - -"@img/sharp-libvips-darwin-x64@npm:1.2.4": - version: 1.2.4 - resolution: "@img/sharp-libvips-darwin-x64@npm:1.2.4" - conditions: os=darwin & cpu=x64 - languageName: node - linkType: hard - -"@img/sharp-libvips-linux-arm64@npm:1.0.4": - version: 1.0.4 - resolution: "@img/sharp-libvips-linux-arm64@npm:1.0.4" - conditions: os=linux & cpu=arm64 & libc=glibc - languageName: node - linkType: hard - -"@img/sharp-libvips-linux-arm64@npm:1.2.3": - version: 1.2.3 - resolution: "@img/sharp-libvips-linux-arm64@npm:1.2.3" - conditions: os=linux & cpu=arm64 & libc=glibc - languageName: node - linkType: hard - -"@img/sharp-libvips-linux-arm64@npm:1.2.4": - version: 1.2.4 - resolution: "@img/sharp-libvips-linux-arm64@npm:1.2.4" - conditions: os=linux & cpu=arm64 & libc=glibc - languageName: node - linkType: hard - -"@img/sharp-libvips-linux-arm@npm:1.0.5": - version: 1.0.5 - resolution: "@img/sharp-libvips-linux-arm@npm:1.0.5" - conditions: os=linux & cpu=arm & libc=glibc - languageName: node - linkType: hard - -"@img/sharp-libvips-linux-arm@npm:1.2.3": - version: 1.2.3 - resolution: "@img/sharp-libvips-linux-arm@npm:1.2.3" - conditions: os=linux & cpu=arm & libc=glibc - languageName: node - linkType: hard - -"@img/sharp-libvips-linux-arm@npm:1.2.4": - version: 1.2.4 - resolution: "@img/sharp-libvips-linux-arm@npm:1.2.4" - conditions: os=linux & cpu=arm & libc=glibc - languageName: node - linkType: hard - -"@img/sharp-libvips-linux-ppc64@npm:1.2.3": - version: 1.2.3 - resolution: "@img/sharp-libvips-linux-ppc64@npm:1.2.3" - conditions: os=linux & cpu=ppc64 & libc=glibc - languageName: node - linkType: hard - -"@img/sharp-libvips-linux-ppc64@npm:1.2.4": - version: 1.2.4 - resolution: "@img/sharp-libvips-linux-ppc64@npm:1.2.4" - conditions: os=linux & cpu=ppc64 & libc=glibc - languageName: node - linkType: hard - -"@img/sharp-libvips-linux-riscv64@npm:1.2.4": - version: 1.2.4 - resolution: "@img/sharp-libvips-linux-riscv64@npm:1.2.4" - conditions: os=linux & cpu=riscv64 & libc=glibc - languageName: node - linkType: hard - -"@img/sharp-libvips-linux-s390x@npm:1.0.4": - version: 1.0.4 - resolution: "@img/sharp-libvips-linux-s390x@npm:1.0.4" - conditions: os=linux & cpu=s390x & libc=glibc - languageName: node - linkType: hard - -"@img/sharp-libvips-linux-s390x@npm:1.2.3": - version: 1.2.3 - resolution: "@img/sharp-libvips-linux-s390x@npm:1.2.3" - conditions: os=linux & cpu=s390x & libc=glibc - languageName: node - linkType: hard - -"@img/sharp-libvips-linux-s390x@npm:1.2.4": - version: 1.2.4 - resolution: "@img/sharp-libvips-linux-s390x@npm:1.2.4" - conditions: os=linux & cpu=s390x & libc=glibc - languageName: node - linkType: hard - -"@img/sharp-libvips-linux-x64@npm:1.0.4": - version: 1.0.4 - resolution: "@img/sharp-libvips-linux-x64@npm:1.0.4" - conditions: os=linux & cpu=x64 & libc=glibc - languageName: node - linkType: hard - -"@img/sharp-libvips-linux-x64@npm:1.2.3": - version: 1.2.3 - resolution: "@img/sharp-libvips-linux-x64@npm:1.2.3" - conditions: os=linux & cpu=x64 & libc=glibc - languageName: node - linkType: hard - -"@img/sharp-libvips-linux-x64@npm:1.2.4": - version: 1.2.4 - resolution: "@img/sharp-libvips-linux-x64@npm:1.2.4" - conditions: os=linux & cpu=x64 & libc=glibc - languageName: node - linkType: hard - -"@img/sharp-libvips-linuxmusl-arm64@npm:1.0.4": - version: 1.0.4 - resolution: "@img/sharp-libvips-linuxmusl-arm64@npm:1.0.4" - conditions: os=linux & cpu=arm64 & libc=musl - languageName: node - linkType: hard - -"@img/sharp-libvips-linuxmusl-arm64@npm:1.2.3": - version: 1.2.3 - resolution: "@img/sharp-libvips-linuxmusl-arm64@npm:1.2.3" - conditions: os=linux & cpu=arm64 & libc=musl - languageName: node - linkType: hard - -"@img/sharp-libvips-linuxmusl-arm64@npm:1.2.4": - version: 1.2.4 - resolution: "@img/sharp-libvips-linuxmusl-arm64@npm:1.2.4" - conditions: os=linux & cpu=arm64 & libc=musl - languageName: node - linkType: hard - -"@img/sharp-libvips-linuxmusl-x64@npm:1.0.4": - version: 1.0.4 - resolution: "@img/sharp-libvips-linuxmusl-x64@npm:1.0.4" - conditions: os=linux & cpu=x64 & libc=musl - languageName: node - linkType: hard - -"@img/sharp-libvips-linuxmusl-x64@npm:1.2.3": - version: 1.2.3 - resolution: "@img/sharp-libvips-linuxmusl-x64@npm:1.2.3" - conditions: os=linux & cpu=x64 & libc=musl - languageName: node - linkType: hard - -"@img/sharp-libvips-linuxmusl-x64@npm:1.2.4": - version: 1.2.4 - resolution: "@img/sharp-libvips-linuxmusl-x64@npm:1.2.4" - conditions: os=linux & cpu=x64 & libc=musl - languageName: node - linkType: hard - -"@img/sharp-linux-arm64@npm:0.33.5": - version: 0.33.5 - resolution: "@img/sharp-linux-arm64@npm:0.33.5" - dependencies: - "@img/sharp-libvips-linux-arm64": "npm:1.0.4" - dependenciesMeta: - "@img/sharp-libvips-linux-arm64": - optional: true - conditions: os=linux & cpu=arm64 & libc=glibc - languageName: node - linkType: hard - -"@img/sharp-linux-arm64@npm:0.34.4": - version: 0.34.4 - resolution: "@img/sharp-linux-arm64@npm:0.34.4" - dependencies: - "@img/sharp-libvips-linux-arm64": "npm:1.2.3" - dependenciesMeta: - "@img/sharp-libvips-linux-arm64": - optional: true - conditions: os=linux & cpu=arm64 & libc=glibc - languageName: node - linkType: hard - -"@img/sharp-linux-arm64@npm:0.34.5": - version: 0.34.5 - resolution: "@img/sharp-linux-arm64@npm:0.34.5" - dependencies: - "@img/sharp-libvips-linux-arm64": "npm:1.2.4" - dependenciesMeta: - "@img/sharp-libvips-linux-arm64": - optional: true - conditions: os=linux & cpu=arm64 & libc=glibc - languageName: node - linkType: hard - -"@img/sharp-linux-arm@npm:0.33.5": - version: 0.33.5 - resolution: "@img/sharp-linux-arm@npm:0.33.5" - dependencies: - "@img/sharp-libvips-linux-arm": "npm:1.0.5" - dependenciesMeta: - "@img/sharp-libvips-linux-arm": - optional: true - conditions: os=linux & cpu=arm & libc=glibc - languageName: node - linkType: hard - -"@img/sharp-linux-arm@npm:0.34.4": - version: 0.34.4 - resolution: "@img/sharp-linux-arm@npm:0.34.4" - dependencies: - "@img/sharp-libvips-linux-arm": "npm:1.2.3" - dependenciesMeta: - "@img/sharp-libvips-linux-arm": - optional: true - conditions: os=linux & cpu=arm & libc=glibc - languageName: node - linkType: hard - -"@img/sharp-linux-arm@npm:0.34.5": - version: 0.34.5 - resolution: "@img/sharp-linux-arm@npm:0.34.5" - dependencies: - "@img/sharp-libvips-linux-arm": "npm:1.2.4" - dependenciesMeta: - "@img/sharp-libvips-linux-arm": - optional: true - conditions: os=linux & cpu=arm & libc=glibc - languageName: node - linkType: hard - -"@img/sharp-linux-ppc64@npm:0.34.4": - version: 0.34.4 - resolution: "@img/sharp-linux-ppc64@npm:0.34.4" - dependencies: - "@img/sharp-libvips-linux-ppc64": "npm:1.2.3" - dependenciesMeta: - "@img/sharp-libvips-linux-ppc64": - optional: true - conditions: os=linux & cpu=ppc64 & libc=glibc - languageName: node - linkType: hard - -"@img/sharp-linux-ppc64@npm:0.34.5": - version: 0.34.5 - resolution: "@img/sharp-linux-ppc64@npm:0.34.5" - dependencies: - "@img/sharp-libvips-linux-ppc64": "npm:1.2.4" - dependenciesMeta: - "@img/sharp-libvips-linux-ppc64": - optional: true - conditions: os=linux & cpu=ppc64 & libc=glibc - languageName: node - linkType: hard - -"@img/sharp-linux-riscv64@npm:0.34.5": - version: 0.34.5 - resolution: "@img/sharp-linux-riscv64@npm:0.34.5" - dependencies: - "@img/sharp-libvips-linux-riscv64": "npm:1.2.4" - dependenciesMeta: - "@img/sharp-libvips-linux-riscv64": - optional: true - conditions: os=linux & cpu=riscv64 & libc=glibc - languageName: node - linkType: hard - -"@img/sharp-linux-s390x@npm:0.33.5": - version: 0.33.5 - resolution: "@img/sharp-linux-s390x@npm:0.33.5" - dependencies: - "@img/sharp-libvips-linux-s390x": "npm:1.0.4" - dependenciesMeta: - "@img/sharp-libvips-linux-s390x": - optional: true - conditions: os=linux & cpu=s390x & libc=glibc - languageName: node - linkType: hard - -"@img/sharp-linux-s390x@npm:0.34.4": - version: 0.34.4 - resolution: "@img/sharp-linux-s390x@npm:0.34.4" - dependencies: - "@img/sharp-libvips-linux-s390x": "npm:1.2.3" - dependenciesMeta: - "@img/sharp-libvips-linux-s390x": - optional: true - conditions: os=linux & cpu=s390x & libc=glibc - languageName: node - linkType: hard - -"@img/sharp-linux-s390x@npm:0.34.5": - version: 0.34.5 - resolution: "@img/sharp-linux-s390x@npm:0.34.5" - dependencies: - "@img/sharp-libvips-linux-s390x": "npm:1.2.4" - dependenciesMeta: - "@img/sharp-libvips-linux-s390x": - optional: true - conditions: os=linux & cpu=s390x & libc=glibc - languageName: node - linkType: hard - -"@img/sharp-linux-x64@npm:0.33.5": - version: 0.33.5 - resolution: "@img/sharp-linux-x64@npm:0.33.5" - dependencies: - "@img/sharp-libvips-linux-x64": "npm:1.0.4" - dependenciesMeta: - "@img/sharp-libvips-linux-x64": - optional: true - conditions: os=linux & cpu=x64 & libc=glibc - languageName: node - linkType: hard - -"@img/sharp-linux-x64@npm:0.34.4": - version: 0.34.4 - resolution: "@img/sharp-linux-x64@npm:0.34.4" - dependencies: - "@img/sharp-libvips-linux-x64": "npm:1.2.3" - dependenciesMeta: - "@img/sharp-libvips-linux-x64": - optional: true - conditions: os=linux & cpu=x64 & libc=glibc - languageName: node - linkType: hard - -"@img/sharp-linux-x64@npm:0.34.5": - version: 0.34.5 - resolution: "@img/sharp-linux-x64@npm:0.34.5" - dependencies: - "@img/sharp-libvips-linux-x64": "npm:1.2.4" - dependenciesMeta: - "@img/sharp-libvips-linux-x64": - optional: true - conditions: os=linux & cpu=x64 & libc=glibc - languageName: node - linkType: hard - -"@img/sharp-linuxmusl-arm64@npm:0.33.5": - version: 0.33.5 - resolution: "@img/sharp-linuxmusl-arm64@npm:0.33.5" - dependencies: - "@img/sharp-libvips-linuxmusl-arm64": "npm:1.0.4" - dependenciesMeta: - "@img/sharp-libvips-linuxmusl-arm64": - optional: true - conditions: os=linux & cpu=arm64 & libc=musl - languageName: node - linkType: hard - -"@img/sharp-linuxmusl-arm64@npm:0.34.4": - version: 0.34.4 - resolution: "@img/sharp-linuxmusl-arm64@npm:0.34.4" - dependencies: - "@img/sharp-libvips-linuxmusl-arm64": "npm:1.2.3" - dependenciesMeta: - "@img/sharp-libvips-linuxmusl-arm64": - optional: true - conditions: os=linux & cpu=arm64 & libc=musl - languageName: node - linkType: hard - -"@img/sharp-linuxmusl-arm64@npm:0.34.5": - version: 0.34.5 - resolution: "@img/sharp-linuxmusl-arm64@npm:0.34.5" - dependencies: - "@img/sharp-libvips-linuxmusl-arm64": "npm:1.2.4" - dependenciesMeta: - "@img/sharp-libvips-linuxmusl-arm64": - optional: true - conditions: os=linux & cpu=arm64 & libc=musl - languageName: node - linkType: hard - -"@img/sharp-linuxmusl-x64@npm:0.33.5": - version: 0.33.5 - resolution: "@img/sharp-linuxmusl-x64@npm:0.33.5" - dependencies: - "@img/sharp-libvips-linuxmusl-x64": "npm:1.0.4" - dependenciesMeta: - "@img/sharp-libvips-linuxmusl-x64": - optional: true - conditions: os=linux & cpu=x64 & libc=musl - languageName: node - linkType: hard - -"@img/sharp-linuxmusl-x64@npm:0.34.4": - version: 0.34.4 - resolution: "@img/sharp-linuxmusl-x64@npm:0.34.4" - dependencies: - "@img/sharp-libvips-linuxmusl-x64": "npm:1.2.3" - dependenciesMeta: - "@img/sharp-libvips-linuxmusl-x64": - optional: true - conditions: os=linux & cpu=x64 & libc=musl - languageName: node - linkType: hard - -"@img/sharp-linuxmusl-x64@npm:0.34.5": - version: 0.34.5 - resolution: "@img/sharp-linuxmusl-x64@npm:0.34.5" - dependencies: - "@img/sharp-libvips-linuxmusl-x64": "npm:1.2.4" - dependenciesMeta: - "@img/sharp-libvips-linuxmusl-x64": - optional: true - conditions: os=linux & cpu=x64 & libc=musl - languageName: node - linkType: hard - -"@img/sharp-wasm32@npm:0.33.5": - version: 0.33.5 - resolution: "@img/sharp-wasm32@npm:0.33.5" - dependencies: - "@emnapi/runtime": "npm:^1.2.0" - conditions: cpu=wasm32 - languageName: node - linkType: hard - -"@img/sharp-wasm32@npm:0.34.4": - version: 0.34.4 - resolution: "@img/sharp-wasm32@npm:0.34.4" - dependencies: - "@emnapi/runtime": "npm:^1.5.0" - conditions: cpu=wasm32 - languageName: node - linkType: hard - -"@img/sharp-wasm32@npm:0.34.5": - version: 0.34.5 - resolution: "@img/sharp-wasm32@npm:0.34.5" - dependencies: - "@emnapi/runtime": "npm:^1.7.0" - conditions: cpu=wasm32 - languageName: node - linkType: hard - -"@img/sharp-win32-arm64@npm:0.34.4": - version: 0.34.4 - resolution: "@img/sharp-win32-arm64@npm:0.34.4" - conditions: os=win32 & cpu=arm64 - languageName: node - linkType: hard - -"@img/sharp-win32-arm64@npm:0.34.5": - version: 0.34.5 - resolution: "@img/sharp-win32-arm64@npm:0.34.5" - conditions: os=win32 & cpu=arm64 - languageName: node - linkType: hard - -"@img/sharp-win32-ia32@npm:0.33.5": - version: 0.33.5 - resolution: "@img/sharp-win32-ia32@npm:0.33.5" - conditions: os=win32 & cpu=ia32 - languageName: node - linkType: hard - -"@img/sharp-win32-ia32@npm:0.34.4": - version: 0.34.4 - resolution: "@img/sharp-win32-ia32@npm:0.34.4" - conditions: os=win32 & cpu=ia32 - languageName: node - linkType: hard - -"@img/sharp-win32-ia32@npm:0.34.5": - version: 0.34.5 - resolution: "@img/sharp-win32-ia32@npm:0.34.5" - conditions: os=win32 & cpu=ia32 - languageName: node - linkType: hard - -"@img/sharp-win32-x64@npm:0.33.5": - version: 0.33.5 - resolution: "@img/sharp-win32-x64@npm:0.33.5" - conditions: os=win32 & cpu=x64 - languageName: node - linkType: hard - -"@img/sharp-win32-x64@npm:0.34.4": - version: 0.34.4 - resolution: "@img/sharp-win32-x64@npm:0.34.4" - conditions: os=win32 & cpu=x64 - languageName: node - linkType: hard - -"@img/sharp-win32-x64@npm:0.34.5": - version: 0.34.5 - resolution: "@img/sharp-win32-x64@npm:0.34.5" - conditions: os=win32 & cpu=x64 - languageName: node - linkType: hard - "@inquirer/ansi@npm:^1.0.2": version: 1.0.2 resolution: "@inquirer/ansi@npm:1.0.2" @@ -8143,7 +7444,7 @@ __metadata: languageName: node linkType: hard -"@jridgewell/gen-mapping@npm:^0.3.12, @jridgewell/gen-mapping@npm:^0.3.2, @jridgewell/gen-mapping@npm:^0.3.5": +"@jridgewell/gen-mapping@npm:^0.3.12, @jridgewell/gen-mapping@npm:^0.3.5": version: 0.3.13 resolution: "@jridgewell/gen-mapping@npm:0.3.13" dependencies: @@ -8277,7 +7578,7 @@ __metadata: languageName: node linkType: hard -"@lit-labs/ssr-dom-shim@npm:^1.0.0, @lit-labs/ssr-dom-shim@npm:^1.1.0, @lit-labs/ssr-dom-shim@npm:^1.2.0": +"@lit-labs/ssr-dom-shim@npm:^1.2.0": version: 1.3.0 resolution: "@lit-labs/ssr-dom-shim@npm:1.3.0" checksum: 10/a15c5d145a20f367a392cff91f2091ffe54457119ac26569670bbbe32760f86d1e250f865dc1bd0604641106376776c4862a8fff9adb44f9881b510747c08680 @@ -8302,15 +7603,6 @@ __metadata: languageName: node linkType: hard -"@lit/reactive-element@npm:^1.3.0, @lit/reactive-element@npm:^1.6.0": - version: 1.6.3 - resolution: "@lit/reactive-element@npm:1.6.3" - dependencies: - "@lit-labs/ssr-dom-shim": "npm:^1.0.0" - checksum: 10/664c899bb0b144590dc4faf83b358b1504810eac107778c3aeb384affc65a7ef4eda754944bcc34a57237db03dff145332406345ac24da19ca37cf4b3cb343d3 - languageName: node - linkType: hard - "@lit/reactive-element@npm:^1.6.2 || ^2.1.0, @lit/reactive-element@npm:^2.1.0": version: 2.1.0 resolution: "@lit/reactive-element@npm:2.1.0" @@ -8320,38 +7612,20 @@ __metadata: languageName: node linkType: hard -"@lottiefiles/dotlottie-react@npm:0.13.3": - version: 0.13.3 - resolution: "@lottiefiles/dotlottie-react@npm:0.13.3" +"@lottiefiles/dotlottie-wc@npm:^0.9.4": + version: 0.9.4 + resolution: "@lottiefiles/dotlottie-wc@npm:0.9.4" dependencies: - "@lottiefiles/dotlottie-web": "npm:0.42.0" - peerDependencies: - react: ^17 || ^18 || ^19 - checksum: 10/b9b00dc606ad998ffe635944b7ddad21c9c252d3b51729ae3e29f8673b134eaf2bb05b42010fe310f1df7e912e62bf581ea52c50ecbadc834f163639f1640d3d - languageName: node - linkType: hard - -"@lottiefiles/dotlottie-wc@npm:^0.5.0": - version: 0.5.3 - resolution: "@lottiefiles/dotlottie-wc@npm:0.5.3" - dependencies: - "@lottiefiles/dotlottie-web": "npm:0.44.0" + "@lottiefiles/dotlottie-web": "npm:0.65.0" lit: "npm:^3.2.1" - checksum: 10/c1851320783b7efb1d3cbfbe447f54a920bef1f9b5afd71ebdcb25e475c27c1bb4aa1a09f854ef9672b03ddadb66c70b5f47aa05ce37fed7915d3d8520348353 + checksum: 10/5685a370c675f0b846354ad73d8931fc8e978582511c079b58e3dc21c004e7b629c566d6a1b9fe97d4f7458f9b966b8520bc64bc7be18d9a09aa5abfc7596a73 languageName: node linkType: hard -"@lottiefiles/dotlottie-web@npm:0.42.0": - version: 0.42.0 - resolution: "@lottiefiles/dotlottie-web@npm:0.42.0" - checksum: 10/ced847f8ffe353821e045c7c4ddc058d85766faebcab346485cace03202b4a4871a6a27517fe2137a9d560c0f24607dd4b9432caf26d3dfd197ceb76f7498314 - languageName: node - linkType: hard - -"@lottiefiles/dotlottie-web@npm:0.44.0": - version: 0.44.0 - resolution: "@lottiefiles/dotlottie-web@npm:0.44.0" - checksum: 10/d8349ff353da858fcdd3df307f2f0cdf7e1d629f87454d8f221917ea199dbb26e46213e5c50abf0bf04a935aa31fe2bc535d3f605d64e1688666d3d0e4f0c252 +"@lottiefiles/dotlottie-web@npm:0.65.0": + version: 0.65.0 + resolution: "@lottiefiles/dotlottie-web@npm:0.65.0" + checksum: 10/221c3287cdea610bfe802caeb2fac768b851285f99dca5287a644e811733992f482ef2fb7b8379796b147143c92d8af86d25c708265802a014e1c3b1e962dac3 languageName: node linkType: hard @@ -10055,69 +9329,6 @@ __metadata: languageName: node linkType: hard -"@next/env@npm:15.5.2": - version: 15.5.2 - resolution: "@next/env@npm:15.5.2" - checksum: 10/1e1c4f5b725165663460bae67de95cab624c66a865395a0af98405d3302483bebed8e79fcc2dc1c447b7010b5519fddb49670de16b00b75d679b52b29a4d86f5 - languageName: node - linkType: hard - -"@next/swc-darwin-arm64@npm:15.5.2": - version: 15.5.2 - resolution: "@next/swc-darwin-arm64@npm:15.5.2" - conditions: os=darwin & cpu=arm64 - languageName: node - linkType: hard - -"@next/swc-darwin-x64@npm:15.5.2": - version: 15.5.2 - resolution: "@next/swc-darwin-x64@npm:15.5.2" - conditions: os=darwin & cpu=x64 - languageName: node - linkType: hard - -"@next/swc-linux-arm64-gnu@npm:15.5.2": - version: 15.5.2 - resolution: "@next/swc-linux-arm64-gnu@npm:15.5.2" - conditions: os=linux & cpu=arm64 & libc=glibc - languageName: node - linkType: hard - -"@next/swc-linux-arm64-musl@npm:15.5.2": - version: 15.5.2 - resolution: "@next/swc-linux-arm64-musl@npm:15.5.2" - conditions: os=linux & cpu=arm64 & libc=musl - languageName: node - linkType: hard - -"@next/swc-linux-x64-gnu@npm:15.5.2": - version: 15.5.2 - resolution: "@next/swc-linux-x64-gnu@npm:15.5.2" - conditions: os=linux & cpu=x64 & libc=glibc - languageName: node - linkType: hard - -"@next/swc-linux-x64-musl@npm:15.5.2": - version: 15.5.2 - resolution: "@next/swc-linux-x64-musl@npm:15.5.2" - conditions: os=linux & cpu=x64 & libc=musl - languageName: node - linkType: hard - -"@next/swc-win32-arm64-msvc@npm:15.5.2": - version: 15.5.2 - resolution: "@next/swc-win32-arm64-msvc@npm:15.5.2" - conditions: os=win32 & cpu=arm64 - languageName: node - linkType: hard - -"@next/swc-win32-x64-msvc@npm:15.5.2": - version: 15.5.2 - resolution: "@next/swc-win32-x64-msvc@npm:15.5.2" - conditions: os=win32 & cpu=x64 - languageName: node - linkType: hard - "@noble/hashes@npm:^1.1.5": version: 1.8.0 resolution: "@noble/hashes@npm:1.8.0" @@ -11731,7 +10942,7 @@ __metadata: languageName: node linkType: hard -"@preact/signals-core@npm:^1.2.3, @preact/signals-core@npm:^1.8.0": +"@preact/signals-core@npm:^1.8.0": version: 1.8.0 resolution: "@preact/signals-core@npm:1.8.0" checksum: 10/480c1aaf1bce6f8bd5544eec9fd92a70ccdfffa24c23d99aa8e3c13783cc6b06ec0a3d90578c5fd368d06121cbe0f8fbe81368aa45ddba11d8a28af15410a9dc @@ -11964,13 +11175,6 @@ __metadata: languageName: node linkType: hard -"@radix-ui/colors@npm:3.0.0": - version: 3.0.0 - resolution: "@radix-ui/colors@npm:3.0.0" - checksum: 10/bc9ffb01b3964f16482dc278cf6d86d85b73eae7cb94a77018fbd53b103b3d5ec1ecf77882cfbf8892f28c2c6057db8e19bf4d66234ed330a430373b092c5cfe - languageName: node - linkType: hard - "@radix-ui/number@npm:1.1.1": version: 1.1.1 resolution: "@radix-ui/number@npm:1.1.1" @@ -12302,7 +11506,7 @@ __metadata: languageName: node linkType: hard -"@radix-ui/react-dropdown-menu@npm:2.1.16, @radix-ui/react-dropdown-menu@npm:^2.1.16, @radix-ui/react-dropdown-menu@npm:^2.1.3": +"@radix-ui/react-dropdown-menu@npm:^2.1.16, @radix-ui/react-dropdown-menu@npm:^2.1.3": version: 2.1.16 resolution: "@radix-ui/react-dropdown-menu@npm:2.1.16" dependencies: @@ -12527,7 +11731,7 @@ __metadata: languageName: node linkType: hard -"@radix-ui/react-popover@npm:1.1.15, @radix-ui/react-popover@npm:^1.1.15, @radix-ui/react-popover@npm:^1.1.3": +"@radix-ui/react-popover@npm:^1.1.15, @radix-ui/react-popover@npm:^1.1.3": version: 1.1.15 resolution: "@radix-ui/react-popover@npm:1.1.15" dependencies: @@ -12929,7 +12133,7 @@ __metadata: languageName: node linkType: hard -"@radix-ui/react-tabs@npm:1.1.13, @radix-ui/react-tabs@npm:^1.1.13, @radix-ui/react-tabs@npm:^1.1.2": +"@radix-ui/react-tabs@npm:^1.1.13, @radix-ui/react-tabs@npm:^1.1.2": version: 1.1.13 resolution: "@radix-ui/react-tabs@npm:1.1.13" dependencies: @@ -13056,7 +12260,7 @@ __metadata: languageName: node linkType: hard -"@radix-ui/react-tooltip@npm:1.2.8, @radix-ui/react-tooltip@npm:^1.1.5, @radix-ui/react-tooltip@npm:^1.1.8": +"@radix-ui/react-tooltip@npm:^1.1.5, @radix-ui/react-tooltip@npm:^1.1.8": version: 1.2.8 resolution: "@radix-ui/react-tooltip@npm:1.2.8" dependencies: @@ -14346,55 +13550,6 @@ __metadata: languageName: node linkType: hard -"@react-email/preview-server@npm:^4.3.2": - version: 4.3.2 - resolution: "@react-email/preview-server@npm:4.3.2" - dependencies: - "@babel/core": "npm:7.26.10" - "@babel/parser": "npm:7.27.0" - "@babel/traverse": "npm:7.27.0" - "@lottiefiles/dotlottie-react": "npm:0.13.3" - "@radix-ui/colors": "npm:3.0.0" - "@radix-ui/react-collapsible": "npm:1.1.12" - "@radix-ui/react-dropdown-menu": "npm:2.1.16" - "@radix-ui/react-popover": "npm:1.1.15" - "@radix-ui/react-slot": "npm:1.2.3" - "@radix-ui/react-tabs": "npm:1.1.13" - "@radix-ui/react-toggle-group": "npm:1.1.11" - "@radix-ui/react-tooltip": "npm:1.2.8" - "@types/node": "npm:22.14.1" - "@types/normalize-path": "npm:3.0.2" - "@types/react": "npm:19.0.10" - "@types/react-dom": "npm:19.0.4" - "@types/webpack": "npm:5.28.5" - autoprefixer: "npm:10.4.21" - clsx: "npm:2.1.1" - esbuild: "npm:0.25.10" - framer-motion: "npm:12.23.22" - json5: "npm:2.2.3" - log-symbols: "npm:4.1.0" - module-punycode: "npm:punycode@2.3.1" - next: "npm:15.5.2" - node-html-parser: "npm:7.0.1" - ora: "npm:5.4.1" - pretty-bytes: "npm:6.1.1" - prism-react-renderer: "npm:2.4.1" - react: "npm:19.0.0" - react-dom: "npm:19.0.0" - sharp: "npm:0.34.4" - socket.io-client: "npm:4.8.1" - sonner: "npm:2.0.3" - source-map-js: "npm:1.2.1" - spamc: "npm:0.0.5" - stacktrace-parser: "npm:0.1.11" - tailwind-merge: "npm:3.2.0" - tailwindcss: "npm:3.4.0" - use-debounce: "npm:10.0.4" - zod: "npm:3.24.3" - checksum: 10/b5d7d107eae3d24c9d2b92c832aab4f07c972ed9c1b4ea20b867165d590f34747aff29d47397d86e43b631a9b347aecb82c163efcfd58ef1b699598bf2f4a880 - languageName: node - linkType: hard - "@react-email/preview@npm:0.0.13": version: 0.0.13 resolution: "@react-email/preview@npm:0.0.13" @@ -15304,42 +14459,6 @@ __metadata: languageName: node linkType: hard -"@rgba-image/common@npm:^0.1.0, @rgba-image/common@npm:^0.1.13": - version: 0.1.13 - resolution: "@rgba-image/common@npm:0.1.13" - checksum: 10/9e2598b551a1097f5265c53df6ef1d03d11f356e30f25e19ee69da43a989e1f731925d0c61e169eb9f40e87e3a24650cbafd3dc09787c26d14b6d9cdc8f89504 - languageName: node - linkType: hard - -"@rgba-image/copy@npm:^0.1.2": - version: 0.1.3 - resolution: "@rgba-image/copy@npm:0.1.3" - dependencies: - "@rgba-image/common": "npm:^0.1.13" - checksum: 10/0e01876353767e930bc5b4ba17cc3a6344478dc7c8f51c6626f8b4c0e91595f12d5e191816ceadabdadbf0728db08d19a6aa235b2261371120056f3fd9a8e624 - languageName: node - linkType: hard - -"@rgba-image/create-image@npm:^0.1.1": - version: 0.1.1 - resolution: "@rgba-image/create-image@npm:0.1.1" - dependencies: - "@rgba-image/common": "npm:^0.1.0" - checksum: 10/2f55720b58a2ba8dbc5502552eee3639972436b840a2b6cde0d381553e8ed2ef7110aee2b204bc7522a3e01aff4be532f432f49bc0ba7bd4d99b31b9170f9b64 - languageName: node - linkType: hard - -"@rgba-image/lanczos@npm:^0.1.0": - version: 0.1.1 - resolution: "@rgba-image/lanczos@npm:0.1.1" - dependencies: - "@rgba-image/common": "npm:^0.1.13" - "@rgba-image/copy": "npm:^0.1.2" - "@rgba-image/create-image": "npm:^0.1.1" - checksum: 10/d5074a9ced2f3573f5d3a38adc048a7ae642013392986b3ff90daac09f475bc2f61d23e5d4a197f15b2ae61033749acf2d9e9704f203a8e318dc15413be71c58 - languageName: node - linkType: hard - "@rolldown/pluginutils@npm:1.0.0-beta.53": version: 1.0.0-beta.53 resolution: "@rolldown/pluginutils@npm:1.0.0-beta.53" @@ -16587,15 +15706,6 @@ __metadata: languageName: node linkType: hard -"@swc/helpers@npm:0.5.15": - version: 0.5.15 - resolution: "@swc/helpers@npm:0.5.15" - dependencies: - tslib: "npm:^2.8.0" - checksum: 10/e3f32c6deeecfb0fa3f22edff03a7b358e7ce16d27b0f1c8b5cdc3042c5c4ce4da6eac0b781ab7cc4f54696ece657467d56734fb26883439fb00017385364c4c - languageName: node - linkType: hard - "@swc/helpers@npm:^0.5.0": version: 0.5.18 resolution: "@swc/helpers@npm:0.5.18" @@ -18046,15 +17156,6 @@ __metadata: languageName: node linkType: hard -"@types/node@npm:22.14.1": - version: 22.14.1 - resolution: "@types/node@npm:22.14.1" - dependencies: - undici-types: "npm:~6.21.0" - checksum: 10/561b1ad98ef5176d6da856ffbbe494f16655149f6a7d561de0423c8784910c81267d7d6459f59d68a97b3cbae9b5996b3b5dfe64f4de3de2239d295dcf4a4dcc - languageName: node - linkType: hard - "@types/node@npm:^20.0.0": version: 20.19.1 resolution: "@types/node@npm:20.19.1" @@ -18073,13 +17174,6 @@ __metadata: languageName: node linkType: hard -"@types/normalize-path@npm:3.0.2": - version: 3.0.2 - resolution: "@types/normalize-path@npm:3.0.2" - checksum: 10/0fafa7d0c19eca1501cc4f9ce8a8c6ca7739d0fcd58f5851c56ad2babafc07c6113d593b4d8cc045678e0828af134f2339901f8dfe200801ee7b2d3e1496c316 - languageName: node - linkType: hard - "@types/object-path@npm:^0.11.1": version: 0.11.4 resolution: "@types/object-path@npm:0.11.4" @@ -18149,13 +17243,6 @@ __metadata: languageName: node linkType: hard -"@types/prismjs@npm:^1.26.0": - version: 1.26.6 - resolution: "@types/prismjs@npm:1.26.6" - checksum: 10/37c056eb7a9130ef6548d7655af78ea575c8eaa9167ea2dd64d8719384b1af4a385ffe928aa4939da607ce276703a6787bdac8ecc79a373e2a73ddf6d75bc161 - languageName: node - linkType: hard - "@types/qs@npm:*": version: 6.9.18 resolution: "@types/qs@npm:6.9.18" @@ -18170,15 +17257,6 @@ __metadata: languageName: node linkType: hard -"@types/react-dom@npm:19.0.4": - version: 19.0.4 - resolution: "@types/react-dom@npm:19.0.4" - peerDependencies: - "@types/react": ^19.0.0 - checksum: 10/f15d470242f0b7cca57dd7e991a2852525ac93b2cb92f7e6c104d7bd6a978c3b1d0ba9b8698f23bc19c16b5cd98a6d160007be52c61196952f57cf019f204254 - languageName: node - linkType: hard - "@types/react-dom@npm:^19.0.2": version: 19.1.5 resolution: "@types/react-dom@npm:19.1.5" @@ -18188,15 +17266,6 @@ __metadata: languageName: node linkType: hard -"@types/react@npm:19.0.10": - version: 19.0.10 - resolution: "@types/react@npm:19.0.10" - dependencies: - csstype: "npm:^3.0.2" - checksum: 10/10b592d212ebe4b4e0bd42a95c58af3d8dfcb8b3fa4b412d686c2ff8810d5dd3e3a30ebedb31d7b738e33a39c43503e24fe4e6ca8a21d842870043793f4eda98 - languageName: node - linkType: hard - "@types/react@npm:^19.0.1": version: 19.1.5 resolution: "@types/react@npm:19.1.5" @@ -18396,17 +17465,6 @@ __metadata: languageName: node linkType: hard -"@types/webpack@npm:5.28.5": - version: 5.28.5 - resolution: "@types/webpack@npm:5.28.5" - dependencies: - "@types/node": "npm:*" - tapable: "npm:^2.2.0" - webpack: "npm:^5" - checksum: 10/14359d9ccecef7ef1ea271c00baec5337213c7fda63a34c61b9e519505b3928d0807cdbb5b1172d1994e1179920b89c57eaf2cbf64599958b67cd70720ac2a9b - languageName: node - linkType: hard - "@types/whatwg-mimetype@npm:^3.0.2": version: 3.0.2 resolution: "@types/whatwg-mimetype@npm:3.0.2" @@ -19582,13 +18640,6 @@ __metadata: languageName: node linkType: hard -"any-promise@npm:^1.0.0": - version: 1.3.0 - resolution: "any-promise@npm:1.3.0" - checksum: 10/6737469ba353b5becf29e4dc3680736b9caa06d300bda6548812a8fee63ae7d336d756f88572fa6b5219aed36698d808fa55f62af3e7e6845c7a1dc77d240edb - languageName: node - linkType: hard - "anymatch@npm:~3.1.2": version: 3.1.3 resolution: "anymatch@npm:3.1.3" @@ -19688,7 +18739,7 @@ __metadata: languageName: node linkType: hard -"arg@npm:5.0.2, arg@npm:^5.0.2": +"arg@npm:5.0.2": version: 5.0.2 resolution: "arg@npm:5.0.2" checksum: 10/92fe7de222054a060fd2329e92e867410b3ea260328147ee3fb7855f78efae005f4087e698d4e688a856893c56bb09951588c40f2c901cf6996cd8cd7bcfef2c @@ -19925,7 +18976,7 @@ __metadata: languageName: node linkType: hard -"autoprefixer@npm:10.4.21, autoprefixer@npm:^10.4.20": +"autoprefixer@npm:^10.4.20": version: 10.4.21 resolution: "autoprefixer@npm:10.4.21" dependencies: @@ -20339,17 +19390,6 @@ __metadata: languageName: node linkType: hard -"browser-image-hash@npm:^0.0.5": - version: 0.0.5 - resolution: "browser-image-hash@npm:0.0.5" - dependencies: - "@rgba-image/lanczos": "npm:^0.1.0" - decimal.js: "npm:^10.2.0" - wasm-imagemagick: "npm:^1.2.3" - checksum: 10/fa45bdcb4f6338a3e4a80b4495732b2a675f9dad9bb98999a2c39348fdc0057d772232972dee32db9f1a58de509355731c31b2d1533e5ac93f285d809775addd - languageName: node - linkType: hard - "browserslist@npm:^4.0.0, browserslist@npm:^4.24.0, browserslist@npm:^4.24.4, browserslist@npm:^4.24.5, browserslist@npm:^4.28.1": version: 4.28.1 resolution: "browserslist@npm:4.28.1" @@ -20675,13 +19715,6 @@ __metadata: languageName: node linkType: hard -"camelcase-css@npm:^2.0.1": - version: 2.0.1 - resolution: "camelcase-css@npm:2.0.1" - checksum: 10/1cec2b3b3dcb5026688a470b00299a8db7d904c4802845c353dbd12d9d248d3346949a814d83bfd988d4d2e5b9904c07efe76fecd195a1d4f05b543e7c0b56b1 - languageName: node - linkType: hard - "camelcase@npm:^5.3.1": version: 5.3.1 resolution: "camelcase@npm:5.3.1" @@ -20708,7 +19741,7 @@ __metadata: languageName: node linkType: hard -"caniuse-lite@npm:^1.0.0, caniuse-lite@npm:^1.0.30001579, caniuse-lite@npm:^1.0.30001702, caniuse-lite@npm:^1.0.30001759": +"caniuse-lite@npm:^1.0.0, caniuse-lite@npm:^1.0.30001702, caniuse-lite@npm:^1.0.30001759": version: 1.0.30001774 resolution: "caniuse-lite@npm:1.0.30001774" checksum: 10/63c87aeac08548847ecd12746144029761707d9eae57750f673543a2b2a6126bca98584dd551818e8dc2a480d11489bebe0027af26de4ee46466e7b216109862 @@ -21245,7 +20278,7 @@ __metadata: languageName: node linkType: hard -"client-only@npm:0.0.1, client-only@npm:^0.0.1": +"client-only@npm:^0.0.1": version: 0.0.1 resolution: "client-only@npm:0.0.1" checksum: 10/0c16bf660dadb90610553c1d8946a7fdfb81d624adea073b8440b7d795d5b5b08beb3c950c6a2cf16279365a3265158a236876d92bce16423c485c322d7dfaf8 @@ -21334,7 +20367,7 @@ __metadata: languageName: node linkType: hard -"clsx@npm:2.1.1, clsx@npm:^2.0.0, clsx@npm:^2.1.1": +"clsx@npm:^2.0.0, clsx@npm:^2.1.1": version: 2.1.1 resolution: "clsx@npm:2.1.1" checksum: 10/cdfb57fa6c7649bbff98d9028c2f0de2f91c86f551179541cf784b1cfdc1562dcb951955f46d54d930a3879931a980e32a46b598acaea274728dbe068deca919 @@ -21523,13 +20556,6 @@ __metadata: languageName: node linkType: hard -"commander@npm:^4.0.0": - version: 4.1.1 - resolution: "commander@npm:4.1.1" - checksum: 10/3b2dc4125f387dab73b3294dbcb0ab2a862f9c0ad748ee2b27e3544d25325b7a8cdfbcc228d103a98a716960b14478114a5206b5415bd48cdafa38797891562c - languageName: node - linkType: hard - "commander@npm:^5.0.0": version: 5.1.0 resolution: "commander@npm:5.1.0" @@ -22808,7 +21834,7 @@ __metadata: languageName: node linkType: hard -"debug@npm:~4.3.1, debug@npm:~4.3.2, debug@npm:~4.3.4": +"debug@npm:~4.3.1, debug@npm:~4.3.4": version: 4.3.7 resolution: "debug@npm:4.3.7" dependencies: @@ -22827,7 +21853,7 @@ __metadata: languageName: node linkType: hard -"decimal.js@npm:^10.2.0, decimal.js@npm:^10.4.3": +"decimal.js@npm:^10.4.3": version: 10.6.0 resolution: "decimal.js@npm:10.6.0" checksum: 10/c0d45842d47c311d11b38ce7ccc911121953d4df3ebb1465d92b31970eb4f6738a065426a06094af59bee4b0d64e42e7c8984abd57b6767c64ea90cf90bb4a69 @@ -23057,7 +22083,7 @@ __metadata: languageName: node linkType: hard -"detect-libc@npm:^2.0.0, detect-libc@npm:^2.0.1, detect-libc@npm:^2.0.3, detect-libc@npm:^2.1.0, detect-libc@npm:^2.1.2": +"detect-libc@npm:^2.0.0, detect-libc@npm:^2.0.1, detect-libc@npm:^2.0.3": version: 2.1.2 resolution: "detect-libc@npm:2.1.2" checksum: 10/b736c8d97d5d46164c0d1bed53eb4e6a3b1d8530d460211e2d52f1c552875e706c58a5376854e4e54f8b828c9cada58c855288c968522eb93ac7696d65970766 @@ -23104,13 +22130,6 @@ __metadata: languageName: node linkType: hard -"didyoumean@npm:^1.2.2": - version: 1.2.2 - resolution: "didyoumean@npm:1.2.2" - checksum: 10/de7f11b6a0c8c61018629b7f405bb9746d6e994ce87c1a4b7655c3c718442dc69037a3d46d804950604fd9cbe85c074f7b224a119fc1bda851690a74540c6cf8 - languageName: node - linkType: hard - "diff@npm:^8.0.2": version: 8.0.3 resolution: "diff@npm:8.0.3" @@ -23144,13 +22163,6 @@ __metadata: languageName: node linkType: hard -"dlv@npm:^1.1.3": - version: 1.1.3 - resolution: "dlv@npm:1.1.3" - checksum: 10/836459ec6b50e43e9ed388a5fc28954be99e3481af3fa4b5d82a600762eb65ef8faacd454097ed7fc2f8a60aea2800d65a4cece5cd0d81ab82b2031f3f759e6e - languageName: node - linkType: hard - "dns-packet@npm:^5.2.2": version: 5.6.1 resolution: "dns-packet@npm:5.6.1" @@ -23801,15 +22813,6 @@ __metadata: languageName: node linkType: hard -"error-stack-parser@npm:^2.0.6": - version: 2.1.4 - resolution: "error-stack-parser@npm:2.1.4" - dependencies: - stackframe: "npm:^1.3.4" - checksum: 10/23db33135bfc6ba701e5eee45e1bb9bd2fe33c5d4f9927440d9a499c7ac538f91f455fcd878611361269893c56734419252c40d8105eb3b023cf8b0fc2ebb64e - languageName: node - linkType: hard - "es-iterator-helpers@npm:@nolyfill/es-iterator-helpers@^1": version: 1.0.21 resolution: "@nolyfill/es-iterator-helpers@npm:1.0.21" @@ -23859,95 +22862,6 @@ __metadata: languageName: node linkType: hard -"esbuild@npm:0.25.10, esbuild@npm:^0.25.0": - version: 0.25.10 - resolution: "esbuild@npm:0.25.10" - dependencies: - "@esbuild/aix-ppc64": "npm:0.25.10" - "@esbuild/android-arm": "npm:0.25.10" - "@esbuild/android-arm64": "npm:0.25.10" - "@esbuild/android-x64": "npm:0.25.10" - "@esbuild/darwin-arm64": "npm:0.25.10" - "@esbuild/darwin-x64": "npm:0.25.10" - "@esbuild/freebsd-arm64": "npm:0.25.10" - "@esbuild/freebsd-x64": "npm:0.25.10" - "@esbuild/linux-arm": "npm:0.25.10" - "@esbuild/linux-arm64": "npm:0.25.10" - "@esbuild/linux-ia32": "npm:0.25.10" - "@esbuild/linux-loong64": "npm:0.25.10" - "@esbuild/linux-mips64el": "npm:0.25.10" - "@esbuild/linux-ppc64": "npm:0.25.10" - "@esbuild/linux-riscv64": "npm:0.25.10" - "@esbuild/linux-s390x": "npm:0.25.10" - "@esbuild/linux-x64": "npm:0.25.10" - "@esbuild/netbsd-arm64": "npm:0.25.10" - "@esbuild/netbsd-x64": "npm:0.25.10" - "@esbuild/openbsd-arm64": "npm:0.25.10" - "@esbuild/openbsd-x64": "npm:0.25.10" - "@esbuild/openharmony-arm64": "npm:0.25.10" - "@esbuild/sunos-x64": "npm:0.25.10" - "@esbuild/win32-arm64": "npm:0.25.10" - "@esbuild/win32-ia32": "npm:0.25.10" - "@esbuild/win32-x64": "npm:0.25.10" - dependenciesMeta: - "@esbuild/aix-ppc64": - optional: true - "@esbuild/android-arm": - optional: true - "@esbuild/android-arm64": - optional: true - "@esbuild/android-x64": - optional: true - "@esbuild/darwin-arm64": - optional: true - "@esbuild/darwin-x64": - optional: true - "@esbuild/freebsd-arm64": - optional: true - "@esbuild/freebsd-x64": - optional: true - "@esbuild/linux-arm": - optional: true - "@esbuild/linux-arm64": - optional: true - "@esbuild/linux-ia32": - optional: true - "@esbuild/linux-loong64": - optional: true - "@esbuild/linux-mips64el": - optional: true - "@esbuild/linux-ppc64": - optional: true - "@esbuild/linux-riscv64": - optional: true - "@esbuild/linux-s390x": - optional: true - "@esbuild/linux-x64": - optional: true - "@esbuild/netbsd-arm64": - optional: true - "@esbuild/netbsd-x64": - optional: true - "@esbuild/openbsd-arm64": - optional: true - "@esbuild/openbsd-x64": - optional: true - "@esbuild/openharmony-arm64": - optional: true - "@esbuild/sunos-x64": - optional: true - "@esbuild/win32-arm64": - optional: true - "@esbuild/win32-ia32": - optional: true - "@esbuild/win32-x64": - optional: true - bin: - esbuild: bin/esbuild - checksum: 10/a8e4d33d7e785b7c8e1255d2ef532a53d1406659dbf2d0d3cdeb95c4760f51f86683e42974643b4f1dbe58381b6c7ce1217d4c8325f84353fbfc40be7b326358 - languageName: node - linkType: hard - "esbuild@npm:^0.18.0 || ^0.19.0 || ^0.20.0 || ^0.21.0 || ^0.22.0 || ^0.23.0 || ^0.24.0 || ^0.25.0 || ^0.26.0 || ^0.27.0, esbuild@npm:^0.27.0, esbuild@npm:esbuild@>=0.17.6 <0.28.0, esbuild@npm:~0.27.0": version: 0.27.3 resolution: "esbuild@npm:0.27.3" @@ -24037,6 +22951,95 @@ __metadata: languageName: node linkType: hard +"esbuild@npm:^0.25.0": + version: 0.25.10 + resolution: "esbuild@npm:0.25.10" + dependencies: + "@esbuild/aix-ppc64": "npm:0.25.10" + "@esbuild/android-arm": "npm:0.25.10" + "@esbuild/android-arm64": "npm:0.25.10" + "@esbuild/android-x64": "npm:0.25.10" + "@esbuild/darwin-arm64": "npm:0.25.10" + "@esbuild/darwin-x64": "npm:0.25.10" + "@esbuild/freebsd-arm64": "npm:0.25.10" + "@esbuild/freebsd-x64": "npm:0.25.10" + "@esbuild/linux-arm": "npm:0.25.10" + "@esbuild/linux-arm64": "npm:0.25.10" + "@esbuild/linux-ia32": "npm:0.25.10" + "@esbuild/linux-loong64": "npm:0.25.10" + "@esbuild/linux-mips64el": "npm:0.25.10" + "@esbuild/linux-ppc64": "npm:0.25.10" + "@esbuild/linux-riscv64": "npm:0.25.10" + "@esbuild/linux-s390x": "npm:0.25.10" + "@esbuild/linux-x64": "npm:0.25.10" + "@esbuild/netbsd-arm64": "npm:0.25.10" + "@esbuild/netbsd-x64": "npm:0.25.10" + "@esbuild/openbsd-arm64": "npm:0.25.10" + "@esbuild/openbsd-x64": "npm:0.25.10" + "@esbuild/openharmony-arm64": "npm:0.25.10" + "@esbuild/sunos-x64": "npm:0.25.10" + "@esbuild/win32-arm64": "npm:0.25.10" + "@esbuild/win32-ia32": "npm:0.25.10" + "@esbuild/win32-x64": "npm:0.25.10" + dependenciesMeta: + "@esbuild/aix-ppc64": + optional: true + "@esbuild/android-arm": + optional: true + "@esbuild/android-arm64": + optional: true + "@esbuild/android-x64": + optional: true + "@esbuild/darwin-arm64": + optional: true + "@esbuild/darwin-x64": + optional: true + "@esbuild/freebsd-arm64": + optional: true + "@esbuild/freebsd-x64": + optional: true + "@esbuild/linux-arm": + optional: true + "@esbuild/linux-arm64": + optional: true + "@esbuild/linux-ia32": + optional: true + "@esbuild/linux-loong64": + optional: true + "@esbuild/linux-mips64el": + optional: true + "@esbuild/linux-ppc64": + optional: true + "@esbuild/linux-riscv64": + optional: true + "@esbuild/linux-s390x": + optional: true + "@esbuild/linux-x64": + optional: true + "@esbuild/netbsd-arm64": + optional: true + "@esbuild/netbsd-x64": + optional: true + "@esbuild/openbsd-arm64": + optional: true + "@esbuild/openbsd-x64": + optional: true + "@esbuild/openharmony-arm64": + optional: true + "@esbuild/sunos-x64": + optional: true + "@esbuild/win32-arm64": + optional: true + "@esbuild/win32-ia32": + optional: true + "@esbuild/win32-x64": + optional: true + bin: + esbuild: bin/esbuild + checksum: 10/a8e4d33d7e785b7c8e1255d2ef532a53d1406659dbf2d0d3cdeb95c4760f51f86683e42974643b4f1dbe58381b6c7ce1217d4c8325f84353fbfc40be7b326358 + languageName: node + linkType: hard + "escalade@npm:^3.1.1, escalade@npm:^3.2.0": version: 3.2.0 resolution: "escalade@npm:3.2.0" @@ -24761,7 +23764,7 @@ __metadata: languageName: node linkType: hard -"fast-glob@npm:3.3.3, fast-glob@npm:^3.2.7, fast-glob@npm:^3.2.9, fast-glob@npm:^3.3.0, fast-glob@npm:^3.3.3": +"fast-glob@npm:3.3.3, fast-glob@npm:^3.2.7, fast-glob@npm:^3.2.9, fast-glob@npm:^3.3.3": version: 3.3.3 resolution: "fast-glob@npm:3.3.3" dependencies: @@ -24900,7 +23903,7 @@ __metadata: languageName: node linkType: hard -"fflate@npm:^0.8.1, fflate@npm:^0.8.2": +"fflate@npm:^0.8.2": version: 0.8.2 resolution: "fflate@npm:0.8.2" checksum: 10/2bd26ba6d235d428de793c6a0cd1aaa96a06269ebd4e21b46c8fd1bd136abc631acf27e188d47c3936db090bf3e1ede11d15ce9eae9bffdc4bfe1b9dc66ca9cb @@ -25252,28 +24255,6 @@ __metadata: languageName: node linkType: hard -"framer-motion@npm:12.23.22": - version: 12.23.22 - resolution: "framer-motion@npm:12.23.22" - dependencies: - motion-dom: "npm:^12.23.21" - motion-utils: "npm:^12.23.6" - tslib: "npm:^2.4.0" - peerDependencies: - "@emotion/is-prop-valid": "*" - react: ^18.0.0 || ^19.0.0 - react-dom: ^18.0.0 || ^19.0.0 - peerDependenciesMeta: - "@emotion/is-prop-valid": - optional: true - react: - optional: true - react-dom: - optional: true - checksum: 10/ea16b23a7587634e42a5fd0ac0fafaaee34ec720947f9cd4c7f80d7e8a68c3371df43309c1216302387b7d3682d132c27d376b2b63628df56270539046c3acda - languageName: node - linkType: hard - "fresh@npm:^2.0.0": version: 2.0.0 resolution: "fresh@npm:2.0.0" @@ -25837,13 +24818,6 @@ __metadata: languageName: node linkType: hard -"globals@npm:^11.1.0": - version: 11.12.0 - resolution: "globals@npm:11.12.0" - checksum: 10/9f054fa38ff8de8fa356502eb9d2dae0c928217b8b5c8de1f09f5c9b6c8a96d8b9bd3afc49acbcd384a98a81fea713c859e1b09e214c60509517bb8fc2bc13c2 - languageName: node - linkType: hard - "globals@npm:^14.0.0": version: 14.0.0 resolution: "globals@npm:14.0.0" @@ -26278,7 +25252,7 @@ __metadata: languageName: node linkType: hard -"he@npm:1.2.0, he@npm:^1.2.0": +"he@npm:^1.2.0": version: 1.2.0 resolution: "he@npm:1.2.0" bin: @@ -26361,13 +25335,6 @@ __metadata: languageName: node linkType: hard -"howler@npm:^2.2.3": - version: 2.2.4 - resolution: "howler@npm:2.2.4" - checksum: 10/e4177f6581ede99fdec68c2dc16a01e74ed3e4f3b28d4804030246f74f15a50311bd3d4d332a6e968a296e6bae1d0a8c8703e8e22d98ef8f5a3299e545e2fe55 - languageName: node - linkType: hard - "hpack.js@npm:^2.1.6": version: 2.1.6 resolution: "hpack.js@npm:2.1.6" @@ -27755,7 +26722,7 @@ __metadata: languageName: node linkType: hard -"jiti@npm:^1.17.1, jiti@npm:^1.19.1, jiti@npm:^1.20.0, jiti@npm:^1.21.6": +"jiti@npm:^1.17.1, jiti@npm:^1.20.0, jiti@npm:^1.21.6": version: 1.21.7 resolution: "jiti@npm:1.21.7" bin: @@ -27980,7 +26947,7 @@ __metadata: languageName: node linkType: hard -"json5@npm:2.2.3, json5@npm:^2.1.2, json5@npm:^2.2.2, json5@npm:^2.2.3": +"json5@npm:^2.1.2, json5@npm:^2.2.2, json5@npm:^2.2.3": version: 2.2.3 resolution: "json5@npm:2.2.3" bin: @@ -28386,14 +27353,7 @@ __metadata: languageName: node linkType: hard -"lilconfig@npm:^2.1.0": - version: 2.1.0 - resolution: "lilconfig@npm:2.1.0" - checksum: 10/b1314a2e55319013d5e7d7d08be39015829d2764a1eaee130129545d40388499d81b1c31b0f9b3417d4db12775a88008b72ec33dd06e0184cf7503b32ca7cc0b - languageName: node - linkType: hard - -"lilconfig@npm:^3.0.0, lilconfig@npm:^3.1.3": +"lilconfig@npm:^3.1.3": version: 3.1.3 resolution: "lilconfig@npm:3.1.3" checksum: 10/b932ce1af94985f0efbe8896e57b1f814a48c8dbd7fc0ef8469785c6303ed29d0090af3ccad7e36b626bfca3a4dc56cc262697e9a8dd867623cf09a39d54e4c3 @@ -28495,17 +27455,6 @@ __metadata: languageName: node linkType: hard -"lit-element@npm:^3.3.0": - version: 3.3.3 - resolution: "lit-element@npm:3.3.3" - dependencies: - "@lit-labs/ssr-dom-shim": "npm:^1.1.0" - "@lit/reactive-element": "npm:^1.3.0" - lit-html: "npm:^2.8.0" - checksum: 10/7968e7f3ce3994911f27c4c54acc956488c91d8af81677cce3d6f0c2eaea45cceb79b064077159392238d6e43d46015a950269db9914fea8913566aacb17eaa1 - languageName: node - linkType: hard - "lit-element@npm:^4.2.0": version: 4.2.0 resolution: "lit-element@npm:4.2.0" @@ -28517,15 +27466,6 @@ __metadata: languageName: node linkType: hard -"lit-html@npm:^2.8.0": - version: 2.8.0 - resolution: "lit-html@npm:2.8.0" - dependencies: - "@types/trusted-types": "npm:^2.0.2" - checksum: 10/3503e55e2927c2ff94773cf041fc4128f92291869c9192f36eacb7f95132d11f6b329e5b910ab60a4456349cd2e6d23b33d83291b24d557bcd6b904d6314ac1a - languageName: node - linkType: hard - "lit-html@npm:^3.2.1, lit-html@npm:^3.3.0": version: 3.3.0 resolution: "lit-html@npm:3.3.0" @@ -28535,17 +27475,6 @@ __metadata: languageName: node linkType: hard -"lit@npm:^2.7.5": - version: 2.8.0 - resolution: "lit@npm:2.8.0" - dependencies: - "@lit/reactive-element": "npm:^1.6.0" - lit-element: "npm:^3.3.0" - lit-html: "npm:^2.8.0" - checksum: 10/aa64c1136b855ba328d41157dba67657d480345aeec3c1dd829abeb67719d759c9ff2ade9903f9cfb4f9d012b16087034aaa5b33f1182e70c615765562e3251b - languageName: node - linkType: hard - "lit@npm:^3.2.0, lit@npm:^3.2.1": version: 3.3.0 resolution: "lit@npm:3.3.0" @@ -28866,7 +27795,7 @@ __metadata: languageName: node linkType: hard -"log-symbols@npm:4.1.0, log-symbols@npm:^4.0.0, log-symbols@npm:^4.1.0": +"log-symbols@npm:^4.0.0, log-symbols@npm:^4.1.0": version: 4.1.0 resolution: "log-symbols@npm:4.1.0" dependencies: @@ -30376,13 +29305,6 @@ __metadata: languageName: node linkType: hard -"module-punycode@npm:punycode@2.3.1, punycode@npm:^2.1.0": - version: 2.3.1 - resolution: "punycode@npm:2.3.1" - checksum: 10/febdc4362bead22f9e2608ff0171713230b57aff9dddc1c273aa2a651fbd366f94b7d6a71d78342a7c0819906750351ca7f2edd26ea41b626d87d6a13d1bd059 - languageName: node - linkType: hard - "monaco-editor@npm:^0.52.2": version: 0.52.2 resolution: "monaco-editor@npm:0.52.2" @@ -30390,22 +29312,6 @@ __metadata: languageName: node linkType: hard -"motion-dom@npm:^12.23.21": - version: 12.34.3 - resolution: "motion-dom@npm:12.34.3" - dependencies: - motion-utils: "npm:^12.29.2" - checksum: 10/17abb91f87020f00470f886cced6c6ebd58b9d5848c9bb12eb38f029dc7077344cf6ac2ccbe0adf1a8996191c17a98abfe91eaa99a1723909d7dd25a4f2b1101 - languageName: node - linkType: hard - -"motion-utils@npm:^12.23.6, motion-utils@npm:^12.29.2": - version: 12.29.2 - resolution: "motion-utils@npm:12.29.2" - checksum: 10/ae5f9be58c07939af72334894ed1a18653d724946182a718dc3d11268ef26e63804c3f16dee5a6110596d4406b539c4513822b74f86adebef9488601c34b18b7 - languageName: node - linkType: hard - "mp4-muxer@npm:^5.2.2": version: 5.2.2 resolution: "mp4-muxer@npm:5.2.2" @@ -30612,17 +29518,6 @@ __metadata: languageName: node linkType: hard -"mz@npm:^2.7.0": - version: 2.7.0 - resolution: "mz@npm:2.7.0" - dependencies: - any-promise: "npm:^1.0.0" - object-assign: "npm:^4.0.1" - thenify-all: "npm:^1.0.0" - checksum: 10/8427de0ece99a07e9faed3c0c6778820d7543e3776f9a84d22cf0ec0a8eb65f6e9aee9c9d353ff9a105ff62d33a9463c6ca638974cc652ee8140cd1e35951c87 - languageName: node - linkType: hard - "nano-spawn@npm:^1.0.0": version: 1.0.1 resolution: "nano-spawn@npm:1.0.1" @@ -30630,7 +29525,7 @@ __metadata: languageName: node linkType: hard -"nanoid@npm:^3.3.11, nanoid@npm:^3.3.6": +"nanoid@npm:^3.3.11": version: 3.3.11 resolution: "nanoid@npm:3.3.11" bin: @@ -30764,65 +29659,6 @@ __metadata: languageName: node linkType: hard -"next@npm:15.5.2": - version: 15.5.2 - resolution: "next@npm:15.5.2" - dependencies: - "@next/env": "npm:15.5.2" - "@next/swc-darwin-arm64": "npm:15.5.2" - "@next/swc-darwin-x64": "npm:15.5.2" - "@next/swc-linux-arm64-gnu": "npm:15.5.2" - "@next/swc-linux-arm64-musl": "npm:15.5.2" - "@next/swc-linux-x64-gnu": "npm:15.5.2" - "@next/swc-linux-x64-musl": "npm:15.5.2" - "@next/swc-win32-arm64-msvc": "npm:15.5.2" - "@next/swc-win32-x64-msvc": "npm:15.5.2" - "@swc/helpers": "npm:0.5.15" - caniuse-lite: "npm:^1.0.30001579" - postcss: "npm:8.4.31" - sharp: "npm:^0.34.3" - styled-jsx: "npm:5.1.6" - peerDependencies: - "@opentelemetry/api": ^1.1.0 - "@playwright/test": ^1.51.1 - babel-plugin-react-compiler: "*" - react: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 - react-dom: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 - sass: ^1.3.0 - dependenciesMeta: - "@next/swc-darwin-arm64": - optional: true - "@next/swc-darwin-x64": - optional: true - "@next/swc-linux-arm64-gnu": - optional: true - "@next/swc-linux-arm64-musl": - optional: true - "@next/swc-linux-x64-gnu": - optional: true - "@next/swc-linux-x64-musl": - optional: true - "@next/swc-win32-arm64-msvc": - optional: true - "@next/swc-win32-x64-msvc": - optional: true - sharp: - optional: true - peerDependenciesMeta: - "@opentelemetry/api": - optional: true - "@playwright/test": - optional: true - babel-plugin-react-compiler: - optional: true - sass: - optional: true - bin: - next: dist/bin/next - checksum: 10/0e5a7420e7ea9bba57b32575378c9d74eb4cc95a34453d0e88dd6212f95d7d4f9fd35a106dba0ca5f537e3265a3ab48cf93487f7c792502ee83da3a9bb4be92c - languageName: node - linkType: hard - "nice-try@npm:^1.0.4": version: 1.0.5 resolution: "nice-try@npm:1.0.5" @@ -30984,16 +29820,6 @@ __metadata: languageName: node linkType: hard -"node-html-parser@npm:7.0.1": - version: 7.0.1 - resolution: "node-html-parser@npm:7.0.1" - dependencies: - css-select: "npm:^5.1.0" - he: "npm:1.2.0" - checksum: 10/726db99091551ab3620f001892d6afb4c87b505ffc8fc6b8cd7bb225701a805b85615504dd93a0d4ee095ef46d2ec4dabc9b61165d8034704b191601f5bf6936 - languageName: node - linkType: hard - "node-int64@npm:^0.4.0": version: 0.4.0 resolution: "node-int64@npm:0.4.0" @@ -31199,14 +30025,14 @@ __metadata: languageName: node linkType: hard -"object-assign@npm:^4, object-assign@npm:^4.0.1, object-assign@npm:^4.1.0, object-assign@npm:^4.1.1": +"object-assign@npm:^4, object-assign@npm:^4.1.0, object-assign@npm:^4.1.1": version: 4.1.1 resolution: "object-assign@npm:4.1.1" checksum: 10/fcc6e4ea8c7fe48abfbb552578b1c53e0d194086e2e6bbbf59e0a536381a292f39943c6e9628af05b5528aa5e3318bb30d6b2e53cadaf5b8fe9e12c4b69af23f languageName: node linkType: hard -"object-hash@npm:3.0.0, object-hash@npm:^3.0.0": +"object-hash@npm:3.0.0": version: 3.0.0 resolution: "object-hash@npm:3.0.0" checksum: 10/f498d456a20512ba7be500cef4cf7b3c183cc72c65372a549c9a0e6dd78ce26f375e9b1315c07592d3fde8f10d5019986eba35970570d477ed9a2a702514432a @@ -31426,7 +30252,7 @@ __metadata: languageName: node linkType: hard -"ora@npm:5.4.1, ora@npm:^5.1.0, ora@npm:^5.4.1": +"ora@npm:^5.1.0, ora@npm:^5.4.1": version: 5.4.1 resolution: "ora@npm:5.4.1" dependencies: @@ -31647,13 +30473,6 @@ __metadata: languageName: node linkType: hard -"p-map@npm:^2.0.0": - version: 2.1.0 - resolution: "p-map@npm:2.1.0" - checksum: 10/9e3ad3c9f6d75a5b5661bcad78c91f3a63849189737cd75e4f1225bf9ac205194e5c44aac2ef6f09562b1facdb9bd1425584d7ac375bfaa17b3f1a142dab936d - languageName: node - linkType: hard - "p-map@npm:^4.0.0": version: 4.0.0 resolution: "p-map@npm:4.0.0" @@ -32222,20 +31041,13 @@ __metadata: languageName: node linkType: hard -"pify@npm:^2.0.0, pify@npm:^2.3.0": +"pify@npm:^2.0.0": version: 2.3.0 resolution: "pify@npm:2.3.0" checksum: 10/9503aaeaf4577acc58642ad1d25c45c6d90288596238fb68f82811c08104c800e5a7870398e9f015d82b44ecbcbef3dc3d4251a1cbb582f6e5959fe09884b2ba languageName: node linkType: hard -"pirates@npm:^4.0.1": - version: 4.0.7 - resolution: "pirates@npm:4.0.7" - checksum: 10/2427f371366081ae42feb58214f04805d6b41d6b84d74480ebcc9e0ddbd7105a139f7c653daeaf83ad8a1a77214cf07f64178e76de048128fec501eab3305a96 - languageName: node - linkType: hard - "piscina@npm:^5.1.4": version: 5.1.4 resolution: "piscina@npm:5.1.4" @@ -32437,48 +31249,6 @@ __metadata: languageName: node linkType: hard -"postcss-import@npm:^15.1.0": - version: 15.1.0 - resolution: "postcss-import@npm:15.1.0" - dependencies: - postcss-value-parser: "npm:^4.0.0" - read-cache: "npm:^1.0.0" - resolve: "npm:^1.1.7" - peerDependencies: - postcss: ^8.0.0 - checksum: 10/33c91b7e6b794b5c33d7d7d4730e5f0729c131d2de1ada7fcc116955625a78c3ce613983f019fa9447681795cf3f851e9c38dfbe3f48a2d08a8aef917c70a32a - languageName: node - linkType: hard - -"postcss-js@npm:^4.0.1": - version: 4.1.0 - resolution: "postcss-js@npm:4.1.0" - dependencies: - camelcase-css: "npm:^2.0.1" - peerDependencies: - postcss: ^8.4.21 - checksum: 10/32f5422478e60086e5d70b4ea6f4bcdb15baae16e9e311497fbbf5e6d07dfb5916e7fd61957e8664b923c8c68a5bd364cb0517d8e263cfd12cc601a1c1ab9ad2 - languageName: node - linkType: hard - -"postcss-load-config@npm:^4.0.1": - version: 4.0.2 - resolution: "postcss-load-config@npm:4.0.2" - dependencies: - lilconfig: "npm:^3.0.0" - yaml: "npm:^2.3.4" - peerDependencies: - postcss: ">=8.0.9" - ts-node: ">=9.0.0" - peerDependenciesMeta: - postcss: - optional: true - ts-node: - optional: true - checksum: 10/e2c2ed9b7998a5b123e1ce0c124daf6504b1454c67dcc1c8fdbcc5ffb2597b7de245e3ac34f63afc928d3fd3260b1e36492ebbdb01a9ff63f16b3c8b7b925d1b - languageName: node - linkType: hard - "postcss-loader@npm:^8.1.1": version: 8.1.1 resolution: "postcss-loader@npm:8.1.1" @@ -32618,17 +31388,6 @@ __metadata: languageName: node linkType: hard -"postcss-nested@npm:^6.0.1": - version: 6.2.0 - resolution: "postcss-nested@npm:6.2.0" - dependencies: - postcss-selector-parser: "npm:^6.1.1" - peerDependencies: - postcss: ^8.2.14 - checksum: 10/d7f6ba6bfd03d42f84689a0630d4e393c421bb53723f16fe179a840f03ed17763b0fe494458577d2a015e857e0ec27c7e194909ffe209ee5f0676aec39737317 - languageName: node - linkType: hard - "postcss-normalize-charset@npm:^7.0.1": version: 7.0.1 resolution: "postcss-normalize-charset@npm:7.0.1" @@ -32762,16 +31521,6 @@ __metadata: languageName: node linkType: hard -"postcss-selector-parser@npm:^6.0.11, postcss-selector-parser@npm:^6.1.1": - version: 6.1.2 - resolution: "postcss-selector-parser@npm:6.1.2" - dependencies: - cssesc: "npm:^3.0.0" - util-deprecate: "npm:^1.0.2" - checksum: 10/190034c94d809c115cd2f32ee6aade84e933450a43ec3899c3e78e7d7b33efd3a2a975bb45d7700b6c5b196c06a7d9acf3f1ba6f1d87032d9675a29d8bca1dd3 - languageName: node - linkType: hard - "postcss-selector-parser@npm:^7.0.0, postcss-selector-parser@npm:^7.1.0": version: 7.1.0 resolution: "postcss-selector-parser@npm:7.1.0" @@ -32805,25 +31554,14 @@ __metadata: languageName: node linkType: hard -"postcss-value-parser@npm:^4.0.0, postcss-value-parser@npm:^4.1.0, postcss-value-parser@npm:^4.2.0": +"postcss-value-parser@npm:^4.1.0, postcss-value-parser@npm:^4.2.0": version: 4.2.0 resolution: "postcss-value-parser@npm:4.2.0" checksum: 10/e4e4486f33b3163a606a6ed94f9c196ab49a37a7a7163abfcd469e5f113210120d70b8dd5e33d64636f41ad52316a3725655421eb9a1094f1bcab1db2f555c62 languageName: node linkType: hard -"postcss@npm:8.4.31": - version: 8.4.31 - resolution: "postcss@npm:8.4.31" - dependencies: - nanoid: "npm:^3.3.6" - picocolors: "npm:^1.0.0" - source-map-js: "npm:^1.0.2" - checksum: 10/1a6653e72105907377f9d4f2cd341d8d90e3fde823a5ddea1e2237aaa56933ea07853f0f2758c28892a1d70c53bbaca200eb8b80f8ed55f13093003dbec5afa0 - languageName: node - linkType: hard - -"postcss@npm:^8.4.23, postcss@npm:^8.4.33, postcss@npm:^8.4.41, postcss@npm:^8.4.49, postcss@npm:^8.5.6": +"postcss@npm:^8.4.33, postcss@npm:^8.4.41, postcss@npm:^8.4.49, postcss@npm:^8.5.6": version: 8.5.6 resolution: "postcss@npm:8.5.6" dependencies: @@ -32891,13 +31629,6 @@ __metadata: languageName: node linkType: hard -"pretty-bytes@npm:6.1.1": - version: 6.1.1 - resolution: "pretty-bytes@npm:6.1.1" - checksum: 10/43d29d909d2d88072da2c3d72f8fd0f2d2523c516bfa640aff6e31f596ea1004b6601f4cabc50d14b2cf10e82635ebe5b7d9378f3d5bae1c0067131829421b8a - languageName: node - linkType: hard - "pretty-error@npm:^4.0.0": version: 4.0.0 resolution: "pretty-error@npm:4.0.0" @@ -32928,18 +31659,6 @@ __metadata: languageName: node linkType: hard -"prism-react-renderer@npm:2.4.1": - version: 2.4.1 - resolution: "prism-react-renderer@npm:2.4.1" - dependencies: - "@types/prismjs": "npm:^1.26.0" - clsx: "npm:^2.0.0" - peerDependencies: - react: ">=16.0.0" - checksum: 10/f76ea89b8b18c477eb74e9ddda2571b5c4d21142731f6733160723aa03567b17df315d7db68ffb1122c199750ece65578ecacb488559229b26db5474d6aae55b - languageName: node - linkType: hard - "prisma@npm:^6.6.0": version: 6.8.2 resolution: "prisma@npm:6.8.2" @@ -33145,6 +31864,13 @@ __metadata: languageName: node linkType: hard +"punycode@npm:^2.1.0": + version: 2.3.1 + resolution: "punycode@npm:2.3.1" + checksum: 10/febdc4362bead22f9e2608ff0171713230b57aff9dddc1c273aa2a651fbd366f94b7d6a71d78342a7c0819906750351ca7f2edd26ea41b626d87d6a13d1bd059 + languageName: node + linkType: hard + "qr-creator@npm:^1.0.0": version: 1.0.0 resolution: "qr-creator@npm:1.0.0" @@ -33452,17 +32178,6 @@ __metadata: languageName: node linkType: hard -"react-dom@npm:19.0.0": - version: 19.0.0 - resolution: "react-dom@npm:19.0.0" - dependencies: - scheduler: "npm:^0.25.0" - peerDependencies: - react: ^19.0.0 - checksum: 10/aa64a2f1991042f516260e8b0eca0ae777b6c8f1aa2b5ae096e80bbb6ac9b005aef2bca697969841d34f7e1819556263476bdfea36c35092e8d9aefde3de2d9a - languageName: node - linkType: hard - "react-dom@npm:19.2.1, react-dom@npm:^19.2.1": version: 19.2.1 resolution: "react-dom@npm:19.2.1" @@ -33842,13 +32557,6 @@ __metadata: languageName: node linkType: hard -"react@npm:19.0.0": - version: 19.0.0 - resolution: "react@npm:19.0.0" - checksum: 10/2490969c503f644703c88990d20e4011fa6119ddeca451e9de48f6d7ab058d670d2852a5fcd3aa3cd90a923ab2815d532637bd4a814add402ae5c0d4f129ee71 - languageName: node - linkType: hard - "react@npm:^19.2.1": version: 19.2.1 resolution: "react@npm:19.2.1" @@ -33867,15 +32575,6 @@ __metadata: languageName: node linkType: hard -"read-cache@npm:^1.0.0": - version: 1.0.0 - resolution: "read-cache@npm:1.0.0" - dependencies: - pify: "npm:^2.3.0" - checksum: 10/83a39149d9dfa38f0c482ea0d77b34773c92fef07fe7599cdd914d255b14d0453e0229ef6379d8d27d6947f42d7581635296d0cfa7708f05a9bd8e789d398b31 - languageName: node - linkType: hard - "read-pkg-up@npm:^2.0.0": version: 2.0.0 resolution: "read-pkg-up@npm:2.0.0" @@ -34350,7 +33049,7 @@ __metadata: languageName: node linkType: hard -"resolve@npm:^1.1.6, resolve@npm:^1.1.7, resolve@npm:^1.10.0, resolve@npm:^1.19.0, resolve@npm:^1.20.0, resolve@npm:^1.22.1, resolve@npm:^1.22.2, resolve@npm:^1.22.8": +"resolve@npm:^1.1.6, resolve@npm:^1.10.0, resolve@npm:^1.19.0, resolve@npm:^1.20.0, resolve@npm:^1.22.1, resolve@npm:^1.22.8": version: 1.22.11 resolution: "resolve@npm:1.22.11" dependencies: @@ -34376,7 +33075,7 @@ __metadata: languageName: node linkType: hard -"resolve@patch:resolve@npm%3A^1.1.6#optional!builtin, resolve@patch:resolve@npm%3A^1.1.7#optional!builtin, resolve@patch:resolve@npm%3A^1.10.0#optional!builtin, resolve@patch:resolve@npm%3A^1.19.0#optional!builtin, resolve@patch:resolve@npm%3A^1.20.0#optional!builtin, resolve@patch:resolve@npm%3A^1.22.1#optional!builtin, resolve@patch:resolve@npm%3A^1.22.2#optional!builtin, resolve@patch:resolve@npm%3A^1.22.8#optional!builtin": +"resolve@patch:resolve@npm%3A^1.1.6#optional!builtin, resolve@patch:resolve@npm%3A^1.10.0#optional!builtin, resolve@patch:resolve@npm%3A^1.19.0#optional!builtin, resolve@patch:resolve@npm%3A^1.20.0#optional!builtin, resolve@patch:resolve@npm%3A^1.22.1#optional!builtin, resolve@patch:resolve@npm%3A^1.22.8#optional!builtin": version: 1.22.11 resolution: "resolve@patch:resolve@npm%3A1.22.11#optional!builtin::version=1.22.11&hash=c3c19d" dependencies: @@ -34738,13 +33437,6 @@ __metadata: languageName: node linkType: hard -"scheduler@npm:^0.25.0": - version: 0.25.0 - resolution: "scheduler@npm:0.25.0" - checksum: 10/e661e38503ab29a153429a99203fefa764f28b35c079719eb5efdd2c1c1086522f6653d8ffce388209682c23891a6d1d32fa6badf53c35fb5b9cd0c55ace42de - languageName: node - linkType: hard - "scheduler@npm:^0.27.0": version: 0.27.0 resolution: "scheduler@npm:0.27.0" @@ -35072,246 +33764,6 @@ __metadata: languageName: node linkType: hard -"sharp-phash@npm:^2.1.0": - version: 2.2.0 - resolution: "sharp-phash@npm:2.2.0" - peerDependencies: - sharp: ">= 0.32.0" - checksum: 10/a9b0ca1426c5ce618d956e3bf23acdb2b341833b53a69e959fad4a91a0751ae8310e5d82f045fb3eba27b40d1de258096038fc1c6b13dd71aa10a8bee28d071f - languageName: node - linkType: hard - -"sharp@npm:0.34.4": - version: 0.34.4 - resolution: "sharp@npm:0.34.4" - dependencies: - "@img/colour": "npm:^1.0.0" - "@img/sharp-darwin-arm64": "npm:0.34.4" - "@img/sharp-darwin-x64": "npm:0.34.4" - "@img/sharp-libvips-darwin-arm64": "npm:1.2.3" - "@img/sharp-libvips-darwin-x64": "npm:1.2.3" - "@img/sharp-libvips-linux-arm": "npm:1.2.3" - "@img/sharp-libvips-linux-arm64": "npm:1.2.3" - "@img/sharp-libvips-linux-ppc64": "npm:1.2.3" - "@img/sharp-libvips-linux-s390x": "npm:1.2.3" - "@img/sharp-libvips-linux-x64": "npm:1.2.3" - "@img/sharp-libvips-linuxmusl-arm64": "npm:1.2.3" - "@img/sharp-libvips-linuxmusl-x64": "npm:1.2.3" - "@img/sharp-linux-arm": "npm:0.34.4" - "@img/sharp-linux-arm64": "npm:0.34.4" - "@img/sharp-linux-ppc64": "npm:0.34.4" - "@img/sharp-linux-s390x": "npm:0.34.4" - "@img/sharp-linux-x64": "npm:0.34.4" - "@img/sharp-linuxmusl-arm64": "npm:0.34.4" - "@img/sharp-linuxmusl-x64": "npm:0.34.4" - "@img/sharp-wasm32": "npm:0.34.4" - "@img/sharp-win32-arm64": "npm:0.34.4" - "@img/sharp-win32-ia32": "npm:0.34.4" - "@img/sharp-win32-x64": "npm:0.34.4" - detect-libc: "npm:^2.1.0" - semver: "npm:^7.7.2" - dependenciesMeta: - "@img/sharp-darwin-arm64": - optional: true - "@img/sharp-darwin-x64": - optional: true - "@img/sharp-libvips-darwin-arm64": - optional: true - "@img/sharp-libvips-darwin-x64": - optional: true - "@img/sharp-libvips-linux-arm": - optional: true - "@img/sharp-libvips-linux-arm64": - optional: true - "@img/sharp-libvips-linux-ppc64": - optional: true - "@img/sharp-libvips-linux-s390x": - optional: true - "@img/sharp-libvips-linux-x64": - optional: true - "@img/sharp-libvips-linuxmusl-arm64": - optional: true - "@img/sharp-libvips-linuxmusl-x64": - optional: true - "@img/sharp-linux-arm": - optional: true - "@img/sharp-linux-arm64": - optional: true - "@img/sharp-linux-ppc64": - optional: true - "@img/sharp-linux-s390x": - optional: true - "@img/sharp-linux-x64": - optional: true - "@img/sharp-linuxmusl-arm64": - optional: true - "@img/sharp-linuxmusl-x64": - optional: true - "@img/sharp-wasm32": - optional: true - "@img/sharp-win32-arm64": - optional: true - "@img/sharp-win32-ia32": - optional: true - "@img/sharp-win32-x64": - optional: true - checksum: 10/8e6268e3b0fba7704291684e63c2829963a5ec311d8a8ebbcd32d750c4efb0b01594d925d289ccb5ac0ac373df40fedf5a05a8f331470db799b9c78c48923cba - languageName: node - linkType: hard - -"sharp@npm:^0.33.2": - version: 0.33.5 - resolution: "sharp@npm:0.33.5" - dependencies: - "@img/sharp-darwin-arm64": "npm:0.33.5" - "@img/sharp-darwin-x64": "npm:0.33.5" - "@img/sharp-libvips-darwin-arm64": "npm:1.0.4" - "@img/sharp-libvips-darwin-x64": "npm:1.0.4" - "@img/sharp-libvips-linux-arm": "npm:1.0.5" - "@img/sharp-libvips-linux-arm64": "npm:1.0.4" - "@img/sharp-libvips-linux-s390x": "npm:1.0.4" - "@img/sharp-libvips-linux-x64": "npm:1.0.4" - "@img/sharp-libvips-linuxmusl-arm64": "npm:1.0.4" - "@img/sharp-libvips-linuxmusl-x64": "npm:1.0.4" - "@img/sharp-linux-arm": "npm:0.33.5" - "@img/sharp-linux-arm64": "npm:0.33.5" - "@img/sharp-linux-s390x": "npm:0.33.5" - "@img/sharp-linux-x64": "npm:0.33.5" - "@img/sharp-linuxmusl-arm64": "npm:0.33.5" - "@img/sharp-linuxmusl-x64": "npm:0.33.5" - "@img/sharp-wasm32": "npm:0.33.5" - "@img/sharp-win32-ia32": "npm:0.33.5" - "@img/sharp-win32-x64": "npm:0.33.5" - color: "npm:^4.2.3" - detect-libc: "npm:^2.0.3" - semver: "npm:^7.6.3" - dependenciesMeta: - "@img/sharp-darwin-arm64": - optional: true - "@img/sharp-darwin-x64": - optional: true - "@img/sharp-libvips-darwin-arm64": - optional: true - "@img/sharp-libvips-darwin-x64": - optional: true - "@img/sharp-libvips-linux-arm": - optional: true - "@img/sharp-libvips-linux-arm64": - optional: true - "@img/sharp-libvips-linux-s390x": - optional: true - "@img/sharp-libvips-linux-x64": - optional: true - "@img/sharp-libvips-linuxmusl-arm64": - optional: true - "@img/sharp-libvips-linuxmusl-x64": - optional: true - "@img/sharp-linux-arm": - optional: true - "@img/sharp-linux-arm64": - optional: true - "@img/sharp-linux-s390x": - optional: true - "@img/sharp-linux-x64": - optional: true - "@img/sharp-linuxmusl-arm64": - optional: true - "@img/sharp-linuxmusl-x64": - optional: true - "@img/sharp-wasm32": - optional: true - "@img/sharp-win32-ia32": - optional: true - "@img/sharp-win32-x64": - optional: true - checksum: 10/9f153578cb02735359cbcc874f52b56b8074ed997498c35255c7099d4f4f506f6ddf83a437a55242c7ad4f979336660504b6c78e29d6933f4981dedbdae5ce09 - languageName: node - linkType: hard - -"sharp@npm:^0.34.3": - version: 0.34.5 - resolution: "sharp@npm:0.34.5" - dependencies: - "@img/colour": "npm:^1.0.0" - "@img/sharp-darwin-arm64": "npm:0.34.5" - "@img/sharp-darwin-x64": "npm:0.34.5" - "@img/sharp-libvips-darwin-arm64": "npm:1.2.4" - "@img/sharp-libvips-darwin-x64": "npm:1.2.4" - "@img/sharp-libvips-linux-arm": "npm:1.2.4" - "@img/sharp-libvips-linux-arm64": "npm:1.2.4" - "@img/sharp-libvips-linux-ppc64": "npm:1.2.4" - "@img/sharp-libvips-linux-riscv64": "npm:1.2.4" - "@img/sharp-libvips-linux-s390x": "npm:1.2.4" - "@img/sharp-libvips-linux-x64": "npm:1.2.4" - "@img/sharp-libvips-linuxmusl-arm64": "npm:1.2.4" - "@img/sharp-libvips-linuxmusl-x64": "npm:1.2.4" - "@img/sharp-linux-arm": "npm:0.34.5" - "@img/sharp-linux-arm64": "npm:0.34.5" - "@img/sharp-linux-ppc64": "npm:0.34.5" - "@img/sharp-linux-riscv64": "npm:0.34.5" - "@img/sharp-linux-s390x": "npm:0.34.5" - "@img/sharp-linux-x64": "npm:0.34.5" - "@img/sharp-linuxmusl-arm64": "npm:0.34.5" - "@img/sharp-linuxmusl-x64": "npm:0.34.5" - "@img/sharp-wasm32": "npm:0.34.5" - "@img/sharp-win32-arm64": "npm:0.34.5" - "@img/sharp-win32-ia32": "npm:0.34.5" - "@img/sharp-win32-x64": "npm:0.34.5" - detect-libc: "npm:^2.1.2" - semver: "npm:^7.7.3" - dependenciesMeta: - "@img/sharp-darwin-arm64": - optional: true - "@img/sharp-darwin-x64": - optional: true - "@img/sharp-libvips-darwin-arm64": - optional: true - "@img/sharp-libvips-darwin-x64": - optional: true - "@img/sharp-libvips-linux-arm": - optional: true - "@img/sharp-libvips-linux-arm64": - optional: true - "@img/sharp-libvips-linux-ppc64": - optional: true - "@img/sharp-libvips-linux-riscv64": - optional: true - "@img/sharp-libvips-linux-s390x": - optional: true - "@img/sharp-libvips-linux-x64": - optional: true - "@img/sharp-libvips-linuxmusl-arm64": - optional: true - "@img/sharp-libvips-linuxmusl-x64": - optional: true - "@img/sharp-linux-arm": - optional: true - "@img/sharp-linux-arm64": - optional: true - "@img/sharp-linux-ppc64": - optional: true - "@img/sharp-linux-riscv64": - optional: true - "@img/sharp-linux-s390x": - optional: true - "@img/sharp-linux-x64": - optional: true - "@img/sharp-linuxmusl-arm64": - optional: true - "@img/sharp-linuxmusl-x64": - optional: true - "@img/sharp-wasm32": - optional: true - "@img/sharp-win32-arm64": - optional: true - "@img/sharp-win32-ia32": - optional: true - "@img/sharp-win32-x64": - optional: true - checksum: 10/d62bc638c8ad382dffc266beeaffab71457d592abeb6fdf95b512e6dcbce0abf47b8d903b4ea081f012ceb40e4462f1e219184c729329146df32a5ccec2c231f - languageName: node - linkType: hard - "shebang-command@npm:^1.2.0": version: 1.2.0 resolution: "shebang-command@npm:1.2.0" @@ -35552,18 +34004,6 @@ __metadata: languageName: node linkType: hard -"socket.io-client@npm:4.8.1": - version: 4.8.1 - resolution: "socket.io-client@npm:4.8.1" - dependencies: - "@socket.io/component-emitter": "npm:~3.1.0" - debug: "npm:~4.3.2" - engine.io-client: "npm:~6.6.1" - socket.io-parser: "npm:~4.2.4" - checksum: 10/7480cf1ab30eba371a96dd1ce2ce9018dcbeaf81035a066fb89d99df0d0a6388b05840c92d970317c739956b68b28b0f4833f3b18e460a24eef557b9bca127c1 - languageName: node - linkType: hard - "socket.io-client@npm:^4.8.3": version: 4.8.3 resolution: "socket.io-client@npm:4.8.3" @@ -35644,16 +34084,6 @@ __metadata: languageName: node linkType: hard -"sonner@npm:2.0.3": - version: 2.0.3 - resolution: "sonner@npm:2.0.3" - peerDependencies: - react: ^18.0.0 || ^19.0.0 || ^19.0.0-rc - react-dom: ^18.0.0 || ^19.0.0 || ^19.0.0-rc - checksum: 10/e7e4233c9ef96f2db4f5516a181d0b464104a6b8554ac36b403a53d14f21baddae48187ce48d22a7821eb1e3e9168f7df471405001652ab3abfcfe8930f7a6fa - languageName: node - linkType: hard - "sonner@npm:^2.0.7": version: 2.0.7 resolution: "sonner@npm:2.0.7" @@ -35664,7 +34094,7 @@ __metadata: languageName: node linkType: hard -"source-map-js@npm:1.2.1, source-map-js@npm:^1.0.1, source-map-js@npm:^1.0.2, source-map-js@npm:^1.2.0, source-map-js@npm:^1.2.1": +"source-map-js@npm:^1.0.1, source-map-js@npm:^1.0.2, source-map-js@npm:^1.2.0, source-map-js@npm:^1.2.1": version: 1.2.1 resolution: "source-map-js@npm:1.2.1" checksum: 10/ff9d8c8bf096d534a5b7707e0382ef827b4dd360a577d3f34d2b9f48e12c9d230b5747974ee7c607f0df65113732711bb701fe9ece3c7edbd43cb2294d707df3 @@ -35693,13 +34123,6 @@ __metadata: languageName: node linkType: hard -"source-map@npm:0.5.6": - version: 0.5.6 - resolution: "source-map@npm:0.5.6" - checksum: 10/c62fe98e106c762307eea3a982242c1a76a31bc762da10fe2dda12252d423c163e0cd45d313330c8bd040cc5121702511138252308f72b8a9273825e81e4db30 - languageName: node - linkType: hard - "source-map@npm:^0.5.7": version: 0.5.7 resolution: "source-map@npm:0.5.7" @@ -35728,13 +34151,6 @@ __metadata: languageName: node linkType: hard -"spamc@npm:0.0.5": - version: 0.0.5 - resolution: "spamc@npm:0.0.5" - checksum: 10/297e89aae95ab9a706a811f32d28131ccebce008f409f78436ad6bb44c40c091ececf3a589fb29c3b382a05694795e03f60689bf77595c668d96930f93f27ff2 - languageName: node - linkType: hard - "spdx-correct@npm:^3.0.0": version: 3.2.0 resolution: "spdx-correct@npm:3.2.0" @@ -35865,15 +34281,6 @@ __metadata: languageName: node linkType: hard -"stack-generator@npm:^2.0.5": - version: 2.0.10 - resolution: "stack-generator@npm:2.0.10" - dependencies: - stackframe: "npm:^1.3.4" - checksum: 10/4fc3978a934424218a0aa9f398034e1f78153d5ff4f4ff9c62478c672debb47dd58de05b09fc3900530cbb526d72c93a6e6c9353bacc698e3b1c00ca3dda0c47 - languageName: node - linkType: hard - "stack-trace@npm:0.0.x": version: 0.0.10 resolution: "stack-trace@npm:0.0.10" @@ -35897,43 +34304,6 @@ __metadata: languageName: node linkType: hard -"stackframe@npm:^1.3.4": - version: 1.3.4 - resolution: "stackframe@npm:1.3.4" - checksum: 10/29ca71c1fd17974c1c178df0236b1407bc65f6ea389cc43dec000def6e42ff548d4453de9a85b76469e2ae2b2abdd802c6b6f3db947c05794efbd740d1cf4121 - languageName: node - linkType: hard - -"stacktrace-gps@npm:^3.0.4": - version: 3.1.2 - resolution: "stacktrace-gps@npm:3.1.2" - dependencies: - source-map: "npm:0.5.6" - stackframe: "npm:^1.3.4" - checksum: 10/21cb60ce0990f7a661e964cf4bdef1e70dda2286fb628fbd0fd1e69e8925138433d08ed84969de2d396b3b91515e15336a502f777c26587db89f3933d6f63f9b - languageName: node - linkType: hard - -"stacktrace-js@npm:^2.0.0": - version: 2.0.2 - resolution: "stacktrace-js@npm:2.0.2" - dependencies: - error-stack-parser: "npm:^2.0.6" - stack-generator: "npm:^2.0.5" - stacktrace-gps: "npm:^3.0.4" - checksum: 10/e5f60a09852687e4a9206927fe1078e24d63e00a71a2dcddd67940e9504a54931a3454439d5b4e3e0e62aeb979be810573e8d3332fbef0dbfa335a8781b4b57c - languageName: node - linkType: hard - -"stacktrace-parser@npm:0.1.11": - version: 0.1.11 - resolution: "stacktrace-parser@npm:0.1.11" - dependencies: - type-fest: "npm:^0.7.1" - checksum: 10/1120cf716606ec6a8e25cc9b6ada79d7b91e6a599bba1a6664e6badc8b5f37987d7df7d9ad0344f717a042781fd8e1e999de08614a5afea451b68902421036b5 - languageName: node - linkType: hard - "standard-as-callback@npm:^2.1.0": version: 2.1.0 resolution: "standard-as-callback@npm:2.1.0" @@ -36278,22 +34648,6 @@ __metadata: languageName: node linkType: hard -"styled-jsx@npm:5.1.6": - version: 5.1.6 - resolution: "styled-jsx@npm:5.1.6" - dependencies: - client-only: "npm:0.0.1" - peerDependencies: - react: ">= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0" - peerDependenciesMeta: - "@babel/core": - optional: true - babel-plugin-macros: - optional: true - checksum: 10/ba01200e8227fe1441a719c2e7da96c8aa7ef61d14211d1500e1abce12efa118479bcb6e7e12beecb9e1db76432caad2f4e01bbc0c9be21c134b088a4ca5ffe0 - languageName: node - linkType: hard - "stylehacks@npm:^7.0.5": version: 7.0.5 resolution: "stylehacks@npm:7.0.5" @@ -36335,24 +34689,6 @@ __metadata: languageName: node linkType: hard -"sucrase@npm:^3.32.0": - version: 3.35.1 - resolution: "sucrase@npm:3.35.1" - dependencies: - "@jridgewell/gen-mapping": "npm:^0.3.2" - commander: "npm:^4.0.0" - lines-and-columns: "npm:^1.1.6" - mz: "npm:^2.7.0" - pirates: "npm:^4.0.1" - tinyglobby: "npm:^0.2.11" - ts-interface-checker: "npm:^0.1.9" - bin: - sucrase: bin/sucrase - sucrase-node: bin/sucrase-node - checksum: 10/539f5c6ebc1ff8d449a89eb52b8c8944a730b9840ddadbd299a7d89ebcf16c3f4bc9aa59e1f2e112a502e5cf1508f7e02065f0e97c0435eb9a7058e997dfff5a - languageName: node - linkType: hard - "sumchecker@npm:^3.0.1": version: 3.0.1 resolution: "sumchecker@npm:3.0.1" @@ -36542,13 +34878,6 @@ __metadata: languageName: node linkType: hard -"tailwind-merge@npm:3.2.0": - version: 3.2.0 - resolution: "tailwind-merge@npm:3.2.0" - checksum: 10/ece231b18bf27cb70847e236d987e254c152e0440dbeb59c08ddf157de79fe89d6b7d1127c75d753e868f31dd77ded38ce8d23a1e405ff735a6642407c671fb9 - languageName: node - linkType: hard - "tailwind-merge@npm:^3.4.0": version: 3.4.0 resolution: "tailwind-merge@npm:3.4.0" @@ -36565,39 +34894,6 @@ __metadata: languageName: node linkType: hard -"tailwindcss@npm:3.4.0": - version: 3.4.0 - resolution: "tailwindcss@npm:3.4.0" - dependencies: - "@alloc/quick-lru": "npm:^5.2.0" - arg: "npm:^5.0.2" - chokidar: "npm:^3.5.3" - didyoumean: "npm:^1.2.2" - dlv: "npm:^1.1.3" - fast-glob: "npm:^3.3.0" - glob-parent: "npm:^6.0.2" - is-glob: "npm:^4.0.3" - jiti: "npm:^1.19.1" - lilconfig: "npm:^2.1.0" - micromatch: "npm:^4.0.5" - normalize-path: "npm:^3.0.0" - object-hash: "npm:^3.0.0" - picocolors: "npm:^1.0.0" - postcss: "npm:^8.4.23" - postcss-import: "npm:^15.1.0" - postcss-js: "npm:^4.0.1" - postcss-load-config: "npm:^4.0.1" - postcss-nested: "npm:^6.0.1" - postcss-selector-parser: "npm:^6.0.11" - resolve: "npm:^1.22.2" - sucrase: "npm:^3.32.0" - bin: - tailwind: lib/cli.js - tailwindcss: lib/cli.js - checksum: 10/e69de4856308b3a6bcd084cc6745b6e3dcf6623553414f042d0365adceb70d79e41ec97a2a38c3aea0d5a875aa1eb4e84e04ad35ea1f0f7debcb7150779eae52 - languageName: node - linkType: hard - "tailwindcss@npm:4.1.18": version: 4.1.18 resolution: "tailwindcss@npm:4.1.18" @@ -36612,7 +34908,7 @@ __metadata: languageName: node linkType: hard -"tapable@npm:^2.0.0, tapable@npm:^2.2.0, tapable@npm:^2.2.1, tapable@npm:^2.3.0": +"tapable@npm:^2.0.0, tapable@npm:^2.2.1, tapable@npm:^2.3.0": version: 2.3.0 resolution: "tapable@npm:2.3.0" checksum: 10/496a841039960533bb6e44816a01fffc2a1eb428bb2051ecab9e87adf07f19e1f937566cbbbb09dceff31163c0ffd81baafcad84db900b601f0155dd0b37e9f2 @@ -36743,24 +35039,6 @@ __metadata: languageName: node linkType: hard -"thenify-all@npm:^1.0.0": - version: 1.6.0 - resolution: "thenify-all@npm:1.6.0" - dependencies: - thenify: "npm:>= 3.1.0 < 4" - checksum: 10/dba7cc8a23a154cdcb6acb7f51d61511c37a6b077ec5ab5da6e8b874272015937788402fd271fdfc5f187f8cb0948e38d0a42dcc89d554d731652ab458f5343e - languageName: node - linkType: hard - -"thenify@npm:>= 3.1.0 < 4": - version: 3.3.1 - resolution: "thenify@npm:3.3.1" - dependencies: - any-promise: "npm:^1.0.0" - checksum: 10/486e1283a867440a904e36741ff1a177faa827cf94d69506f7e3ae4187b9afdf9ec368b3d8da225c192bfe2eb943f3f0080594156bf39f21b57cd1411e2e7f6d - languageName: node - linkType: hard - "thingies@npm:^1.20.0": version: 1.21.0 resolution: "thingies@npm:1.21.0" @@ -36872,7 +35150,7 @@ __metadata: languageName: node linkType: hard -"tinyglobby@npm:^0.2.11, tinyglobby@npm:^0.2.12, tinyglobby@npm:^0.2.14, tinyglobby@npm:^0.2.15": +"tinyglobby@npm:^0.2.12, tinyglobby@npm:^0.2.14, tinyglobby@npm:^0.2.15": version: 0.2.15 resolution: "tinyglobby@npm:0.2.15" dependencies: @@ -37128,13 +35406,6 @@ __metadata: languageName: node linkType: hard -"ts-interface-checker@npm:^0.1.9": - version: 0.1.13 - resolution: "ts-interface-checker@npm:0.1.13" - checksum: 10/9f7346b9e25bade7a1050c001ec5a4f7023909c0e1644c5a96ae20703a131627f081479e6622a4ecee2177283d0069e651e507bedadd3904fc4010ab28ffce00 - languageName: node - linkType: hard - "ts-log@npm:^2.2.3": version: 2.2.7 resolution: "ts-log@npm:2.2.7" @@ -37248,13 +35519,6 @@ __metadata: languageName: node linkType: hard -"type-fest@npm:^0.7.1": - version: 0.7.1 - resolution: "type-fest@npm:0.7.1" - checksum: 10/0699b6011bb3f7fac5fd5385e2e09432cde08fa89283f24084f29db00ec69a5445cd3aa976438ec74fc552a9a96f4a04ed390b5cb62eb7483aa4b6e5b935e059 - languageName: node - linkType: hard - "type-fest@npm:^1.0.2": version: 1.4.0 resolution: "type-fest@npm:1.4.0" @@ -37865,15 +36129,6 @@ __metadata: languageName: node linkType: hard -"use-debounce@npm:10.0.4": - version: 10.0.4 - resolution: "use-debounce@npm:10.0.4" - peerDependencies: - react: "*" - checksum: 10/e193bbed307204b655abab545704ca608b23db10680f299f4b9b48b935a9fd68b68827c79de3bf5517010524bfa15709bf6b0ab1f915d6305b5d2ce27bf11ad7 - languageName: node - linkType: hard - "use-sidecar@npm:^1.1.3": version: 1.1.3 resolution: "use-sidecar@npm:1.1.3" @@ -37993,13 +36248,6 @@ __metadata: languageName: node linkType: hard -"valibot@npm:^0.13.1": - version: 0.13.1 - resolution: "valibot@npm:0.13.1" - checksum: 10/feaef6de3a18c24cf6bc0c8874d64b920cf906b0613569122163d298546e81df22233a364983899c81d0e04097f73bde6cbbfbfe135232a079da42c45e8ccae5 - languageName: node - linkType: hard - "validate-npm-package-license@npm:^3.0.1": version: 3.0.4 resolution: "validate-npm-package-license@npm:3.0.4" @@ -38326,16 +36574,6 @@ __metadata: languageName: node linkType: hard -"wasm-imagemagick@npm:^1.2.3": - version: 1.2.8 - resolution: "wasm-imagemagick@npm:1.2.8" - dependencies: - p-map: "npm:^2.0.0" - stacktrace-js: "npm:^2.0.0" - checksum: 10/44d8e28c6b03168f017e816a71367804aee79c901ba6208db0f53faa8bac7b0c1b5b423d561674c6d4d853f97d1bfc79def61c80600cd328124b3a1a8e43fdba - languageName: node - linkType: hard - "watchpack@npm:^2.5.1": version: 2.5.1 resolution: "watchpack@npm:2.5.1" @@ -38491,7 +36729,7 @@ __metadata: languageName: node linkType: hard -"webpack@npm:^5, webpack@npm:^5.102.1, webpack@npm:^5.69.1": +"webpack@npm:^5.102.1, webpack@npm:^5.69.1": version: 5.105.2 resolution: "webpack@npm:5.105.2" dependencies: @@ -38881,13 +37119,6 @@ __metadata: languageName: node linkType: hard -"xstate@npm:^4.38.1": - version: 4.38.3 - resolution: "xstate@npm:4.38.3" - checksum: 10/82f30ed1d049d6be6274e54e34f46cad93fe773e4e333753acf363b8010f3685d256f154a91e5c1d615df654e14164dfc630c768af090925442b2c877cb9f11c - languageName: node - linkType: hard - "xtend@npm:^4.0.0, xtend@npm:^4.0.2": version: 4.0.2 resolution: "xtend@npm:4.0.2" @@ -38968,7 +37199,7 @@ __metadata: languageName: node linkType: hard -"yaml@npm:^2.0.0, yaml@npm:^2.3.1, yaml@npm:^2.3.4, yaml@npm:^2.5.1, yaml@npm:^2.7.1, yaml@npm:^2.8.1": +"yaml@npm:^2.0.0, yaml@npm:^2.3.1, yaml@npm:^2.5.1, yaml@npm:^2.7.1, yaml@npm:^2.8.1": version: 2.8.2 resolution: "yaml@npm:2.8.2" bin: @@ -39095,13 +37326,6 @@ __metadata: languageName: node linkType: hard -"zod@npm:3.24.3": - version: 3.24.3 - resolution: "zod@npm:3.24.3" - checksum: 10/1b15db625ca633324084f3a8587bfb907043bbca407a09f7d5da6a9781b3838c68e9312b49e91e479d2f8bf04cdda5810803ac9504e3b7ccbec3adf2de625fb8 - languageName: node - linkType: hard - "zod@npm:^3.22.0, zod@npm:^3.24.2, zod@npm:^3.25.76": version: 3.25.76 resolution: "zod@npm:3.25.76" From c90f173821cd90a884fdd1f961b20c69501e0341 Mon Sep 17 00:00:00 2001 From: DarkSky <25152247+darkskygit@users.noreply.github.com> Date: Fri, 27 Feb 2026 20:17:06 +0800 Subject: [PATCH 05/49] chore: bump deps (#14526) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #### PR Dependency Tree * **PR #14526** 👈 This tree was auto-generated by [Charcoal](https://github.com/danerwilliams/charcoal) ## Summary by CodeRabbit * **Chores** * Updated Storybook component development tooling to version 10.2.13 for improved stability and performance * Removed Chromatic integration from the component preview system --- .../frontend/component/.storybook/main.ts | 4 +- packages/frontend/component/package.json | 7 +- .../src/ui/checkbox/checkbox.stories.tsx | 4 +- yarn.lock | 445 +++++++++--------- 4 files changed, 235 insertions(+), 225 deletions(-) diff --git a/packages/frontend/component/.storybook/main.ts b/packages/frontend/component/.storybook/main.ts index f181adb3d8..52b9205fdc 100644 --- a/packages/frontend/component/.storybook/main.ts +++ b/packages/frontend/component/.storybook/main.ts @@ -8,9 +8,7 @@ import { mergeConfig } from 'vite'; export default { stories: ['../src/ui/**/*.@(mdx|stories.@(js|jsx|ts|tsx))'], - addons: [ - '@chromatic-com/storybook', - ], + addons: [], framework: { name: getAbsolutePath('@storybook/react-vite'), diff --git a/packages/frontend/component/package.json b/packages/frontend/component/package.json index 5ac573b037..c32f7f3070 100644 --- a/packages/frontend/component/package.json +++ b/packages/frontend/component/package.json @@ -73,16 +73,15 @@ "devDependencies": { "@affine-tools/utils": "workspace:*", "@blocksuite/affine": "workspace:*", - "@chromatic-com/storybook": "^5.0.0", - "@storybook/react": "^10.0.0", - "@storybook/react-vite": "^10.0.0", + "@storybook/react": "^10.2.13", + "@storybook/react-vite": "^10.2.13", "@testing-library/dom": "^10.4.0", "@testing-library/react": "^16.1.0", "@types/bytes": "^3.1.5", "@types/react": "^19.0.1", "@types/react-dom": "^19.0.2", "@vanilla-extract/css": "^1.17.0", - "storybook": "^10.1.5", + "storybook": "^10.2.13", "typescript": "^5.9.3", "unplugin-swc": "^1.5.9", "vite": "^7.2.7", diff --git a/packages/frontend/component/src/ui/checkbox/checkbox.stories.tsx b/packages/frontend/component/src/ui/checkbox/checkbox.stories.tsx index db5d156734..69734c41de 100644 --- a/packages/frontend/component/src/ui/checkbox/checkbox.stories.tsx +++ b/packages/frontend/component/src/ui/checkbox/checkbox.stories.tsx @@ -6,9 +6,7 @@ import { Checkbox } from './checkbox'; export default { title: 'UI/Checkbox', component: Checkbox, - parameters: { - chromatic: { disableSnapshot: true }, - }, + parameters: {}, } satisfies Meta; export const Basic: StoryFn = props => { diff --git a/yarn.lock b/yarn.lock index c8389b4b5c..a00e9bb446 100644 --- a/yarn.lock +++ b/yarn.lock @@ -321,7 +321,6 @@ __metadata: "@atlaskit/pragmatic-drag-and-drop-hitbox": "npm:^1.1.0" "@blocksuite/affine": "workspace:*" "@blocksuite/icons": "npm:^2.2.17" - "@chromatic-com/storybook": "npm:^5.0.0" "@emotion/react": "npm:^11.14.0" "@emotion/styled": "npm:^11.14.0" "@radix-ui/react-avatar": "npm:^1.1.11" @@ -339,8 +338,8 @@ __metadata: "@radix-ui/react-toast": "npm:^1.2.15" "@radix-ui/react-tooltip": "npm:^1.1.8" "@radix-ui/react-visually-hidden": "npm:^1.1.3" - "@storybook/react": "npm:^10.0.0" - "@storybook/react-vite": "npm:^10.0.0" + "@storybook/react": "npm:^10.2.13" + "@storybook/react-vite": "npm:^10.2.13" "@testing-library/dom": "npm:^10.4.0" "@testing-library/react": "npm:^16.1.0" "@toeverything/theme": "npm:^1.1.23" @@ -369,7 +368,7 @@ __metadata: react-router-dom: "npm:^6.30.3" react-transition-state: "npm:^2.2.0" sonner: "npm:^2.0.7" - storybook: "npm:^10.1.5" + storybook: "npm:^10.2.13" swr: "npm:^2.3.7" typescript: "npm:^5.9.3" unplugin-swc: "npm:^1.5.9" @@ -4042,21 +4041,6 @@ __metadata: languageName: node linkType: hard -"@chromatic-com/storybook@npm:^5.0.0": - version: 5.0.0 - resolution: "@chromatic-com/storybook@npm:5.0.0" - dependencies: - "@neoconfetti/react": "npm:^1.0.0" - chromatic: "npm:^13.3.4" - filesize: "npm:^10.0.12" - jsonfile: "npm:^6.1.0" - strip-ansi: "npm:^7.1.0" - peerDependencies: - storybook: ^0.0.0-0 || ^10.1.0 || ^10.1.0-0 || ^10.2.0-0 || ^10.3.0-0 - checksum: 10/4964c1086f4aaaf5a0db80063801fafd0595546e22914dff1e6e0869dad9cf9f9cae66bd41133f1bbd0d59696923ca65e9734b76ca4a6ca13f1f97e9d4286e64 - languageName: node - linkType: hard - "@colors/colors@npm:1.6.0, @colors/colors@npm:^1.6.0": version: 1.6.0 resolution: "@colors/colors@npm:1.6.0" @@ -7427,12 +7411,11 @@ __metadata: languageName: node linkType: hard -"@joshwooding/vite-plugin-react-docgen-typescript@npm:0.6.1": - version: 0.6.1 - resolution: "@joshwooding/vite-plugin-react-docgen-typescript@npm:0.6.1" +"@joshwooding/vite-plugin-react-docgen-typescript@npm:^0.6.4": + version: 0.6.4 + resolution: "@joshwooding/vite-plugin-react-docgen-typescript@npm:0.6.4" dependencies: - glob: "npm:^10.0.0" - magic-string: "npm:^0.30.0" + glob: "npm:^13.0.1" react-docgen-typescript: "npm:^2.2.2" peerDependencies: typescript: ">= 4.3.x" @@ -7440,7 +7423,7 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 10/a82b6005378ccda13250fcfeaa04ec2ba17d1c2923b5bba5907d5b2fd658c661b29c1215eb1c0fe305b390bee89ec77c684aa68506262734c3bb3cd76d8a6963 + checksum: 10/9e1ead0120036e3acb2bfe4772c5c1f352ca43e19e3e59ef37aa7d08843302118a8d2313124c6058af60246058a6aa9c8895683e6d56d56b5c8cf20102078e04 languageName: node linkType: hard @@ -8997,13 +8980,6 @@ __metadata: languageName: node linkType: hard -"@neoconfetti/react@npm:^1.0.0": - version: 1.0.0 - resolution: "@neoconfetti/react@npm:1.0.0" - checksum: 10/71a623f2df79c773b6693fab3a252ee2d7bb1da4a8986c2d15b5ef25493835c1de64f2e44637faf823970d43d63f32227b09a6605ad23f39bc82c14d810e45cd - languageName: node - linkType: hard - "@nestjs-cls/transactional-adapter-prisma@npm:^1.2.24": version: 1.3.4 resolution: "@nestjs-cls/transactional-adapter-prisma@npm:1.3.4" @@ -14489,149 +14465,177 @@ __metadata: languageName: node linkType: hard -"@rollup/rollup-android-arm-eabi@npm:4.50.1": - version: 4.50.1 - resolution: "@rollup/rollup-android-arm-eabi@npm:4.50.1" +"@rollup/rollup-android-arm-eabi@npm:4.59.0": + version: 4.59.0 + resolution: "@rollup/rollup-android-arm-eabi@npm:4.59.0" conditions: os=android & cpu=arm languageName: node linkType: hard -"@rollup/rollup-android-arm64@npm:4.50.1": - version: 4.50.1 - resolution: "@rollup/rollup-android-arm64@npm:4.50.1" +"@rollup/rollup-android-arm64@npm:4.59.0": + version: 4.59.0 + resolution: "@rollup/rollup-android-arm64@npm:4.59.0" conditions: os=android & cpu=arm64 languageName: node linkType: hard -"@rollup/rollup-darwin-arm64@npm:4.50.1": - version: 4.50.1 - resolution: "@rollup/rollup-darwin-arm64@npm:4.50.1" +"@rollup/rollup-darwin-arm64@npm:4.59.0": + version: 4.59.0 + resolution: "@rollup/rollup-darwin-arm64@npm:4.59.0" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@rollup/rollup-darwin-x64@npm:4.50.1": - version: 4.50.1 - resolution: "@rollup/rollup-darwin-x64@npm:4.50.1" +"@rollup/rollup-darwin-x64@npm:4.59.0": + version: 4.59.0 + resolution: "@rollup/rollup-darwin-x64@npm:4.59.0" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@rollup/rollup-freebsd-arm64@npm:4.50.1": - version: 4.50.1 - resolution: "@rollup/rollup-freebsd-arm64@npm:4.50.1" +"@rollup/rollup-freebsd-arm64@npm:4.59.0": + version: 4.59.0 + resolution: "@rollup/rollup-freebsd-arm64@npm:4.59.0" conditions: os=freebsd & cpu=arm64 languageName: node linkType: hard -"@rollup/rollup-freebsd-x64@npm:4.50.1": - version: 4.50.1 - resolution: "@rollup/rollup-freebsd-x64@npm:4.50.1" +"@rollup/rollup-freebsd-x64@npm:4.59.0": + version: 4.59.0 + resolution: "@rollup/rollup-freebsd-x64@npm:4.59.0" conditions: os=freebsd & cpu=x64 languageName: node linkType: hard -"@rollup/rollup-linux-arm-gnueabihf@npm:4.50.1": - version: 4.50.1 - resolution: "@rollup/rollup-linux-arm-gnueabihf@npm:4.50.1" +"@rollup/rollup-linux-arm-gnueabihf@npm:4.59.0": + version: 4.59.0 + resolution: "@rollup/rollup-linux-arm-gnueabihf@npm:4.59.0" conditions: os=linux & cpu=arm & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-arm-musleabihf@npm:4.50.1": - version: 4.50.1 - resolution: "@rollup/rollup-linux-arm-musleabihf@npm:4.50.1" +"@rollup/rollup-linux-arm-musleabihf@npm:4.59.0": + version: 4.59.0 + resolution: "@rollup/rollup-linux-arm-musleabihf@npm:4.59.0" conditions: os=linux & cpu=arm & libc=musl languageName: node linkType: hard -"@rollup/rollup-linux-arm64-gnu@npm:4.50.1": - version: 4.50.1 - resolution: "@rollup/rollup-linux-arm64-gnu@npm:4.50.1" +"@rollup/rollup-linux-arm64-gnu@npm:4.59.0": + version: 4.59.0 + resolution: "@rollup/rollup-linux-arm64-gnu@npm:4.59.0" conditions: os=linux & cpu=arm64 & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-arm64-musl@npm:4.50.1": - version: 4.50.1 - resolution: "@rollup/rollup-linux-arm64-musl@npm:4.50.1" +"@rollup/rollup-linux-arm64-musl@npm:4.59.0": + version: 4.59.0 + resolution: "@rollup/rollup-linux-arm64-musl@npm:4.59.0" conditions: os=linux & cpu=arm64 & libc=musl languageName: node linkType: hard -"@rollup/rollup-linux-loongarch64-gnu@npm:4.50.1": - version: 4.50.1 - resolution: "@rollup/rollup-linux-loongarch64-gnu@npm:4.50.1" +"@rollup/rollup-linux-loong64-gnu@npm:4.59.0": + version: 4.59.0 + resolution: "@rollup/rollup-linux-loong64-gnu@npm:4.59.0" conditions: os=linux & cpu=loong64 & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-ppc64-gnu@npm:4.50.1": - version: 4.50.1 - resolution: "@rollup/rollup-linux-ppc64-gnu@npm:4.50.1" +"@rollup/rollup-linux-loong64-musl@npm:4.59.0": + version: 4.59.0 + resolution: "@rollup/rollup-linux-loong64-musl@npm:4.59.0" + conditions: os=linux & cpu=loong64 & libc=musl + languageName: node + linkType: hard + +"@rollup/rollup-linux-ppc64-gnu@npm:4.59.0": + version: 4.59.0 + resolution: "@rollup/rollup-linux-ppc64-gnu@npm:4.59.0" conditions: os=linux & cpu=ppc64 & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-riscv64-gnu@npm:4.50.1": - version: 4.50.1 - resolution: "@rollup/rollup-linux-riscv64-gnu@npm:4.50.1" +"@rollup/rollup-linux-ppc64-musl@npm:4.59.0": + version: 4.59.0 + resolution: "@rollup/rollup-linux-ppc64-musl@npm:4.59.0" + conditions: os=linux & cpu=ppc64 & libc=musl + languageName: node + linkType: hard + +"@rollup/rollup-linux-riscv64-gnu@npm:4.59.0": + version: 4.59.0 + resolution: "@rollup/rollup-linux-riscv64-gnu@npm:4.59.0" conditions: os=linux & cpu=riscv64 & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-riscv64-musl@npm:4.50.1": - version: 4.50.1 - resolution: "@rollup/rollup-linux-riscv64-musl@npm:4.50.1" +"@rollup/rollup-linux-riscv64-musl@npm:4.59.0": + version: 4.59.0 + resolution: "@rollup/rollup-linux-riscv64-musl@npm:4.59.0" conditions: os=linux & cpu=riscv64 & libc=musl languageName: node linkType: hard -"@rollup/rollup-linux-s390x-gnu@npm:4.50.1": - version: 4.50.1 - resolution: "@rollup/rollup-linux-s390x-gnu@npm:4.50.1" +"@rollup/rollup-linux-s390x-gnu@npm:4.59.0": + version: 4.59.0 + resolution: "@rollup/rollup-linux-s390x-gnu@npm:4.59.0" conditions: os=linux & cpu=s390x & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-x64-gnu@npm:4.50.1": - version: 4.50.1 - resolution: "@rollup/rollup-linux-x64-gnu@npm:4.50.1" +"@rollup/rollup-linux-x64-gnu@npm:4.59.0": + version: 4.59.0 + resolution: "@rollup/rollup-linux-x64-gnu@npm:4.59.0" conditions: os=linux & cpu=x64 & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-x64-musl@npm:4.50.1": - version: 4.50.1 - resolution: "@rollup/rollup-linux-x64-musl@npm:4.50.1" +"@rollup/rollup-linux-x64-musl@npm:4.59.0": + version: 4.59.0 + resolution: "@rollup/rollup-linux-x64-musl@npm:4.59.0" conditions: os=linux & cpu=x64 & libc=musl languageName: node linkType: hard -"@rollup/rollup-openharmony-arm64@npm:4.50.1": - version: 4.50.1 - resolution: "@rollup/rollup-openharmony-arm64@npm:4.50.1" +"@rollup/rollup-openbsd-x64@npm:4.59.0": + version: 4.59.0 + resolution: "@rollup/rollup-openbsd-x64@npm:4.59.0" + conditions: os=openbsd & cpu=x64 + languageName: node + linkType: hard + +"@rollup/rollup-openharmony-arm64@npm:4.59.0": + version: 4.59.0 + resolution: "@rollup/rollup-openharmony-arm64@npm:4.59.0" conditions: os=openharmony & cpu=arm64 languageName: node linkType: hard -"@rollup/rollup-win32-arm64-msvc@npm:4.50.1": - version: 4.50.1 - resolution: "@rollup/rollup-win32-arm64-msvc@npm:4.50.1" +"@rollup/rollup-win32-arm64-msvc@npm:4.59.0": + version: 4.59.0 + resolution: "@rollup/rollup-win32-arm64-msvc@npm:4.59.0" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@rollup/rollup-win32-ia32-msvc@npm:4.50.1": - version: 4.50.1 - resolution: "@rollup/rollup-win32-ia32-msvc@npm:4.50.1" +"@rollup/rollup-win32-ia32-msvc@npm:4.59.0": + version: 4.59.0 + resolution: "@rollup/rollup-win32-ia32-msvc@npm:4.59.0" conditions: os=win32 & cpu=ia32 languageName: node linkType: hard -"@rollup/rollup-win32-x64-msvc@npm:4.50.1": - version: 4.50.1 - resolution: "@rollup/rollup-win32-x64-msvc@npm:4.50.1" +"@rollup/rollup-win32-x64-gnu@npm:4.59.0": + version: 4.59.0 + resolution: "@rollup/rollup-win32-x64-gnu@npm:4.59.0" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + +"@rollup/rollup-win32-x64-msvc@npm:4.59.0": + version: 4.59.0 + resolution: "@rollup/rollup-win32-x64-msvc@npm:4.59.0" conditions: os=win32 & cpu=x64 languageName: node linkType: hard @@ -15476,29 +15480,28 @@ __metadata: languageName: node linkType: hard -"@storybook/builder-vite@npm:10.1.5": - version: 10.1.5 - resolution: "@storybook/builder-vite@npm:10.1.5" +"@storybook/builder-vite@npm:10.2.13": + version: 10.2.13 + resolution: "@storybook/builder-vite@npm:10.2.13" dependencies: - "@storybook/csf-plugin": "npm:10.1.5" - "@vitest/mocker": "npm:3.2.4" + "@storybook/csf-plugin": "npm:10.2.13" ts-dedent: "npm:^2.0.0" peerDependencies: - storybook: ^10.1.5 + storybook: ^10.2.13 vite: ^5.0.0 || ^6.0.0 || ^7.0.0 - checksum: 10/0eb97f40f4b46fd3c1d054038feed8b74137697cf0b82fcc8eb2ee12842ecf7a1774a41670270301263e1bb2778b39e4bb1805150ecc421777f4c703c6df45a2 + checksum: 10/35c61a3ffed17d69dce626138e8e92b7e2ea55bebe77140cb49ebd50f8625848d5bbfe586ac1cdf29ced9ff7dda2b30db588a784c81674f3b0fcab3a9d128ceb languageName: node linkType: hard -"@storybook/csf-plugin@npm:10.1.5": - version: 10.1.5 - resolution: "@storybook/csf-plugin@npm:10.1.5" +"@storybook/csf-plugin@npm:10.2.13": + version: 10.2.13 + resolution: "@storybook/csf-plugin@npm:10.2.13" dependencies: unplugin: "npm:^2.3.5" peerDependencies: esbuild: "*" rollup: "*" - storybook: ^10.1.5 + storybook: ^10.2.13 vite: "*" webpack: "*" peerDependenciesMeta: @@ -15510,7 +15513,7 @@ __metadata: optional: true webpack: optional: true - checksum: 10/7c2be5f881728a7fc17c89d5cd9d14f89dda0776805bd2fbde4cba7da8e945fd2a57990d27b0647552848b07efe4c03da1ba6e8e1a1b53a45ac1e2e7f00820e4 + checksum: 10/b233d3de4622d335034a4fe58145e907a8a007c5c5aef4a480b30b7ccf31888db1ae9513b4fbcc5fb1c449b8599dfe195abade5a7300bb535e02e2f563b8a4f3 languageName: node linkType: hard @@ -15521,7 +15524,7 @@ __metadata: languageName: node linkType: hard -"@storybook/icons@npm:^2.0.0": +"@storybook/icons@npm:^2.0.1": version: 2.0.1 resolution: "@storybook/icons@npm:2.0.1" peerDependencies: @@ -15531,25 +15534,25 @@ __metadata: languageName: node linkType: hard -"@storybook/react-dom-shim@npm:10.1.5": - version: 10.1.5 - resolution: "@storybook/react-dom-shim@npm:10.1.5" +"@storybook/react-dom-shim@npm:10.2.13": + version: 10.2.13 + resolution: "@storybook/react-dom-shim@npm:10.2.13" peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - storybook: ^10.1.5 - checksum: 10/b8db92ae654a13684f058054fb7c04fe853c7181bf5b179604fec9d8b9c66caf4bb5b78867814b84fc8330942bc604eb7d87650fa1bb8371ea41070a6002cc4b + storybook: ^10.2.13 + checksum: 10/3008c30073022ef230574ad718cbac48b9c0a2bca651b4e73397338d4d7879a89406a6489f468403b2350a74f10535c0f8b488cae0a490ee78006e1ffcc0c576 languageName: node linkType: hard -"@storybook/react-vite@npm:^10.0.0": - version: 10.1.5 - resolution: "@storybook/react-vite@npm:10.1.5" +"@storybook/react-vite@npm:^10.2.13": + version: 10.2.13 + resolution: "@storybook/react-vite@npm:10.2.13" dependencies: - "@joshwooding/vite-plugin-react-docgen-typescript": "npm:0.6.1" + "@joshwooding/vite-plugin-react-docgen-typescript": "npm:^0.6.4" "@rollup/pluginutils": "npm:^5.0.2" - "@storybook/builder-vite": "npm:10.1.5" - "@storybook/react": "npm:10.1.5" + "@storybook/builder-vite": "npm:10.2.13" + "@storybook/react": "npm:10.2.13" empathic: "npm:^2.0.0" magic-string: "npm:^0.30.0" react-docgen: "npm:^8.0.0" @@ -15558,28 +15561,28 @@ __metadata: peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - storybook: ^10.1.5 + storybook: ^10.2.13 vite: ^5.0.0 || ^6.0.0 || ^7.0.0 - checksum: 10/8072a305d5554b596037151b3c4bd6dcb23bcee957283232780026b26a82d461a7f395d97c6f44a0c2612fb4e35b2a9f75fcba727b75d9c5f9548aea43bd6e2e + checksum: 10/1a1cd92d29e5dfcf9c84d0fa13f39c0cd65941164a644bb641218c8a8c9c43c89f1b79916c5c90b7b0a75cfbbc290c30c677cee81660b536c66c835b4ae3f811 languageName: node linkType: hard -"@storybook/react@npm:10.1.5, @storybook/react@npm:^10.0.0": - version: 10.1.5 - resolution: "@storybook/react@npm:10.1.5" +"@storybook/react@npm:10.2.13, @storybook/react@npm:^10.2.13": + version: 10.2.13 + resolution: "@storybook/react@npm:10.2.13" dependencies: "@storybook/global": "npm:^5.0.0" - "@storybook/react-dom-shim": "npm:10.1.5" + "@storybook/react-dom-shim": "npm:10.2.13" react-docgen: "npm:^8.0.2" peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - storybook: ^10.1.5 + storybook: ^10.2.13 typescript: ">= 4.9.x" peerDependenciesMeta: typescript: optional: true - checksum: 10/8e3d3b7f6dc3ffb794f124fc93143af79eb407795ab225d1757e5da2e61c7051d5ec8d068a8e14b0a291ae047e72f9ecf92e9bfdb67580ab472470cc7f3d107e + checksum: 10/d3f8f281edcdae2aaccc0abe7fc551018269fe32380cc9bfbf7fb36d86966f62d7ad7a694e5200d95d0b40009cab9b7b837c47cb255e8cdbb37fa6578522d65b languageName: node linkType: hard @@ -19347,12 +19350,12 @@ __metadata: languageName: node linkType: hard -"brace-expansion@npm:^2.0.1": - version: 2.0.1 - resolution: "brace-expansion@npm:2.0.1" +"brace-expansion@npm:^2.0.1, brace-expansion@npm:^2.0.2": + version: 2.0.2 + resolution: "brace-expansion@npm:2.0.2" dependencies: balanced-match: "npm:^1.0.0" - checksum: 10/a61e7cd2e8a8505e9f0036b3b6108ba5e926b4b55089eeb5550cd04a471fe216c96d4fe7e4c7f995c728c554ae20ddfc4244cad10aef255e72b62930afd233d1 + checksum: 10/01dff195e3646bc4b0d27b63d9bab84d2ebc06121ff5013ad6e5356daa5a9d6b60fa26cf73c74797f2dc3fbec112af13578d51f75228c1112b26c790a87b0488 languageName: node linkType: hard @@ -20082,25 +20085,6 @@ __metadata: languageName: node linkType: hard -"chromatic@npm:^13.3.4": - version: 13.3.5 - resolution: "chromatic@npm:13.3.5" - peerDependencies: - "@chromatic-com/cypress": ^0.*.* || ^1.0.0 - "@chromatic-com/playwright": ^0.*.* || ^1.0.0 - peerDependenciesMeta: - "@chromatic-com/cypress": - optional: true - "@chromatic-com/playwright": - optional: true - bin: - chroma: dist/bin.js - chromatic: dist/bin.js - chromatic-cli: dist/bin.js - checksum: 10/d660e926e2763158eb216c12fd443ac909235b62e0855d6485c5ec270cbde8ce6d5467fc9792a988f2cd4c32722efb9899982b26d4bd8265381846c7d7006c21 - languageName: node - linkType: hard - "chrome-trace-event@npm:^1.0.2, chrome-trace-event@npm:^1.0.3": version: 1.0.4 resolution: "chrome-trace-event@npm:1.0.4" @@ -23805,14 +23789,22 @@ __metadata: languageName: node linkType: hard +"fast-xml-builder@npm:^1.0.0": + version: 1.0.0 + resolution: "fast-xml-builder@npm:1.0.0" + checksum: 10/06c04d80545e5c9f4d1d6cca00567b5cc09953a92c6328fa48cfb4d7f42630313b8c2bb62e9cb81accee7bb5e1c5312fcae06c3d20dbe52d969a5938233316da + languageName: node + linkType: hard + "fast-xml-parser@npm:^5.3.4": - version: 5.3.7 - resolution: "fast-xml-parser@npm:5.3.7" + version: 5.4.1 + resolution: "fast-xml-parser@npm:5.4.1" dependencies: + fast-xml-builder: "npm:^1.0.0" strnum: "npm:^2.1.2" bin: fxparser: src/cli/cli.js - checksum: 10/c3dfba84b8c8920a1a6f2596c387c8fbb3b76fcad9a26769a793f1e26d7718c50363478f3be2a71e952b2bf765be51d8f8e3434b37cc7af029c6a09662ea6ba4 + checksum: 10/2b40067c3ad3542ca197d1353bcb0416cd5db20d5c66d74ac176b99af6ff9bd55a6182d36856a2fd477c95b8fc1f07405475f1662a31185480130ba7076c702a languageName: node linkType: hard @@ -23983,7 +23975,7 @@ __metadata: languageName: node linkType: hard -"filesize@npm:^10.0.12, filesize@npm:^10.1.6": +"filesize@npm:^10.1.6": version: 10.1.6 resolution: "filesize@npm:10.1.6" checksum: 10/e800837c4fc02303f1944d5a4c7b706df1c5cd95d745181852604fb00a1c2d55d2d3921252722bd2f0c86b59c94edaba23fa224776bbf977455d4034e7be1f45 @@ -24759,6 +24751,17 @@ __metadata: languageName: node linkType: hard +"glob@npm:^13.0.1": + version: 13.0.6 + resolution: "glob@npm:13.0.6" + dependencies: + minimatch: "npm:^10.2.2" + minipass: "npm:^7.1.3" + path-scurry: "npm:^2.0.2" + checksum: 10/201ad69e5f0aa74e1d8c00a481581f8b8c804b6a4fbfabeeb8541f5d756932800331daeba99b58fb9e4cd67e12ba5a7eba5b82fb476691588418060b84353214 + languageName: node + linkType: hard + "glob@npm:^7.1.3, glob@npm:^7.1.4, glob@npm:^7.1.6": version: 7.2.3 resolution: "glob@npm:7.2.3" @@ -26975,7 +26978,7 @@ __metadata: languageName: node linkType: hard -"jsonfile@npm:^6.0.1, jsonfile@npm:^6.1.0": +"jsonfile@npm:^6.0.1": version: 6.1.0 resolution: "jsonfile@npm:6.1.0" dependencies: @@ -29091,47 +29094,47 @@ __metadata: linkType: hard "minimatch@npm:^10.0.3, minimatch@npm:^10.1.1, minimatch@npm:^10.2.1, minimatch@npm:^10.2.2, minimatch@npm:^9.0.3 || ^10.0.1": - version: 10.2.2 - resolution: "minimatch@npm:10.2.2" + version: 10.2.4 + resolution: "minimatch@npm:10.2.4" dependencies: brace-expansion: "npm:^5.0.2" - checksum: 10/e135be7b502ac97c02bcee42ccc1c55dc26dbac036c0f4acde69e42fe339d7fb53fae711e57b3546cb533426382ea492c73a073c7f78832e0453d120d48dd015 + checksum: 10/aea4874e521c55bb60744685bbffe3d152e5460f84efac3ea936e6bbe2ceba7deb93345fec3f9bb17f7b6946776073a64d40ae32bf5f298ad690308121068a1f languageName: node linkType: hard "minimatch@npm:^3.0.4, minimatch@npm:^3.0.5, minimatch@npm:^3.1.1, minimatch@npm:^3.1.2": - version: 3.1.3 - resolution: "minimatch@npm:3.1.3" + version: 3.1.5 + resolution: "minimatch@npm:3.1.5" dependencies: brace-expansion: "npm:^1.1.7" - checksum: 10/d430c40785fdb42c9fc1a36b9c9e3b08146044bd0f2fd043b05afb436aa4eaf6cdcb7756939ab8fc01664cd75d6335fd5043b2fe2aa084756927ffc77c1e3597 + checksum: 10/b11a7ee5773cd34c1a0c8436cdbe910901018fb4b6cb47aa508a18d567f6efd2148507959e35fba798389b161b8604a2d704ccef751ea36bd4582f9852b7d63f languageName: node linkType: hard "minimatch@npm:^5.0.1": - version: 5.1.7 - resolution: "minimatch@npm:5.1.7" + version: 5.1.9 + resolution: "minimatch@npm:5.1.9" dependencies: brace-expansion: "npm:^2.0.1" - checksum: 10/8c0129a7994bded261e4f4ae2d186ef9cbe7d4fb0616575c903693d39c788443c3c16c666f682932f655885c3eb7f9d992e08f9ccd5d8cd3a0533317b1d4af4a + checksum: 10/23b4feb64dcb77ba93b70a72be551eb2e2677ac02178cf1ed3d38836cc4cd84802d90b77f60ef87f2bac64d270d2d8eba242e428f0554ea4e36bfdb7e9d25d0c languageName: node linkType: hard "minimatch@npm:^7.4.6": - version: 7.4.7 - resolution: "minimatch@npm:7.4.7" + version: 7.4.9 + resolution: "minimatch@npm:7.4.9" dependencies: - brace-expansion: "npm:^2.0.1" - checksum: 10/509558c83a264ef8ba5cccab39a8937d8a1fdb2da336031de2444cda4dc3fb4e0d8ec78c0d51309635b910aaaa88d84a59f1a7dcfbefb6f6f5b7ce3204de17d4 + brace-expansion: "npm:^2.0.2" + checksum: 10/9bc60b593dafb71d68b1a671a0c1a4bb9a71ef2f8daa8ed4b8b6199bb2d522163fb2e94d82ca40518eaa3b00218f587ad7ab2ed40e56e4c57a8bddb6c2bd1d27 languageName: node linkType: hard "minimatch@npm:^9.0.0, minimatch@npm:^9.0.3, minimatch@npm:^9.0.4, minimatch@npm:^9.0.5": - version: 9.0.6 - resolution: "minimatch@npm:9.0.6" + version: 9.0.9 + resolution: "minimatch@npm:9.0.9" dependencies: - brace-expansion: "npm:^5.0.2" - checksum: 10/c7a46134aaf349f386de9a3f6c5b48c53bc3a4e2ef4b8b6365184504e28cc31cc261a388e181648cbc756b40e213dbce115c8087a47eff8f54ee28d62bc17b08 + brace-expansion: "npm:^2.0.2" + checksum: 10/b91fad937deaffb68a45a2cb731ff3cff1c3baf9b6469c879477ed16f15c8f4ce39d63a3f75c2455107c2fdff0f3ab597d97dc09e2e93b883aafcf926ef0c8f9 languageName: node linkType: hard @@ -29233,10 +29236,10 @@ __metadata: languageName: node linkType: hard -"minipass@npm:^5.0.0 || ^6.0.2 || ^7.0.0, minipass@npm:^7.0.2, minipass@npm:^7.0.3, minipass@npm:^7.0.4, minipass@npm:^7.1.2": - version: 7.1.2 - resolution: "minipass@npm:7.1.2" - checksum: 10/c25f0ee8196d8e6036661104bacd743785b2599a21de5c516b32b3fa2b83113ac89a2358465bc04956baab37ffb956ae43be679b2262bf7be15fce467ccd7950 +"minipass@npm:^5.0.0 || ^6.0.2 || ^7.0.0, minipass@npm:^7.0.2, minipass@npm:^7.0.3, minipass@npm:^7.0.4, minipass@npm:^7.1.2, minipass@npm:^7.1.3": + version: 7.1.3 + resolution: "minipass@npm:7.1.3" + checksum: 10/175e4d5e20980c3cd316ae82d2c031c42f6c746467d8b1905b51060a0ba4461441a0c25bb67c025fd9617f9a3873e152c7b543c6b5ac83a1846be8ade80dffd6 languageName: node linkType: hard @@ -30824,13 +30827,13 @@ __metadata: languageName: node linkType: hard -"path-scurry@npm:^2.0.0": - version: 2.0.0 - resolution: "path-scurry@npm:2.0.0" +"path-scurry@npm:^2.0.0, path-scurry@npm:^2.0.2": + version: 2.0.2 + resolution: "path-scurry@npm:2.0.2" dependencies: lru-cache: "npm:^11.0.0" minipass: "npm:^7.1.2" - checksum: 10/285ae0c2d6c34ae91dc1d5378ede21981c9a2f6de1ea9ca5a88b5a270ce9763b83dbadc7a324d512211d8d36b0c540427d3d0817030849d97a60fa840a2c59ec + checksum: 10/2b4257422bcb870a4c2d205b3acdbb213a72f5e2250f61c80f79c9d014d010f82bdf8584441612c8e1fa4eb098678f5704a66fa8377d72646bad4be38e57a2c3 languageName: node linkType: hard @@ -33238,30 +33241,34 @@ __metadata: linkType: hard "rollup@npm:^4.43.0": - version: 4.50.1 - resolution: "rollup@npm:4.50.1" + version: 4.59.0 + resolution: "rollup@npm:4.59.0" dependencies: - "@rollup/rollup-android-arm-eabi": "npm:4.50.1" - "@rollup/rollup-android-arm64": "npm:4.50.1" - "@rollup/rollup-darwin-arm64": "npm:4.50.1" - "@rollup/rollup-darwin-x64": "npm:4.50.1" - "@rollup/rollup-freebsd-arm64": "npm:4.50.1" - "@rollup/rollup-freebsd-x64": "npm:4.50.1" - "@rollup/rollup-linux-arm-gnueabihf": "npm:4.50.1" - "@rollup/rollup-linux-arm-musleabihf": "npm:4.50.1" - "@rollup/rollup-linux-arm64-gnu": "npm:4.50.1" - "@rollup/rollup-linux-arm64-musl": "npm:4.50.1" - "@rollup/rollup-linux-loongarch64-gnu": "npm:4.50.1" - "@rollup/rollup-linux-ppc64-gnu": "npm:4.50.1" - "@rollup/rollup-linux-riscv64-gnu": "npm:4.50.1" - "@rollup/rollup-linux-riscv64-musl": "npm:4.50.1" - "@rollup/rollup-linux-s390x-gnu": "npm:4.50.1" - "@rollup/rollup-linux-x64-gnu": "npm:4.50.1" - "@rollup/rollup-linux-x64-musl": "npm:4.50.1" - "@rollup/rollup-openharmony-arm64": "npm:4.50.1" - "@rollup/rollup-win32-arm64-msvc": "npm:4.50.1" - "@rollup/rollup-win32-ia32-msvc": "npm:4.50.1" - "@rollup/rollup-win32-x64-msvc": "npm:4.50.1" + "@rollup/rollup-android-arm-eabi": "npm:4.59.0" + "@rollup/rollup-android-arm64": "npm:4.59.0" + "@rollup/rollup-darwin-arm64": "npm:4.59.0" + "@rollup/rollup-darwin-x64": "npm:4.59.0" + "@rollup/rollup-freebsd-arm64": "npm:4.59.0" + "@rollup/rollup-freebsd-x64": "npm:4.59.0" + "@rollup/rollup-linux-arm-gnueabihf": "npm:4.59.0" + "@rollup/rollup-linux-arm-musleabihf": "npm:4.59.0" + "@rollup/rollup-linux-arm64-gnu": "npm:4.59.0" + "@rollup/rollup-linux-arm64-musl": "npm:4.59.0" + "@rollup/rollup-linux-loong64-gnu": "npm:4.59.0" + "@rollup/rollup-linux-loong64-musl": "npm:4.59.0" + "@rollup/rollup-linux-ppc64-gnu": "npm:4.59.0" + "@rollup/rollup-linux-ppc64-musl": "npm:4.59.0" + "@rollup/rollup-linux-riscv64-gnu": "npm:4.59.0" + "@rollup/rollup-linux-riscv64-musl": "npm:4.59.0" + "@rollup/rollup-linux-s390x-gnu": "npm:4.59.0" + "@rollup/rollup-linux-x64-gnu": "npm:4.59.0" + "@rollup/rollup-linux-x64-musl": "npm:4.59.0" + "@rollup/rollup-openbsd-x64": "npm:4.59.0" + "@rollup/rollup-openharmony-arm64": "npm:4.59.0" + "@rollup/rollup-win32-arm64-msvc": "npm:4.59.0" + "@rollup/rollup-win32-ia32-msvc": "npm:4.59.0" + "@rollup/rollup-win32-x64-gnu": "npm:4.59.0" + "@rollup/rollup-win32-x64-msvc": "npm:4.59.0" "@types/estree": "npm:1.0.8" fsevents: "npm:~2.3.2" dependenciesMeta: @@ -33285,10 +33292,14 @@ __metadata: optional: true "@rollup/rollup-linux-arm64-musl": optional: true - "@rollup/rollup-linux-loongarch64-gnu": + "@rollup/rollup-linux-loong64-gnu": + optional: true + "@rollup/rollup-linux-loong64-musl": optional: true "@rollup/rollup-linux-ppc64-gnu": optional: true + "@rollup/rollup-linux-ppc64-musl": + optional: true "@rollup/rollup-linux-riscv64-gnu": optional: true "@rollup/rollup-linux-riscv64-musl": @@ -33299,19 +33310,23 @@ __metadata: optional: true "@rollup/rollup-linux-x64-musl": optional: true + "@rollup/rollup-openbsd-x64": + optional: true "@rollup/rollup-openharmony-arm64": optional: true "@rollup/rollup-win32-arm64-msvc": optional: true "@rollup/rollup-win32-ia32-msvc": optional: true + "@rollup/rollup-win32-x64-gnu": + optional: true "@rollup/rollup-win32-x64-msvc": optional: true fsevents: optional: true bin: rollup: dist/bin/rollup - checksum: 10/99f47dc64ea5bc15056a9af49a10a287ec1c49550563ce7827d85d2c03a4a46e42ad2fd48f91b647193e849a22e01a66a782c8311bcefd4246932f02cc437e74 + checksum: 10/728237932aad7022c0640cd126b9fe5285f2578099f22a0542229a17785320a6553b74582fa5977877541c1faf27de65ed2750bc89dbb55b525405244a46d9f1 languageName: node linkType: hard @@ -33523,7 +33538,7 @@ __metadata: languageName: node linkType: hard -"semver@npm:7.7.4, semver@npm:^7.0.0, semver@npm:^7.1.1, semver@npm:^7.1.3, semver@npm:^7.2.1, semver@npm:^7.3.2, semver@npm:^7.3.5, semver@npm:^7.3.8, semver@npm:^7.5.3, semver@npm:^7.5.4, semver@npm:^7.6.0, semver@npm:^7.6.2, semver@npm:^7.6.3, semver@npm:^7.7.1, semver@npm:^7.7.2, semver@npm:^7.7.3, semver@npm:~7.7.3": +"semver@npm:7.7.4, semver@npm:^7.0.0, semver@npm:^7.1.1, semver@npm:^7.1.3, semver@npm:^7.2.1, semver@npm:^7.3.2, semver@npm:^7.3.5, semver@npm:^7.3.8, semver@npm:^7.5.3, semver@npm:^7.5.4, semver@npm:^7.6.0, semver@npm:^7.6.3, semver@npm:^7.7.1, semver@npm:^7.7.2, semver@npm:^7.7.3, semver@npm:~7.7.3": version: 7.7.4 resolution: "semver@npm:7.7.4" bin: @@ -34353,12 +34368,12 @@ __metadata: languageName: node linkType: hard -"storybook@npm:^10.1.5": - version: 10.1.10 - resolution: "storybook@npm:10.1.10" +"storybook@npm:^10.2.13": + version: 10.2.13 + resolution: "storybook@npm:10.2.13" dependencies: "@storybook/global": "npm:^5.0.0" - "@storybook/icons": "npm:^2.0.0" + "@storybook/icons": "npm:^2.0.1" "@testing-library/jest-dom": "npm:^6.6.3" "@testing-library/user-event": "npm:^14.6.1" "@vitest/expect": "npm:3.2.4" @@ -34366,7 +34381,7 @@ __metadata: esbuild: "npm:^0.18.0 || ^0.19.0 || ^0.20.0 || ^0.21.0 || ^0.22.0 || ^0.23.0 || ^0.24.0 || ^0.25.0 || ^0.26.0 || ^0.27.0" open: "npm:^10.2.0" recast: "npm:^0.23.5" - semver: "npm:^7.6.2" + semver: "npm:^7.7.3" use-sync-external-store: "npm:^1.5.0" ws: "npm:^8.18.0" peerDependencies: @@ -34376,7 +34391,7 @@ __metadata: optional: true bin: storybook: ./dist/bin/dispatcher.js - checksum: 10/c1f01c7ab57e80d2f2ef3a5c49baad5904e77c8e079199ad134e98a7ae455d52422390cd704e64142b36668874c055670dbffe0e334e1f4d541ebd4384052dd7 + checksum: 10/1e325ed686f080f61858a631d7fb5bef62ee54bf1381fdda951a0f40a30a6b4ce65480e149d1af7fd53813da8ae9e9ff4a8c30e61d607bda35d40c2f13b47015 languageName: node linkType: hard @@ -36394,8 +36409,8 @@ __metadata: linkType: hard "vite@npm:^5.0.0 || ^6.0.0 || ^7.0.0, vite@npm:^5.0.0 || ^6.0.0 || ^7.0.0-0, vite@npm:^7.2.7": - version: 7.3.0 - resolution: "vite@npm:7.3.0" + version: 7.3.1 + resolution: "vite@npm:7.3.1" dependencies: esbuild: "npm:^0.27.0" fdir: "npm:^6.5.0" @@ -36444,7 +36459,7 @@ __metadata: optional: true bin: vite: bin/vite.js - checksum: 10/044490133aaf4cc024700995edaac10ff182262c721a44a8ac7839207b3e5af435c8b9dd8ee4658dc0f47147fa4211632cca3120177aa4bab99a7cb095e5149e + checksum: 10/62e48ffa4283b688f0049005405a004447ad38ffc99a0efea4c3aa9b7eed739f7402b43f00668c0ee5a895b684dc953d62f0722d8a92c5b2f6c95f051bceb208 languageName: node linkType: hard From a4e2242b8dfa3241a9836911bce07771faa42db2 Mon Sep 17 00:00:00 2001 From: DarkSky <25152247+darkskygit@users.noreply.github.com> Date: Fri, 27 Feb 2026 22:56:43 +0800 Subject: [PATCH 06/49] chore: bump playwright (#13947) ## Summary by CodeRabbit * **Chores** * Updated Playwright test tooling to 1.58.2 across the repository and test packages. * **Tests** * Improved end-to-end robustness: replaced fragile timing/coordinate logic with element-based interactions, added polling/retry checks for flaky asserts and async state, and simplified input/rename flows to reduce test flakiness. --- package.json | 2 +- tests/affine-cloud-copilot/package.json | 2 +- tests/affine-cloud/package.json | 2 +- tests/affine-desktop-cloud/package.json | 2 +- tests/affine-desktop/package.json | 4 +- tests/affine-local/e2e/quick-search.spec.ts | 13 +++- tests/affine-local/package.json | 2 +- tests/affine-mobile/package.json | 2 +- tests/blocksuite/e2e/attachment.spec.ts | 17 ++-- .../inline/inline-editor.spec.ts | 35 +++++---- .../blocksuite/e2e/utils/actions/edgeless.ts | 8 +- tests/blocksuite/e2e/utils/actions/misc.ts | 78 +++++++++++++------ tests/blocksuite/e2e/utils/asserts.ts | 70 ++++++++++------- tests/blocksuite/package.json | 2 +- tests/kit/package.json | 2 +- yarn.lock | 48 ++++++------ 16 files changed, 170 insertions(+), 119 deletions(-) diff --git a/package.json b/package.json index 71ffb21f79..e89c8b981c 100644 --- a/package.json +++ b/package.json @@ -56,7 +56,7 @@ "@faker-js/faker": "^10.1.0", "@istanbuljs/schema": "^0.1.3", "@magic-works/i18n-codegen": "^0.6.1", - "@playwright/test": "=1.52.0", + "@playwright/test": "=1.58.2", "@smarttools/eslint-plugin-rxjs": "^1.0.8", "@taplo/cli": "^0.7.0", "@toeverything/infra": "workspace:*", diff --git a/tests/affine-cloud-copilot/package.json b/tests/affine-cloud-copilot/package.json index 8aac7e2ed1..a81b2af191 100644 --- a/tests/affine-cloud-copilot/package.json +++ b/tests/affine-cloud-copilot/package.json @@ -7,7 +7,7 @@ }, "devDependencies": { "@affine-test/kit": "workspace:*", - "@playwright/test": "=1.52.0" + "@playwright/test": "=1.58.2" }, "version": "0.26.3" } diff --git a/tests/affine-cloud/package.json b/tests/affine-cloud/package.json index 3be53c02c1..afb50235bb 100644 --- a/tests/affine-cloud/package.json +++ b/tests/affine-cloud/package.json @@ -7,7 +7,7 @@ }, "devDependencies": { "@affine-test/kit": "workspace:*", - "@playwright/test": "=1.52.0" + "@playwright/test": "=1.58.2" }, "version": "0.26.3" } diff --git a/tests/affine-desktop-cloud/package.json b/tests/affine-desktop-cloud/package.json index 4a8ca27b84..c0ed9e39dd 100644 --- a/tests/affine-desktop-cloud/package.json +++ b/tests/affine-desktop-cloud/package.json @@ -7,7 +7,7 @@ }, "devDependencies": { "@affine-test/kit": "workspace:*", - "@playwright/test": "=1.52.0" + "@playwright/test": "=1.58.2" }, "version": "0.26.3" } diff --git a/tests/affine-desktop/package.json b/tests/affine-desktop/package.json index e8da361308..653a2f6327 100644 --- a/tests/affine-desktop/package.json +++ b/tests/affine-desktop/package.json @@ -8,10 +8,10 @@ "devDependencies": { "@affine-test/kit": "workspace:*", "@affine/electron-api": "workspace:*", - "@playwright/test": "=1.52.0", + "@playwright/test": "=1.58.2", "@types/fs-extra": "^11.0.4", "fs-extra": "^11.2.0", - "playwright": "=1.52.0" + "playwright": "=1.58.2" }, "version": "0.26.3" } diff --git a/tests/affine-local/e2e/quick-search.spec.ts b/tests/affine-local/e2e/quick-search.spec.ts index a3a77d5442..a6e4935d3f 100644 --- a/tests/affine-local/e2e/quick-search.spec.ts +++ b/tests/affine-local/e2e/quick-search.spec.ts @@ -417,12 +417,19 @@ test('Create a new page with special characters in the title and search for this await clickNewPageButton(page); await getBlockSuiteEditorTitle(page).click(); await getBlockSuiteEditorTitle(page).fill(specialTitle); + await page.keyboard.press('Enter'); + await expect(getBlockSuiteEditorTitle(page)).toContainText(specialTitle); await openQuickSearchByShortcut(page); await insertInputText(page, specialTitle); - await page.waitForTimeout(1000); - - await assertResultList(page, [specialTitle, specialTitle]); + await expect + .poll(async () => { + const labels = await page + .locator('[cmdk-item] [data-testid=cmdk-label]') + .allInnerTexts(); + return labels.some(label => label.split('\n').includes(specialTitle)); + }) + .toBe(true); await page.keyboard.press('Enter'); await page.waitForTimeout(1000); await assertTitle(page, specialTitle); diff --git a/tests/affine-local/package.json b/tests/affine-local/package.json index f0ddadfb4b..c4e8a75aaf 100644 --- a/tests/affine-local/package.json +++ b/tests/affine-local/package.json @@ -9,7 +9,7 @@ "@affine-test/kit": "workspace:*", "@affine-tools/cli": "workspace:*", "@affine-tools/utils": "workspace:*", - "@playwright/test": "=1.52.0", + "@playwright/test": "=1.58.2", "webpack": "^5.102.1" }, "version": "0.26.3" diff --git a/tests/affine-mobile/package.json b/tests/affine-mobile/package.json index bf87587b03..bfcf167055 100644 --- a/tests/affine-mobile/package.json +++ b/tests/affine-mobile/package.json @@ -7,7 +7,7 @@ }, "devDependencies": { "@affine-test/kit": "workspace:*", - "@playwright/test": "=1.52.0" + "@playwright/test": "=1.58.2" }, "version": "0.26.3" } diff --git a/tests/blocksuite/e2e/attachment.spec.ts b/tests/blocksuite/e2e/attachment.spec.ts index d6d81fa044..5f633aeb04 100644 --- a/tests/blocksuite/e2e/attachment.spec.ts +++ b/tests/blocksuite/e2e/attachment.spec.ts @@ -15,7 +15,6 @@ import { pressShiftTab, pressTab, redoByKeyboard, - SHORT_KEY, type, undoByKeyboard, } from './utils/actions/keyboard.js'; @@ -113,11 +112,13 @@ function getAttachment(page: Page) { await attachment.click(); await expect(toolbar).toBeVisible(); await renameBtn.click(); - await page.keyboard.press(`${SHORT_KEY}+a`, { delay: 50 }); - await pressBackspace(page); - await type(page, newName); + await expect(renameInput).toBeVisible(); + await renameInput.fill(newName); await pressEnter(page); - expect(await getName()).toContain(newName); + await expect(renameInput).not.toBeVisible(); + if (newName.length > 0) { + await expect.poll(getName).toContain(newName); + } }, // external @@ -215,11 +216,11 @@ test('should rename attachment works', async ({ page }) => { await expect(renameInput).not.toBeVisible(); await rename('new-name'); - expect(await getName()).toBe('new-name.png'); + await expect.poll(getName).toBe('new-name.png'); await rename(''); - expect(await getName()).toBe('.png'); + await expect.poll(getName).toBe('.png'); await rename('abc'); - expect(await getName()).toBe('abc'); + await expect.poll(getName).toBe('abc'); }); test('should turn attachment to image works', async ({ page }, testInfo) => { diff --git a/tests/blocksuite/e2e/cross-platform/inline/inline-editor.spec.ts b/tests/blocksuite/e2e/cross-platform/inline/inline-editor.spec.ts index 090699cee5..6ee037d35d 100644 --- a/tests/blocksuite/e2e/cross-platform/inline/inline-editor.spec.ts +++ b/tests/blocksuite/e2e/cross-platform/inline/inline-editor.spec.ts @@ -143,17 +143,20 @@ async function assertSelection( rangeIndex: number, rangeLength = 0 ) { - const actual = await page.evaluate( - ([richTextIndex]) => { - const richText = - document?.querySelectorAll('test-rich-text')[richTextIndex]; - // @ts-expect-error getInlineRange - const inlineEditor = richText.inlineEditor; - return inlineEditor?.getInlineRange(); - }, - [richTextIndex] - ); - expect(actual).toEqual({ index: rangeIndex, length: rangeLength }); + await expect + .poll(async () => { + return page.evaluate( + ([richTextIndex]) => { + const richText = + document?.querySelectorAll('test-rich-text')[richTextIndex]; + // @ts-expect-error getInlineRange + const inlineEditor = richText.inlineEditor; + return inlineEditor?.getInlineRange(); + }, + [richTextIndex] + ); + }) + .toEqual({ index: rangeIndex, length: rangeLength }); } test('basic input', async ({ page, browserName }) => { @@ -1113,16 +1116,14 @@ test('embed', async ({ page }) => { await assertSelection(page, 0, 3, 1); // try to update cursor position and select embed element by clicking embed element - let rect = await getInlineRangeIndexRect(page, [0, 1]); - await page.mouse.click(rect.x + 3, rect.y); + const embeds = page.locator('[data-v-embed="true"]'); + await embeds.nth(0).click(); await assertSelection(page, 0, 1, 1); - rect = await getInlineRangeIndexRect(page, [0, 2]); - await page.mouse.click(rect.x + 3, rect.y); + await embeds.nth(1).click(); await assertSelection(page, 0, 2, 1); - rect = await getInlineRangeIndexRect(page, [0, 3]); - await page.mouse.click(rect.x + 3, rect.y); + await embeds.nth(2).click(); await assertSelection(page, 0, 3, 1); }); diff --git a/tests/blocksuite/e2e/utils/actions/edgeless.ts b/tests/blocksuite/e2e/utils/actions/edgeless.ts index 7aa505c47f..3828fc8d85 100644 --- a/tests/blocksuite/e2e/utils/actions/edgeless.ts +++ b/tests/blocksuite/e2e/utils/actions/edgeless.ts @@ -820,10 +820,10 @@ export async function updateExistedBrushElementSize( page: Page, nthSizeButton: 1 | 2 | 3 | 4 | 5 | 6 ) { - // get the nth brush size button - const btn = page.locator( - `edgeless-line-width-panel .point-button:nth-child(${nthSizeButton})` - ); + // pick from the visible panel to avoid strict-mode collisions from hidden/duplicate toolbars + const btn = page + .locator('edgeless-line-width-panel:visible .point-button') + .nth(nthSizeButton - 1); await btn.click(); } diff --git a/tests/blocksuite/e2e/utils/actions/misc.ts b/tests/blocksuite/e2e/utils/actions/misc.ts index 9cb928da79..f2d37644f6 100644 --- a/tests/blocksuite/e2e/utils/actions/misc.ts +++ b/tests/blocksuite/e2e/utils/actions/misc.ts @@ -1015,31 +1015,63 @@ export async function getIndexCoordinate( [richTextIndex, vIndex]: [number, number], coordOffSet: { x: number; y: number } = { x: 0, y: 0 } ) { - const coord = await page.evaluate( - ({ richTextIndex, vIndex, coordOffSet, currentEditorIndex }) => { - const editorHost = - document.querySelectorAll('editor-host')[currentEditorIndex]; - const richText = editorHost.querySelectorAll('rich-text')[ - richTextIndex - ] as any; - const domRange = richText.inlineEditor.toDomRange({ - index: vIndex, - length: 0, - }); - const pointBound = domRange.getBoundingClientRect(); - return { - x: pointBound.left + coordOffSet.x, - y: pointBound.top + pointBound.height / 2 + coordOffSet.y, - }; - }, - { - richTextIndex, - vIndex, - coordOffSet, - currentEditorIndex, + for (let attempt = 0; attempt < 20; attempt++) { + const coord = await page.evaluate( + ({ richTextIndex, vIndex, coordOffSet, currentEditorIndex }) => { + const editorHost = + document.querySelectorAll('editor-host')[currentEditorIndex]; + const richTexts = Array.from( + editorHost?.querySelectorAll('rich-text') ?? [] + ); + if (!richTexts.length) { + return null; + } + const richText = richTexts[ + Math.min(richTextIndex, richTexts.length - 1) + ] as any; + const inlineEditor = richText?.inlineEditor; + if (!inlineEditor) { + return null; + } + const clampedIndex = Math.max( + 0, + Math.min(vIndex, inlineEditor.yTextLength ?? vIndex) + ); + const domRange = inlineEditor.toDomRange({ + index: clampedIndex, + length: 0, + }); + if (!domRange) { + return null; + } + const pointBound = domRange.getBoundingClientRect(); + if ( + !Number.isFinite(pointBound.left) || + !Number.isFinite(pointBound.top) + ) { + return null; + } + return { + x: pointBound.left + coordOffSet.x, + y: pointBound.top + pointBound.height / 2 + coordOffSet.y, + }; + }, + { + richTextIndex, + vIndex, + coordOffSet, + currentEditorIndex, + } + ); + if (coord) { + return coord; } + await page.waitForTimeout(50); + } + + throw new Error( + `Failed to get index coordinate: richTextIndex=${richTextIndex}, vIndex=${vIndex}` ); - return coord; } export function inlineEditorInnerTextToString(innerText: string): string { diff --git a/tests/blocksuite/e2e/utils/asserts.ts b/tests/blocksuite/e2e/utils/asserts.ts index 61471815a4..fbc4160d80 100644 --- a/tests/blocksuite/e2e/utils/asserts.ts +++ b/tests/blocksuite/e2e/utils/asserts.ts @@ -159,17 +159,20 @@ export async function assertTextContain(page: Page, text: string, i = 0) { } export async function assertRichTexts(page: Page, texts: string[]) { - const actualTexts = await page.evaluate(() => { - const editorHost = document.querySelector('editor-host'); - const richTexts = Array.from( - editorHost?.querySelectorAll('rich-text') ?? [] - ); - return richTexts.map(richText => { - const editor = richText.inlineEditor as AffineInlineEditor; - return editor.yText.toString(); - }); - }); - expect(actualTexts).toEqual(texts); + await expect + .poll(async () => { + return page.evaluate(() => { + const editorHost = document.querySelector('editor-host'); + const richTexts = Array.from( + editorHost?.querySelectorAll('rich-text') ?? [] + ); + return richTexts.map(richText => { + const editor = richText.inlineEditor as AffineInlineEditor; + return editor.yText.toString(); + }); + }); + }) + .toEqual(texts); } export async function assertEdgelessCanvasText(page: Page, text: string) { @@ -274,16 +277,20 @@ export async function assertRichTextInlineRange( rangeIndex: number, rangeLength = 0 ) { - const actual = await page.evaluate( - ([richTextIndex]) => { - const editorHost = document.querySelector('editor-host'); - const richText = editorHost?.querySelectorAll('rich-text')[richTextIndex]; - const inlineEditor = richText?.inlineEditor; - return inlineEditor?.getInlineRange(); - }, - [richTextIndex] - ); - expect(actual).toEqual({ index: rangeIndex, length: rangeLength }); + await expect + .poll(async () => { + return page.evaluate( + ([richTextIndex]) => { + const editorHost = document.querySelector('editor-host'); + const richText = + editorHost?.querySelectorAll('rich-text')[richTextIndex]; + const inlineEditor = richText?.inlineEditor; + return inlineEditor?.getInlineRange(); + }, + [richTextIndex] + ); + }) + .toEqual({ index: rangeIndex, length: rangeLength }); } export async function assertNativeSelectionRangeCount( @@ -1137,15 +1144,18 @@ export async function assertNoteSequence(page: Page, expected: string) { } export async function assertBlockSelections(page: Page, paths: string[]) { - const selections = await page.evaluate(() => { - const host = document.querySelector('editor-host'); - if (!host) { - throw new Error('editor-host host not found'); - } - return host.selection.value.filter(b => b.type === 'block'); - }); - const actualPaths = selections.map(selection => selection.blockId); - expect(actualPaths).toEqual(paths); + await expect + .poll(async () => { + const selections = await page.evaluate(() => { + const host = document.querySelector('editor-host'); + if (!host) { + throw new Error('editor-host host not found'); + } + return host.selection.value.filter(b => b.type === 'block'); + }); + return selections.map(selection => selection.blockId); + }) + .toEqual(paths); } export async function assertTextSelection( diff --git a/tests/blocksuite/package.json b/tests/blocksuite/package.json index 461a235430..af474a2fbf 100644 --- a/tests/blocksuite/package.json +++ b/tests/blocksuite/package.json @@ -9,7 +9,7 @@ "@affine-test/kit": "workspace:*", "@blocksuite/affine": "workspace:*", "@blocksuite/integration-test": "workspace:*", - "@playwright/test": "=1.52.0", + "@playwright/test": "=1.58.2", "@toeverything/theme": "^1.1.23", "json-stable-stringify": "^1.2.1", "rxjs": "^7.8.2" diff --git a/tests/kit/package.json b/tests/kit/package.json index 1a97b4c9f0..f91ac9e861 100644 --- a/tests/kit/package.json +++ b/tests/kit/package.json @@ -14,7 +14,7 @@ "@affine-tools/utils": "workspace:*", "@blocksuite/affine": "workspace:*", "@node-rs/argon2": "^2.0.2", - "@playwright/test": "=1.52.0", + "@playwright/test": "=1.58.2", "@toeverything/infra": "workspace:*", "express": "^5.0.0", "http-proxy-middleware": "^3.0.3" diff --git a/yarn.lock b/yarn.lock index a00e9bb446..7d8eb17994 100644 --- a/yarn.lock +++ b/yarn.lock @@ -24,7 +24,7 @@ __metadata: resolution: "@affine-test/affine-cloud-copilot@workspace:tests/affine-cloud-copilot" dependencies: "@affine-test/kit": "workspace:*" - "@playwright/test": "npm:=1.52.0" + "@playwright/test": "npm:=1.58.2" languageName: unknown linkType: soft @@ -33,7 +33,7 @@ __metadata: resolution: "@affine-test/affine-cloud@workspace:tests/affine-cloud" dependencies: "@affine-test/kit": "workspace:*" - "@playwright/test": "npm:=1.52.0" + "@playwright/test": "npm:=1.58.2" languageName: unknown linkType: soft @@ -42,7 +42,7 @@ __metadata: resolution: "@affine-test/affine-desktop-cloud@workspace:tests/affine-desktop-cloud" dependencies: "@affine-test/kit": "workspace:*" - "@playwright/test": "npm:=1.52.0" + "@playwright/test": "npm:=1.58.2" languageName: unknown linkType: soft @@ -52,10 +52,10 @@ __metadata: dependencies: "@affine-test/kit": "workspace:*" "@affine/electron-api": "workspace:*" - "@playwright/test": "npm:=1.52.0" + "@playwright/test": "npm:=1.58.2" "@types/fs-extra": "npm:^11.0.4" fs-extra: "npm:^11.2.0" - playwright: "npm:=1.52.0" + playwright: "npm:=1.58.2" languageName: unknown linkType: soft @@ -66,7 +66,7 @@ __metadata: "@affine-test/kit": "workspace:*" "@affine-tools/cli": "workspace:*" "@affine-tools/utils": "workspace:*" - "@playwright/test": "npm:=1.52.0" + "@playwright/test": "npm:=1.58.2" webpack: "npm:^5.102.1" languageName: unknown linkType: soft @@ -76,7 +76,7 @@ __metadata: resolution: "@affine-test/affine-mobile@workspace:tests/affine-mobile" dependencies: "@affine-test/kit": "workspace:*" - "@playwright/test": "npm:=1.52.0" + "@playwright/test": "npm:=1.58.2" languageName: unknown linkType: soft @@ -87,7 +87,7 @@ __metadata: "@affine-test/kit": "workspace:*" "@blocksuite/affine": "workspace:*" "@blocksuite/integration-test": "workspace:*" - "@playwright/test": "npm:=1.52.0" + "@playwright/test": "npm:=1.58.2" "@toeverything/theme": "npm:^1.1.23" json-stable-stringify: "npm:^1.2.1" rxjs: "npm:^7.8.2" @@ -101,7 +101,7 @@ __metadata: "@affine-tools/utils": "workspace:*" "@blocksuite/affine": "workspace:*" "@node-rs/argon2": "npm:^2.0.2" - "@playwright/test": "npm:=1.52.0" + "@playwright/test": "npm:=1.58.2" "@toeverything/infra": "workspace:*" express: "npm:^5.0.0" http-proxy-middleware: "npm:^3.0.3" @@ -809,7 +809,7 @@ __metadata: "@faker-js/faker": "npm:^10.1.0" "@istanbuljs/schema": "npm:^0.1.3" "@magic-works/i18n-codegen": "npm:^0.6.1" - "@playwright/test": "npm:=1.52.0" + "@playwright/test": "npm:=1.58.2" "@smarttools/eslint-plugin-rxjs": "npm:^1.0.8" "@taplo/cli": "npm:^0.7.0" "@toeverything/infra": "workspace:*" @@ -10900,14 +10900,14 @@ __metadata: languageName: node linkType: hard -"@playwright/test@npm:=1.52.0": - version: 1.52.0 - resolution: "@playwright/test@npm:1.52.0" +"@playwright/test@npm:=1.58.2": + version: 1.58.2 + resolution: "@playwright/test@npm:1.58.2" dependencies: - playwright: "npm:1.52.0" + playwright: "npm:1.58.2" bin: playwright: cli.js - checksum: 10/e18a4eb626c7bc6cba212ff2e197cf9ae2e4da1c91bfdf08a744d62e27222751173e4b220fa27da72286a89a3b4dea7c09daf384d23708f284b64f98e9a63a88 + checksum: 10/58bf90139280a0235eeeb6049e9fb4db6425e98be1bf0cc17913b068eef616cf67be57bfb36dc4cb56bcf116f498ffd0225c4916e85db404b343ea6c5efdae13 languageName: node linkType: hard @@ -31101,27 +31101,27 @@ __metadata: languageName: node linkType: hard -"playwright-core@npm:1.52.0": - version: 1.52.0 - resolution: "playwright-core@npm:1.52.0" +"playwright-core@npm:1.58.2": + version: 1.58.2 + resolution: "playwright-core@npm:1.58.2" bin: playwright-core: cli.js - checksum: 10/42e13f5f98dc25ebc95525fb338a215b9097b2ba39d41e99972a190bf75d79979f163f5bc07b1ca06847ee07acb2c9b487d070fab67e9cd55e33310fc05aca3c + checksum: 10/8a98fcf122167e8703d525db2252de0e3da4ab9110ab6ea9951247e52d846310eb25ea2c805e1b7ccb54b4010c44e5adc3a76aae6da02f34324ccc3e76683bb1 languageName: node linkType: hard -"playwright@npm:1.52.0, playwright@npm:=1.52.0": - version: 1.52.0 - resolution: "playwright@npm:1.52.0" +"playwright@npm:1.58.2, playwright@npm:=1.58.2": + version: 1.58.2 + resolution: "playwright@npm:1.58.2" dependencies: fsevents: "npm:2.3.2" - playwright-core: "npm:1.52.0" + playwright-core: "npm:1.58.2" dependenciesMeta: fsevents: optional: true bin: playwright: cli.js - checksum: 10/214175446089000c2ac997b925063b95f7d86d129c5d7c74caa5ddcb05bcad598dfd569d2133a10dc82d288bf67e7858877dcd099274b0b928b9c63db7d6ecec + checksum: 10/d89d6c8a32388911b9aff9ee0f1a90076219f15c804f2b287db048b9e9cde182aea3131fac1959051d25189ed4218ec4272b137c83cd7f9cd24781cbc77edd86 languageName: node linkType: hard From 2cb171f5530b3679060bbbc89eb44f9962c8649b Mon Sep 17 00:00:00 2001 From: DarkSky <25152247+darkskygit@users.noreply.github.com> Date: Sat, 28 Feb 2026 00:24:08 +0800 Subject: [PATCH 07/49] feat: cleanup webpack deps (#14530) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #### PR Dependency Tree * **PR #14530** 👈 This tree was auto-generated by [Charcoal](https://github.com/danerwilliams/charcoal) ## Summary by CodeRabbit * **Breaking Changes** * Webpack bundler support removed from the build system * Bundler selection parameter removed from build and development commands * **Refactor** * Build configuration consolidated to a single bundler approach * Webpack-specific build paths and workflows removed; development server simplified * **Chores** * Removed webpack-related dev dependencies and tooling * Updated package build scripts for a unified bundle command * **Dependencies** * Upgraded Sentry packages across frontend packages (react/electron/esbuild plugin) --- .github/workflows/build-test.yml | 46 - packages/common/reader/esbuild.config.js | 23 - packages/common/reader/package.json | 4 +- packages/frontend/admin/package.json | 2 +- packages/frontend/apps/android/package.json | 2 +- .../apps/electron-renderer/package.json | 2 +- packages/frontend/apps/electron/package.json | 7 +- packages/frontend/apps/ios/package.json | 2 +- packages/frontend/apps/mobile/package.json | 2 +- packages/frontend/apps/web/package.json | 2 +- packages/frontend/core/package.json | 2 +- packages/frontend/core/src/types/types.d.ts | 1 - packages/frontend/track/package.json | 2 +- tests/affine-local/package.json | 3 +- tools/cli/package.json | 14 +- tools/cli/src/bundle-shared.ts | 7 +- tools/cli/src/bundle.ts | 210 +-- tools/cli/src/bundler.ts | 27 - .../{webpack => rspack-shared}/cache-group.ts | 0 .../error-handler.js | 16 +- .../{webpack => rspack-shared}/html-plugin.ts | 9 +- .../{webpack => rspack-shared}/node-loader.js | 0 .../{webpack => rspack-shared}/s3-plugin.ts | 0 .../{webpack => rspack-shared}/template.html | 0 tools/cli/src/rspack/index.ts | 100 +- tools/cli/src/run.ts | 2 +- tools/cli/src/webpack/index.ts | 639 -------- tools/cli/src/webpack/types.ts | 4 - tsconfig.web.json | 2 +- yarn.lock | 1387 ++++++----------- 30 files changed, 588 insertions(+), 1929 deletions(-) delete mode 100644 packages/common/reader/esbuild.config.js delete mode 100644 tools/cli/src/bundler.ts rename tools/cli/src/{webpack => rspack-shared}/cache-group.ts (100%) rename tools/cli/src/{webpack => rspack-shared}/error-handler.js (91%) rename tools/cli/src/{webpack => rspack-shared}/html-plugin.ts (98%) rename tools/cli/src/{webpack => rspack-shared}/node-loader.js (100%) rename tools/cli/src/{webpack => rspack-shared}/s3-plugin.ts (100%) rename tools/cli/src/{webpack => rspack-shared}/template.html (100%) delete mode 100644 tools/cli/src/webpack/index.ts delete mode 100644 tools/cli/src/webpack/types.ts diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml index 0c072cbf3d..8704e60108 100644 --- a/.github/workflows/build-test.yml +++ b/.github/workflows/build-test.yml @@ -282,52 +282,6 @@ jobs: path: ./test-results if-no-files-found: ignore - bundler-matrix: - name: Bundler Matrix (${{ matrix.bundler }}) - runs-on: ubuntu-24.04-arm - strategy: - fail-fast: false - matrix: - bundler: [webpack, rspack] - steps: - - uses: actions/checkout@v4 - - name: Setup Node.js - uses: ./.github/actions/setup-node - with: - playwright-install: false - electron-install: false - full-cache: true - - - name: Run frontend build matrix - env: - AFFINE_BUNDLER: ${{ matrix.bundler }} - run: | - set -euo pipefail - packages=( - "@affine/web" - "@affine/mobile" - "@affine/ios" - "@affine/android" - "@affine/admin" - "@affine/electron-renderer" - ) - summary="test-results-bundler-${AFFINE_BUNDLER}.txt" - : > "$summary" - for pkg in "${packages[@]}"; do - start=$(date +%s) - yarn affine "$pkg" build - end=$(date +%s) - echo "${pkg},$((end-start))" >> "$summary" - done - - - name: Upload bundler timing - if: always() - uses: actions/upload-artifact@v4 - with: - name: test-results-bundler-${{ matrix.bundler }} - path: ./test-results-bundler-${{ matrix.bundler }}.txt - if-no-files-found: ignore - e2e-test: name: E2E Test runs-on: ubuntu-24.04-arm diff --git a/packages/common/reader/esbuild.config.js b/packages/common/reader/esbuild.config.js deleted file mode 100644 index 416fc537f2..0000000000 --- a/packages/common/reader/esbuild.config.js +++ /dev/null @@ -1,23 +0,0 @@ -import fs from 'node:fs/promises'; -import path from 'node:path'; - -import { build } from 'esbuild'; - -const result = await build({ - entryPoints: ['./src/index.ts'], - bundle: true, - platform: 'node', - outdir: 'dist', - target: 'es2024', - sourcemap: true, - format: 'esm', - external: ['yjs'], - metafile: true, -}); - -if (process.env.METAFILE) { - await fs.writeFile( - path.resolve(`metafile-${Date.now()}.json`), - JSON.stringify(result.metafile, null, 2) - ); -} diff --git a/packages/common/reader/package.json b/packages/common/reader/package.json index 58eab0fabe..2c6981e7e1 100644 --- a/packages/common/reader/package.json +++ b/packages/common/reader/package.json @@ -10,8 +10,8 @@ "./dist": "./dist/index.js" }, "scripts": { - "build": "yarn bundle", - "bundle": "node esbuild.config.js" + "build": "affine bundle -p @affine/reader", + "bundle": "affine bundle -p @affine/reader" }, "dependencies": { "lodash-es": "^4.17.23", diff --git a/packages/frontend/admin/package.json b/packages/frontend/admin/package.json index 6150a5c073..156ed74e05 100644 --- a/packages/frontend/admin/package.json +++ b/packages/frontend/admin/package.json @@ -37,7 +37,7 @@ "@radix-ui/react-toggle": "^1.1.1", "@radix-ui/react-toggle-group": "^1.1.1", "@radix-ui/react-tooltip": "^1.1.5", - "@sentry/react": "^9.47.1", + "@sentry/react": "^10.40.0", "@tanstack/react-table": "^8.20.5", "@toeverything/infra": "workspace:*", "@toeverything/theme": "^1.1.23", diff --git a/packages/frontend/apps/android/package.json b/packages/frontend/apps/android/package.json index c00807ba31..9762a7554d 100644 --- a/packages/frontend/apps/android/package.json +++ b/packages/frontend/apps/android/package.json @@ -26,7 +26,7 @@ "@capacitor/keyboard": "^7.0.0", "@capacitor/status-bar": "^7.0.0", "@capgo/inappbrowser": "^8.0.0", - "@sentry/react": "^9.47.1", + "@sentry/react": "^10.40.0", "@toeverything/infra": "workspace:*", "async-call-rpc": "^6.4.2", "idb": "^8.0.0", diff --git a/packages/frontend/apps/electron-renderer/package.json b/packages/frontend/apps/electron-renderer/package.json index fbfefb7154..18434dbb57 100644 --- a/packages/frontend/apps/electron-renderer/package.json +++ b/packages/frontend/apps/electron-renderer/package.json @@ -17,7 +17,7 @@ "@affine/track": "workspace:*", "@blocksuite/affine": "workspace:*", "@emotion/react": "^11.14.0", - "@sentry/react": "^9.47.1", + "@sentry/react": "^10.40.0", "@toeverything/infra": "workspace:*", "@toeverything/theme": "^1.1.23", "@vanilla-extract/css": "^1.17.0", diff --git a/packages/frontend/apps/electron/package.json b/packages/frontend/apps/electron/package.json index 94961b2d52..25c848854b 100644 --- a/packages/frontend/apps/electron/package.json +++ b/packages/frontend/apps/electron/package.json @@ -38,7 +38,6 @@ "@affine/nbstore": "workspace:*", "@electron-forge/cli": "^7.10.2", "@electron-forge/core": "^7.10.2", - "@electron-forge/core-utils": "^7.10.2", "@electron-forge/maker-deb": "^7.10.2", "@electron-forge/maker-dmg": "^7.10.2", "@electron-forge/maker-flatpak": "^7.10.2", @@ -48,9 +47,9 @@ "@electron-forge/plugin-fuses": "^7.10.2", "@electron-forge/shared-types": "^7.10.2", "@reforged/maker-appimage": "^5.2.0", - "@sentry/electron": "^7.0.0", - "@sentry/esbuild-plugin": "^4.0.0", - "@sentry/react": "^9.47.1", + "@sentry/electron": "^7.9.0", + "@sentry/esbuild-plugin": "^5.1.1", + "@sentry/react": "^10.40.0", "@toeverything/infra": "workspace:*", "@types/set-cookie-parser": "^2.4.10", "@types/uuid": "^11.0.0", diff --git a/packages/frontend/apps/ios/package.json b/packages/frontend/apps/ios/package.json index 31b1dc93a3..f07220e773 100644 --- a/packages/frontend/apps/ios/package.json +++ b/packages/frontend/apps/ios/package.json @@ -30,7 +30,7 @@ "@capacitor/haptics": "^7.0.0", "@capacitor/ios": "^7.0.0", "@capacitor/keyboard": "^7.0.0", - "@sentry/react": "^9.47.1", + "@sentry/react": "^10.40.0", "@toeverything/infra": "workspace:^", "async-call-rpc": "^6.4.2", "capacitor-plugin-app-tracking-transparency": "^2.0.5", diff --git a/packages/frontend/apps/mobile/package.json b/packages/frontend/apps/mobile/package.json index 1bc49f8615..b1998b6191 100644 --- a/packages/frontend/apps/mobile/package.json +++ b/packages/frontend/apps/mobile/package.json @@ -17,7 +17,7 @@ "@affine/track": "workspace:*", "@blocksuite/affine": "workspace:*", "@blocksuite/icons": "^2.2.17", - "@sentry/react": "^9.47.1", + "@sentry/react": "^10.40.0", "@toeverything/infra": "workspace:*", "react": "^19.2.1", "react-dom": "^19.2.1", diff --git a/packages/frontend/apps/web/package.json b/packages/frontend/apps/web/package.json index ebd677b86c..cdff43e9eb 100644 --- a/packages/frontend/apps/web/package.json +++ b/packages/frontend/apps/web/package.json @@ -16,7 +16,7 @@ "@affine/nbstore": "workspace:*", "@affine/track": "workspace:*", "@emotion/react": "^11.14.0", - "@sentry/react": "^9.47.1", + "@sentry/react": "^10.40.0", "@toeverything/infra": "workspace:*", "react": "^19.2.1", "react-dom": "^19.2.1", diff --git a/packages/frontend/core/package.json b/packages/frontend/core/package.json index 8bb8fc4ee9..a5c903d7f6 100644 --- a/packages/frontend/core/package.json +++ b/packages/frontend/core/package.json @@ -45,7 +45,7 @@ "@radix-ui/react-scroll-area": "^1.2.2", "@radix-ui/react-slot": "^1.1.1", "@radix-ui/react-toolbar": "^1.1.1", - "@sentry/react": "^9.47.1", + "@sentry/react": "^10.40.0", "@toeverything/infra": "workspace:*", "@toeverything/pdf-viewer": "^0.1.1", "@toeverything/theme": "^1.1.23", diff --git a/packages/frontend/core/src/types/types.d.ts b/packages/frontend/core/src/types/types.d.ts index aaf9a5423b..7f31cf9e12 100644 --- a/packages/frontend/core/src/types/types.d.ts +++ b/packages/frontend/core/src/types/types.d.ts @@ -1,4 +1,3 @@ -/// /// declare module '*.md' { diff --git a/packages/frontend/track/package.json b/packages/frontend/track/package.json index 28f40cbadd..d584d9340f 100644 --- a/packages/frontend/track/package.json +++ b/packages/frontend/track/package.json @@ -8,7 +8,7 @@ }, "dependencies": { "@affine/debug": "workspace:*", - "@sentry/react": "^9.47.1", + "@sentry/react": "^10.40.0", "nanoid": "^5.1.6", "react-router-dom": "^6.30.3" }, diff --git a/tests/affine-local/package.json b/tests/affine-local/package.json index c4e8a75aaf..c1c40781d7 100644 --- a/tests/affine-local/package.json +++ b/tests/affine-local/package.json @@ -9,8 +9,7 @@ "@affine-test/kit": "workspace:*", "@affine-tools/cli": "workspace:*", "@affine-tools/utils": "workspace:*", - "@playwright/test": "=1.58.2", - "webpack": "^5.102.1" + "@playwright/test": "=1.58.2" }, "version": "0.26.3" } diff --git a/tools/cli/package.json b/tools/cli/package.json index 81b6c3a41f..dbaa33749c 100644 --- a/tools/cli/package.json +++ b/tools/cli/package.json @@ -18,16 +18,14 @@ "@affine-tools/utils": "workspace:*", "@affine/s3-compat": "workspace:*", "@napi-rs/simple-git": "^0.1.22", - "@perfsee/webpack": "^1.13.0", "@rspack/core": "^1.7.6", "@rspack/dev-server": "^1.1.3", - "@sentry/webpack-plugin": "^4.0.0", + "@sentry/webpack-plugin": "^5.1.1", "@swc/core": "^1.10.1", "@tailwindcss/postcss": "^4.0.0", "@vanilla-extract/webpack-plugin": "^2.3.15", "autoprefixer": "^10.4.20", "clipanion": "^3.2.1", - "copy-webpack-plugin": "^13.0.0", "css-loader": "^7.1.2", "cssnano": "^7.0.6", "html-webpack-plugin": "^5.6.3", @@ -35,7 +33,6 @@ "jsonc-parser": "^3.3.1", "lodash-es": "^4.17.23", "mime-types": "^3.0.0", - "mini-css-extract-plugin": "^2.9.2", "node-loader": "^2.1.0", "postcss": "^8.4.49", "postcss-loader": "^8.1.1", @@ -46,18 +43,13 @@ "style-loader": "^4.0.0", "swc-loader": "^0.2.6", "tailwindcss": "^4.1.17", - "terser-webpack-plugin": "^5.3.10", "tsx": "^4.21.0", "typanion": "^3.14.0", - "typescript": "^5.9.3", - "webpack": "^5.102.1", - "webpack-dev-server": "^5.2.0", - "webpack-merge": "^6.0.1" + "typescript": "^5.9.3" }, "devDependencies": { "@types/lodash-es": "^4.17.12", "@types/mime-types": "^3.0.0", - "@types/node": "^22.0.0", - "@types/webpack-env": "^1.18.5" + "@types/node": "^22.0.0" } } diff --git a/tools/cli/src/bundle-shared.ts b/tools/cli/src/bundle-shared.ts index 630f1b063e..27038ea0c3 100644 --- a/tools/cli/src/bundle-shared.ts +++ b/tools/cli/src/bundle-shared.ts @@ -1,4 +1,4 @@ -import type { Configuration as WebpackDevServerConfiguration } from 'webpack-dev-server'; +import type { Configuration as RspackDevServerConfiguration } from '@rspack/dev-server'; export const RSPACK_SUPPORTED_PACKAGES = [ '@affine/admin', @@ -8,6 +8,7 @@ export const RSPACK_SUPPORTED_PACKAGES = [ '@affine/android', '@affine/electron-renderer', '@affine/server', + '@affine/reader', ] as const; const rspackSupportedPackageSet = new Set(RSPACK_SUPPORTED_PACKAGES); @@ -22,14 +23,14 @@ export function assertRspackSupportedPackageName(name: string) { } throw new Error( - `AFFINE_BUNDLER=rspack currently supports: ${Array.from(RSPACK_SUPPORTED_PACKAGES).join(', ')}. Use AFFINE_BUNDLER=webpack for ${name}.` + `Rspack bundling currently supports: ${Array.from(RSPACK_SUPPORTED_PACKAGES).join(', ')}. Unsupported package: ${name}.` ); } const IN_CI = !!process.env.CI; const httpProxyMiddlewareLogLevel = IN_CI ? 'silent' : 'error'; -export const DEFAULT_DEV_SERVER_CONFIG: WebpackDevServerConfiguration = { +export const DEFAULT_DEV_SERVER_CONFIG: RspackDevServerConfiguration = { host: '0.0.0.0', allowedHosts: 'all', hot: false, diff --git a/tools/cli/src/bundle.ts b/tools/cli/src/bundle.ts index 43a0756434..e1d7e56916 100644 --- a/tools/cli/src/bundle.ts +++ b/tools/cli/src/bundle.ts @@ -9,32 +9,21 @@ import { RspackDevServer, } from '@rspack/dev-server'; import { merge } from 'lodash-es'; -import webpack from 'webpack'; -import WebpackDevServer, { - type Configuration as WebpackDevServerConfiguration, -} from 'webpack-dev-server'; import { assertRspackSupportedPackageName, DEFAULT_DEV_SERVER_CONFIG, - isRspackSupportedPackageName, } from './bundle-shared'; -import { type Bundler, getBundler } from './bundler'; import { Option, PackageCommand } from './command'; import { createHTMLTargetConfig as createRspackHTMLTargetConfig, createNodeTargetConfig as createRspackNodeTargetConfig, createWorkerTargetConfig as createRspackWorkerTargetConfig, } from './rspack'; -import { - createHTMLTargetConfig as createWebpackHTMLTargetConfig, - createNodeTargetConfig as createWebpackNodeTargetConfig, - createWorkerTargetConfig as createWebpackWorkerTargetConfig, -} from './webpack'; import { shouldUploadReleaseAssets, uploadDistAssetsToS3, -} from './webpack/s3-plugin.js'; +} from './rspack-shared/s3-plugin.js'; type WorkerConfig = { name: string }; type CreateWorkerTargetConfig = (pkg: Package, entry: string) => WorkerConfig; @@ -84,78 +73,6 @@ function getBaseWorkerConfigs( ]; } -function getWebpackBundleConfigs(pkg: Package): webpack.MultiConfiguration { - switch (pkg.name) { - case '@affine/admin': { - return [ - createWebpackHTMLTargetConfig( - pkg, - pkg.srcPath.join('index.tsx').value, - { selfhostPublicPath: '/admin/' } - ), - ] as webpack.MultiConfiguration; - } - case '@affine/web': - case '@affine/mobile': - case '@affine/ios': - case '@affine/android': { - const workerConfigs = getBaseWorkerConfigs( - pkg, - createWebpackWorkerTargetConfig - ); - workerConfigs.push( - createWebpackWorkerTargetConfig( - pkg, - pkg.srcPath.join('nbstore.worker.ts').value - ) - ); - - return [ - createWebpackHTMLTargetConfig( - pkg, - pkg.srcPath.join('index.tsx').value, - {}, - workerConfigs.map(config => config.name) - ), - ...workerConfigs, - ] as webpack.MultiConfiguration; - } - case '@affine/electron-renderer': { - const workerConfigs = getBaseWorkerConfigs( - pkg, - createWebpackWorkerTargetConfig - ); - - return [ - createWebpackHTMLTargetConfig( - pkg, - { - index: pkg.srcPath.join('app/index.tsx').value, - shell: pkg.srcPath.join('shell/index.tsx').value, - popup: pkg.srcPath.join('popup/index.tsx').value, - backgroundWorker: pkg.srcPath.join('background-worker/index.ts') - .value, - }, - { - additionalEntryForSelfhost: false, - injectGlobalErrorHandler: false, - emitAssetsManifest: false, - }, - workerConfigs.map(config => config.name) - ), - ...workerConfigs, - ] as webpack.MultiConfiguration; - } - case '@affine/server': { - return [ - createWebpackNodeTargetConfig(pkg, pkg.srcPath.join('index.ts').value), - ] as webpack.MultiConfiguration; - } - } - - throw new Error(`Unsupported package: ${pkg.name}`); -} - function getRspackBundleConfigs(pkg: Package): MultiRspackOptions { assertRspackSupportedPackage(pkg); @@ -223,13 +140,24 @@ function getRspackBundleConfigs(pkg: Package): MultiRspackOptions { createRspackNodeTargetConfig(pkg, pkg.srcPath.join('index.ts').value), ] as MultiRspackOptions; } + case '@affine/reader': { + return [ + createRspackNodeTargetConfig(pkg, pkg.srcPath.join('index.ts').value, { + outputFilename: 'index.js', + decoratorVersion: '2022-03', + libraryType: 'module', + bundleAllDependencies: true, + forceExternal: ['yjs'], + }), + ] as MultiRspackOptions; + } } throw new Error(`Unsupported package: ${pkg.name}`); } export class BundleCommand extends PackageCommand { - static override paths = [['bundle'], ['webpack'], ['pack'], ['bun']]; + static override paths = [['bundle'], ['pack'], ['bun']]; // bundle is not able to run with deps override _deps = false; @@ -241,123 +169,23 @@ export class BundleCommand extends PackageCommand { async execute() { const pkg = this.workspace.getPackage(this.package); - const bundler = getBundler(); if (this.dev) { - await BundleCommand.dev(pkg, bundler); + await BundleCommand.dev(pkg); } else { - await BundleCommand.build(pkg, bundler); + await BundleCommand.build(pkg); } } - static async build(pkg: Package, bundler: Bundler = getBundler()) { - if (bundler === 'rspack' && !isRspackSupportedPackageName(pkg.name)) { - return BundleCommand.buildWithWebpack(pkg); - } - - switch (bundler) { - case 'webpack': - return BundleCommand.buildWithWebpack(pkg); - case 'rspack': - return BundleCommand.buildWithRspack(pkg); - } - } - - static async buildWithWebpack(pkg: Package) { - process.env.NODE_ENV = 'production'; - const logger = new Logger('bundle'); - logger.info(`Packing package ${pkg.name} with webpack...`); - logger.info('Cleaning old output...'); - rmSync(pkg.distPath.value, { recursive: true, force: true }); - - const config = getWebpackBundleConfigs(pkg); - config.parallelism = cpus().length; - - const compiler = webpack(config); - if (!compiler) { - throw new Error('Failed to create webpack compiler'); - } - - try { - const stats = await new Promise( - (resolve, reject) => { - compiler.run((error, stats) => { - if (error) { - reject(error); - return; - } - if (!stats) { - reject(new Error('Failed to get webpack stats')); - return; - } - resolve(stats); - }); - } - ); - if (stats.hasErrors()) { - console.error(stats.toString('errors-only')); - process.exit(1); - return; - } - console.log(stats.toString('minimal')); - await uploadAssetsForPackage(pkg, logger); - } catch (error) { - console.error(error); - process.exit(1); - return; - } + static async build(pkg: Package) { + return BundleCommand.buildWithRspack(pkg); } static async dev( pkg: Package, - bundler: Bundler = getBundler(), - devServerConfig?: - | WebpackDevServerConfiguration - | RspackDevServerConfiguration + devServerConfig?: RspackDevServerConfiguration ) { - if (bundler === 'rspack' && !isRspackSupportedPackageName(pkg.name)) { - return BundleCommand.devWithWebpack( - pkg, - devServerConfig as WebpackDevServerConfiguration | undefined - ); - } - - switch (bundler) { - case 'webpack': - return BundleCommand.devWithWebpack( - pkg, - devServerConfig as WebpackDevServerConfiguration | undefined - ); - case 'rspack': - return BundleCommand.devWithRspack( - pkg, - devServerConfig as RspackDevServerConfiguration | undefined - ); - } - } - - static async devWithWebpack( - pkg: Package, - devServerConfig?: WebpackDevServerConfiguration - ) { - process.env.NODE_ENV = 'development'; - const logger = new Logger('bundle'); - logger.info(`Starting webpack dev server for ${pkg.name}...`); - - const config = getWebpackBundleConfigs(pkg); - config.parallelism = cpus().length; - - const compiler = webpack(config); - if (!compiler) { - throw new Error('Failed to create webpack compiler'); - } - - const devServer = new WebpackDevServer( - merge({}, DEFAULT_DEV_SERVER_CONFIG, devServerConfig), - compiler - ); - - await devServer.start(); + return BundleCommand.devWithRspack(pkg, devServerConfig); } static async buildWithRspack(pkg: Package) { diff --git a/tools/cli/src/bundler.ts b/tools/cli/src/bundler.ts deleted file mode 100644 index 49e6735278..0000000000 --- a/tools/cli/src/bundler.ts +++ /dev/null @@ -1,27 +0,0 @@ -export const SUPPORTED_BUNDLERS = ['webpack', 'rspack'] as const; - -export type Bundler = (typeof SUPPORTED_BUNDLERS)[number]; - -export const DEFAULT_BUNDLER: Bundler = 'rspack'; - -function isBundler(value: string): value is Bundler { - return SUPPORTED_BUNDLERS.includes(value as Bundler); -} - -export function normalizeBundler(input: string | undefined | null): Bundler { - const value = input?.trim().toLowerCase(); - if (!value) { - return DEFAULT_BUNDLER; - } - if (isBundler(value)) { - return value; - } - - throw new Error( - `Unsupported AFFINE_BUNDLER: "${input}". Expected one of: ${SUPPORTED_BUNDLERS.join(', ')}.` - ); -} - -export function getBundler(env: NodeJS.ProcessEnv = process.env): Bundler { - return normalizeBundler(env.AFFINE_BUNDLER); -} diff --git a/tools/cli/src/webpack/cache-group.ts b/tools/cli/src/rspack-shared/cache-group.ts similarity index 100% rename from tools/cli/src/webpack/cache-group.ts rename to tools/cli/src/rspack-shared/cache-group.ts diff --git a/tools/cli/src/webpack/error-handler.js b/tools/cli/src/rspack-shared/error-handler.js similarity index 91% rename from tools/cli/src/webpack/error-handler.js rename to tools/cli/src/rspack-shared/error-handler.js index 533d3fe202..989dda9d16 100644 --- a/tools/cli/src/webpack/error-handler.js +++ b/tools/cli/src/rspack-shared/error-handler.js @@ -1,5 +1,5 @@ (function () { - var errorEl = null; + let errorEl = null; function showGlobalErrorPage() { if (errorEl) { return; @@ -37,7 +37,7 @@ * @param event {PromiseRejectionEvent|ErrorEvent} */ function handler(event) { - var error; + let error; if ('error' in event) { error = @@ -51,7 +51,7 @@ console.error('unhandled unrecoverable error', error); - var shouldCache = + const shouldCache = // syntax error error && error instanceof SyntaxError; @@ -79,9 +79,9 @@ function unregisterRegisterGlobalErrorHandler(fn) { if (typeof fn === 'function') { - var app = document.getElementById('app'); + const app = document.getElementById('app'); if (app) { - var ob = new MutationObserver(function () { + let ob = new MutationObserver(function () { fn(); ob.disconnect(); ob = null; @@ -93,7 +93,7 @@ } function ensureBasicEnvironment() { - var globals = [ + const globals = [ 'Promise', 'Map', 'fetch', @@ -102,7 +102,7 @@ ]; // eslint-disable-next-line @typescript-eslint/prefer-for-of - for (var i = 0; i < globals.length; i++) { + for (let i = 0; i < globals.length; i++) { if (!(globals[i] in globalThis)) { showGlobalErrorPage(); return; @@ -111,6 +111,6 @@ } ensureBasicEnvironment(); - var goodtogo = registerGlobalErrorHandler(); + const goodtogo = registerGlobalErrorHandler(); unregisterRegisterGlobalErrorHandler(goodtogo); })(); diff --git a/tools/cli/src/webpack/html-plugin.ts b/tools/cli/src/rspack-shared/html-plugin.ts similarity index 98% rename from tools/cli/src/webpack/html-plugin.ts rename to tools/cli/src/rspack-shared/html-plugin.ts index e6286122d4..44c7e80a37 100644 --- a/tools/cli/src/webpack/html-plugin.ts +++ b/tools/cli/src/rspack-shared/html-plugin.ts @@ -5,7 +5,10 @@ import { Path, ProjectRoot } from '@affine-tools/utils/path'; import { Repository } from '@napi-rs/simple-git'; import HTMLPlugin from 'html-webpack-plugin'; import { once } from 'lodash-es'; -import type { WebpackPluginInstance } from 'webpack'; + +type PluginLike = { + apply: (compiler: CompilerLike) => void; +}; type CompilerLike = { webpack?: { @@ -204,12 +207,12 @@ const CorsPlugin = { export function createHTMLPlugins( BUILD_CONFIG: BUILD_CONFIG_TYPE, config: CreateHTMLPluginConfig -): WebpackPluginInstance[] { +): (HTMLPlugin | PluginLike)[] { const publicPath = getPublicPath(BUILD_CONFIG); const htmlPluginOptions = getHTMLPluginOptions(BUILD_CONFIG); const selfhostPublicPath = config.selfhostPublicPath ?? '/'; - const plugins: WebpackPluginInstance[] = []; + const plugins: (HTMLPlugin | PluginLike)[] = []; plugins.push( new HTMLPlugin({ ...htmlPluginOptions, diff --git a/tools/cli/src/webpack/node-loader.js b/tools/cli/src/rspack-shared/node-loader.js similarity index 100% rename from tools/cli/src/webpack/node-loader.js rename to tools/cli/src/rspack-shared/node-loader.js diff --git a/tools/cli/src/webpack/s3-plugin.ts b/tools/cli/src/rspack-shared/s3-plugin.ts similarity index 100% rename from tools/cli/src/webpack/s3-plugin.ts rename to tools/cli/src/rspack-shared/s3-plugin.ts diff --git a/tools/cli/src/webpack/template.html b/tools/cli/src/rspack-shared/template.html similarity index 100% rename from tools/cli/src/webpack/template.html rename to tools/cli/src/rspack-shared/template.html diff --git a/tools/cli/src/rspack/index.ts b/tools/cli/src/rspack/index.ts index 62af85842e..1026994164 100644 --- a/tools/cli/src/rspack/index.ts +++ b/tools/cli/src/rspack/index.ts @@ -7,21 +7,51 @@ import { Package } from '@affine-tools/utils/workspace'; import rspack, { type Configuration as RspackConfiguration, } from '@rspack/core'; -import { sentryWebpackPlugin } from '@sentry/webpack-plugin'; +import type { sentryWebpackPlugin as SentryWebpackPluginFactory } from '@sentry/webpack-plugin'; import { VanillaExtractPlugin } from '@vanilla-extract/webpack-plugin'; import cssnano from 'cssnano'; import { compact, merge } from 'lodash-es'; import { queuedashScopePostcssPlugin } from '../postcss/queuedash-scope.js'; -import { productionCacheGroups } from '../webpack/cache-group.js'; +import { productionCacheGroups } from '../rspack-shared/cache-group.js'; import { type CreateHTMLPluginConfig, - createHTMLPlugins as createWebpackCompatibleHTMLPlugins, -} from '../webpack/html-plugin.js'; + createHTMLPlugins, +} from '../rspack-shared/html-plugin.js'; const require = createRequire(import.meta.url); const IN_CI = !!process.env.CI; +const hasSentryBuildEnvs = () => + !!( + process.env.SENTRY_AUTH_TOKEN && + process.env.SENTRY_ORG && + process.env.SENTRY_PROJECT + ); + +function createSentryPlugin() { + if (!hasSentryBuildEnvs()) { + return null; + } + + try { + const { sentryWebpackPlugin } = require('@sentry/webpack-plugin') as { + sentryWebpackPlugin: typeof SentryWebpackPluginFactory; + }; + + return sentryWebpackPlugin({ + org: process.env.SENTRY_ORG!, + project: process.env.SENTRY_PROJECT!, + authToken: process.env.SENTRY_AUTH_TOKEN!, + }); + } catch (error) { + const reason = + error instanceof Error ? error.message : 'unknown load error'; + throw new Error( + `Failed to load @sentry/webpack-plugin while SENTRY_* envs are set: ${reason}` + ); + } +} const availableChannels = ['canary', 'beta', 'stable', 'internal']; function getBuildConfigFromEnv(pkg: Package) { @@ -73,7 +103,7 @@ export function createHTMLTargetConfig( console.log(`Config: ${JSON.stringify(buildConfig, null, 2)}`); const config: RspackConfiguration = { - //#region basic webpack config + //#region basic bundler config name: entry['index'], dependencies: deps, context: ProjectRoot.value, @@ -253,7 +283,7 @@ export function createHTMLTargetConfig( //#region plugins plugins: compact([ !IN_CI && new rspack.ProgressPlugin(), - ...createWebpackCompatibleHTMLPlugins(buildConfig, htmlConfig), + ...createHTMLPlugins(buildConfig, htmlConfig), new rspack.DefinePlugin({ 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV), ...Object.entries(buildConfig).reduce( @@ -280,14 +310,7 @@ export function createHTMLTargetConfig( }, ], }), - process.env.SENTRY_AUTH_TOKEN && - process.env.SENTRY_ORG && - process.env.SENTRY_PROJECT && - sentryWebpackPlugin({ - org: process.env.SENTRY_ORG, - project: process.env.SENTRY_PROJECT, - authToken: process.env.SENTRY_AUTH_TOKEN, - }), + createSentryPlugin(), // sourcemap url like # sourceMappingURL=76-6370cd185962bc89.js.map wont load in electron // this is because the default file:// protocol will be ignored by Chromium // so we need to replace the sourceMappingURL to assets:// protocol @@ -470,14 +493,7 @@ export function createWorkerTargetConfig( ) ), new rspack.optimize.LimitChunkCountPlugin({ maxChunks: 1 }), - process.env.SENTRY_AUTH_TOKEN && - process.env.SENTRY_ORG && - process.env.SENTRY_PROJECT && - sentryWebpackPlugin({ - org: process.env.SENTRY_ORG, - project: process.env.SENTRY_PROJECT, - authToken: process.env.SENTRY_AUTH_TOKEN, - }), + createSentryPlugin(), ]), stats: { errorDetails: true }, optimization: { @@ -506,9 +522,18 @@ export function createWorkerTargetConfig( export function createNodeTargetConfig( pkg: Package, - entry: string + entry: string, + options: { + outputFilename?: string; + decoratorVersion?: 'legacy' | '2022-03'; + libraryType?: 'module' | 'commonjs2'; + bundleAllDependencies?: boolean; + forceExternal?: string[]; + } = {} ): Omit & { name: string } { const dev = process.env.NODE_ENV === 'development'; + const useLegacyDecorator = options.decoratorVersion !== '2022-03'; + const forceExternal = options.forceExternal ?? []; return { name: entry, context: ProjectRoot.value, @@ -519,17 +544,28 @@ export function createNodeTargetConfig( }, entry: { index: entry }, output: { - filename: `main.js`, + filename: options.outputFilename ?? 'main.js', path: pkg.distPath.value, clean: true, globalObject: 'globalThis', + ...(options.libraryType + ? { library: { type: options.libraryType } } + : {}), }, target: ['node', 'es2022'], externals: ((data: any, callback: (err: null, value: boolean) => void) => { if ( + data.request && + forceExternal.some( + dep => data.request === dep || data.request.startsWith(`${dep}/`) + ) + ) { + callback(null, true); + } else if ( data.request && // import ... from 'module' /^[a-zA-Z@]/.test(data.request) && + !options.bundleAllDependencies && // not workspace deps !pkg.deps.some(dep => data.request!.startsWith(dep.name)) ) { @@ -561,8 +597,9 @@ export function createNodeTargetConfig( }, { test: /\.node$/, - loader: Path.dir(import.meta.url).join('../webpack/node-loader.js') - .value, + loader: Path.dir(import.meta.url).join( + '../rspack-shared/node-loader.js' + ).value, }, { test: /\.tsx?$/, @@ -582,8 +619,15 @@ export function createNodeTargetConfig( target: 'es2022', externalHelpers: false, transform: { - legacyDecorator: true, - decoratorMetadata: true, + ...(useLegacyDecorator + ? { + legacyDecorator: true, + decoratorMetadata: true, + } + : { + useDefineForClassFields: false, + decoratorVersion: '2022-03', + }), react: { runtime: 'automatic' }, }, }, diff --git a/tools/cli/src/run.ts b/tools/cli/src/run.ts index 731b97cc74..be6acf4975 100644 --- a/tools/cli/src/run.ts +++ b/tools/cli/src/run.ts @@ -42,7 +42,7 @@ export class RunCommand extends PackageCommand { \`affine init\` Generate the required files if there are any package added or removed - \`affine clean\` Clean the output files of ts, cargo, webpack, etc. + \`affine clean\` Clean the output files of ts, cargo, bundler outputs, etc. \`affine bundle\` Bundle the packages diff --git a/tools/cli/src/webpack/index.ts b/tools/cli/src/webpack/index.ts deleted file mode 100644 index c3473b94d5..0000000000 --- a/tools/cli/src/webpack/index.ts +++ /dev/null @@ -1,639 +0,0 @@ -import { createRequire } from 'node:module'; -import path from 'node:path'; - -import { getBuildConfig } from '@affine-tools/utils/build-config'; -import { Path, ProjectRoot } from '@affine-tools/utils/path'; -import { Package } from '@affine-tools/utils/workspace'; -import { PerfseePlugin } from '@perfsee/webpack'; -import { sentryWebpackPlugin } from '@sentry/webpack-plugin'; -import { VanillaExtractPlugin } from '@vanilla-extract/webpack-plugin'; -import CopyPlugin from 'copy-webpack-plugin'; -import { compact, merge } from 'lodash-es'; -import MiniCssExtractPlugin from 'mini-css-extract-plugin'; -import TerserPlugin from 'terser-webpack-plugin'; -import webpack from 'webpack'; - -import { queuedashScopePostcssPlugin } from '../postcss/queuedash-scope.js'; -import { productionCacheGroups } from './cache-group.js'; -import { - type CreateHTMLPluginConfig, - createHTMLPlugins, -} from './html-plugin.js'; - -const require = createRequire(import.meta.url); -const cssnano = require('cssnano'); - -const IN_CI = !!process.env.CI; - -const availableChannels = ['canary', 'beta', 'stable', 'internal']; -function getBuildConfigFromEnv(pkg: Package) { - const channel = process.env.BUILD_TYPE ?? 'canary'; - const dev = process.env.NODE_ENV === 'development'; - if (!availableChannels.includes(channel)) { - throw new Error( - `BUILD_TYPE must be one of ${availableChannels.join(', ')}, received [${channel}]` - ); - } - - return getBuildConfig(pkg, { - // @ts-expect-error checked - channel, - mode: dev ? 'development' : 'production', - }); -} - -export function createHTMLTargetConfig( - pkg: Package, - entry: string | Record, - htmlConfig: Partial = {}, - deps?: string[] -): webpack.Configuration { - entry = typeof entry === 'string' ? { index: entry } : entry; - - htmlConfig = merge( - {}, - { - filename: 'index.html', - additionalEntryForSelfhost: true, - injectGlobalErrorHandler: true, - emitAssetsManifest: true, - }, - htmlConfig - ); - - const buildConfig = getBuildConfigFromEnv(pkg); - - console.log( - `Building [${pkg.name}] for [${buildConfig.appBuildType}] channel in [${buildConfig.debug ? 'development' : 'production'}] mode.` - ); - console.log( - `Entry points: ${Object.entries(entry) - .map(([name, path]) => `${name}: ${path}`) - .join(', ')}` - ); - console.log(`Output path: ${pkg.distPath.value}`); - console.log(`Config: ${JSON.stringify(buildConfig, null, 2)}`); - - const config: webpack.Configuration = { - //#region basic webpack config - name: entry['index'], - dependencies: deps, - context: ProjectRoot.value, - experiments: { - topLevelAwait: true, - outputModule: false, - syncWebAssembly: true, - }, - entry, - output: { - environment: { module: true, dynamicImport: true }, - filename: buildConfig.debug - ? 'js/[name].js' - : 'js/[name].[contenthash:8].js', - assetModuleFilename: buildConfig.debug - ? '[name].[contenthash:8][ext]' - : 'assets/[name].[contenthash:8][ext][query]', - path: pkg.distPath.value, - clean: false, - globalObject: 'globalThis', - // NOTE(@forehalo): always keep it '/' - publicPath: '/', - }, - target: ['web', 'es2022'], - mode: buildConfig.debug ? 'development' : 'production', - devtool: buildConfig.debug ? 'cheap-module-source-map' : 'source-map', - resolve: { - symlinks: true, - extensionAlias: { - '.js': ['.js', '.tsx', '.ts'], - '.mjs': ['.mjs', '.mts'], - }, - extensions: ['.js', '.ts', '.tsx'], - alias: { - yjs: ProjectRoot.join('node_modules', 'yjs').value, - lit: ProjectRoot.join('node_modules', 'lit').value, - '@preact/signals-core': ProjectRoot.join( - 'node_modules', - '@preact', - 'signals-core' - ).value, - }, - }, - //#endregion - - //#region module config - module: { - parser: { - javascript: { - // Do not mock Node.js globals - node: false, - requireJs: false, - import: true, - // Treat as missing export as error - strictExportPresence: true, - }, - }, - //#region rules - rules: [ - { test: /\.m?js?$/, resolve: { fullySpecified: false } }, - { - test: /\.js$/, - enforce: 'pre', - include: /@blocksuite/, - use: ['source-map-loader'], - }, - { - oneOf: [ - { - test: /\.ts$/, - exclude: /node_modules/, - loader: 'swc-loader', - options: { - // https://swc.rs/docs/configuring-swc/ - jsc: { - preserveAllComments: true, - parser: { - syntax: 'typescript', - dynamicImport: true, - topLevelAwait: false, - tsx: false, - decorators: true, - }, - target: 'es2022', - externalHelpers: false, - transform: { - useDefineForClassFields: false, - decoratorVersion: '2022-03', - }, - }, - sourceMaps: true, - inlineSourcesContent: true, - }, - }, - { - test: /\.tsx$/, - exclude: /node_modules/, - loader: 'swc-loader', - options: { - // https://swc.rs/docs/configuring-swc/ - jsc: { - preserveAllComments: true, - parser: { - syntax: 'typescript', - dynamicImport: true, - topLevelAwait: false, - tsx: true, - decorators: true, - }, - target: 'es2022', - externalHelpers: false, - transform: { - react: { runtime: 'automatic' }, - useDefineForClassFields: false, - decoratorVersion: '2022-03', - }, - }, - sourceMaps: true, - inlineSourcesContent: true, - }, - }, - { - test: /\.(png|jpg|gif|svg|webp|mp4|zip)$/, - type: 'asset/resource', - }, - { test: /\.(ttf|eot|woff|woff2)$/, type: 'asset/resource' }, - { test: /\.txt$/, type: 'asset/source' }, - { test: /\.inline\.svg$/, type: 'asset/inline' }, - { - test: /\.css$/, - use: [ - buildConfig.debug - ? 'style-loader' - : MiniCssExtractPlugin.loader, - { - loader: 'css-loader', - options: { - url: true, - sourceMap: false, - modules: false, - import: true, - importLoaders: 1, - }, - }, - { - loader: 'postcss-loader', - options: { - postcssOptions: { - plugins: pkg.join('tailwind.config.js').exists() - ? [ - [ - '@tailwindcss/postcss', - require(pkg.join('tailwind.config.js').value), - ], - ['autoprefixer'], - ...(buildConfig.isAdmin - ? [queuedashScopePostcssPlugin()] - : []), - ] - : [ - cssnano({ - preset: ['default', { convertValues: false }], - }), - ], - }, - }, - }, - ], - }, - ], - }, - ], - //#endregion - }, - //#endregion - - //#region plugins - plugins: compact([ - !IN_CI && new webpack.ProgressPlugin({ percentBy: 'entries' }), - ...createHTMLPlugins(buildConfig, htmlConfig), - new webpack.DefinePlugin({ - 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV), - ...Object.entries(buildConfig).reduce( - (def, [k, v]) => { - def[`BUILD_CONFIG.${k}`] = JSON.stringify(v); - return def; - }, - {} as Record - ), - }), - !buildConfig.debug && - // todo: support multiple entry points - new MiniCssExtractPlugin({ - filename: `[name].[contenthash:8].css`, - ignoreOrder: true, - }), - new VanillaExtractPlugin(), - !buildConfig.isAdmin && - new CopyPlugin({ - patterns: [ - { - // copy the shared public assets into dist - from: new Package('@affine/core').join('public').value, - }, - ], - }), - !buildConfig.debug && - process.env.PERFSEE_TOKEN && - new PerfseePlugin({ project: 'affine-toeverything' }), - process.env.SENTRY_AUTH_TOKEN && - process.env.SENTRY_ORG && - process.env.SENTRY_PROJECT && - sentryWebpackPlugin({ - org: process.env.SENTRY_ORG, - project: process.env.SENTRY_PROJECT, - authToken: process.env.SENTRY_AUTH_TOKEN, - }), - // sourcemap url like # sourceMappingURL=76-6370cd185962bc89.js.map wont load in electron - // this is because the default file:// protocol will be ignored by Chromium - // so we need to replace the sourceMappingURL to assets:// protocol - // for example: - // replace # sourceMappingURL=76-6370cd185962bc89.js.map - // to # sourceMappingURL=assets://./{dir}/76-6370cd185962bc89.js.map - buildConfig.isElectron && - new webpack.SourceMapDevToolPlugin({ - append: pathData => { - return `\n//# sourceMappingURL=assets://./${pathData.filename}.map`; - }, - filename: '[file].map', - }), - ]), - //#endregion - - stats: { errorDetails: true }, - - //#region optimization - optimization: { - minimize: !buildConfig.debug, - minimizer: [ - new TerserPlugin({ - minify: TerserPlugin.swcMinify, - parallel: true, - extractComments: true, - terserOptions: { - ecma: 2020, - compress: { unused: true }, - mangle: { keep_classnames: true }, - }, - }), - ], - removeEmptyChunks: true, - providedExports: true, - usedExports: true, - sideEffects: true, - removeAvailableModules: true, - runtimeChunk: { name: 'runtime' }, - splitChunks: { - chunks: 'all', - minSize: 1, - minChunks: 1, - maxInitialRequests: Number.MAX_SAFE_INTEGER, - maxAsyncRequests: Number.MAX_SAFE_INTEGER, - cacheGroups: productionCacheGroups, - }, - }, - //#endregion - }; - - if (buildConfig.debug && !IN_CI) { - config.optimization = { - ...config.optimization, - minimize: false, - runtimeChunk: false, - splitChunks: { - maxInitialRequests: Infinity, - chunks: 'all', - cacheGroups: { - defaultVendors: { - test: `[\\/]node_modules[\\/](?!.*vanilla-extract)`, - priority: -10, - reuseExistingChunk: true, - }, - default: { minChunks: 2, priority: -20, reuseExistingChunk: true }, - styles: { - name: 'styles', - type: 'css/mini-extract', - chunks: 'all', - enforce: true, - }, - }, - }, - }; - } - - return config; -} - -export function createWorkerTargetConfig( - pkg: Package, - entry: string -): Omit & { name: string } { - const workerName = path.basename(entry).replace(/\.worker\.ts$/, ''); - const buildConfig = getBuildConfigFromEnv(pkg); - - return { - name: entry, - context: ProjectRoot.value, - experiments: { - topLevelAwait: true, - outputModule: false, - syncWebAssembly: true, - }, - entry: { [workerName]: entry }, - output: { - filename: `js/${workerName}-${buildConfig.appVersion}.worker.js`, - path: pkg.distPath.value, - clean: false, - globalObject: 'globalThis', - // NOTE(@forehalo): always keep it '/' - publicPath: '/', - }, - target: ['webworker', 'es2022'], - mode: buildConfig.debug ? 'development' : 'production', - devtool: buildConfig.debug ? 'cheap-module-source-map' : 'source-map', - resolve: { - symlinks: true, - extensionAlias: { '.js': ['.js', '.ts'], '.mjs': ['.mjs', '.mts'] }, - extensions: ['.js', '.ts'], - alias: { yjs: ProjectRoot.join('node_modules', 'yjs').value }, - }, - - module: { - parser: { - javascript: { - // Do not mock Node.js globals - node: false, - requireJs: false, - import: true, - // Treat as missing export as error - strictExportPresence: true, - }, - }, - rules: [ - { test: /\.m?js?$/, resolve: { fullySpecified: false } }, - { - test: /\.js$/, - enforce: 'pre', - include: /@blocksuite/, - use: ['source-map-loader'], - }, - { - oneOf: [ - { - test: /\.ts$/, - exclude: /node_modules/, - loader: 'swc-loader', - options: { - // https://swc.rs/docs/configuring-swc/ - jsc: { - preserveAllComments: true, - parser: { - syntax: 'typescript', - dynamicImport: true, - topLevelAwait: false, - tsx: false, - decorators: true, - }, - target: 'es2022', - externalHelpers: false, - transform: { - useDefineForClassFields: false, - decoratorVersion: '2022-03', - }, - }, - sourceMaps: true, - inlineSourcesContent: true, - }, - }, - ], - }, - ], - }, - plugins: compact([ - new webpack.DefinePlugin( - Object.entries(buildConfig).reduce( - (def, [k, v]) => { - def[`BUILD_CONFIG.${k}`] = JSON.stringify(v); - return def; - }, - {} as Record - ) - ), - new webpack.optimize.LimitChunkCountPlugin({ maxChunks: 1 }), - process.env.SENTRY_AUTH_TOKEN && - process.env.SENTRY_ORG && - process.env.SENTRY_PROJECT && - sentryWebpackPlugin({ - org: process.env.SENTRY_ORG, - project: process.env.SENTRY_PROJECT, - authToken: process.env.SENTRY_AUTH_TOKEN, - }), - ]), - stats: { errorDetails: true }, - optimization: { - minimize: !buildConfig.debug, - minimizer: [ - new TerserPlugin({ - minify: TerserPlugin.swcMinify, - parallel: true, - extractComments: true, - terserOptions: { - ecma: 2020, - compress: { unused: true }, - mangle: { keep_classnames: true }, - }, - }), - ], - removeEmptyChunks: true, - providedExports: true, - usedExports: true, - sideEffects: true, - removeAvailableModules: true, - runtimeChunk: false, - splitChunks: false, - }, - performance: { hints: false }, - }; -} - -export function createNodeTargetConfig( - pkg: Package, - entry: string -): Omit & { name: string } { - const dev = process.env.NODE_ENV === 'development'; - return { - name: entry, - context: ProjectRoot.value, - experiments: { - topLevelAwait: true, - outputModule: pkg.packageJson.type === 'module', - syncWebAssembly: true, - }, - entry: { index: entry }, - output: { - filename: `main.js`, - path: pkg.distPath.value, - clean: true, - globalObject: 'globalThis', - }, - target: ['node', 'es2022'], - externals: (data, callback) => { - if ( - data.request && - // import ... from 'module' - /^[a-zA-Z@]/.test(data.request) && - // not workspace deps - !pkg.deps.some(dep => data.request!.startsWith(dep.name)) - ) { - callback(null, true); - } else { - callback(null, false); - } - }, - externalsPresets: { node: true }, - node: { __dirname: false, __filename: false }, - mode: dev ? 'development' : 'production', - devtool: 'source-map', - resolve: { - symlinks: true, - extensionAlias: { '.js': ['.js', '.ts'], '.mjs': ['.mjs', '.mts'] }, - extensions: ['.js', '.ts', '.tsx', '.node'], - alias: { yjs: ProjectRoot.join('node_modules', 'yjs').value }, - }, - module: { - parser: { - javascript: { url: false, importMeta: false, createRequire: false }, - }, - rules: [ - { - test: /\.js$/, - enforce: 'pre', - include: /@blocksuite/, - use: ['source-map-loader'], - }, - { - test: /\.node$/, - loader: Path.dir(import.meta.url).join('node-loader.js').value, - }, - { - test: /\.tsx?$/, - exclude: /node_modules/, - loader: 'swc-loader', - options: { - // https://swc.rs/docs/configuring-swc/ - jsc: { - preserveAllComments: true, - parser: { - syntax: 'typescript', - dynamicImport: true, - topLevelAwait: true, - tsx: true, - decorators: true, - }, - target: 'es2022', - externalHelpers: false, - transform: { - legacyDecorator: true, - decoratorMetadata: true, - react: { runtime: 'automatic' }, - }, - }, - sourceMaps: true, - inlineSourcesContent: true, - }, - }, - ], - }, - plugins: compact([ - new webpack.optimize.LimitChunkCountPlugin({ maxChunks: 1 }), - new webpack.IgnorePlugin({ - checkResource(resource) { - const lazyImports = [ - '@nestjs/microservices', - '@nestjs/websockets/socket-module', - '@apollo/subgraph', - '@apollo/gateway', - '@as-integrations/fastify', - 'ts-morph', - 'class-validator', - 'class-transformer', - ]; - return lazyImports.some(lazyImport => - resource.startsWith(lazyImport) - ); - }, - }), - new webpack.DefinePlugin({ - 'process.env.NODE_ENV': '"production"', - }), - ]), - stats: { errorDetails: true }, - optimization: { - nodeEnv: false, - minimize: !dev, - minimizer: [ - new TerserPlugin({ - minify: TerserPlugin.swcMinify, - parallel: true, - extractComments: true, - terserOptions: { - ecma: 2020, - compress: { unused: true }, - mangle: { keep_classnames: true }, - }, - }), - ], - }, - performance: { hints: false }, - ignoreWarnings: [/^(?!CriticalDependenciesWarning$)/], - }; -} diff --git a/tools/cli/src/webpack/types.ts b/tools/cli/src/webpack/types.ts deleted file mode 100644 index 6e17eb43fe..0000000000 --- a/tools/cli/src/webpack/types.ts +++ /dev/null @@ -1,4 +0,0 @@ -export interface BuildFlags { - mode: 'development' | 'production'; - channel: 'stable' | 'beta' | 'canary' | 'internal'; -} diff --git a/tsconfig.web.json b/tsconfig.web.json index ddd83819ee..64645ff7d4 100644 --- a/tsconfig.web.json +++ b/tsconfig.web.json @@ -1,7 +1,7 @@ { "extends": "./tsconfig.json", "compilerOptions": { - "types": ["build-config", "affine__env", "webpack-env"], + "types": ["build-config", "affine__env"], "lib": ["ESNext", "DOM", "DOM.Iterable"], "jsx": "react-jsx", "composite": true diff --git a/yarn.lock b/yarn.lock index 7d8eb17994..300c2d8d3d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -67,7 +67,6 @@ __metadata: "@affine-tools/cli": "workspace:*" "@affine-tools/utils": "workspace:*" "@playwright/test": "npm:=1.58.2" - webpack: "npm:^5.102.1" languageName: unknown linkType: soft @@ -119,20 +118,17 @@ __metadata: "@affine-tools/utils": "workspace:*" "@affine/s3-compat": "workspace:*" "@napi-rs/simple-git": "npm:^0.1.22" - "@perfsee/webpack": "npm:^1.13.0" "@rspack/core": "npm:^1.7.6" "@rspack/dev-server": "npm:^1.1.3" - "@sentry/webpack-plugin": "npm:^4.0.0" + "@sentry/webpack-plugin": "npm:^5.1.1" "@swc/core": "npm:^1.10.1" "@tailwindcss/postcss": "npm:^4.0.0" "@types/lodash-es": "npm:^4.17.12" "@types/mime-types": "npm:^3.0.0" "@types/node": "npm:^22.0.0" - "@types/webpack-env": "npm:^1.18.5" "@vanilla-extract/webpack-plugin": "npm:^2.3.15" autoprefixer: "npm:^10.4.20" clipanion: "npm:^3.2.1" - copy-webpack-plugin: "npm:^13.0.0" css-loader: "npm:^7.1.2" cssnano: "npm:^7.0.6" html-webpack-plugin: "npm:^5.6.3" @@ -140,7 +136,6 @@ __metadata: jsonc-parser: "npm:^3.3.1" lodash-es: "npm:^4.17.23" mime-types: "npm:^3.0.0" - mini-css-extract-plugin: "npm:^2.9.2" node-loader: "npm:^2.1.0" postcss: "npm:^8.4.49" postcss-loader: "npm:^8.1.1" @@ -151,13 +146,9 @@ __metadata: style-loader: "npm:^4.0.0" swc-loader: "npm:^0.2.6" tailwindcss: "npm:^4.1.17" - terser-webpack-plugin: "npm:^5.3.10" tsx: "npm:^4.21.0" typanion: "npm:^3.14.0" typescript: "npm:^5.9.3" - webpack: "npm:^5.102.1" - webpack-dev-server: "npm:^5.2.0" - webpack-merge: "npm:^6.0.1" bin: affine: ./bin/cli.js r: ./bin/runner.js @@ -215,7 +206,7 @@ __metadata: "@radix-ui/react-toggle": "npm:^1.1.1" "@radix-ui/react-toggle-group": "npm:^1.1.1" "@radix-ui/react-tooltip": "npm:^1.1.5" - "@sentry/react": "npm:^9.47.1" + "@sentry/react": "npm:^10.40.0" "@tanstack/react-table": "npm:^8.20.5" "@testing-library/react": "npm:^16.3.2" "@toeverything/infra": "workspace:*" @@ -269,7 +260,7 @@ __metadata: "@capacitor/keyboard": "npm:^7.0.0" "@capacitor/status-bar": "npm:^7.0.0" "@capgo/inappbrowser": "npm:^8.0.0" - "@sentry/react": "npm:^9.47.1" + "@sentry/react": "npm:^10.40.0" "@toeverything/infra": "workspace:*" "@types/react": "npm:^19.0.1" "@types/react-dom": "npm:^19.0.2" @@ -436,7 +427,7 @@ __metadata: "@radix-ui/react-scroll-area": "npm:^1.2.2" "@radix-ui/react-slot": "npm:^1.1.1" "@radix-ui/react-toolbar": "npm:^1.1.1" - "@sentry/react": "npm:^9.47.1" + "@sentry/react": "npm:^10.40.0" "@testing-library/dom": "npm:^10.4.0" "@testing-library/react": "npm:^16.1.0" "@toeverything/infra": "workspace:*" @@ -557,7 +548,7 @@ __metadata: "@affine/track": "workspace:*" "@blocksuite/affine": "workspace:*" "@emotion/react": "npm:^11.14.0" - "@sentry/react": "npm:^9.47.1" + "@sentry/react": "npm:^10.40.0" "@toeverything/infra": "workspace:*" "@toeverything/theme": "npm:^1.1.23" "@types/react": "npm:^19.0.1" @@ -585,7 +576,6 @@ __metadata: "@affine/nbstore": "workspace:*" "@electron-forge/cli": "npm:^7.10.2" "@electron-forge/core": "npm:^7.10.2" - "@electron-forge/core-utils": "npm:^7.10.2" "@electron-forge/maker-deb": "npm:^7.10.2" "@electron-forge/maker-dmg": "npm:^7.10.2" "@electron-forge/maker-flatpak": "npm:^7.10.2" @@ -595,9 +585,9 @@ __metadata: "@electron-forge/plugin-fuses": "npm:^7.10.2" "@electron-forge/shared-types": "npm:^7.10.2" "@reforged/maker-appimage": "npm:^5.2.0" - "@sentry/electron": "npm:^7.0.0" - "@sentry/esbuild-plugin": "npm:^4.0.0" - "@sentry/react": "npm:^9.47.1" + "@sentry/electron": "npm:^7.9.0" + "@sentry/esbuild-plugin": "npm:^5.1.1" + "@sentry/react": "npm:^10.40.0" "@toeverything/infra": "workspace:*" "@types/set-cookie-parser": "npm:^2.4.10" "@types/uuid": "npm:^11.0.0" @@ -716,7 +706,7 @@ __metadata: "@capacitor/haptics": "npm:^7.0.0" "@capacitor/ios": "npm:^7.0.0" "@capacitor/keyboard": "npm:^7.0.0" - "@sentry/react": "npm:^9.47.1" + "@sentry/react": "npm:^10.40.0" "@toeverything/infra": "workspace:^" "@types/react": "npm:^19.0.1" "@types/react-dom": "npm:^19.0.2" @@ -787,7 +777,7 @@ __metadata: "@affine/track": "workspace:*" "@blocksuite/affine": "workspace:*" "@blocksuite/icons": "npm:^2.2.17" - "@sentry/react": "npm:^9.47.1" + "@sentry/react": "npm:^10.40.0" "@toeverything/infra": "workspace:*" "@types/react": "npm:^19.0.1" "@types/react-dom": "npm:^19.0.2" @@ -1108,7 +1098,7 @@ __metadata: resolution: "@affine/track@workspace:packages/frontend/track" dependencies: "@affine/debug": "workspace:*" - "@sentry/react": "npm:^9.47.1" + "@sentry/react": "npm:^10.40.0" "@types/react": "npm:^19.0.1" nanoid: "npm:^5.1.6" react-router-dom: "npm:^6.30.3" @@ -1127,7 +1117,7 @@ __metadata: "@affine/nbstore": "workspace:*" "@affine/track": "workspace:*" "@emotion/react": "npm:^11.14.0" - "@sentry/react": "npm:^9.47.1" + "@sentry/react": "npm:^10.40.0" "@toeverything/infra": "workspace:*" "@types/react": "npm:^19.0.1" "@types/react-dom": "npm:^19.0.2" @@ -1273,24 +1263,6 @@ __metadata: languageName: node linkType: hard -"@apm-js-collab/code-transformer@npm:^0.8.0": - version: 0.8.2 - resolution: "@apm-js-collab/code-transformer@npm:0.8.2" - checksum: 10/ff4b8fea9a27ef4e82a0a022bececfa9966e5e2a4ae1e6ca0b31f4a2bbc6d79f5bd1257f281ed8a90900d693e1a88a79c42982eabe7ca999b267d5d69c57393f - languageName: node - linkType: hard - -"@apm-js-collab/tracing-hooks@npm:^0.3.1": - version: 0.3.1 - resolution: "@apm-js-collab/tracing-hooks@npm:0.3.1" - dependencies: - "@apm-js-collab/code-transformer": "npm:^0.8.0" - debug: "npm:^4.4.1" - module-details-from-path: "npm:^1.0.4" - checksum: 10/0af2220168d4fc2700ec577632eac066f756c3aaa34ef2e833ea4725abb80f7486c1a585a93e8f0d8304c51192f63c53e7ddd70290abac489a734f9693359f7f - languageName: node - linkType: hard - "@apollo/cache-control-types@npm:^1.0.3": version: 1.0.3 resolution: "@apollo/cache-control-types@npm:1.0.3" @@ -4299,7 +4271,7 @@ __metadata: languageName: node linkType: hard -"@electron-forge/core-utils@npm:7.10.2, @electron-forge/core-utils@npm:^7.10.2": +"@electron-forge/core-utils@npm:7.10.2": version: 7.10.2 resolution: "@electron-forge/core-utils@npm:7.10.2" dependencies: @@ -5524,13 +5496,6 @@ __metadata: languageName: node linkType: hard -"@eyhn/msgpack-stream@npm:^2.8.4": - version: 2.8.4 - resolution: "@eyhn/msgpack-stream@npm:2.8.4" - checksum: 10/deefb2a8d3e94b8bfc576b7c4d0d6b3ee3c936a2c01e32db24905574b0a911647366d6a41c14d4526acdc93e828ab783ecb06e9e15d133d730ed33d675411bad - languageName: node - linkType: hard - "@faker-js/faker@npm:^10.1.0": version: 10.1.0 resolution: "@faker-js/faker@npm:10.1.0" @@ -5556,6 +5521,20 @@ __metadata: languageName: node linkType: hard +"@fastify/otel@npm:0.16.0": + version: 0.16.0 + resolution: "@fastify/otel@npm:0.16.0" + dependencies: + "@opentelemetry/core": "npm:^2.0.0" + "@opentelemetry/instrumentation": "npm:^0.208.0" + "@opentelemetry/semantic-conventions": "npm:^1.28.0" + minimatch: "npm:^10.0.3" + peerDependencies: + "@opentelemetry/api": ^1.9.0 + checksum: 10/b8a4e122859ce236910fa1a07e3937f4cd91fba088f84724fe7dc2dd4a0479e21c727063ae0e11f16f36a1d88183920fa500a939fd1b4c7f71bc7b0c3b06e044 + languageName: node + linkType: hard + "@fig/complete-commander@npm:^3.0.0": version: 3.2.0 resolution: "@fig/complete-commander@npm:3.2.0" @@ -7464,7 +7443,7 @@ __metadata: languageName: node linkType: hard -"@jridgewell/sourcemap-codec@npm:^1.4.14, @jridgewell/sourcemap-codec@npm:^1.4.15, @jridgewell/sourcemap-codec@npm:^1.5.0, @jridgewell/sourcemap-codec@npm:^1.5.5": +"@jridgewell/sourcemap-codec@npm:^1.4.14, @jridgewell/sourcemap-codec@npm:^1.5.0, @jridgewell/sourcemap-codec@npm:^1.5.5": version: 1.5.5 resolution: "@jridgewell/sourcemap-codec@npm:1.5.5" checksum: 10/5d9d207b462c11e322d71911e55e21a4e2772f71ffe8d6f1221b8eb5ae6774458c1d242f897fb0814e8714ca9a6b498abfa74dfe4f434493342902b1a48b33a5 @@ -7527,22 +7506,6 @@ __metadata: languageName: node linkType: hard -"@kwsites/file-exists@npm:^1.1.1": - version: 1.1.1 - resolution: "@kwsites/file-exists@npm:1.1.1" - dependencies: - debug: "npm:^4.1.1" - checksum: 10/4ff945de7293285133aeae759caddc71e73c4a44a12fac710fdd4f574cce2671a3f89d8165fdb03d383cfc97f3f96f677d8de3c95133da3d0e12a123a23109fe - languageName: node - linkType: hard - -"@kwsites/promise-deferred@npm:^1.1.1": - version: 1.1.1 - resolution: "@kwsites/promise-deferred@npm:1.1.1" - checksum: 10/07455477a0123d9a38afb503739eeff2c5424afa8d3dbdcc7f9502f13604488a4b1d9742fc7288832a52a6422cf1e1c0a1d51f69a39052f14d27c9a0420b6629 - languageName: node - linkType: hard - "@leichtgewicht/ip-codec@npm:^2.0.1": version: 2.0.5 resolution: "@leichtgewicht/ip-codec@npm:2.0.5" @@ -9856,6 +9819,15 @@ __metadata: languageName: node linkType: hard +"@opentelemetry/api-logs@npm:0.207.0": + version: 0.207.0 + resolution: "@opentelemetry/api-logs@npm:0.207.0" + dependencies: + "@opentelemetry/api": "npm:^1.3.0" + checksum: 10/d50251e34f1cb8208d02870d3c25a0ba31eb2e33844a1ed5c0107d920bfbb52dbc3a1c5072586501a5096778f90e9ef1ce2fef63fa6ab5908bc1f94099121264 + languageName: node + linkType: hard + "@opentelemetry/api-logs@npm:0.208.0": version: 0.208.0 resolution: "@opentelemetry/api-logs@npm:0.208.0" @@ -9893,7 +9865,7 @@ __metadata: languageName: node linkType: hard -"@opentelemetry/context-async-hooks@npm:2.5.0, @opentelemetry/context-async-hooks@npm:^2.2.0": +"@opentelemetry/context-async-hooks@npm:2.5.0": version: 2.5.0 resolution: "@opentelemetry/context-async-hooks@npm:2.5.0" peerDependencies: @@ -9902,18 +9874,16 @@ __metadata: languageName: node linkType: hard -"@opentelemetry/core@npm:2.2.0": - version: 2.2.0 - resolution: "@opentelemetry/core@npm:2.2.0" - dependencies: - "@opentelemetry/semantic-conventions": "npm:^1.29.0" +"@opentelemetry/context-async-hooks@npm:^2.5.1": + version: 2.5.1 + resolution: "@opentelemetry/context-async-hooks@npm:2.5.1" peerDependencies: "@opentelemetry/api": ">=1.0.0 <1.10.0" - checksum: 10/f25193ba8b1fadb7bd8ed0d86ac39dd0f3fd3eec47c2fb2745bd22442b2d5e3ca88e5cab6d97111349d3182bf8e4356f8b7c7213ebea8f7719de944ce13a19cb + checksum: 10/06e29a59ae114628a3d83337443c469407367eed375ed3e69fc3886840016b8805b3071ff4f1877db6d2d71dadb5dd6c34a0abc6561deb030c6033a89908b615 languageName: node linkType: hard -"@opentelemetry/core@npm:2.5.0, @opentelemetry/core@npm:^2.0.0, @opentelemetry/core@npm:^2.2.0": +"@opentelemetry/core@npm:2.5.0": version: 2.5.0 resolution: "@opentelemetry/core@npm:2.5.0" dependencies: @@ -9924,6 +9894,17 @@ __metadata: languageName: node linkType: hard +"@opentelemetry/core@npm:2.5.1, @opentelemetry/core@npm:^2.0.0, @opentelemetry/core@npm:^2.2.0, @opentelemetry/core@npm:^2.5.1": + version: 2.5.1 + resolution: "@opentelemetry/core@npm:2.5.1" + dependencies: + "@opentelemetry/semantic-conventions": "npm:^1.29.0" + peerDependencies: + "@opentelemetry/api": ">=1.0.0 <1.10.0" + checksum: 10/35c8493d07aebfc9c7b39e487a0e55232a18ee84b2c8cfdaef0f9a3432f8e98e691f4c34548e554c0c5d45363820f20244f6cd1a6bae2bb1aeadf2cacc48f532 + languageName: node + linkType: hard + "@opentelemetry/exporter-logs-otlp-grpc@npm:0.211.0": version: 0.211.0 resolution: "@opentelemetry/exporter-logs-otlp-grpc@npm:0.211.0" @@ -10106,91 +10087,81 @@ __metadata: languageName: node linkType: hard -"@opentelemetry/instrumentation-amqplib@npm:0.55.0": - version: 0.55.0 - resolution: "@opentelemetry/instrumentation-amqplib@npm:0.55.0" +"@opentelemetry/instrumentation-amqplib@npm:0.58.0": + version: 0.58.0 + resolution: "@opentelemetry/instrumentation-amqplib@npm:0.58.0" dependencies: "@opentelemetry/core": "npm:^2.0.0" - "@opentelemetry/instrumentation": "npm:^0.208.0" + "@opentelemetry/instrumentation": "npm:^0.211.0" + "@opentelemetry/semantic-conventions": "npm:^1.33.0" peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: 10/03e028c4dfe9a8a9372f6ef6d4c4520343a3ec571e2e04dcd29e684cf25d212f6331be268656006220b476f6b46748aba2d142b7b4c62efd24baebf6a3f1b77b + checksum: 10/de6d6cd239a30e2eeb5b997c8e7e3acc13db9f512fabf77576487489cdb830a454f0745d69d2a6ac79a90f24c1494512a81b81e6d0aa348aac9cab180469096e languageName: node linkType: hard -"@opentelemetry/instrumentation-connect@npm:0.52.0": - version: 0.52.0 - resolution: "@opentelemetry/instrumentation-connect@npm:0.52.0" +"@opentelemetry/instrumentation-connect@npm:0.54.0": + version: 0.54.0 + resolution: "@opentelemetry/instrumentation-connect@npm:0.54.0" dependencies: "@opentelemetry/core": "npm:^2.0.0" - "@opentelemetry/instrumentation": "npm:^0.208.0" + "@opentelemetry/instrumentation": "npm:^0.211.0" "@opentelemetry/semantic-conventions": "npm:^1.27.0" "@types/connect": "npm:3.4.38" peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: 10/c526768a10a4f6c76b791e382edeae2217a7b3c448b1a3458ef34ca46a645b6cf67eeec79bae119e2005f5d766c8eabc03b16058da6e94300110d029157e7e95 + checksum: 10/335e42610a88f9265ca350945575b5011a8a96ba0b20eb7cf3d43da9efb1ec308d39b538ac2c0243ddbb63749d1300dd8841fd4ad0d9abe9964c78929df28cd2 languageName: node linkType: hard -"@opentelemetry/instrumentation-dataloader@npm:0.26.0": - version: 0.26.0 - resolution: "@opentelemetry/instrumentation-dataloader@npm:0.26.0" +"@opentelemetry/instrumentation-dataloader@npm:0.28.0": + version: 0.28.0 + resolution: "@opentelemetry/instrumentation-dataloader@npm:0.28.0" dependencies: - "@opentelemetry/instrumentation": "npm:^0.208.0" + "@opentelemetry/instrumentation": "npm:^0.211.0" peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: 10/e3efde5515698fc25437d4e347cc829da1f82df95c0523149913030b53e4a359577ee988b66d5b0a3bd8230697cd785e983176c0b4bb14d001c64c8948d46c10 + checksum: 10/e2c30ee9d4c52146832c05228db8d68027889b1bfce1dd081c46f129d60bce166c138620d75eedbd8a87726a71ecf0221b39ad050f371d4ce5097bbc2f04ce90 languageName: node linkType: hard -"@opentelemetry/instrumentation-express@npm:0.57.0": - version: 0.57.0 - resolution: "@opentelemetry/instrumentation-express@npm:0.57.0" +"@opentelemetry/instrumentation-express@npm:0.59.0": + version: 0.59.0 + resolution: "@opentelemetry/instrumentation-express@npm:0.59.0" dependencies: "@opentelemetry/core": "npm:^2.0.0" - "@opentelemetry/instrumentation": "npm:^0.208.0" + "@opentelemetry/instrumentation": "npm:^0.211.0" "@opentelemetry/semantic-conventions": "npm:^1.27.0" peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: 10/66c10e878433d0e90bbf88dfbf28b23ecdbc3777326f46548c16c5062118b37c623011cef390a5ed3de2855f67f91587703581846f4e1e702ff3a068404f3e89 + checksum: 10/a7da4e49429a5b06e740847ae1204fde61695a3777d864fd6fa09ff98d9859f2c243c98e61bf3a98936bfd14afed6cf5a53cb1f1f545e0ac60f9b2ac9bed4169 languageName: node linkType: hard -"@opentelemetry/instrumentation-fs@npm:0.28.0": - version: 0.28.0 - resolution: "@opentelemetry/instrumentation-fs@npm:0.28.0" +"@opentelemetry/instrumentation-fs@npm:0.30.0": + version: 0.30.0 + resolution: "@opentelemetry/instrumentation-fs@npm:0.30.0" dependencies: "@opentelemetry/core": "npm:^2.0.0" - "@opentelemetry/instrumentation": "npm:^0.208.0" + "@opentelemetry/instrumentation": "npm:^0.211.0" peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: 10/f62c1256e3c47d958b296b57f8ab1d0b8b8851e9c3d6ad8691af514a33a2341ec1a9345d57a705a420a7a5757a297e03cc04c497a5701ac027a98b63b1a90ab1 + checksum: 10/5bae626d157a9c56266e5f8dd3fae438ced9ab20b567285071dc2d47cc36f3ce36148b8a9e301ab0857701a23b9cf370c0c1f625fc783c36511a6fc62bf33d9e languageName: node linkType: hard -"@opentelemetry/instrumentation-generic-pool@npm:0.52.0": - version: 0.52.0 - resolution: "@opentelemetry/instrumentation-generic-pool@npm:0.52.0" +"@opentelemetry/instrumentation-generic-pool@npm:0.54.0": + version: 0.54.0 + resolution: "@opentelemetry/instrumentation-generic-pool@npm:0.54.0" dependencies: - "@opentelemetry/instrumentation": "npm:^0.208.0" + "@opentelemetry/instrumentation": "npm:^0.211.0" peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: 10/f94b27d84a4172f95f7a33fa967f2ad562d4dba3182b1e8b6658b4eceb8a26a678b407a232858378a034dd8ffdb4e66bd98b4a8861fe042be59af3e4b400244f + checksum: 10/3a92649c142375c8db5938fbddd604da16e4a9bd78f1278b3775fa16ff1b5b96ffd8abc868745644d0d6ea8a0c83697983d5c999cf2b21974e55004899be92e4 languageName: node linkType: hard -"@opentelemetry/instrumentation-graphql@npm:0.56.0": - version: 0.56.0 - resolution: "@opentelemetry/instrumentation-graphql@npm:0.56.0" - dependencies: - "@opentelemetry/instrumentation": "npm:^0.208.0" - peerDependencies: - "@opentelemetry/api": ^1.3.0 - checksum: 10/7895e702484367ef9c26f7c79f0039ac9677133342253f3935e7203156cbc396dfd799ef84e4758e83c008ed8c6b6893a05fc1df2566cfaae65e3770485ad8c9 - languageName: node - linkType: hard - -"@opentelemetry/instrumentation-graphql@npm:^0.58.0": +"@opentelemetry/instrumentation-graphql@npm:0.58.0, @opentelemetry/instrumentation-graphql@npm:^0.58.0": version: 0.58.0 resolution: "@opentelemetry/instrumentation-graphql@npm:0.58.0" dependencies: @@ -10201,34 +10172,20 @@ __metadata: languageName: node linkType: hard -"@opentelemetry/instrumentation-hapi@npm:0.55.0": - version: 0.55.0 - resolution: "@opentelemetry/instrumentation-hapi@npm:0.55.0" +"@opentelemetry/instrumentation-hapi@npm:0.57.0": + version: 0.57.0 + resolution: "@opentelemetry/instrumentation-hapi@npm:0.57.0" dependencies: "@opentelemetry/core": "npm:^2.0.0" - "@opentelemetry/instrumentation": "npm:^0.208.0" + "@opentelemetry/instrumentation": "npm:^0.211.0" "@opentelemetry/semantic-conventions": "npm:^1.27.0" peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: 10/575c059a2dbcd77256acfca897d2cc08968b4e7e9e41449dfd5de2ca761fa2a544aaa6f2a8213f7374a42026e1f0b7e612ce01337e43108631e20e19fec01c81 + checksum: 10/142684b85a69f29243961315acd7be390a00e536caa0897632dd38f480ef059a96e7795bdcfa4be8946abc4b4d03e6b54206ec7aed790cdcf4f4f2a467419613 languageName: node linkType: hard -"@opentelemetry/instrumentation-http@npm:0.208.0": - version: 0.208.0 - resolution: "@opentelemetry/instrumentation-http@npm:0.208.0" - dependencies: - "@opentelemetry/core": "npm:2.2.0" - "@opentelemetry/instrumentation": "npm:0.208.0" - "@opentelemetry/semantic-conventions": "npm:^1.29.0" - forwarded-parse: "npm:2.1.2" - peerDependencies: - "@opentelemetry/api": ^1.3.0 - checksum: 10/f5e11eb7054d6701ea44ecb90321558e524b253a7945d1539f9971f83c5dfc1d294a6ac632eb35d2f19309837f16f6c405958c0bd9c50a8751dd07ee0704ca4e - languageName: node - linkType: hard - -"@opentelemetry/instrumentation-http@npm:^0.211.0": +"@opentelemetry/instrumentation-http@npm:0.211.0, @opentelemetry/instrumentation-http@npm:^0.211.0": version: 0.211.0 resolution: "@opentelemetry/instrumentation-http@npm:0.211.0" dependencies: @@ -10242,19 +10199,7 @@ __metadata: languageName: node linkType: hard -"@opentelemetry/instrumentation-ioredis@npm:0.56.0": - version: 0.56.0 - resolution: "@opentelemetry/instrumentation-ioredis@npm:0.56.0" - dependencies: - "@opentelemetry/instrumentation": "npm:^0.208.0" - "@opentelemetry/redis-common": "npm:^0.38.2" - peerDependencies: - "@opentelemetry/api": ^1.3.0 - checksum: 10/8fd316eb94323fca62b71b51df4ef1dc0cf7879315f3006633d07cd9ea87bb9ff1315e216e6e61013f6ab84142593935d2920812794736ce4f0ca97da522ff09 - languageName: node - linkType: hard - -"@opentelemetry/instrumentation-ioredis@npm:^0.59.0": +"@opentelemetry/instrumentation-ioredis@npm:0.59.0, @opentelemetry/instrumentation-ioredis@npm:^0.59.0": version: 0.59.0 resolution: "@opentelemetry/instrumentation-ioredis@npm:0.59.0" dependencies: @@ -10267,99 +10212,102 @@ __metadata: languageName: node linkType: hard -"@opentelemetry/instrumentation-kafkajs@npm:0.18.0": - version: 0.18.0 - resolution: "@opentelemetry/instrumentation-kafkajs@npm:0.18.0" +"@opentelemetry/instrumentation-kafkajs@npm:0.20.0": + version: 0.20.0 + resolution: "@opentelemetry/instrumentation-kafkajs@npm:0.20.0" dependencies: - "@opentelemetry/instrumentation": "npm:^0.208.0" + "@opentelemetry/instrumentation": "npm:^0.211.0" "@opentelemetry/semantic-conventions": "npm:^1.30.0" peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: 10/e3b998d905dc6c87b542e6b7004e12eeac19903872fe3e7d4c17771f69843b721dd73d0b136b2f21207d4dec7e53fd17d5042cf27a0028ec3c3074c0861654fe + checksum: 10/f6d67ab1fc7019de319ac21a58769fa58112fb9c8fa5a1a66591e5e5d90c256e7a19e8328178748d89c01a8789e00df8cd7d34420fa4ff7c51e82df4e8b74886 languageName: node linkType: hard -"@opentelemetry/instrumentation-knex@npm:0.53.0": - version: 0.53.0 - resolution: "@opentelemetry/instrumentation-knex@npm:0.53.0" +"@opentelemetry/instrumentation-knex@npm:0.55.0": + version: 0.55.0 + resolution: "@opentelemetry/instrumentation-knex@npm:0.55.0" dependencies: - "@opentelemetry/instrumentation": "npm:^0.208.0" + "@opentelemetry/instrumentation": "npm:^0.211.0" "@opentelemetry/semantic-conventions": "npm:^1.33.1" peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: 10/70506c24957374276ef63a18d103fb74a37888ffeb9c1c6b6419a3abcf970d4c8dfed3129ca840f71f1207e246c7bc337d3bc4ab249b1a1c67dfc854dd7da7fd + checksum: 10/02d9a3c1941d08a075c9be0ddd25e0b74e801c8bcc12a200f28267397c05f6152f6059e9a5148d118bff85c065ddca2ab93b586c30a8aacb41d772f8002d3b7e languageName: node linkType: hard -"@opentelemetry/instrumentation-koa@npm:0.57.0": - version: 0.57.0 - resolution: "@opentelemetry/instrumentation-koa@npm:0.57.0" +"@opentelemetry/instrumentation-koa@npm:0.59.0": + version: 0.59.0 + resolution: "@opentelemetry/instrumentation-koa@npm:0.59.0" dependencies: "@opentelemetry/core": "npm:^2.0.0" - "@opentelemetry/instrumentation": "npm:^0.208.0" + "@opentelemetry/instrumentation": "npm:^0.211.0" "@opentelemetry/semantic-conventions": "npm:^1.36.0" peerDependencies: "@opentelemetry/api": ^1.9.0 - checksum: 10/7df972b4a5c6c8cad6e1fe6ab3a6ea391d4db09f0d3e2b0b46f0ffa0289df88fe2446e06c08744d65293aeaff2f28628d51f8dea5d97404907a49f9e567f50f6 + checksum: 10/604468baf698af3290ffc610bbe0a5c4e2ade43824069ae4ebe28416efa21ca82d2e6b0885d6d5cacbfb7b829bf631a80eb4860747c3503543a083f5ab1dcb3f languageName: node linkType: hard -"@opentelemetry/instrumentation-lru-memoizer@npm:0.53.0": - version: 0.53.0 - resolution: "@opentelemetry/instrumentation-lru-memoizer@npm:0.53.0" - dependencies: - "@opentelemetry/instrumentation": "npm:^0.208.0" - peerDependencies: - "@opentelemetry/api": ^1.3.0 - checksum: 10/6f83abdb58e83fe87ce926236c54fbaaf49f64f8149e455b1dc1f33d735faf575e6f6d4df36b8eadf176a74d01cd05c6f3a3babff56a5a7448744e0cba39df5e - languageName: node - linkType: hard - -"@opentelemetry/instrumentation-mongodb@npm:0.61.0": - version: 0.61.0 - resolution: "@opentelemetry/instrumentation-mongodb@npm:0.61.0" - dependencies: - "@opentelemetry/instrumentation": "npm:^0.208.0" - peerDependencies: - "@opentelemetry/api": ^1.3.0 - checksum: 10/fe5eb79c8924aa268c863af4a5878c47ba5730622cb861899802144a4dfe7431e7af6e9b568dd205fdedfd77fbbfe95539cdcf35e6b326ba695eeaadd61240ed - languageName: node - linkType: hard - -"@opentelemetry/instrumentation-mongoose@npm:0.55.0": +"@opentelemetry/instrumentation-lru-memoizer@npm:0.55.0": version: 0.55.0 - resolution: "@opentelemetry/instrumentation-mongoose@npm:0.55.0" + resolution: "@opentelemetry/instrumentation-lru-memoizer@npm:0.55.0" + dependencies: + "@opentelemetry/instrumentation": "npm:^0.211.0" + peerDependencies: + "@opentelemetry/api": ^1.3.0 + checksum: 10/6c2594032e3e8fa7edc1873c628c53dfaf9d6049f836255b3c87e6e284aec945be4c9fac955a5fa53d53901a73e710f85985ec73634caa4d61e9804089182427 + languageName: node + linkType: hard + +"@opentelemetry/instrumentation-mongodb@npm:0.64.0": + version: 0.64.0 + resolution: "@opentelemetry/instrumentation-mongodb@npm:0.64.0" + dependencies: + "@opentelemetry/instrumentation": "npm:^0.211.0" + "@opentelemetry/semantic-conventions": "npm:^1.33.0" + peerDependencies: + "@opentelemetry/api": ^1.3.0 + checksum: 10/ecaef6f687c32a6643f9c75a2f87868d07661bd265a9babea1f6adeb482617c03b305af5e7eaa68d85ae251f7b61493d60e4a494992ae67327160123f08f6b85 + languageName: node + linkType: hard + +"@opentelemetry/instrumentation-mongoose@npm:0.57.0": + version: 0.57.0 + resolution: "@opentelemetry/instrumentation-mongoose@npm:0.57.0" dependencies: "@opentelemetry/core": "npm:^2.0.0" - "@opentelemetry/instrumentation": "npm:^0.208.0" + "@opentelemetry/instrumentation": "npm:^0.211.0" + "@opentelemetry/semantic-conventions": "npm:^1.33.0" peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: 10/5ee25946b7a6a50178ff6b50d5a88b8a189f0ba6effc45ee07e6026c353b1cad605f51cb9c61f9200e066833a7f3b588ede02582dc7dbbce4a9d715ec312cea6 + checksum: 10/a64878d3a6ebc39451dfa8b4003d3ee83a6fcc0dff00cc0fa883eaafd671cc45047aeee03b21ce622fd46dcdfb992aa3c48bd638c16496b64d5b98f8fcfea9d0 languageName: node linkType: hard -"@opentelemetry/instrumentation-mysql2@npm:0.55.0": - version: 0.55.0 - resolution: "@opentelemetry/instrumentation-mysql2@npm:0.55.0" +"@opentelemetry/instrumentation-mysql2@npm:0.57.0": + version: 0.57.0 + resolution: "@opentelemetry/instrumentation-mysql2@npm:0.57.0" dependencies: - "@opentelemetry/instrumentation": "npm:^0.208.0" + "@opentelemetry/instrumentation": "npm:^0.211.0" "@opentelemetry/semantic-conventions": "npm:^1.33.0" "@opentelemetry/sql-common": "npm:^0.41.2" peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: 10/ca5bb6c99bd8fd3590341955aeece3c69982e07b2df520998ea282ac9135311f8fc37ba55fb66adf07a80adcf98d42892b698422c9817667231064cc251e626d + checksum: 10/b1d120318c2fbd86539182e6fedba334f5a05d87c10a574694b67b8efac820ee46350fb2664be802e28800705739d1be08e257f25b79661f1214d497eba1cdd6 languageName: node linkType: hard -"@opentelemetry/instrumentation-mysql@npm:0.54.0": - version: 0.54.0 - resolution: "@opentelemetry/instrumentation-mysql@npm:0.54.0" +"@opentelemetry/instrumentation-mysql@npm:0.57.0": + version: 0.57.0 + resolution: "@opentelemetry/instrumentation-mysql@npm:0.57.0" dependencies: - "@opentelemetry/instrumentation": "npm:^0.208.0" + "@opentelemetry/instrumentation": "npm:^0.211.0" + "@opentelemetry/semantic-conventions": "npm:^1.33.0" "@types/mysql": "npm:2.15.27" peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: 10/d4756b4d72c0232f92fc00fd8fb03d02fe27d9108c8c74ae1d8aa50800207f7e6dc10aa8f5a636d9b6c8865b10e10a79741242c08af4d4f0599977182b7508ae + checksum: 10/d36cfca4f0ab748eea3736ef521a5d225ddea048d30e7bc65f1e5063eff179ce0c45d1018600036cb5997d420460c4dbdf2f94071b046b094751fa83a9a8afe4 languageName: node linkType: hard @@ -10375,32 +10323,32 @@ __metadata: languageName: node linkType: hard -"@opentelemetry/instrumentation-pg@npm:0.61.0": - version: 0.61.0 - resolution: "@opentelemetry/instrumentation-pg@npm:0.61.0" +"@opentelemetry/instrumentation-pg@npm:0.63.0": + version: 0.63.0 + resolution: "@opentelemetry/instrumentation-pg@npm:0.63.0" dependencies: "@opentelemetry/core": "npm:^2.0.0" - "@opentelemetry/instrumentation": "npm:^0.208.0" + "@opentelemetry/instrumentation": "npm:^0.211.0" "@opentelemetry/semantic-conventions": "npm:^1.34.0" "@opentelemetry/sql-common": "npm:^0.41.2" "@types/pg": "npm:8.15.6" - "@types/pg-pool": "npm:2.0.6" + "@types/pg-pool": "npm:2.0.7" peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: 10/84825695303d79720a87622bfb0bcbc6c46463a595a36d7fb611684bfb23df9645ff17780b60a00cc97a78e70ef109603fc473b2cefd91a7099b14d2d93fdb56 + checksum: 10/f937e1e535455ed6d9e9bf07c296e025a4ff05e003c4b259f5dede78cf5ce96631805602c90d26251a366542a19f15a4d514c9241d965873a9d8bef1812b121f languageName: node linkType: hard -"@opentelemetry/instrumentation-redis@npm:0.57.0": - version: 0.57.0 - resolution: "@opentelemetry/instrumentation-redis@npm:0.57.0" +"@opentelemetry/instrumentation-redis@npm:0.59.0": + version: 0.59.0 + resolution: "@opentelemetry/instrumentation-redis@npm:0.59.0" dependencies: - "@opentelemetry/instrumentation": "npm:^0.208.0" + "@opentelemetry/instrumentation": "npm:^0.211.0" "@opentelemetry/redis-common": "npm:^0.38.2" "@opentelemetry/semantic-conventions": "npm:^1.27.0" peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: 10/171f5e57d0141088f8e4cdb8f744226d7999ca045842708e65c8b784f53a41e25a7248f22382bf1b4a80b6fa1cc4c41658502bb15340b3fa2c22f2e9db8b76e0 + checksum: 10/b5f455901ddfe40cc0e8e0c0c7889d0836995605593d134fe3c127791adf866a69519d9158634ba121ffa239746f15269a97bbb104a2271a4a83507bde43af66 languageName: node linkType: hard @@ -10415,41 +10363,29 @@ __metadata: languageName: node linkType: hard -"@opentelemetry/instrumentation-tedious@npm:0.27.0": - version: 0.27.0 - resolution: "@opentelemetry/instrumentation-tedious@npm:0.27.0" +"@opentelemetry/instrumentation-tedious@npm:0.30.0": + version: 0.30.0 + resolution: "@opentelemetry/instrumentation-tedious@npm:0.30.0" dependencies: - "@opentelemetry/instrumentation": "npm:^0.208.0" + "@opentelemetry/instrumentation": "npm:^0.211.0" + "@opentelemetry/semantic-conventions": "npm:^1.33.0" "@types/tedious": "npm:^4.0.14" peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: 10/453492b72cf16b855da1a4ba38b9619261ef77ed4afe8ae551c0abc529c81c8640d816934aae197fa719e8e79591613d2398a8a7f3b77c82de41bf51db3eebfc + checksum: 10/d8f62caa556571b21100c5fc8c1f06a689afcec2099ce59b988f6782463ab18b59f38adf3b84c8adbb736ae8bb7820f5368527a984e41ec2b90e9cccfb18a9de languageName: node linkType: hard -"@opentelemetry/instrumentation-undici@npm:0.19.0": - version: 0.19.0 - resolution: "@opentelemetry/instrumentation-undici@npm:0.19.0" +"@opentelemetry/instrumentation-undici@npm:0.21.0": + version: 0.21.0 + resolution: "@opentelemetry/instrumentation-undici@npm:0.21.0" dependencies: "@opentelemetry/core": "npm:^2.0.0" - "@opentelemetry/instrumentation": "npm:^0.208.0" + "@opentelemetry/instrumentation": "npm:^0.211.0" "@opentelemetry/semantic-conventions": "npm:^1.24.0" peerDependencies: "@opentelemetry/api": ^1.7.0 - checksum: 10/862ea5e49c2cf38c7a135f5ea6a95f1b8ca009620f9b0e4d6c7ffb69e8e1d4e7d4169e4cf0cd2af4ce574864b37ea3f7c039b0e6600d3e490f3c263a8647325e - languageName: node - linkType: hard - -"@opentelemetry/instrumentation@npm:0.208.0, @opentelemetry/instrumentation@npm:^0.208.0": - version: 0.208.0 - resolution: "@opentelemetry/instrumentation@npm:0.208.0" - dependencies: - "@opentelemetry/api-logs": "npm:0.208.0" - import-in-the-middle: "npm:^2.0.0" - require-in-the-middle: "npm:^8.0.0" - peerDependencies: - "@opentelemetry/api": ^1.3.0 - checksum: 10/0591121c1bab29b8246ba879b1ed91f2db17680cfce56a635bf2e81390a9140f029b094ff4498ff154132379192bf424d7d234d2114883735603e4a6581a4a79 + checksum: 10/e2e39d7ef3a786c65979517c3db0f6a3cfab263db1072031623f51aa9b1bdd79ae6f1f216718b4ce0be1334655c3ec19906fd2d4d646cfe12ae630deb456fc13 languageName: node linkType: hard @@ -10466,6 +10402,32 @@ __metadata: languageName: node linkType: hard +"@opentelemetry/instrumentation@npm:^0.207.0": + version: 0.207.0 + resolution: "@opentelemetry/instrumentation@npm:0.207.0" + dependencies: + "@opentelemetry/api-logs": "npm:0.207.0" + import-in-the-middle: "npm:^2.0.0" + require-in-the-middle: "npm:^8.0.0" + peerDependencies: + "@opentelemetry/api": ^1.3.0 + checksum: 10/ea9b9a7324016116ba5ded98ebf7e8db722625a7408532be707db2ad9f5a760e7f17809097c5fc61b95f135281349534045e0242eaa9fc57c4b508d2ddf4c181 + languageName: node + linkType: hard + +"@opentelemetry/instrumentation@npm:^0.208.0": + version: 0.208.0 + resolution: "@opentelemetry/instrumentation@npm:0.208.0" + dependencies: + "@opentelemetry/api-logs": "npm:0.208.0" + import-in-the-middle: "npm:^2.0.0" + require-in-the-middle: "npm:^8.0.0" + peerDependencies: + "@opentelemetry/api": ^1.3.0 + checksum: 10/0591121c1bab29b8246ba879b1ed91f2db17680cfce56a635bf2e81390a9140f029b094ff4498ff154132379192bf424d7d234d2114883735603e4a6581a4a79 + languageName: node + linkType: hard + "@opentelemetry/otlp-exporter-base@npm:0.211.0": version: 0.211.0 resolution: "@opentelemetry/otlp-exporter-base@npm:0.211.0" @@ -10538,7 +10500,7 @@ __metadata: languageName: node linkType: hard -"@opentelemetry/resources@npm:2.5.0, @opentelemetry/resources@npm:^2.2.0": +"@opentelemetry/resources@npm:2.5.0": version: 2.5.0 resolution: "@opentelemetry/resources@npm:2.5.0" dependencies: @@ -10550,6 +10512,18 @@ __metadata: languageName: node linkType: hard +"@opentelemetry/resources@npm:2.5.1, @opentelemetry/resources@npm:^2.2.0, @opentelemetry/resources@npm:^2.5.1": + version: 2.5.1 + resolution: "@opentelemetry/resources@npm:2.5.1" + dependencies: + "@opentelemetry/core": "npm:2.5.1" + "@opentelemetry/semantic-conventions": "npm:^1.29.0" + peerDependencies: + "@opentelemetry/api": ">=1.3.0 <1.10.0" + checksum: 10/5a9fc07fede70eb9b72d25c654b1ab0e7133e1ed0f7940418e9e637b9298a07c7a7db38b5765d6690865aeb88934b1544631ca183e32e518fd012ca7ffa6ee87 + languageName: node + linkType: hard + "@opentelemetry/sdk-logs@npm:0.211.0": version: 0.211.0 resolution: "@opentelemetry/sdk-logs@npm:0.211.0" @@ -10609,7 +10583,7 @@ __metadata: languageName: node linkType: hard -"@opentelemetry/sdk-trace-base@npm:2.5.0, @opentelemetry/sdk-trace-base@npm:^2.2.0": +"@opentelemetry/sdk-trace-base@npm:2.5.0": version: 2.5.0 resolution: "@opentelemetry/sdk-trace-base@npm:2.5.0" dependencies: @@ -10622,6 +10596,19 @@ __metadata: languageName: node linkType: hard +"@opentelemetry/sdk-trace-base@npm:^2.5.1": + version: 2.5.1 + resolution: "@opentelemetry/sdk-trace-base@npm:2.5.1" + dependencies: + "@opentelemetry/core": "npm:2.5.1" + "@opentelemetry/resources": "npm:2.5.1" + "@opentelemetry/semantic-conventions": "npm:^1.29.0" + peerDependencies: + "@opentelemetry/api": ">=1.3.0 <1.10.0" + checksum: 10/5d8de3fa2cbfc09f45e042423e32a67098261ca8a0e326bca6f33cbe866670709332b81cf5a73bf35f44f165c506aed910215a5294a6ba204fb4bd3d8ea0f531 + languageName: node + linkType: hard + "@opentelemetry/sdk-trace-node@npm:2.5.0, @opentelemetry/sdk-trace-node@npm:^2.2.0": version: 2.5.0 resolution: "@opentelemetry/sdk-trace-node@npm:2.5.0" @@ -10635,10 +10622,10 @@ __metadata: languageName: node linkType: hard -"@opentelemetry/semantic-conventions@npm:^1.22.0, @opentelemetry/semantic-conventions@npm:^1.24.0, @opentelemetry/semantic-conventions@npm:^1.27.0, @opentelemetry/semantic-conventions@npm:^1.29.0, @opentelemetry/semantic-conventions@npm:^1.30.0, @opentelemetry/semantic-conventions@npm:^1.33.0, @opentelemetry/semantic-conventions@npm:^1.33.1, @opentelemetry/semantic-conventions@npm:^1.34.0, @opentelemetry/semantic-conventions@npm:^1.36.0, @opentelemetry/semantic-conventions@npm:^1.37.0, @opentelemetry/semantic-conventions@npm:^1.38.0": - version: 1.39.0 - resolution: "@opentelemetry/semantic-conventions@npm:1.39.0" - checksum: 10/30b8f78468ef38c541f9c8a6831d53dc66c097c4c2cf5eb662c64dd2c52327d44779104fdcd14c8d0f1e9802dc7674accfd9186777493202595f9a9af2e5d1b6 +"@opentelemetry/semantic-conventions@npm:^1.22.0, @opentelemetry/semantic-conventions@npm:^1.24.0, @opentelemetry/semantic-conventions@npm:^1.27.0, @opentelemetry/semantic-conventions@npm:^1.28.0, @opentelemetry/semantic-conventions@npm:^1.29.0, @opentelemetry/semantic-conventions@npm:^1.30.0, @opentelemetry/semantic-conventions@npm:^1.33.0, @opentelemetry/semantic-conventions@npm:^1.33.1, @opentelemetry/semantic-conventions@npm:^1.34.0, @opentelemetry/semantic-conventions@npm:^1.36.0, @opentelemetry/semantic-conventions@npm:^1.38.0, @opentelemetry/semantic-conventions@npm:^1.39.0": + version: 1.40.0 + resolution: "@opentelemetry/semantic-conventions@npm:1.40.0" + checksum: 10/edb58894590e42e631006a9f5741955fad248e3589aa334a5e59080c535ead44ee9f376c444ef2be094d1e6c1a2e596538c1df0a31a04508551e91b1a5d5c93c languageName: node linkType: hard @@ -10813,86 +10800,6 @@ __metadata: languageName: node linkType: hard -"@perfsee/bundle-analyzer@npm:1.14.2": - version: 1.14.2 - resolution: "@perfsee/bundle-analyzer@npm:1.14.2" - dependencies: - "@eyhn/msgpack-stream": "npm:^2.8.4" - "@perfsee/jsonr": "npm:1.14.2" - "@perfsee/utils": "npm:1.14.2" - acorn: "npm:^8.7.1" - acorn-walk: "npm:^8.2.0" - htmlparser2: "npm:^8.0.1" - lodash: "npm:^4.17.21" - minimatch: "npm:^7.4.6" - query-string: "npm:^7.1.1" - tar: "npm:^6.1.11" - tslib: "npm:^2.4.0" - peerDependencies: - isolated-vm: ^4.7.2 - peerDependenciesMeta: - isolated-vm: - optional: true - checksum: 10/641739f305ce701969e2582620d3ebbff1e01d81a4e472346372fc100455159b2d7d63d1de89432a14e835d9772f5d23d8235068e89f69e44231349c0a0cb178 - languageName: node - linkType: hard - -"@perfsee/jsonr@npm:1.14.2": - version: 1.14.2 - resolution: "@perfsee/jsonr@npm:1.14.2" - dependencies: - tslib: "npm:^2.4.0" - checksum: 10/501d93fb6f6378ef22426ff7a76ec5eefe0e83dd4f25d6b1a13b0842fcedfe9caedabb3a5144a5c5610631dcd2256d310b22c3eb693a5747210dcf5532fb3aa1 - languageName: node - linkType: hard - -"@perfsee/plugin-utils@npm:1.14.2": - version: 1.14.2 - resolution: "@perfsee/plugin-utils@npm:1.14.2" - dependencies: - "@perfsee/bundle-analyzer": "npm:1.14.2" - "@perfsee/jsonr": "npm:1.14.2" - "@perfsee/utils": "npm:1.14.2" - chalk: "npm:^4.1.2" - debug: "npm:4.3.4" - env-ci: "npm:^7.2.1" - find-cache-dir: "npm:^3.3.2" - lodash: "npm:^4.17.21" - node-fetch: "npm:^2.6.2" - open: "npm:^8.4.2" - query-string: "npm:^7.1.1" - simple-git: "npm:3.15.0" - table: "npm:^6.8.0" - tar: "npm:^6.1.11" - tslib: "npm:^2.4.0" - uuid: "npm:^9.0.0" - checksum: 10/5c4717b64dddaa9e48f189b83ae1a50cdd257b137ea5b076330da02ec999d044aef744aac68ccb43570492fdd2ca8cb34aad134606fa087b62ff85e88300479d - languageName: node - linkType: hard - -"@perfsee/utils@npm:1.14.2": - version: 1.14.2 - resolution: "@perfsee/utils@npm:1.14.2" - dependencies: - tslib: "npm:^2.4.0" - checksum: 10/a6ec554f2ac75f7b8d05e7556901c3ed3b3c02bf8bb7cb9a79e0e82431e46f4e3eff92f32e3be8d9d0f96946a34c40104b140be5ea39d226e6c648aeb5ae68e0 - languageName: node - linkType: hard - -"@perfsee/webpack@npm:^1.13.0": - version: 1.14.2 - resolution: "@perfsee/webpack@npm:1.14.2" - dependencies: - "@perfsee/bundle-analyzer": "npm:1.14.2" - "@perfsee/plugin-utils": "npm:1.14.2" - chalk: "npm:^4.1.2" - tslib: "npm:^2.4.0" - peerDependencies: - webpack: ">= 4" - checksum: 10/ff27347b4a7892c1ee935fcf098f231bc3b4d151a0c8050bfda52475ff5ed0144e221a861e0e4acdb1fa3d9e312491d402ba5e87fabb8bc1436e4d17b021e9b4 - languageName: node - linkType: hard - "@pkgjs/parseargs@npm:^0.11.0": version: 0.11.0 resolution: "@pkgjs/parseargs@npm:0.11.0" @@ -10995,7 +10902,18 @@ __metadata: languageName: node linkType: hard -"@prisma/instrumentation@npm:6.19.0, @prisma/instrumentation@npm:^6.7.0": +"@prisma/instrumentation@npm:7.2.0": + version: 7.2.0 + resolution: "@prisma/instrumentation@npm:7.2.0" + dependencies: + "@opentelemetry/instrumentation": "npm:^0.207.0" + peerDependencies: + "@opentelemetry/api": ^1.8 + checksum: 10/a02d16543fdeb7e2d804d0c3ecdb9f83e4996eea1cce52519bb0f772cbf943e7ea4c89e726004eabd6cb6008991ad4530a03c68ee27ec572f762f97ef5213b33 + languageName: node + linkType: hard + +"@prisma/instrumentation@npm:^6.7.0": version: 6.19.0 resolution: "@prisma/instrumentation@npm:6.19.0" dependencies: @@ -14836,199 +14754,147 @@ __metadata: languageName: node linkType: hard -"@sentry-internal/browser-utils@npm:10.29.0": - version: 10.29.0 - resolution: "@sentry-internal/browser-utils@npm:10.29.0" +"@sentry-internal/browser-utils@npm:10.40.0": + version: 10.40.0 + resolution: "@sentry-internal/browser-utils@npm:10.40.0" dependencies: - "@sentry/core": "npm:10.29.0" - checksum: 10/eacb0b4d08a732370b9d70a53f1348fe80463abb39d70aa2935cc1bd611f034d0cd6c1e7b783b654856a24e7a525524f9d305ec9133d0574abb09e1412ea8237 + "@sentry/core": "npm:10.40.0" + checksum: 10/db037096d87368209119b83e0e4a4c1acafd341cbded1139ef121f65a7520bbe4f5157cf84419c01ee374c5af668a547c9abfe79eee0fdf002f5b26097db5f31 languageName: node linkType: hard -"@sentry-internal/browser-utils@npm:9.47.1": - version: 9.47.1 - resolution: "@sentry-internal/browser-utils@npm:9.47.1" +"@sentry-internal/feedback@npm:10.40.0": + version: 10.40.0 + resolution: "@sentry-internal/feedback@npm:10.40.0" dependencies: - "@sentry/core": "npm:9.47.1" - checksum: 10/18d99dc0fba5df749915a61433ca9d9f2019afd62a9effcab96aef01b7912d37e4415fbe35c50a5c8a1bdd304a4dbf46c2b9d48ca6b100c348847044f895e88d + "@sentry/core": "npm:10.40.0" + checksum: 10/42fb400e6203e7d4ba2ddd0a13e9c3b84f0fb7f136e677415073cd0c2037faaa21c5184ef015a9b11a2fb88f588154a5743664af7188658e0edd0561d05ef72c languageName: node linkType: hard -"@sentry-internal/feedback@npm:10.29.0": - version: 10.29.0 - resolution: "@sentry-internal/feedback@npm:10.29.0" +"@sentry-internal/replay-canvas@npm:10.40.0": + version: 10.40.0 + resolution: "@sentry-internal/replay-canvas@npm:10.40.0" dependencies: - "@sentry/core": "npm:10.29.0" - checksum: 10/3b19a1f8d0ecce20b67bee4aa866d10338bad968461b772944ced96413c650c655f5345f9cab193716f381e354ae08c4e055d356d108953e6411c5be51c85550 + "@sentry-internal/replay": "npm:10.40.0" + "@sentry/core": "npm:10.40.0" + checksum: 10/cb98dc28721bfa8d7e10a081ee4dde52bc7188500a3be601b864756fa95f0748ae69e1d8092c9a3e58f57d1136027401aec3b69b3a62a09febba5ab7dfe53170 languageName: node linkType: hard -"@sentry-internal/feedback@npm:9.47.1": - version: 9.47.1 - resolution: "@sentry-internal/feedback@npm:9.47.1" +"@sentry-internal/replay@npm:10.40.0": + version: 10.40.0 + resolution: "@sentry-internal/replay@npm:10.40.0" dependencies: - "@sentry/core": "npm:9.47.1" - checksum: 10/775e8a2022b913b74bd2bea8d83eb1caeeeb78ae1929b1fda22ac38290386e9d21c0eb8cfafa0b4b9b075ffb90124b5dccf92e4c353784949d6d58989dba9d68 + "@sentry-internal/browser-utils": "npm:10.40.0" + "@sentry/core": "npm:10.40.0" + checksum: 10/0aaf9ebdbf13cd465771ff5b56211db7205b82f9bd70a7ed704c8a281124d9c4852c44750789d5853d2d68721a3eb4c9451e4446a8cd72150a18db9be3832e17 languageName: node linkType: hard -"@sentry-internal/replay-canvas@npm:10.29.0": - version: 10.29.0 - resolution: "@sentry-internal/replay-canvas@npm:10.29.0" +"@sentry/babel-plugin-component-annotate@npm:5.1.1": + version: 5.1.1 + resolution: "@sentry/babel-plugin-component-annotate@npm:5.1.1" + checksum: 10/8c7da826dc2dd4a3335628fb9094d3976354a0a72ca46e8bebe4945402225fdca868f9717843c640ca381278f62d7798b697843a3add3422f409702ebca094cc + languageName: node + linkType: hard + +"@sentry/browser@npm:10.40.0": + version: 10.40.0 + resolution: "@sentry/browser@npm:10.40.0" dependencies: - "@sentry-internal/replay": "npm:10.29.0" - "@sentry/core": "npm:10.29.0" - checksum: 10/af5cea43b144eefd565c2af48515bf9f8ed120ed6671a86a671e04c1930e5d0532f64e3b618c7d72b0881e0caa812692c02d6af7207388a07170835521164e38 + "@sentry-internal/browser-utils": "npm:10.40.0" + "@sentry-internal/feedback": "npm:10.40.0" + "@sentry-internal/replay": "npm:10.40.0" + "@sentry-internal/replay-canvas": "npm:10.40.0" + "@sentry/core": "npm:10.40.0" + checksum: 10/0bb4707329e7f0d66aea93ca1cb65041d813072ab880b3876c36a007bf983c6130840d7de08d86b152c672e5eb10f4903383429cf67d33089a3cbd4fb4cee476 languageName: node linkType: hard -"@sentry-internal/replay-canvas@npm:9.47.1": - version: 9.47.1 - resolution: "@sentry-internal/replay-canvas@npm:9.47.1" - dependencies: - "@sentry-internal/replay": "npm:9.47.1" - "@sentry/core": "npm:9.47.1" - checksum: 10/1a1d230b3ba22c3ceacd7b7144737b2f2aad5f7fa0dec023cc43f27d2bf28cda2ffb5d1154333b4b949cbd89a66ab43a6d21bec6cad48e5089cde33dbfeb5e6b - languageName: node - linkType: hard - -"@sentry-internal/replay@npm:10.29.0": - version: 10.29.0 - resolution: "@sentry-internal/replay@npm:10.29.0" - dependencies: - "@sentry-internal/browser-utils": "npm:10.29.0" - "@sentry/core": "npm:10.29.0" - checksum: 10/2314d9d6da1e57a830732351a7a57bca44e2f75a79b52e9998da20666fe3a15b6e64844758256d1281f8c9f9f07e71d84d05e5648792268cfe61762965484e7e - languageName: node - linkType: hard - -"@sentry-internal/replay@npm:9.47.1": - version: 9.47.1 - resolution: "@sentry-internal/replay@npm:9.47.1" - dependencies: - "@sentry-internal/browser-utils": "npm:9.47.1" - "@sentry/core": "npm:9.47.1" - checksum: 10/94f3f2f5c72fff4234d4cefd574a1e49fcc85d8c2e7054af2c7a659c5e6b7e531504e6dbf0934d37e992840ca8e947ee0254faf6dbf977a18a4f63cd9a17850e - languageName: node - linkType: hard - -"@sentry/babel-plugin-component-annotate@npm:4.8.0": - version: 4.8.0 - resolution: "@sentry/babel-plugin-component-annotate@npm:4.8.0" - checksum: 10/7cc62dfea3dd3d895e52624c2b27a81c7c641d42a3de05ff14bf0fede9d876a9cfec11962d33bacf42dfea59ec75c4271448a6c284dc63c2c0bb634002419867 - languageName: node - linkType: hard - -"@sentry/browser@npm:10.29.0": - version: 10.29.0 - resolution: "@sentry/browser@npm:10.29.0" - dependencies: - "@sentry-internal/browser-utils": "npm:10.29.0" - "@sentry-internal/feedback": "npm:10.29.0" - "@sentry-internal/replay": "npm:10.29.0" - "@sentry-internal/replay-canvas": "npm:10.29.0" - "@sentry/core": "npm:10.29.0" - checksum: 10/b1ab4f7a9a0304174134be4e432b6cf03d7cf91402107549648996d541336ff5846004d5c5bea34769bdd2c46d62a5e00e3f0ba317f25fb8ec4c5d6321d74ce8 - languageName: node - linkType: hard - -"@sentry/browser@npm:9.47.1": - version: 9.47.1 - resolution: "@sentry/browser@npm:9.47.1" - dependencies: - "@sentry-internal/browser-utils": "npm:9.47.1" - "@sentry-internal/feedback": "npm:9.47.1" - "@sentry-internal/replay": "npm:9.47.1" - "@sentry-internal/replay-canvas": "npm:9.47.1" - "@sentry/core": "npm:9.47.1" - checksum: 10/16a4883034ec73e4cca25c3586b0133da72372812d7b635bb2b973113c91e59c818cd488ef7dbeeedc15a4b1f295c14601c1d4d5905bd7b247116de015cac9c6 - languageName: node - linkType: hard - -"@sentry/bundler-plugin-core@npm:4.8.0": - version: 4.8.0 - resolution: "@sentry/bundler-plugin-core@npm:4.8.0" +"@sentry/bundler-plugin-core@npm:5.1.1": + version: 5.1.1 + resolution: "@sentry/bundler-plugin-core@npm:5.1.1" dependencies: "@babel/core": "npm:^7.18.5" - "@sentry/babel-plugin-component-annotate": "npm:4.8.0" - "@sentry/cli": "npm:^2.57.0" + "@sentry/babel-plugin-component-annotate": "npm:5.1.1" + "@sentry/cli": "npm:^2.58.5" dotenv: "npm:^16.3.1" find-up: "npm:^5.0.0" - glob: "npm:^10.5.0" - magic-string: "npm:0.30.8" - unplugin: "npm:1.0.1" - checksum: 10/a19eaf1c118e273ed3383da0ede9365c23b5668871f21b89c22fb873ae29cf972464472d7c448f84afdea7e99e50dc5bf5f46579721f88696400cab994a2d123 + glob: "npm:^13.0.6" + magic-string: "npm:~0.30.8" + checksum: 10/6d08a02ed44d15ce4905be33d573787b75689d75c9fdc4026a6fce4c9f62e4539d2f281e10b57dd97ceddb0b52a34c091f57cfd8b96d20993a0cbc83b25c26d0 languageName: node linkType: hard -"@sentry/cli-darwin@npm:2.58.4": - version: 2.58.4 - resolution: "@sentry/cli-darwin@npm:2.58.4" +"@sentry/cli-darwin@npm:2.58.5": + version: 2.58.5 + resolution: "@sentry/cli-darwin@npm:2.58.5" conditions: os=darwin languageName: node linkType: hard -"@sentry/cli-linux-arm64@npm:2.58.4": - version: 2.58.4 - resolution: "@sentry/cli-linux-arm64@npm:2.58.4" +"@sentry/cli-linux-arm64@npm:2.58.5": + version: 2.58.5 + resolution: "@sentry/cli-linux-arm64@npm:2.58.5" conditions: (os=linux | os=freebsd | os=android) & cpu=arm64 languageName: node linkType: hard -"@sentry/cli-linux-arm@npm:2.58.4": - version: 2.58.4 - resolution: "@sentry/cli-linux-arm@npm:2.58.4" +"@sentry/cli-linux-arm@npm:2.58.5": + version: 2.58.5 + resolution: "@sentry/cli-linux-arm@npm:2.58.5" conditions: (os=linux | os=freebsd | os=android) & cpu=arm languageName: node linkType: hard -"@sentry/cli-linux-i686@npm:2.58.4": - version: 2.58.4 - resolution: "@sentry/cli-linux-i686@npm:2.58.4" +"@sentry/cli-linux-i686@npm:2.58.5": + version: 2.58.5 + resolution: "@sentry/cli-linux-i686@npm:2.58.5" conditions: (os=linux | os=freebsd | os=android) & (cpu=x86 | cpu=ia32) languageName: node linkType: hard -"@sentry/cli-linux-x64@npm:2.58.4": - version: 2.58.4 - resolution: "@sentry/cli-linux-x64@npm:2.58.4" +"@sentry/cli-linux-x64@npm:2.58.5": + version: 2.58.5 + resolution: "@sentry/cli-linux-x64@npm:2.58.5" conditions: (os=linux | os=freebsd | os=android) & cpu=x64 languageName: node linkType: hard -"@sentry/cli-win32-arm64@npm:2.58.4": - version: 2.58.4 - resolution: "@sentry/cli-win32-arm64@npm:2.58.4" +"@sentry/cli-win32-arm64@npm:2.58.5": + version: 2.58.5 + resolution: "@sentry/cli-win32-arm64@npm:2.58.5" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@sentry/cli-win32-i686@npm:2.58.4": - version: 2.58.4 - resolution: "@sentry/cli-win32-i686@npm:2.58.4" +"@sentry/cli-win32-i686@npm:2.58.5": + version: 2.58.5 + resolution: "@sentry/cli-win32-i686@npm:2.58.5" conditions: os=win32 & (cpu=x86 | cpu=ia32) languageName: node linkType: hard -"@sentry/cli-win32-x64@npm:2.58.4": - version: 2.58.4 - resolution: "@sentry/cli-win32-x64@npm:2.58.4" +"@sentry/cli-win32-x64@npm:2.58.5": + version: 2.58.5 + resolution: "@sentry/cli-win32-x64@npm:2.58.5" conditions: os=win32 & cpu=x64 languageName: node linkType: hard -"@sentry/cli@npm:^2.57.0": - version: 2.58.4 - resolution: "@sentry/cli@npm:2.58.4" +"@sentry/cli@npm:^2.58.5": + version: 2.58.5 + resolution: "@sentry/cli@npm:2.58.5" dependencies: - "@sentry/cli-darwin": "npm:2.58.4" - "@sentry/cli-linux-arm": "npm:2.58.4" - "@sentry/cli-linux-arm64": "npm:2.58.4" - "@sentry/cli-linux-i686": "npm:2.58.4" - "@sentry/cli-linux-x64": "npm:2.58.4" - "@sentry/cli-win32-arm64": "npm:2.58.4" - "@sentry/cli-win32-i686": "npm:2.58.4" - "@sentry/cli-win32-x64": "npm:2.58.4" + "@sentry/cli-darwin": "npm:2.58.5" + "@sentry/cli-linux-arm": "npm:2.58.5" + "@sentry/cli-linux-arm64": "npm:2.58.5" + "@sentry/cli-linux-i686": "npm:2.58.5" + "@sentry/cli-linux-x64": "npm:2.58.5" + "@sentry/cli-win32-arm64": "npm:2.58.5" + "@sentry/cli-win32-i686": "npm:2.58.5" + "@sentry/cli-win32-x64": "npm:2.58.5" https-proxy-agent: "npm:^5.0.0" node-fetch: "npm:^2.6.7" progress: "npm:^2.0.3" @@ -15053,152 +14919,156 @@ __metadata: optional: true bin: sentry-cli: bin/sentry-cli - checksum: 10/cf5df020ed96c05e74f742c80b4c5f16750ee82a6b6f3619c0edb964c5b02b4dfca5688eb8a5278274fce38f9cd2b770e20d9365253bb86e9f24ceb309f9f6eb + checksum: 10/347fb8236b1db52ccf111b397df379af798373b4a022a03b5136f9e5db5d873e24616094a92f5216b1a218fac54c8e8f47e91c9fa089e6bf31c6989691216b2a languageName: node linkType: hard -"@sentry/core@npm:10.29.0": - version: 10.29.0 - resolution: "@sentry/core@npm:10.29.0" - checksum: 10/aa7a233a8c6327c5f60321cd65e2704e46945f5140da55e6016d949ad97529e362b3e2885c16e5defc53e5de0f870074aa94defd8376e50931bdf677c73c66fa +"@sentry/core@npm:10.40.0": + version: 10.40.0 + resolution: "@sentry/core@npm:10.40.0" + checksum: 10/a7ff4eb99c9418731049ed5730e54f231fdb588145df09c602ccf84c22ff6afef35c389b48cf18326fc6ffa110a6c51f746a35178e19fa6fd2caaaebf733712f languageName: node linkType: hard -"@sentry/core@npm:9.47.1": - version: 9.47.1 - resolution: "@sentry/core@npm:9.47.1" - checksum: 10/62cc2a0f45d89e3b78f083fe365007e59aed54e20b55ae5b45931cfa8e4d79d457c0c57450c6c7f92cec71fa682cd9cb3b64414fa86273f08cf3d8d06bd99c24 - languageName: node - linkType: hard - -"@sentry/electron@npm:^7.0.0": - version: 7.5.0 - resolution: "@sentry/electron@npm:7.5.0" +"@sentry/electron@npm:^7.9.0": + version: 7.9.0 + resolution: "@sentry/electron@npm:7.9.0" dependencies: - "@sentry/browser": "npm:10.29.0" - "@sentry/core": "npm:10.29.0" - "@sentry/node": "npm:10.29.0" + "@sentry/browser": "npm:10.40.0" + "@sentry/core": "npm:10.40.0" + "@sentry/node": "npm:10.40.0" peerDependencies: - "@sentry/node-native": 10.29.0 + "@sentry/node-native": 10.40.0 peerDependenciesMeta: "@sentry/node-native": optional: true - checksum: 10/b5d5a512fa6dd748a393b8574b6d975a6b0e213c0081aa2e7c1305e9fb55221b1af956c88617cb2fc7b097c560ccbedf2903c8d7cd40bafc49294939a70ec85a + checksum: 10/5daea9a40a5fb7e40f4e3c57bbcbe15807a744737ecbc58a9c9a02dbc22bfd44f27f11e5f8848dcbe1bffa19638c2979eda575870a3e7baf90203e75ee641786 languageName: node linkType: hard -"@sentry/esbuild-plugin@npm:^4.0.0": - version: 4.8.0 - resolution: "@sentry/esbuild-plugin@npm:4.8.0" +"@sentry/esbuild-plugin@npm:^5.1.1": + version: 5.1.1 + resolution: "@sentry/esbuild-plugin@npm:5.1.1" dependencies: - "@sentry/bundler-plugin-core": "npm:4.8.0" - unplugin: "npm:1.0.1" + "@sentry/bundler-plugin-core": "npm:5.1.1" uuid: "npm:^9.0.0" - checksum: 10/d5204896f1b2bc780ea9cac7e057746b9ac8a33591f16c754c03248e273e92a0bbaf46c66467d5300cb41f4763b2a82fa623bae3c853d5254dd6a68716017b2d + checksum: 10/d0bb8b83e8c1aaac48a87437640589dfb9523effad3e6222d88712cfb635f269472271f0180ecefa7a3c1d20dad299ebd27b4c7e8404e89e8a5e268f27a6a482 languageName: node linkType: hard -"@sentry/node-core@npm:10.29.0": - version: 10.29.0 - resolution: "@sentry/node-core@npm:10.29.0" +"@sentry/node-core@npm:10.40.0": + version: 10.40.0 + resolution: "@sentry/node-core@npm:10.40.0" dependencies: - "@apm-js-collab/tracing-hooks": "npm:^0.3.1" - "@sentry/core": "npm:10.29.0" - "@sentry/opentelemetry": "npm:10.29.0" - import-in-the-middle: "npm:^2" + "@sentry/core": "npm:10.40.0" + "@sentry/opentelemetry": "npm:10.40.0" + import-in-the-middle: "npm:^2.0.6" peerDependencies: "@opentelemetry/api": ^1.9.0 - "@opentelemetry/context-async-hooks": ^1.30.1 || ^2.1.0 || ^2.2.0 - "@opentelemetry/core": ^1.30.1 || ^2.1.0 || ^2.2.0 + "@opentelemetry/context-async-hooks": ^1.30.1 || ^2.1.0 + "@opentelemetry/core": ^1.30.1 || ^2.1.0 "@opentelemetry/instrumentation": ">=0.57.1 <1" - "@opentelemetry/resources": ^1.30.1 || ^2.1.0 || ^2.2.0 - "@opentelemetry/sdk-trace-base": ^1.30.1 || ^2.1.0 || ^2.2.0 - "@opentelemetry/semantic-conventions": ^1.37.0 - checksum: 10/5a5c307b5719f50fdbbc7e0f9c38c37814de1ec8552786cdf8d9ae302c8b3fa2f7521550958d49514035ee0ab293b4dd729c3eb371e730fde5e93aea379ce10f + "@opentelemetry/resources": ^1.30.1 || ^2.1.0 + "@opentelemetry/sdk-trace-base": ^1.30.1 || ^2.1.0 + "@opentelemetry/semantic-conventions": ^1.39.0 + peerDependenciesMeta: + "@opentelemetry/api": + optional: true + "@opentelemetry/context-async-hooks": + optional: true + "@opentelemetry/core": + optional: true + "@opentelemetry/instrumentation": + optional: true + "@opentelemetry/resources": + optional: true + "@opentelemetry/sdk-trace-base": + optional: true + "@opentelemetry/semantic-conventions": + optional: true + checksum: 10/cf2f8cd6b4852823b7ecb5c92bbbba6a621cab9cac4a2d15f163c861015a8935056b72f58b7d0bfced8ed36f3e328df087207e2fb88dd718359f927ce6940035 languageName: node linkType: hard -"@sentry/node@npm:10.29.0": - version: 10.29.0 - resolution: "@sentry/node@npm:10.29.0" +"@sentry/node@npm:10.40.0": + version: 10.40.0 + resolution: "@sentry/node@npm:10.40.0" dependencies: + "@fastify/otel": "npm:0.16.0" "@opentelemetry/api": "npm:^1.9.0" - "@opentelemetry/context-async-hooks": "npm:^2.2.0" - "@opentelemetry/core": "npm:^2.2.0" - "@opentelemetry/instrumentation": "npm:^0.208.0" - "@opentelemetry/instrumentation-amqplib": "npm:0.55.0" - "@opentelemetry/instrumentation-connect": "npm:0.52.0" - "@opentelemetry/instrumentation-dataloader": "npm:0.26.0" - "@opentelemetry/instrumentation-express": "npm:0.57.0" - "@opentelemetry/instrumentation-fs": "npm:0.28.0" - "@opentelemetry/instrumentation-generic-pool": "npm:0.52.0" - "@opentelemetry/instrumentation-graphql": "npm:0.56.0" - "@opentelemetry/instrumentation-hapi": "npm:0.55.0" - "@opentelemetry/instrumentation-http": "npm:0.208.0" - "@opentelemetry/instrumentation-ioredis": "npm:0.56.0" - "@opentelemetry/instrumentation-kafkajs": "npm:0.18.0" - "@opentelemetry/instrumentation-knex": "npm:0.53.0" - "@opentelemetry/instrumentation-koa": "npm:0.57.0" - "@opentelemetry/instrumentation-lru-memoizer": "npm:0.53.0" - "@opentelemetry/instrumentation-mongodb": "npm:0.61.0" - "@opentelemetry/instrumentation-mongoose": "npm:0.55.0" - "@opentelemetry/instrumentation-mysql": "npm:0.54.0" - "@opentelemetry/instrumentation-mysql2": "npm:0.55.0" - "@opentelemetry/instrumentation-pg": "npm:0.61.0" - "@opentelemetry/instrumentation-redis": "npm:0.57.0" - "@opentelemetry/instrumentation-tedious": "npm:0.27.0" - "@opentelemetry/instrumentation-undici": "npm:0.19.0" - "@opentelemetry/resources": "npm:^2.2.0" - "@opentelemetry/sdk-trace-base": "npm:^2.2.0" - "@opentelemetry/semantic-conventions": "npm:^1.37.0" - "@prisma/instrumentation": "npm:6.19.0" - "@sentry/core": "npm:10.29.0" - "@sentry/node-core": "npm:10.29.0" - "@sentry/opentelemetry": "npm:10.29.0" - import-in-the-middle: "npm:^2" - minimatch: "npm:^9.0.0" - checksum: 10/76fb7e83a16db29b37b7520800053ffe3418993fc58ff43e178477eae1c247a8a3968151534289bb764a81fa64b3d6d2c1f1cb10b59d240691e04316bbc95556 + "@opentelemetry/context-async-hooks": "npm:^2.5.1" + "@opentelemetry/core": "npm:^2.5.1" + "@opentelemetry/instrumentation": "npm:^0.211.0" + "@opentelemetry/instrumentation-amqplib": "npm:0.58.0" + "@opentelemetry/instrumentation-connect": "npm:0.54.0" + "@opentelemetry/instrumentation-dataloader": "npm:0.28.0" + "@opentelemetry/instrumentation-express": "npm:0.59.0" + "@opentelemetry/instrumentation-fs": "npm:0.30.0" + "@opentelemetry/instrumentation-generic-pool": "npm:0.54.0" + "@opentelemetry/instrumentation-graphql": "npm:0.58.0" + "@opentelemetry/instrumentation-hapi": "npm:0.57.0" + "@opentelemetry/instrumentation-http": "npm:0.211.0" + "@opentelemetry/instrumentation-ioredis": "npm:0.59.0" + "@opentelemetry/instrumentation-kafkajs": "npm:0.20.0" + "@opentelemetry/instrumentation-knex": "npm:0.55.0" + "@opentelemetry/instrumentation-koa": "npm:0.59.0" + "@opentelemetry/instrumentation-lru-memoizer": "npm:0.55.0" + "@opentelemetry/instrumentation-mongodb": "npm:0.64.0" + "@opentelemetry/instrumentation-mongoose": "npm:0.57.0" + "@opentelemetry/instrumentation-mysql": "npm:0.57.0" + "@opentelemetry/instrumentation-mysql2": "npm:0.57.0" + "@opentelemetry/instrumentation-pg": "npm:0.63.0" + "@opentelemetry/instrumentation-redis": "npm:0.59.0" + "@opentelemetry/instrumentation-tedious": "npm:0.30.0" + "@opentelemetry/instrumentation-undici": "npm:0.21.0" + "@opentelemetry/resources": "npm:^2.5.1" + "@opentelemetry/sdk-trace-base": "npm:^2.5.1" + "@opentelemetry/semantic-conventions": "npm:^1.39.0" + "@prisma/instrumentation": "npm:7.2.0" + "@sentry/core": "npm:10.40.0" + "@sentry/node-core": "npm:10.40.0" + "@sentry/opentelemetry": "npm:10.40.0" + import-in-the-middle: "npm:^2.0.6" + checksum: 10/8b18fcfef1923b203e9e37041ee57bcae3ec6418afc5a4fce6d65bd63652dfca9e6c7a1c4289243ff9051ccc5234119953e414f27e10032ca558e15cd32d9b85 languageName: node linkType: hard -"@sentry/opentelemetry@npm:10.29.0": - version: 10.29.0 - resolution: "@sentry/opentelemetry@npm:10.29.0" +"@sentry/opentelemetry@npm:10.40.0": + version: 10.40.0 + resolution: "@sentry/opentelemetry@npm:10.40.0" dependencies: - "@sentry/core": "npm:10.29.0" + "@sentry/core": "npm:10.40.0" peerDependencies: "@opentelemetry/api": ^1.9.0 - "@opentelemetry/context-async-hooks": ^1.30.1 || ^2.1.0 || ^2.2.0 - "@opentelemetry/core": ^1.30.1 || ^2.1.0 || ^2.2.0 - "@opentelemetry/sdk-trace-base": ^1.30.1 || ^2.1.0 || ^2.2.0 - "@opentelemetry/semantic-conventions": ^1.37.0 - checksum: 10/5937847cbca24980b2f14557bc21bae9f69561b4668897843456026564047d9f07b49f20efcea0b229355a4ffc5f0c1eaa379cfd188b627020a22d121b8e4c65 + "@opentelemetry/context-async-hooks": ^1.30.1 || ^2.1.0 + "@opentelemetry/core": ^1.30.1 || ^2.1.0 + "@opentelemetry/sdk-trace-base": ^1.30.1 || ^2.1.0 + "@opentelemetry/semantic-conventions": ^1.39.0 + checksum: 10/cadf8c01167cdb9f61f7ad467fd53af9962df9a16ab1058644e02267f4dcfe7f061b3c12081e90c7edb94f0d3e4431acbf131d0c9cdf341f14cd8b7e9202e5d9 languageName: node linkType: hard -"@sentry/react@npm:^9.47.1": - version: 9.47.1 - resolution: "@sentry/react@npm:9.47.1" +"@sentry/react@npm:^10.40.0": + version: 10.40.0 + resolution: "@sentry/react@npm:10.40.0" dependencies: - "@sentry/browser": "npm:9.47.1" - "@sentry/core": "npm:9.47.1" - hoist-non-react-statics: "npm:^3.3.2" + "@sentry/browser": "npm:10.40.0" + "@sentry/core": "npm:10.40.0" peerDependencies: react: ^16.14.0 || 17.x || 18.x || 19.x - checksum: 10/696db0516810ba36a84c946fbbe8e938944c8e861da749e2d0aa1a3f7af846e13c5f458ee1dc3bf2be20c6c2dfb7ac4614e57a022281195c4931856d96cc9435 + checksum: 10/f18e4c223310a359baccc1f7e882624b3d52e3d27888cf5cc9b6b35d0d241fbfd782f6ed318e5db8352ef6960de88d5e0ffe1f29e572068663cad672b3f8fe70 languageName: node linkType: hard -"@sentry/webpack-plugin@npm:^4.0.0": - version: 4.8.0 - resolution: "@sentry/webpack-plugin@npm:4.8.0" +"@sentry/webpack-plugin@npm:^5.1.1": + version: 5.1.1 + resolution: "@sentry/webpack-plugin@npm:5.1.1" dependencies: - "@sentry/bundler-plugin-core": "npm:4.8.0" - unplugin: "npm:1.0.1" + "@sentry/bundler-plugin-core": "npm:5.1.1" uuid: "npm:^9.0.0" peerDependencies: - webpack: ">=4.40.0" - checksum: 10/d29568e272a3b5d4a3099ca2925ff8fa2a155b0896dfca2bd0a3b7ebaa7c6f516ed4e1f9a407045d20db90a741927a35140d9327d6bd9e0b2369498220072011 + webpack: ">=5.0.0" + checksum: 10/f1b3ccad6a0acbfe7062d2de43baa810abb9c6dfc5236e6965e33a6e312f963574f78b656b154141d26705c6eeee9f1c50f5f22f65168a9728b46edba2e0aa1e languageName: node linkType: hard @@ -16791,7 +16661,7 @@ __metadata: languageName: node linkType: hard -"@types/express@npm:^4.17.13, @types/express@npm:^4.17.21, @types/express@npm:^4.17.25": +"@types/express@npm:^4.17.13, @types/express@npm:^4.17.25": version: 4.17.25 resolution: "@types/express@npm:4.17.25" dependencies: @@ -17219,12 +17089,12 @@ __metadata: languageName: node linkType: hard -"@types/pg-pool@npm:2.0.6": - version: 2.0.6 - resolution: "@types/pg-pool@npm:2.0.6" +"@types/pg-pool@npm:2.0.7": + version: 2.0.7 + resolution: "@types/pg-pool@npm:2.0.7" dependencies: "@types/pg": "npm:*" - checksum: 10/cc54ce97115effc982bd052f79901a78215e76554aca0ecc92e78eb907e4fb2962924039369cd9aaf48075f1637593ce14647c62d3a2eb03789ce5d1c6df750b + checksum: 10/b2ac51f1e98cd97ef8ee9c09f4db6bb369dfa406dc41533b13a3b7c6e3a5c8c1d52ee139f8bc453b5b5c0125d1fedea610c230696a722ec9176076455e6f267a languageName: node linkType: hard @@ -17461,13 +17331,6 @@ __metadata: languageName: node linkType: hard -"@types/webpack-env@npm:^1.18.5": - version: 1.18.8 - resolution: "@types/webpack-env@npm:1.18.8" - checksum: 10/f3932f3d6c2530f644cfc898eda1ab8182d6ae57f555c2f0179d813549b639078671b71e4041831fc306c5ebe61f5cdac794fe4ceae281fce8bf67e23661a488 - languageName: node - linkType: hard - "@types/whatwg-mimetype@npm:^3.0.2": version: 3.0.2 resolution: "@types/whatwg-mimetype@npm:3.0.2" @@ -18396,7 +18259,7 @@ __metadata: languageName: node linkType: hard -"acorn-walk@npm:^8.2.0, acorn-walk@npm:^8.3.4": +"acorn-walk@npm:^8.3.4": version: 8.3.4 resolution: "acorn-walk@npm:8.3.4" dependencies: @@ -18405,7 +18268,7 @@ __metadata: languageName: node linkType: hard -"acorn@npm:^8.11.0, acorn@npm:^8.14.0, acorn@npm:^8.15.0, acorn@npm:^8.6.0, acorn@npm:^8.7.1, acorn@npm:^8.8.1, acorn@npm:^8.8.2": +"acorn@npm:^8.11.0, acorn@npm:^8.14.0, acorn@npm:^8.15.0, acorn@npm:^8.6.0, acorn@npm:^8.8.2": version: 8.15.0 resolution: "acorn@npm:8.15.0" bin: @@ -18535,7 +18398,7 @@ __metadata: languageName: node linkType: hard -"ajv@npm:^8.0.0, ajv@npm:^8.0.1, ajv@npm:^8.11.0, ajv@npm:^8.17.1, ajv@npm:^8.9.0": +"ajv@npm:^8.0.0, ajv@npm:^8.11.0, ajv@npm:^8.17.1, ajv@npm:^8.9.0": version: 8.18.0 resolution: "ajv@npm:8.18.0" dependencies: @@ -20136,10 +19999,10 @@ __metadata: languageName: node linkType: hard -"cjs-module-lexer@npm:^1.2.2": - version: 1.4.3 - resolution: "cjs-module-lexer@npm:1.4.3" - checksum: 10/d2b92f919a2dedbfd61d016964fce8da0035f827182ed6839c97cac56e8a8077cfa6a59388adfe2bc588a19cef9bbe830d683a76a6e93c51f65852062cfe2591 +"cjs-module-lexer@npm:^2.2.0": + version: 2.2.0 + resolution: "cjs-module-lexer@npm:2.2.0" + checksum: 10/fc8eb5c1919504366d8260a150d93c4e857740e770467dc59ca0cc34de4b66c93075559a5af65618f359187866b1be40e036f4e1a1bab2f1e06001c216415f74 languageName: node linkType: hard @@ -20324,17 +20187,6 @@ __metadata: languageName: node linkType: hard -"clone-deep@npm:^4.0.1": - version: 4.0.1 - resolution: "clone-deep@npm:4.0.1" - dependencies: - is-plain-object: "npm:^2.0.4" - kind-of: "npm:^6.0.2" - shallow-clone: "npm:^3.0.0" - checksum: 10/770f912fe4e6f21873c8e8fbb1e99134db3b93da32df271d00589ea4a29dbe83a9808a322c93f3bcaf8584b8b4fa6fc269fc8032efbaa6728e0c9886c74467d2 - languageName: node - linkType: hard - "clone-response@npm:^1.0.2": version: 1.0.3 resolution: "clone-response@npm:1.0.3" @@ -20594,13 +20446,6 @@ __metadata: languageName: node linkType: hard -"commondir@npm:^1.0.1": - version: 1.0.1 - resolution: "commondir@npm:1.0.1" - checksum: 10/4620bc4936a4ef12ce7dfcd272bb23a99f2ad68889a4e4ad766c9f8ad21af982511934d6f7050d4a8bde90011b1c15d56e61a1b4576d9913efbf697a20172d6c - languageName: node - linkType: hard - "compare-func@npm:^2.0.0": version: 2.0.0 resolution: "compare-func@npm:2.0.0" @@ -20643,7 +20488,7 @@ __metadata: languageName: node linkType: hard -"compression@npm:1.8.1, compression@npm:^1.7.4, compression@npm:^1.8.1": +"compression@npm:1.8.1, compression@npm:^1.8.1": version: 1.8.1 resolution: "compression@npm:1.8.1" dependencies: @@ -20876,21 +20721,6 @@ __metadata: languageName: node linkType: hard -"copy-webpack-plugin@npm:^13.0.0": - version: 13.0.0 - resolution: "copy-webpack-plugin@npm:13.0.0" - dependencies: - glob-parent: "npm:^6.0.1" - normalize-path: "npm:^3.0.0" - schema-utils: "npm:^4.2.0" - serialize-javascript: "npm:^6.0.2" - tinyglobby: "npm:^0.2.12" - peerDependencies: - webpack: ^5.1.0 - checksum: 10/209051dd3c0bc7ab97170309cdb1826e642044d2d53e0adc35bb227123c89ae1296a504409325e9b955d7b2d1a505b063f0023e924151d382dbcc92cb9325e6a - languageName: node - linkType: hard - "core-js-compat@npm:^3.46.0": version: 3.48.0 resolution: "core-js-compat@npm:3.48.0" @@ -21806,18 +21636,6 @@ __metadata: languageName: node linkType: hard -"debug@npm:4.3.4": - version: 4.3.4 - resolution: "debug@npm:4.3.4" - dependencies: - ms: "npm:2.1.2" - peerDependenciesMeta: - supports-color: - optional: true - checksum: 10/0073c3bcbd9cb7d71dd5f6b55be8701af42df3e56e911186dfa46fac3a5b9eb7ce7f377dd1d3be6db8977221f8eb333d945216f645cf56f6b688cd484837d255 - languageName: node - linkType: hard - "debug@npm:~4.3.1, debug@npm:~4.3.4": version: 4.3.7 resolution: "debug@npm:4.3.7" @@ -21862,13 +21680,6 @@ __metadata: languageName: node linkType: hard -"decode-uri-component@npm:^0.2.2": - version: 0.2.2 - resolution: "decode-uri-component@npm:0.2.2" - checksum: 10/17a0e5fa400bf9ea84432226e252aa7b5e72793e16bf80b907c99b46a799aeacc139ec20ea57121e50c7bd875a1a4365928f884e92abf02e21a5a13790a0f33e - languageName: node - linkType: hard - "decode-uri-component@npm:^0.4.1": version: 0.4.1 resolution: "decode-uri-component@npm:0.4.1" @@ -22756,17 +22567,6 @@ __metadata: languageName: node linkType: hard -"env-ci@npm:^7.2.1": - version: 7.3.0 - resolution: "env-ci@npm:7.3.0" - dependencies: - execa: "npm:^5.0.0" - fromentries: "npm:^1.3.2" - java-properties: "npm:^1.0.0" - checksum: 10/b270f6b17d89558899e895235fc3a241d2f5e43a5df4ea40bbf65131469dcd9fa5e3495395faf0cc83b6e277e6ef7dca7e15e21d619342647153b97d59583e94 - languageName: node - linkType: hard - "env-paths@npm:^2.2.0, env-paths@npm:^2.2.1": version: 2.2.1 resolution: "env-paths@npm:2.2.1" @@ -23518,7 +23318,7 @@ __metadata: languageName: node linkType: hard -"execa@npm:^5.0.0, execa@npm:^5.1.1": +"execa@npm:^5.1.1": version: 5.1.1 resolution: "execa@npm:5.1.1" dependencies: @@ -23625,7 +23425,7 @@ __metadata: languageName: node linkType: hard -"express@npm:^4.21.1, express@npm:^4.21.2, express@npm:^4.22.1": +"express@npm:^4.21.1, express@npm:^4.22.1": version: 4.22.1 resolution: "express@npm:4.22.1" dependencies: @@ -23991,13 +23791,6 @@ __metadata: languageName: node linkType: hard -"filter-obj@npm:^1.1.0": - version: 1.1.0 - resolution: "filter-obj@npm:1.1.0" - checksum: 10/9d681939eec2b4b129cb4f307b7e93d954a0657421d4e5357d86093b26d3f4f570909ed43717dcfd62428b3cf8cddd9841b35f9d40d12ac62cfabaa677942593 - languageName: node - linkType: hard - "filter-obj@npm:^5.1.0": version: 5.1.0 resolution: "filter-obj@npm:5.1.0" @@ -24034,17 +23827,6 @@ __metadata: languageName: node linkType: hard -"find-cache-dir@npm:^3.3.2": - version: 3.3.2 - resolution: "find-cache-dir@npm:3.3.2" - dependencies: - commondir: "npm:^1.0.1" - make-dir: "npm:^3.0.2" - pkg-dir: "npm:^4.1.0" - checksum: 10/3907c2e0b15132704ed67083686cd3e68ab7d9ecc22e50ae9da20678245d488b01fa22c0e34c0544dc6edc4354c766f016c8c186a787be7c17f7cde8c5281e85 - languageName: node - linkType: hard - "find-root@npm:^1.1.0": version: 1.1.0 resolution: "find-root@npm:1.1.0" @@ -24068,7 +23850,7 @@ __metadata: languageName: node linkType: hard -"find-up@npm:^4.0.0, find-up@npm:^4.1.0": +"find-up@npm:^4.1.0": version: 4.1.0 resolution: "find-up@npm:4.1.0" dependencies: @@ -24109,15 +23891,6 @@ __metadata: languageName: node linkType: hard -"flat@npm:^5.0.2": - version: 5.0.2 - resolution: "flat@npm:5.0.2" - bin: - flat: cli.js - checksum: 10/72479e651c15eab53e25ce04c31bab18cfaac0556505cac19221dbbe85bbb9686bc76e4d397e89e5bf516ce667dcf818f8b07e585568edba55abc2bf1f698fb5 - languageName: node - linkType: hard - "flatted@npm:^3.2.9, flatted@npm:^3.3.3": version: 3.3.3 resolution: "flatted@npm:3.3.3" @@ -24261,13 +24034,6 @@ __metadata: languageName: node linkType: hard -"fromentries@npm:^1.3.2": - version: 1.3.2 - resolution: "fromentries@npm:1.3.2" - checksum: 10/10d6e07d289db102c0c1eaf5c3e3fa55ddd6b50033d7de16d99a7cd89f1e1a302dfadb26457031f9bb5d2ed95a179aaf0396092dde5abcae06e8a2f0476826be - languageName: node - linkType: hard - "fs-capacitor@npm:^8.0.0": version: 8.0.0 resolution: "fs-capacitor@npm:8.0.0" @@ -24703,7 +24469,7 @@ __metadata: languageName: node linkType: hard -"glob-parent@npm:^6.0.1, glob-parent@npm:^6.0.2": +"glob-parent@npm:^6.0.2": version: 6.0.2 resolution: "glob-parent@npm:6.0.2" dependencies: @@ -24719,7 +24485,7 @@ __metadata: languageName: node linkType: hard -"glob@npm:^10.0.0, glob@npm:^10.2.2, glob@npm:^10.4.1, glob@npm:^10.4.5, glob@npm:^10.5.0": +"glob@npm:^10.0.0, glob@npm:^10.2.2, glob@npm:^10.4.1, glob@npm:^10.4.5": version: 10.5.0 resolution: "glob@npm:10.5.0" dependencies: @@ -24751,7 +24517,7 @@ __metadata: languageName: node linkType: hard -"glob@npm:^13.0.1": +"glob@npm:^13.0.1, glob@npm:^13.0.6": version: 13.0.6 resolution: "glob@npm:13.0.6" dependencies: @@ -25306,7 +25072,7 @@ __metadata: languageName: node linkType: hard -"hoist-non-react-statics@npm:^3.3.1, hoist-non-react-statics@npm:^3.3.2": +"hoist-non-react-statics@npm:^3.3.1": version: 3.3.2 resolution: "hoist-non-react-statics@npm:3.3.2" dependencies: @@ -25580,7 +25346,7 @@ __metadata: languageName: node linkType: hard -"http-proxy-middleware@npm:^2.0.7, http-proxy-middleware@npm:^2.0.9": +"http-proxy-middleware@npm:^2.0.9": version: 2.0.9 resolution: "http-proxy-middleware@npm:2.0.9" dependencies: @@ -25856,15 +25622,15 @@ __metadata: languageName: node linkType: hard -"import-in-the-middle@npm:^2, import-in-the-middle@npm:^2.0.0": - version: 2.0.0 - resolution: "import-in-the-middle@npm:2.0.0" +"import-in-the-middle@npm:^2.0.0, import-in-the-middle@npm:^2.0.6": + version: 2.0.6 + resolution: "import-in-the-middle@npm:2.0.6" dependencies: - acorn: "npm:^8.14.0" + acorn: "npm:^8.15.0" acorn-import-attributes: "npm:^1.9.5" - cjs-module-lexer: "npm:^1.2.2" - module-details-from-path: "npm:^1.0.3" - checksum: 10/badb8359552f1e9fedc8569299dd1937e802256ce0fe6aa9cb348bca6f217f06e16a3ca46f889bfcb66028a096a1956674d257de9e809db4271ca0e508521c30 + cjs-module-lexer: "npm:^2.2.0" + module-details-from-path: "npm:^1.0.4" + checksum: 10/8be80d7f2d4ad34e5eb1082925ee2e90844edb65359cad0f5d8e934a09fafeca10e66f50d0b07570bd6b877ff678755d3c2d36d05258cc3541e39fa6aae6ae56 languageName: node linkType: hard @@ -26382,15 +26148,6 @@ __metadata: languageName: node linkType: hard -"is-plain-object@npm:^2.0.4": - version: 2.0.4 - resolution: "is-plain-object@npm:2.0.4" - dependencies: - isobject: "npm:^3.0.1" - checksum: 10/2a401140cfd86cabe25214956ae2cfee6fbd8186809555cd0e84574f88de7b17abacb2e477a6a658fa54c6083ecbda1e6ae404c7720244cd198903848fca70ca - languageName: node - linkType: hard - "is-plain-object@npm:^5.0.0": version: 5.0.0 resolution: "is-plain-object@npm:5.0.0" @@ -26566,13 +26323,6 @@ __metadata: languageName: node linkType: hard -"isobject@npm:^3.0.1": - version: 3.0.1 - resolution: "isobject@npm:3.0.1" - checksum: 10/db85c4c970ce30693676487cca0e61da2ca34e8d4967c2e1309143ff910c207133a969f9e4ddb2dc6aba670aabce4e0e307146c310350b298e74a31f7d464703 - languageName: node - linkType: hard - "isomorphic-ws@npm:^5.0.0": version: 5.0.0 resolution: "isomorphic-ws@npm:5.0.0" @@ -26691,13 +26441,6 @@ __metadata: languageName: node linkType: hard -"java-properties@npm:^1.0.0": - version: 1.0.2 - resolution: "java-properties@npm:1.0.2" - checksum: 10/d6e8bf8a28a8782afadbcebf2504ab8ea2c75d3675d7eec470920f6c056fd90c8a35a2705cd492a07ec3b2309d3d848ff4cfae098a2cda33a922153eed4bef6a - languageName: node - linkType: hard - "javascript-stringify@npm:^2.0.1": version: 2.1.0 resolution: "javascript-stringify@npm:2.1.0" @@ -27118,13 +26861,6 @@ __metadata: languageName: node linkType: hard -"kind-of@npm:^6.0.2": - version: 6.0.3 - resolution: "kind-of@npm:6.0.3" - checksum: 10/5873d303fb36aad875b7538798867da2ae5c9e328d67194b0162a3659a627d22f742fc9c4ae95cd1704132a24b00cae5041fc00c0f6ef937dc17080dc4dbb962 - languageName: node - linkType: hard - "kleur@npm:^3.0.3": version: 3.0.3 resolution: "kleur@npm:3.0.3" @@ -27763,13 +27499,6 @@ __metadata: languageName: node linkType: hard -"lodash.truncate@npm:^4.4.2": - version: 4.4.2 - resolution: "lodash.truncate@npm:4.4.2" - checksum: 10/7a495616121449e5d2288c606b1025d42ab9979e8c93ba885e5c5802ffd4f1ebad4428c793ccc12f73e73237e85a9f5b67dd6415757546fbd5a4653ba83e25ac - languageName: node - linkType: hard - "lodash.uniq@npm:^4.5.0": version: 4.5.0 resolution: "lodash.uniq@npm:4.5.0" @@ -28064,16 +27793,7 @@ __metadata: languageName: node linkType: hard -"magic-string@npm:0.30.8": - version: 0.30.8 - resolution: "magic-string@npm:0.30.8" - dependencies: - "@jridgewell/sourcemap-codec": "npm:^1.4.15" - checksum: 10/72ab63817af600e92c19dc8489c1aa4a9599da00cfd59b2319709bd48fb0cf533fdf354bf140ac86e598dbd63e6b2cc83647fe8448f864a3eb6061c62c94e784 - languageName: node - linkType: hard - -"magic-string@npm:^0.30.0, magic-string@npm:^0.30.17, magic-string@npm:^0.30.21": +"magic-string@npm:^0.30.0, magic-string@npm:^0.30.17, magic-string@npm:^0.30.21, magic-string@npm:~0.30.8": version: 0.30.21 resolution: "magic-string@npm:0.30.21" dependencies: @@ -28093,15 +27813,6 @@ __metadata: languageName: node linkType: hard -"make-dir@npm:^3.0.2": - version: 3.1.0 - resolution: "make-dir@npm:3.1.0" - dependencies: - semver: "npm:^6.0.0" - checksum: 10/484200020ab5a1fdf12f393fe5f385fc8e4378824c940fba1729dcd198ae4ff24867bc7a5646331e50cead8abff5d9270c456314386e629acec6dff4b8016b78 - languageName: node - linkType: hard - "make-dir@npm:^4.0.0": version: 4.0.0 resolution: "make-dir@npm:4.0.0" @@ -29056,18 +28767,6 @@ __metadata: languageName: node linkType: hard -"mini-css-extract-plugin@npm:^2.9.2": - version: 2.9.2 - resolution: "mini-css-extract-plugin@npm:2.9.2" - dependencies: - schema-utils: "npm:^4.0.0" - tapable: "npm:^2.2.1" - peerDependencies: - webpack: ^5.0.0 - checksum: 10/db6ddb8ba56affa1a295b57857d66bad435d36e48e1f95c75d16fadd6c70e3ba33e8c4141c3fb0e22b4d875315b41c4f58550c6ac73b50bdbe429f768297e3ff - languageName: node - linkType: hard - "minimalistic-assert@npm:^1.0.0": version: 1.0.1 resolution: "minimalistic-assert@npm:1.0.1" @@ -29120,16 +28819,7 @@ __metadata: languageName: node linkType: hard -"minimatch@npm:^7.4.6": - version: 7.4.9 - resolution: "minimatch@npm:7.4.9" - dependencies: - brace-expansion: "npm:^2.0.2" - checksum: 10/9bc60b593dafb71d68b1a671a0c1a4bb9a71ef2f8daa8ed4b8b6199bb2d522163fb2e94d82ca40518eaa3b00218f587ad7ab2ed40e56e4c57a8bddb6c2bd1d27 - languageName: node - linkType: hard - -"minimatch@npm:^9.0.0, minimatch@npm:^9.0.3, minimatch@npm:^9.0.4, minimatch@npm:^9.0.5": +"minimatch@npm:^9.0.3, minimatch@npm:^9.0.4, minimatch@npm:^9.0.5": version: 9.0.9 resolution: "minimatch@npm:9.0.9" dependencies: @@ -29346,13 +29036,6 @@ __metadata: languageName: node linkType: hard -"ms@npm:2.1.2": - version: 2.1.2 - resolution: "ms@npm:2.1.2" - checksum: 10/673cdb2c3133eb050c745908d8ce632ed2c02d85640e2edb3ace856a2266a813b30c613569bf3354fdf4ea7d1a1494add3bfa95e2713baa27d0c2c71fc44f58f - languageName: node - linkType: hard - "ms@npm:2.1.3, ms@npm:^2.0.0, ms@npm:^2.1.1, ms@npm:^2.1.3": version: 2.1.3 resolution: "ms@npm:2.1.3" @@ -29727,7 +29410,7 @@ __metadata: languageName: node linkType: hard -"node-fetch@npm:^2.6.2, node-fetch@npm:^2.6.7, node-fetch@npm:^2.6.9, node-fetch@npm:^2.7.0": +"node-fetch@npm:^2.6.7, node-fetch@npm:^2.6.9, node-fetch@npm:^2.7.0": version: 2.7.0 resolution: "node-fetch@npm:2.7.0" dependencies: @@ -30206,7 +29889,7 @@ __metadata: languageName: node linkType: hard -"open@npm:^8.4.0, open@npm:^8.4.2": +"open@npm:^8.4.0": version: 8.4.2 resolution: "open@npm:8.4.2" dependencies: @@ -31070,15 +30753,6 @@ __metadata: languageName: node linkType: hard -"pkg-dir@npm:^4.1.0": - version: 4.2.0 - resolution: "pkg-dir@npm:4.2.0" - dependencies: - find-up: "npm:^4.0.0" - checksum: 10/9863e3f35132bf99ae1636d31ff1e1e3501251d480336edb1c211133c8d58906bed80f154a1d723652df1fda91e01c7442c2eeaf9dc83157c7ae89087e43c8d6 - languageName: node - linkType: hard - "pkg-types@npm:^1.2.0, pkg-types@npm:^1.3.0, pkg-types@npm:^1.3.1": version: 1.3.1 resolution: "pkg-types@npm:1.3.1" @@ -31897,18 +31571,6 @@ __metadata: languageName: node linkType: hard -"query-string@npm:^7.1.1": - version: 7.1.3 - resolution: "query-string@npm:7.1.3" - dependencies: - decode-uri-component: "npm:^0.2.2" - filter-obj: "npm:^1.1.0" - split-on-first: "npm:^1.0.0" - strict-uri-encode: "npm:^2.0.0" - checksum: 10/3b6f2c167e76ca4094c5f1a9eb276efcbb9ebfd8b1a28c413f3c4e4e7d6428c8187bf46c8cbc9f92a229369dd0015de10a7fd712c8cee98d5d84c2ac6140357e - languageName: node - linkType: hard - "query-string@npm:^9.1.1": version: 9.2.0 resolution: "query-string@npm:9.2.0" @@ -33547,7 +33209,7 @@ __metadata: languageName: node linkType: hard -"semver@npm:^6.0.0, semver@npm:^6.2.0, semver@npm:^6.3.1": +"semver@npm:^6.2.0, semver@npm:^6.3.1": version: 6.3.1 resolution: "semver@npm:6.3.1" bin: @@ -33770,15 +33432,6 @@ __metadata: languageName: node linkType: hard -"shallow-clone@npm:^3.0.0": - version: 3.0.1 - resolution: "shallow-clone@npm:3.0.1" - dependencies: - kind-of: "npm:^6.0.2" - checksum: 10/e066bd540cfec5e1b0f78134853e0d892d1c8945fb9a926a579946052e7cb0c70ca4fc34f875a8083aa7910d751805d36ae64af250a6de6f3d28f9fa7be6c21b - languageName: node - linkType: hard - "shebang-command@npm:^1.2.0": version: 1.2.0 resolution: "shebang-command@npm:1.2.0" @@ -33869,17 +33522,6 @@ __metadata: languageName: node linkType: hard -"simple-git@npm:3.15.0": - version: 3.15.0 - resolution: "simple-git@npm:3.15.0" - dependencies: - "@kwsites/file-exists": "npm:^1.1.1" - "@kwsites/promise-deferred": "npm:^1.1.1" - debug: "npm:^4.3.4" - checksum: 10/36739621c0dc76eb72f94364ed74211bbb8a10872effe212052be21f3035256d32e20261e6093561413501435864719b0664cdb21c01c392cda1b08b4ea4b6ae - languageName: node - linkType: hard - "simple-swizzle@npm:^0.2.2": version: 0.2.2 resolution: "simple-swizzle@npm:0.2.2" @@ -34227,13 +33869,6 @@ __metadata: languageName: node linkType: hard -"split-on-first@npm:^1.0.0": - version: 1.1.0 - resolution: "split-on-first@npm:1.1.0" - checksum: 10/16ff85b54ddcf17f9147210a4022529b343edbcbea4ce977c8f30e38408b8d6e0f25f92cd35b86a524d4797f455e29ab89eb8db787f3c10708e0b47ebf528d30 - languageName: node - linkType: hard - "split-on-first@npm:^3.0.0": version: 3.0.0 resolution: "split-on-first@npm:3.0.0" @@ -34416,13 +34051,6 @@ __metadata: languageName: node linkType: hard -"strict-uri-encode@npm:^2.0.0": - version: 2.0.0 - resolution: "strict-uri-encode@npm:2.0.0" - checksum: 10/eaac4cf978b6fbd480f1092cab8b233c9b949bcabfc9b598dd79a758f7243c28765ef7639c876fa72940dac687181b35486ea01ff7df3e65ce3848c64822c581 - languageName: node - linkType: hard - "string-argv@npm:^0.3.2": version: 0.3.2 resolution: "string-argv@npm:0.3.2" @@ -34873,19 +34501,6 @@ __metadata: languageName: node linkType: hard -"table@npm:^6.8.0": - version: 6.9.0 - resolution: "table@npm:6.9.0" - dependencies: - ajv: "npm:^8.0.1" - lodash.truncate: "npm:^4.4.2" - slice-ansi: "npm:^4.0.0" - string-width: "npm:^4.2.3" - strip-ansi: "npm:^6.0.1" - checksum: 10/976da6d89841566e39628d1ba107ffab126964c9390a0a877a7c54ebb08820bf388d28fe9f8dcf354b538f19634a572a506c38a3762081640013a149cc862af9 - languageName: node - linkType: hard - "tagged-tag@npm:^1.0.0": version: 1.0.0 resolution: "tagged-tag@npm:1.0.0" @@ -34923,7 +34538,7 @@ __metadata: languageName: node linkType: hard -"tapable@npm:^2.0.0, tapable@npm:^2.2.1, tapable@npm:^2.3.0": +"tapable@npm:^2.0.0, tapable@npm:^2.3.0": version: 2.3.0 resolution: "tapable@npm:2.3.0" checksum: 10/496a841039960533bb6e44816a01fffc2a1eb428bb2051ecab9e87adf07f19e1f937566cbbbb09dceff31163c0ffd81baafcad84db900b601f0155dd0b37e9f2 @@ -34984,7 +34599,7 @@ __metadata: languageName: node linkType: hard -"terser-webpack-plugin@npm:^5.3.10, terser-webpack-plugin@npm:^5.3.16": +"terser-webpack-plugin@npm:^5.3.16": version: 5.3.16 resolution: "terser-webpack-plugin@npm:5.3.16" dependencies: @@ -35949,18 +35564,6 @@ __metadata: languageName: node linkType: hard -"unplugin@npm:1.0.1": - version: 1.0.1 - resolution: "unplugin@npm:1.0.1" - dependencies: - acorn: "npm:^8.8.1" - chokidar: "npm:^3.5.3" - webpack-sources: "npm:^3.2.3" - webpack-virtual-modules: "npm:^0.5.0" - checksum: 10/59f0d29c634adbc56e7e770f9753bff9ec52c479ff837b798354ec5d1b2e8cb971412645df43eb14a698db5bff4db23634c1506657e24d1ba86f4a8f27c1bf87 - languageName: node - linkType: hard - "unplugin@npm:^2.3.11, unplugin@npm:^2.3.5": version: 2.3.11 resolution: "unplugin@npm:2.3.11" @@ -36667,76 +36270,13 @@ __metadata: languageName: node linkType: hard -"webpack-dev-server@npm:^5.2.0": - version: 5.2.1 - resolution: "webpack-dev-server@npm:5.2.1" - dependencies: - "@types/bonjour": "npm:^3.5.13" - "@types/connect-history-api-fallback": "npm:^1.5.4" - "@types/express": "npm:^4.17.21" - "@types/express-serve-static-core": "npm:^4.17.21" - "@types/serve-index": "npm:^1.9.4" - "@types/serve-static": "npm:^1.15.5" - "@types/sockjs": "npm:^0.3.36" - "@types/ws": "npm:^8.5.10" - ansi-html-community: "npm:^0.0.8" - bonjour-service: "npm:^1.2.1" - chokidar: "npm:^3.6.0" - colorette: "npm:^2.0.10" - compression: "npm:^1.7.4" - connect-history-api-fallback: "npm:^2.0.0" - express: "npm:^4.21.2" - graceful-fs: "npm:^4.2.6" - http-proxy-middleware: "npm:^2.0.7" - ipaddr.js: "npm:^2.1.0" - launch-editor: "npm:^2.6.1" - open: "npm:^10.0.3" - p-retry: "npm:^6.2.0" - schema-utils: "npm:^4.2.0" - selfsigned: "npm:^2.4.1" - serve-index: "npm:^1.9.1" - sockjs: "npm:^0.3.24" - spdy: "npm:^4.0.2" - webpack-dev-middleware: "npm:^7.4.2" - ws: "npm:^8.18.0" - peerDependencies: - webpack: ^5.0.0 - peerDependenciesMeta: - webpack: - optional: true - webpack-cli: - optional: true - bin: - webpack-dev-server: bin/webpack-dev-server.js - checksum: 10/424edfe22b7bbe2301a38b8b519dfeb7643e0ca643be01af3fa48ec18512955c1952246741d7577bdb911ee09dcd6c521ade7d65e0059448ee69ab02bfac4624 - languageName: node - linkType: hard - -"webpack-merge@npm:^6.0.1": - version: 6.0.1 - resolution: "webpack-merge@npm:6.0.1" - dependencies: - clone-deep: "npm:^4.0.1" - flat: "npm:^5.0.2" - wildcard: "npm:^2.0.1" - checksum: 10/39ab911c26237922295d9b3d0617c8ea0c438c35a3b21b05506616a10423f5ece1962bccbedec932c5db61af57999b6d055d56d1f1755c63e2701bd4a55c3887 - languageName: node - linkType: hard - -"webpack-sources@npm:^3.2.3, webpack-sources@npm:^3.3.3": +"webpack-sources@npm:^3.3.3": version: 3.3.3 resolution: "webpack-sources@npm:3.3.3" checksum: 10/ec5d72607e8068467370abccbfff855c596c098baedbe9d198a557ccf198e8546a322836a6f74241492576adba06100286592993a62b63196832cdb53c8bae91 languageName: node linkType: hard -"webpack-virtual-modules@npm:^0.5.0": - version: 0.5.0 - resolution: "webpack-virtual-modules@npm:0.5.0" - checksum: 10/65a8f90c7e6609ba1c4ad2697bb83ae662485893fb545f6aa9a74e3a5d7485bbc50ef057c5bc3feca25d3153ebf9c097c233cbe4d67b52418bc84348dfb20c1a - languageName: node - linkType: hard - "webpack-virtual-modules@npm:^0.6.2": version: 0.6.2 resolution: "webpack-virtual-modules@npm:0.6.2" @@ -36744,7 +36284,7 @@ __metadata: languageName: node linkType: hard -"webpack@npm:^5.102.1, webpack@npm:^5.69.1": +"webpack@npm:^5.69.1": version: 5.105.2 resolution: "webpack@npm:5.105.2" dependencies: @@ -36901,13 +36441,6 @@ __metadata: languageName: node linkType: hard -"wildcard@npm:^2.0.1": - version: 2.0.1 - resolution: "wildcard@npm:2.0.1" - checksum: 10/e0c60a12a219e4b12065d1199802d81c27b841ed6ad6d9d28240980c73ceec6f856771d575af367cbec2982d9ae7838759168b551776577f155044f5a5ba843c - languageName: node - linkType: hard - "winston-transport@npm:^4.9.0": version: 4.9.0 resolution: "winston-transport@npm:4.9.0" From 2e95d91093136eb7184a089c2916062c80e1bc02 Mon Sep 17 00:00:00 2001 From: GyeongSu Han Date: Sun, 1 Mar 2026 23:32:28 +0900 Subject: [PATCH 08/49] fix: restore Accept header and prevent encoded response in GitHub OAuth token request (regression from #14061) (#14538) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## 📝 Summary This PR fixes a regression that caused the following error during GitHub OAuth login: > Unable to parse JSON response from [https://github.com/login/oauth/access_token](https://github.com/login/oauth/access_token) Related issue: [https://github.com/toeverything/AFFiNE/issues/14334](https://github.com/toeverything/AFFiNE/issues/14334) Regression introduced in: [https://github.com/toeverything/AFFiNE/pull/14061](https://github.com/toeverything/AFFiNE/pull/14061) --- ## 🎯 Background GitHub’s OAuth access token endpoint returns different response formats depending on the request headers. To receive a JSON response, the request must include: ``` Accept: application/json ``` If the `Accept` header is missing, GitHub responds with: ``` application/x-www-form-urlencoded ``` The current implementation assumes a JSON response and parses it directly. When a non-JSON response is returned, JSON parsing fails, breaking the OAuth login flow. --- ## 🔍 Traffic Analysis (tcpdump) Network path: affine-graphql → (HTTPS) → envoy → (HTTP, tcpdump) → envoy → GitHub ### Observed Request ``` POST /login/oauth/access_token HTTP/1.1 host: github-proxy.com content-type: application/x-www-form-urlencoded accept: */* ... ``` ### Observed Response ``` HTTP/1.1 200 OK date: Sat, 28 Feb 2026 14:47:43 GMT content-type: application/x-www-form-urlencoded; charset=utf-8 ... ``` The `Accept` header was `*/*` instead of `application/json`, causing GitHub to return a form-urlencoded response. --- ## 🐛 Root Cause PR #14061 introduced a side effect in the request configuration. Although the `Accept` header was initially defined, the request options were later overwritten by the `init` parameter. Because `init.headers` replaced the previously defined headers object, the required header was lost. Resulting in: * Missing `Accept: application/json` * GitHub returning `application/x-www-form-urlencoded` * JSON parsing failure * OAuth login failure --- ## 🔧 Changes ### 1️⃣ Fix header overwrite order * Process the incoming `init` parameter first * Explicitly overwrite required headers afterward * Ensure `Accept: application/json` is always enforced --- ## 💥 Breaking Changes None. --- ## 🧪 How to Test 1. Configure GitHub OAuth. 2. Attempt login via GitHub. 3. Verify that: * The request contains `Accept: application/json` * The response content-type is `application/json` * No JSON parsing error occurs * OAuth login completes successfully --- ## 📌 Notes This change restores correct OAuth behavior and prevents regression caused by header overwriting introduced in #14061. The same header overwrite pattern identified in this issue was also found in the calendar module and has been corrected there as well. ## Summary by CodeRabbit * **Refactor** * Improved backend HTTP header handling for external integrations to avoid unintended header overrides, ensuring content-type and encoding hints are applied consistently and improving reliability of service requests. --------- Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --- packages/backend/server/src/plugins/calendar/providers/def.ts | 2 +- packages/backend/server/src/plugins/oauth/providers/def.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/backend/server/src/plugins/calendar/providers/def.ts b/packages/backend/server/src/plugins/calendar/providers/def.ts index a9089d2ab6..02ad30482a 100644 --- a/packages/backend/server/src/plugins/calendar/providers/def.ts +++ b/packages/backend/server/src/plugins/calendar/providers/def.ts @@ -154,8 +154,8 @@ export abstract class CalendarProvider { protected async fetchJson(url: string, init?: RequestInit) { const response = await fetch(url, { - headers: { Accept: 'application/json', ...init?.headers }, ...init, + headers: { ...init?.headers, Accept: 'application/json' }, }); const body = await response.text(); if (!response.ok) { diff --git a/packages/backend/server/src/plugins/oauth/providers/def.ts b/packages/backend/server/src/plugins/oauth/providers/def.ts index 8258e860d2..695eea7a07 100644 --- a/packages/backend/server/src/plugins/oauth/providers/def.ts +++ b/packages/backend/server/src/plugins/oauth/providers/def.ts @@ -84,8 +84,8 @@ export abstract class OAuthProvider { options?: { treatServerErrorAsInvalid?: boolean } ) { const response = await fetch(url, { - headers: { Accept: 'application/json', ...init?.headers }, ...init, + headers: { ...init?.headers, Accept: 'application/json' }, }); const body = await response.text(); From e249e2e88460dbe3204580d54db5ce4bcfcd0e01 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 2 Mar 2026 05:19:09 +0800 Subject: [PATCH 09/49] chore: bump up opentelemetry (#14543) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Change | [Age](https://docs.renovatebot.com/merge-confidence/) | [Confidence](https://docs.renovatebot.com/merge-confidence/) | |---|---|---|---| | [@opentelemetry/exporter-prometheus](https://redirect.github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/opentelemetry-exporter-prometheus) ([source](https://redirect.github.com/open-telemetry/opentelemetry-js)) | [`^0.211.0` → `^0.212.0`](https://renovatebot.com/diffs/npm/@opentelemetry%2fexporter-prometheus/0.211.0/0.212.0) | ![age](https://developer.mend.io/api/mc/badges/age/npm/@opentelemetry%2fexporter-prometheus/0.212.0?slim=true) | ![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@opentelemetry%2fexporter-prometheus/0.211.0/0.212.0?slim=true) | | [@opentelemetry/exporter-zipkin](https://redirect.github.com/open-telemetry/opentelemetry-js/tree/main/packages/opentelemetry-exporter-zipkin) ([source](https://redirect.github.com/open-telemetry/opentelemetry-js)) | [`2.5.0` → `2.5.1`](https://renovatebot.com/diffs/npm/@opentelemetry%2fexporter-zipkin/2.5.0/2.5.1) | ![age](https://developer.mend.io/api/mc/badges/age/npm/@opentelemetry%2fexporter-zipkin/2.5.1?slim=true) | ![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@opentelemetry%2fexporter-zipkin/2.5.0/2.5.1?slim=true) | | [@opentelemetry/host-metrics](https://redirect.github.com/open-telemetry/opentelemetry-js-contrib/tree/main/packages/host-metrics#readme) ([source](https://redirect.github.com/open-telemetry/opentelemetry-js-contrib/tree/HEAD/packages/host-metrics)) | [`0.38.2` → `0.38.3`](https://renovatebot.com/diffs/npm/@opentelemetry%2fhost-metrics/0.38.2/0.38.3) | ![age](https://developer.mend.io/api/mc/badges/age/npm/@opentelemetry%2fhost-metrics/0.38.3?slim=true) | ![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@opentelemetry%2fhost-metrics/0.38.2/0.38.3?slim=true) | | [@opentelemetry/instrumentation](https://redirect.github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/opentelemetry-instrumentation) ([source](https://redirect.github.com/open-telemetry/opentelemetry-js)) | [`^0.211.0` → `^0.212.0`](https://renovatebot.com/diffs/npm/@opentelemetry%2finstrumentation/0.211.0/0.212.0) | ![age](https://developer.mend.io/api/mc/badges/age/npm/@opentelemetry%2finstrumentation/0.212.0?slim=true) | ![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@opentelemetry%2finstrumentation/0.211.0/0.212.0?slim=true) | | [@opentelemetry/instrumentation-graphql](https://redirect.github.com/open-telemetry/opentelemetry-js-contrib/tree/main/packages/instrumentation-graphql#readme) ([source](https://redirect.github.com/open-telemetry/opentelemetry-js-contrib/tree/HEAD/packages/instrumentation-graphql)) | [`^0.58.0` → `^0.60.0`](https://renovatebot.com/diffs/npm/@opentelemetry%2finstrumentation-graphql/0.58.0/0.60.0) | ![age](https://developer.mend.io/api/mc/badges/age/npm/@opentelemetry%2finstrumentation-graphql/0.60.0?slim=true) | ![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@opentelemetry%2finstrumentation-graphql/0.58.0/0.60.0?slim=true) | | [@opentelemetry/instrumentation-http](https://redirect.github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/opentelemetry-instrumentation-http) ([source](https://redirect.github.com/open-telemetry/opentelemetry-js)) | [`^0.211.0` → `^0.212.0`](https://renovatebot.com/diffs/npm/@opentelemetry%2finstrumentation-http/0.211.0/0.212.0) | ![age](https://developer.mend.io/api/mc/badges/age/npm/@opentelemetry%2finstrumentation-http/0.212.0?slim=true) | ![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@opentelemetry%2finstrumentation-http/0.211.0/0.212.0?slim=true) | | [@opentelemetry/instrumentation-ioredis](https://redirect.github.com/open-telemetry/opentelemetry-js-contrib/tree/main/packages/instrumentation-ioredis#readme) ([source](https://redirect.github.com/open-telemetry/opentelemetry-js-contrib/tree/HEAD/packages/instrumentation-ioredis)) | [`^0.59.0` → `^0.60.0`](https://renovatebot.com/diffs/npm/@opentelemetry%2finstrumentation-ioredis/0.59.0/0.60.0) | ![age](https://developer.mend.io/api/mc/badges/age/npm/@opentelemetry%2finstrumentation-ioredis/0.60.0?slim=true) | ![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@opentelemetry%2finstrumentation-ioredis/0.59.0/0.60.0?slim=true) | | [@opentelemetry/instrumentation-nestjs-core](https://redirect.github.com/open-telemetry/opentelemetry-js-contrib/tree/main/packages/instrumentation-nestjs-core#readme) ([source](https://redirect.github.com/open-telemetry/opentelemetry-js-contrib/tree/HEAD/packages/instrumentation-nestjs-core)) | [`^0.57.0` → `^0.58.0`](https://renovatebot.com/diffs/npm/@opentelemetry%2finstrumentation-nestjs-core/0.57.0/0.58.0) | ![age](https://developer.mend.io/api/mc/badges/age/npm/@opentelemetry%2finstrumentation-nestjs-core/0.58.0?slim=true) | ![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@opentelemetry%2finstrumentation-nestjs-core/0.57.0/0.58.0?slim=true) | | [@opentelemetry/instrumentation-socket.io](https://redirect.github.com/open-telemetry/opentelemetry-js-contrib/tree/main/packages/instrumentation-socket.io#readme) ([source](https://redirect.github.com/open-telemetry/opentelemetry-js-contrib/tree/HEAD/packages/instrumentation-socket.io)) | [`^0.57.0` → `^0.59.0`](https://renovatebot.com/diffs/npm/@opentelemetry%2finstrumentation-socket.io/0.57.0/0.59.0) | ![age](https://developer.mend.io/api/mc/badges/age/npm/@opentelemetry%2finstrumentation-socket.io/0.59.0?slim=true) | ![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@opentelemetry%2finstrumentation-socket.io/0.57.0/0.59.0?slim=true) | | [@opentelemetry/sdk-metrics](https://redirect.github.com/open-telemetry/opentelemetry-js/tree/main/packages/sdk-metrics) ([source](https://redirect.github.com/open-telemetry/opentelemetry-js)) | [`2.5.0` → `2.5.1`](https://renovatebot.com/diffs/npm/@opentelemetry%2fsdk-metrics/2.5.0/2.5.1) | ![age](https://developer.mend.io/api/mc/badges/age/npm/@opentelemetry%2fsdk-metrics/2.5.1?slim=true) | ![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@opentelemetry%2fsdk-metrics/2.5.0/2.5.1?slim=true) | | [@opentelemetry/sdk-node](https://redirect.github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/opentelemetry-sdk-node) ([source](https://redirect.github.com/open-telemetry/opentelemetry-js)) | [`^0.211.0` → `^0.212.0`](https://renovatebot.com/diffs/npm/@opentelemetry%2fsdk-node/0.211.0/0.212.0) | ![age](https://developer.mend.io/api/mc/badges/age/npm/@opentelemetry%2fsdk-node/0.212.0?slim=true) | ![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@opentelemetry%2fsdk-node/0.211.0/0.212.0?slim=true) | | [@opentelemetry/sdk-trace-node](https://redirect.github.com/open-telemetry/opentelemetry-js/tree/main/packages/opentelemetry-sdk-trace-node) ([source](https://redirect.github.com/open-telemetry/opentelemetry-js)) | [`2.5.0` → `2.5.1`](https://renovatebot.com/diffs/npm/@opentelemetry%2fsdk-trace-node/2.5.0/2.5.1) | ![age](https://developer.mend.io/api/mc/badges/age/npm/@opentelemetry%2fsdk-trace-node/2.5.1?slim=true) | ![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@opentelemetry%2fsdk-trace-node/2.5.0/2.5.1?slim=true) | --- ### Release Notes
open-telemetry/opentelemetry-js (@​opentelemetry/exporter-prometheus) ### [`v0.212.0`](https://redirect.github.com/open-telemetry/opentelemetry-js/compare/38924cbff2a6e924ce8a2a227d3a72de52fbcd35...ad92be4c2c1094745a85b0b7eeff1444a11b1b4a) [Compare Source](https://redirect.github.com/open-telemetry/opentelemetry-js/compare/38924cbff2a6e924ce8a2a227d3a72de52fbcd35...ad92be4c2c1094745a85b0b7eeff1444a11b1b4a)
open-telemetry/opentelemetry-js-contrib (@​opentelemetry/host-metrics) ### [`v0.38.3`](https://redirect.github.com/open-telemetry/opentelemetry-js-contrib/blob/HEAD/packages/host-metrics/CHANGELOG.md#0383-2026-02-25) [Compare Source](https://redirect.github.com/open-telemetry/opentelemetry-js-contrib/compare/7a5f3c0a09b6a2d32c712b2962b95137c906a016...630937db1575c652201558467ae5c449075f0881) ##### Bug Fixes - **instrumentation-host-metrics:** unpin and update to systeminformation@^5.31.1 ([#​3392](https://redirect.github.com/open-telemetry/opentelemetry-js-contrib/issues/3392)) ([e4ffdb4](https://redirect.github.com/open-telemetry/opentelemetry-js-contrib/commit/e4ffdb43d160ace57420978da9c1855be653abe1))
open-telemetry/opentelemetry-js-contrib (@​opentelemetry/instrumentation-graphql) ### [`v0.60.0`](https://redirect.github.com/open-telemetry/opentelemetry-js-contrib/blob/HEAD/packages/instrumentation-graphql/CHANGELOG.md#0600-2026-02-25) [Compare Source](https://redirect.github.com/open-telemetry/opentelemetry-js-contrib/compare/0b33a118f289c0435a241c84c3c3923312fc2b98...630937db1575c652201558467ae5c449075f0881) ##### Features - **instrumentation-graphql:** add parent name in attributes of resolver span ([#​3287](https://redirect.github.com/open-telemetry/opentelemetry-js-contrib/issues/3287)) ([ea2a90a](https://redirect.github.com/open-telemetry/opentelemetry-js-contrib/commit/ea2a90a87b5b5a6d29f980a73e61cefa020ab81c)) ### [`v0.59.0`](https://redirect.github.com/open-telemetry/opentelemetry-js-contrib/blob/HEAD/packages/instrumentation-graphql/CHANGELOG.md#0590-2026-02-16) [Compare Source](https://redirect.github.com/open-telemetry/opentelemetry-js-contrib/compare/7a5f3c0a09b6a2d32c712b2962b95137c906a016...0b33a118f289c0435a241c84c3c3923312fc2b98) ##### Features - **deps:** update deps matching "@​opentelemetry/\*" ([#​3383](https://redirect.github.com/open-telemetry/opentelemetry-js-contrib/issues/3383)) ([d3ac785](https://redirect.github.com/open-telemetry/opentelemetry-js-contrib/commit/d3ac7851d69d0781c2c631012937a73998b744e1))
open-telemetry/opentelemetry-js-contrib (@​opentelemetry/instrumentation-ioredis) ### [`v0.60.0`](https://redirect.github.com/open-telemetry/opentelemetry-js-contrib/blob/HEAD/packages/instrumentation-ioredis/CHANGELOG.md#0600-2026-02-16) [Compare Source](https://redirect.github.com/open-telemetry/opentelemetry-js-contrib/compare/7a5f3c0a09b6a2d32c712b2962b95137c906a016...0b33a118f289c0435a241c84c3c3923312fc2b98) ##### Features - **deps:** update deps matching "@​opentelemetry/\*" ([#​3383](https://redirect.github.com/open-telemetry/opentelemetry-js-contrib/issues/3383)) ([d3ac785](https://redirect.github.com/open-telemetry/opentelemetry-js-contrib/commit/d3ac7851d69d0781c2c631012937a73998b744e1)) ##### Dependencies - The following workspace dependencies were updated - devDependencies - [@​opentelemetry/contrib-test-utils](https://redirect.github.com/opentelemetry/contrib-test-utils) bumped from ^0.58.0 to ^0.59.0
open-telemetry/opentelemetry-js-contrib (@​opentelemetry/instrumentation-nestjs-core) ### [`v0.58.0`](https://redirect.github.com/open-telemetry/opentelemetry-js-contrib/blob/HEAD/packages/instrumentation-nestjs-core/CHANGELOG.md#0580-2026-02-16) [Compare Source](https://redirect.github.com/open-telemetry/opentelemetry-js-contrib/compare/7a5f3c0a09b6a2d32c712b2962b95137c906a016...0b33a118f289c0435a241c84c3c3923312fc2b98) ##### Features - **deps:** update deps matching "@​opentelemetry/\*" ([#​3383](https://redirect.github.com/open-telemetry/opentelemetry-js-contrib/issues/3383)) ([d3ac785](https://redirect.github.com/open-telemetry/opentelemetry-js-contrib/commit/d3ac7851d69d0781c2c631012937a73998b744e1))
open-telemetry/opentelemetry-js-contrib (@​opentelemetry/instrumentation-socket.io) ### [`v0.59.0`](https://redirect.github.com/open-telemetry/opentelemetry-js-contrib/blob/HEAD/packages/instrumentation-socket.io/CHANGELOG.md#0590-2026-02-25) [Compare Source](https://redirect.github.com/open-telemetry/opentelemetry-js-contrib/compare/0b33a118f289c0435a241c84c3c3923312fc2b98...630937db1575c652201558467ae5c449075f0881) ##### Features - **deps:** lock file maintenance ([#​3261](https://redirect.github.com/open-telemetry/opentelemetry-js-contrib/issues/3261)) ([540926b](https://redirect.github.com/open-telemetry/opentelemetry-js-contrib/commit/540926bffe713c591163abaf56fbb0e18aaf5b88)) ### [`v0.58.0`](https://redirect.github.com/open-telemetry/opentelemetry-js-contrib/blob/HEAD/packages/instrumentation-socket.io/CHANGELOG.md#0580-2026-02-16) [Compare Source](https://redirect.github.com/open-telemetry/opentelemetry-js-contrib/compare/7a5f3c0a09b6a2d32c712b2962b95137c906a016...0b33a118f289c0435a241c84c3c3923312fc2b98) ##### Features - **deps:** update deps matching "@​opentelemetry/\*" ([#​3383](https://redirect.github.com/open-telemetry/opentelemetry-js-contrib/issues/3383)) ([d3ac785](https://redirect.github.com/open-telemetry/opentelemetry-js-contrib/commit/d3ac7851d69d0781c2c631012937a73998b744e1)) ##### Dependencies - The following workspace dependencies were updated - devDependencies - [@​opentelemetry/contrib-test-utils](https://redirect.github.com/opentelemetry/contrib-test-utils) bumped from ^0.58.0 to ^0.59.0
--- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 👻 **Immortal**: This PR will be recreated if closed unmerged. Get [config help](https://redirect.github.com/renovatebot/renovate/discussions) if that's undesired. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/toeverything/AFFiNE). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- packages/backend/server/package.json | 16 +- yarn.lock | 565 ++++++++++++++------------- 2 files changed, 297 insertions(+), 284 deletions(-) diff --git a/packages/backend/server/package.json b/packages/backend/server/package.json index 9c6d6cf9f9..350718e9a4 100644 --- a/packages/backend/server/package.json +++ b/packages/backend/server/package.json @@ -55,18 +55,18 @@ "@node-rs/crc32": "^1.10.6", "@opentelemetry/api": "^1.9.0", "@opentelemetry/core": "^2.2.0", - "@opentelemetry/exporter-prometheus": "^0.211.0", + "@opentelemetry/exporter-prometheus": "^0.212.0", "@opentelemetry/exporter-zipkin": "^2.2.0", "@opentelemetry/host-metrics": "^0.38.0", - "@opentelemetry/instrumentation": "^0.211.0", - "@opentelemetry/instrumentation-graphql": "^0.58.0", - "@opentelemetry/instrumentation-http": "^0.211.0", - "@opentelemetry/instrumentation-ioredis": "^0.59.0", - "@opentelemetry/instrumentation-nestjs-core": "^0.57.0", - "@opentelemetry/instrumentation-socket.io": "^0.57.0", + "@opentelemetry/instrumentation": "^0.212.0", + "@opentelemetry/instrumentation-graphql": "^0.60.0", + "@opentelemetry/instrumentation-http": "^0.212.0", + "@opentelemetry/instrumentation-ioredis": "^0.60.0", + "@opentelemetry/instrumentation-nestjs-core": "^0.58.0", + "@opentelemetry/instrumentation-socket.io": "^0.59.0", "@opentelemetry/resources": "^2.2.0", "@opentelemetry/sdk-metrics": "^2.2.0", - "@opentelemetry/sdk-node": "^0.211.0", + "@opentelemetry/sdk-node": "^0.212.0", "@opentelemetry/sdk-trace-node": "^2.2.0", "@opentelemetry/semantic-conventions": "^1.38.0", "@prisma/client": "^6.6.0", diff --git a/yarn.lock b/yarn.lock index 300c2d8d3d..d4bca6a1e8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -992,18 +992,18 @@ __metadata: "@node-rs/crc32": "npm:^1.10.6" "@opentelemetry/api": "npm:^1.9.0" "@opentelemetry/core": "npm:^2.2.0" - "@opentelemetry/exporter-prometheus": "npm:^0.211.0" + "@opentelemetry/exporter-prometheus": "npm:^0.212.0" "@opentelemetry/exporter-zipkin": "npm:^2.2.0" "@opentelemetry/host-metrics": "npm:^0.38.0" - "@opentelemetry/instrumentation": "npm:^0.211.0" - "@opentelemetry/instrumentation-graphql": "npm:^0.58.0" - "@opentelemetry/instrumentation-http": "npm:^0.211.0" - "@opentelemetry/instrumentation-ioredis": "npm:^0.59.0" - "@opentelemetry/instrumentation-nestjs-core": "npm:^0.57.0" - "@opentelemetry/instrumentation-socket.io": "npm:^0.57.0" + "@opentelemetry/instrumentation": "npm:^0.212.0" + "@opentelemetry/instrumentation-graphql": "npm:^0.60.0" + "@opentelemetry/instrumentation-http": "npm:^0.212.0" + "@opentelemetry/instrumentation-ioredis": "npm:^0.60.0" + "@opentelemetry/instrumentation-nestjs-core": "npm:^0.58.0" + "@opentelemetry/instrumentation-socket.io": "npm:^0.59.0" "@opentelemetry/resources": "npm:^2.2.0" "@opentelemetry/sdk-metrics": "npm:^2.2.0" - "@opentelemetry/sdk-node": "npm:^0.211.0" + "@opentelemetry/sdk-node": "npm:^0.212.0" "@opentelemetry/sdk-trace-node": "npm:^2.2.0" "@opentelemetry/semantic-conventions": "npm:^1.38.0" "@prisma/client": "npm:^6.6.0" @@ -6429,27 +6429,13 @@ __metadata: languageName: node linkType: hard -"@grpc/grpc-js@npm:^1.1.8, @grpc/grpc-js@npm:^1.7.1": - version: 1.13.3 - resolution: "@grpc/grpc-js@npm:1.13.3" +"@grpc/grpc-js@npm:^1.1.8, @grpc/grpc-js@npm:^1.14.3": + version: 1.14.3 + resolution: "@grpc/grpc-js@npm:1.14.3" dependencies: - "@grpc/proto-loader": "npm:^0.7.13" + "@grpc/proto-loader": "npm:^0.8.0" "@js-sdsl/ordered-map": "npm:^4.4.2" - checksum: 10/0b5016baf063ae115972b9765b53ade072a6feb5bf45ddbbc24f2aab6e69ebb6069792cf0451fb6e08eaf58a837e1916b8f04740008fa6550bf8442ee2588305 - languageName: node - linkType: hard - -"@grpc/proto-loader@npm:^0.7.13": - version: 0.7.15 - resolution: "@grpc/proto-loader@npm:0.7.15" - dependencies: - lodash.camelcase: "npm:^4.3.0" - long: "npm:^5.0.0" - protobufjs: "npm:^7.2.5" - yargs: "npm:^17.7.2" - bin: - proto-loader-gen-types: build/bin/proto-loader-gen-types.js - checksum: 10/2e2b33ace8bc34211522751a9e654faf9ac997577a9e9291b1619b4c05d7878a74d2101c3bc43b2b2b92bca7509001678fb191d4eb100684cc2910d66f36c373 + checksum: 10/bb9bfe2f749179ae5ac7774d30486dfa2e0b004518c28de158b248e0f6f65f40138f01635c48266fa540670220f850216726e3724e1eb29d078817581c96e4db languageName: node linkType: hard @@ -9846,6 +9832,15 @@ __metadata: languageName: node linkType: hard +"@opentelemetry/api-logs@npm:0.212.0": + version: 0.212.0 + resolution: "@opentelemetry/api-logs@npm:0.212.0" + dependencies: + "@opentelemetry/api": "npm:^1.3.0" + checksum: 10/215ba71dc1e04bee2721ef5b74074c7d8ec33e12dbd386c399a2c3989ba1e1b8f50a19c048d0317d915335eeee83ba7549486df2d54818697abca6da1d9c6f90 + languageName: node + linkType: hard + "@opentelemetry/api@npm:1.9.0, @opentelemetry/api@npm:^1.3.0, @opentelemetry/api@npm:^1.9.0": version: 1.9.0 resolution: "@opentelemetry/api@npm:1.9.0" @@ -9853,28 +9848,19 @@ __metadata: languageName: node linkType: hard -"@opentelemetry/configuration@npm:0.211.0": - version: 0.211.0 - resolution: "@opentelemetry/configuration@npm:0.211.0" +"@opentelemetry/configuration@npm:0.212.0": + version: 0.212.0 + resolution: "@opentelemetry/configuration@npm:0.212.0" dependencies: - "@opentelemetry/core": "npm:2.5.0" + "@opentelemetry/core": "npm:2.5.1" yaml: "npm:^2.0.0" peerDependencies: "@opentelemetry/api": ^1.9.0 - checksum: 10/b16885a96c68e679d337ff0f4a34a2dcee02570047511879e8ac9ccdb9785431eb90d2e82a07d7c8c17987bced43ccd97768fe1efca84c65f347203ccffa9dca + checksum: 10/53d2fcda4cc8a07cc1b1ac163d97f76dd671b56d901aa33082339c772003f88212d46650049040864a43c8869f486b581a98779b621a5cc77fe6f60450aa9949 languageName: node linkType: hard -"@opentelemetry/context-async-hooks@npm:2.5.0": - version: 2.5.0 - resolution: "@opentelemetry/context-async-hooks@npm:2.5.0" - peerDependencies: - "@opentelemetry/api": ">=1.0.0 <1.10.0" - checksum: 10/2c474fcd21781f85dff5001b25f522a8325a653bad4189ae121a8ed446661da84e641e489f912f4409b1642911072b5c923305d87821457452755e3d2d651319 - languageName: node - linkType: hard - -"@opentelemetry/context-async-hooks@npm:^2.5.1": +"@opentelemetry/context-async-hooks@npm:2.5.1, @opentelemetry/context-async-hooks@npm:^2.5.1": version: 2.5.1 resolution: "@opentelemetry/context-async-hooks@npm:2.5.1" peerDependencies: @@ -9905,185 +9891,186 @@ __metadata: languageName: node linkType: hard -"@opentelemetry/exporter-logs-otlp-grpc@npm:0.211.0": - version: 0.211.0 - resolution: "@opentelemetry/exporter-logs-otlp-grpc@npm:0.211.0" +"@opentelemetry/exporter-logs-otlp-grpc@npm:0.212.0": + version: 0.212.0 + resolution: "@opentelemetry/exporter-logs-otlp-grpc@npm:0.212.0" dependencies: - "@grpc/grpc-js": "npm:^1.7.1" - "@opentelemetry/core": "npm:2.5.0" - "@opentelemetry/otlp-exporter-base": "npm:0.211.0" - "@opentelemetry/otlp-grpc-exporter-base": "npm:0.211.0" - "@opentelemetry/otlp-transformer": "npm:0.211.0" - "@opentelemetry/sdk-logs": "npm:0.211.0" + "@grpc/grpc-js": "npm:^1.14.3" + "@opentelemetry/core": "npm:2.5.1" + "@opentelemetry/otlp-exporter-base": "npm:0.212.0" + "@opentelemetry/otlp-grpc-exporter-base": "npm:0.212.0" + "@opentelemetry/otlp-transformer": "npm:0.212.0" + "@opentelemetry/sdk-logs": "npm:0.212.0" peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: 10/5440ad82f64e421f3fa394f0fef2db8b0ad30e429bd958965c3bd58b48525c6a4b1fb787c8aaaa216e1e7e991fb9bbaf3317df7707cd1f6c39cfadd273b4c927 + checksum: 10/7762599196fb1bef767842e894eb7bc8007853115eb852d5f8fe9d50acfb9a37289005792520213bfdc3a7a4ac3e866721bf5d450ea424195002d2a933146573 languageName: node linkType: hard -"@opentelemetry/exporter-logs-otlp-http@npm:0.211.0": - version: 0.211.0 - resolution: "@opentelemetry/exporter-logs-otlp-http@npm:0.211.0" +"@opentelemetry/exporter-logs-otlp-http@npm:0.212.0": + version: 0.212.0 + resolution: "@opentelemetry/exporter-logs-otlp-http@npm:0.212.0" dependencies: - "@opentelemetry/api-logs": "npm:0.211.0" - "@opentelemetry/core": "npm:2.5.0" - "@opentelemetry/otlp-exporter-base": "npm:0.211.0" - "@opentelemetry/otlp-transformer": "npm:0.211.0" - "@opentelemetry/sdk-logs": "npm:0.211.0" + "@opentelemetry/api-logs": "npm:0.212.0" + "@opentelemetry/core": "npm:2.5.1" + "@opentelemetry/otlp-exporter-base": "npm:0.212.0" + "@opentelemetry/otlp-transformer": "npm:0.212.0" + "@opentelemetry/sdk-logs": "npm:0.212.0" peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: 10/94f8c3ec45c2d1fbd7510360681c2bbc6c3d04f8087cb094e16ba538480a8b90b167ffee2aee7804f3f978a9adb28685a5bd4c5b5b344d9664f4c3d57bfe3396 + checksum: 10/621920888b1acc83655b545e28458265adaa2923123c5af47d3dc9582758b4db8f163ff57532a3d841bf31832d54093d77a351aa2949dcff3fd02e110787c01c languageName: node linkType: hard -"@opentelemetry/exporter-logs-otlp-proto@npm:0.211.0": - version: 0.211.0 - resolution: "@opentelemetry/exporter-logs-otlp-proto@npm:0.211.0" +"@opentelemetry/exporter-logs-otlp-proto@npm:0.212.0": + version: 0.212.0 + resolution: "@opentelemetry/exporter-logs-otlp-proto@npm:0.212.0" dependencies: - "@opentelemetry/api-logs": "npm:0.211.0" - "@opentelemetry/core": "npm:2.5.0" - "@opentelemetry/otlp-exporter-base": "npm:0.211.0" - "@opentelemetry/otlp-transformer": "npm:0.211.0" - "@opentelemetry/resources": "npm:2.5.0" - "@opentelemetry/sdk-logs": "npm:0.211.0" - "@opentelemetry/sdk-trace-base": "npm:2.5.0" + "@opentelemetry/api-logs": "npm:0.212.0" + "@opentelemetry/core": "npm:2.5.1" + "@opentelemetry/otlp-exporter-base": "npm:0.212.0" + "@opentelemetry/otlp-transformer": "npm:0.212.0" + "@opentelemetry/resources": "npm:2.5.1" + "@opentelemetry/sdk-logs": "npm:0.212.0" + "@opentelemetry/sdk-trace-base": "npm:2.5.1" peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: 10/0e8435b1011dd9e5aa165fce7ad024976838c61c2a8e4fb7d72ea1703de907d801d432fdf1d195e49b22fc09bc987da406d5b8b6c7a3ff5bd04a23d3136478fd + checksum: 10/0e2ccd5c28f492a02636426b4666a6dbc0acde9676be9e2503a934cd61e1dde9a43a719d85dc4f80670f44ad3084461417b93b7ef702e36f72ff2bb32c0dc8c9 languageName: node linkType: hard -"@opentelemetry/exporter-metrics-otlp-grpc@npm:0.211.0": - version: 0.211.0 - resolution: "@opentelemetry/exporter-metrics-otlp-grpc@npm:0.211.0" +"@opentelemetry/exporter-metrics-otlp-grpc@npm:0.212.0": + version: 0.212.0 + resolution: "@opentelemetry/exporter-metrics-otlp-grpc@npm:0.212.0" dependencies: - "@grpc/grpc-js": "npm:^1.7.1" - "@opentelemetry/core": "npm:2.5.0" - "@opentelemetry/exporter-metrics-otlp-http": "npm:0.211.0" - "@opentelemetry/otlp-exporter-base": "npm:0.211.0" - "@opentelemetry/otlp-grpc-exporter-base": "npm:0.211.0" - "@opentelemetry/otlp-transformer": "npm:0.211.0" - "@opentelemetry/resources": "npm:2.5.0" - "@opentelemetry/sdk-metrics": "npm:2.5.0" + "@grpc/grpc-js": "npm:^1.14.3" + "@opentelemetry/core": "npm:2.5.1" + "@opentelemetry/exporter-metrics-otlp-http": "npm:0.212.0" + "@opentelemetry/otlp-exporter-base": "npm:0.212.0" + "@opentelemetry/otlp-grpc-exporter-base": "npm:0.212.0" + "@opentelemetry/otlp-transformer": "npm:0.212.0" + "@opentelemetry/resources": "npm:2.5.1" + "@opentelemetry/sdk-metrics": "npm:2.5.1" peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: 10/ffd5c471cf771fcf3c33e6957790e258bc419a9f2cc76ffb7a211be8f9f1aca74fd62a0e107df99360851ea1d311789647436cadc6dd0c04d9e144dbe7a16228 + checksum: 10/32b0d5281e14e02bf268152fdaff72aaa5ba69320841a7179c4df07eed2d131b01ed7657221cada63eedf98b7ae82c65ba2e983e83982cf5f836d71626c2e5f1 languageName: node linkType: hard -"@opentelemetry/exporter-metrics-otlp-http@npm:0.211.0": - version: 0.211.0 - resolution: "@opentelemetry/exporter-metrics-otlp-http@npm:0.211.0" +"@opentelemetry/exporter-metrics-otlp-http@npm:0.212.0": + version: 0.212.0 + resolution: "@opentelemetry/exporter-metrics-otlp-http@npm:0.212.0" dependencies: - "@opentelemetry/core": "npm:2.5.0" - "@opentelemetry/otlp-exporter-base": "npm:0.211.0" - "@opentelemetry/otlp-transformer": "npm:0.211.0" - "@opentelemetry/resources": "npm:2.5.0" - "@opentelemetry/sdk-metrics": "npm:2.5.0" + "@opentelemetry/core": "npm:2.5.1" + "@opentelemetry/otlp-exporter-base": "npm:0.212.0" + "@opentelemetry/otlp-transformer": "npm:0.212.0" + "@opentelemetry/resources": "npm:2.5.1" + "@opentelemetry/sdk-metrics": "npm:2.5.1" peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: 10/9411013cf47a29daebf95fdca20af033f08362e101a18bccbd74c7ab138b1358106ed5428f132731feb793cc2745ba8a9512b2364880e08477d7b6b997aaf8db + checksum: 10/87189d9685dd02ff4facd240b4be61db1805bc6b45a15edfcb47fd43860ef7fa7b0010c24b7130e2d0b17a9e77443375f0141e491d59418cb567e613c1f98d8c languageName: node linkType: hard -"@opentelemetry/exporter-metrics-otlp-proto@npm:0.211.0": - version: 0.211.0 - resolution: "@opentelemetry/exporter-metrics-otlp-proto@npm:0.211.0" +"@opentelemetry/exporter-metrics-otlp-proto@npm:0.212.0": + version: 0.212.0 + resolution: "@opentelemetry/exporter-metrics-otlp-proto@npm:0.212.0" dependencies: - "@opentelemetry/core": "npm:2.5.0" - "@opentelemetry/exporter-metrics-otlp-http": "npm:0.211.0" - "@opentelemetry/otlp-exporter-base": "npm:0.211.0" - "@opentelemetry/otlp-transformer": "npm:0.211.0" - "@opentelemetry/resources": "npm:2.5.0" - "@opentelemetry/sdk-metrics": "npm:2.5.0" + "@opentelemetry/core": "npm:2.5.1" + "@opentelemetry/exporter-metrics-otlp-http": "npm:0.212.0" + "@opentelemetry/otlp-exporter-base": "npm:0.212.0" + "@opentelemetry/otlp-transformer": "npm:0.212.0" + "@opentelemetry/resources": "npm:2.5.1" + "@opentelemetry/sdk-metrics": "npm:2.5.1" peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: 10/c145ff961033c426f5c98bc0fa4bae0138c7596eb219af75ec10c2f0458f116d367fe7343df5a8f42052dbb4326994ff4d68970c8c2b111b4cd5385dd89bb699 + checksum: 10/aba4a9d8609dc2d08d4249810523711bad6a892f2e461c95e1bba5a136e027c866bb54397090951e06f80f843691ffbf0e83d958108c1eb5a8b1530e444e1f4d languageName: node linkType: hard -"@opentelemetry/exporter-prometheus@npm:0.211.0, @opentelemetry/exporter-prometheus@npm:^0.211.0": - version: 0.211.0 - resolution: "@opentelemetry/exporter-prometheus@npm:0.211.0" +"@opentelemetry/exporter-prometheus@npm:0.212.0, @opentelemetry/exporter-prometheus@npm:^0.212.0": + version: 0.212.0 + resolution: "@opentelemetry/exporter-prometheus@npm:0.212.0" dependencies: - "@opentelemetry/core": "npm:2.5.0" - "@opentelemetry/resources": "npm:2.5.0" - "@opentelemetry/sdk-metrics": "npm:2.5.0" + "@opentelemetry/core": "npm:2.5.1" + "@opentelemetry/resources": "npm:2.5.1" + "@opentelemetry/sdk-metrics": "npm:2.5.1" + "@opentelemetry/semantic-conventions": "npm:^1.29.0" peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: 10/c7acc042bc6ad1713d1dbffe3517b94e31ad50404c1c3f345b46187d52c6dd20b7a8eca4594b6c107120b876af7e17a11704fb813da64bb760d250adf2c29973 + checksum: 10/8da375a5120367897cb4928526606b76aedc7f914d4d5afbf620e89d190e3adc4636113f5b151c634b294e45771172635b1e6c1c4fc9ca45ff3a6b486e7ed1f8 languageName: node linkType: hard -"@opentelemetry/exporter-trace-otlp-grpc@npm:0.211.0": - version: 0.211.0 - resolution: "@opentelemetry/exporter-trace-otlp-grpc@npm:0.211.0" +"@opentelemetry/exporter-trace-otlp-grpc@npm:0.212.0": + version: 0.212.0 + resolution: "@opentelemetry/exporter-trace-otlp-grpc@npm:0.212.0" dependencies: - "@grpc/grpc-js": "npm:^1.7.1" - "@opentelemetry/core": "npm:2.5.0" - "@opentelemetry/otlp-exporter-base": "npm:0.211.0" - "@opentelemetry/otlp-grpc-exporter-base": "npm:0.211.0" - "@opentelemetry/otlp-transformer": "npm:0.211.0" - "@opentelemetry/resources": "npm:2.5.0" - "@opentelemetry/sdk-trace-base": "npm:2.5.0" + "@grpc/grpc-js": "npm:^1.14.3" + "@opentelemetry/core": "npm:2.5.1" + "@opentelemetry/otlp-exporter-base": "npm:0.212.0" + "@opentelemetry/otlp-grpc-exporter-base": "npm:0.212.0" + "@opentelemetry/otlp-transformer": "npm:0.212.0" + "@opentelemetry/resources": "npm:2.5.1" + "@opentelemetry/sdk-trace-base": "npm:2.5.1" peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: 10/623b84253f476a49383536e51903026f43a4348e069230ceee22f61cc18f98d417b75644db2324f763f7f4ac283a3f956e80da23ea0d3e6c91dc53da0a6715c1 + checksum: 10/8198b7bb025aedfff909f138d465a42eb38879e7d0a40d4b7d75a7d08180458e410194a2e604da5ebd1aaa63ab4d3b4de78724c9fbff176f439060733edbc373 languageName: node linkType: hard -"@opentelemetry/exporter-trace-otlp-http@npm:0.211.0": - version: 0.211.0 - resolution: "@opentelemetry/exporter-trace-otlp-http@npm:0.211.0" +"@opentelemetry/exporter-trace-otlp-http@npm:0.212.0": + version: 0.212.0 + resolution: "@opentelemetry/exporter-trace-otlp-http@npm:0.212.0" dependencies: - "@opentelemetry/core": "npm:2.5.0" - "@opentelemetry/otlp-exporter-base": "npm:0.211.0" - "@opentelemetry/otlp-transformer": "npm:0.211.0" - "@opentelemetry/resources": "npm:2.5.0" - "@opentelemetry/sdk-trace-base": "npm:2.5.0" + "@opentelemetry/core": "npm:2.5.1" + "@opentelemetry/otlp-exporter-base": "npm:0.212.0" + "@opentelemetry/otlp-transformer": "npm:0.212.0" + "@opentelemetry/resources": "npm:2.5.1" + "@opentelemetry/sdk-trace-base": "npm:2.5.1" peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: 10/2dbd3bbbbe6106ffd4821e906ca2581dad64e4aa65c6048a2ff1bb63bd2f285869a49874570a7cf854b6419008abcb9d92296a9f77e5896caecacf214009f684 + checksum: 10/5611bde7ce4aedcc6b8e770927feed062b062a5918664267007cf25367802c0dbcd90ec57c9c74306628849295ed9a04925bea71b85957ed75901c1254c742c7 languageName: node linkType: hard -"@opentelemetry/exporter-trace-otlp-proto@npm:0.211.0": - version: 0.211.0 - resolution: "@opentelemetry/exporter-trace-otlp-proto@npm:0.211.0" +"@opentelemetry/exporter-trace-otlp-proto@npm:0.212.0": + version: 0.212.0 + resolution: "@opentelemetry/exporter-trace-otlp-proto@npm:0.212.0" dependencies: - "@opentelemetry/core": "npm:2.5.0" - "@opentelemetry/otlp-exporter-base": "npm:0.211.0" - "@opentelemetry/otlp-transformer": "npm:0.211.0" - "@opentelemetry/resources": "npm:2.5.0" - "@opentelemetry/sdk-trace-base": "npm:2.5.0" + "@opentelemetry/core": "npm:2.5.1" + "@opentelemetry/otlp-exporter-base": "npm:0.212.0" + "@opentelemetry/otlp-transformer": "npm:0.212.0" + "@opentelemetry/resources": "npm:2.5.1" + "@opentelemetry/sdk-trace-base": "npm:2.5.1" peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: 10/7fc4d0d432425a3f068ef30b47cbe536d13f029e4fda8c54797d3fab43e67c15d183737b5141ccc7273620d070bcc90db91b4c38f7acd93314afff9211204469 + checksum: 10/f8b913a449c91381c4834be248c95ae0830df0f788dc466d7bca405a5bd843c11ca4c240f588d23997ed0b673bcdef1b1e1fbd00190d426e5555a681a65156d7 languageName: node linkType: hard -"@opentelemetry/exporter-zipkin@npm:2.5.0, @opentelemetry/exporter-zipkin@npm:^2.2.0": - version: 2.5.0 - resolution: "@opentelemetry/exporter-zipkin@npm:2.5.0" +"@opentelemetry/exporter-zipkin@npm:2.5.1, @opentelemetry/exporter-zipkin@npm:^2.2.0": + version: 2.5.1 + resolution: "@opentelemetry/exporter-zipkin@npm:2.5.1" dependencies: - "@opentelemetry/core": "npm:2.5.0" - "@opentelemetry/resources": "npm:2.5.0" - "@opentelemetry/sdk-trace-base": "npm:2.5.0" + "@opentelemetry/core": "npm:2.5.1" + "@opentelemetry/resources": "npm:2.5.1" + "@opentelemetry/sdk-trace-base": "npm:2.5.1" "@opentelemetry/semantic-conventions": "npm:^1.29.0" peerDependencies: "@opentelemetry/api": ^1.0.0 - checksum: 10/6befd9a76c8f8786c754048b9cdbcfc99ca03fa0f1db00907c015f0b1828ed7feace1cae358220e46e5e9269fb726c385cd7593dbc1cb791e158cbf7f63fc4b4 + checksum: 10/41b8da30694ed72d3715698bdb9f53d022d4bb96367f99fafcd70c372e9304bdf54b5c06b8e61f2dbc516b4ba719af7a3969c2e1801fc78d5a12504241ffd459 languageName: node linkType: hard "@opentelemetry/host-metrics@npm:^0.38.0": - version: 0.38.2 - resolution: "@opentelemetry/host-metrics@npm:0.38.2" + version: 0.38.3 + resolution: "@opentelemetry/host-metrics@npm:0.38.3" dependencies: - systeminformation: "npm:5.30.3" + systeminformation: "npm:^5.31.1" peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: 10/c55ef0c3831973045d2186f28b635ddf433a113e8f7ea13cd3edd722a04847b737c75fda7760f0de65f07dbfec2bd5e003f00ae0e597841d73ed1edb295a9065 + checksum: 10/b83e8b3a21d8a92ed566795e55a7f816505d7b4311820198fd509b9b8dc681baddc60f4c8cb2f140b07b7117925e7a4d8b1dcb302e98c79d9294739b5d3a0de8 languageName: node linkType: hard @@ -10161,7 +10148,7 @@ __metadata: languageName: node linkType: hard -"@opentelemetry/instrumentation-graphql@npm:0.58.0, @opentelemetry/instrumentation-graphql@npm:^0.58.0": +"@opentelemetry/instrumentation-graphql@npm:0.58.0": version: 0.58.0 resolution: "@opentelemetry/instrumentation-graphql@npm:0.58.0" dependencies: @@ -10172,6 +10159,17 @@ __metadata: languageName: node linkType: hard +"@opentelemetry/instrumentation-graphql@npm:^0.60.0": + version: 0.60.0 + resolution: "@opentelemetry/instrumentation-graphql@npm:0.60.0" + dependencies: + "@opentelemetry/instrumentation": "npm:^0.212.0" + peerDependencies: + "@opentelemetry/api": ^1.3.0 + checksum: 10/10f5a1366e132c2446bf340fedb400350a982b867194006b5e3a7ae42f377264af0e8403fa1c45bf1257632a697011eceaea26a22b1e2fb9b0cff0c4f08dbaae + languageName: node + linkType: hard + "@opentelemetry/instrumentation-hapi@npm:0.57.0": version: 0.57.0 resolution: "@opentelemetry/instrumentation-hapi@npm:0.57.0" @@ -10185,7 +10183,7 @@ __metadata: languageName: node linkType: hard -"@opentelemetry/instrumentation-http@npm:0.211.0, @opentelemetry/instrumentation-http@npm:^0.211.0": +"@opentelemetry/instrumentation-http@npm:0.211.0": version: 0.211.0 resolution: "@opentelemetry/instrumentation-http@npm:0.211.0" dependencies: @@ -10199,7 +10197,21 @@ __metadata: languageName: node linkType: hard -"@opentelemetry/instrumentation-ioredis@npm:0.59.0, @opentelemetry/instrumentation-ioredis@npm:^0.59.0": +"@opentelemetry/instrumentation-http@npm:^0.212.0": + version: 0.212.0 + resolution: "@opentelemetry/instrumentation-http@npm:0.212.0" + dependencies: + "@opentelemetry/core": "npm:2.5.1" + "@opentelemetry/instrumentation": "npm:0.212.0" + "@opentelemetry/semantic-conventions": "npm:^1.29.0" + forwarded-parse: "npm:2.1.2" + peerDependencies: + "@opentelemetry/api": ^1.3.0 + checksum: 10/eb52699f645e9751d1f4addf406c6f6fd8276ac089abb2fd801077eda1bff6797fc9801b2d1ad856c10f4756c2c5cd562a92d1433932850b590362a6ced6e450 + languageName: node + linkType: hard + +"@opentelemetry/instrumentation-ioredis@npm:0.59.0": version: 0.59.0 resolution: "@opentelemetry/instrumentation-ioredis@npm:0.59.0" dependencies: @@ -10212,6 +10224,19 @@ __metadata: languageName: node linkType: hard +"@opentelemetry/instrumentation-ioredis@npm:^0.60.0": + version: 0.60.0 + resolution: "@opentelemetry/instrumentation-ioredis@npm:0.60.0" + dependencies: + "@opentelemetry/instrumentation": "npm:^0.212.0" + "@opentelemetry/redis-common": "npm:^0.38.2" + "@opentelemetry/semantic-conventions": "npm:^1.33.0" + peerDependencies: + "@opentelemetry/api": ^1.3.0 + checksum: 10/91842908425bd4f2a15ad80f32ec3eddb329caaaf74328a618efd5dde4152620ba2f5b608eaa9d33dd2f501bcaf0233527b1128be2ca1b772a118637264b2789 + languageName: node + linkType: hard + "@opentelemetry/instrumentation-kafkajs@npm:0.20.0": version: 0.20.0 resolution: "@opentelemetry/instrumentation-kafkajs@npm:0.20.0" @@ -10311,15 +10336,15 @@ __metadata: languageName: node linkType: hard -"@opentelemetry/instrumentation-nestjs-core@npm:^0.57.0": - version: 0.57.0 - resolution: "@opentelemetry/instrumentation-nestjs-core@npm:0.57.0" +"@opentelemetry/instrumentation-nestjs-core@npm:^0.58.0": + version: 0.58.0 + resolution: "@opentelemetry/instrumentation-nestjs-core@npm:0.58.0" dependencies: - "@opentelemetry/instrumentation": "npm:^0.211.0" + "@opentelemetry/instrumentation": "npm:^0.212.0" "@opentelemetry/semantic-conventions": "npm:^1.30.0" peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: 10/ae1f2fcd97729acde1341da07180ba20dfaaeb8534fade59d011264c40432406669ee24f60cf87791927da76d32d76c304279151b8b4d68f01d48ca19bc2cac1 + checksum: 10/3ea57cf8c33e97a021c0ea9bff4dc3fa7693921ae6b349f2e97668aeeac8a13bf6d88f99e5e610a69d75ed57da279d562e35450977d1121a7f3ba669b1167a7d languageName: node linkType: hard @@ -10352,14 +10377,14 @@ __metadata: languageName: node linkType: hard -"@opentelemetry/instrumentation-socket.io@npm:^0.57.0": - version: 0.57.0 - resolution: "@opentelemetry/instrumentation-socket.io@npm:0.57.0" +"@opentelemetry/instrumentation-socket.io@npm:^0.59.0": + version: 0.59.0 + resolution: "@opentelemetry/instrumentation-socket.io@npm:0.59.0" dependencies: - "@opentelemetry/instrumentation": "npm:^0.211.0" + "@opentelemetry/instrumentation": "npm:^0.212.0" peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: 10/237c883b99fa9ae6012de89ad4d8d8bb92ec846bd22724c478b47ec2cd85e4ac6d84398b4771ebb249999680255084faf0917fd976191a5550ea3e369dafaddb + checksum: 10/514991fd98feafd7d87cd9f9bdcb9f6049cf2da2950759012fbc1eccd6f745cd4938b3d739841d091316f46fcfb9c4595993e40921203f2064a9fc93e0bdf902 languageName: node linkType: hard @@ -10389,7 +10414,7 @@ __metadata: languageName: node linkType: hard -"@opentelemetry/instrumentation@npm:0.211.0, @opentelemetry/instrumentation@npm:>=0.52.0 <1, @opentelemetry/instrumentation@npm:^0.211.0": +"@opentelemetry/instrumentation@npm:0.211.0, @opentelemetry/instrumentation@npm:^0.211.0": version: 0.211.0 resolution: "@opentelemetry/instrumentation@npm:0.211.0" dependencies: @@ -10402,6 +10427,19 @@ __metadata: languageName: node linkType: hard +"@opentelemetry/instrumentation@npm:0.212.0, @opentelemetry/instrumentation@npm:>=0.52.0 <1, @opentelemetry/instrumentation@npm:^0.212.0": + version: 0.212.0 + resolution: "@opentelemetry/instrumentation@npm:0.212.0" + dependencies: + "@opentelemetry/api-logs": "npm:0.212.0" + import-in-the-middle: "npm:^2.0.6" + require-in-the-middle: "npm:^8.0.0" + peerDependencies: + "@opentelemetry/api": ^1.3.0 + checksum: 10/2798d096bb6e821853011f5020dfb284501eade727d1d9289c3d515189b2b2d7e549f41db760f21474d2b449ade6dbc0d2a26c137c44071c274f51d0cfae843b + languageName: node + linkType: hard + "@opentelemetry/instrumentation@npm:^0.207.0": version: 0.207.0 resolution: "@opentelemetry/instrumentation@npm:0.207.0" @@ -10428,68 +10466,68 @@ __metadata: languageName: node linkType: hard -"@opentelemetry/otlp-exporter-base@npm:0.211.0": - version: 0.211.0 - resolution: "@opentelemetry/otlp-exporter-base@npm:0.211.0" +"@opentelemetry/otlp-exporter-base@npm:0.212.0": + version: 0.212.0 + resolution: "@opentelemetry/otlp-exporter-base@npm:0.212.0" dependencies: - "@opentelemetry/core": "npm:2.5.0" - "@opentelemetry/otlp-transformer": "npm:0.211.0" + "@opentelemetry/core": "npm:2.5.1" + "@opentelemetry/otlp-transformer": "npm:0.212.0" peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: 10/c9c223bcd1cf64a27a74d30c7637679136e66717a9e42eaa217948df0230f9cd2cc7311b9201cd4717aa43c77fd92b867e91408c21aa3dd412be180573ae08b2 + checksum: 10/3b4229d3d67b947aa79719ba1b87b37afcf991facb077b188445ec7ffddca95fcdc3414507573783830fd4ad628c622b5f5c2146bded91da01accf7acaecc6b7 languageName: node linkType: hard -"@opentelemetry/otlp-grpc-exporter-base@npm:0.211.0": - version: 0.211.0 - resolution: "@opentelemetry/otlp-grpc-exporter-base@npm:0.211.0" +"@opentelemetry/otlp-grpc-exporter-base@npm:0.212.0": + version: 0.212.0 + resolution: "@opentelemetry/otlp-grpc-exporter-base@npm:0.212.0" dependencies: - "@grpc/grpc-js": "npm:^1.7.1" - "@opentelemetry/core": "npm:2.5.0" - "@opentelemetry/otlp-exporter-base": "npm:0.211.0" - "@opentelemetry/otlp-transformer": "npm:0.211.0" + "@grpc/grpc-js": "npm:^1.14.3" + "@opentelemetry/core": "npm:2.5.1" + "@opentelemetry/otlp-exporter-base": "npm:0.212.0" + "@opentelemetry/otlp-transformer": "npm:0.212.0" peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: 10/6bea591414e3cbe4739d274c504431e9ba37af606579d24d3fb834ffab20334f80e8dc67c0ca29a38acf4c457af229ac4fea4b44ff1e200238ece125d16418d6 + checksum: 10/9155dc652f8e0e25403a6bff45a2fed942f0a81c74f3605cbc76cc6818836da5967ee75b850b1fb2c963a36a8de836358a478914ddf3e20716d079a21cdb474c languageName: node linkType: hard -"@opentelemetry/otlp-transformer@npm:0.211.0": - version: 0.211.0 - resolution: "@opentelemetry/otlp-transformer@npm:0.211.0" +"@opentelemetry/otlp-transformer@npm:0.212.0": + version: 0.212.0 + resolution: "@opentelemetry/otlp-transformer@npm:0.212.0" dependencies: - "@opentelemetry/api-logs": "npm:0.211.0" - "@opentelemetry/core": "npm:2.5.0" - "@opentelemetry/resources": "npm:2.5.0" - "@opentelemetry/sdk-logs": "npm:0.211.0" - "@opentelemetry/sdk-metrics": "npm:2.5.0" - "@opentelemetry/sdk-trace-base": "npm:2.5.0" + "@opentelemetry/api-logs": "npm:0.212.0" + "@opentelemetry/core": "npm:2.5.1" + "@opentelemetry/resources": "npm:2.5.1" + "@opentelemetry/sdk-logs": "npm:0.212.0" + "@opentelemetry/sdk-metrics": "npm:2.5.1" + "@opentelemetry/sdk-trace-base": "npm:2.5.1" protobufjs: "npm:8.0.0" peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: 10/65f98ac066bb627e420ebc6671f89180a2771b0be1b34effe9d83ea02906c125533b38a262084849f3a05317889e0ca60d17dc956c37f622e1175345e7c00ac5 + checksum: 10/9fb7be33fd9d423f4e16edb83d62e2dc742453679ee648ecde26aa59ade12446f232bc7fb8ac4536bd52e45c5274ccedbc4b2dea23ad1c17af17c807495c3398 languageName: node linkType: hard -"@opentelemetry/propagator-b3@npm:2.5.0": - version: 2.5.0 - resolution: "@opentelemetry/propagator-b3@npm:2.5.0" +"@opentelemetry/propagator-b3@npm:2.5.1": + version: 2.5.1 + resolution: "@opentelemetry/propagator-b3@npm:2.5.1" dependencies: - "@opentelemetry/core": "npm:2.5.0" + "@opentelemetry/core": "npm:2.5.1" peerDependencies: "@opentelemetry/api": ">=1.0.0 <1.10.0" - checksum: 10/42acdebafb37be3aa76cf4a18a68aad77131f2ccf28014850502e8767b0ef21ef9b3fb47c784223d55ca5d691f920e0ab24438a8c7ef13bd58fa9c3ab5d3e57b + checksum: 10/c8ad9bba7c7321bb4eb27e1dd6cd045b769b211643d5f2a5155680857f2ba839e42da8a69b1281ded690a56075ba84050ac8632fe7eebb86180469a98cc6aee7 languageName: node linkType: hard -"@opentelemetry/propagator-jaeger@npm:2.5.0": - version: 2.5.0 - resolution: "@opentelemetry/propagator-jaeger@npm:2.5.0" +"@opentelemetry/propagator-jaeger@npm:2.5.1": + version: 2.5.1 + resolution: "@opentelemetry/propagator-jaeger@npm:2.5.1" dependencies: - "@opentelemetry/core": "npm:2.5.0" + "@opentelemetry/core": "npm:2.5.1" peerDependencies: "@opentelemetry/api": ">=1.0.0 <1.10.0" - checksum: 10/bf0a345c0925b361e0352cd08d3daf4bd597b477ef5c2ef1780660078c8bda162bdfe2a2962ef1488f8fec0a2178572dbffa99c516919b13e2e388f5a24ac395 + checksum: 10/1d24c7f564782998893790eb98bcb20c16bdfd095101597df1ce9a378ca31d5d0c4a346e0291a1dbc3415638887b224f3d43fb3f99709354cfb823f82d24cf00 languageName: node linkType: hard @@ -10500,18 +10538,6 @@ __metadata: languageName: node linkType: hard -"@opentelemetry/resources@npm:2.5.0": - version: 2.5.0 - resolution: "@opentelemetry/resources@npm:2.5.0" - dependencies: - "@opentelemetry/core": "npm:2.5.0" - "@opentelemetry/semantic-conventions": "npm:^1.29.0" - peerDependencies: - "@opentelemetry/api": ">=1.3.0 <1.10.0" - checksum: 10/0400e5db66c2bab05424b6701badd891cba61cf0a4c07a9c01d74ff131d27f5ea55846d2ae59af2eb9c3fb48e71097eacb529224f2c6498a0a2306dd8a890bbb - languageName: node - linkType: hard - "@opentelemetry/resources@npm:2.5.1, @opentelemetry/resources@npm:^2.2.0, @opentelemetry/resources@npm:^2.5.1": version: 2.5.1 resolution: "@opentelemetry/resources@npm:2.5.1" @@ -10524,79 +10550,66 @@ __metadata: languageName: node linkType: hard -"@opentelemetry/sdk-logs@npm:0.211.0": - version: 0.211.0 - resolution: "@opentelemetry/sdk-logs@npm:0.211.0" +"@opentelemetry/sdk-logs@npm:0.212.0": + version: 0.212.0 + resolution: "@opentelemetry/sdk-logs@npm:0.212.0" dependencies: - "@opentelemetry/api-logs": "npm:0.211.0" - "@opentelemetry/core": "npm:2.5.0" - "@opentelemetry/resources": "npm:2.5.0" + "@opentelemetry/api-logs": "npm:0.212.0" + "@opentelemetry/core": "npm:2.5.1" + "@opentelemetry/resources": "npm:2.5.1" peerDependencies: "@opentelemetry/api": ">=1.4.0 <1.10.0" - checksum: 10/fd7d4dcfaaee2a93751b2bc5ce504e27eafa66f93b903a7bc2ff9649b8804c1280ec488a51bf95814b0ff6bab827d156cdcd8c9633f0a51a8798710e3b95e825 + checksum: 10/15b0fe5ad1593ac3cb7933e0307b0efadafa6c100625126a1acf3bd3eaca537c95ca29863a32a383a93dd14ce427f23f98795beb5deb09b18772f7f0b453756d languageName: node linkType: hard -"@opentelemetry/sdk-metrics@npm:2.5.0, @opentelemetry/sdk-metrics@npm:^2.2.0": - version: 2.5.0 - resolution: "@opentelemetry/sdk-metrics@npm:2.5.0" +"@opentelemetry/sdk-metrics@npm:2.5.1, @opentelemetry/sdk-metrics@npm:^2.2.0": + version: 2.5.1 + resolution: "@opentelemetry/sdk-metrics@npm:2.5.1" dependencies: - "@opentelemetry/core": "npm:2.5.0" - "@opentelemetry/resources": "npm:2.5.0" + "@opentelemetry/core": "npm:2.5.1" + "@opentelemetry/resources": "npm:2.5.1" peerDependencies: "@opentelemetry/api": ">=1.9.0 <1.10.0" - checksum: 10/911399e56d0d4045ceafb83422bdffe0bfa9e8d75e542d746f18f22fe12654ae52efa5a8dc7fdfe17a6df906a3cf3886191ef655830efc578d70821200d55914 + checksum: 10/7ebdc04717e29358d97bc4dd8df0a3f847e5d449a52dc813eb6fe232e6fbd0cabb6e80cf1d83a06f9386d49261bd3c6d6b7fdfad14253441721ec2abe5d4153a languageName: node linkType: hard -"@opentelemetry/sdk-node@npm:^0.211.0": - version: 0.211.0 - resolution: "@opentelemetry/sdk-node@npm:0.211.0" +"@opentelemetry/sdk-node@npm:^0.212.0": + version: 0.212.0 + resolution: "@opentelemetry/sdk-node@npm:0.212.0" dependencies: - "@opentelemetry/api-logs": "npm:0.211.0" - "@opentelemetry/configuration": "npm:0.211.0" - "@opentelemetry/context-async-hooks": "npm:2.5.0" - "@opentelemetry/core": "npm:2.5.0" - "@opentelemetry/exporter-logs-otlp-grpc": "npm:0.211.0" - "@opentelemetry/exporter-logs-otlp-http": "npm:0.211.0" - "@opentelemetry/exporter-logs-otlp-proto": "npm:0.211.0" - "@opentelemetry/exporter-metrics-otlp-grpc": "npm:0.211.0" - "@opentelemetry/exporter-metrics-otlp-http": "npm:0.211.0" - "@opentelemetry/exporter-metrics-otlp-proto": "npm:0.211.0" - "@opentelemetry/exporter-prometheus": "npm:0.211.0" - "@opentelemetry/exporter-trace-otlp-grpc": "npm:0.211.0" - "@opentelemetry/exporter-trace-otlp-http": "npm:0.211.0" - "@opentelemetry/exporter-trace-otlp-proto": "npm:0.211.0" - "@opentelemetry/exporter-zipkin": "npm:2.5.0" - "@opentelemetry/instrumentation": "npm:0.211.0" - "@opentelemetry/propagator-b3": "npm:2.5.0" - "@opentelemetry/propagator-jaeger": "npm:2.5.0" - "@opentelemetry/resources": "npm:2.5.0" - "@opentelemetry/sdk-logs": "npm:0.211.0" - "@opentelemetry/sdk-metrics": "npm:2.5.0" - "@opentelemetry/sdk-trace-base": "npm:2.5.0" - "@opentelemetry/sdk-trace-node": "npm:2.5.0" + "@opentelemetry/api-logs": "npm:0.212.0" + "@opentelemetry/configuration": "npm:0.212.0" + "@opentelemetry/context-async-hooks": "npm:2.5.1" + "@opentelemetry/core": "npm:2.5.1" + "@opentelemetry/exporter-logs-otlp-grpc": "npm:0.212.0" + "@opentelemetry/exporter-logs-otlp-http": "npm:0.212.0" + "@opentelemetry/exporter-logs-otlp-proto": "npm:0.212.0" + "@opentelemetry/exporter-metrics-otlp-grpc": "npm:0.212.0" + "@opentelemetry/exporter-metrics-otlp-http": "npm:0.212.0" + "@opentelemetry/exporter-metrics-otlp-proto": "npm:0.212.0" + "@opentelemetry/exporter-prometheus": "npm:0.212.0" + "@opentelemetry/exporter-trace-otlp-grpc": "npm:0.212.0" + "@opentelemetry/exporter-trace-otlp-http": "npm:0.212.0" + "@opentelemetry/exporter-trace-otlp-proto": "npm:0.212.0" + "@opentelemetry/exporter-zipkin": "npm:2.5.1" + "@opentelemetry/instrumentation": "npm:0.212.0" + "@opentelemetry/propagator-b3": "npm:2.5.1" + "@opentelemetry/propagator-jaeger": "npm:2.5.1" + "@opentelemetry/resources": "npm:2.5.1" + "@opentelemetry/sdk-logs": "npm:0.212.0" + "@opentelemetry/sdk-metrics": "npm:2.5.1" + "@opentelemetry/sdk-trace-base": "npm:2.5.1" + "@opentelemetry/sdk-trace-node": "npm:2.5.1" "@opentelemetry/semantic-conventions": "npm:^1.29.0" peerDependencies: "@opentelemetry/api": ">=1.3.0 <1.10.0" - checksum: 10/895c5c6385a466db5e7d27f46263fa26ed57f152519fbdc9a4dbcbba20d241a89956ffd07d9be3c0b57900b7cb88f3116a3b69d0c7fabab997918cc4e30d31ba + checksum: 10/e596a14b66c26bc61e62d17ec54f0615070241eeef24328e560030d102e8517ed7a791564671f0337b366b7915eaabe3701f4d999a2b8f5a57ad5e3a21b74a19 languageName: node linkType: hard -"@opentelemetry/sdk-trace-base@npm:2.5.0": - version: 2.5.0 - resolution: "@opentelemetry/sdk-trace-base@npm:2.5.0" - dependencies: - "@opentelemetry/core": "npm:2.5.0" - "@opentelemetry/resources": "npm:2.5.0" - "@opentelemetry/semantic-conventions": "npm:^1.29.0" - peerDependencies: - "@opentelemetry/api": ">=1.3.0 <1.10.0" - checksum: 10/5a1f72ed8063d452755d9bf834f5b1c83afcaabf3382e8dc4d9f2987768b32097c9307f0fac8efc9f9ce9f1525ac66e5a21d51ae85ed2a426bf91ae1d26c51ed - languageName: node - linkType: hard - -"@opentelemetry/sdk-trace-base@npm:^2.5.1": +"@opentelemetry/sdk-trace-base@npm:2.5.1, @opentelemetry/sdk-trace-base@npm:^2.5.1": version: 2.5.1 resolution: "@opentelemetry/sdk-trace-base@npm:2.5.1" dependencies: @@ -10609,16 +10622,16 @@ __metadata: languageName: node linkType: hard -"@opentelemetry/sdk-trace-node@npm:2.5.0, @opentelemetry/sdk-trace-node@npm:^2.2.0": - version: 2.5.0 - resolution: "@opentelemetry/sdk-trace-node@npm:2.5.0" +"@opentelemetry/sdk-trace-node@npm:2.5.1, @opentelemetry/sdk-trace-node@npm:^2.2.0": + version: 2.5.1 + resolution: "@opentelemetry/sdk-trace-node@npm:2.5.1" dependencies: - "@opentelemetry/context-async-hooks": "npm:2.5.0" - "@opentelemetry/core": "npm:2.5.0" - "@opentelemetry/sdk-trace-base": "npm:2.5.0" + "@opentelemetry/context-async-hooks": "npm:2.5.1" + "@opentelemetry/core": "npm:2.5.1" + "@opentelemetry/sdk-trace-base": "npm:2.5.1" peerDependencies: "@opentelemetry/api": ">=1.0.0 <1.10.0" - checksum: 10/378380e9a5263259b9253538f110bd54c7f1343da02a449cfae3ca6610d69883ad3be33a1cd9e6330795e9a5aa6249af81e23cb9cd932310b37e5356ee0fb677 + checksum: 10/a525d14773c29056176fa3fcb16bd0b1c3f94ab0dbdb838238b58dd1fb6bf757aef86d4f2f07936a51611a01373baf017dbb7d606b9f33f049e7dffe60306b75 languageName: node linkType: hard @@ -31473,7 +31486,7 @@ __metadata: languageName: node linkType: hard -"protobufjs@npm:^7.2.5, protobufjs@npm:^7.5.3": +"protobufjs@npm:^7.5.3": version: 7.5.4 resolution: "protobufjs@npm:7.5.4" dependencies: @@ -34491,12 +34504,12 @@ __metadata: languageName: node linkType: hard -"systeminformation@npm:5.30.3": - version: 5.30.3 - resolution: "systeminformation@npm:5.30.3" +"systeminformation@npm:^5.31.1": + version: 5.31.1 + resolution: "systeminformation@npm:5.31.1" bin: systeminformation: lib/cli.js - checksum: 10/519970defecfaee8c001901624c7da155e50ba4d639467bcdead2f4e0e37ae9686ad9b9cd499976ebbbe4057584b08d6c92f518b8e76b08c427db2f98fb4126f + checksum: 10/1fff0b2827f7de2ec5379385c9bb12896db92186ee1d721cb08791ae7277a02f39fb8f3060df47312b70fe88c5b91a70726e7265ca8e5bab1f87780fb2acb991 conditions: (os=darwin | os=linux | os=win32 | os=freebsd | os=openbsd | os=netbsd | os=sunos | os=android) languageName: node linkType: hard From 4136abdd9721830b386bfb5c2896759590bb9f78 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 2 Mar 2026 06:25:51 +0800 Subject: [PATCH 10/49] chore: bump up rustc version to v1.93.1 (#14542) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Update | Change | |---|---|---| | [rustc](https://redirect.github.com/rust-lang/rust) | patch | `1.93.0` → `1.93.1` | --- ### Release Notes
rust-lang/rust (rustc) ### [`v1.93.1`](https://redirect.github.com/rust-lang/rust/blob/HEAD/RELEASES.md#Version-1931-2026-02-12) [Compare Source](https://redirect.github.com/rust-lang/rust/compare/1.93.0...1.93.1) \=========================== - [Don't try to recover keyword as non-keyword identifier](https://redirect.github.com/rust-lang/rust/pull/150590), fixing an ICE that especially [affected rustfmt](https://redirect.github.com/rust-lang/rustfmt/issues/6739). - [Fix `clippy::panicking_unwrap` false-positive on field access with implicit deref](https://redirect.github.com/rust-lang/rust-clippy/pull/16196). - [Revert "Update wasm-related dependencies in CI"](https://redirect.github.com/rust-lang/rust/pull/152259), fixing file descriptor leaks on the `wasm32-wasip2` target.
--- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/toeverything/AFFiNE). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- rust-toolchain.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain.toml b/rust-toolchain.toml index c976725f26..71223b6514 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,3 +1,3 @@ [toolchain] -channel = "1.93.0" +channel = "1.93.1" profile = "default" From fff63562b1696a4eb53bb282e1fe43ad087bd2a0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 2 Mar 2026 06:26:03 +0800 Subject: [PATCH 11/49] chore: bump up Lakr233/MarkdownView version to from: "3.6.3" (#14540) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Update | Change | |---|---|---| | [Lakr233/MarkdownView](https://redirect.github.com/Lakr233/MarkdownView) | patch | `from: "3.6.2"` → `from: "3.6.3"` | --- ### Release Notes
Lakr233/MarkdownView (Lakr233/MarkdownView) ### [`v3.6.3`](https://redirect.github.com/Lakr233/MarkdownView/compare/3.6.2...3.6.3) [Compare Source](https://redirect.github.com/Lakr233/MarkdownView/compare/3.6.2...3.6.3)
--- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/toeverything/AFFiNE). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .../frontend/apps/ios/App/Packages/Intelligents/Package.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/frontend/apps/ios/App/Packages/Intelligents/Package.swift b/packages/frontend/apps/ios/App/Packages/Intelligents/Package.swift index cf58c30f50..6c439e9e56 100644 --- a/packages/frontend/apps/ios/App/Packages/Intelligents/Package.swift +++ b/packages/frontend/apps/ios/App/Packages/Intelligents/Package.swift @@ -22,7 +22,7 @@ let package = Package( .package(url: "https://github.com/SwifterSwift/SwifterSwift.git", from: "6.2.0"), .package(url: "https://github.com/Recouse/EventSource.git", from: "0.1.5"), .package(url: "https://github.com/Lakr233/ListViewKit.git", from: "1.1.8"), - .package(url: "https://github.com/Lakr233/MarkdownView.git", from: "3.6.2"), + .package(url: "https://github.com/Lakr233/MarkdownView.git", from: "3.6.3"), ], targets: [ .target(name: "Intelligents", dependencies: [ From d5245a32735cb2a0a6ecfc1b9ce78d5d4e9d3b72 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 2 Mar 2026 06:26:20 +0800 Subject: [PATCH 12/49] chore: bump up Recouse/EventSource version to from: "0.1.7" (#14541) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Update | Change | |---|---|---| | [Recouse/EventSource](https://redirect.github.com/Recouse/EventSource) | patch | `from: "0.1.5"` → `from: "0.1.7"` | --- ### Release Notes
Recouse/EventSource (Recouse/EventSource) ### [`v0.1.7`](https://redirect.github.com/Recouse/EventSource/releases/tag/0.1.7) [Compare Source](https://redirect.github.com/Recouse/EventSource/compare/0.1.6...0.1.7) #### What's Changed - Separate timeout interval values for request and resource by [@​Recouse](https://redirect.github.com/Recouse) in [#​46](https://redirect.github.com/Recouse/EventSource/pull/46) **Full Changelog**: ### [`v0.1.6`](https://redirect.github.com/Recouse/EventSource/releases/tag/0.1.6) [Compare Source](https://redirect.github.com/Recouse/EventSource/compare/0.1.5...0.1.6) #### What's Changed - Fix visionOS availability error for split(by:) method by [@​danielseidl](https://redirect.github.com/danielseidl) in [#​45](https://redirect.github.com/Recouse/EventSource/pull/45) #### New Contributors - [@​danielseidl](https://redirect.github.com/danielseidl) made their first contribution in [#​45](https://redirect.github.com/Recouse/EventSource/pull/45) **Full Changelog**:
--- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/toeverything/AFFiNE). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .../frontend/apps/ios/App/Packages/Intelligents/Package.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/frontend/apps/ios/App/Packages/Intelligents/Package.swift b/packages/frontend/apps/ios/App/Packages/Intelligents/Package.swift index 6c439e9e56..b62c113c59 100644 --- a/packages/frontend/apps/ios/App/Packages/Intelligents/Package.swift +++ b/packages/frontend/apps/ios/App/Packages/Intelligents/Package.swift @@ -20,7 +20,7 @@ let package = Package( .package(url: "https://github.com/apple/swift-collections.git", from: "1.3.0"), .package(url: "https://github.com/SnapKit/SnapKit.git", from: "5.7.1"), .package(url: "https://github.com/SwifterSwift/SwifterSwift.git", from: "6.2.0"), - .package(url: "https://github.com/Recouse/EventSource.git", from: "0.1.5"), + .package(url: "https://github.com/Recouse/EventSource.git", from: "0.1.7"), .package(url: "https://github.com/Lakr233/ListViewKit.git", from: "1.1.8"), .package(url: "https://github.com/Lakr233/MarkdownView.git", from: "3.6.3"), ], From 2b6146727b03234596b85f364489ee1da187fdc2 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 2 Mar 2026 08:48:25 +0800 Subject: [PATCH 13/49] chore: bump up RevenueCat/purchases-ios-spm version to from: "5.60.0" (#14545) --- .../frontend/apps/ios/App/Packages/AffinePaywall/Package.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/frontend/apps/ios/App/Packages/AffinePaywall/Package.swift b/packages/frontend/apps/ios/App/Packages/AffinePaywall/Package.swift index f46195b783..964d063ccd 100644 --- a/packages/frontend/apps/ios/App/Packages/AffinePaywall/Package.swift +++ b/packages/frontend/apps/ios/App/Packages/AffinePaywall/Package.swift @@ -17,7 +17,7 @@ let package = Package( ], dependencies: [ .package(path: "../AffineResources"), - .package(url: "https://github.com/RevenueCat/purchases-ios-spm.git", from: "5.58.0"), + .package(url: "https://github.com/RevenueCat/purchases-ios-spm.git", from: "5.60.0"), ], targets: [ .target( From 342451be1bc242373e34b9f7f64193131a62b5e4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 2 Mar 2026 10:44:37 +0800 Subject: [PATCH 14/49] chore: bump up actions/attest-build-provenance action to v4 (#14547) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [actions/attest-build-provenance](https://redirect.github.com/actions/attest-build-provenance) | action | major | `v2` → `v4` | --- ### Release Notes
actions/attest-build-provenance (actions/attest-build-provenance) ### [`v4`](https://redirect.github.com/actions/attest-build-provenance/compare/v3...v4) [Compare Source](https://redirect.github.com/actions/attest-build-provenance/compare/v3...v4) ### [`v3`](https://redirect.github.com/actions/attest-build-provenance/compare/v2...v3) [Compare Source](https://redirect.github.com/actions/attest-build-provenance/compare/v2...v3)
--- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/toeverything/AFFiNE). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/release-desktop-platform.yml | 4 ++-- .github/workflows/release-desktop.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/release-desktop-platform.yml b/.github/workflows/release-desktop-platform.yml index 91b8e761bd..a553a87aa2 100644 --- a/.github/workflows/release-desktop-platform.yml +++ b/.github/workflows/release-desktop-platform.yml @@ -178,14 +178,14 @@ jobs: mv packages/frontend/apps/electron/out/*/make/deb/${{ inputs.arch }}/*.deb ./builds/affine-${{ env.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-linux-${{ inputs.arch }}.deb mv packages/frontend/apps/electron/out/*/make/flatpak/*/*.flatpak ./builds/affine-${{ env.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-linux-${{ inputs.arch }}.flatpak - - uses: actions/attest-build-provenance@v2 + - uses: actions/attest-build-provenance@v4 if: ${{ inputs.platform == 'darwin' }} with: subject-path: | ./builds/affine-${{ env.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-macos-${{ inputs.arch }}.zip ./builds/affine-${{ env.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-macos-${{ inputs.arch }}.dmg - - uses: actions/attest-build-provenance@v2 + - uses: actions/attest-build-provenance@v4 if: ${{ inputs.platform == 'linux' }} with: subject-path: | diff --git a/.github/workflows/release-desktop.yml b/.github/workflows/release-desktop.yml index 275265b1b3..915c25b2a5 100644 --- a/.github/workflows/release-desktop.yml +++ b/.github/workflows/release-desktop.yml @@ -344,7 +344,7 @@ jobs: mv packages/frontend/apps/electron/out/*/make/squirrel.windows/${{ matrix.spec.arch }}/*.exe ./builds/affine-${{ env.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-windows-${{ matrix.spec.arch }}.exe mv packages/frontend/apps/electron/out/*/make/nsis.windows/${{ matrix.spec.arch }}/*.exe ./builds/affine-${{ env.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-windows-${{ matrix.spec.arch }}.nsis.exe - - uses: actions/attest-build-provenance@v2 + - uses: actions/attest-build-provenance@v4 with: subject-path: | ./builds/affine-${{ env.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-windows-${{ matrix.spec.arch }}.zip From 784382cfb16289e11a5518f8802ec77bd62d904b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 2 Mar 2026 10:58:27 +0800 Subject: [PATCH 15/49] chore: bump up actions/cache action to v5 (#14549) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [actions/cache](https://redirect.github.com/actions/cache) | action | major | `v4` → `v5` | --- ### Release Notes
actions/cache (actions/cache) ### [`v5`](https://redirect.github.com/actions/cache/compare/v4...v5) [Compare Source](https://redirect.github.com/actions/cache/compare/v4...v5)
--- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/toeverything/AFFiNE). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/actions/setup-node/action.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/actions/setup-node/action.yml b/.github/actions/setup-node/action.yml index 78ce827954..efb3d5f688 100644 --- a/.github/actions/setup-node/action.yml +++ b/.github/actions/setup-node/action.yml @@ -93,7 +93,7 @@ runs: run: node -e "const p = $(yarn config cacheFolder --json).effective; console.log('yarn_global_cache=' + p)" >> $GITHUB_OUTPUT - name: Cache non-full yarn cache on Linux - uses: actions/cache@v4 + uses: actions/cache@v5 if: ${{ inputs.full-cache != 'true' && runner.os == 'Linux' }} with: path: | @@ -105,7 +105,7 @@ runs: # and the decompression performance on Windows is very terrible # so we reduce the number of cached files on non-Linux systems by remove node_modules from cache path. - name: Cache non-full yarn cache on non-Linux - uses: actions/cache@v4 + uses: actions/cache@v5 if: ${{ inputs.full-cache != 'true' && runner.os != 'Linux' }} with: path: | @@ -113,7 +113,7 @@ runs: key: node_modules-cache-${{ github.job }}-${{ runner.os }}-${{ runner.arch }}-${{ steps.system-info.outputs.name }}-${{ steps.system-info.outputs.release }}-${{ steps.system-info.outputs.version }} - name: Cache full yarn cache on Linux - uses: actions/cache@v4 + uses: actions/cache@v5 if: ${{ inputs.full-cache == 'true' && runner.os == 'Linux' }} with: path: | @@ -122,7 +122,7 @@ runs: key: node_modules-cache-full-${{ runner.os }}-${{ runner.arch }}-${{ steps.system-info.outputs.name }}-${{ steps.system-info.outputs.release }}-${{ steps.system-info.outputs.version }} - name: Cache full yarn cache on non-Linux - uses: actions/cache@v4 + uses: actions/cache@v5 if: ${{ inputs.full-cache == 'true' && runner.os != 'Linux' }} with: path: | @@ -154,7 +154,7 @@ runs: # Note: Playwright's cache directory is hard coded because that's what it # says to do in the docs. There doesn't appear to be a command that prints # it out for us. - - uses: actions/cache@v4 + - uses: actions/cache@v5 id: playwright-cache if: ${{ inputs.playwright-install == 'true' }} with: @@ -189,7 +189,7 @@ runs: run: | echo "version=$(yarn why --json electron | grep -h 'workspace:.' | jq --raw-output '.children[].locator' | sed -e 's/@playwright\/test@.*://' | head -n 1)" >> $GITHUB_OUTPUT - - uses: actions/cache@v4 + - uses: actions/cache@v5 id: electron-cache if: ${{ inputs.electron-install == 'true' }} with: From 78f567a17892382589a78c0ad5206bdc4dadb0f4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 2 Mar 2026 10:58:53 +0800 Subject: [PATCH 16/49] chore: bump up actions/checkout action to v6 (#14550) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [actions/checkout](https://redirect.github.com/actions/checkout) | action | major | `v4` → `v6` | --- ### Release Notes
actions/checkout (actions/checkout) ### [`v6`](https://redirect.github.com/actions/checkout/compare/v5...v6) [Compare Source](https://redirect.github.com/actions/checkout/compare/v5...v6) ### [`v5`](https://redirect.github.com/actions/checkout/compare/v4...v5) [Compare Source](https://redirect.github.com/actions/checkout/compare/v4...v5)
--- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/toeverything/AFFiNE). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/auto-labeler.yml | 2 +- .github/workflows/build-images.yml | 12 ++-- .github/workflows/build-test.yml | 60 +++++++++---------- .github/workflows/copilot-test.yml | 8 +-- .github/workflows/pr-title-lint.yml | 2 +- .github/workflows/release-cloud.yml | 2 +- .../workflows/release-desktop-platform.yml | 2 +- .github/workflows/release-desktop.yml | 6 +- .github/workflows/release-mobile.yml | 8 +-- .github/workflows/release.yml | 2 +- 10 files changed, 52 insertions(+), 52 deletions(-) diff --git a/.github/workflows/auto-labeler.yml b/.github/workflows/auto-labeler.yml index 010a7eadf3..6922e4b3df 100644 --- a/.github/workflows/auto-labeler.yml +++ b/.github/workflows/auto-labeler.yml @@ -13,5 +13,5 @@ jobs: pull-requests: write runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - uses: actions/labeler@v5 diff --git a/.github/workflows/build-images.yml b/.github/workflows/build-images.yml index dd5d84fea3..a0cc9f667e 100644 --- a/.github/workflows/build-images.yml +++ b/.github/workflows/build-images.yml @@ -24,7 +24,7 @@ jobs: runs-on: ubuntu-latest environment: ${{ inputs.build-type }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Setup Version uses: ./.github/actions/setup-version with: @@ -57,7 +57,7 @@ jobs: runs-on: ubuntu-latest environment: ${{ inputs.build-type }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Setup Version uses: ./.github/actions/setup-version with: @@ -89,7 +89,7 @@ jobs: runs-on: ubuntu-latest environment: ${{ inputs.build-type }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Setup Version uses: ./.github/actions/setup-version with: @@ -132,7 +132,7 @@ jobs: file: server-native.armv7.node steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Setup Version uses: ./.github/actions/setup-version with: @@ -166,7 +166,7 @@ jobs: needs: - build-server-native steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Setup Version uses: ./.github/actions/setup-version with: @@ -202,7 +202,7 @@ jobs: - build-mobile - build-admin steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Download server dist uses: actions/download-artifact@v4 with: diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml index 8704e60108..46fd230d3e 100644 --- a/.github/workflows/build-test.yml +++ b/.github/workflows/build-test.yml @@ -46,7 +46,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Initialize CodeQL uses: github/codeql-action/init@v3 @@ -67,7 +67,7 @@ jobs: name: Lint runs-on: ubuntu-24.04-arm steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Setup Go (for actionlint) uses: actions/setup-go@v5 with: @@ -111,7 +111,7 @@ jobs: env: NODE_OPTIONS: --max-old-space-size=14384 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Setup Node.js uses: ./.github/actions/setup-node with: @@ -138,7 +138,7 @@ jobs: outputs: run-rust: ${{ steps.rust-filter.outputs.rust }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - uses: dorny/paths-filter@v3 id: rust-filter @@ -159,7 +159,7 @@ jobs: needs: - rust-test-filter steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - uses: ./.github/actions/build-rust with: target: x86_64-unknown-linux-gnu @@ -182,7 +182,7 @@ jobs: needs: - build-server-native steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Setup Node.js uses: ./.github/actions/setup-node with: @@ -212,7 +212,7 @@ jobs: name: Check yarn binary runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Run check run: | set -euo pipefail @@ -228,7 +228,7 @@ jobs: matrix: shard: [1, 2] steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Setup Node.js uses: ./.github/actions/setup-node with: @@ -256,7 +256,7 @@ jobs: name: E2E BlockSuite Cross Browser Test runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Setup Node.js uses: ./.github/actions/setup-node with: @@ -294,7 +294,7 @@ jobs: matrix: shard: [1, 2, 3, 4, 5] steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Setup Node.js uses: ./.github/actions/setup-node with: @@ -326,7 +326,7 @@ jobs: matrix: shard: [1, 2] steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Setup Node.js uses: ./.github/actions/setup-node with: @@ -358,7 +358,7 @@ jobs: matrix: shard: [1, 2, 3] steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Setup Node.js uses: ./.github/actions/setup-node with: @@ -391,7 +391,7 @@ jobs: env: CARGO_PROFILE_RELEASE_DEBUG: '1' steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Setup Node.js uses: ./.github/actions/setup-node with: @@ -430,7 +430,7 @@ jobs: - { os: macos-latest, target: aarch64-apple-darwin } steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Setup Node.js uses: ./.github/actions/setup-node with: @@ -471,7 +471,7 @@ jobs: - { os: windows-latest, target: aarch64-pc-windows-msvc } steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - uses: samypr100/setup-dev-drive@v3 with: workspace-copy: true @@ -511,7 +511,7 @@ jobs: env: CARGO_PROFILE_RELEASE_DEBUG: '1' steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Setup Node.js uses: ./.github/actions/setup-node with: @@ -534,7 +534,7 @@ jobs: name: Build @affine/electron renderer runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Setup Node.js uses: ./.github/actions/setup-node with: @@ -561,7 +561,7 @@ jobs: needs: - build-native-linux steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Setup Node.js uses: ./.github/actions/setup-node with: @@ -615,7 +615,7 @@ jobs: ports: - 9308:9308 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Setup Node.js uses: ./.github/actions/setup-node @@ -696,7 +696,7 @@ jobs: stack-version: 9.0.1 security-enabled: false - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Setup Node.js uses: ./.github/actions/setup-node @@ -759,7 +759,7 @@ jobs: ports: - 9308:9308 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Setup Node.js uses: ./.github/actions/setup-node @@ -800,7 +800,7 @@ jobs: CARGO_TERM_COLOR: always MIRIFLAGS: -Zmiri-backtrace=full -Zmiri-tree-borrows steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Setup Rust uses: dtolnay/rust-toolchain@stable @@ -828,7 +828,7 @@ jobs: RUST_BACKTRACE: full CARGO_TERM_COLOR: always steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Setup Rust uses: dtolnay/rust-toolchain@stable @@ -852,7 +852,7 @@ jobs: env: CARGO_TERM_COLOR: always steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Setup Rust uses: dtolnay/rust-toolchain@stable @@ -891,7 +891,7 @@ jobs: env: CARGO_TERM_COLOR: always steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Setup Rust uses: ./.github/actions/build-rust with: @@ -914,7 +914,7 @@ jobs: run-api: ${{ steps.decision.outputs.run_api }} run-e2e: ${{ steps.decision.outputs.run_e2e }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - uses: dorny/paths-filter@v3 id: copilot-filter @@ -983,7 +983,7 @@ jobs: ports: - 9308:9308 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Setup Node.js uses: ./.github/actions/setup-node @@ -1056,7 +1056,7 @@ jobs: ports: - 9308:9308 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Setup Node.js uses: ./.github/actions/setup-node @@ -1139,7 +1139,7 @@ jobs: ports: - 9308:9308 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Setup Node.js uses: ./.github/actions/setup-node @@ -1220,7 +1220,7 @@ jobs: test: true, } steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Setup Node.js uses: ./.github/actions/setup-node timeout-minutes: 10 diff --git a/.github/workflows/copilot-test.yml b/.github/workflows/copilot-test.yml index 066ea81bda..24773fca17 100644 --- a/.github/workflows/copilot-test.yml +++ b/.github/workflows/copilot-test.yml @@ -10,7 +10,7 @@ jobs: env: CARGO_PROFILE_RELEASE_DEBUG: '1' steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Setup Node.js uses: ./.github/actions/setup-node with: @@ -64,7 +64,7 @@ jobs: ports: - 9308:9308 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Setup Node.js uses: ./.github/actions/setup-node @@ -134,7 +134,7 @@ jobs: ports: - 9308:9308 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Setup Node.js uses: ./.github/actions/setup-node @@ -167,7 +167,7 @@ jobs: runs-on: ubuntu-latest name: Post test result message steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 with: fetch-depth: 0 - name: Setup Node.js diff --git a/.github/workflows/pr-title-lint.yml b/.github/workflows/pr-title-lint.yml index d8d9044dcb..ea5480692c 100644 --- a/.github/workflows/pr-title-lint.yml +++ b/.github/workflows/pr-title-lint.yml @@ -18,7 +18,7 @@ jobs: runs-on: ubuntu-latest if: ${{ github.event.action != 'edited' || github.event.changes.title != null }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Setup Node.js uses: actions/setup-node@v4 with: diff --git a/.github/workflows/release-cloud.yml b/.github/workflows/release-cloud.yml index 18b046e71a..dc9ea56fc7 100644 --- a/.github/workflows/release-cloud.yml +++ b/.github/workflows/release-cloud.yml @@ -35,7 +35,7 @@ jobs: - build-images runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Deploy to ${{ inputs.build-type }} uses: ./.github/actions/deploy with: diff --git a/.github/workflows/release-desktop-platform.yml b/.github/workflows/release-desktop-platform.yml index a553a87aa2..b068a1908b 100644 --- a/.github/workflows/release-desktop-platform.yml +++ b/.github/workflows/release-desktop-platform.yml @@ -69,7 +69,7 @@ jobs: SENTRY_DSN: ${{ secrets.SENTRY_DSN }} SENTRY_RELEASE: ${{ inputs.app_version }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Setup Version uses: ./.github/actions/setup-version diff --git a/.github/workflows/release-desktop.yml b/.github/workflows/release-desktop.yml index 915c25b2a5..a1890955f7 100644 --- a/.github/workflows/release-desktop.yml +++ b/.github/workflows/release-desktop.yml @@ -48,7 +48,7 @@ jobs: runs-on: ubuntu-latest environment: ${{ inputs.build-type }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Setup Version uses: ./.github/actions/setup-version with: @@ -187,7 +187,7 @@ jobs: FILES_TO_BE_SIGNED_x64: ${{ steps.get_files_to_be_signed.outputs.FILES_TO_BE_SIGNED_x64 }} FILES_TO_BE_SIGNED_arm64: ${{ steps.get_files_to_be_signed.outputs.FILES_TO_BE_SIGNED_arm64 }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Setup Version uses: ./.github/actions/setup-version with: @@ -369,7 +369,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Download Artifacts (macos-x64) uses: actions/download-artifact@v4 with: diff --git a/.github/workflows/release-mobile.yml b/.github/workflows/release-mobile.yml index cffad397c6..327c8963f2 100644 --- a/.github/workflows/release-mobile.yml +++ b/.github/workflows/release-mobile.yml @@ -26,7 +26,7 @@ jobs: runs-on: ubuntu-latest environment: ${{ inputs.build-type }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Setup Version uses: ./.github/actions/setup-version with: @@ -54,7 +54,7 @@ jobs: build-android-web: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Setup Version uses: ./.github/actions/setup-version with: @@ -83,7 +83,7 @@ jobs: needs: - build-ios-web steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Setup Version uses: ./.github/actions/setup-version with: @@ -147,7 +147,7 @@ jobs: needs: - build-android-web steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Setup Version uses: ./.github/actions/setup-version with: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 98c0db20f9..6b9093874d 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -55,7 +55,7 @@ jobs: GIT_SHORT_HASH: ${{ steps.prepare.outputs.GIT_SHORT_HASH }} BUILD_TYPE: ${{ steps.prepare.outputs.BUILD_TYPE }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Prepare Release id: prepare uses: ./.github/actions/prepare-release From 60acd81d4b8a7d9e72dcebd1002917d60b208898 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 2 Mar 2026 11:59:25 +0800 Subject: [PATCH 17/49] chore: bump up actions/labeler action to v6 (#14552) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [actions/labeler](https://redirect.github.com/actions/labeler) | action | major | `v5` → `v6` | --- ### Release Notes
actions/labeler (actions/labeler) ### [`v6`](https://redirect.github.com/actions/labeler/compare/v5...v6) [Compare Source](https://redirect.github.com/actions/labeler/compare/v5...v6)
--- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/toeverything/AFFiNE). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/auto-labeler.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/auto-labeler.yml b/.github/workflows/auto-labeler.yml index 6922e4b3df..f45b177645 100644 --- a/.github/workflows/auto-labeler.yml +++ b/.github/workflows/auto-labeler.yml @@ -14,4 +14,4 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 - - uses: actions/labeler@v5 + - uses: actions/labeler@v6 From c5d622531cede9abf9b8aaef1a375aaa59083ba0 Mon Sep 17 00:00:00 2001 From: DarkSky <25152247+darkskygit@users.noreply.github.com> Date: Mon, 2 Mar 2026 13:57:55 +0800 Subject: [PATCH 18/49] feat: refactor copilot module (#14537) --- .docker/selfhost/schema.json | 10 + Cargo.lock | 515 +++++++++++- Cargo.toml | 1 + .../blocks/bookmark/src/bookmark-block.ts | 4 +- .../components/src/link-preview/link.ts | 22 +- .../src/footnote-node/footnote-node.ts | 5 +- blocksuite/affine/shared/src/utils/url.ts | 6 + package.json | 2 +- packages/backend/native/Cargo.toml | 3 + packages/backend/native/index.d.ts | 8 + packages/backend/native/src/lib.rs | 1 + packages/backend/native/src/llm.rs | 339 ++++++++ packages/backend/server/package.json | 8 +- .../__snapshots__/copilot.e2e.ts.snap | Bin 1167 -> 0 bytes .../__tests__/__snapshots__/worker.e2e.ts.md | 4 +- .../__snapshots__/worker.e2e.ts.snap | Bin 950 -> 1005 bytes .../__snapshots__/copilot.e2e.ts.md | 8 +- .../copilot/__snapshots__/copilot.e2e.ts.snap | Bin 0 -> 1175 bytes .../__snapshots__/copilot.spec.ts.md | 0 .../__snapshots__/copilot.spec.ts.snap | Bin .../{ => copilot}/copilot-provider.spec.ts | 24 +- .../__tests__/{ => copilot}/copilot.e2e.ts | 40 +- .../__tests__/{ => copilot}/copilot.spec.ts | 139 +++- .../__tests__/copilot/native-adapter.spec.ts | 210 +++++ .../copilot/provider-middleware.spec.ts | 56 ++ .../__tests__/copilot/provider-native.spec.ts | 99 +++ .../copilot/provider-registry.spec.ts | 165 ++++ .../__tests__/copilot/tool-call-loop.spec.ts | 134 ++++ .../src/__tests__/copilot/utils.spec.ts | 116 +++ .../server/src/__tests__/native.spec.ts | 82 ++ .../server/src/__tests__/utils/copilot.ts | 25 +- .../server/src/__tests__/worker.e2e.ts | 80 +- .../server/src/core/telemetry/ga4-client.ts | 14 +- packages/backend/server/src/native.ts | 313 ++++++++ .../server/src/plugins/copilot/config.ts | 188 ++++- .../server/src/plugins/copilot/controller.ts | 58 -- .../src/plugins/copilot/prompt/prompts.ts | 9 +- .../src/plugins/copilot/prompt/service.ts | 290 +++++-- .../copilot/providers/anthropic/anthropic.ts | 244 +++--- .../copilot/providers/anthropic/official.ts | 10 - .../copilot/providers/anthropic/vertex.ts | 9 +- .../src/plugins/copilot/providers/factory.ts | 221 ++++- .../src/plugins/copilot/providers/loop.ts | 381 +++++++++ .../src/plugins/copilot/providers/morph.ts | 137 ++-- .../src/plugins/copilot/providers/native.ts | 464 +++++++++++ .../src/plugins/copilot/providers/openai.ts | 755 +++++++++++------- .../plugins/copilot/providers/perplexity.ts | 195 ++--- .../copilot/providers/provider-middleware.ts | 98 +++ .../copilot/providers/provider-registry.ts | 273 +++++++ .../src/plugins/copilot/providers/provider.ts | 73 +- .../src/plugins/copilot/providers/utils.ts | 72 +- .../server/src/plugins/copilot/resolver.ts | 165 +--- .../server/src/plugins/copilot/session.ts | 40 +- .../src/plugins/copilot/tools/blob-read.ts | 18 +- .../server/src/plugins/worker/controller.ts | 86 +- packages/backend/server/src/schema.gql | 62 +- .../src/graphql/admin/copilot-prompt-list.gql | 18 - .../graphql/admin/copilot-prompt-update.gql | 21 - .../copilot-history-list-doc-sessions.gql | 2 +- .../copilot-history-list-pinned-session.gql | 2 +- ...opilot-history-list-workspace-sessions.gql | 2 +- .../src/graphql/copilot-history-list.gql | 2 +- .../copilot-session-create-with-history.gql | 7 + .../copilot-session-get-latest-doc.gql | 2 +- .../src/graphql/copilot-session-get.gql | 2 +- .../graphql/copilot-session-list-recent.gql | 2 +- .../src/graphql/copilot-sessions-get.gql | 2 +- .../fragments/copilot-chat-history.gql | 30 + .../graphql/src/graphql/fragments/copilot.gql | 49 -- .../fragments/paginated-copilot-chats.gql | 16 + packages/common/graphql/src/graphql/index.ts | 131 +-- packages/common/graphql/src/schema.ts | 294 +++---- packages/frontend/admin/src/config.json | 8 + .../admin/src/modules/ai/edit-prompt.tsx | 146 ---- .../frontend/admin/src/modules/ai/index.tsx | 1 - .../frontend/admin/src/modules/ai/prompts.tsx | 108 --- .../admin/src/modules/ai/use-prompt.ts | 51 -- .../core/src/blocksuite/ai/actions/types.ts | 3 + .../ai-chat-toolbar/ai-session-history.ts | 14 +- .../src/blocksuite/ai/provider/ai-provider.ts | 2 + .../blocksuite/ai/provider/copilot-client.ts | 56 +- .../src/blocksuite/ai/provider/request.ts | 148 ++-- .../blocksuite/ai/provider/setup-provider.tsx | 17 +- .../providers/workspace-side-effects.tsx | 9 +- .../desktop/pages/workspace/chat/index.tsx | 163 ++-- .../pages/workspace/detail-page/tabs/chat.tsx | 132 +-- .../e2e/ai-action/explain-code.spec.ts | 2 +- .../e2e/chat-with/attachments.spec.ts | 5 +- .../e2e/settings/embedding.spec.ts | 29 +- .../e2e/utils/chat-panel-utils.ts | 128 ++- .../e2e/utils/editor-utils.ts | 2 +- yarn.lock | 42 +- 92 files changed, 5759 insertions(+), 2170 deletions(-) create mode 100644 packages/backend/native/src/llm.rs delete mode 100644 packages/backend/server/src/__tests__/__snapshots__/copilot.e2e.ts.snap rename packages/backend/server/src/__tests__/{ => copilot}/__snapshots__/copilot.e2e.ts.md (95%) create mode 100644 packages/backend/server/src/__tests__/copilot/__snapshots__/copilot.e2e.ts.snap rename packages/backend/server/src/__tests__/{ => copilot}/__snapshots__/copilot.spec.ts.md (100%) rename packages/backend/server/src/__tests__/{ => copilot}/__snapshots__/copilot.spec.ts.snap (100%) rename packages/backend/server/src/__tests__/{ => copilot}/copilot-provider.spec.ts (97%) rename packages/backend/server/src/__tests__/{ => copilot}/copilot.e2e.ts (97%) rename packages/backend/server/src/__tests__/{ => copilot}/copilot.spec.ts (94%) create mode 100644 packages/backend/server/src/__tests__/copilot/native-adapter.spec.ts create mode 100644 packages/backend/server/src/__tests__/copilot/provider-middleware.spec.ts create mode 100644 packages/backend/server/src/__tests__/copilot/provider-native.spec.ts create mode 100644 packages/backend/server/src/__tests__/copilot/provider-registry.spec.ts create mode 100644 packages/backend/server/src/__tests__/copilot/tool-call-loop.spec.ts create mode 100644 packages/backend/server/src/__tests__/copilot/utils.spec.ts create mode 100644 packages/backend/server/src/__tests__/native.spec.ts create mode 100644 packages/backend/server/src/plugins/copilot/providers/loop.ts create mode 100644 packages/backend/server/src/plugins/copilot/providers/native.ts create mode 100644 packages/backend/server/src/plugins/copilot/providers/provider-middleware.ts create mode 100644 packages/backend/server/src/plugins/copilot/providers/provider-registry.ts delete mode 100644 packages/common/graphql/src/graphql/admin/copilot-prompt-list.gql delete mode 100644 packages/common/graphql/src/graphql/admin/copilot-prompt-update.gql create mode 100644 packages/common/graphql/src/graphql/copilot-session-create-with-history.gql create mode 100644 packages/common/graphql/src/graphql/fragments/copilot-chat-history.gql delete mode 100644 packages/common/graphql/src/graphql/fragments/copilot.gql create mode 100644 packages/common/graphql/src/graphql/fragments/paginated-copilot-chats.gql delete mode 100644 packages/frontend/admin/src/modules/ai/edit-prompt.tsx delete mode 100644 packages/frontend/admin/src/modules/ai/prompts.tsx delete mode 100644 packages/frontend/admin/src/modules/ai/use-prompt.ts diff --git a/.docker/selfhost/schema.json b/.docker/selfhost/schema.json index ef819a6089..1feba431ba 100644 --- a/.docker/selfhost/schema.json +++ b/.docker/selfhost/schema.json @@ -988,6 +988,16 @@ } } }, + "providers.profiles": { + "type": "array", + "description": "The profile list for copilot providers.\n@default []", + "default": [] + }, + "providers.defaults": { + "type": "object", + "description": "The default provider ids for model output types and global fallback.\n@default {}", + "default": {} + }, "providers.openai": { "type": "object", "description": "The config for the openai provider.\n@default {\"apiKey\":\"\",\"baseURL\":\"https://api.openai.com/v1\"}\n@link https://github.com/openai/openai-node", diff --git a/Cargo.lock b/Cargo.lock index cee519b41d..f5fa565556 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -181,6 +181,7 @@ dependencies = [ "chrono", "file-format", "infer", + "llm_adapter", "mimalloc", "mp4parse", "napi", @@ -188,6 +189,8 @@ dependencies = [ "napi-derive", "rand 0.9.2", "rayon", + "serde", + "serde_json", "sha3", "tiktoken-rs", "tokio", @@ -245,7 +248,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed7572b7ba83a31e20d1b48970ee402d2e3e0537dcfe0a3ff4d6eb7508617d43" dependencies = [ "alsa-sys", - "bitflags 2.10.0", + "bitflags 2.11.0", "cfg-if", "libc", ] @@ -458,6 +461,12 @@ dependencies = [ "num-traits", ] +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + [[package]] name = "auto_enums" version = "0.8.7" @@ -476,6 +485,28 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" +[[package]] +name = "aws-lc-rs" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9a7b350e3bb1767102698302bc37256cbd48422809984b98d292c40e2579aa9" +dependencies = [ + "aws-lc-sys", + "zeroize", +] + +[[package]] +name = "aws-lc-sys" +version = "0.37.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b092fe214090261288111db7a2b2c2118e5a7f30dc2569f1732c4069a6840549" +dependencies = [ + "cc", + "cmake", + "dunce", + "fs_extra", +] + [[package]] name = "base64" version = "0.22.1" @@ -533,7 +564,7 @@ version = "0.72.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "993776b509cfb49c750f11b8f07a46fa23e0a1386ffc01fb1e7d343efc387895" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.11.0", "cexpr", "clang-sys", "itertools 0.13.0", @@ -583,9 +614,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.10.0" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" +checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af" dependencies = [ "serde_core", ] @@ -904,6 +935,15 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d" +[[package]] +name = "cmake" +version = "0.1.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75443c44cd6b379beb8c5b45d85d0773baf31cce901fe7bb252f4eff3008ef7d" +dependencies = [ + "cc", +] + [[package]] name = "colorchoice" version = "1.0.4" @@ -983,7 +1023,7 @@ version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fa95a34622365fa5bbf40b20b75dba8dfa8c94c734aea8ac9a5ca38af14316f1" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.11.0", "core-foundation", "core-graphics-types", "foreign-types", @@ -996,7 +1036,7 @@ version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "064badf302c3194842cf2c5d61f56cc88e54a759313879cdf03abdd27d0c3b97" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.11.0", "core-foundation", "core-graphics-types", "foreign-types", @@ -1009,7 +1049,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d44a101f213f6c4cdc1853d4b78aef6db6bdfa3468798cc1d9912f4735013eb" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.11.0", "core-foundation", "libc", ] @@ -1379,7 +1419,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "89a09f22a6c6069a18470eb92d2298acf25463f14256d24778e1230d789a2aec" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.11.0", "block2", "libc", "objc2", @@ -1442,6 +1482,12 @@ version = "0.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f678cf4a922c215c63e0de95eb1ff08a958a81d47e485cf9da1e27bf6305cfa5" +[[package]] +name = "dunce" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" + [[package]] name = "ecb" version = "0.1.2" @@ -1664,6 +1710,12 @@ dependencies = [ "autocfg", ] +[[package]] +name = "fs_extra" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" + [[package]] name = "futf" version = "0.1.5" @@ -1828,9 +1880,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" dependencies = [ "cfg-if", + "js-sys", "libc", "r-efi", "wasip2", + "wasm-bindgen", ] [[package]] @@ -1880,7 +1934,7 @@ version = "1.41.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0c43e7c3212bd992c11b6b9796563388170950521ae8487f5cdf6f6e792f1c8" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.11.0", "proc-macro2", "quote", "syn 1.0.109", @@ -2003,6 +2057,105 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "http" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a" +dependencies = [ + "bytes", + "itoa", +] + +[[package]] +name = "http-body" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +dependencies = [ + "bytes", + "http", +] + +[[package]] +name = "http-body-util" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" +dependencies = [ + "bytes", + "futures-core", + "http", + "http-body", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" + +[[package]] +name = "hyper" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ab2d4f250c3d7b1c9fcdff1cece94ea4e2dfbec68614f7b87cb205f24ca9d11" +dependencies = [ + "atomic-waker", + "bytes", + "futures-channel", + "futures-core", + "http", + "http-body", + "httparse", + "itoa", + "pin-project-lite", + "pin-utils", + "smallvec", + "tokio", + "want", +] + +[[package]] +name = "hyper-rustls" +version = "0.27.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58" +dependencies = [ + "http", + "hyper", + "hyper-util", + "rustls", + "rustls-pki-types", + "tokio", + "tokio-rustls", + "tower-service", +] + +[[package]] +name = "hyper-util" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0" +dependencies = [ + "base64", + "bytes", + "futures-channel", + "futures-util", + "http", + "http-body", + "hyper", + "ipnet", + "libc", + "percent-encoding", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", +] + [[package]] name = "iana-time-zone" version = "0.1.64" @@ -2253,6 +2406,22 @@ dependencies = [ "leaky-cow", ] +[[package]] +name = "ipnet" +version = "2.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" + +[[package]] +name = "iri-string" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c91338f0783edbd6195decb37bae672fd3b165faffb89bf7b9e6942f8b1a731a" +dependencies = [ + "memchr", + "serde", +] + [[package]] name = "is-terminal" version = "0.4.17" @@ -2376,9 +2545,9 @@ dependencies = [ [[package]] name = "keccak" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" +checksum = "cb26cec98cce3a3d96cbb7bced3c4b16e3d13f27ec56dbd62cbc8f39cfb9d653" dependencies = [ "cpufeatures", ] @@ -2490,7 +2659,7 @@ version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d0b95e02c851351f877147b7deea7b1afb1df71b63aa5f8270716e0c5720616" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.11.0", "libc", "redox_syscall 0.7.0", ] @@ -2518,6 +2687,19 @@ version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77" +[[package]] +name = "llm_adapter" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8dd9a548766bccf8b636695e8d514edee672d180e96a16ab932c971783b4e353" +dependencies = [ + "base64", + "reqwest", + "serde", + "serde_json", + "thiserror 2.0.17", +] + [[package]] name = "lock_api" version = "0.4.14" @@ -2555,7 +2737,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "59fa2559e99ba0f26a12458aabc754432c805bbb8cba516c427825a997af1fb7" dependencies = [ "aes", - "bitflags 2.10.0", + "bitflags 2.11.0", "cbc", "ecb", "encoding_rs", @@ -2583,6 +2765,12 @@ dependencies = [ "hashbrown 0.16.1", ] +[[package]] +name = "lru-slab" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" + [[package]] name = "mac" version = "0.1.1" @@ -2741,7 +2929,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "000f205daae6646003fdc38517be6232af2b150bad4b67bdaf4c5aadb119d738" dependencies = [ "anyhow", - "bitflags 2.10.0", + "bitflags 2.11.0", "chrono", "ctor", "futures", @@ -2801,7 +2989,7 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2076a31b7010b17a38c01907c45b945e8f11495ee4dd588309718901b1f7a5b7" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.11.0", "jni-sys", "log", "ndk-sys", @@ -2836,7 +3024,7 @@ version = "0.30.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.11.0", "cfg-if", "cfg_aliases", "libc", @@ -3000,7 +3188,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.11.0", "dispatch2", "objc2", ] @@ -3017,7 +3205,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3e0adef53c21f888deb4fa59fc59f7eb17404926ee8a6f59f5df0fd7f9f3272" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.11.0", "block2", "libc", "objc2", @@ -3074,6 +3262,12 @@ version = "11.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6790f58c7ff633d8771f42965289203411a5e5c68388703c06e14f24770b41e" +[[package]] +name = "openssl-probe" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe" + [[package]] name = "ordered-float" version = "5.1.0" @@ -3469,7 +3663,7 @@ checksum = "bee689443a2bd0a16ab0348b52ee43e3b2d1b1f931c8aa5c9f8de4c86fbe8c40" dependencies = [ "bit-set 0.8.0", "bit-vec 0.8.0", - "bitflags 2.10.0", + "bitflags 2.11.0", "num-traits", "rand 0.9.2", "rand_chacha 0.9.0", @@ -3497,7 +3691,7 @@ version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e8bbe1a966bd2f362681a44f6edce3c2310ac21e4d5067a6e7ec396297a6ea0" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.11.0", "getopts", "memchr", "pulldown-cmark-escape", @@ -3516,6 +3710,62 @@ version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" +[[package]] +name = "quinn" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e20a958963c291dc322d98411f541009df2ced7b5a4f2bd52337638cfccf20" +dependencies = [ + "bytes", + "cfg_aliases", + "pin-project-lite", + "quinn-proto", + "quinn-udp", + "rustc-hash 2.1.1", + "rustls", + "socket2", + "thiserror 2.0.17", + "tokio", + "tracing", + "web-time", +] + +[[package]] +name = "quinn-proto" +version = "0.11.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1906b49b0c3bc04b5fe5d86a77925ae6524a19b816ae38ce1e426255f1d8a31" +dependencies = [ + "aws-lc-rs", + "bytes", + "getrandom 0.3.4", + "lru-slab", + "rand 0.9.2", + "ring", + "rustc-hash 2.1.1", + "rustls", + "rustls-pki-types", + "slab", + "thiserror 2.0.17", + "tinyvec", + "tracing", + "web-time", +] + +[[package]] +name = "quinn-udp" +version = "0.5.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "addec6a0dcad8a8d96a771f815f0eaf55f9d1805756410b39f5fa81332574cbd" +dependencies = [ + "cfg_aliases", + "libc", + "once_cell", + "socket2", + "tracing", + "windows-sys 0.60.2", +] + [[package]] name = "quote" version = "1.0.43" @@ -3663,7 +3913,7 @@ version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.11.0", ] [[package]] @@ -3672,7 +3922,7 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49f3fe0889e69e2ae9e41f4d6c4c0181701d00e4697b356fb1f74173a5e0ee27" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.11.0", ] [[package]] @@ -3704,6 +3954,45 @@ version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" +[[package]] +name = "reqwest" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab3f43e3283ab1488b624b44b0e988d0acea0b3214e694730a055cb6b2efa801" +dependencies = [ + "base64", + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-rustls", + "hyper-util", + "js-sys", + "log", + "percent-encoding", + "pin-project-lite", + "quinn", + "rustls", + "rustls-pki-types", + "rustls-platform-verifier", + "serde", + "serde_json", + "sync_wrapper", + "tokio", + "tokio-rustls", + "tower", + "tower-http", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + [[package]] name = "ring" version = "0.17.14" @@ -3831,7 +4120,7 @@ version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "146c9e247ccc180c1f61615433868c99f3de3ae256a30a43b49f67c2d9171f34" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.11.0", "errno", "libc", "linux-raw-sys", @@ -3844,6 +4133,7 @@ version = "0.23.36" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c665f33d38cea657d9614f766881e4d510e0eda4239891eea56b4cadcf01801b" dependencies = [ + "aws-lc-rs", "once_cell", "ring", "rustls-pki-types", @@ -3852,21 +4142,62 @@ dependencies = [ "zeroize", ] +[[package]] +name = "rustls-native-certs" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "612460d5f7bea540c490b2b6395d8e34a953e52b491accd6c86c8164c5932a63" +dependencies = [ + "openssl-probe", + "rustls-pki-types", + "schannel", + "security-framework", +] + [[package]] name = "rustls-pki-types" version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "21e6f2ab2928ca4291b86736a8bd920a277a399bba1589409d72154ff87c1282" dependencies = [ + "web-time", "zeroize", ] +[[package]] +name = "rustls-platform-verifier" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d99feebc72bae7ab76ba994bb5e121b8d83d910ca40b36e0921f53becc41784" +dependencies = [ + "core-foundation", + "core-foundation-sys", + "jni", + "log", + "once_cell", + "rustls", + "rustls-native-certs", + "rustls-platform-verifier-android", + "rustls-webpki", + "security-framework", + "security-framework-sys", + "webpki-root-certs", + "windows-sys 0.61.2", +] + +[[package]] +name = "rustls-platform-verifier-android" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f" + [[package]] name = "rustls-webpki" version = "0.103.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2ffdfa2f5286e2247234e03f680868ac2815974dc39e00ea15adc445d0aafe52" dependencies = [ + "aws-lc-rs", "ring", "rustls-pki-types", "untrusted", @@ -3905,6 +4236,15 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "schannel" +version = "0.1.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "891d81b926048e76efe18581bf793546b4c0eaf8448d72be8de2bbee5fd166e1" +dependencies = [ + "windows-sys 0.61.2", +] + [[package]] name = "scoped-tls" version = "1.0.1" @@ -3953,6 +4293,29 @@ dependencies = [ "syn 2.0.114", ] +[[package]] +name = "security-framework" +version = "3.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7f4bc775c73d9a02cde8bf7b2ec4c9d12743edf609006c7facc23998404cd1d" +dependencies = [ + "bitflags 2.11.0", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce2691df843ecc5d231c0b14ece2acc3efb62c0a398c7e1d875f3983ce020e3" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "semver" version = "1.0.27" @@ -4269,7 +4632,7 @@ checksum = "aa003f0038df784eb8fecbbac13affe3da23b45194bd57dba231c8f48199c526" dependencies = [ "atoi", "base64", - "bitflags 2.10.0", + "bitflags 2.11.0", "byteorder", "bytes", "chrono", @@ -4312,7 +4675,7 @@ checksum = "db58fcd5a53cf07c184b154801ff91347e4c30d17a3562a635ff028ad5deda46" dependencies = [ "atoi", "base64", - "bitflags 2.10.0", + "bitflags 2.11.0", "byteorder", "chrono", "crc", @@ -4678,6 +5041,15 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "sync_wrapper" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" +dependencies = [ + "futures-core", +] + [[package]] name = "synstructure" version = "0.13.2" @@ -4869,6 +5241,16 @@ dependencies = [ "syn 2.0.114", ] +[[package]] +name = "tokio-rustls" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" +dependencies = [ + "rustls", + "tokio", +] + [[package]] name = "tokio-stream" version = "0.1.18" @@ -4912,13 +5294,58 @@ dependencies = [ [[package]] name = "toml_parser" -version = "1.0.6+spec-1.1.0" +version = "1.0.9+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3198b4b0a8e11f09dd03e133c0280504d0801269e9afa46362ffde1cbeebf44" +checksum = "702d4415e08923e7e1ef96cd5727c0dfed80b4d2fa25db9647fe5eb6f7c5a4c4" dependencies = [ "winnow", ] +[[package]] +name = "tower" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebe5ef63511595f1344e2d5cfa636d973292adc0eec1f0ad45fae9f0851ab1d4" +dependencies = [ + "futures-core", + "futures-util", + "pin-project-lite", + "sync_wrapper", + "tokio", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-http" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8" +dependencies = [ + "bitflags 2.11.0", + "bytes", + "futures-util", + "http", + "http-body", + "iri-string", + "pin-project-lite", + "tower", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-layer" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" + +[[package]] +name = "tower-service" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" + [[package]] name = "tracing" version = "0.1.44" @@ -5121,6 +5548,12 @@ dependencies = [ "tree-sitter-language", ] +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + [[package]] name = "type1-encoding-parser" version = "0.1.0" @@ -5441,6 +5874,15 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + [[package]] name = "wasi" version = "0.11.1+wasi-snapshot-preview1" @@ -5530,6 +5972,25 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "web-time" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "webpki-root-certs" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "804f18a4ac2676ffb4e8b5b5fa9ae38af06df08162314f96a68d2a363e21a8ca" +dependencies = [ + "rustls-pki-types", +] + [[package]] name = "webpki-roots" version = "0.26.11" diff --git a/Cargo.toml b/Cargo.toml index c64a297349..4f435f3212 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -44,6 +44,7 @@ resolver = "3" lasso = { version = "0.7", features = ["multi-threaded"] } lib0 = { version = "0.16", features = ["lib0-serde"] } libc = "0.2" + llm_adapter = "0.1.1" log = "0.4" loom = { version = "0.7", features = ["checkpoint"] } lru = "0.16" diff --git a/blocksuite/affine/blocks/bookmark/src/bookmark-block.ts b/blocksuite/affine/blocks/bookmark/src/bookmark-block.ts index a591397ff0..8d944a1050 100644 --- a/blocksuite/affine/blocks/bookmark/src/bookmark-block.ts +++ b/blocksuite/affine/blocks/bookmark/src/bookmark-block.ts @@ -108,7 +108,9 @@ export class BookmarkBlockComponent extends CaptionedBlockComponent { - window.open(this.link, '_blank'); + const link = this.link; + if (!link) return; + window.open(link, '_blank', 'noopener,noreferrer'); }; refreshData = () => { diff --git a/blocksuite/affine/components/src/link-preview/link.ts b/blocksuite/affine/components/src/link-preview/link.ts index 2fde9be69f..201fc209bc 100644 --- a/blocksuite/affine/components/src/link-preview/link.ts +++ b/blocksuite/affine/components/src/link-preview/link.ts @@ -1,4 +1,8 @@ -import { getHostName } from '@blocksuite/affine-shared/utils'; +import { + getHostName, + isValidUrl, + normalizeUrl, +} from '@blocksuite/affine-shared/utils'; import { PropTypes, requiredProperties } from '@blocksuite/std'; import { css, LitElement } from 'lit'; import { property } from 'lit/decorators.js'; @@ -44,15 +48,27 @@ export class LinkPreview extends LitElement { override render() { const { url } = this; + const normalizedUrl = normalizeUrl(url); + const safeUrl = + normalizedUrl && isValidUrl(normalizedUrl) ? normalizedUrl : null; + const hostName = getHostName(safeUrl ?? url); + + if (!safeUrl) { + return html` + + ${hostName} + + `; + } return html` - ${getHostName(url)} + ${hostName} `; } diff --git a/blocksuite/affine/inlines/footnote/src/footnote-node/footnote-node.ts b/blocksuite/affine/inlines/footnote/src/footnote-node/footnote-node.ts index 8a02e583c1..f0bbcf2056 100644 --- a/blocksuite/affine/inlines/footnote/src/footnote-node/footnote-node.ts +++ b/blocksuite/affine/inlines/footnote/src/footnote-node/footnote-node.ts @@ -4,6 +4,7 @@ import type { FootNote } from '@blocksuite/affine-model'; import { CitationProvider } from '@blocksuite/affine-shared/services'; import { unsafeCSSVarV2 } from '@blocksuite/affine-shared/theme'; import type { AffineTextAttributes } from '@blocksuite/affine-shared/types'; +import { isValidUrl, normalizeUrl } from '@blocksuite/affine-shared/utils'; import { WithDisposable } from '@blocksuite/global/lit'; import { BlockSelection, @@ -152,7 +153,9 @@ export class AffineFootnoteNode extends WithDisposable(ShadowlessElement) { }; private readonly _handleUrlReference = (url: string) => { - window.open(url, '_blank'); + const normalizedUrl = normalizeUrl(url); + if (!normalizedUrl || !isValidUrl(normalizedUrl)) return; + window.open(normalizedUrl, '_blank', 'noopener,noreferrer'); }; private readonly _updateFootnoteAttributes = (footnote: FootNote) => { diff --git a/blocksuite/affine/shared/src/utils/url.ts b/blocksuite/affine/shared/src/utils/url.ts index f1a67a2ab8..4c0f97d273 100644 --- a/blocksuite/affine/shared/src/utils/url.ts +++ b/blocksuite/affine/shared/src/utils/url.ts @@ -24,6 +24,11 @@ const toURL = (str: string) => { } }; +const hasAllowedScheme = (url: URL) => { + const protocol = url.protocol.slice(0, -1).toLowerCase(); + return ALLOWED_SCHEMES.has(protocol); +}; + function resolveURL(str: string, baseUrl: string, padded = false) { const url = toURL(str); if (!url) return null; @@ -61,6 +66,7 @@ export function normalizeUrl(str: string) { // Formatted if (url) { + if (!hasAllowedScheme(url)) return ''; if (!str.endsWith('/') && url.href.endsWith('/')) { return url.href.substring(0, url.href.length - 1); } diff --git a/package.json b/package.json index e89c8b981c..45a396526f 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,7 @@ "af": "r affine.ts", "dev": "yarn affine dev", "build": "yarn affine build", - "lint:eslint": "cross-env NODE_OPTIONS=\"--max-old-space-size=8192\" eslint --report-unused-disable-directives-severity=off . --cache", + "lint:eslint": "cross-env NODE_OPTIONS=\"--max-old-space-size=16384\" eslint --report-unused-disable-directives-severity=off . --cache", "lint:eslint:fix": "yarn lint:eslint --fix --fix-type problem,suggestion,layout", "lint:prettier": "prettier --ignore-unknown --cache --check .", "lint:prettier:fix": "prettier --ignore-unknown --cache --write .", diff --git a/packages/backend/native/Cargo.toml b/packages/backend/native/Cargo.toml index faecf5eebe..e286123bd8 100644 --- a/packages/backend/native/Cargo.toml +++ b/packages/backend/native/Cargo.toml @@ -17,10 +17,13 @@ affine_common = { workspace = true, features = [ chrono = { workspace = true } file-format = { workspace = true } infer = { workspace = true } +llm_adapter = { workspace = true } mp4parse = { workspace = true } napi = { workspace = true, features = ["async"] } napi-derive = { workspace = true } rand = { workspace = true } +serde = { workspace = true, features = ["derive"] } +serde_json = { workspace = true } sha3 = { workspace = true } tiktoken-rs = { workspace = true } v_htmlescape = { workspace = true } diff --git a/packages/backend/native/index.d.ts b/packages/backend/native/index.d.ts index 825cf5dbd0..785572f201 100644 --- a/packages/backend/native/index.d.ts +++ b/packages/backend/native/index.d.ts @@ -1,5 +1,9 @@ /* auto-generated by NAPI-RS */ /* eslint-disable */ +export declare class LlmStreamHandle { + abort(): void +} + export declare class Tokenizer { count(content: string, allowedSpecial?: Array | undefined | null): number } @@ -46,6 +50,10 @@ export declare function getMime(input: Uint8Array): string export declare function htmlSanitize(input: string): string +export declare function llmDispatch(protocol: string, backendConfigJson: string, requestJson: string): string + +export declare function llmDispatchStream(protocol: string, backendConfigJson: string, requestJson: string, callback: ((err: Error | null, arg: string) => void)): LlmStreamHandle + /** * Merge updates in form like `Y.applyUpdate(doc, update)` way and return the * result binary. diff --git a/packages/backend/native/src/lib.rs b/packages/backend/native/src/lib.rs index 253c492858..0332c53750 100644 --- a/packages/backend/native/src/lib.rs +++ b/packages/backend/native/src/lib.rs @@ -7,6 +7,7 @@ pub mod doc_loader; pub mod file_type; pub mod hashcash; pub mod html_sanitize; +pub mod llm; pub mod tiktoken; use affine_common::napi_utils::map_napi_err; diff --git a/packages/backend/native/src/llm.rs b/packages/backend/native/src/llm.rs new file mode 100644 index 0000000000..718db3dbdf --- /dev/null +++ b/packages/backend/native/src/llm.rs @@ -0,0 +1,339 @@ +use std::sync::{ + Arc, + atomic::{AtomicBool, Ordering}, +}; + +use llm_adapter::{ + backend::{ + BackendConfig, BackendError, BackendProtocol, ReqwestHttpClient, dispatch_request, dispatch_stream_events_with, + }, + core::{CoreRequest, StreamEvent}, + middleware::{ + MiddlewareConfig, PipelineContext, RequestMiddleware, StreamMiddleware, citation_indexing, clamp_max_tokens, + normalize_messages, run_request_middleware_chain, run_stream_middleware_chain, stream_event_normalize, + tool_schema_rewrite, + }, +}; +use napi::{ + Error, Result, Status, + threadsafe_function::{ThreadsafeFunction, ThreadsafeFunctionCallMode}, +}; +use serde::Deserialize; + +pub const STREAM_END_MARKER: &str = "__AFFINE_LLM_STREAM_END__"; +const STREAM_ABORTED_REASON: &str = "__AFFINE_LLM_STREAM_ABORTED__"; +const STREAM_CALLBACK_DISPATCH_FAILED_REASON: &str = "__AFFINE_LLM_STREAM_CALLBACK_DISPATCH_FAILED__"; + +#[derive(Debug, Clone, Default, Deserialize)] +#[serde(default)] +struct LlmMiddlewarePayload { + request: Vec, + stream: Vec, + config: MiddlewareConfig, +} + +#[derive(Debug, Clone, Deserialize)] +struct LlmDispatchPayload { + #[serde(flatten)] + request: CoreRequest, + #[serde(default)] + middleware: LlmMiddlewarePayload, +} + +#[napi] +pub struct LlmStreamHandle { + aborted: Arc, +} + +#[napi] +impl LlmStreamHandle { + #[napi] + pub fn abort(&self) { + self.aborted.store(true, Ordering::SeqCst); + } +} + +#[napi(catch_unwind)] +pub fn llm_dispatch(protocol: String, backend_config_json: String, request_json: String) -> Result { + let protocol = parse_protocol(&protocol)?; + let config: BackendConfig = serde_json::from_str(&backend_config_json).map_err(map_json_error)?; + let payload: LlmDispatchPayload = serde_json::from_str(&request_json).map_err(map_json_error)?; + let request = apply_request_middlewares(payload.request, &payload.middleware)?; + + let response = + dispatch_request(&ReqwestHttpClient::default(), &config, protocol, &request).map_err(map_backend_error)?; + + serde_json::to_string(&response).map_err(map_json_error) +} + +#[napi(catch_unwind)] +pub fn llm_dispatch_stream( + protocol: String, + backend_config_json: String, + request_json: String, + callback: ThreadsafeFunction, +) -> Result { + let protocol = parse_protocol(&protocol)?; + let config: BackendConfig = serde_json::from_str(&backend_config_json).map_err(map_json_error)?; + let payload: LlmDispatchPayload = serde_json::from_str(&request_json).map_err(map_json_error)?; + let request = apply_request_middlewares(payload.request, &payload.middleware)?; + let middleware = payload.middleware.clone(); + + let aborted = Arc::new(AtomicBool::new(false)); + let aborted_in_worker = aborted.clone(); + + std::thread::spawn(move || { + let chain = match resolve_stream_chain(&middleware.stream) { + Ok(chain) => chain, + Err(error) => { + emit_error_event(&callback, error.reason.clone(), "middleware_error"); + let _ = callback.call( + Ok(STREAM_END_MARKER.to_string()), + ThreadsafeFunctionCallMode::NonBlocking, + ); + return; + } + }; + let mut pipeline = StreamPipeline::new(chain, middleware.config.clone()); + let mut aborted_by_user = false; + let mut callback_dispatch_failed = false; + + let result = dispatch_stream_events_with(&ReqwestHttpClient::default(), &config, protocol, &request, |event| { + if aborted_in_worker.load(Ordering::Relaxed) { + aborted_by_user = true; + return Err(BackendError::Http(STREAM_ABORTED_REASON.to_string())); + } + + for event in pipeline.process(event) { + let status = emit_stream_event(&callback, &event); + if status != Status::Ok { + callback_dispatch_failed = true; + return Err(BackendError::Http(format!( + "{STREAM_CALLBACK_DISPATCH_FAILED_REASON}:{status}" + ))); + } + } + + Ok(()) + }); + + if !aborted_by_user { + for event in pipeline.finish() { + if aborted_in_worker.load(Ordering::Relaxed) { + aborted_by_user = true; + break; + } + if emit_stream_event(&callback, &event) != Status::Ok { + callback_dispatch_failed = true; + break; + } + } + } + + if let Err(error) = result + && !aborted_by_user + && !callback_dispatch_failed + && !is_abort_error(&error) + && !is_callback_dispatch_failed_error(&error) + { + emit_error_event(&callback, error.to_string(), "dispatch_error"); + } + + if !callback_dispatch_failed { + let _ = callback.call( + Ok(STREAM_END_MARKER.to_string()), + ThreadsafeFunctionCallMode::NonBlocking, + ); + } + }); + + Ok(LlmStreamHandle { aborted }) +} + +fn apply_request_middlewares(request: CoreRequest, middleware: &LlmMiddlewarePayload) -> Result { + let chain = resolve_request_chain(&middleware.request)?; + Ok(run_request_middleware_chain(request, &middleware.config, &chain)) +} + +#[derive(Clone)] +struct StreamPipeline { + chain: Vec, + config: MiddlewareConfig, + context: PipelineContext, +} + +impl StreamPipeline { + fn new(chain: Vec, config: MiddlewareConfig) -> Self { + Self { + chain, + config, + context: PipelineContext::default(), + } + } + + fn process(&mut self, event: StreamEvent) -> Vec { + run_stream_middleware_chain(event, &mut self.context, &self.config, &self.chain) + } + + fn finish(&mut self) -> Vec { + self.context.flush_pending_deltas(); + self.context.drain_queued_events() + } +} + +fn emit_stream_event(callback: &ThreadsafeFunction, event: &StreamEvent) -> Status { + let value = serde_json::to_string(event).unwrap_or_else(|error| { + serde_json::json!({ + "type": "error", + "message": format!("failed to serialize stream event: {error}"), + }) + .to_string() + }); + + callback.call(Ok(value), ThreadsafeFunctionCallMode::NonBlocking) +} + +fn emit_error_event(callback: &ThreadsafeFunction, message: String, code: &str) { + let error_event = serde_json::to_string(&StreamEvent::Error { + message: message.clone(), + code: Some(code.to_string()), + }) + .unwrap_or_else(|_| { + serde_json::json!({ + "type": "error", + "message": message, + "code": code, + }) + .to_string() + }); + + let _ = callback.call(Ok(error_event), ThreadsafeFunctionCallMode::NonBlocking); +} + +fn is_abort_error(error: &BackendError) -> bool { + matches!( + error, + BackendError::Http(reason) if reason == STREAM_ABORTED_REASON + ) +} + +fn is_callback_dispatch_failed_error(error: &BackendError) -> bool { + matches!( + error, + BackendError::Http(reason) if reason.starts_with(STREAM_CALLBACK_DISPATCH_FAILED_REASON) + ) +} + +fn resolve_request_chain(request: &[String]) -> Result> { + if request.is_empty() { + return Ok(vec![normalize_messages, tool_schema_rewrite]); + } + + request + .iter() + .map(|name| match name.as_str() { + "normalize_messages" => Ok(normalize_messages as RequestMiddleware), + "clamp_max_tokens" => Ok(clamp_max_tokens as RequestMiddleware), + "tool_schema_rewrite" => Ok(tool_schema_rewrite as RequestMiddleware), + _ => Err(Error::new( + Status::InvalidArg, + format!("Unsupported request middleware: {name}"), + )), + }) + .collect() +} + +fn resolve_stream_chain(stream: &[String]) -> Result> { + if stream.is_empty() { + return Ok(vec![stream_event_normalize, citation_indexing]); + } + + stream + .iter() + .map(|name| match name.as_str() { + "stream_event_normalize" => Ok(stream_event_normalize as StreamMiddleware), + "citation_indexing" => Ok(citation_indexing as StreamMiddleware), + _ => Err(Error::new( + Status::InvalidArg, + format!("Unsupported stream middleware: {name}"), + )), + }) + .collect() +} + +fn parse_protocol(protocol: &str) -> Result { + match protocol { + "openai_chat" | "openai-chat" | "openai_chat_completions" | "chat-completions" | "chat_completions" => { + Ok(BackendProtocol::OpenaiChatCompletions) + } + "openai_responses" | "openai-responses" | "responses" => Ok(BackendProtocol::OpenaiResponses), + "anthropic" | "anthropic_messages" | "anthropic-messages" => Ok(BackendProtocol::AnthropicMessages), + other => Err(Error::new( + Status::InvalidArg, + format!("Unsupported llm backend protocol: {other}"), + )), + } +} + +fn map_json_error(error: serde_json::Error) -> Error { + Error::new(Status::InvalidArg, format!("Invalid JSON payload: {error}")) +} + +fn map_backend_error(error: BackendError) -> Error { + Error::new(Status::GenericFailure, error.to_string()) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn should_parse_supported_protocol_aliases() { + assert!(parse_protocol("openai_chat").is_ok()); + assert!(parse_protocol("chat-completions").is_ok()); + assert!(parse_protocol("responses").is_ok()); + assert!(parse_protocol("anthropic").is_ok()); + } + + #[test] + fn should_reject_unsupported_protocol() { + let error = parse_protocol("unknown").unwrap_err(); + assert_eq!(error.status, Status::InvalidArg); + assert!(error.reason.contains("Unsupported llm backend protocol")); + } + + #[test] + fn llm_dispatch_should_reject_invalid_backend_json() { + let error = llm_dispatch("openai_chat".to_string(), "{".to_string(), "{}".to_string()).unwrap_err(); + assert_eq!(error.status, Status::InvalidArg); + assert!(error.reason.contains("Invalid JSON payload")); + } + + #[test] + fn map_json_error_should_use_invalid_arg_status() { + let parse_error = serde_json::from_str::("{").unwrap_err(); + let error = map_json_error(parse_error); + assert_eq!(error.status, Status::InvalidArg); + assert!(error.reason.contains("Invalid JSON payload")); + } + + #[test] + fn resolve_request_chain_should_support_clamp_max_tokens() { + let chain = resolve_request_chain(&["normalize_messages".to_string(), "clamp_max_tokens".to_string()]).unwrap(); + assert_eq!(chain.len(), 2); + } + + #[test] + fn resolve_request_chain_should_reject_unknown_middleware() { + let error = resolve_request_chain(&["unknown".to_string()]).unwrap_err(); + assert_eq!(error.status, Status::InvalidArg); + assert!(error.reason.contains("Unsupported request middleware")); + } + + #[test] + fn resolve_stream_chain_should_reject_unknown_middleware() { + let error = resolve_stream_chain(&["unknown".to_string()]).unwrap_err(); + assert_eq!(error.status, Status::InvalidArg); + assert!(error.reason.contains("Unsupported stream middleware")); + } +} diff --git a/packages/backend/server/package.json b/packages/backend/server/package.json index 350718e9a4..b4c6152247 100644 --- a/packages/backend/server/package.json +++ b/packages/backend/server/package.json @@ -12,9 +12,9 @@ "dev": "nodemon ./src/index.ts", "dev:mail": "email dev -d src/mails", "test": "ava --concurrency 1 --serial", - "test:copilot": "ava \"src/__tests__/copilot-*.spec.ts\"", + "test:copilot": "ava \"src/__tests__/copilot/copilot-*.spec.ts\"", "test:coverage": "c8 ava --concurrency 1 --serial", - "test:copilot:coverage": "c8 ava --timeout=5m \"src/__tests__/copilot-*.spec.ts\"", + "test:copilot:coverage": "c8 ava --timeout=5m \"src/__tests__/copilot/copilot-*.spec.ts\"", "e2e": "cross-env TEST_MODE=e2e ava --serial", "e2e:coverage": "cross-env TEST_MODE=e2e c8 ava --serial", "data-migration": "cross-env NODE_ENV=development SERVER_FLAVOR=script r ./src/index.ts", @@ -28,12 +28,8 @@ "dependencies": { "@affine/s3-compat": "workspace:*", "@affine/server-native": "workspace:*", - "@ai-sdk/anthropic": "^2.0.54", "@ai-sdk/google": "^2.0.45", "@ai-sdk/google-vertex": "^3.0.88", - "@ai-sdk/openai": "^2.0.80", - "@ai-sdk/openai-compatible": "^1.0.28", - "@ai-sdk/perplexity": "^2.0.21", "@apollo/server": "^4.13.0", "@fal-ai/serverless-client": "^0.15.0", "@google-cloud/opentelemetry-cloud-trace-exporter": "^3.0.0", diff --git a/packages/backend/server/src/__tests__/__snapshots__/copilot.e2e.ts.snap b/packages/backend/server/src/__tests__/__snapshots__/copilot.e2e.ts.snap deleted file mode 100644 index 9239165a9356f4027e684914fe98809337c5d236..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1167 zcmV;A1aSL7RzVUIUnYIVp*g1?dlDaWC`@n@hI{`61 zQ{!dk86S%X00000000B+n9pw;MHI)sZ+|#Wqc*7u5=c}Ui5~}WQ=5h&MHNyJ5eXFv z2nkUThw<(>-gtLryE9JWaDxcM4^auh1tCFufdk?Y4xA7d#2IaS&+9W8G9nzkb#Cx#1V-EgNI#eyB`V1;C>KPEhGMx#yFFcZl-Q&wD3Wc7wqQ&XU$ARBay=m!9Ib;s^;Dn~+Vz9ckg5+}&Y zub1LLO5vwdYpQtDsFsjAojO!b-T&o=C%+Zkw|92`@7#U+Ap$A{a4NX&47hF;d>HeT zG(wtue)p1)BH>0bBi2k8fA_m!m36{FIW_IY?)BDZ3s{phCdRqy;DAa%6ry(d~WfgT)5PU7dvvMUaXXHui2KZ7lQRI zunvmMC69W{k7ypnp_q>SM$sW{xM}O&!Z=Z$&^nMyS$6KtP^T%$=(0u-3cUsPrEm7j z)m{P+0eF9SCl$-l3VJL{zVa6Q+Fs+kXQ%jl<>|cE?i;K%lW?iMB#8f2XB!!g%lpM) zc>sdpC}{Uc$C9>`+hIPKMWNgEC@_q-{h%)nCE2p7XT4&p{RUCe06GA^0&oq$I05H| z_lsMU8}4;|(|eMeA_*_#K_vX*qjfuqc+%O^qusP7hM62AdWE*d{%9ZPwB$Dkc<08F z4{3;WTPfF1Ddjpr^dljKT_)GHfC&pYZ2`|&z>2lInwQD_(gHRu;3o_C!vap)1rv9u zg4sg$TCQBJ&Q`0lGmj0RjRkLsB%jmyB1Ua^VhWErQ!T9O=ayfcnipZHDom`1q@$#m z9?i|#Y_0hG0XLr<#m$+sBe_|b4=T(wxookHYO{t)*s=<`9mz~nut*4#j+M_l(^-=~ zkTq#qu)Fu@|3YWnR}XdOmg`c2HPf33qWdl6dh}v< zXs5sMwgp_afUhm!ng#qdT!pGOaMlK1wt?4d;K~pcDwF%W4g6^XCmrAk2k@PONom03 zV+Z)m0ls&DpB-SrEtrfQYTfP7x{*St9SrH(Ehb$%7}B->z*{BT?at+k6VcThKWH>W zBBWuuyK7dGnNBP;+r9o~vN3vlzmjzJ&o{TSq?XP@muP8#wlUwOO1n9N|zj|^kW h`c5JtRTA-V7>T?r=0+yrEAOTl{sGY6VPIwy001}4I-39h diff --git a/packages/backend/server/src/__tests__/__snapshots__/worker.e2e.ts.md b/packages/backend/server/src/__tests__/__snapshots__/worker.e2e.ts.md index d59ba4a7e3..ffd25a2b5c 100644 --- a/packages/backend/server/src/__tests__/__snapshots__/worker.e2e.ts.md +++ b/packages/backend/server/src/__tests__/__snapshots__/worker.e2e.ts.md @@ -43,7 +43,9 @@ Generated by [AVA](https://avajs.dev). > Snapshot 5 Buffer @Uint8Array [ - 66616b65 20696d61 6765 + 89504e47 0d0a1a0a 0000000d 49484452 00000001 00000001 08040000 00b51c0c + 02000000 0b494441 5478da63 fcff1f00 03030200 efa37c9f 00000000 49454e44 + ae426082 ] ## should preview link diff --git a/packages/backend/server/src/__tests__/__snapshots__/worker.e2e.ts.snap b/packages/backend/server/src/__tests__/__snapshots__/worker.e2e.ts.snap index 4679da1148b079dbe9df567b9bd7567c4d40653e..eefab65bc3ee4e597750821f2232f6983fc0f71e 100644 GIT binary patch literal 1005 zcmV< zsy?){Gk0gFJ3BL-dv}{agltIK1}h3RRSIfj@j--E5Fvs^>4Ps)AAJxhl&uIg(g$A! z?c8K0n_(up2E#sNUgpm^bIzIXcka2fP{w=(zWVMk_Q3g02lzS z0QerjU0|IsAe|s>AQ|i;u?I*Tq-`fjD3(gSoAiLJN+a}Cg)$!SYcEsAWX*Sd@I{?5 z-PEM+ieq$3w(Q7d%Bd3!Z_4F{@cp^tBZEiB245Ks_$3*ad4-AFMC=_B48tev&@i4f z9Z}L;0&oMs?ah;B$FNzI4PBLrR93eXX%R(^ed-JH2#G&^|6Bub))!%*QYcWz6(KdI zoBWx6$B`#8*$l`&bdlWL%ST@5OzlYl=o}u(jks}yxCsDX?%f^(kRHzUkB@GOULE1ZO|UYD)-v5Mn%d}W6G+oQj59D#Lg1nEl-6u zF*-@iyUJuT!s%NAd>3$vuXS2uORTY_#OU1amhG3&9a8IxL_NA<9jZRp7yjbjkQar5 zJ+`TN>^~1wv8hf(gUujNZZ-93@04>gIp>(2GdzkG82-q+{v zEMEL|{(OCEdL87uL)6gneNR5oCz8J&0sS-q-dG>{=Cby{-3SAB>i!1(=E}eF&v3tJ z!{9ntQ7`c0C-r4W`y=rkZ4%$Z_1cB{^o4ruvwCfzUb|MGs{I>|VO=dsJm8gBjzBp_ zfVW!_<+U)B?sjwrz=r^SaBUk$naJzfQ$nKMkrWU9uZu8j?)pW&7QwAbfXPo&SCQ{iT`3rAzPbmzHK0?|w1U b)8r6sC{B$aI7NUntwiu|Evr}o$PfSkCsXZi literal 950 zcmV;n14;ZrRzVMieR7(vbcTTBKmDp)V0EmOl6*`skAgvK665eDEL8 zon$7PVJ5l;!#-r5X6BqZ=gjwW=X+-^pEGT}B&WXMN+^@NvS?RKLvvjF?1U!DtiXk| zm?Mj}k~4FL!4y0GY7$*&9JC2rD7BeV@8(W%T@eMR*=%+(`911e&Zg8J03!fQ0Ji{q z3*afRN*U0zpiWQ*TPX1yB|)8=sYAC7?qBo_GeaBYrz>2lP+nJ=OUVjB>eeGdN?{eW z{)%h%YYuZ+nJeyw%Ui76RDR#c$<8~m(OO$*Qz(D{<0uhEQ`8;=>6y8(9v3dWm)r;Ad>gv#QW-OL~z5O_7vmFf!Do)ANzQX}tPl zja#9-WW_au?YXFwvwLumpJipoLn^Qx2y_-+p?id;vxYb`YLpK21p72 zER)H2NskElCX|$1nY1F-u_BiCtn-=1*ue<>5wk8yG$3?)Z}sh==m%enc+gXDz_AKG z`}+HMqB6B5If%=79$y4`*Sk!x4MBVq~;mu!eKm6mXD^KRH z|2li6J~_1t@@)}n6mmnazc%DGe?JEL83N9)4t;%D``{i&fjbT0gQY*-AJKTDHG}Jx zMUhu0Pl-iHJ7e)3Z4ux0dhJ?$>RP>ar(T<@*Y4FPYyXC0)T;JI+~tp0jzM{ufREY{ z<-I7BjqT_HfX@MZ--xXpWk*gF-tZ*a7E5u@|N0R|`ED@Oi5PBG0?xG~w=bi(SpY5p zxVf}%_N<*-idXbqCD#+_l~{6zS|s=U!tABrW@dk%{d8e^e&NQ)JGF)B`KJ%22U;}I Yrs0ejf|CSXXeWYy0bE4yq>c~(06S35Bme*a diff --git a/packages/backend/server/src/__tests__/__snapshots__/copilot.e2e.ts.md b/packages/backend/server/src/__tests__/copilot/__snapshots__/copilot.e2e.ts.md similarity index 95% rename from packages/backend/server/src/__tests__/__snapshots__/copilot.e2e.ts.md rename to packages/backend/server/src/__tests__/copilot/__snapshots__/copilot.e2e.ts.md index 49f5c10e76..2bf58ee451 100644 --- a/packages/backend/server/src/__tests__/__snapshots__/copilot.e2e.ts.md +++ b/packages/backend/server/src/__tests__/copilot/__snapshots__/copilot.e2e.ts.md @@ -12,12 +12,12 @@ Generated by [AVA](https://avajs.dev). { messages: [ { - content: 'generate text to text', + content: 'generate text to text stream', role: 'assistant', }, ], pinned: false, - tokens: 8, + tokens: 10, }, ] @@ -27,12 +27,12 @@ Generated by [AVA](https://avajs.dev). { messages: [ { - content: 'generate text to text', + content: 'generate text to text stream', role: 'assistant', }, ], pinned: false, - tokens: 8, + tokens: 10, }, ] diff --git a/packages/backend/server/src/__tests__/copilot/__snapshots__/copilot.e2e.ts.snap b/packages/backend/server/src/__tests__/copilot/__snapshots__/copilot.e2e.ts.snap new file mode 100644 index 0000000000000000000000000000000000000000..59261fcfc6d46f5c334b15d6eb9701cf0490e629 GIT binary patch literal 1175 zcmV;I1Zev~RzVliYlZcA{r_b z5E7yw4&&W%yz%bLc4nN!;RX>BKh#PHE(i(Q3mg!KaNvZvApQVUaplB`3y1>(F4UV{ zhpf{$QBoDE`r?`0dF%H+@4fHN_-eBetDtSxt_d62SgbJ9Qk^(t4Z(OL7R)N9h1FfQ z9N8A*X%rdBQ`1t`ym2iIx#bt>vWpS)K2#-V62M~sj#1?(`RBCeU7}(%K0XdQ1R~HF z(b>YtYXi6h;9UTp7si$O#-a!;IsM_p#02Ot$ORoC`X0bNy|I6ks);a$F9-t~$1!q> z>ysW-^Y9Wv$3q zrMrwbttz@GXF!0948p2MfR}XR;Bi z##~rTADv52FLjnzJB{UM<$SyE8jGnkY?d7|mfMc$FHE%xgfWp^$g^{Qjyg+8PM0;KSeOm4 zFMqvXuI>VW1iwAswzU|@*RbYx*J3d%zR&!|r9i{)Ov$Y(@ zmHpyy0szr)6tr`sBf2ByW|$A(E-X#2>0)u8{qftJZ2Wwc5<|;{#|@!P`O?b2?YXXe`&Z^qAAN(yFc8imManMI5V1 zCYFTmDk-LR=VpDTUVi?7n@{b=&FM3{a&z*0G|6m>%Qow(4r?mS7FE>iNM>7tB|_M2 ztU}(M%A54Tyh*cy-ML5a2%Yg?yQ?#|RA>D62zZ}>j|upUfc0T|<7Irm>Fdp}x!#Ns zJ>a0wqnCO^H~WRR9pH)seB}Vw9pJCwDpYfUGcNFo3%u?ESBI!jmHgjb;7=Dg;Q>#2 zK;Yqb$z9$FEP+FAf@J8Hufa?c#4Ek{I#~?pD`)nR^vXD=PD%c6e pcn;(Iu3>Cg|DQ-mr4t?xBTKgT! { ); const messageId = await createCopilotMessage(app, sessionId); const ret = await chatWithText(app, sessionId, messageId); - t.is(ret, 'generate text to text', 'should be able to chat with text'); + t.is( + ret, + 'generate text to text stream', + 'should be able to chat with text' + ); const ret2 = await chatWithTextStream(app, sessionId, messageId); t.is( @@ -657,7 +661,7 @@ test('should be able to retry with api', async t => { const histories = await getHistories(app, { workspaceId: id, docId }); t.deepEqual( histories.map(h => h.messages.map(m => m.content)), - [['generate text to text', 'generate text to text']], + [['generate text to text stream', 'generate text to text stream']], 'should be able to list history' ); } @@ -794,7 +798,7 @@ test('should be able to list history', async t => { const histories = await getHistories(app, { workspaceId, docId }); t.deepEqual( histories.map(h => h.messages.map(m => m.content)), - [['hello', 'generate text to text']], + [['hello', 'generate text to text stream']], 'should be able to list history' ); } @@ -807,7 +811,7 @@ test('should be able to list history', async t => { }); t.deepEqual( histories.map(h => h.messages.map(m => m.content)), - [['generate text to text', 'hello']], + [['generate text to text stream', 'hello']], 'should be able to list history' ); } @@ -858,7 +862,7 @@ test('should reject request that user have not permission', async t => { const histories = await getHistories(app, { workspaceId, docId }); t.deepEqual( histories.map(h => h.messages.map(m => m.content)), - [['generate text to text']], + [['generate text to text stream']], 'should able to list history' ); diff --git a/packages/backend/server/src/__tests__/copilot.spec.ts b/packages/backend/server/src/__tests__/copilot/copilot.spec.ts similarity index 94% rename from packages/backend/server/src/__tests__/copilot.spec.ts rename to packages/backend/server/src/__tests__/copilot/copilot.spec.ts index 88afae12e0..30e6999c40 100644 --- a/packages/backend/server/src/__tests__/copilot.spec.ts +++ b/packages/backend/server/src/__tests__/copilot/copilot.spec.ts @@ -8,38 +8,38 @@ import ava from 'ava'; import { nanoid } from 'nanoid'; import Sinon from 'sinon'; -import { EventBus, JobQueue } from '../base'; -import { ConfigModule } from '../base/config'; -import { AuthService } from '../core/auth'; -import { QuotaModule } from '../core/quota'; -import { StorageModule, WorkspaceBlobStorage } from '../core/storage'; +import { EventBus, JobQueue } from '../../base'; +import { ConfigModule } from '../../base/config'; +import { AuthService } from '../../core/auth'; +import { QuotaModule } from '../../core/quota'; +import { StorageModule, WorkspaceBlobStorage } from '../../core/storage'; import { ContextCategories, CopilotSessionModel, WorkspaceModel, -} from '../models'; -import { CopilotModule } from '../plugins/copilot'; -import { CopilotContextService } from '../plugins/copilot/context'; -import { CopilotCronJobs } from '../plugins/copilot/cron'; +} from '../../models'; +import { CopilotModule } from '../../plugins/copilot'; +import { CopilotContextService } from '../../plugins/copilot/context'; +import { CopilotCronJobs } from '../../plugins/copilot/cron'; import { CopilotEmbeddingJob, MockEmbeddingClient, -} from '../plugins/copilot/embedding'; -import { prompts, PromptService } from '../plugins/copilot/prompt'; +} from '../../plugins/copilot/embedding'; +import { prompts, PromptService } from '../../plugins/copilot/prompt'; import { CopilotProviderFactory, CopilotProviderType, ModelInputType, ModelOutputType, OpenAIProvider, -} from '../plugins/copilot/providers'; +} from '../../plugins/copilot/providers'; import { CitationParser, TextStreamParser, -} from '../plugins/copilot/providers/utils'; -import { ChatSessionService } from '../plugins/copilot/session'; -import { CopilotStorage } from '../plugins/copilot/storage'; -import { CopilotTranscriptionService } from '../plugins/copilot/transcript'; +} from '../../plugins/copilot/providers/utils'; +import { ChatSessionService } from '../../plugins/copilot/session'; +import { CopilotStorage } from '../../plugins/copilot/storage'; +import { CopilotTranscriptionService } from '../../plugins/copilot/transcript'; import { CopilotChatTextExecutor, CopilotWorkflowService, @@ -48,7 +48,7 @@ import { WorkflowGraphExecutor, type WorkflowNodeData, WorkflowNodeType, -} from '../plugins/copilot/workflow'; +} from '../../plugins/copilot/workflow'; import { CopilotChatImageExecutor, CopilotCheckHtmlExecutor, @@ -56,16 +56,16 @@ import { getWorkflowExecutor, NodeExecuteState, NodeExecutorType, -} from '../plugins/copilot/workflow/executor'; -import { AutoRegisteredWorkflowExecutor } from '../plugins/copilot/workflow/executor/utils'; -import { WorkflowGraphList } from '../plugins/copilot/workflow/graph'; -import { CopilotWorkspaceService } from '../plugins/copilot/workspace'; -import { PaymentModule } from '../plugins/payment'; -import { SubscriptionService } from '../plugins/payment/service'; -import { SubscriptionStatus } from '../plugins/payment/types'; -import { MockCopilotProvider } from './mocks'; -import { createTestingModule, TestingModule } from './utils'; -import { WorkflowTestCases } from './utils/copilot'; +} from '../../plugins/copilot/workflow/executor'; +import { AutoRegisteredWorkflowExecutor } from '../../plugins/copilot/workflow/executor/utils'; +import { WorkflowGraphList } from '../../plugins/copilot/workflow/graph'; +import { CopilotWorkspaceService } from '../../plugins/copilot/workspace'; +import { PaymentModule } from '../../plugins/payment'; +import { SubscriptionService } from '../../plugins/payment/service'; +import { SubscriptionStatus } from '../../plugins/payment/types'; +import { MockCopilotProvider } from '../mocks'; +import { createTestingModule, TestingModule } from '../utils'; +import { WorkflowTestCases } from '../utils/copilot'; type Context = { auth: AuthService; @@ -364,6 +364,21 @@ test('should be able to manage chat session', async t => { }); t.is(newSessionId, sessionId, 'should get same session id'); } + + // should create a fresh session when reuseLatestChat is explicitly disabled + { + const newSessionId = await session.create({ + userId, + promptName, + ...commonParams, + reuseLatestChat: false, + }); + t.not( + newSessionId, + sessionId, + 'should create new session id when reuseLatestChat is false' + ); + } }); test('should be able to update chat session prompt', async t => { @@ -881,6 +896,26 @@ test('should be able to get provider', async t => { } }); +test('should resolve provider by prefixed model id', async t => { + const { factory } = t.context; + + const provider = await factory.getProviderByModel('openai-default/test'); + t.truthy(provider, 'should resolve prefixed model id'); + t.is(provider?.type, CopilotProviderType.OpenAI); + + const result = await provider?.text({ modelId: 'openai-default/test' }, [ + { role: 'user', content: 'hello' }, + ]); + t.is(result, 'generate text to text'); +}); + +test('should fallback to null when prefixed provider id does not exist', async t => { + const { factory } = t.context; + + const provider = await factory.getProviderByModel('unknown/test'); + t.is(provider, null); +}); + // ==================== workflow ==================== // this test used to preview the final result of the workflow @@ -2063,25 +2098,23 @@ test('should handle copilot cron jobs correctly', async t => { }); test('should resolve model correctly based on subscription status and prompt config', async t => { - const { db, session, subscription } = t.context; + const { prompt, session, subscription } = t.context; // 1) Seed a prompt that has optionalModels and proModels in config const promptName = 'resolve-model-test'; - await db.aiPrompt.create({ - data: { - name: promptName, - model: 'gemini-2.5-flash', - messages: { - create: [{ idx: 0, role: 'system', content: 'test' }], - }, - config: { proModels: ['gemini-2.5-pro', 'claude-sonnet-4-5@20250929'] }, + await prompt.set( + promptName, + 'gemini-2.5-flash', + [{ role: 'system', content: 'test' }], + { proModels: ['gemini-2.5-pro', 'claude-sonnet-4-5@20250929'] }, + { optionalModels: [ 'gemini-2.5-flash', 'gemini-2.5-pro', 'claude-sonnet-4-5@20250929', ], - }, - }); + } + ); // 2) Create a chat session with this prompt const sessionId = await session.create({ @@ -2106,6 +2139,16 @@ test('should resolve model correctly based on subscription status and prompt con const model1 = await s.resolveModel(false, 'gemini-2.5-pro'); t.snapshot(model1, 'should honor requested pro model'); + const model1WithPrefix = await s.resolveModel( + false, + 'openai-default/gemini-2.5-pro' + ); + t.is( + model1WithPrefix, + 'openai-default/gemini-2.5-pro', + 'should honor requested prefixed pro model' + ); + const model2 = await s.resolveModel(false, 'not-in-optional'); t.snapshot(model2, 'should fallback to default model'); } @@ -2119,6 +2162,16 @@ test('should resolve model correctly based on subscription status and prompt con 'should fallback to default model when requesting pro model during trialing' ); + const model3WithPrefix = await s.resolveModel( + true, + 'openai-default/gemini-2.5-pro' + ); + t.is( + model3WithPrefix, + 'gemini-2.5-flash', + 'should fallback to default model when requesting prefixed pro model during trialing' + ); + const model4 = await s.resolveModel(true, 'gemini-2.5-flash'); t.snapshot(model4, 'should honor requested non-pro model during trialing'); @@ -2141,6 +2194,16 @@ test('should resolve model correctly based on subscription status and prompt con const model7 = await s.resolveModel(true, 'claude-sonnet-4-5@20250929'); t.snapshot(model7, 'should honor requested pro model during active'); + const model7WithPrefix = await s.resolveModel( + true, + 'openai-default/claude-sonnet-4-5@20250929' + ); + t.is( + model7WithPrefix, + 'openai-default/claude-sonnet-4-5@20250929', + 'should honor requested prefixed pro model during active' + ); + const model8 = await s.resolveModel(true, 'not-in-optional'); t.snapshot( model8, diff --git a/packages/backend/server/src/__tests__/copilot/native-adapter.spec.ts b/packages/backend/server/src/__tests__/copilot/native-adapter.spec.ts new file mode 100644 index 0000000000..820d16093c --- /dev/null +++ b/packages/backend/server/src/__tests__/copilot/native-adapter.spec.ts @@ -0,0 +1,210 @@ +import test from 'ava'; +import { z } from 'zod'; + +import type { NativeLlmRequest, NativeLlmStreamEvent } from '../../native'; +import { + buildNativeRequest, + NativeProviderAdapter, +} from '../../plugins/copilot/providers/native'; + +const mockDispatch = () => + (async function* (): AsyncIterableIterator { + yield { type: 'text_delta', text: 'Use [^1] now' }; + yield { type: 'citation', index: 1, url: 'https://affine.pro' }; + yield { type: 'done', finish_reason: 'stop' }; + })(); + +test('NativeProviderAdapter streamText should append citation footnotes', async t => { + const adapter = new NativeProviderAdapter(mockDispatch, {}, 3); + const chunks: string[] = []; + for await (const chunk of adapter.streamText({ + model: 'gpt-4.1', + stream: true, + messages: [{ role: 'user', content: [{ type: 'text', text: 'hi' }] }], + })) { + chunks.push(chunk); + } + + const text = chunks.join(''); + t.true(text.includes('Use [^1] now')); + t.true( + text.includes('[^1]: {"type":"url","url":"https%3A%2F%2Faffine.pro"}') + ); +}); + +test('NativeProviderAdapter streamObject should append citation footnotes', async t => { + const adapter = new NativeProviderAdapter(mockDispatch, {}, 3); + const chunks = []; + for await (const chunk of adapter.streamObject({ + model: 'gpt-4.1', + stream: true, + messages: [{ role: 'user', content: [{ type: 'text', text: 'hi' }] }], + })) { + chunks.push(chunk); + } + + t.deepEqual( + chunks.map(chunk => chunk.type), + ['text-delta', 'text-delta'] + ); + const text = chunks + .filter(chunk => chunk.type === 'text-delta') + .map(chunk => chunk.textDelta) + .join(''); + t.true(text.includes('Use [^1] now')); + t.true( + text.includes('[^1]: {"type":"url","url":"https%3A%2F%2Faffine.pro"}') + ); +}); + +test('NativeProviderAdapter streamObject should append fallback attachment footnotes', async t => { + const dispatch = () => + (async function* (): AsyncIterableIterator { + yield { + type: 'tool_result', + call_id: 'call_1', + name: 'blob_read', + arguments: { blob_id: 'blob_1' }, + output: { + blobId: 'blob_1', + fileName: 'a.txt', + fileType: 'text/plain', + content: 'A', + }, + }; + yield { + type: 'tool_result', + call_id: 'call_2', + name: 'blob_read', + arguments: { blob_id: 'blob_2' }, + output: { + blobId: 'blob_2', + fileName: 'b.txt', + fileType: 'text/plain', + content: 'B', + }, + }; + yield { type: 'text_delta', text: 'Answer from files.' }; + yield { type: 'done', finish_reason: 'stop' }; + })(); + + const adapter = new NativeProviderAdapter(dispatch, {}, 3); + const chunks = []; + for await (const chunk of adapter.streamObject({ + model: 'gpt-4.1', + stream: true, + messages: [{ role: 'user', content: [{ type: 'text', text: 'hi' }] }], + })) { + chunks.push(chunk); + } + + const text = chunks + .filter(chunk => chunk.type === 'text-delta') + .map(chunk => chunk.textDelta) + .join(''); + t.true(text.includes('Answer from files.')); + t.true(text.includes('[^1][^2]')); + t.true( + text.includes( + '[^1]: {"type":"attachment","blobId":"blob_1","fileName":"a.txt","fileType":"text/plain"}' + ) + ); + t.true( + text.includes( + '[^2]: {"type":"attachment","blobId":"blob_2","fileName":"b.txt","fileType":"text/plain"}' + ) + ); +}); + +test('NativeProviderAdapter streamObject should map tool and text events', async t => { + let round = 0; + const dispatch = (_request: NativeLlmRequest) => + (async function* (): AsyncIterableIterator { + round += 1; + if (round === 1) { + yield { + type: 'tool_call', + call_id: 'call_1', + name: 'doc_read', + arguments: { doc_id: 'a1' }, + }; + yield { type: 'done', finish_reason: 'tool_calls' }; + return; + } + yield { type: 'text_delta', text: 'ok' }; + yield { type: 'done', finish_reason: 'stop' }; + })(); + + const adapter = new NativeProviderAdapter( + dispatch, + { + doc_read: { + inputSchema: z.object({ doc_id: z.string() }), + execute: async () => ({ markdown: '# a1' }), + }, + }, + 4 + ); + + const events = []; + for await (const event of adapter.streamObject({ + model: 'gpt-4.1', + stream: true, + messages: [{ role: 'user', content: [{ type: 'text', text: 'read' }] }], + })) { + events.push(event); + } + + t.deepEqual( + events.map(event => event.type), + ['tool-call', 'tool-result', 'text-delta'] + ); + t.deepEqual(events[0], { + type: 'tool-call', + toolCallId: 'call_1', + toolName: 'doc_read', + args: { doc_id: 'a1' }, + }); +}); + +test('buildNativeRequest should include rust middleware from profile', async t => { + const { request } = await buildNativeRequest({ + model: 'gpt-4.1', + messages: [{ role: 'user', content: 'hello' }], + tools: {}, + middleware: { + rust: { + request: ['normalize_messages', 'clamp_max_tokens'], + stream: ['stream_event_normalize', 'citation_indexing'], + }, + node: { + text: ['callout'], + }, + }, + }); + + t.deepEqual(request.middleware, { + request: ['normalize_messages', 'clamp_max_tokens'], + stream: ['stream_event_normalize', 'citation_indexing'], + }); +}); + +test('NativeProviderAdapter streamText should skip citation footnotes when disabled', async t => { + const adapter = new NativeProviderAdapter(mockDispatch, {}, 3, { + nodeTextMiddleware: ['callout'], + }); + const chunks: string[] = []; + for await (const chunk of adapter.streamText({ + model: 'gpt-4.1', + stream: true, + messages: [{ role: 'user', content: [{ type: 'text', text: 'hi' }] }], + })) { + chunks.push(chunk); + } + + const text = chunks.join(''); + t.true(text.includes('Use [^1] now')); + t.false( + text.includes('[^1]: {"type":"url","url":"https%3A%2F%2Faffine.pro"}') + ); +}); diff --git a/packages/backend/server/src/__tests__/copilot/provider-middleware.spec.ts b/packages/backend/server/src/__tests__/copilot/provider-middleware.spec.ts new file mode 100644 index 0000000000..81bda1a604 --- /dev/null +++ b/packages/backend/server/src/__tests__/copilot/provider-middleware.spec.ts @@ -0,0 +1,56 @@ +import test from 'ava'; + +import { resolveProviderMiddleware } from '../../plugins/copilot/providers/provider-middleware'; +import { buildProviderRegistry } from '../../plugins/copilot/providers/provider-registry'; +import { CopilotProviderType } from '../../plugins/copilot/providers/types'; + +test('resolveProviderMiddleware should include anthropic defaults', t => { + const middleware = resolveProviderMiddleware(CopilotProviderType.Anthropic); + + t.deepEqual(middleware.rust?.request, [ + 'normalize_messages', + 'tool_schema_rewrite', + ]); + t.deepEqual(middleware.rust?.stream, [ + 'stream_event_normalize', + 'citation_indexing', + ]); + t.deepEqual(middleware.node?.text, ['citation_footnote', 'callout']); +}); + +test('resolveProviderMiddleware should merge defaults and overrides', t => { + const middleware = resolveProviderMiddleware(CopilotProviderType.OpenAI, { + rust: { request: ['clamp_max_tokens'] }, + node: { text: ['thinking_format'] }, + }); + + t.deepEqual(middleware.rust?.request, [ + 'normalize_messages', + 'clamp_max_tokens', + ]); + t.deepEqual(middleware.node?.text, [ + 'citation_footnote', + 'callout', + 'thinking_format', + ]); +}); + +test('buildProviderRegistry should normalize profile middleware defaults', t => { + const registry = buildProviderRegistry({ + profiles: [ + { + id: 'openai-main', + type: CopilotProviderType.OpenAI, + config: { apiKey: '1' }, + }, + ], + }); + + const profile = registry.profiles.get('openai-main'); + t.truthy(profile); + t.deepEqual(profile?.middleware.rust?.stream, [ + 'stream_event_normalize', + 'citation_indexing', + ]); + t.deepEqual(profile?.middleware.node?.text, ['citation_footnote', 'callout']); +}); diff --git a/packages/backend/server/src/__tests__/copilot/provider-native.spec.ts b/packages/backend/server/src/__tests__/copilot/provider-native.spec.ts new file mode 100644 index 0000000000..34ac62cfc0 --- /dev/null +++ b/packages/backend/server/src/__tests__/copilot/provider-native.spec.ts @@ -0,0 +1,99 @@ +import test from 'ava'; + +import { ProviderMiddlewareConfig } from '../../plugins/copilot/config'; +import { CopilotProvider } from '../../plugins/copilot/providers/provider'; +import { + CopilotProviderType, + ModelInputType, + ModelOutputType, +} from '../../plugins/copilot/providers/types'; + +class TestOpenAIProvider extends CopilotProvider<{ apiKey: string }> { + readonly type = CopilotProviderType.OpenAI; + readonly models = [ + { + id: 'gpt-4.1', + capabilities: [ + { + input: [ModelInputType.Text], + output: [ModelOutputType.Text], + defaultForOutputType: true, + }, + ], + }, + ]; + + configured() { + return true; + } + + async text(_cond: any, _messages: any[], _options?: any) { + return ''; + } + + async *streamText(_cond: any, _messages: any[], _options?: any) { + yield ''; + } + + exposeMetricLabels() { + return this.metricLabels('gpt-4.1'); + } + + exposeMiddleware() { + return this.getActiveProviderMiddleware(); + } +} + +function createProvider(profileMiddleware?: ProviderMiddlewareConfig) { + const provider = new TestOpenAIProvider(); + (provider as any).AFFiNEConfig = { + copilot: { + providers: { + profiles: [ + { + id: 'openai-main', + type: CopilotProviderType.OpenAI, + config: { apiKey: 'test' }, + middleware: profileMiddleware, + }, + ], + defaults: {}, + openai: { apiKey: 'legacy' }, + }, + }, + }; + return provider; +} + +test('metricLabels should include active provider id', t => { + const provider = createProvider(); + const labels = provider.runWithProfile('openai-main', () => + provider.exposeMetricLabels() + ); + t.is(labels.providerId, 'openai-main'); +}); + +test('getActiveProviderMiddleware should merge defaults with profile override', t => { + const provider = createProvider({ + rust: { request: ['clamp_max_tokens'] }, + node: { text: ['thinking_format'] }, + }); + + const middleware = provider.runWithProfile('openai-main', () => + provider.exposeMiddleware() + ); + + t.deepEqual(middleware.rust?.request, [ + 'normalize_messages', + 'clamp_max_tokens', + ]); + t.deepEqual(middleware.rust?.stream, [ + 'stream_event_normalize', + 'citation_indexing', + ]); + t.deepEqual(middleware.node?.text, [ + 'citation_footnote', + 'callout', + 'thinking_format', + ]); +}); diff --git a/packages/backend/server/src/__tests__/copilot/provider-registry.spec.ts b/packages/backend/server/src/__tests__/copilot/provider-registry.spec.ts new file mode 100644 index 0000000000..858c3d3cde --- /dev/null +++ b/packages/backend/server/src/__tests__/copilot/provider-registry.spec.ts @@ -0,0 +1,165 @@ +import test from 'ava'; + +import { + buildProviderRegistry, + resolveModel, + stripProviderPrefix, +} from '../../plugins/copilot/providers/provider-registry'; +import { + CopilotProviderType, + ModelOutputType, +} from '../../plugins/copilot/providers/types'; + +test('buildProviderRegistry should keep explicit profile over legacy compatibility profile', t => { + const registry = buildProviderRegistry({ + profiles: [ + { + id: 'openai-default', + type: CopilotProviderType.OpenAI, + priority: 100, + config: { apiKey: 'new' }, + }, + ], + openai: { apiKey: 'legacy' }, + }); + + const profile = registry.profiles.get('openai-default'); + t.truthy(profile); + t.deepEqual(profile?.config, { apiKey: 'new' }); +}); + +test('buildProviderRegistry should reject duplicated profile ids', t => { + const error = t.throws(() => + buildProviderRegistry({ + profiles: [ + { + id: 'openai-main', + type: CopilotProviderType.OpenAI, + config: { apiKey: '1' }, + }, + { + id: 'openai-main', + type: CopilotProviderType.OpenAI, + config: { apiKey: '2' }, + }, + ], + }) + ) as Error; + + t.truthy(error); + t.regex(error.message, /Duplicated copilot provider profile id/); +}); + +test('buildProviderRegistry should reject defaults that reference unknown providers', t => { + const error = t.throws(() => + buildProviderRegistry({ + profiles: [ + { + id: 'openai-main', + type: CopilotProviderType.OpenAI, + config: { apiKey: '1' }, + }, + ], + defaults: { + fallback: 'unknown-provider', + }, + }) + ) as Error; + + t.truthy(error); + t.regex(error.message, /defaults references unknown providerId/); +}); + +test('resolveModel should support explicit provider prefix and keep slash models untouched', t => { + const registry = buildProviderRegistry({ + profiles: [ + { + id: 'openai-main', + type: CopilotProviderType.OpenAI, + config: { apiKey: '1' }, + }, + { + id: 'fal-main', + type: CopilotProviderType.FAL, + config: { apiKey: '2' }, + }, + ], + }); + + const prefixed = resolveModel({ + registry, + modelId: 'openai-main/gpt-4.1', + }); + t.deepEqual(prefixed, { + rawModelId: 'openai-main/gpt-4.1', + modelId: 'gpt-4.1', + explicitProviderId: 'openai-main', + candidateProviderIds: ['openai-main'], + }); + + const slashModel = resolveModel({ + registry, + modelId: 'lora/image-to-image', + }); + t.is(slashModel.modelId, 'lora/image-to-image'); + t.false(slashModel.candidateProviderIds.includes('lora')); +}); + +test('resolveModel should follow defaults -> fallback -> order and apply filters', t => { + const registry = buildProviderRegistry({ + profiles: [ + { + id: 'openai-main', + type: CopilotProviderType.OpenAI, + priority: 10, + config: { apiKey: '1' }, + }, + { + id: 'anthropic-main', + type: CopilotProviderType.Anthropic, + priority: 5, + config: { apiKey: '2' }, + }, + { + id: 'fal-main', + type: CopilotProviderType.FAL, + priority: 1, + config: { apiKey: '3' }, + }, + ], + defaults: { + [ModelOutputType.Text]: 'anthropic-main', + fallback: 'openai-main', + }, + }); + + const routed = resolveModel({ + registry, + outputType: ModelOutputType.Text, + preferredProviderIds: ['openai-main', 'fal-main'], + }); + + t.deepEqual(routed.candidateProviderIds, ['openai-main', 'fal-main']); +}); + +test('stripProviderPrefix should only strip matched provider prefix', t => { + const registry = buildProviderRegistry({ + profiles: [ + { + id: 'openai-main', + type: CopilotProviderType.OpenAI, + config: { apiKey: '1' }, + }, + ], + }); + + t.is( + stripProviderPrefix(registry, 'openai-main', 'openai-main/gpt-4.1'), + 'gpt-4.1' + ); + t.is( + stripProviderPrefix(registry, 'openai-main', 'another-main/gpt-4.1'), + 'another-main/gpt-4.1' + ); + t.is(stripProviderPrefix(registry, 'openai-main', 'gpt-4.1'), 'gpt-4.1'); +}); diff --git a/packages/backend/server/src/__tests__/copilot/tool-call-loop.spec.ts b/packages/backend/server/src/__tests__/copilot/tool-call-loop.spec.ts new file mode 100644 index 0000000000..95ec395a81 --- /dev/null +++ b/packages/backend/server/src/__tests__/copilot/tool-call-loop.spec.ts @@ -0,0 +1,134 @@ +import test from 'ava'; +import { z } from 'zod'; + +import { NativeLlmRequest, NativeLlmStreamEvent } from '../../native'; +import { + ToolCallAccumulator, + ToolCallLoop, + ToolSchemaExtractor, +} from '../../plugins/copilot/providers/loop'; + +test('ToolCallAccumulator should merge deltas and complete tool call', t => { + const accumulator = new ToolCallAccumulator(); + + accumulator.feedDelta({ + type: 'tool_call_delta', + call_id: 'call_1', + name: 'doc_read', + arguments_delta: '{"doc_id":"', + }); + accumulator.feedDelta({ + type: 'tool_call_delta', + call_id: 'call_1', + arguments_delta: 'a1"}', + }); + + const completed = accumulator.complete({ + type: 'tool_call', + call_id: 'call_1', + name: 'doc_read', + arguments: { doc_id: 'a1' }, + }); + + t.deepEqual(completed, { + id: 'call_1', + name: 'doc_read', + args: { doc_id: 'a1' }, + thought: undefined, + }); +}); + +test('ToolSchemaExtractor should convert zod schema to json schema', t => { + const toolSet = { + doc_read: { + description: 'Read doc', + inputSchema: z.object({ + doc_id: z.string(), + limit: z.number().optional(), + }), + execute: async () => ({}), + }, + }; + + const extracted = ToolSchemaExtractor.extract(toolSet); + + t.deepEqual(extracted, [ + { + name: 'doc_read', + description: 'Read doc', + parameters: { + type: 'object', + properties: { + doc_id: { type: 'string' }, + limit: { type: 'number' }, + }, + additionalProperties: false, + required: ['doc_id'], + }, + }, + ]); +}); + +test('ToolCallLoop should execute tool call and continue to next round', async t => { + const dispatchRequests: NativeLlmRequest[] = []; + + const dispatch = (request: NativeLlmRequest) => { + dispatchRequests.push(request); + const round = dispatchRequests.length; + + return (async function* (): AsyncIterableIterator { + if (round === 1) { + yield { + type: 'tool_call_delta', + call_id: 'call_1', + name: 'doc_read', + arguments_delta: '{"doc_id":"a1"}', + }; + yield { + type: 'tool_call', + call_id: 'call_1', + name: 'doc_read', + arguments: { doc_id: 'a1' }, + }; + yield { type: 'done', finish_reason: 'tool_calls' }; + return; + } + + yield { type: 'text_delta', text: 'done' }; + yield { type: 'done', finish_reason: 'stop' }; + })(); + }; + + let executedArgs: Record | null = null; + const loop = new ToolCallLoop( + dispatch, + { + doc_read: { + inputSchema: z.object({ doc_id: z.string() }), + execute: async args => { + executedArgs = args; + return { markdown: '# doc' }; + }, + }, + }, + 4 + ); + + const events: NativeLlmStreamEvent[] = []; + for await (const event of loop.run({ + model: 'gpt-4.1', + stream: true, + messages: [{ role: 'user', content: [{ type: 'text', text: 'read doc' }] }], + })) { + events.push(event); + } + + t.deepEqual(executedArgs, { doc_id: 'a1' }); + t.true( + dispatchRequests[1]?.messages.some(message => message.role === 'tool') + ); + t.deepEqual( + events.map(event => event.type), + ['tool_call', 'tool_result', 'text_delta', 'done'] + ); +}); diff --git a/packages/backend/server/src/__tests__/copilot/utils.spec.ts b/packages/backend/server/src/__tests__/copilot/utils.spec.ts new file mode 100644 index 0000000000..12c13e5fee --- /dev/null +++ b/packages/backend/server/src/__tests__/copilot/utils.spec.ts @@ -0,0 +1,116 @@ +import test from 'ava'; +import { z } from 'zod'; + +import { + chatToGPTMessage, + CitationFootnoteFormatter, + CitationParser, + StreamPatternParser, +} from '../../plugins/copilot/providers/utils'; + +test('CitationFootnoteFormatter should format sorted footnotes from citation events', t => { + const formatter = new CitationFootnoteFormatter(); + + formatter.consume({ + type: 'citation', + index: 2, + url: 'https://example.com/b', + }); + formatter.consume({ + type: 'citation', + index: 1, + url: 'https://example.com/a', + }); + + t.is( + formatter.end(), + [ + '[^1]: {"type":"url","url":"https%3A%2F%2Fexample.com%2Fa"}', + '[^2]: {"type":"url","url":"https%3A%2F%2Fexample.com%2Fb"}', + ].join('\n') + ); +}); + +test('CitationFootnoteFormatter should overwrite duplicated index with latest url', t => { + const formatter = new CitationFootnoteFormatter(); + + formatter.consume({ + type: 'citation', + index: 1, + url: 'https://example.com/old', + }); + formatter.consume({ + type: 'citation', + index: 1, + url: 'https://example.com/new', + }); + + t.is( + formatter.end(), + '[^1]: {"type":"url","url":"https%3A%2F%2Fexample.com%2Fnew"}' + ); +}); + +test('StreamPatternParser should keep state across chunks', t => { + const parser = new StreamPatternParser(pattern => { + if (pattern.kind === 'wrappedLink') { + return `[^${pattern.url}]`; + } + if (pattern.kind === 'index') { + return `[#${pattern.value}]`; + } + return `[${pattern.text}](${pattern.url})`; + }); + + const first = parser.write('ref ([AFFiNE](https://affine.pro'); + const second = parser.write(')) and [2]'); + + t.is(first, 'ref '); + t.is(second, '[^https://affine.pro] and [#2]'); + t.is(parser.end(), ''); +}); + +test('CitationParser should convert wrapped links to numbered footnotes', t => { + const parser = new CitationParser(); + + const output = parser.parse('Use ([AFFiNE](https://affine.pro)) now'); + t.is(output, 'Use [^1] now'); + t.regex( + parser.end(), + /\[\^1\]: \{"type":"url","url":"https%3A%2F%2Faffine.pro"\}/ + ); +}); + +test('chatToGPTMessage should not mutate input and should keep system schema', async t => { + const schema = z.object({ + query: z.string(), + }); + const messages = [ + { + role: 'system' as const, + content: 'You are helper', + params: { schema }, + }, + { + role: 'user' as const, + content: '', + attachments: ['https://example.com/a.png'], + }, + ]; + const firstRef = messages[0]; + const secondRef = messages[1]; + const [system, normalized, parsedSchema] = await chatToGPTMessage( + messages, + false + ); + + t.is(system, 'You are helper'); + t.is(parsedSchema, schema); + t.is(messages.length, 2); + t.is(messages[0], firstRef); + t.is(messages[1], secondRef); + t.deepEqual(normalized[0], { + role: 'user', + content: [{ type: 'text', text: '[no content]' }], + }); +}); diff --git a/packages/backend/server/src/__tests__/native.spec.ts b/packages/backend/server/src/__tests__/native.spec.ts new file mode 100644 index 0000000000..bc088cfaa4 --- /dev/null +++ b/packages/backend/server/src/__tests__/native.spec.ts @@ -0,0 +1,82 @@ +import test from 'ava'; + +import { NativeStreamAdapter } from '../native'; + +test('NativeStreamAdapter should support buffered and awaited consumption', async t => { + const adapter = new NativeStreamAdapter(undefined); + + adapter.push(1); + const first = await adapter.next(); + t.deepEqual(first, { value: 1, done: false }); + + const pending = adapter.next(); + adapter.push(2); + const second = await pending; + t.deepEqual(second, { value: 2, done: false }); + + adapter.push(null); + const done = await adapter.next(); + t.true(done.done); +}); + +test('NativeStreamAdapter return should abort handle and end iteration', async t => { + let abortCount = 0; + const adapter = new NativeStreamAdapter({ + abort: () => { + abortCount += 1; + }, + }); + + const ended = await adapter.return(); + t.is(abortCount, 1); + t.true(ended.done); + + const secondReturn = await adapter.return(); + t.true(secondReturn.done); + t.is(abortCount, 1); + + const next = await adapter.next(); + t.true(next.done); +}); + +test('NativeStreamAdapter should abort when AbortSignal is triggered', async t => { + let abortCount = 0; + const controller = new AbortController(); + const adapter = new NativeStreamAdapter( + { + abort: () => { + abortCount += 1; + }, + }, + controller.signal + ); + + const pending = adapter.next(); + controller.abort(); + const done = await pending; + t.true(done.done); + t.is(abortCount, 1); +}); + +test('NativeStreamAdapter should end immediately for pre-aborted signal', async t => { + let abortCount = 0; + const controller = new AbortController(); + controller.abort(); + + const adapter = new NativeStreamAdapter( + { + abort: () => { + abortCount += 1; + }, + }, + controller.signal + ); + + const next = await adapter.next(); + t.true(next.done); + t.is(abortCount, 1); + + adapter.push(1); + const stillDone = await adapter.next(); + t.true(stillDone.done); +}); diff --git a/packages/backend/server/src/__tests__/utils/copilot.ts b/packages/backend/server/src/__tests__/utils/copilot.ts index 9e738ba43d..59aacb7b9e 100644 --- a/packages/backend/server/src/__tests__/utils/copilot.ts +++ b/packages/backend/server/src/__tests__/utils/copilot.ts @@ -629,14 +629,35 @@ export async function chatWithText( prefix = '', retry?: boolean ): Promise { + const endpoint = prefix || '/stream'; const query = messageId ? `?messageId=${messageId}` + (retry ? '&retry=true' : '') : ''; const res = await app - .GET(`/api/copilot/chat/${sessionId}${prefix}${query}`) + .GET(`/api/copilot/chat/${sessionId}${endpoint}${query}`) .expect(200); - return res.text; + if (prefix) { + return res.text; + } + + const events = sse2array(res.text); + const errorEvent = events.find(event => event.event === 'error'); + if (errorEvent?.data) { + let message = errorEvent.data; + try { + const parsed = JSON.parse(errorEvent.data); + message = parsed.message || message; + } catch { + // noop: keep raw error data + } + throw new Error(message); + } + + return events + .filter(event => event.event === 'message') + .map(event => event.data ?? '') + .join(''); } export async function chatWithTextStream( diff --git a/packages/backend/server/src/__tests__/worker.e2e.ts b/packages/backend/server/src/__tests__/worker.e2e.ts index 1ebe09006e..d111a03d09 100644 --- a/packages/backend/server/src/__tests__/worker.e2e.ts +++ b/packages/backend/server/src/__tests__/worker.e2e.ts @@ -38,8 +38,11 @@ test.before(async t => { t.context.app = app; }); -test.after.always(async t => { +test.afterEach.always(() => { Sinon.restore(); +}); + +test.after.always(async t => { __resetDnsLookupForTests(); await t.context.app.close(); }); @@ -80,6 +83,7 @@ const assertAndSnapshotRaw = async ( test('should proxy image', async t => { const assertAndSnapshot = assertAndSnapshotRaw.bind(null, t); + const imageUrl = `http://example.com/image-${Date.now()}.png`; await assertAndSnapshot( '/api/worker/image-proxy', @@ -105,7 +109,7 @@ test('should proxy image', async t => { { await assertAndSnapshot( - '/api/worker/image-proxy?url=http://example.com/image.png', + `/api/worker/image-proxy?url=${imageUrl}`, 'should return 400 if origin and referer are missing', { status: 400, origin: null, referer: null } ); @@ -113,14 +117,17 @@ test('should proxy image', async t => { { await assertAndSnapshot( - '/api/worker/image-proxy?url=http://example.com/image.png', + `/api/worker/image-proxy?url=${imageUrl}`, 'should return 400 for invalid origin header', { status: 400, origin: 'http://invalid.com' } ); } { - const fakeBuffer = Buffer.from('fake image'); + const fakeBuffer = Buffer.from( + 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8/x8AAwMCAO+jfJ8AAAAASUVORK5CYII=', + 'base64' + ); const fakeResponse = new Response(fakeBuffer, { status: 200, headers: { @@ -130,13 +137,14 @@ test('should proxy image', async t => { }); const fetchSpy = Sinon.stub(global, 'fetch').resolves(fakeResponse); - - await assertAndSnapshot( - '/api/worker/image-proxy?url=http://example.com/image.png', - 'should return image buffer' - ); - - fetchSpy.restore(); + try { + await assertAndSnapshot( + `/api/worker/image-proxy?url=${imageUrl}`, + 'should return image buffer' + ); + } finally { + fetchSpy.restore(); + } } }); @@ -200,18 +208,19 @@ test('should preview link', async t => { }); const fetchSpy = Sinon.stub(global, 'fetch').resolves(fakeHTML); - - await assertAndSnapshot( - '/api/worker/link-preview', - 'should process a valid external URL and return link preview data', - { - status: 200, - method: 'POST', - body: { url: 'http://external.com/page' }, - } - ); - - fetchSpy.restore(); + try { + await assertAndSnapshot( + '/api/worker/link-preview', + 'should process a valid external URL and return link preview data', + { + status: 200, + method: 'POST', + body: { url: 'http://external.com/page' }, + } + ); + } finally { + fetchSpy.restore(); + } } { @@ -251,18 +260,19 @@ test('should preview link', async t => { }); const fetchSpy = Sinon.stub(global, 'fetch').resolves(fakeHTML); - - await assertAndSnapshot( - '/api/worker/link-preview', - 'should decode HTML content with charset', - { - status: 200, - method: 'POST', - body: { url: `http://example.com/${charset}` }, - } - ); - - fetchSpy.restore(); + try { + await assertAndSnapshot( + '/api/worker/link-preview', + 'should decode HTML content with charset', + { + status: 200, + method: 'POST', + body: { url: `http://example.com/${charset}` }, + } + ); + } finally { + fetchSpy.restore(); + } } } }); diff --git a/packages/backend/server/src/core/telemetry/ga4-client.ts b/packages/backend/server/src/core/telemetry/ga4-client.ts index 6afa73fdb1..b9e2a18a15 100644 --- a/packages/backend/server/src/core/telemetry/ga4-client.ts +++ b/packages/backend/server/src/core/telemetry/ga4-client.ts @@ -42,8 +42,18 @@ export class Ga4Client { timestamp_micros: event.timestampMicros, })), }; - - await this.post(payload); + try { + await this.post(payload); + } catch { + if (env.DEPLOYMENT_TYPE === 'affine') { + // In production, we want to be resilient to GA4 failures, so we catch and ignore errors. + // In non-production environments, we rethrow to surface issues during development and testing. + console.info( + 'Failed to send telemetry event to GA4:', + chunk.map(e => e.eventName).join(', ') + ); + } + } } } } diff --git a/packages/backend/server/src/native.ts b/packages/backend/server/src/native.ts index 7563eb7a5a..6ec908b567 100644 --- a/packages/backend/server/src/native.ts +++ b/packages/backend/server/src/native.ts @@ -57,3 +57,316 @@ export const addDocToRootDoc = serverNativeModule.addDocToRootDoc; export const updateDocTitle = serverNativeModule.updateDocTitle; export const updateDocProperties = serverNativeModule.updateDocProperties; export const updateRootDocMetaTitle = serverNativeModule.updateRootDocMetaTitle; + +type NativeLlmModule = { + llmDispatch?: ( + protocol: string, + backendConfigJson: string, + requestJson: string + ) => string | Promise; + llmDispatchStream?: ( + protocol: string, + backendConfigJson: string, + requestJson: string, + callback: (error: Error | null, eventJson: string) => void + ) => { abort?: () => void } | undefined; +}; + +const nativeLlmModule = serverNativeModule as typeof serverNativeModule & + NativeLlmModule; + +export type NativeLlmProtocol = + | 'openai_chat' + | 'openai_responses' + | 'anthropic'; + +export type NativeLlmBackendConfig = { + base_url: string; + auth_token: string; + request_layer?: 'anthropic' | 'chat_completions' | 'responses' | 'vertex'; + headers?: Record; + no_streaming?: boolean; + timeout_ms?: number; +}; + +export type NativeLlmCoreRole = 'system' | 'user' | 'assistant' | 'tool'; + +export type NativeLlmCoreContent = + | { type: 'text'; text: string } + | { type: 'reasoning'; text: string; signature?: string } + | { + type: 'tool_call'; + call_id: string; + name: string; + arguments: Record; + thought?: string; + } + | { + type: 'tool_result'; + call_id: string; + output: unknown; + is_error?: boolean; + name?: string; + arguments?: Record; + } + | { type: 'image'; source: Record | string }; + +export type NativeLlmCoreMessage = { + role: NativeLlmCoreRole; + content: NativeLlmCoreContent[]; +}; + +export type NativeLlmToolDefinition = { + name: string; + description?: string; + parameters: Record; +}; + +export type NativeLlmRequest = { + model: string; + messages: NativeLlmCoreMessage[]; + stream?: boolean; + max_tokens?: number; + temperature?: number; + tools?: NativeLlmToolDefinition[]; + tool_choice?: 'auto' | 'none' | 'required' | { name: string }; + include?: string[]; + reasoning?: Record; + middleware?: { + request?: Array< + 'normalize_messages' | 'clamp_max_tokens' | 'tool_schema_rewrite' + >; + stream?: Array<'stream_event_normalize' | 'citation_indexing'>; + config?: { + no_additional_properties?: boolean; + drop_property_format?: boolean; + drop_property_min_length?: boolean; + drop_array_min_items?: boolean; + drop_array_max_items?: boolean; + max_tokens_cap?: number; + }; + }; +}; + +export type NativeLlmDispatchResponse = { + id: string; + model: string; + message: NativeLlmCoreMessage; + usage: { + prompt_tokens: number; + completion_tokens: number; + total_tokens: number; + cached_tokens?: number; + }; + finish_reason: string; + reasoning_details?: unknown; +}; + +export type NativeLlmStreamEvent = + | { type: 'message_start'; id?: string; model?: string } + | { type: 'text_delta'; text: string } + | { type: 'reasoning_delta'; text: string } + | { + type: 'tool_call_delta'; + call_id: string; + name?: string; + arguments_delta: string; + } + | { + type: 'tool_call'; + call_id: string; + name: string; + arguments: Record; + thought?: string; + } + | { + type: 'tool_result'; + call_id: string; + output: unknown; + is_error?: boolean; + name?: string; + arguments?: Record; + } + | { type: 'citation'; index: number; url: string } + | { + type: 'usage'; + usage: { + prompt_tokens: number; + completion_tokens: number; + total_tokens: number; + cached_tokens?: number; + }; + } + | { + type: 'done'; + finish_reason?: string; + usage?: { + prompt_tokens: number; + completion_tokens: number; + total_tokens: number; + cached_tokens?: number; + }; + } + | { type: 'error'; message: string; code?: string; raw?: string }; +const LLM_STREAM_END_MARKER = '__AFFINE_LLM_STREAM_END__'; + +export async function llmDispatch( + protocol: NativeLlmProtocol, + backendConfig: NativeLlmBackendConfig, + request: NativeLlmRequest +): Promise { + if (!nativeLlmModule.llmDispatch) { + throw new Error('native llm dispatch is not available'); + } + const response = nativeLlmModule.llmDispatch( + protocol, + JSON.stringify(backendConfig), + JSON.stringify(request) + ); + const responseText = await Promise.resolve(response); + return JSON.parse(responseText) as NativeLlmDispatchResponse; +} + +export class NativeStreamAdapter implements AsyncIterableIterator { + readonly #queue: T[] = []; + readonly #waiters: ((result: IteratorResult) => void)[] = []; + readonly #handle: { abort?: () => void } | undefined; + readonly #signal?: AbortSignal; + readonly #abortListener?: () => void; + #ended = false; + + constructor( + handle: { abort?: () => void } | undefined, + signal?: AbortSignal + ) { + this.#handle = handle; + this.#signal = signal; + + if (signal?.aborted) { + this.close(true); + return; + } + + if (signal) { + this.#abortListener = () => { + this.close(true); + }; + signal.addEventListener('abort', this.#abortListener, { once: true }); + } + } + + private close(abortHandle: boolean) { + if (this.#ended) { + return; + } + + this.#ended = true; + if (this.#signal && this.#abortListener) { + this.#signal.removeEventListener('abort', this.#abortListener); + } + if (abortHandle) { + this.#handle?.abort?.(); + } + + while (this.#waiters.length) { + const waiter = this.#waiters.shift(); + waiter?.({ value: undefined as T, done: true }); + } + } + + push(value: T | null) { + if (this.#ended) { + return; + } + + if (value === null) { + this.close(false); + return; + } + + const waiter = this.#waiters.shift(); + if (waiter) { + waiter({ value, done: false }); + return; + } + + this.#queue.push(value); + } + + [Symbol.asyncIterator]() { + return this; + } + + async next(): Promise> { + if (this.#queue.length > 0) { + const value = this.#queue.shift() as T; + return { value, done: false }; + } + + if (this.#ended) { + return { value: undefined as T, done: true }; + } + + return await new Promise(resolve => { + this.#waiters.push(resolve); + }); + } + + async return(): Promise> { + this.close(true); + + return { value: undefined as T, done: true }; + } +} + +export function llmDispatchStream( + protocol: NativeLlmProtocol, + backendConfig: NativeLlmBackendConfig, + request: NativeLlmRequest, + signal?: AbortSignal +): AsyncIterableIterator { + if (!nativeLlmModule.llmDispatchStream) { + throw new Error('native llm stream dispatch is not available'); + } + + let adapter: NativeStreamAdapter | undefined; + const buffer: (NativeLlmStreamEvent | null)[] = []; + let pushFn = (event: NativeLlmStreamEvent | null) => { + buffer.push(event); + }; + const handle = nativeLlmModule.llmDispatchStream( + protocol, + JSON.stringify(backendConfig), + JSON.stringify(request), + (error, eventJson) => { + if (error) { + pushFn({ type: 'error', message: error.message, raw: eventJson }); + return; + } + if (eventJson === LLM_STREAM_END_MARKER) { + pushFn(null); + return; + } + try { + pushFn(JSON.parse(eventJson) as NativeLlmStreamEvent); + } catch (error) { + pushFn({ + type: 'error', + message: + error instanceof Error + ? error.message + : 'failed to parse native stream event', + raw: eventJson, + }); + } + } + ); + adapter = new NativeStreamAdapter(handle, signal); + pushFn = event => { + adapter.push(event); + }; + for (const event of buffer) { + adapter.push(event); + } + return adapter; +} diff --git a/packages/backend/server/src/plugins/copilot/config.ts b/packages/backend/server/src/plugins/copilot/config.ts index 0f40790f67..bc695edae5 100644 --- a/packages/backend/server/src/plugins/copilot/config.ts +++ b/packages/backend/server/src/plugins/copilot/config.ts @@ -1,3 +1,5 @@ +import { z } from 'zod'; + import { defineModuleConfig, StorageJSONSchema, @@ -13,7 +15,179 @@ import { GeminiGenerativeConfig, GeminiVertexConfig } from './providers/gemini'; import { MorphConfig } from './providers/morph'; import { OpenAIConfig } from './providers/openai'; import { PerplexityConfig } from './providers/perplexity'; -import { VertexSchema } from './providers/types'; +import { + CopilotProviderType, + ModelOutputType, + VertexSchema, +} from './providers/types'; + +export type CopilotProviderConfigMap = { + [CopilotProviderType.OpenAI]: OpenAIConfig; + [CopilotProviderType.FAL]: FalConfig; + [CopilotProviderType.Gemini]: GeminiGenerativeConfig; + [CopilotProviderType.GeminiVertex]: GeminiVertexConfig; + [CopilotProviderType.Perplexity]: PerplexityConfig; + [CopilotProviderType.Anthropic]: AnthropicOfficialConfig; + [CopilotProviderType.AnthropicVertex]: AnthropicVertexConfig; + [CopilotProviderType.Morph]: MorphConfig; +}; + +export type ProviderSpecificConfig = + CopilotProviderConfigMap[keyof CopilotProviderConfigMap]; + +export const RustRequestMiddlewareValues = [ + 'normalize_messages', + 'clamp_max_tokens', + 'tool_schema_rewrite', +] as const; +export type RustRequestMiddleware = + (typeof RustRequestMiddlewareValues)[number]; + +export const RustStreamMiddlewareValues = [ + 'stream_event_normalize', + 'citation_indexing', +] as const; +export type RustStreamMiddleware = (typeof RustStreamMiddlewareValues)[number]; + +export const NodeTextMiddlewareValues = [ + 'citation_footnote', + 'callout', + 'thinking_format', +] as const; +export type NodeTextMiddleware = (typeof NodeTextMiddlewareValues)[number]; + +export type ProviderMiddlewareConfig = { + rust?: { request?: RustRequestMiddleware[]; stream?: RustStreamMiddleware[] }; + node?: { text?: NodeTextMiddleware[] }; +}; + +type CopilotProviderProfileCommon = { + id: string; + displayName?: string; + priority?: number; + enabled?: boolean; + models?: string[]; + middleware?: ProviderMiddlewareConfig; +}; + +type CopilotProviderProfileVariant = { + type: T; + config: CopilotProviderConfigMap[T]; +}; + +export type CopilotProviderProfile = CopilotProviderProfileCommon & + { + [Type in CopilotProviderType]: CopilotProviderProfileVariant; + }[CopilotProviderType]; + +export type CopilotProviderDefaults = Partial< + Record +> & { + fallback?: string; +}; + +const CopilotProviderProfileBaseShape = z.object({ + id: z.string().regex(/^[a-zA-Z0-9-_]+$/), + displayName: z.string().optional(), + priority: z.number().optional(), + enabled: z.boolean().optional(), + models: z.array(z.string()).optional(), + middleware: z + .object({ + rust: z + .object({ + request: z.array(z.enum(RustRequestMiddlewareValues)).optional(), + stream: z.array(z.enum(RustStreamMiddlewareValues)).optional(), + }) + .optional(), + node: z + .object({ text: z.array(z.enum(NodeTextMiddlewareValues)).optional() }) + .optional(), + }) + .optional(), +}); + +const OpenAIConfigShape = z.object({ + apiKey: z.string(), + baseURL: z.string().optional(), + oldApiStyle: z.boolean().optional(), +}); + +const FalConfigShape = z.object({ + apiKey: z.string(), +}); + +const GeminiGenerativeConfigShape = z.object({ + apiKey: z.string(), + baseURL: z.string().optional(), +}); + +const VertexProviderConfigShape = z.object({ + location: z.string().optional(), + project: z.string().optional(), + baseURL: z.string().optional(), + googleAuthOptions: z.any().optional(), + fetch: z.any().optional(), +}); + +const PerplexityConfigShape = z.object({ + apiKey: z.string(), + endpoint: z.string().optional(), +}); + +const AnthropicOfficialConfigShape = z.object({ + apiKey: z.string(), + baseURL: z.string().optional(), +}); + +const MorphConfigShape = z.object({ + apiKey: z.string().optional(), +}); + +const CopilotProviderProfileShape = z.discriminatedUnion('type', [ + CopilotProviderProfileBaseShape.extend({ + type: z.literal(CopilotProviderType.OpenAI), + config: OpenAIConfigShape, + }), + CopilotProviderProfileBaseShape.extend({ + type: z.literal(CopilotProviderType.FAL), + config: FalConfigShape, + }), + CopilotProviderProfileBaseShape.extend({ + type: z.literal(CopilotProviderType.Gemini), + config: GeminiGenerativeConfigShape, + }), + CopilotProviderProfileBaseShape.extend({ + type: z.literal(CopilotProviderType.GeminiVertex), + config: VertexProviderConfigShape, + }), + CopilotProviderProfileBaseShape.extend({ + type: z.literal(CopilotProviderType.Perplexity), + config: PerplexityConfigShape, + }), + CopilotProviderProfileBaseShape.extend({ + type: z.literal(CopilotProviderType.Anthropic), + config: AnthropicOfficialConfigShape, + }), + CopilotProviderProfileBaseShape.extend({ + type: z.literal(CopilotProviderType.AnthropicVertex), + config: VertexProviderConfigShape, + }), + CopilotProviderProfileBaseShape.extend({ + type: z.literal(CopilotProviderType.Morph), + config: MorphConfigShape, + }), +]); + +const CopilotProviderDefaultsShape = z.object({ + [ModelOutputType.Text]: z.string().optional(), + [ModelOutputType.Object]: z.string().optional(), + [ModelOutputType.Embedding]: z.string().optional(), + [ModelOutputType.Image]: z.string().optional(), + [ModelOutputType.Structured]: z.string().optional(), + fallback: z.string().optional(), +}); + declare global { interface AppConfigSchema { copilot: { @@ -27,6 +201,8 @@ declare global { storage: ConfigItem; scenarios: ConfigItem; providers: { + profiles: ConfigItem; + defaults: ConfigItem; openai: ConfigItem; fal: ConfigItem; gemini: ConfigItem; @@ -63,6 +239,16 @@ defineModuleConfig('copilot', { }, }, }, + 'providers.profiles': { + desc: 'The profile list for copilot providers.', + default: [], + shape: z.array(CopilotProviderProfileShape), + }, + 'providers.defaults': { + desc: 'The default provider ids for model output types and global fallback.', + default: {}, + shape: CopilotProviderDefaultsShape, + }, 'providers.openai': { desc: 'The config for the openai provider.', default: { diff --git a/packages/backend/server/src/plugins/copilot/controller.ts b/packages/backend/server/src/plugins/copilot/controller.ts index 921e50a088..d76ea50591 100644 --- a/packages/backend/server/src/plugins/copilot/controller.ts +++ b/packages/backend/server/src/plugins/copilot/controller.ts @@ -36,10 +36,7 @@ import { BlobNotFound, CallMetric, Config, - CopilotFailedToGenerateText, CopilotSessionNotFound, - InternalServerError, - mapAnyError, mapSseError, metrics, NoCopilotProviderAvailable, @@ -242,61 +239,6 @@ export class CopilotController implements BeforeApplicationShutdown { }; } - @Get('/chat/:sessionId') - @CallMetric('ai', 'chat', { timer: true }) - async chat( - @CurrentUser() user: CurrentUser, - @Req() req: Request, - @Param('sessionId') sessionId: string, - @Query() query: Record - ): Promise { - const info: any = { sessionId, params: query }; - - try { - const { provider, model, session, finalMessage } = - await this.prepareChatSession( - user, - sessionId, - query, - ModelOutputType.Text - ); - - info.model = model; - info.finalMessage = finalMessage.filter(m => m.role !== 'system'); - metrics.ai.counter('chat_calls').add(1, { model }); - - const { reasoning, webSearch, toolsConfig } = - ChatQuerySchema.parse(query); - const content = await provider.text({ modelId: model }, finalMessage, { - ...session.config.promptConfig, - signal: getSignal(req).signal, - user: user.id, - session: session.config.sessionId, - workspace: session.config.workspaceId, - reasoning, - webSearch, - tools: getTools(session.config.promptConfig?.tools, toolsConfig), - }); - - session.push({ - role: 'assistant', - content, - createdAt: new Date(), - }); - await session.save(); - - return content; - } catch (e: any) { - metrics.ai.counter('chat_errors').add(1); - let error = mapAnyError(e); - if (error instanceof InternalServerError) { - error = new CopilotFailedToGenerateText(e.message); - } - error.log('CopilotChat', info); - throw error; - } - } - @Sse('/chat/:sessionId/stream') @CallMetric('ai', 'chat_stream', { timer: true }) async chatStream( diff --git a/packages/backend/server/src/plugins/copilot/prompt/prompts.ts b/packages/backend/server/src/plugins/copilot/prompt/prompts.ts index 74d4acb911..cedbfe9368 100644 --- a/packages/backend/server/src/plugins/copilot/prompt/prompts.ts +++ b/packages/backend/server/src/plugins/copilot/prompt/prompts.ts @@ -3,7 +3,7 @@ import { AiPrompt, PrismaClient } from '@prisma/client'; import type { PromptConfig, PromptMessage } from '../providers/types'; -type Prompt = Omit< +export type Prompt = Omit< AiPrompt, | 'id' | 'createdAt' @@ -2095,17 +2095,14 @@ export const prompts: Prompt[] = [ export async function refreshPrompts(db: PrismaClient) { const needToSkip = await db.aiPrompt - .findMany({ - where: { modified: true }, - select: { name: true }, - }) + .findMany({ where: { modified: true }, select: { name: true } }) .then(p => p.map(p => p.name)); for (const prompt of prompts) { // skip prompt update if already modified by admin panel if (needToSkip.includes(prompt.name)) { new Logger('CopilotPrompt').warn(`Skip modified prompt: ${prompt.name}`); - return; + continue; } await db.aiPrompt.upsert({ diff --git a/packages/backend/server/src/plugins/copilot/prompt/service.ts b/packages/backend/server/src/plugins/copilot/prompt/service.ts index 789c1722a8..c89ba31be7 100644 --- a/packages/backend/server/src/plugins/copilot/prompt/service.ts +++ b/packages/backend/server/src/plugins/copilot/prompt/service.ts @@ -12,6 +12,7 @@ import { import { ChatPrompt } from './chat-prompt'; import { CopilotPromptScenario, + type Prompt, prompts, refreshPrompts, Scenario, @@ -21,6 +22,7 @@ import { export class PromptService implements OnApplicationBootstrap { private readonly logger = new Logger(PromptService.name); private readonly cache = new Map(); + private readonly inMemoryPrompts = new Map(); constructor( private readonly config: Config, @@ -28,7 +30,7 @@ export class PromptService implements OnApplicationBootstrap { ) {} async onApplicationBootstrap() { - this.cache.clear(); + this.resetInMemoryPrompts(); await refreshPrompts(this.db); } @@ -45,6 +47,7 @@ export class PromptService implements OnApplicationBootstrap { } protected async setup(scenarios?: CopilotPromptScenario) { + this.ensureInMemoryPrompts(); if (!!scenarios && scenarios.override_enabled && scenarios.scenarios) { this.logger.log('Updating prompts based on scenarios...'); for (const [scenario, model] of Object.entries(scenarios.scenarios)) { @@ -75,25 +78,29 @@ export class PromptService implements OnApplicationBootstrap { * @returns prompt names */ async listNames() { - return this.db.aiPrompt - .findMany({ select: { name: true } }) - .then(prompts => Array.from(new Set(prompts.map(p => p.name)))); + this.ensureInMemoryPrompts(); + return Array.from(this.inMemoryPrompts.keys()); } async list() { - return this.db.aiPrompt.findMany({ - select: { - name: true, - action: true, - model: true, - config: true, - messages: { - select: { role: true, content: true, params: true }, - orderBy: { idx: 'asc' }, - }, - }, - orderBy: { action: { sort: 'asc', nulls: 'first' } }, - }); + this.ensureInMemoryPrompts(); + return Array.from(this.inMemoryPrompts.values()) + .map(prompt => ({ + name: prompt.name, + action: prompt.action ?? null, + model: prompt.model, + config: prompt.config ? structuredClone(prompt.config) : null, + messages: prompt.messages.map(message => ({ + role: message.role, + content: message.content, + params: message.params ?? null, + })), + })) + .sort((a, b) => { + if (a.action === null && b.action !== null) return -1; + if (a.action !== null && b.action === null) return 1; + return (a.action ?? '').localeCompare(b.action ?? ''); + }); } /** @@ -102,40 +109,24 @@ export class PromptService implements OnApplicationBootstrap { * @returns prompt messages */ async get(name: string): Promise { + this.ensureInMemoryPrompts(); + // skip cache in dev mode to ensure the latest prompt is always fetched if (!env.dev) { const cached = this.cache.get(name); if (cached) return cached; } - const prompt = await this.db.aiPrompt.findUnique({ - where: { - name, - }, - select: { - name: true, - action: true, - model: true, - optionalModels: true, - config: true, - messages: { - select: { - role: true, - content: true, - params: true, - }, - orderBy: { - idx: 'asc', - }, - }, - }, - }); + const prompt = this.inMemoryPrompts.get(name); + if (!prompt) return null; - const messages = PromptMessageSchema.array().safeParse(prompt?.messages); - const config = PromptConfigSchema.safeParse(prompt?.config); - if (prompt && messages.success && config.success) { + const messages = PromptMessageSchema.array().safeParse(prompt.messages); + const config = PromptConfigSchema.safeParse(prompt.config); + if (messages.success && config.success) { const chatPrompt = ChatPrompt.createFromPrompt({ - ...prompt, + ...this.clonePrompt(prompt), + action: prompt.action ?? null, + optionalModels: prompt.optionalModels ?? [], config: config.data, messages: messages.data, }); @@ -149,25 +140,69 @@ export class PromptService implements OnApplicationBootstrap { name: string, model: string, messages: PromptMessage[], - config?: PromptConfig | null + config?: PromptConfig | null, + extraConfig?: { optionalModels: string[] } ) { - return await this.db.aiPrompt - .create({ - data: { - name, - model, - config: config || undefined, - messages: { - create: messages.map((m, idx) => ({ - idx, - ...m, - attachments: m.attachments || undefined, - params: m.params || undefined, - })), + this.ensureInMemoryPrompts(); + + const existing = this.inMemoryPrompts.get(name); + const mergedOptionalModels = existing?.optionalModels + ? [...existing.optionalModels, ...(extraConfig?.optionalModels ?? [])] + : extraConfig?.optionalModels; + const inMemoryConfig = (!!config && structuredClone(config)) || undefined; + const dbConfig = this.toDbConfig(config); + this.inMemoryPrompts.set(name, { + name, + model, + action: existing?.action, + optionalModels: mergedOptionalModels, + config: inMemoryConfig, + messages: this.cloneMessages(messages), + }); + this.cache.delete(name); + + try { + return await this.db.aiPrompt + .upsert({ + where: { name }, + create: { + name, + action: existing?.action, + model, + optionalModels: mergedOptionalModels, + config: dbConfig, + messages: { + create: messages.map((m, idx) => ({ + idx, + ...m, + attachments: m.attachments || undefined, + params: m.params || undefined, + })), + }, }, - }, - }) - .then(ret => ret.id); + update: { + model, + optionalModels: mergedOptionalModels, + config: dbConfig, + updatedAt: new Date(), + messages: { + deleteMany: {}, + create: messages.map((m, idx) => ({ + idx, + ...m, + attachments: m.attachments || undefined, + params: m.params || undefined, + })), + }, + }, + }) + .then(ret => ret.id); + } catch (error) { + this.logger.warn( + `Compat prompt upsert failed for "${name}": ${this.stringifyError(error)}` + ); + return -1; + } } @Transactional() @@ -177,44 +212,123 @@ export class PromptService implements OnApplicationBootstrap { messages?: PromptMessage[]; model?: string; modified?: boolean; - config?: PromptConfig; + config?: PromptConfig | null; }, where?: Prisma.AiPromptWhereInput ) { + this.ensureInMemoryPrompts(); const { config, messages, model, modified } = data; - const existing = await this.db.aiPrompt - .count({ where: { ...where, name } }) - .then(count => count > 0); - if (existing) { - await this.db.aiPrompt.update({ - where: { name }, - data: { - config: config || undefined, - updatedAt: new Date(), - modified, - model, - messages: messages - ? { - // cleanup old messages - deleteMany: {}, - create: messages.map((m, idx) => ({ - idx, - ...m, - attachments: m.attachments || undefined, - params: m.params || undefined, - })), - } - : undefined, - }, - }); + const current = this.inMemoryPrompts.get(name); + if (current) { + const next = this.clonePrompt(current); + if (model !== undefined) { + next.model = model; + } + if (config === null) { + next.config = undefined; + } else if (config !== undefined) { + next.config = structuredClone(config); + } + if (messages) { + next.messages = this.cloneMessages(messages); + } + + this.inMemoryPrompts.set(name, next); this.cache.delete(name); } + + try { + const existing = await this.db.aiPrompt + .count({ where: { ...where, name } }) + .then(count => count > 0); + if (existing) { + await this.db.aiPrompt.update({ + where: { name }, + data: { + config: this.toDbConfig(config), + updatedAt: new Date(), + modified, + model, + messages: messages + ? { + // cleanup old messages + deleteMany: {}, + create: messages.map((m, idx) => ({ + idx, + ...m, + attachments: m.attachments || undefined, + params: m.params || undefined, + })), + } + : undefined, + }, + }); + } + } catch (error) { + this.logger.warn( + `Compat prompt update failed for "${name}": ${this.stringifyError(error)}` + ); + } } async delete(name: string) { - const { id } = await this.db.aiPrompt.delete({ where: { name } }); + this.inMemoryPrompts.delete(name); this.cache.delete(name); - return id; + + try { + const { id } = await this.db.aiPrompt.delete({ where: { name } }); + return id; + } catch (error) { + this.logger.warn( + `Compat prompt delete failed for "${name}": ${this.stringifyError(error)}` + ); + return -1; + } + } + + private resetInMemoryPrompts() { + this.cache.clear(); + this.inMemoryPrompts.clear(); + for (const prompt of prompts) { + this.inMemoryPrompts.set(prompt.name, this.clonePrompt(prompt)); + } + } + + private ensureInMemoryPrompts() { + if (!this.inMemoryPrompts.size) { + this.resetInMemoryPrompts(); + } + } + + private toDbConfig( + config: PromptConfig | null | undefined + ): Prisma.InputJsonValue | Prisma.NullableJsonNullValueInput | undefined { + if (config === null) return Prisma.DbNull; + if (config === undefined) return undefined; + return config as Prisma.InputJsonValue; + } + + private cloneMessages(messages: PromptMessage[]) { + return messages.map(message => ({ + ...message, + attachments: message.attachments ? [...message.attachments] : undefined, + params: message.params ? structuredClone(message.params) : undefined, + })); + } + + private clonePrompt(prompt: Prompt): Prompt { + return { + ...prompt, + optionalModels: prompt.optionalModels + ? [...prompt.optionalModels] + : undefined, + config: prompt.config ? structuredClone(prompt.config) : undefined, + messages: this.cloneMessages(prompt.messages), + }; + } + + private stringifyError(error: unknown) { + return error instanceof Error ? error.message : String(error); } } diff --git a/packages/backend/server/src/plugins/copilot/providers/anthropic/anthropic.ts b/packages/backend/server/src/plugins/copilot/providers/anthropic/anthropic.ts index 483188cf69..26f2052fa7 100644 --- a/packages/backend/server/src/plugins/copilot/providers/anthropic/anthropic.ts +++ b/packages/backend/server/src/plugins/copilot/providers/anthropic/anthropic.ts @@ -1,52 +1,90 @@ -import { - type AnthropicProvider as AnthropicSDKProvider, - type AnthropicProviderOptions, -} from '@ai-sdk/anthropic'; -import { type GoogleVertexAnthropicProvider } from '@ai-sdk/google-vertex/anthropic'; -import { AISDKError, generateText, stepCountIs, streamText } from 'ai'; +import type { ToolSet } from 'ai'; import { CopilotProviderSideError, metrics, UserFriendlyError, } from '../../../../base'; +import { + llmDispatchStream, + type NativeLlmBackendConfig, + type NativeLlmRequest, +} from '../../../../native'; +import type { NodeTextMiddleware } from '../../config'; +import { buildNativeRequest, NativeProviderAdapter } from '../native'; import { CopilotProvider } from '../provider'; import type { CopilotChatOptions, - CopilotProviderModel, ModelConditions, PromptMessage, StreamObject, } from '../types'; -import { ModelOutputType } from '../types'; -import { - chatToGPTMessage, - StreamObjectParser, - TextStreamParser, -} from '../utils'; +import { CopilotProviderType, ModelOutputType } from '../types'; +import { getGoogleAuth, getVertexAnthropicBaseUrl } from '../utils'; export abstract class AnthropicProvider extends CopilotProvider { - protected abstract instance: - | AnthropicSDKProvider - | GoogleVertexAnthropicProvider; - private handleError(e: any) { if (e instanceof UserFriendlyError) { return e; - } else if (e instanceof AISDKError) { - this.logger.error('Throw error from ai sdk:', e); - return new CopilotProviderSideError({ - provider: this.type, - kind: e.name || 'unknown', - message: e.message, - }); - } else { - return new CopilotProviderSideError({ - provider: this.type, - kind: 'unexpected_response', - message: e?.message || 'Unexpected anthropic response', - }); } + return new CopilotProviderSideError({ + provider: this.type, + kind: 'unexpected_response', + message: e?.message || 'Unexpected anthropic response', + }); + } + + private async createNativeConfig(): Promise { + if (this.type === CopilotProviderType.AnthropicVertex) { + const auth = await getGoogleAuth(this.config as any, 'anthropic'); + const headers = auth.headers(); + const authorization = + headers.Authorization || + (headers as Record).authorization; + const token = + typeof authorization === 'string' + ? authorization.replace(/^Bearer\s+/i, '') + : ''; + const baseUrl = + getVertexAnthropicBaseUrl(this.config as any) || auth.baseUrl; + return { + base_url: baseUrl || '', + auth_token: token, + request_layer: 'vertex', + headers, + }; + } + + const config = this.config as { apiKey: string; baseURL?: string }; + const baseUrl = config.baseURL || 'https://api.anthropic.com/v1'; + return { + base_url: baseUrl.replace(/\/v1\/?$/, ''), + auth_token: config.apiKey, + }; + } + + private createAdapter( + backendConfig: NativeLlmBackendConfig, + tools: ToolSet, + nodeTextMiddleware?: NodeTextMiddleware[] + ) { + return new NativeProviderAdapter( + (request: NativeLlmRequest, signal?: AbortSignal) => + llmDispatchStream('anthropic', backendConfig, request, signal), + tools, + this.MAX_STEPS, + { nodeTextMiddleware } + ); + } + + private getReasoning( + options: NonNullable, + model: string + ): Record | undefined { + if (options.reasoning && this.isReasoningModel(model)) { + return { budget_tokens: 12000, include_thought: true }; + } + return undefined; } async text( @@ -59,28 +97,29 @@ export abstract class AnthropicProvider extends CopilotProvider { const model = this.selectModel(fullCond); try { - metrics.ai.counter('chat_text_calls').add(1, { model: model.id }); - - const [system, msgs] = await chatToGPTMessage(messages, true, true); - - const modelInstance = this.instance(model.id); - const { text, reasoning } = await generateText({ - model: modelInstance, - system, - messages: msgs, - abortSignal: options.signal, - providerOptions: { - anthropic: this.getAnthropicOptions(options, model.id), - }, - tools: await this.getTools(options, model.id), - stopWhen: stepCountIs(this.MAX_STEPS), + metrics.ai.counter('chat_text_calls').add(1, this.metricLabels(model.id)); + const backendConfig = await this.createNativeConfig(); + const tools = await this.getTools(options, model.id); + const middleware = this.getActiveProviderMiddleware(); + const reasoning = this.getReasoning(options, model.id); + const { request } = await buildNativeRequest({ + model: model.id, + messages, + options, + tools, + reasoning, + middleware, }); - - if (!text) throw new Error('Failed to generate text'); - - return reasoning ? `${reasoning}\n${text}` : text; + const adapter = this.createAdapter( + backendConfig, + tools, + middleware.node?.text + ); + return await adapter.text(request, options.signal); } catch (e: any) { - metrics.ai.counter('chat_text_errors').add(1, { model: model.id }); + metrics.ai + .counter('chat_text_errors') + .add(1, this.metricLabels(model.id)); throw this.handleError(e); } } @@ -95,25 +134,32 @@ export abstract class AnthropicProvider extends CopilotProvider { const model = this.selectModel(fullCond); try { - metrics.ai.counter('chat_text_stream_calls').add(1, { model: model.id }); - const fullStream = await this.getFullStream(model, messages, options); - const parser = new TextStreamParser(); - for await (const chunk of fullStream) { - const result = parser.parse(chunk); - yield result; - if (options.signal?.aborted) { - await fullStream.cancel(); - break; - } - } - if (!options.signal?.aborted) { - const footnotes = parser.end(); - if (footnotes.length) { - yield `\n\n${footnotes}`; - } + metrics.ai + .counter('chat_text_stream_calls') + .add(1, this.metricLabels(model.id)); + const backendConfig = await this.createNativeConfig(); + const tools = await this.getTools(options, model.id); + const middleware = this.getActiveProviderMiddleware(); + const { request } = await buildNativeRequest({ + model: model.id, + messages, + options, + tools, + reasoning: this.getReasoning(options, model.id), + middleware, + }); + const adapter = this.createAdapter( + backendConfig, + tools, + middleware.node?.text + ); + for await (const chunk of adapter.streamText(request, options.signal)) { + yield chunk; } } catch (e: any) { - metrics.ai.counter('chat_text_stream_errors').add(1, { model: model.id }); + metrics.ai + .counter('chat_text_stream_errors') + .add(1, this.metricLabels(model.id)); throw this.handleError(e); } } @@ -130,58 +176,34 @@ export abstract class AnthropicProvider extends CopilotProvider { try { metrics.ai .counter('chat_object_stream_calls') - .add(1, { model: model.id }); - const fullStream = await this.getFullStream(model, messages, options); - const parser = new StreamObjectParser(); - for await (const chunk of fullStream) { - const result = parser.parse(chunk); - if (result) { - yield result; - } - if (options.signal?.aborted) { - await fullStream.cancel(); - break; - } + .add(1, this.metricLabels(model.id)); + const backendConfig = await this.createNativeConfig(); + const tools = await this.getTools(options, model.id); + const middleware = this.getActiveProviderMiddleware(); + const { request } = await buildNativeRequest({ + model: model.id, + messages, + options, + tools, + reasoning: this.getReasoning(options, model.id), + middleware, + }); + const adapter = this.createAdapter( + backendConfig, + tools, + middleware.node?.text + ); + for await (const chunk of adapter.streamObject(request, options.signal)) { + yield chunk; } } catch (e: any) { metrics.ai .counter('chat_object_stream_errors') - .add(1, { model: model.id }); + .add(1, this.metricLabels(model.id)); throw this.handleError(e); } } - private async getFullStream( - model: CopilotProviderModel, - messages: PromptMessage[], - options: CopilotChatOptions = {} - ) { - const [system, msgs] = await chatToGPTMessage(messages, true, true); - const { fullStream } = streamText({ - model: this.instance(model.id), - system, - messages: msgs, - abortSignal: options.signal, - providerOptions: { - anthropic: this.getAnthropicOptions(options, model.id), - }, - tools: await this.getTools(options, model.id), - stopWhen: stepCountIs(this.MAX_STEPS), - }); - return fullStream; - } - - private getAnthropicOptions(options: CopilotChatOptions, model: string) { - const result: AnthropicProviderOptions = {}; - if (options?.reasoning && this.isReasoningModel(model)) { - result.thinking = { - type: 'enabled', - budgetTokens: 12000, - }; - } - return result; - } - private isReasoningModel(model: string) { // claude 3.5 sonnet doesn't support reasoning config return model.includes('sonnet') && !model.startsWith('claude-3-5-sonnet'); diff --git a/packages/backend/server/src/plugins/copilot/providers/anthropic/official.ts b/packages/backend/server/src/plugins/copilot/providers/anthropic/official.ts index 5d69aa8771..7f4b476481 100644 --- a/packages/backend/server/src/plugins/copilot/providers/anthropic/official.ts +++ b/packages/backend/server/src/plugins/copilot/providers/anthropic/official.ts @@ -1,7 +1,3 @@ -import { - type AnthropicProvider as AnthropicSDKProvider, - createAnthropic, -} from '@ai-sdk/anthropic'; import z from 'zod'; import { CopilotProviderType, ModelInputType, ModelOutputType } from '../types'; @@ -52,18 +48,12 @@ export class AnthropicOfficialProvider extends AnthropicProvider { + return ( + value !== null && + value !== undefined && + typeof (value as AsyncIterable)[Symbol.asyncIterator] === + 'function' + ); +} + @Injectable() export class CopilotProviderFactory { - constructor(private readonly server: ServerService) {} + constructor( + private readonly server: ServerService, + private readonly config: Config + ) {} private readonly logger = new Logger(CopilotProviderFactory.name); - readonly #providers = new Map(); + readonly #providers = new Map(); + readonly #boundProviders = new Map(); + readonly #providerIdsByType = new Map>(); + + private getRegistry() { + return buildProviderRegistry(this.config.copilot.providers); + } + + private getPreferredProviderIds(type?: CopilotProviderType) { + if (!type) return undefined; + return this.#providerIdsByType.get(type); + } + + private normalizeCond( + providerId: string, + cond: ModelFullConditions + ): ModelFullConditions { + const registry = this.getRegistry(); + const modelId = stripProviderPrefix(registry, providerId, cond.modelId); + return { ...cond, modelId }; + } + + private normalizeMethodArgs(providerId: string, args: unknown[]) { + const [first, ...rest] = args; + if ( + !first || + typeof first !== 'object' || + Array.isArray(first) || + !('modelId' in first) + ) { + return args; + } + + const cond = first as Record; + if (typeof cond.modelId !== 'string') return args; + + const registry = this.getRegistry(); + const modelId = stripProviderPrefix(registry, providerId, cond.modelId); + return [{ ...cond, modelId }, ...rest]; + } + + private wrapAsyncIterable( + provider: CopilotProvider, + providerId: string, + iterable: AsyncIterable + ): AsyncIterableIterator { + const iterator = iterable[Symbol.asyncIterator](); + + return { + next: value => + provider.runWithProfile(providerId, () => iterator.next(value)), + return: value => + provider.runWithProfile(providerId, async () => { + if (typeof iterator.return === 'function') { + return iterator.return(value as never); + } + return { done: true, value: value as T }; + }), + throw: error => + provider.runWithProfile(providerId, async () => { + if (typeof iterator.throw === 'function') { + return iterator.throw(error); + } + throw error; + }), + [Symbol.asyncIterator]() { + return this; + }, + }; + } + + private getBoundProvider(providerId: string, provider: CopilotProvider) { + const cached = this.#boundProviders.get(providerId); + if (cached) { + return cached; + } + + const wrapped = new Proxy(provider, { + get: (target, prop, receiver) => { + if (prop === 'providerId') { + return providerId; + } + + const value = Reflect.get(target, prop, receiver); + if (typeof value !== 'function') { + return value; + } + + return (...args: unknown[]) => { + const normalizedArgs = this.normalizeMethodArgs(providerId, args); + const result = provider.runWithProfile(providerId, () => + Reflect.apply(value, provider, normalizedArgs) + ); + if (isAsyncIterable(result)) { + return this.wrapAsyncIterable( + provider, + providerId, + result as AsyncIterable + ); + } + return result; + }; + }, + }) as CopilotProvider; + + this.#boundProviders.set(providerId, wrapped); + return wrapped; + } async getProvider( cond: ModelFullConditions, @@ -21,22 +146,41 @@ export class CopilotProviderFactory { this.logger.debug( `Resolving copilot provider for output type: ${cond.outputType}` ); - let candidate: CopilotProvider | null = null; - for (const [type, provider] of this.#providers.entries()) { - if (filter.prefer && filter.prefer !== type) { + const route = resolveModel({ + registry: this.getRegistry(), + modelId: cond.modelId, + outputType: cond.outputType, + availableProviderIds: this.#providers.keys(), + preferredProviderIds: this.getPreferredProviderIds(filter.prefer), + }); + + const registry = this.getRegistry(); + for (const providerId of route.candidateProviderIds) { + const provider = this.#providers.get(providerId); + if (!provider) continue; + + const profile = registry.profiles.get(providerId); + const normalizedCond = this.normalizeCond(providerId, cond); + if ( + normalizedCond.modelId && + profile?.models?.length && + !profile.models.includes(normalizedCond.modelId) + ) { continue; } - const isMatched = await provider.match(cond); + const matched = await provider.runWithProfile(providerId, () => + provider.match(normalizedCond) + ); + if (!matched) continue; - if (isMatched) { - candidate = provider; - this.logger.debug(`Copilot provider candidate found: ${type}`); - break; - } + this.logger.debug( + `Copilot provider candidate found: ${provider.type} (${providerId})` + ); + return this.getBoundProvider(providerId, provider); } - return candidate; + return null; } async getProviderByModel( @@ -46,31 +190,50 @@ export class CopilotProviderFactory { } = {} ): Promise { this.logger.debug(`Resolving copilot provider for model: ${modelId}`); + return this.getProvider({ modelId }, filter); + } - let candidate: CopilotProvider | null = null; - for (const [type, provider] of this.#providers.entries()) { - if (filter.prefer && filter.prefer !== type) { - continue; - } - - if (await provider.match({ modelId })) { - candidate = provider; - this.logger.debug(`Copilot provider candidate found: ${type}`); + register(providerId: string, provider: CopilotProvider) { + const existed = this.#providers.get(providerId); + if (existed?.type && existed.type !== provider.type) { + const ids = this.#providerIdsByType.get(existed.type); + ids?.delete(providerId); + if (!ids?.size) { + this.#providerIdsByType.delete(existed.type); } } - return candidate; - } + this.#providers.set(providerId, provider); + this.#boundProviders.delete(providerId); - register(provider: CopilotProvider) { - this.#providers.set(provider.type, provider); - this.logger.log(`Copilot provider [${provider.type}] registered.`); + const ids = this.#providerIdsByType.get(provider.type) ?? new Set(); + ids.add(providerId); + this.#providerIdsByType.set(provider.type, ids); + + this.logger.log( + `Copilot provider [${provider.type}] registered as [${providerId}].` + ); this.server.enableFeature(ServerFeature.Copilot); } - unregister(provider: CopilotProvider) { - this.#providers.delete(provider.type); - this.logger.log(`Copilot provider [${provider.type}] unregistered.`); + unregister(providerId: string, provider: CopilotProvider) { + const existed = this.#providers.get(providerId); + if (!existed || existed !== provider) { + return; + } + + this.#providers.delete(providerId); + this.#boundProviders.delete(providerId); + + const ids = this.#providerIdsByType.get(provider.type); + ids?.delete(providerId); + if (!ids?.size) { + this.#providerIdsByType.delete(provider.type); + } + + this.logger.log( + `Copilot provider [${provider.type}] unregistered from [${providerId}].` + ); if (this.#providers.size === 0) { this.server.disableFeature(ServerFeature.Copilot); } diff --git a/packages/backend/server/src/plugins/copilot/providers/loop.ts b/packages/backend/server/src/plugins/copilot/providers/loop.ts new file mode 100644 index 0000000000..1da0f35146 --- /dev/null +++ b/packages/backend/server/src/plugins/copilot/providers/loop.ts @@ -0,0 +1,381 @@ +import type { ToolSet } from 'ai'; +import { z } from 'zod'; + +import type { + NativeLlmRequest, + NativeLlmStreamEvent, + NativeLlmToolDefinition, +} from '../../../native'; + +export type NativeDispatchFn = ( + request: NativeLlmRequest, + signal?: AbortSignal +) => AsyncIterableIterator; + +export type NativeToolCall = { + id: string; + name: string; + args: Record; + thought?: string; +}; + +type ToolCallState = { + name?: string; + argumentsText: string; +}; + +type ToolExecutionResult = { + callId: string; + name: string; + args: Record; + output: unknown; + isError?: boolean; +}; + +export class ToolCallAccumulator { + readonly #states = new Map(); + + feedDelta(event: Extract) { + const state = this.#states.get(event.call_id) ?? { + argumentsText: '', + }; + if (event.name) { + state.name = event.name; + } + if (event.arguments_delta) { + state.argumentsText += event.arguments_delta; + } + this.#states.set(event.call_id, state); + } + + complete(event: Extract) { + const state = this.#states.get(event.call_id); + this.#states.delete(event.call_id); + return { + id: event.call_id, + name: event.name || state?.name || '', + args: this.parseArgs( + event.arguments ?? this.parseJson(state?.argumentsText ?? '{}') + ), + thought: event.thought, + } satisfies NativeToolCall; + } + + drainPending() { + const pending: NativeToolCall[] = []; + for (const [callId, state] of this.#states.entries()) { + if (!state.name) { + continue; + } + pending.push({ + id: callId, + name: state.name, + args: this.parseArgs(this.parseJson(state.argumentsText)), + }); + } + this.#states.clear(); + return pending; + } + + private parseJson(jsonText: string): unknown { + if (!jsonText.trim()) { + return {}; + } + try { + return JSON.parse(jsonText); + } catch { + return {}; + } + } + + private parseArgs(value: unknown): Record { + if (value && typeof value === 'object' && !Array.isArray(value)) { + return value as Record; + } + return {}; + } +} + +export class ToolSchemaExtractor { + static extract(toolSet: ToolSet): NativeLlmToolDefinition[] { + return Object.entries(toolSet).map(([name, tool]) => { + const unknownTool = tool as Record; + const inputSchema = + unknownTool.inputSchema ?? unknownTool.parameters ?? z.object({}); + + return { + name, + description: + typeof unknownTool.description === 'string' + ? unknownTool.description + : undefined, + parameters: this.toJsonSchema(inputSchema), + }; + }); + } + + private static toJsonSchema(schema: unknown): Record { + if (!(schema instanceof z.ZodType)) { + if (schema && typeof schema === 'object' && !Array.isArray(schema)) { + return schema as Record; + } + return { type: 'object', properties: {} }; + } + + if (schema instanceof z.ZodObject) { + const shape = schema.shape; + const properties: Record = {}; + const required: string[] = []; + + for (const [key, child] of Object.entries( + shape as Record + )) { + properties[key] = this.toJsonSchema(child); + if (!this.isOptional(child)) { + required.push(key); + } + } + + return { + type: 'object', + properties, + additionalProperties: false, + ...(required.length ? { required } : {}), + }; + } + + if (schema instanceof z.ZodString) { + return { type: 'string' }; + } + if (schema instanceof z.ZodNumber) { + return { type: 'number' }; + } + if (schema instanceof z.ZodBoolean) { + return { type: 'boolean' }; + } + if (schema instanceof z.ZodArray) { + return { type: 'array', items: this.toJsonSchema(schema.element) }; + } + if (schema instanceof z.ZodEnum) { + return { type: 'string', enum: schema.options }; + } + if (schema instanceof z.ZodLiteral) { + const literal = schema.value; + if (literal === null) { + return { const: null, type: 'null' }; + } + if (typeof literal === 'string') { + return { const: literal, type: 'string' }; + } + if (typeof literal === 'number') { + return { const: literal, type: 'number' }; + } + if (typeof literal === 'boolean') { + return { const: literal, type: 'boolean' }; + } + return { const: literal }; + } + if (schema instanceof z.ZodUnion) { + return { + anyOf: schema.options.map((option: z.ZodTypeAny) => + this.toJsonSchema(option) + ), + }; + } + if (schema instanceof z.ZodRecord) { + return { + type: 'object', + additionalProperties: this.toJsonSchema(schema.valueSchema), + }; + } + + if (schema instanceof z.ZodNullable) { + const inner = (schema._def as { innerType?: z.ZodTypeAny }).innerType; + return { anyOf: [this.toJsonSchema(inner), { type: 'null' }] }; + } + + if (schema instanceof z.ZodOptional || schema instanceof z.ZodDefault) { + return this.toJsonSchema( + (schema._def as { innerType?: z.ZodTypeAny }).innerType + ); + } + + if (schema instanceof z.ZodEffects) { + return this.toJsonSchema( + (schema._def as { schema?: z.ZodTypeAny }).schema + ); + } + + return { type: 'object', properties: {} }; + } + + private static isOptional(schema: z.ZodTypeAny): boolean { + if (schema instanceof z.ZodOptional || schema instanceof z.ZodDefault) { + return true; + } + if (schema instanceof z.ZodNullable) { + return this.isOptional( + (schema._def as { innerType: z.ZodTypeAny }).innerType + ); + } + if (schema instanceof z.ZodEffects) { + return this.isOptional((schema._def as { schema: z.ZodTypeAny }).schema); + } + return false; + } +} + +export class ToolCallLoop { + constructor( + private readonly dispatch: NativeDispatchFn, + private readonly tools: ToolSet, + private readonly maxSteps = 20 + ) {} + + async *run( + request: NativeLlmRequest, + signal?: AbortSignal + ): AsyncIterableIterator { + const messages = request.messages.map(message => ({ + ...message, + content: [...message.content], + })); + + for (let step = 0; step < this.maxSteps; step++) { + const toolCalls: NativeToolCall[] = []; + const accumulator = new ToolCallAccumulator(); + let finalDone: Extract | null = + null; + + for await (const event of this.dispatch( + { + ...request, + stream: true, + messages, + }, + signal + )) { + switch (event.type) { + case 'tool_call_delta': { + accumulator.feedDelta(event); + break; + } + case 'tool_call': { + toolCalls.push(accumulator.complete(event)); + yield event; + break; + } + case 'done': { + finalDone = event; + break; + } + case 'error': { + throw new Error(event.message); + } + default: { + yield event; + break; + } + } + } + + toolCalls.push(...accumulator.drainPending()); + if (toolCalls.length === 0) { + if (finalDone) { + yield finalDone; + } + break; + } + + if (step === this.maxSteps - 1) { + throw new Error('ToolCallLoop max steps reached'); + } + + const toolResults = await this.executeTools(toolCalls); + + messages.push({ + role: 'assistant', + content: toolCalls.map(call => ({ + type: 'tool_call', + call_id: call.id, + name: call.name, + arguments: call.args, + thought: call.thought, + })), + }); + + for (const result of toolResults) { + messages.push({ + role: 'tool', + content: [ + { + type: 'tool_result', + call_id: result.callId, + output: result.output, + is_error: result.isError, + }, + ], + }); + yield { + type: 'tool_result', + call_id: result.callId, + name: result.name, + arguments: result.args, + output: result.output, + is_error: result.isError, + }; + } + } + } + + private async executeTools(calls: NativeToolCall[]) { + return await Promise.all(calls.map(call => this.executeTool(call))); + } + + private async executeTool( + call: NativeToolCall + ): Promise { + const tool = this.tools[call.name] as + | { + execute?: (args: Record) => Promise; + } + | undefined; + + if (!tool?.execute) { + return { + callId: call.id, + name: call.name, + args: call.args, + isError: true, + output: { + message: `Tool not found: ${call.name}`, + }, + }; + } + + try { + const output = await tool.execute(call.args); + return { + callId: call.id, + name: call.name, + args: call.args, + output: output ?? null, + }; + } catch (error) { + console.error('Tool execution failed', { + callId: call.id, + toolName: call.name, + error, + }); + return { + callId: call.id, + name: call.name, + args: call.args, + isError: true, + output: { + message: 'Tool execution failed', + }, + }; + } + } +} diff --git a/packages/backend/server/src/plugins/copilot/providers/morph.ts b/packages/backend/server/src/plugins/copilot/providers/morph.ts index 36f96c9f26..3d5d2aa961 100644 --- a/packages/backend/server/src/plugins/copilot/providers/morph.ts +++ b/packages/backend/server/src/plugins/copilot/providers/morph.ts @@ -1,14 +1,17 @@ -import { - createOpenAICompatible, - OpenAICompatibleProvider as VercelOpenAICompatibleProvider, -} from '@ai-sdk/openai-compatible'; -import { AISDKError, generateText, streamText } from 'ai'; +import type { ToolSet } from 'ai'; import { CopilotProviderSideError, metrics, UserFriendlyError, } from '../../../base'; +import { + llmDispatchStream, + type NativeLlmBackendConfig, + type NativeLlmRequest, +} from '../../../native'; +import type { NodeTextMiddleware } from '../config'; +import { buildNativeRequest, NativeProviderAdapter } from './native'; import { CopilotProvider } from './provider'; import type { CopilotChatOptions, @@ -16,7 +19,6 @@ import type { PromptMessage, } from './types'; import { CopilotProviderType, ModelInputType, ModelOutputType } from './types'; -import { chatToGPTMessage, TextStreamParser } from './utils'; export const DEFAULT_DIMENSIONS = 256; @@ -57,37 +59,48 @@ export class MorphProvider extends CopilotProvider { }, ]; - #instance!: VercelOpenAICompatibleProvider; - override configured(): boolean { return !!this.config.apiKey; } protected override setup() { super.setup(); - this.#instance = createOpenAICompatible({ - name: this.type, - apiKey: this.config.apiKey, - baseURL: 'https://api.morphllm.com/v1', - }); } private handleError(e: any) { if (e instanceof UserFriendlyError) { return e; - } else if (e instanceof AISDKError) { - return new CopilotProviderSideError({ - provider: this.type, - kind: e.name || 'unknown', - message: e.message, - }); - } else { - return new CopilotProviderSideError({ - provider: this.type, - kind: 'unexpected_response', - message: e?.message || 'Unexpected morph response', - }); } + return new CopilotProviderSideError({ + provider: this.type, + kind: 'unexpected_response', + message: e?.message || 'Unexpected morph response', + }); + } + + private createNativeConfig(): NativeLlmBackendConfig { + return { + base_url: 'https://api.morphllm.com', + auth_token: this.config.apiKey ?? '', + }; + } + + private createNativeAdapter( + tools: ToolSet, + nodeTextMiddleware?: NodeTextMiddleware[] + ) { + return new NativeProviderAdapter( + (request: NativeLlmRequest, signal?: AbortSignal) => + llmDispatchStream( + 'openai_chat', + this.createNativeConfig(), + request, + signal + ), + tools, + this.MAX_STEPS, + { nodeTextMiddleware } + ); } async text( @@ -103,22 +116,22 @@ export class MorphProvider extends CopilotProvider { const model = this.selectModel(fullCond); try { - metrics.ai.counter('chat_text_calls').add(1, { model: model.id }); - - const [system, msgs] = await chatToGPTMessage(messages); - - const modelInstance = this.#instance(model.id); - - const { text } = await generateText({ - model: modelInstance, - system, - messages: msgs, - abortSignal: options.signal, + metrics.ai.counter('chat_text_calls').add(1, this.metricLabels(model.id)); + const tools = await this.getTools(options, model.id); + const middleware = this.getActiveProviderMiddleware(); + const { request } = await buildNativeRequest({ + model: model.id, + messages, + options, + tools, + middleware, }); - - return text.trim(); + const adapter = this.createNativeAdapter(tools, middleware.node?.text); + return await adapter.text(request, options.signal); } catch (e: any) { - metrics.ai.counter('chat_text_errors').add(1, { model: model.id }); + metrics.ai + .counter('chat_text_errors') + .add(1, this.metricLabels(model.id)); throw this.handleError(e); } } @@ -136,38 +149,26 @@ export class MorphProvider extends CopilotProvider { const model = this.selectModel(fullCond); try { - metrics.ai.counter('chat_text_stream_calls').add(1, { model: model.id }); - const [system, msgs] = await chatToGPTMessage(messages); - - const modelInstance = this.#instance(model.id); - - const { fullStream } = streamText({ - model: modelInstance, - system, - messages: msgs, - abortSignal: options.signal, + metrics.ai + .counter('chat_text_stream_calls') + .add(1, this.metricLabels(model.id)); + const tools = await this.getTools(options, model.id); + const middleware = this.getActiveProviderMiddleware(); + const { request } = await buildNativeRequest({ + model: model.id, + messages, + options, + tools, + middleware, }); - - const textParser = new TextStreamParser(); - for await (const chunk of fullStream) { - switch (chunk.type) { - case 'text-delta': { - let result = textParser.parse(chunk); - yield result; - break; - } - default: { - yield textParser.parse(chunk); - break; - } - } - if (options.signal?.aborted) { - await fullStream.cancel(); - break; - } + const adapter = this.createNativeAdapter(tools, middleware.node?.text); + for await (const chunk of adapter.streamText(request, options.signal)) { + yield chunk; } } catch (e: any) { - metrics.ai.counter('chat_text_stream_errors').add(1, { model: model.id }); + metrics.ai + .counter('chat_text_stream_errors') + .add(1, this.metricLabels(model.id)); throw this.handleError(e); } } diff --git a/packages/backend/server/src/plugins/copilot/providers/native.ts b/packages/backend/server/src/plugins/copilot/providers/native.ts new file mode 100644 index 0000000000..0d79a1a7c8 --- /dev/null +++ b/packages/backend/server/src/plugins/copilot/providers/native.ts @@ -0,0 +1,464 @@ +import type { ToolSet } from 'ai'; +import { ZodType } from 'zod'; + +import type { + NativeLlmCoreContent, + NativeLlmCoreMessage, + NativeLlmRequest, + NativeLlmStreamEvent, +} from '../../../native'; +import type { NodeTextMiddleware, ProviderMiddlewareConfig } from '../config'; +import { NativeDispatchFn, ToolCallLoop, ToolSchemaExtractor } from './loop'; +import type { CopilotChatOptions, PromptMessage, StreamObject } from './types'; +import { + CitationFootnoteFormatter, + inferMimeType, + TextStreamParser, +} from './utils'; + +const SIMPLE_IMAGE_URL_REGEX = /^(https?:\/\/|data:image\/)/; + +type BuildNativeRequestOptions = { + model: string; + messages: PromptMessage[]; + options?: CopilotChatOptions; + tools?: ToolSet; + withAttachment?: boolean; + include?: string[]; + reasoning?: Record; + middleware?: ProviderMiddlewareConfig; +}; + +type BuildNativeRequestResult = { + request: NativeLlmRequest; + schema?: ZodType; +}; + +type ToolCallMeta = { + name: string; + args: Record; +}; + +type NormalizedToolResultEvent = Extract< + NativeLlmStreamEvent, + { type: 'tool_result' } +> & { + name: string; + arguments: Record; +}; + +type AttachmentFootnote = { + blobId: string; + fileName: string; + fileType: string; +}; + +type NativeProviderAdapterOptions = { + nodeTextMiddleware?: NodeTextMiddleware[]; +}; + +function roleToCore(role: PromptMessage['role']) { + switch (role) { + case 'assistant': + return 'assistant'; + case 'system': + return 'system'; + default: + return 'user'; + } +} + +async function toCoreContents( + message: PromptMessage, + withAttachment: boolean +): Promise { + const contents: NativeLlmCoreContent[] = []; + + if (typeof message.content === 'string' && message.content.length) { + contents.push({ type: 'text', text: message.content }); + } + + if (!withAttachment || !Array.isArray(message.attachments)) return contents; + + for (const entry of message.attachments) { + let attachmentUrl: string; + let mediaType: string; + + if (typeof entry === 'string') { + attachmentUrl = entry; + mediaType = + typeof message.params?.mimetype === 'string' + ? message.params.mimetype + : await inferMimeType(entry); + } else { + attachmentUrl = entry.attachment; + mediaType = entry.mimeType; + } + + if (!SIMPLE_IMAGE_URL_REGEX.test(attachmentUrl)) continue; + if (!mediaType.startsWith('image/')) continue; + + contents.push({ type: 'image', source: { url: attachmentUrl } }); + } + + return contents; +} + +export async function buildNativeRequest({ + model, + messages, + options = {}, + tools = {}, + withAttachment = true, + include, + reasoning, + middleware, +}: BuildNativeRequestOptions): Promise { + const copiedMessages = messages.map(message => ({ + ...message, + attachments: message.attachments + ? [...message.attachments] + : message.attachments, + })); + + const systemMessage = + copiedMessages[0]?.role === 'system' ? copiedMessages.shift() : undefined; + const schema = + systemMessage?.params?.schema instanceof ZodType + ? systemMessage.params.schema + : undefined; + + const coreMessages: NativeLlmCoreMessage[] = []; + if (systemMessage?.content?.length) { + coreMessages.push({ + role: 'system', + content: [{ type: 'text', text: systemMessage.content }], + }); + } + + for (const message of copiedMessages) { + if (message.role === 'system') continue; + const content = await toCoreContents(message, withAttachment); + coreMessages.push({ role: roleToCore(message.role), content }); + } + + return { + request: { + model, + stream: true, + messages: coreMessages, + max_tokens: options.maxTokens ?? undefined, + temperature: options.temperature ?? undefined, + tools: ToolSchemaExtractor.extract(tools), + tool_choice: Object.keys(tools).length ? 'auto' : undefined, + include, + reasoning, + middleware: middleware?.rust + ? { request: middleware.rust.request, stream: middleware.rust.stream } + : undefined, + }, + schema, + }; +} + +function ensureToolResultMeta( + event: Extract, + toolCalls: Map +): NormalizedToolResultEvent | null { + const name = event.name ?? toolCalls.get(event.call_id)?.name; + const args = event.arguments ?? toolCalls.get(event.call_id)?.args; + + if (!name || !args) return null; + return { ...event, name, arguments: args }; +} + +function pickAttachmentFootnote(value: unknown): AttachmentFootnote | null { + if (!value || typeof value !== 'object') { + return null; + } + + const record = value as Record; + const blobId = + typeof record.blobId === 'string' + ? record.blobId + : typeof record.blob_id === 'string' + ? record.blob_id + : undefined; + const fileName = + typeof record.fileName === 'string' + ? record.fileName + : typeof record.name === 'string' + ? record.name + : undefined; + const fileType = + typeof record.fileType === 'string' + ? record.fileType + : typeof record.mimeType === 'string' + ? record.mimeType + : 'application/octet-stream'; + + if (!blobId || !fileName) { + return null; + } + + return { blobId, fileName, fileType }; +} + +function collectAttachmentFootnotes( + event: NormalizedToolResultEvent +): AttachmentFootnote[] { + if (event.name === 'blob_read') { + const item = pickAttachmentFootnote(event.output); + return item ? [item] : []; + } + + if (event.name === 'doc_semantic_search' && Array.isArray(event.output)) { + return event.output + .map(item => pickAttachmentFootnote(item)) + .filter((item): item is AttachmentFootnote => item !== null); + } + + return []; +} + +function formatAttachmentFootnotes(attachments: AttachmentFootnote[]) { + const references = attachments.map((_, index) => `[^${index + 1}]`).join(''); + const definitions = attachments + .map((attachment, index) => { + return `[^${index + 1}]: ${JSON.stringify({ + type: 'attachment', + blobId: attachment.blobId, + fileName: attachment.fileName, + fileType: attachment.fileType, + })}`; + }) + .join('\n'); + + return `\n\n${references}\n\n${definitions}`; +} + +export class NativeProviderAdapter { + readonly #loop: ToolCallLoop; + readonly #enableCallout: boolean; + readonly #enableCitationFootnote: boolean; + + constructor( + dispatch: NativeDispatchFn, + tools: ToolSet, + maxSteps = 20, + options: NativeProviderAdapterOptions = {} + ) { + this.#loop = new ToolCallLoop(dispatch, tools, maxSteps); + const enabledNodeTextMiddlewares = new Set( + options.nodeTextMiddleware ?? ['citation_footnote', 'callout'] + ); + this.#enableCallout = + enabledNodeTextMiddlewares.has('callout') || + enabledNodeTextMiddlewares.has('thinking_format'); + this.#enableCitationFootnote = + enabledNodeTextMiddlewares.has('citation_footnote'); + } + + async text(request: NativeLlmRequest, signal?: AbortSignal) { + let output = ''; + for await (const chunk of this.streamText(request, signal)) { + output += chunk; + } + return output.trim(); + } + + async *streamText( + request: NativeLlmRequest, + signal?: AbortSignal + ): AsyncIterableIterator { + const textParser = this.#enableCallout ? new TextStreamParser() : null; + const citationFormatter = this.#enableCitationFootnote + ? new CitationFootnoteFormatter() + : null; + const toolCalls = new Map(); + let streamPartId = 0; + + for await (const event of this.#loop.run(request, signal)) { + switch (event.type) { + case 'text_delta': { + if (textParser) { + yield textParser.parse({ + type: 'text-delta', + id: String(streamPartId++), + text: event.text, + }); + } else { + yield event.text; + } + break; + } + case 'reasoning_delta': { + if (textParser) { + yield textParser.parse({ + type: 'reasoning-delta', + id: String(streamPartId++), + text: event.text, + }); + } else { + yield event.text; + } + break; + } + case 'tool_call': { + const toolCall = { + name: event.name, + args: event.arguments, + }; + toolCalls.set(event.call_id, toolCall); + if (textParser) { + yield textParser.parse({ + type: 'tool-call', + toolCallId: event.call_id, + toolName: event.name as never, + input: event.arguments, + }); + } + break; + } + case 'tool_result': { + const normalized = ensureToolResultMeta(event, toolCalls); + if (!normalized || !textParser) { + break; + } + yield textParser.parse({ + type: 'tool-result', + toolCallId: normalized.call_id, + toolName: normalized.name as never, + input: normalized.arguments, + output: normalized.output, + }); + break; + } + case 'citation': { + if (citationFormatter) { + citationFormatter.consume({ + type: 'citation', + index: event.index, + url: event.url, + }); + } + break; + } + case 'done': { + const footnotes = textParser?.end() ?? ''; + const citations = citationFormatter?.end() ?? ''; + const tails = [citations, footnotes].filter(Boolean).join('\n'); + if (tails) { + yield `\n${tails}`; + } + break; + } + case 'error': { + throw new Error(event.message); + } + default: + break; + } + } + } + + async *streamObject( + request: NativeLlmRequest, + signal?: AbortSignal + ): AsyncIterableIterator { + const toolCalls = new Map(); + const citationFormatter = this.#enableCitationFootnote + ? new CitationFootnoteFormatter() + : null; + const fallbackAttachmentFootnotes = new Map(); + let hasFootnoteReference = false; + + for await (const event of this.#loop.run(request, signal)) { + switch (event.type) { + case 'text_delta': { + if (event.text.includes('[^')) { + hasFootnoteReference = true; + } + yield { + type: 'text-delta', + textDelta: event.text, + }; + break; + } + case 'reasoning_delta': { + yield { + type: 'reasoning', + textDelta: event.text, + }; + break; + } + case 'tool_call': { + const toolCall = { + name: event.name, + args: event.arguments, + }; + toolCalls.set(event.call_id, toolCall); + yield { + type: 'tool-call', + toolCallId: event.call_id, + toolName: event.name, + args: event.arguments, + }; + break; + } + case 'tool_result': { + const normalized = ensureToolResultMeta(event, toolCalls); + if (!normalized) { + break; + } + const attachments = collectAttachmentFootnotes(normalized); + attachments.forEach(attachment => { + fallbackAttachmentFootnotes.set(attachment.blobId, attachment); + }); + yield { + type: 'tool-result', + toolCallId: normalized.call_id, + toolName: normalized.name, + args: normalized.arguments, + result: normalized.output, + }; + break; + } + case 'citation': { + if (citationFormatter) { + citationFormatter.consume({ + type: 'citation', + index: event.index, + url: event.url, + }); + } + break; + } + case 'done': { + const citations = citationFormatter?.end() ?? ''; + if (citations) { + hasFootnoteReference = true; + yield { + type: 'text-delta', + textDelta: `\n${citations}`, + }; + } + if (!hasFootnoteReference && fallbackAttachmentFootnotes.size > 0) { + yield { + type: 'text-delta', + textDelta: formatAttachmentFootnotes( + Array.from(fallbackAttachmentFootnotes.values()) + ), + }; + } + break; + } + case 'error': { + throw new Error(event.message); + } + default: + break; + } + } + } +} diff --git a/packages/backend/server/src/plugins/copilot/providers/openai.ts b/packages/backend/server/src/plugins/copilot/providers/openai.ts index 1b69e9037f..4297552c6c 100644 --- a/packages/backend/server/src/plugins/copilot/providers/openai.ts +++ b/packages/backend/server/src/plugins/copilot/providers/openai.ts @@ -1,53 +1,35 @@ -import { - createOpenAI, - openai, - type OpenAIProvider as VercelOpenAIProvider, - OpenAIResponsesProviderOptions, -} from '@ai-sdk/openai'; -import { - createOpenAICompatible, - type OpenAICompatibleProvider as VercelOpenAICompatibleProvider, -} from '@ai-sdk/openai-compatible'; -import { - AISDKError, - embedMany, - experimental_generateImage as generateImage, - generateObject, - generateText, - stepCountIs, - streamText, - Tool, -} from 'ai'; +import type { Tool, ToolSet } from 'ai'; import { z } from 'zod'; import { CopilotPromptInvalid, - CopilotProviderNotSupported, CopilotProviderSideError, - fetchBuffer, metrics, OneMB, + readResponseBufferWithLimit, + safeFetch, UserFriendlyError, } from '../../../base'; +import { + llmDispatchStream, + type NativeLlmBackendConfig, + type NativeLlmRequest, +} from '../../../native'; +import type { NodeTextMiddleware } from '../config'; +import { buildNativeRequest, NativeProviderAdapter } from './native'; import { CopilotProvider } from './provider'; import type { CopilotChatOptions, CopilotChatTools, CopilotEmbeddingOptions, CopilotImageOptions, - CopilotProviderModel, CopilotStructuredOptions, ModelConditions, PromptMessage, StreamObject, } from './types'; import { CopilotProviderType, ModelInputType, ModelOutputType } from './types'; -import { - chatToGPTMessage, - CitationParser, - StreamObjectParser, - TextStreamParser, -} from './utils'; +import { chatToGPTMessage } from './utils'; export const DEFAULT_DIMENSIONS = 256; @@ -63,7 +45,12 @@ const ModelListSchema = z.object({ const ImageResponseSchema = z.union([ z.object({ - data: z.array(z.object({ b64_json: z.string() })), + data: z.array( + z.object({ + b64_json: z.string().optional(), + url: z.string().optional(), + }) + ), }), z.object({ error: z.object({ @@ -87,6 +74,38 @@ const LogProbsSchema = z.array( }) ); +const TRUSTED_ATTACHMENT_HOST_SUFFIXES = ['cdn.affine.pro']; + +function normalizeImageFormatToMime(format?: string) { + switch (format?.toLowerCase()) { + case 'jpg': + case 'jpeg': + return 'image/jpeg'; + case 'webp': + return 'image/webp'; + case 'png': + return 'image/png'; + case 'gif': + return 'image/gif'; + default: + return 'image/png'; + } +} + +function normalizeImageResponseData( + data: { b64_json?: string; url?: string }[], + mimeType: string = 'image/png' +) { + return data + .map(image => { + if (image.b64_json) { + return `data:${mimeType};base64,${image.b64_json}`; + } + return image.url; + }) + .filter((value): value is string => typeof value === 'string'); +} + export class OpenAIProvider extends CopilotProvider { readonly type = CopilotProviderType.OpenAI; @@ -319,53 +338,23 @@ export class OpenAIProvider extends CopilotProvider { }, ]; - #instance!: VercelOpenAIProvider | VercelOpenAICompatibleProvider; - override configured(): boolean { return !!this.config.apiKey; } protected override setup() { super.setup(); - this.#instance = - this.config.oldApiStyle && this.config.baseURL - ? createOpenAICompatible({ - name: 'openai-compatible-old-style', - apiKey: this.config.apiKey, - baseURL: this.config.baseURL, - }) - : createOpenAI({ - apiKey: this.config.apiKey, - baseURL: this.config.baseURL, - }); } - private handleError( - e: any, - model: string, - options: CopilotImageOptions = {} - ) { + private handleError(e: any) { if (e instanceof UserFriendlyError) { return e; - } else if (e instanceof AISDKError) { - if (e.message.includes('safety') || e.message.includes('risk')) { - metrics.ai - .counter('chat_text_risk_errors') - .add(1, { model, user: options.user || undefined }); - } - - return new CopilotProviderSideError({ - provider: this.type, - kind: e.name || 'unknown', - message: e.message, - }); - } else { - return new CopilotProviderSideError({ - provider: this.type, - kind: 'unexpected_response', - message: e?.message || 'Unexpected openai response', - }); } + return new CopilotProviderSideError({ + provider: this.type, + kind: 'unexpected_response', + message: e?.message || 'Unexpected openai response', + }); } override async refreshOnlineModels() { @@ -389,20 +378,50 @@ export class OpenAIProvider extends CopilotProvider { override getProviderSpecificTools( toolName: CopilotChatTools, - model: string + _model: string ): [string, Tool?] | undefined { - if ( - toolName === 'webSearch' && - 'responses' in this.#instance && - !this.isReasoningModel(model) - ) { - return ['web_search_preview', openai.tools.webSearch({})]; - } else if (toolName === 'docEdit') { + if (toolName === 'docEdit') { return ['doc_edit', undefined]; } return; } + private createNativeConfig(): NativeLlmBackendConfig { + const baseUrl = this.config.baseURL || 'https://api.openai.com/v1'; + return { + base_url: baseUrl.replace(/\/v1\/?$/, ''), + auth_token: this.config.apiKey, + }; + } + + private createNativeAdapter( + tools: ToolSet, + nodeTextMiddleware?: NodeTextMiddleware[] + ) { + return new NativeProviderAdapter( + (request: NativeLlmRequest, signal?: AbortSignal) => + llmDispatchStream( + this.config.oldApiStyle ? 'openai_chat' : 'openai_responses', + this.createNativeConfig(), + request, + signal + ), + tools, + this.MAX_STEPS, + { nodeTextMiddleware } + ); + } + + private getReasoning( + options: NonNullable, + model: string + ): Record | undefined { + if (options.reasoning && this.isReasoningModel(model)) { + return { effort: 'medium' }; + } + return undefined; + } + async text( cond: ModelConditions, messages: PromptMessage[], @@ -413,33 +432,25 @@ export class OpenAIProvider extends CopilotProvider { const model = this.selectModel(fullCond); try { - metrics.ai.counter('chat_text_calls').add(1, { model: model.id }); - - const [system, msgs] = await chatToGPTMessage(messages); - - const modelInstance = - 'responses' in this.#instance - ? this.#instance.responses(model.id) - : this.#instance(model.id); - - const { text } = await generateText({ - model: modelInstance, - system, - messages: msgs, - temperature: options.temperature ?? 0, - maxOutputTokens: options.maxTokens ?? 4096, - providerOptions: { - openai: this.getOpenAIOptions(options, model.id), - }, - tools: await this.getTools(options, model.id), - stopWhen: stepCountIs(this.MAX_STEPS), - abortSignal: options.signal, + metrics.ai.counter('chat_text_calls').add(1, this.metricLabels(model.id)); + const tools = await this.getTools(options, model.id); + const middleware = this.getActiveProviderMiddleware(); + const { request } = await buildNativeRequest({ + model: model.id, + messages, + options, + tools, + include: options.webSearch ? ['citations'] : undefined, + reasoning: this.getReasoning(options, model.id), + middleware, }); - - return text.trim(); + const adapter = this.createNativeAdapter(tools, middleware.node?.text); + return await adapter.text(request, options.signal); } catch (e: any) { - metrics.ai.counter('chat_text_errors').add(1, { model: model.id }); - throw this.handleError(e, model.id, options); + metrics.ai + .counter('chat_text_errors') + .add(1, this.metricLabels(model.id)); + throw this.handleError(e); } } @@ -456,38 +467,29 @@ export class OpenAIProvider extends CopilotProvider { const model = this.selectModel(fullCond); try { - metrics.ai.counter('chat_text_stream_calls').add(1, { model: model.id }); - const fullStream = await this.getFullStream(model, messages, options); - const citationParser = new CitationParser(); - const textParser = new TextStreamParser(); - for await (const chunk of fullStream) { - switch (chunk.type) { - case 'text-delta': { - let result = textParser.parse(chunk); - result = citationParser.parse(result); - yield result; - break; - } - case 'finish': { - const footnotes = textParser.end(); - const result = - citationParser.end() + (footnotes.length ? '\n' + footnotes : ''); - yield result; - break; - } - default: { - yield textParser.parse(chunk); - break; - } - } - if (options.signal?.aborted) { - await fullStream.cancel(); - break; - } + metrics.ai + .counter('chat_text_stream_calls') + .add(1, this.metricLabels(model.id)); + const tools = await this.getTools(options, model.id); + const middleware = this.getActiveProviderMiddleware(); + const { request } = await buildNativeRequest({ + model: model.id, + messages, + options, + tools, + include: options.webSearch ? ['citations'] : undefined, + reasoning: this.getReasoning(options, model.id), + middleware, + }); + const adapter = this.createNativeAdapter(tools, middleware.node?.text); + for await (const chunk of adapter.streamText(request, options.signal)) { + yield chunk; } } catch (e: any) { - metrics.ai.counter('chat_text_stream_errors').add(1, { model: model.id }); - throw this.handleError(e, model.id, options); + metrics.ai + .counter('chat_text_stream_errors') + .add(1, this.metricLabels(model.id)); + throw this.handleError(e); } } @@ -503,24 +505,27 @@ export class OpenAIProvider extends CopilotProvider { try { metrics.ai .counter('chat_object_stream_calls') - .add(1, { model: model.id }); - const fullStream = await this.getFullStream(model, messages, options); - const parser = new StreamObjectParser(); - for await (const chunk of fullStream) { - const result = parser.parse(chunk); - if (result) { - yield result; - } - if (options.signal?.aborted) { - await fullStream.cancel(); - break; - } + .add(1, this.metricLabels(model.id)); + const tools = await this.getTools(options, model.id); + const middleware = this.getActiveProviderMiddleware(); + const { request } = await buildNativeRequest({ + model: model.id, + messages, + options, + tools, + include: options.webSearch ? ['citations'] : undefined, + reasoning: this.getReasoning(options, model.id), + middleware, + }); + const adapter = this.createNativeAdapter(tools, middleware.node?.text); + for await (const chunk of adapter.streamObject(request, options.signal)) { + yield chunk; } } catch (e: any) { metrics.ai .counter('chat_object_stream_errors') - .add(1, { model: model.id }); - throw this.handleError(e, model.id, options); + .add(1, this.metricLabels(model.id)); + throw this.handleError(e); } } @@ -535,35 +540,27 @@ export class OpenAIProvider extends CopilotProvider { try { metrics.ai.counter('chat_text_calls').add(1, { model: model.id }); - - const [system, msgs, schema] = await chatToGPTMessage(messages); + const tools = await this.getTools(options, model.id); + const middleware = this.getActiveProviderMiddleware(); + const { request, schema } = await buildNativeRequest({ + model: model.id, + messages, + options, + tools, + reasoning: this.getReasoning(options, model.id), + middleware, + }); if (!schema) { throw new CopilotPromptInvalid('Schema is required'); } - - const modelInstance = - 'responses' in this.#instance - ? this.#instance.responses(model.id) - : this.#instance(model.id); - - const { object } = await generateObject({ - model: modelInstance, - system, - messages: msgs, - temperature: options.temperature ?? 0, - maxOutputTokens: options.maxTokens ?? 4096, - maxRetries: options.maxRetries ?? 3, - schema, - providerOptions: { - openai: options.user ? { user: options.user } : {}, - }, - abortSignal: options.signal, - }); - - return JSON.stringify(object); + const adapter = this.createNativeAdapter(tools, middleware.node?.text); + const text = await adapter.text(request, options.signal); + const parsed = JSON.parse(text); + const validated = schema.parse(parsed); + return JSON.stringify(validated); } catch (e: any) { metrics.ai.counter('chat_text_errors').add(1, { model: model.id }); - throw this.handleError(e, model.id, options); + throw this.handleError(e); } } @@ -575,36 +572,32 @@ export class OpenAIProvider extends CopilotProvider { const fullCond = { ...cond, outputType: ModelOutputType.Text }; await this.checkParams({ messages: [], cond: fullCond, options }); const model = this.selectModel(fullCond); - // get the log probability of "yes"/"no" - const instance = - 'chat' in this.#instance - ? this.#instance.chat(model.id) - : this.#instance(model.id); const scores = await Promise.all( chunkMessages.map(async messages => { const [system, msgs] = await chatToGPTMessage(messages); - - const result = await generateText({ - model: instance, - system, - messages: msgs, - temperature: 0, - maxOutputTokens: 16, - providerOptions: { - openai: { - ...this.getOpenAIOptions(options, model.id), - logprobs: 16, - }, + const response = await this.requestOpenAIJson( + '/chat/completions', + { + model: model.id, + messages: this.toOpenAIChatMessages(system, msgs), + temperature: 0, + max_tokens: 16, + logprobs: true, + top_logprobs: 16, }, - abortSignal: options.signal, - }); + options.signal + ); - const topMap: Record = LogProbsSchema.parse( - result.providerMetadata?.openai?.logprobs - )[0].top_logprobs.reduce>( + const logprobs = response?.choices?.[0]?.logprobs?.content; + if (!Array.isArray(logprobs) || logprobs.length === 0) { + return 0; + } + + const parsedLogprobs = LogProbsSchema.parse(logprobs); + const topMap = parsedLogprobs[0].top_logprobs.reduce( (acc, { token, logprob }) => ({ ...acc, [token]: logprob }), - {} + {} as Record ); const findLogProb = (token: string): number => { @@ -634,50 +627,212 @@ export class OpenAIProvider extends CopilotProvider { return scores; } - private async getFullStream( - model: CopilotProviderModel, - messages: PromptMessage[], - options: CopilotChatOptions = {} - ) { - const [system, msgs] = await chatToGPTMessage(messages); - const modelInstance = - 'responses' in this.#instance - ? this.#instance.responses(model.id) - : this.#instance(model.id); - const { fullStream } = streamText({ - model: modelInstance, - system, - messages: msgs, - frequencyPenalty: options.frequencyPenalty ?? 0, - presencePenalty: options.presencePenalty ?? 0, - temperature: options.temperature ?? 0, - maxOutputTokens: options.maxTokens ?? 4096, - providerOptions: { - openai: this.getOpenAIOptions(options, model.id), - }, - tools: await this.getTools(options, model.id), - stopWhen: stepCountIs(this.MAX_STEPS), - abortSignal: options.signal, - }); - return fullStream; + // ====== text to image ====== + private buildImageFetchOptions(url: URL) { + const baseOptions = { timeoutMs: 15_000, maxRedirects: 3 } as const; + const trustedOrigins = new Set(); + const protocol = this.AFFiNEConfig.server.https ? 'https:' : 'http:'; + const port = this.AFFiNEConfig.server.port; + const isDefaultPort = + (protocol === 'https:' && port === 443) || + (protocol === 'http:' && port === 80); + + const addHostOrigin = (host: string) => { + if (!host) return; + try { + const parsed = new URL(`${protocol}//${host}`); + if (!parsed.port && !isDefaultPort) { + parsed.port = String(port); + } + trustedOrigins.add(parsed.origin); + } catch { + // ignore invalid host config entries + } + }; + + if (this.AFFiNEConfig.server.externalUrl) { + try { + trustedOrigins.add( + new URL(this.AFFiNEConfig.server.externalUrl).origin + ); + } catch { + // ignore invalid external URL + } + } + + addHostOrigin(this.AFFiNEConfig.server.host); + for (const host of this.AFFiNEConfig.server.hosts) { + addHostOrigin(host); + } + + const hostname = url.hostname.toLowerCase(); + const trustedByHost = TRUSTED_ATTACHMENT_HOST_SUFFIXES.some( + suffix => hostname === suffix || hostname.endsWith(`.${suffix}`) + ); + if (trustedOrigins.has(url.origin) || trustedByHost) { + return { ...baseOptions, allowPrivateOrigins: new Set([url.origin]) }; + } + + return baseOptions; + } + + private redactUrl(raw: string | URL): string { + try { + const parsed = raw instanceof URL ? raw : new URL(raw); + if (parsed.protocol === 'data:') return 'data:[redacted]'; + const segments = parsed.pathname.split('/').filter(Boolean); + const redactedPath = + segments.length <= 2 + ? parsed.pathname || '/' + : `/${segments[0]}/${segments[1]}/...`; + return `${parsed.origin}${redactedPath}`; + } catch { + return '[invalid-url]'; + } + } + + private async fetchImage( + url: string, + maxBytes: number, + signal?: AbortSignal + ): Promise<{ buffer: Buffer; type: string } | null> { + if (url.startsWith('data:')) { + let response: Response; + try { + response = await fetch(url, { signal }); + } catch (error) { + this.logger.warn( + `Skip image attachment data URL due to read failure: ${ + error instanceof Error ? error.message : String(error) + }` + ); + return null; + } + + if (!response.ok) { + this.logger.warn( + `Skip image attachment data URL due to invalid response: ${response.status}` + ); + return null; + } + + const type = + response.headers.get('content-type') || 'application/octet-stream'; + if (!type.startsWith('image/')) { + await response.body?.cancel().catch(() => undefined); + this.logger.warn( + `Skip non-image attachment data URL with content-type ${type}` + ); + return null; + } + + try { + const buffer = await readResponseBufferWithLimit(response, maxBytes); + return { buffer, type }; + } catch (error) { + this.logger.warn( + `Skip image attachment data URL due to read failure/size limit: ${ + error instanceof Error ? error.message : String(error) + }` + ); + return null; + } + } + + let parsed: URL; + try { + parsed = new URL(url); + } catch { + this.logger.warn( + `Skip image attachment with invalid URL: ${this.redactUrl(url)}` + ); + return null; + } + const redactedUrl = this.redactUrl(parsed); + + if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') { + this.logger.warn( + `Skip image attachment with unsupported protocol: ${redactedUrl}` + ); + return null; + } + + let response: Response; + try { + response = await safeFetch( + parsed, + { method: 'GET', signal }, + this.buildImageFetchOptions(parsed) + ); + } catch (error) { + this.logger.warn( + `Skip image attachment due to blocked/unreachable URL: ${redactedUrl}, reason: ${ + error instanceof Error ? error.message : String(error) + }` + ); + return null; + } + + if (!response.ok) { + this.logger.warn( + `Skip image attachment fetch failure ${response.status}: ${redactedUrl}` + ); + return null; + } + + const type = + response.headers.get('content-type') || 'application/octet-stream'; + if (!type.startsWith('image/')) { + await response.body?.cancel().catch(() => undefined); + this.logger.warn( + `Skip non-image attachment with content-type ${type}: ${redactedUrl}` + ); + return null; + } + + const contentLength = Number(response.headers.get('content-length')); + if (Number.isFinite(contentLength) && contentLength > maxBytes) { + await response.body?.cancel().catch(() => undefined); + this.logger.warn( + `Skip oversized image attachment by content-length (${contentLength}): ${redactedUrl}` + ); + return null; + } + + try { + const buffer = await readResponseBufferWithLimit(response, maxBytes); + return { buffer, type }; + } catch (error) { + this.logger.warn( + `Skip image attachment due to read failure/size limit: ${redactedUrl}, reason: ${ + error instanceof Error ? error.message : String(error) + }` + ); + return null; + } } - // ====== text to image ====== private async *generateImageWithAttachments( model: string, prompt: string, - attachments: NonNullable + attachments: NonNullable, + signal?: AbortSignal ): AsyncGenerator { const form = new FormData(); + const outputFormat = 'webp'; + const maxBytes = 10 * OneMB; form.set('model', model); form.set('prompt', prompt); - form.set('output_format', 'webp'); + form.set('output_format', outputFormat); for (const [idx, entry] of attachments.entries()) { const url = typeof entry === 'string' ? entry : entry.attachment; try { - const { buffer, type } = await fetchBuffer(url, 10 * OneMB, 'image/'); - const file = new File([buffer], `${idx}.png`, { type }); + const attachment = await this.fetchImage(url, maxBytes, signal); + if (!attachment) continue; + const { buffer, type } = attachment; + const extension = type.split(';')[0].split('/')[1] || 'png'; + const file = new File([buffer], `${idx}.${extension}`, { type }); form.append('image[]', file); } catch { continue; @@ -703,18 +858,24 @@ export class OpenAIProvider extends CopilotProvider { const json = await res.json(); const imageResponse = ImageResponseSchema.safeParse(json); - if (imageResponse.success) { - const data = imageResponse.data; - if ('error' in data) { - throw new Error(data.error.message); - } else { - for (const image of data.data) { - yield `data:image/webp;base64,${image.b64_json}`; - } - } - } else { + if (!imageResponse.success) { throw new Error(imageResponse.error.message); } + const data = imageResponse.data; + if ('error' in data) { + throw new Error(data.error.message); + } + + const images = normalizeImageResponseData( + data.data, + normalizeImageFormatToMime(outputFormat) + ); + if (!images.length) { + throw new Error('No images returned from OpenAI'); + } + for (const image of images) { + yield image; + } } override async *streamImages( @@ -726,13 +887,6 @@ export class OpenAIProvider extends CopilotProvider { await this.checkParams({ messages, cond: fullCond, options }); const model = this.selectModel(fullCond); - if (!('image' in this.#instance)) { - throw new CopilotProviderNotSupported({ - provider: this.type, - kind: 'image', - }); - } - metrics.ai .counter('generate_images_stream_calls') .add(1, { model: model.id }); @@ -742,22 +896,27 @@ export class OpenAIProvider extends CopilotProvider { try { if (attachments && attachments.length > 0) { - yield* this.generateImageWithAttachments(model.id, prompt, attachments); - } else { - const modelInstance = this.#instance.image(model.id); - const result = await generateImage({ - model: modelInstance, + yield* this.generateImageWithAttachments( + model.id, prompt, - providerOptions: { - openai: { - quality: options.quality || null, - }, - }, - }); - - const imageUrls = result.images.map( - image => `data:image/png;base64,${image.base64}` + attachments, + options.signal ); + } else { + const response = await this.requestOpenAIJson('/images/generations', { + model: model.id, + prompt, + ...(options.quality ? { quality: options.quality } : {}), + }); + const imageResponse = ImageResponseSchema.parse(response); + if ('error' in imageResponse) { + throw new Error(imageResponse.error.message); + } + + const imageUrls = normalizeImageResponseData(imageResponse.data); + if (!imageUrls.length) { + throw new Error('No images returned from OpenAI'); + } for (const imageUrl of imageUrls) { yield imageUrl; @@ -769,7 +928,7 @@ export class OpenAIProvider extends CopilotProvider { return; } catch (e: any) { metrics.ai.counter('generate_images_errors').add(1, { model: model.id }); - throw this.handleError(e, model.id, options); + throw this.handleError(e); } } @@ -783,51 +942,85 @@ export class OpenAIProvider extends CopilotProvider { await this.checkParams({ embeddings: messages, cond: fullCond, options }); const model = this.selectModel(fullCond); - if (!('embedding' in this.#instance)) { - throw new CopilotProviderNotSupported({ - provider: this.type, - kind: 'embedding', - }); - } - try { metrics.ai .counter('generate_embedding_calls') .add(1, { model: model.id }); - - const modelInstance = this.#instance.embedding(model.id); - - const { embeddings } = await embedMany({ - model: modelInstance, - values: messages, - providerOptions: { - openai: { - dimensions: options.dimensions || DEFAULT_DIMENSIONS, - }, - }, + const response = await this.requestOpenAIJson('/embeddings', { + model: model.id, + input: messages, + dimensions: options.dimensions || DEFAULT_DIMENSIONS, }); - - return embeddings.filter(v => v && Array.isArray(v)); + const data = Array.isArray(response?.data) ? response.data : []; + return data + .map((item: any) => item?.embedding) + .filter((embedding: unknown) => Array.isArray(embedding)) as number[][]; } catch (e: any) { metrics.ai .counter('generate_embedding_errors') .add(1, { model: model.id }); - throw this.handleError(e, model.id, options); + throw this.handleError(e); } } - private getOpenAIOptions(options: CopilotChatOptions, model: string) { - const result: OpenAIResponsesProviderOptions = {}; - if (options?.reasoning && this.isReasoningModel(model)) { - result.reasoningEffort = 'medium'; - result.reasoningSummary = 'detailed'; + private toOpenAIChatMessages( + system: string | undefined, + messages: Awaited>[1] + ) { + const result: Array<{ role: string; content: string }> = []; + if (system) { + result.push({ role: 'system', content: system }); } - if (options?.user) { - result.user = options.user; + + for (const message of messages) { + if (typeof message.content === 'string') { + result.push({ role: message.role, content: message.content }); + continue; + } + + const text = message.content + .filter( + part => + part && + typeof part === 'object' && + 'type' in part && + part.type === 'text' && + 'text' in part + ) + .map(part => String((part as { text: string }).text)) + .join('\n'); + + result.push({ role: message.role, content: text || '[no content]' }); } + return result; } + private async requestOpenAIJson( + path: string, + body: Record, + signal?: AbortSignal + ): Promise { + const baseUrl = this.config.baseURL || 'https://api.openai.com/v1'; + const response = await fetch(`${baseUrl}${path}`, { + method: 'POST', + headers: { + Authorization: `Bearer ${this.config.apiKey}`, + 'Content-Type': 'application/json', + }, + body: JSON.stringify(body), + signal, + }); + + if (!response.ok) { + throw new Error( + `OpenAI API error ${response.status}: ${await response.text()}` + ); + } + + return await response.json(); + } + private isReasoningModel(model: string) { // o series reasoning models return model.startsWith('o') || model.startsWith('gpt-5'); diff --git a/packages/backend/server/src/plugins/copilot/providers/perplexity.ts b/packages/backend/server/src/plugins/copilot/providers/perplexity.ts index b49f7ece1b..f1dd4d6663 100644 --- a/packages/backend/server/src/plugins/copilot/providers/perplexity.ts +++ b/packages/backend/server/src/plugins/copilot/providers/perplexity.ts @@ -1,11 +1,13 @@ -import { - createPerplexity, - type PerplexityProvider as VercelPerplexityProvider, -} from '@ai-sdk/perplexity'; -import { generateText, streamText } from 'ai'; -import { z } from 'zod'; +import type { ToolSet } from 'ai'; import { CopilotProviderSideError, metrics } from '../../../base'; +import { + llmDispatchStream, + type NativeLlmBackendConfig, + type NativeLlmRequest, +} from '../../../native'; +import type { NodeTextMiddleware } from '../config'; +import { buildNativeRequest, NativeProviderAdapter } from './native'; import { CopilotProvider } from './provider'; import { CopilotChatOptions, @@ -15,34 +17,12 @@ import { ModelOutputType, PromptMessage, } from './types'; -import { chatToGPTMessage, CitationParser } from './utils'; export type PerplexityConfig = { apiKey: string; endpoint?: string; }; -const PerplexityErrorSchema = z.union([ - z.object({ - detail: z.array( - z.object({ - loc: z.array(z.string()), - msg: z.string(), - type: z.string(), - }) - ), - }), - z.object({ - error: z.object({ - message: z.string(), - type: z.string(), - code: z.number(), - }), - }), -]); - -type PerplexityError = z.infer; - export class PerplexityProvider extends CopilotProvider { readonly type = CopilotProviderType.Perplexity; @@ -90,18 +70,38 @@ export class PerplexityProvider extends CopilotProvider { }, ]; - #instance!: VercelPerplexityProvider; - override configured(): boolean { return !!this.config.apiKey; } protected override setup() { super.setup(); - this.#instance = createPerplexity({ - apiKey: this.config.apiKey, - baseURL: this.config.endpoint, - }); + } + + private createNativeConfig(): NativeLlmBackendConfig { + const baseUrl = this.config.endpoint || 'https://api.perplexity.ai'; + return { + base_url: baseUrl.replace(/\/v1\/?$/, ''), + auth_token: this.config.apiKey, + }; + } + + private createNativeAdapter( + tools: ToolSet, + nodeTextMiddleware?: NodeTextMiddleware[] + ) { + return new NativeProviderAdapter( + (request: NativeLlmRequest, signal?: AbortSignal) => + llmDispatchStream( + 'openai_chat', + this.createNativeConfig(), + request, + signal + ), + tools, + this.MAX_STEPS, + { nodeTextMiddleware } + ); } async text( @@ -114,32 +114,25 @@ export class PerplexityProvider extends CopilotProvider { const model = this.selectModel(fullCond); try { - metrics.ai.counter('chat_text_calls').add(1, { model: model.id }); + metrics.ai.counter('chat_text_calls').add(1, this.metricLabels(model.id)); - const [system, msgs] = await chatToGPTMessage(messages, false); - - const modelInstance = this.#instance(model.id); - - const { text, sources } = await generateText({ - model: modelInstance, - system, - messages: msgs, - temperature: options.temperature ?? 0, - maxOutputTokens: options.maxTokens ?? 4096, - abortSignal: options.signal, + const tools = await this.getTools(options, model.id); + const middleware = this.getActiveProviderMiddleware(); + const { request } = await buildNativeRequest({ + model: model.id, + messages, + options, + tools, + withAttachment: false, + include: ['citations'], + middleware, }); - - const parser = new CitationParser(); - for (const source of sources.filter(s => s.sourceType === 'url')) { - parser.push(source.url); - } - - let result = text.replaceAll(/<\/?think>\n/g, '\n---\n'); - result = parser.parse(result); - result += parser.end(); - return result; + const adapter = this.createNativeAdapter(tools, middleware.node?.text); + return await adapter.text(request, options.signal); } catch (e: any) { - metrics.ai.counter('chat_text_errors').add(1, { model: model.id }); + metrics.ai + .counter('chat_text_errors') + .add(1, this.metricLabels(model.id)); throw this.handleError(e); } } @@ -154,79 +147,33 @@ export class PerplexityProvider extends CopilotProvider { const model = this.selectModel(fullCond); try { - metrics.ai.counter('chat_text_stream_calls').add(1, { model: model.id }); + metrics.ai + .counter('chat_text_stream_calls') + .add(1, this.metricLabels(model.id)); - const [system, msgs] = await chatToGPTMessage(messages, false); - - const modelInstance = this.#instance(model.id); - - const stream = streamText({ - model: modelInstance, - system, - messages: msgs, - temperature: options.temperature ?? 0, - maxOutputTokens: options.maxTokens ?? 4096, - abortSignal: options.signal, + const tools = await this.getTools(options, model.id); + const middleware = this.getActiveProviderMiddleware(); + const { request } = await buildNativeRequest({ + model: model.id, + messages, + options, + tools, + withAttachment: false, + include: ['citations'], + middleware, }); - - const parser = new CitationParser(); - for await (const chunk of stream.fullStream) { - switch (chunk.type) { - case 'source': { - if (chunk.sourceType === 'url') { - parser.push(chunk.url); - } - break; - } - case 'text-delta': { - const text = chunk.text.replaceAll(/<\/?think>\n?/g, '\n---\n'); - const result = parser.parse(text); - yield result; - break; - } - case 'finish-step': { - const result = parser.end(); - yield result; - break; - } - case 'error': { - const json = - typeof chunk.error === 'string' - ? JSON.parse(chunk.error) - : chunk.error; - if (json && typeof json === 'object') { - const data = PerplexityErrorSchema.parse(json); - if ('detail' in data || 'error' in data) { - throw this.convertError(data); - } - } - } - } + const adapter = this.createNativeAdapter(tools, middleware.node?.text); + for await (const chunk of adapter.streamText(request, options.signal)) { + yield chunk; } - } catch (e) { - metrics.ai.counter('chat_text_stream_errors').add(1, { model: model.id }); - throw e; + } catch (e: any) { + metrics.ai + .counter('chat_text_stream_errors') + .add(1, this.metricLabels(model.id)); + throw this.handleError(e); } } - private convertError(e: PerplexityError) { - function getErrMessage(e: PerplexityError) { - let err = 'Unexpected perplexity response'; - if ('detail' in e) { - err = e.detail[0].msg || err; - } else if ('error' in e) { - err = e.error.message || err; - } - return err; - } - - throw new CopilotProviderSideError({ - provider: this.type, - kind: 'unexpected_response', - message: getErrMessage(e), - }); - } - private handleError(e: any) { if (e instanceof CopilotProviderSideError) { return e; diff --git a/packages/backend/server/src/plugins/copilot/providers/provider-middleware.ts b/packages/backend/server/src/plugins/copilot/providers/provider-middleware.ts new file mode 100644 index 0000000000..98dc64cefc --- /dev/null +++ b/packages/backend/server/src/plugins/copilot/providers/provider-middleware.ts @@ -0,0 +1,98 @@ +import type { ProviderMiddlewareConfig } from '../config'; +import { CopilotProviderType } from './types'; + +const DEFAULT_MIDDLEWARE_BY_TYPE: Record< + CopilotProviderType, + ProviderMiddlewareConfig +> = { + [CopilotProviderType.OpenAI]: { + rust: { + request: ['normalize_messages'], + stream: ['stream_event_normalize', 'citation_indexing'], + }, + node: { + text: ['citation_footnote', 'callout'], + }, + }, + [CopilotProviderType.Anthropic]: { + rust: { + request: ['normalize_messages', 'tool_schema_rewrite'], + stream: ['stream_event_normalize', 'citation_indexing'], + }, + node: { + text: ['citation_footnote', 'callout'], + }, + }, + [CopilotProviderType.AnthropicVertex]: { + rust: { + request: ['normalize_messages', 'tool_schema_rewrite'], + stream: ['stream_event_normalize', 'citation_indexing'], + }, + node: { + text: ['citation_footnote', 'callout'], + }, + }, + [CopilotProviderType.Morph]: { + rust: { + request: ['clamp_max_tokens'], + stream: ['stream_event_normalize', 'citation_indexing'], + }, + node: { + text: ['citation_footnote', 'callout'], + }, + }, + [CopilotProviderType.Perplexity]: { + rust: { + request: ['clamp_max_tokens'], + stream: ['stream_event_normalize', 'citation_indexing'], + }, + node: { + text: ['citation_footnote', 'callout'], + }, + }, + [CopilotProviderType.Gemini]: { + node: { + text: ['callout'], + }, + }, + [CopilotProviderType.GeminiVertex]: { + node: { + text: ['callout'], + }, + }, + [CopilotProviderType.FAL]: {}, +}; + +function unique(items: T[]) { + return [...new Set(items)]; +} + +function mergeArray(base: T[] | undefined, override: T[] | undefined) { + if (!base?.length && !override?.length) { + return undefined; + } + return unique([...(base ?? []), ...(override ?? [])]); +} + +export function mergeProviderMiddleware( + defaults: ProviderMiddlewareConfig, + override?: ProviderMiddlewareConfig +): ProviderMiddlewareConfig { + return { + rust: { + request: mergeArray(defaults.rust?.request, override?.rust?.request), + stream: mergeArray(defaults.rust?.stream, override?.rust?.stream), + }, + node: { + text: mergeArray(defaults.node?.text, override?.node?.text), + }, + }; +} + +export function resolveProviderMiddleware( + type: CopilotProviderType, + override?: ProviderMiddlewareConfig +): ProviderMiddlewareConfig { + const defaults = DEFAULT_MIDDLEWARE_BY_TYPE[type] ?? {}; + return mergeProviderMiddleware(defaults, override); +} diff --git a/packages/backend/server/src/plugins/copilot/providers/provider-registry.ts b/packages/backend/server/src/plugins/copilot/providers/provider-registry.ts new file mode 100644 index 0000000000..a877bd4cff --- /dev/null +++ b/packages/backend/server/src/plugins/copilot/providers/provider-registry.ts @@ -0,0 +1,273 @@ +import type { + CopilotProviderConfigMap, + CopilotProviderDefaults, + CopilotProviderProfile, + ProviderMiddlewareConfig, +} from '../config'; +import { resolveProviderMiddleware } from './provider-middleware'; +import { CopilotProviderType, type ModelOutputType } from './types'; + +const PROVIDER_ID_PATTERN = /^[a-zA-Z0-9-_]+$/; + +const LEGACY_PROVIDER_ORDER: CopilotProviderType[] = [ + CopilotProviderType.OpenAI, + CopilotProviderType.FAL, + CopilotProviderType.Gemini, + CopilotProviderType.GeminiVertex, + CopilotProviderType.Perplexity, + CopilotProviderType.Anthropic, + CopilotProviderType.AnthropicVertex, + CopilotProviderType.Morph, +]; + +const LEGACY_PROVIDER_PRIORITY = LEGACY_PROVIDER_ORDER.reduce( + (acc, type, index) => { + acc[type] = LEGACY_PROVIDER_ORDER.length - index; + return acc; + }, + {} as Record +); + +type LegacyProvidersConfig = Partial< + Record +>; + +export type CopilotProvidersConfigInput = LegacyProvidersConfig & { + profiles?: CopilotProviderProfile[] | null; + defaults?: CopilotProviderDefaults | null; +}; + +export type NormalizedCopilotProviderProfile = Omit< + CopilotProviderProfile, + 'enabled' | 'priority' | 'middleware' +> & { + enabled: boolean; + priority: number; + middleware: ProviderMiddlewareConfig; +}; + +export type CopilotProviderRegistry = { + profiles: Map; + defaults: CopilotProviderDefaults; + order: string[]; + byType: Map; +}; + +export type ResolveModelResult = { + rawModelId?: string; + modelId?: string; + explicitProviderId?: string; + candidateProviderIds: string[]; +}; + +type ResolveModelOptions = { + registry: CopilotProviderRegistry; + modelId?: string; + outputType?: ModelOutputType; + availableProviderIds?: Iterable; + preferredProviderIds?: Iterable; +}; + +function unique(list: T[]): T[] { + return [...new Set(list)]; +} + +function asArray(iter?: Iterable): T[] { + return iter ? Array.from(iter) : []; +} + +function parseModelPrefix( + registry: CopilotProviderRegistry, + modelId: string +): { providerId: string; modelId?: string } | null { + const index = modelId.indexOf('/'); + if (index <= 0) { + return null; + } + + const providerId = modelId.slice(0, index); + if (!registry.profiles.has(providerId)) { + return null; + } + + const model = modelId.slice(index + 1); + return { providerId, modelId: model || undefined }; +} + +function normalizeProfile( + profile: CopilotProviderProfile +): NormalizedCopilotProviderProfile { + return { + ...profile, + enabled: profile.enabled !== false, + priority: profile.priority ?? 0, + middleware: resolveProviderMiddleware(profile.type, profile.middleware), + }; +} + +function toLegacyProfiles( + config: CopilotProvidersConfigInput +): CopilotProviderProfile[] { + const legacyProfiles: CopilotProviderProfile[] = []; + for (const type of LEGACY_PROVIDER_ORDER) { + const legacyConfig = config[type]; + if (!legacyConfig) { + continue; + } + legacyProfiles.push({ + id: `${type}-default`, + type, + priority: LEGACY_PROVIDER_PRIORITY[type], + config: legacyConfig, + } as CopilotProviderProfile); + } + return legacyProfiles; +} + +function mergeProfiles( + explicitProfiles: CopilotProviderProfile[], + legacyProfiles: CopilotProviderProfile[] +): CopilotProviderProfile[] { + const profiles = new Map(); + + for (const profile of explicitProfiles) { + if (!PROVIDER_ID_PATTERN.test(profile.id)) { + throw new Error(`Invalid copilot provider profile id: ${profile.id}`); + } + if (profiles.has(profile.id)) { + throw new Error(`Duplicated copilot provider profile id: ${profile.id}`); + } + profiles.set(profile.id, profile); + } + + for (const profile of legacyProfiles) { + if (!profiles.has(profile.id)) { + profiles.set(profile.id, profile); + } + } + + return Array.from(profiles.values()); +} + +function sortProfiles(profiles: NormalizedCopilotProviderProfile[]) { + return profiles.toSorted((a, b) => { + if (a.priority !== b.priority) { + return b.priority - a.priority; + } + return a.id.localeCompare(b.id); + }); +} + +function assertDefaults( + defaults: CopilotProviderDefaults, + profiles: Map +) { + for (const providerId of Object.values(defaults)) { + if (!providerId) { + continue; + } + if (!profiles.has(providerId)) { + throw new Error( + `Copilot provider defaults references unknown providerId: ${providerId}` + ); + } + } +} + +export function buildProviderRegistry( + config: CopilotProvidersConfigInput +): CopilotProviderRegistry { + const explicitProfiles = config.profiles ?? []; + const legacyProfiles = toLegacyProfiles(config); + const mergedProfiles = mergeProfiles(explicitProfiles, legacyProfiles) + .map(normalizeProfile) + .filter(profile => profile.enabled); + const sortedProfiles = sortProfiles(mergedProfiles); + + const profiles = new Map( + sortedProfiles.map(profile => [profile.id, profile] as const) + ); + const defaults = config.defaults ?? {}; + assertDefaults(defaults, profiles); + + const order = sortedProfiles.map(profile => profile.id); + const byType = new Map(); + for (const profile of sortedProfiles) { + const ids = byType.get(profile.type) ?? []; + ids.push(profile.id); + byType.set(profile.type, ids); + } + + return { profiles, defaults, order, byType }; +} + +export function resolveModel({ + registry, + modelId, + outputType, + availableProviderIds, + preferredProviderIds, +}: ResolveModelOptions): ResolveModelResult { + const available = new Set(asArray(availableProviderIds)); + const preferred = new Set(asArray(preferredProviderIds)); + const hasAvailableFilter = available.size > 0; + const hasPreferredFilter = preferred.size > 0; + + const isAllowed = (providerId: string) => { + const profile = registry.profiles.get(providerId); + if (!profile?.enabled) { + return false; + } + if (hasAvailableFilter && !available.has(providerId)) { + return false; + } + if (hasPreferredFilter && !preferred.has(providerId)) { + return false; + } + return true; + }; + + const prefixed = modelId ? parseModelPrefix(registry, modelId) : null; + if (prefixed) { + return { + rawModelId: modelId, + modelId: prefixed.modelId, + explicitProviderId: prefixed.providerId, + candidateProviderIds: isAllowed(prefixed.providerId) + ? [prefixed.providerId] + : [], + }; + } + + const fallbackOrder = [ + ...(outputType ? [registry.defaults[outputType]] : []), + registry.defaults.fallback, + ...registry.order, + ].filter((id): id is string => !!id); + + return { + rawModelId: modelId, + modelId, + candidateProviderIds: unique( + fallbackOrder.filter(providerId => isAllowed(providerId)) + ), + }; +} + +export function stripProviderPrefix( + registry: CopilotProviderRegistry, + providerId: string, + modelId?: string +) { + if (!modelId) { + return modelId; + } + const prefixed = parseModelPrefix(registry, modelId); + if (!prefixed) { + return modelId; + } + if (prefixed.providerId !== providerId) { + return modelId; + } + return prefixed.modelId; +} diff --git a/packages/backend/server/src/plugins/copilot/providers/provider.ts b/packages/backend/server/src/plugins/copilot/providers/provider.ts index b021854959..8d594817ce 100644 --- a/packages/backend/server/src/plugins/copilot/providers/provider.ts +++ b/packages/backend/server/src/plugins/copilot/providers/provider.ts @@ -1,3 +1,5 @@ +import { AsyncLocalStorage } from 'node:async_hooks'; + import { Inject, Injectable, Logger } from '@nestjs/common'; import { ModuleRef } from '@nestjs/core'; import { Tool, ToolSet } from 'ai'; @@ -13,6 +15,7 @@ import { DocReader, DocWriter } from '../../../core/doc'; import { AccessController } from '../../../core/permission'; import { Models } from '../../../models'; import { IndexerService } from '../../indexer'; +import type { ProviderMiddlewareConfig } from '../config'; import { CopilotContextService } from '../context/service'; import { PromptService } from '../prompt/service'; import { @@ -40,6 +43,8 @@ import { createSectionEditTool, } from '../tools'; import { CopilotProviderFactory } from './factory'; +import { resolveProviderMiddleware } from './provider-middleware'; +import { buildProviderRegistry } from './provider-registry'; import { type CopilotChatOptions, CopilotChatTools, @@ -58,11 +63,14 @@ import { StreamObject, } from './types'; +const providerProfileContext = new AsyncLocalStorage(); + @Injectable() export abstract class CopilotProvider { protected readonly logger = new Logger(this.constructor.name); protected readonly MAX_STEPS = 20; protected onlineModelList: string[] = []; + abstract readonly type: CopilotProviderType; abstract readonly models: CopilotProviderModel[]; abstract configured(): boolean; @@ -70,8 +78,39 @@ export abstract class CopilotProvider { @Inject() protected readonly AFFiNEConfig!: Config; @Inject() protected readonly factory!: CopilotProviderFactory; @Inject() protected readonly moduleRef!: ModuleRef; + readonly #registeredProviderIds = new Set(); + + runWithProfile(providerId: string, callback: () => T): T { + return providerProfileContext.run(providerId, callback); + } + + protected getActiveProviderId() { + return providerProfileContext.getStore() ?? `${this.type}-default`; + } + + protected getActiveProviderMiddleware(): ProviderMiddlewareConfig { + const providerId = this.getActiveProviderId(); + const registry = buildProviderRegistry(this.AFFiNEConfig.copilot.providers); + const profile = registry.profiles.get(providerId); + return profile?.middleware ?? resolveProviderMiddleware(this.type); + } + + protected metricLabels( + model: string, + labels: Record = {} + ) { + const providerId = this.getActiveProviderId(); + return { model, providerId, ...labels }; + } get config(): C { + const profileId = providerProfileContext.getStore(); + if (profileId) { + const profile = this.AFFiNEConfig.copilot.providers.profiles?.find( + profile => profile.id === profileId && profile.type === this.type + ); + if (profile) return profile.config as C; + } return this.AFFiNEConfig.copilot.providers[this.type] as C; } @@ -88,15 +127,37 @@ export abstract class CopilotProvider { } protected setup() { - if (this.configured()) { - this.factory.register(this); - if (env.selfhosted) { + const registry = buildProviderRegistry(this.AFFiNEConfig.copilot.providers); + const providerIds = registry.byType.get(this.type) ?? []; + const nextProviderIds = new Set(); + + for (const id of providerIds) { + const configured = this.runWithProfile(id, () => this.configured()); + if (configured) { + nextProviderIds.add(id); + this.factory.register(id, this); + } else { + this.factory.unregister(id, this); + } + } + + for (const providerId of this.#registeredProviderIds) { + if (!nextProviderIds.has(providerId)) { + this.factory.unregister(providerId, this); + } + } + this.#registeredProviderIds.clear(); + for (const providerId of nextProviderIds) { + this.#registeredProviderIds.add(providerId); + } + + if (env.selfhosted && nextProviderIds.size > 0) { + const [providerId] = Array.from(nextProviderIds); + this.runWithProfile(providerId, () => { this.refreshOnlineModels().catch(e => this.logger.error('Failed to refresh online models', e) ); - } - } else { - this.factory.unregister(this); + }); } } diff --git a/packages/backend/server/src/plugins/copilot/providers/utils.ts b/packages/backend/server/src/plugins/copilot/providers/utils.ts index a8b3dabe80..bb95a98b64 100644 --- a/packages/backend/server/src/plugins/copilot/providers/utils.ts +++ b/packages/backend/server/src/plugins/copilot/providers/utils.ts @@ -91,7 +91,9 @@ export async function chatToGPTMessage( // so we need to use base64 encoded attachments instead useBase64Attachment: boolean = false ): Promise<[string | undefined, ChatMessage[], ZodType?]> { - const system = messages[0]?.role === 'system' ? messages.shift() : undefined; + const hasSystem = messages[0]?.role === 'system'; + const system = hasSystem ? messages[0] : undefined; + const normalizedMessages = hasSystem ? messages.slice(1) : messages; const schema = system?.params?.schema && system.params.schema instanceof ZodType ? system.params.schema @@ -99,7 +101,7 @@ export async function chatToGPTMessage( // filter redundant fields const msgs: ChatMessage[] = []; - for (let { role, content, attachments, params } of messages.filter( + for (let { role, content, attachments, params } of normalizedMessages.filter( m => m.role !== 'system' )) { content = content.trim(); @@ -406,6 +408,34 @@ export class CitationParser { } } +export type CitationIndexedEvent = { + type: 'citation'; + index: number; + url: string; +}; + +export class CitationFootnoteFormatter { + private readonly citations = new Map(); + + public consume(event: CitationIndexedEvent) { + if (event.type !== 'citation') { + return ''; + } + this.citations.set(event.index, event.url); + return ''; + } + + public end() { + const footnotes = Array.from(this.citations.entries()) + .sort((a, b) => a[0] - b[0]) + .map( + ([index, citation]) => + `[^${index}]: {"type":"url","url":"${encodeURIComponent(citation)}"}` + ); + return footnotes.join('\n'); + } +} + type ChunkType = TextStreamPart['type']; export function toError(error: unknown): Error { @@ -703,21 +733,39 @@ export const VertexModelListSchema = z.object({ ), }); +function normalizeUrl(baseURL?: string) { + if (!baseURL?.trim()) { + return undefined; + } + try { + const url = new URL(baseURL); + const serialized = url.toString(); + if (serialized.endsWith('/')) return serialized.slice(0, -1); + return serialized; + } catch { + return undefined; + } +} + +export function getVertexAnthropicBaseUrl( + options: GoogleVertexAnthropicProviderSettings +) { + const normalizedBaseUrl = normalizeUrl(options.baseURL); + if (normalizedBaseUrl) return normalizedBaseUrl; + const { location, project } = options; + if (!location || !project) return undefined; + return `https://${location}-aiplatform.googleapis.com/v1/projects/${project}/locations/${location}/publishers/anthropic`; +} + export async function getGoogleAuth( options: GoogleVertexAnthropicProviderSettings | GoogleVertexProviderSettings, publisher: 'anthropic' | 'google' ) { function getBaseUrl() { - const { baseURL, location } = options; - if (baseURL?.trim()) { - try { - const url = new URL(baseURL); - if (url.pathname.endsWith('/')) { - url.pathname = url.pathname.slice(0, -1); - } - return url.toString(); - } catch {} - } else if (location) { + const normalizedBaseUrl = normalizeUrl(options.baseURL); + if (normalizedBaseUrl) return normalizedBaseUrl; + const { location } = options; + if (location) { return `https://${location}-aiplatform.googleapis.com/v1beta1/publishers/${publisher}`; } return undefined; diff --git a/packages/backend/server/src/plugins/copilot/resolver.ts b/packages/backend/server/src/plugins/copilot/resolver.ts index 2dc036610c..73d1807e85 100644 --- a/packages/backend/server/src/plugins/copilot/resolver.ts +++ b/packages/backend/server/src/plugins/copilot/resolver.ts @@ -4,7 +4,6 @@ import { BadRequestException, NotFoundException } from '@nestjs/common'; import { Args, Field, - Float, ID, InputType, Mutation, @@ -15,7 +14,6 @@ import { ResolveField, Resolver, } from '@nestjs/graphql'; -import { AiPromptRole } from '@prisma/client'; import { GraphQLJSON, SafeIntResolver } from 'graphql-scalars'; import GraphQLUpload from 'graphql-upload/GraphQLUpload.mjs'; @@ -313,57 +311,6 @@ class CopilotQuotaType { used!: number; } -registerEnumType(AiPromptRole, { - name: 'CopilotPromptMessageRole', -}); - -@InputType('CopilotPromptConfigInput') -@ObjectType() -class CopilotPromptConfigType { - @Field(() => Float, { nullable: true }) - frequencyPenalty!: number | null; - - @Field(() => Float, { nullable: true }) - presencePenalty!: number | null; - - @Field(() => Float, { nullable: true }) - temperature!: number | null; - - @Field(() => Float, { nullable: true }) - topP!: number | null; -} - -@InputType('CopilotPromptMessageInput') -@ObjectType() -class CopilotPromptMessageType { - @Field(() => AiPromptRole) - role!: AiPromptRole; - - @Field(() => String) - content!: string; - - @Field(() => GraphQLJSON, { nullable: true }) - params!: Record | null; -} - -@ObjectType() -class CopilotPromptType { - @Field(() => String) - name!: string; - - @Field(() => String) - model!: string; - - @Field(() => String, { nullable: true }) - action!: string | null; - - @Field(() => CopilotPromptConfigType, { nullable: true }) - config!: CopilotPromptConfigType | null; - - @Field(() => [CopilotPromptMessageType]) - messages!: CopilotPromptMessageType[]; -} - @ObjectType() class CopilotModelType { @Field(() => String) @@ -638,13 +585,8 @@ export class CopilotResolver { ); } - @Mutation(() => String, { - description: 'Create a chat session', - }) - @CallMetric('ai', 'chat_session_create') - async createCopilotSession( - @CurrentUser() user: CurrentUser, - @Args({ name: 'options', type: () => CreateChatSessionInput }) + private async createCopilotSessionInternal( + user: CurrentUser, options: CreateChatSessionInput ): Promise { // permission check based on session type @@ -666,6 +608,42 @@ export class CopilotResolver { }); } + @Mutation(() => String, { + description: 'Create a chat session', + deprecationReason: 'use `createCopilotSessionWithHistory` instead', + }) + @CallMetric('ai', 'chat_session_create') + async createCopilotSession( + @CurrentUser() user: CurrentUser, + @Args({ name: 'options', type: () => CreateChatSessionInput }) + options: CreateChatSessionInput + ): Promise { + return await this.createCopilotSessionInternal(user, options); + } + + @Mutation(() => CopilotHistoriesType, { + description: 'Create a chat session and return full session payload', + }) + @CallMetric('ai', 'chat_session_create_with_history') + async createCopilotSessionWithHistory( + @CurrentUser() user: CurrentUser, + @Args({ name: 'options', type: () => CreateChatSessionInput }) + options: CreateChatSessionInput + ): Promise { + const sessionId = await this.createCopilotSessionInternal(user, options); + const session = await this.chatSession.getSessionInfo(sessionId); + if (!session) { + throw new NotFoundException('Session not found'); + } + return { + ...session, + messages: session.messages.map(message => ({ + ...message, + id: message.id, + })) as ChatMessageType[], + }; + } + @Mutation(() => String, { description: 'Update a chat session', }) @@ -939,31 +917,10 @@ export class UserCopilotResolver { } } -@InputType() -class CreateCopilotPromptInput { - @Field(() => String) - name!: string; - - @Field(() => String) - model!: string; - - @Field(() => String, { nullable: true }) - action!: string | null; - - @Field(() => CopilotPromptConfigType, { nullable: true }) - config!: CopilotPromptConfigType | null; - - @Field(() => [CopilotPromptMessageType]) - messages!: CopilotPromptMessageType[]; -} - @Admin() @Resolver(() => String) export class PromptsManagementResolver { - constructor( - private readonly cron: CopilotCronJobs, - private readonly promptService: PromptService - ) {} + constructor(private readonly cron: CopilotCronJobs) {} @Mutation(() => Boolean, { description: 'Trigger generate missing titles cron job', @@ -980,48 +937,4 @@ export class PromptsManagementResolver { await this.cron.triggerCleanupTrashedDocEmbeddings(); return true; } - - @Query(() => [CopilotPromptType], { - description: 'List all copilot prompts', - }) - async listCopilotPrompts() { - const prompts = await this.promptService.list(); - return prompts.filter( - p => - p.messages.length > 0 && - // ignore internal prompts - !p.name.startsWith('workflow:') && - !p.name.startsWith('debug:') && - !p.name.startsWith('chat:') && - !p.name.startsWith('action:') - ); - } - - @Mutation(() => CopilotPromptType, { - description: 'Create a copilot prompt', - }) - async createCopilotPrompt( - @Args({ type: () => CreateCopilotPromptInput, name: 'input' }) - input: CreateCopilotPromptInput - ) { - await this.promptService.set( - input.name, - input.model, - input.messages, - input.config - ); - return this.promptService.get(input.name); - } - - @Mutation(() => CopilotPromptType, { - description: 'Update a copilot prompt', - }) - async updateCopilotPrompt( - @Args('name') name: string, - @Args('messages', { type: () => [CopilotPromptMessageType] }) - messages: CopilotPromptMessageType[] - ) { - await this.promptService.update(name, { messages, modified: true }); - return this.promptService.get(name); - } } diff --git a/packages/backend/server/src/plugins/copilot/session.ts b/packages/backend/server/src/plugins/copilot/session.ts index 9014620421..36b0ea669e 100644 --- a/packages/backend/server/src/plugins/copilot/session.ts +++ b/packages/backend/server/src/plugins/copilot/session.ts @@ -7,6 +7,7 @@ import { AiPromptRole } from '@prisma/client'; import { pick } from 'lodash-es'; import { + Config, CopilotActionTaken, CopilotMessageNotFound, CopilotPromptNotFound, @@ -31,6 +32,7 @@ import { ChatMessageCache } from './message'; import { ChatPrompt } from './prompt/chat-prompt'; import { PromptService } from './prompt/service'; import { CopilotProviderFactory } from './providers/factory'; +import { buildProviderRegistry } from './providers/provider-registry'; import { ModelOutputType, type PromptMessage, @@ -105,10 +107,31 @@ export class ChatSession implements AsyncDisposable { hasPayment: boolean, requestedModelId?: string ): Promise { + const config = this.moduleRef.get(Config, { strict: false }); + const registry = config + ? buildProviderRegistry(config.copilot.providers) + : null; const defaultModel = this.model; - const normalize = (m?: string) => - !!m && this.optionalModels.includes(m) ? m : defaultModel; - const isPro = (m?: string) => !!m && this.proModels.includes(m); + const normalizeModel = (modelId?: string) => { + if (!modelId) return modelId; + const separatorIndex = modelId.indexOf('/'); + if (separatorIndex <= 0) return modelId; + const providerId = modelId.slice(0, separatorIndex); + if (!registry?.profiles.has(providerId)) return modelId; + return modelId.slice(separatorIndex + 1); + }; + const inModelList = (models: string[], modelId?: string) => { + if (!modelId) return false; + return ( + models.includes(modelId) || + models.includes(normalizeModel(modelId) ?? '') + ); + }; + const normalize = (m?: string) => { + if (inModelList(this.optionalModels, m)) return m; + return defaultModel; + }; + const isPro = (m?: string) => inModelList(this.proModels, m); // try resolve payment subscription service lazily let paymentEnabled = hasPayment; @@ -132,10 +155,19 @@ export class ChatSession implements AsyncDisposable { } if (paymentEnabled && !isUserAIPro && isPro(requestedModelId)) { + if (!defaultModel) { + throw new CopilotSessionInvalidInput( + 'Model is required for AI subscription fallback' + ); + } return defaultModel; } - return normalize(requestedModelId); + const resolvedModel = normalize(requestedModelId); + if (!resolvedModel) { + throw new CopilotSessionInvalidInput('Model is required'); + } + return resolvedModel; } push(message: ChatMessage) { diff --git a/packages/backend/server/src/plugins/copilot/tools/blob-read.ts b/packages/backend/server/src/plugins/copilot/tools/blob-read.ts index 1a556010c3..b331b98a44 100644 --- a/packages/backend/server/src/plugins/copilot/tools/blob-read.ts +++ b/packages/backend/server/src/plugins/copilot/tools/blob-read.ts @@ -32,16 +32,22 @@ export const buildBlobContentGetter = ( return; } + const contextFile = context.files.find( + file => file.blobId === blobId || file.id === blobId + ); + const canonicalBlobId = contextFile?.blobId ?? blobId; + const targetFileId = contextFile?.id; const [file, blob] = await Promise.all([ - context?.getFileContent(blobId, chunk), - context?.getBlobContent(blobId, chunk), + targetFileId ? context.getFileContent(targetFileId, chunk) : undefined, + context.getBlobContent(canonicalBlobId, chunk), ]); const content = file?.trim() || blob?.trim(); - if (!content) { - return; - } + if (!content) return; + const info = contextFile + ? { fileName: contextFile.name, fileType: contextFile.mimeType } + : {}; - return { blobId, chunk, content }; + return { blobId: canonicalBlobId, chunk, content, ...info }; }; return getBlobContent; }; diff --git a/packages/backend/server/src/plugins/worker/controller.ts b/packages/backend/server/src/plugins/worker/controller.ts index ed2e849d22..e7f89114a9 100644 --- a/packages/backend/server/src/plugins/worker/controller.ts +++ b/packages/backend/server/src/plugins/worker/controller.ts @@ -14,6 +14,7 @@ import type { import { HTMLRewriter } from 'htmlrewriter'; import { + applyAttachHeaders, BadRequest, Cache, readResponseBufferWithLimit, @@ -127,15 +128,18 @@ export class WorkerController { if (buffer.length === 0) { return resp.status(404).header(getCorsHeaders(origin)).send(); } - return resp - .status(200) - .header({ - ...getCorsHeaders(origin), - ...(origin ? { Vary: 'Origin' } : {}), - 'Access-Control-Allow-Methods': 'GET', - 'Content-Type': 'image/*', - }) - .send(buffer); + resp.header({ + ...getCorsHeaders(origin), + ...(origin ? { Vary: 'Origin' } : {}), + 'Access-Control-Allow-Methods': 'GET', + }); + applyAttachHeaders(resp, { buffer }); + const contentType = resp.getHeader('Content-Type') as string | undefined; + if (contentType?.startsWith('image/')) { + return resp.status(200).send(buffer); + } else { + throw new BadRequest('Invalid content type'); + } } let response: Response; @@ -171,39 +175,39 @@ export class WorkerController { throw new BadRequest('Failed to fetch image'); } if (response.ok) { - const contentType = response.headers.get('Content-Type'); - if (contentType?.startsWith('image/')) { - let buffer: Buffer; - try { - buffer = await readResponseBufferWithLimit( - response, - IMAGE_PROXY_MAX_BYTES - ); - } catch (error) { - if (error instanceof ResponseTooLargeError) { - this.logger.warn('Image proxy response too large', { - url: imageURL, - limitBytes: error.data?.limitBytes, - receivedBytes: error.data?.receivedBytes, - }); - throw new BadRequest('Response too large'); - } - throw error; + let buffer: Buffer; + try { + buffer = await readResponseBufferWithLimit( + response, + IMAGE_PROXY_MAX_BYTES + ); + } catch (error) { + if (error instanceof ResponseTooLargeError) { + this.logger.warn('Image proxy response too large', { + url: imageURL, + limitBytes: error.data?.limitBytes, + receivedBytes: error.data?.receivedBytes, + }); + throw new BadRequest('Response too large'); } - await this.cache.set(cachedUrl, buffer.toString('base64'), { - ttl: CACHE_TTL, - }); - const contentDisposition = response.headers.get('Content-Disposition'); - return resp - .status(200) - .header({ - ...getCorsHeaders(origin), - ...(origin ? { Vary: 'Origin' } : {}), - 'Access-Control-Allow-Methods': 'GET', - 'Content-Type': contentType, - 'Content-Disposition': contentDisposition, - }) - .send(buffer); + throw error; + } + await this.cache.set(cachedUrl, buffer.toString('base64'), { + ttl: CACHE_TTL, + }); + const contentDisposition = response.headers.get('Content-Disposition'); + resp.header({ + ...getCorsHeaders(origin), + ...(origin ? { Vary: 'Origin' } : {}), + 'Access-Control-Allow-Methods': 'GET', + }); + if (contentDisposition) { + resp.setHeader('Content-Disposition', contentDisposition); + } + applyAttachHeaders(resp, { buffer }); + const contentType = resp.getHeader('Content-Type') as string | undefined; + if (contentType?.startsWith('image/')) { + return resp.status(200).send(buffer); } else { throw new BadRequest('Invalid content type'); } diff --git a/packages/backend/server/src/schema.gql b/packages/backend/server/src/schema.gql index b1874bb303..79e1fb8033 100644 --- a/packages/backend/server/src/schema.gql +++ b/packages/backend/server/src/schema.gql @@ -607,50 +607,10 @@ type CopilotModelsType { proModels: [CopilotModelType!]! } -input CopilotPromptConfigInput { - frequencyPenalty: Float - presencePenalty: Float - temperature: Float - topP: Float -} - -type CopilotPromptConfigType { - frequencyPenalty: Float - presencePenalty: Float - temperature: Float - topP: Float -} - -input CopilotPromptMessageInput { - content: String! - params: JSON - role: CopilotPromptMessageRole! -} - -enum CopilotPromptMessageRole { - assistant - system - user -} - -type CopilotPromptMessageType { - content: String! - params: JSON - role: CopilotPromptMessageRole! -} - type CopilotPromptNotFoundDataType { name: String! } -type CopilotPromptType { - action: String - config: CopilotPromptConfigType - messages: [CopilotPromptMessageType!]! - model: String! - name: String! -} - type CopilotProviderNotSupportedDataType { kind: String! provider: String! @@ -747,14 +707,6 @@ input CreateCheckoutSessionInput { variant: SubscriptionVariant } -input CreateCopilotPromptInput { - action: String - config: CopilotPromptConfigInput - messages: [CopilotPromptMessageInput!]! - model: String! - name: String! -} - input CreateUserInput { email: String! name: String @@ -1551,11 +1503,11 @@ type Mutation { """Create a chat message""" createCopilotMessage(options: CreateChatMessageInput!): String! - """Create a copilot prompt""" - createCopilotPrompt(input: CreateCopilotPromptInput!): CopilotPromptType! - """Create a chat session""" - createCopilotSession(options: CreateChatSessionInput!): String! + createCopilotSession(options: CreateChatSessionInput!): String! @deprecated(reason: "use `createCopilotSessionWithHistory` instead") + + """Create a chat session and return full session payload""" + createCopilotSessionWithHistory(options: CreateChatSessionInput!): CopilotHistories! """Create a stripe customer portal to manage payment methods""" createCustomerPortal: String! @@ -1672,9 +1624,6 @@ type Mutation { """Update a comment content""" updateComment(input: CommentUpdateInput!): Boolean! - """Update a copilot prompt""" - updateCopilotPrompt(messages: [CopilotPromptMessageInput!]!, name: String!): CopilotPromptType! - """Update a chat session""" updateCopilotSession(options: UpdateChatSessionInput!): String! updateDocDefaultRole(input: UpdateDocDefaultRoleInput!): Boolean! @@ -1923,9 +1872,6 @@ type Query { """get workspace invitation info""" getInviteInfo(inviteId: String!): InvitationType! - - """List all copilot prompts""" - listCopilotPrompts: [CopilotPromptType!]! prices: [SubscriptionPrice!]! """Get public user by id""" diff --git a/packages/common/graphql/src/graphql/admin/copilot-prompt-list.gql b/packages/common/graphql/src/graphql/admin/copilot-prompt-list.gql deleted file mode 100644 index 59a9bb5678..0000000000 --- a/packages/common/graphql/src/graphql/admin/copilot-prompt-list.gql +++ /dev/null @@ -1,18 +0,0 @@ -query getPrompts { - listCopilotPrompts { - name - model - action - config { - frequencyPenalty - presencePenalty - temperature - topP - } - messages { - role - content - params - } - } -} diff --git a/packages/common/graphql/src/graphql/admin/copilot-prompt-update.gql b/packages/common/graphql/src/graphql/admin/copilot-prompt-update.gql deleted file mode 100644 index a0795eeb66..0000000000 --- a/packages/common/graphql/src/graphql/admin/copilot-prompt-update.gql +++ /dev/null @@ -1,21 +0,0 @@ -mutation updatePrompt( - $name: String! - $messages: [CopilotPromptMessageInput!]! -) { - updateCopilotPrompt(name: $name, messages: $messages) { - name - model - action - config { - frequencyPenalty - presencePenalty - temperature - topP - } - messages { - role - content - params - } - } -} diff --git a/packages/common/graphql/src/graphql/copilot-history-list-doc-sessions.gql b/packages/common/graphql/src/graphql/copilot-history-list-doc-sessions.gql index 31dc7bd097..6624d29611 100644 --- a/packages/common/graphql/src/graphql/copilot-history-list-doc-sessions.gql +++ b/packages/common/graphql/src/graphql/copilot-history-list-doc-sessions.gql @@ -1,4 +1,4 @@ -#import "./fragments/copilot.gql" +#import "./fragments/paginated-copilot-chats.gql" query getCopilotDocSessions( $workspaceId: String! diff --git a/packages/common/graphql/src/graphql/copilot-history-list-pinned-session.gql b/packages/common/graphql/src/graphql/copilot-history-list-pinned-session.gql index 19aac215cf..9373957d87 100644 --- a/packages/common/graphql/src/graphql/copilot-history-list-pinned-session.gql +++ b/packages/common/graphql/src/graphql/copilot-history-list-pinned-session.gql @@ -1,4 +1,4 @@ -#import "./fragments/copilot.gql" +#import "./fragments/paginated-copilot-chats.gql" query getCopilotPinnedSessions( $workspaceId: String! diff --git a/packages/common/graphql/src/graphql/copilot-history-list-workspace-sessions.gql b/packages/common/graphql/src/graphql/copilot-history-list-workspace-sessions.gql index aeaddf21fa..59a76862b3 100644 --- a/packages/common/graphql/src/graphql/copilot-history-list-workspace-sessions.gql +++ b/packages/common/graphql/src/graphql/copilot-history-list-workspace-sessions.gql @@ -1,4 +1,4 @@ -#import "./fragments/copilot.gql" +#import "./fragments/paginated-copilot-chats.gql" query getCopilotWorkspaceSessions( $workspaceId: String! diff --git a/packages/common/graphql/src/graphql/copilot-history-list.gql b/packages/common/graphql/src/graphql/copilot-history-list.gql index cc2708e50a..79cd0ddb08 100644 --- a/packages/common/graphql/src/graphql/copilot-history-list.gql +++ b/packages/common/graphql/src/graphql/copilot-history-list.gql @@ -1,4 +1,4 @@ -#import "./fragments/copilot.gql" +#import "./fragments/paginated-copilot-chats.gql" query getCopilotHistories( $workspaceId: String! diff --git a/packages/common/graphql/src/graphql/copilot-session-create-with-history.gql b/packages/common/graphql/src/graphql/copilot-session-create-with-history.gql new file mode 100644 index 0000000000..83977fc6be --- /dev/null +++ b/packages/common/graphql/src/graphql/copilot-session-create-with-history.gql @@ -0,0 +1,7 @@ +#import "./fragments/copilot-chat-history.gql" + +mutation createCopilotSessionWithHistory($options: CreateChatSessionInput!) { + createCopilotSessionWithHistory(options: $options) { + ...CopilotChatHistory + } +} diff --git a/packages/common/graphql/src/graphql/copilot-session-get-latest-doc.gql b/packages/common/graphql/src/graphql/copilot-session-get-latest-doc.gql index 382c1f6ee8..3698aab852 100644 --- a/packages/common/graphql/src/graphql/copilot-session-get-latest-doc.gql +++ b/packages/common/graphql/src/graphql/copilot-session-get-latest-doc.gql @@ -1,4 +1,4 @@ -#import "./fragments/copilot.gql" +#import "./fragments/paginated-copilot-chats.gql" query getCopilotLatestDocSession( $workspaceId: String! diff --git a/packages/common/graphql/src/graphql/copilot-session-get.gql b/packages/common/graphql/src/graphql/copilot-session-get.gql index 129dc109af..9bf014245e 100644 --- a/packages/common/graphql/src/graphql/copilot-session-get.gql +++ b/packages/common/graphql/src/graphql/copilot-session-get.gql @@ -1,4 +1,4 @@ -#import "./fragments/copilot.gql" +#import "./fragments/paginated-copilot-chats.gql" query getCopilotSession( $workspaceId: String! diff --git a/packages/common/graphql/src/graphql/copilot-session-list-recent.gql b/packages/common/graphql/src/graphql/copilot-session-list-recent.gql index 515dbccc53..bbc0ae9c96 100644 --- a/packages/common/graphql/src/graphql/copilot-session-list-recent.gql +++ b/packages/common/graphql/src/graphql/copilot-session-list-recent.gql @@ -1,4 +1,4 @@ -#import "./fragments/copilot.gql" +#import "./fragments/paginated-copilot-chats.gql" query getCopilotRecentSessions( $workspaceId: String! diff --git a/packages/common/graphql/src/graphql/copilot-sessions-get.gql b/packages/common/graphql/src/graphql/copilot-sessions-get.gql index 8ec80bfc4e..0ef89c6aef 100644 --- a/packages/common/graphql/src/graphql/copilot-sessions-get.gql +++ b/packages/common/graphql/src/graphql/copilot-sessions-get.gql @@ -1,4 +1,4 @@ -#import "./fragments/copilot.gql" +#import "./fragments/paginated-copilot-chats.gql" query getCopilotSessions( $workspaceId: String! diff --git a/packages/common/graphql/src/graphql/fragments/copilot-chat-history.gql b/packages/common/graphql/src/graphql/fragments/copilot-chat-history.gql new file mode 100644 index 0000000000..eed7dc06f9 --- /dev/null +++ b/packages/common/graphql/src/graphql/fragments/copilot-chat-history.gql @@ -0,0 +1,30 @@ +fragment CopilotChatHistory on CopilotHistories { + sessionId + workspaceId + docId + parentSessionId + promptName + model + optionalModels + action + pinned + title + tokens + messages { + id + role + content + attachments + streamObjects { + type + textDelta + toolCallId + toolName + args + result + } + createdAt + } + createdAt + updatedAt +} diff --git a/packages/common/graphql/src/graphql/fragments/copilot.gql b/packages/common/graphql/src/graphql/fragments/copilot.gql deleted file mode 100644 index 3884cdcd0c..0000000000 --- a/packages/common/graphql/src/graphql/fragments/copilot.gql +++ /dev/null @@ -1,49 +0,0 @@ -fragment CopilotChatMessage on ChatMessage { - id - role - content - attachments - streamObjects { - type - textDelta - toolCallId - toolName - args - result - } - createdAt -} - -fragment CopilotChatHistory on CopilotHistories { - sessionId - workspaceId - docId - parentSessionId - promptName - model - optionalModels - action - pinned - title - tokens - messages { - ...CopilotChatMessage - } - createdAt - updatedAt -} - -fragment PaginatedCopilotChats on PaginatedCopilotHistoriesType { - pageInfo { - hasNextPage - hasPreviousPage - startCursor - endCursor - } - edges { - cursor - node { - ...CopilotChatHistory - } - } -} diff --git a/packages/common/graphql/src/graphql/fragments/paginated-copilot-chats.gql b/packages/common/graphql/src/graphql/fragments/paginated-copilot-chats.gql new file mode 100644 index 0000000000..37ed361dd7 --- /dev/null +++ b/packages/common/graphql/src/graphql/fragments/paginated-copilot-chats.gql @@ -0,0 +1,16 @@ +#import "./copilot-chat-history.gql" + +fragment PaginatedCopilotChats on PaginatedCopilotHistoriesType { + pageInfo { + hasNextPage + hasPreviousPage + startCursor + endCursor + } + edges { + cursor + node { + ...CopilotChatHistory + } + } +} diff --git a/packages/common/graphql/src/graphql/index.ts b/packages/common/graphql/src/graphql/index.ts index 74647207bf..08a2c284d4 100644 --- a/packages/common/graphql/src/graphql/index.ts +++ b/packages/common/graphql/src/graphql/index.ts @@ -6,21 +6,6 @@ export interface GraphQLQuery { file?: boolean; deprecations?: string[]; } -export const copilotChatMessageFragment = `fragment CopilotChatMessage on ChatMessage { - id - role - content - attachments - streamObjects { - type - textDelta - toolCallId - toolName - args - result - } - createdAt -}`; export const copilotChatHistoryFragment = `fragment CopilotChatHistory on CopilotHistories { sessionId workspaceId @@ -34,25 +19,23 @@ export const copilotChatHistoryFragment = `fragment CopilotChatHistory on Copilo title tokens messages { - ...CopilotChatMessage + id + role + content + attachments + streamObjects { + type + textDelta + toolCallId + toolName + args + result + } + createdAt } createdAt updatedAt }`; -export const paginatedCopilotChatsFragment = `fragment PaginatedCopilotChats on PaginatedCopilotHistoriesType { - pageInfo { - hasNextPage - hasPreviousPage - startCursor - endCursor - } - edges { - cursor - node { - ...CopilotChatHistory - } - } -}`; export const credentialsRequirementsFragment = `fragment CredentialsRequirements on CredentialsRequirementType { password { ...PasswordLimits @@ -94,6 +77,20 @@ export const currentUserProfileFragment = `fragment CurrentUserProfile on UserTy } } }`; +export const paginatedCopilotChatsFragment = `fragment PaginatedCopilotChats on PaginatedCopilotHistoriesType { + pageInfo { + hasNextPage + hasPreviousPage + startCursor + endCursor + } + edges { + cursor + node { + ...CopilotChatHistory + } + } +}${copilotChatHistoryFragment}`; export const passwordLimitsFragment = `fragment PasswordLimits on PasswordLimitsType { minLength maxLength @@ -404,52 +401,6 @@ export const appConfigQuery = { }`, }; -export const getPromptsQuery = { - id: 'getPromptsQuery' as const, - op: 'getPrompts', - query: `query getPrompts { - listCopilotPrompts { - name - model - action - config { - frequencyPenalty - presencePenalty - temperature - topP - } - messages { - role - content - params - } - } -}`, -}; - -export const updatePromptMutation = { - id: 'updatePromptMutation' as const, - op: 'updatePrompt', - query: `mutation updatePrompt($name: String!, $messages: [CopilotPromptMessageInput!]!) { - updateCopilotPrompt(name: $name, messages: $messages) { - name - model - action - config { - frequencyPenalty - presencePenalty - temperature - topP - } - messages { - role - content - params - } - } -}`, -}; - export const createUserMutation = { id: 'createUserMutation' as const, op: 'createUser', @@ -1411,8 +1362,6 @@ export const getCopilotDocSessionsQuery = { } } } -${copilotChatMessageFragment} -${copilotChatHistoryFragment} ${paginatedCopilotChatsFragment}`, }; @@ -1432,8 +1381,6 @@ export const getCopilotPinnedSessionsQuery = { } } } -${copilotChatMessageFragment} -${copilotChatHistoryFragment} ${paginatedCopilotChatsFragment}`, }; @@ -1449,8 +1396,6 @@ export const getCopilotWorkspaceSessionsQuery = { } } } -${copilotChatMessageFragment} -${copilotChatHistoryFragment} ${paginatedCopilotChatsFragment}`, }; @@ -1466,8 +1411,6 @@ export const getCopilotHistoriesQuery = { } } } -${copilotChatMessageFragment} -${copilotChatHistoryFragment} ${paginatedCopilotChatsFragment}`, }; @@ -1596,12 +1539,24 @@ export const cleanupCopilotSessionMutation = { }`, }; +export const createCopilotSessionWithHistoryMutation = { + id: 'createCopilotSessionWithHistoryMutation' as const, + op: 'createCopilotSessionWithHistory', + query: `mutation createCopilotSessionWithHistory($options: CreateChatSessionInput!) { + createCopilotSessionWithHistory(options: $options) { + ...CopilotChatHistory + } +} +${copilotChatHistoryFragment}`, +}; + export const createCopilotSessionMutation = { id: 'createCopilotSessionMutation' as const, op: 'createCopilotSession', query: `mutation createCopilotSession($options: CreateChatSessionInput!) { createCopilotSession(options: $options) }`, + deprecations: ["'createCopilotSession' is deprecated: use `createCopilotSessionWithHistory` instead"], }; export const forkCopilotSessionMutation = { @@ -1628,8 +1583,6 @@ export const getCopilotLatestDocSessionQuery = { } } } -${copilotChatMessageFragment} -${copilotChatHistoryFragment} ${paginatedCopilotChatsFragment}`, }; @@ -1645,8 +1598,6 @@ export const getCopilotSessionQuery = { } } } -${copilotChatMessageFragment} -${copilotChatHistoryFragment} ${paginatedCopilotChatsFragment}`, }; @@ -1665,8 +1616,6 @@ export const getCopilotRecentSessionsQuery = { } } } -${copilotChatMessageFragment} -${copilotChatHistoryFragment} ${paginatedCopilotChatsFragment}`, }; @@ -1690,8 +1639,6 @@ export const getCopilotSessionsQuery = { } } } -${copilotChatMessageFragment} -${copilotChatHistoryFragment} ${paginatedCopilotChatsFragment}`, }; diff --git a/packages/common/graphql/src/schema.ts b/packages/common/graphql/src/schema.ts index f11bfbad85..e707e9e6f7 100644 --- a/packages/common/graphql/src/schema.ts +++ b/packages/common/graphql/src/schema.ts @@ -725,54 +725,11 @@ export interface CopilotModelsType { proModels: Array; } -export interface CopilotPromptConfigInput { - frequencyPenalty?: InputMaybe; - presencePenalty?: InputMaybe; - temperature?: InputMaybe; - topP?: InputMaybe; -} - -export interface CopilotPromptConfigType { - __typename?: 'CopilotPromptConfigType'; - frequencyPenalty: Maybe; - presencePenalty: Maybe; - temperature: Maybe; - topP: Maybe; -} - -export interface CopilotPromptMessageInput { - content: Scalars['String']['input']; - params?: InputMaybe; - role: CopilotPromptMessageRole; -} - -export enum CopilotPromptMessageRole { - assistant = 'assistant', - system = 'system', - user = 'user', -} - -export interface CopilotPromptMessageType { - __typename?: 'CopilotPromptMessageType'; - content: Scalars['String']['output']; - params: Maybe; - role: CopilotPromptMessageRole; -} - export interface CopilotPromptNotFoundDataType { __typename?: 'CopilotPromptNotFoundDataType'; name: Scalars['String']['output']; } -export interface CopilotPromptType { - __typename?: 'CopilotPromptType'; - action: Maybe; - config: Maybe; - messages: Array; - model: Scalars['String']['output']; - name: Scalars['String']['output']; -} - export interface CopilotProviderNotSupportedDataType { __typename?: 'CopilotProviderNotSupportedDataType'; kind: Scalars['String']['output']; @@ -884,14 +841,6 @@ export interface CreateCheckoutSessionInput { variant?: InputMaybe; } -export interface CreateCopilotPromptInput { - action?: InputMaybe; - config?: InputMaybe; - messages: Array; - model: Scalars['String']['input']; - name: Scalars['String']['input']; -} - export interface CreateUserInput { email: Scalars['String']['input']; name?: InputMaybe; @@ -1752,10 +1701,13 @@ export interface Mutation { createCopilotContext: Scalars['String']['output']; /** Create a chat message */ createCopilotMessage: Scalars['String']['output']; - /** Create a copilot prompt */ - createCopilotPrompt: CopilotPromptType; - /** Create a chat session */ + /** + * Create a chat session + * @deprecated use `createCopilotSessionWithHistory` instead + */ createCopilotSession: Scalars['String']['output']; + /** Create a chat session and return full session payload */ + createCopilotSessionWithHistory: CopilotHistories; /** Create a stripe customer portal to manage payment methods */ createCustomerPortal: Scalars['String']['output']; createInviteLink: InviteLink; @@ -1845,8 +1797,6 @@ export interface Mutation { updateCalendarAccount: Maybe; /** Update a comment content */ updateComment: Scalars['Boolean']['output']; - /** Update a copilot prompt */ - updateCopilotPrompt: CopilotPromptType; /** Update a chat session */ updateCopilotSession: Scalars['String']['output']; updateDocDefaultRole: Scalars['Boolean']['output']; @@ -1998,11 +1948,11 @@ export interface MutationCreateCopilotMessageArgs { options: CreateChatMessageInput; } -export interface MutationCreateCopilotPromptArgs { - input: CreateCopilotPromptInput; +export interface MutationCreateCopilotSessionArgs { + options: CreateChatSessionInput; } -export interface MutationCreateCopilotSessionArgs { +export interface MutationCreateCopilotSessionWithHistoryArgs { options: CreateChatSessionInput; } @@ -2262,11 +2212,6 @@ export interface MutationUpdateCommentArgs { input: CommentUpdateInput; } -export interface MutationUpdateCopilotPromptArgs { - messages: Array; - name: Scalars['String']['input']; -} - export interface MutationUpdateCopilotSessionArgs { options: UpdateChatSessionInput; } @@ -2554,8 +2499,6 @@ export interface Query { error: ErrorDataUnion; /** get workspace invitation info */ getInviteInfo: InvitationType; - /** List all copilot prompts */ - listCopilotPrompts: Array; prices: Array; /** Get public user by id */ publicUserById: Maybe; @@ -3886,59 +3829,6 @@ export type AppConfigQueryVariables = Exact<{ [key: string]: never }>; export type AppConfigQuery = { __typename?: 'Query'; appConfig: any }; -export type GetPromptsQueryVariables = Exact<{ [key: string]: never }>; - -export type GetPromptsQuery = { - __typename?: 'Query'; - listCopilotPrompts: Array<{ - __typename?: 'CopilotPromptType'; - name: string; - model: string; - action: string | null; - config: { - __typename?: 'CopilotPromptConfigType'; - frequencyPenalty: number | null; - presencePenalty: number | null; - temperature: number | null; - topP: number | null; - } | null; - messages: Array<{ - __typename?: 'CopilotPromptMessageType'; - role: CopilotPromptMessageRole; - content: string; - params: Record | null; - }>; - }>; -}; - -export type UpdatePromptMutationVariables = Exact<{ - name: Scalars['String']['input']; - messages: Array | CopilotPromptMessageInput; -}>; - -export type UpdatePromptMutation = { - __typename?: 'Mutation'; - updateCopilotPrompt: { - __typename?: 'CopilotPromptType'; - name: string; - model: string; - action: string | null; - config: { - __typename?: 'CopilotPromptConfigType'; - frequencyPenalty: number | null; - presencePenalty: number | null; - temperature: number | null; - topP: number | null; - } | null; - messages: Array<{ - __typename?: 'CopilotPromptMessageType'; - role: CopilotPromptMessageRole; - content: string; - params: Record | null; - }>; - }; -}; - export type CreateUserMutationVariables = Exact<{ input: CreateUserInput; }>; @@ -5425,6 +5315,47 @@ export type CleanupCopilotSessionMutation = { cleanupCopilotSession: Array; }; +export type CreateCopilotSessionWithHistoryMutationVariables = Exact<{ + options: CreateChatSessionInput; +}>; + +export type CreateCopilotSessionWithHistoryMutation = { + __typename?: 'Mutation'; + createCopilotSessionWithHistory: { + __typename?: 'CopilotHistories'; + sessionId: string; + workspaceId: string; + docId: string | null; + parentSessionId: string | null; + promptName: string; + model: string; + optionalModels: Array; + action: string | null; + pinned: boolean; + title: string | null; + tokens: number; + createdAt: string; + updatedAt: string; + messages: Array<{ + __typename?: 'ChatMessage'; + id: string | null; + role: string; + content: string; + attachments: Array | null; + createdAt: string; + streamObjects: Array<{ + __typename?: 'StreamObject'; + type: string; + textDelta: string | null; + toolCallId: string | null; + toolName: string | null; + args: Record | null; + result: Record | null; + }> | null; + }>; + }; +}; + export type CreateCopilotSessionMutationVariables = Exact<{ options: CreateChatSessionInput; }>; @@ -5934,24 +5865,6 @@ export type GetDocRolePermissionsQuery = { }; }; -export type CopilotChatMessageFragment = { - __typename?: 'ChatMessage'; - id: string | null; - role: string; - content: string; - attachments: Array | null; - createdAt: string; - streamObjects: Array<{ - __typename?: 'StreamObject'; - type: string; - textDelta: string | null; - toolCallId: string | null; - toolName: string | null; - args: Record | null; - result: Record | null; - }> | null; -}; - export type CopilotChatHistoryFragment = { __typename?: 'CopilotHistories'; sessionId: string; @@ -5986,6 +5899,52 @@ export type CopilotChatHistoryFragment = { }>; }; +export type CredentialsRequirementsFragment = { + __typename?: 'CredentialsRequirementType'; + password: { + __typename?: 'PasswordLimitsType'; + minLength: number; + maxLength: number; + }; +}; + +export type CurrentUserProfileFragment = { + __typename?: 'UserType'; + id: string; + name: string; + email: string; + avatarUrl: string | null; + emailVerified: boolean; + features: Array; + settings: { + __typename?: 'UserSettingsType'; + receiveInvitationEmail: boolean; + receiveMentionEmail: boolean; + receiveCommentEmail: boolean; + }; + quota: { + __typename?: 'UserQuotaType'; + name: string; + blobLimit: number; + storageQuota: number; + historyPeriod: number; + memberLimit: number; + humanReadable: { + __typename?: 'UserQuotaHumanReadableType'; + name: string; + blobLimit: string; + storageQuota: string; + historyPeriod: string; + memberLimit: string; + }; + }; + quotaUsage: { __typename?: 'UserQuotaUsageType'; storageQuota: number }; + copilot: { + __typename?: 'Copilot'; + quota: { __typename?: 'CopilotQuota'; limit: number | null; used: number }; + }; +}; + export type PaginatedCopilotChatsFragment = { __typename?: 'PaginatedCopilotHistoriesType'; pageInfo: { @@ -6034,52 +5993,6 @@ export type PaginatedCopilotChatsFragment = { }>; }; -export type CredentialsRequirementsFragment = { - __typename?: 'CredentialsRequirementType'; - password: { - __typename?: 'PasswordLimitsType'; - minLength: number; - maxLength: number; - }; -}; - -export type CurrentUserProfileFragment = { - __typename?: 'UserType'; - id: string; - name: string; - email: string; - avatarUrl: string | null; - emailVerified: boolean; - features: Array; - settings: { - __typename?: 'UserSettingsType'; - receiveInvitationEmail: boolean; - receiveMentionEmail: boolean; - receiveCommentEmail: boolean; - }; - quota: { - __typename?: 'UserQuotaType'; - name: string; - blobLimit: number; - storageQuota: number; - historyPeriod: number; - memberLimit: number; - humanReadable: { - __typename?: 'UserQuotaHumanReadableType'; - name: string; - blobLimit: string; - storageQuota: string; - historyPeriod: string; - memberLimit: string; - }; - }; - quotaUsage: { __typename?: 'UserQuotaUsageType'; storageQuota: number }; - copilot: { - __typename?: 'Copilot'; - quota: { __typename?: 'CopilotQuota'; limit: number | null; used: number }; - }; -}; - export type PasswordLimitsFragment = { __typename?: 'PasswordLimitsType'; minLength: number; @@ -7623,11 +7536,6 @@ export type Queries = variables: AppConfigQueryVariables; response: AppConfigQuery; } - | { - name: 'getPromptsQuery'; - variables: GetPromptsQueryVariables; - response: GetPromptsQuery; - } | { name: 'getUserByEmailQuery'; variables: GetUserByEmailQueryVariables; @@ -8035,11 +7943,6 @@ export type Mutations = variables: CreateChangePasswordUrlMutationVariables; response: CreateChangePasswordUrlMutation; } - | { - name: 'updatePromptMutation'; - variables: UpdatePromptMutationVariables; - response: UpdatePromptMutation; - } | { name: 'createUserMutation'; variables: CreateUserMutationVariables; @@ -8275,6 +8178,11 @@ export type Mutations = variables: CleanupCopilotSessionMutationVariables; response: CleanupCopilotSessionMutation; } + | { + name: 'createCopilotSessionWithHistoryMutation'; + variables: CreateCopilotSessionWithHistoryMutationVariables; + response: CreateCopilotSessionWithHistoryMutation; + } | { name: 'createCopilotSessionMutation'; variables: CreateCopilotSessionMutationVariables; diff --git a/packages/frontend/admin/src/config.json b/packages/frontend/admin/src/config.json index 42709642b7..687a54518d 100644 --- a/packages/frontend/admin/src/config.json +++ b/packages/frontend/admin/src/config.json @@ -313,6 +313,14 @@ "type": "Object", "desc": "Use custom models in scenarios and override default settings." }, + "providers.profiles": { + "type": "Array", + "desc": "The profile list for copilot providers." + }, + "providers.defaults": { + "type": "Object", + "desc": "The default provider ids for model output types and global fallback." + }, "providers.openai": { "type": "Object", "desc": "The config for the openai provider.", diff --git a/packages/frontend/admin/src/modules/ai/edit-prompt.tsx b/packages/frontend/admin/src/modules/ai/edit-prompt.tsx deleted file mode 100644 index 0cf9010d65..0000000000 --- a/packages/frontend/admin/src/modules/ai/edit-prompt.tsx +++ /dev/null @@ -1,146 +0,0 @@ -import { ScrollArea } from '@affine/admin/components/ui/scroll-area'; -import { Separator } from '@affine/admin/components/ui/separator'; -import { Textarea } from '@affine/admin/components/ui/textarea'; -import { useCallback, useEffect, useMemo, useState } from 'react'; - -import { RightPanelHeader } from '../header'; -import { useRightPanel } from '../panel/context'; -import type { Prompt } from './prompts'; -import { usePrompt } from './use-prompt'; - -export function EditPrompt({ - item, - setCanSave, -}: { - item: Prompt; - setCanSave: (changed: boolean) => void; -}) { - const { closePanel } = useRightPanel(); - - const [messages, setMessages] = useState(item.messages); - const { updatePrompt } = usePrompt(); - - const disableSave = useMemo( - () => JSON.stringify(messages) === JSON.stringify(item.messages), - [item.messages, messages] - ); - - const handleChange = useCallback( - (e: React.ChangeEvent, index: number) => { - const newMessages = [...messages]; - newMessages[index] = { - ...newMessages[index], - content: e.target.value, - }; - setMessages(newMessages); - setCanSave(!disableSave); - }, - [disableSave, messages, setCanSave] - ); - const handleClose = useCallback(() => { - setMessages(item.messages); - closePanel(); - }, [closePanel, item.messages]); - - const onConfirm = useCallback(() => { - if (!disableSave) { - updatePrompt({ name: item.name, messages }); - } - handleClose(); - }, [disableSave, handleClose, item.name, messages, updatePrompt]); - - useEffect(() => { - setMessages(item.messages); - }, [item.messages]); - - return ( -
- - -
-
-
-
Name
-
- {item.name} -
-
- {item.action ? ( -
-
Action
-
- {item.action} -
-
- ) : null} -
-
Model
-
- {item.model} -
-
- {item.config ? ( -
-
Config
- {Object.entries(item.config).map(([key, value], index) => ( -
- {index !== 0 && } - {key} - - {value?.toString()} - -
- ))} -
- ) : null} -
-
-
Messages
- {messages.map((message, index) => ( -
- {index !== 0 && } -
-
Role
-
- {message.role} -
-
- - {message.params ? ( -
-
Params
- {Object.entries(message.params).map( - ([key, value], index) => ( -
- {index !== 0 && } - {key} - - {value.toString()} - -
- ) - )} -
- ) : null} -
Content
-