feat: bump eslint & oxlint (#14452)

#### PR Dependency Tree


* **PR #14452** 👈

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Bug Fixes**
* Improved null-safety, dependency tracking, upload validation, and
error logging for more reliable uploads, clipboard, calendar linking,
telemetry, PDF/theme printing, and preview/zoom behavior.
* Tightened handling of all-day calendar events (missing date now
reported).

* **Deprecations**
  * Removed deprecated RadioButton and RadioButtonGroup; use RadioGroup.

* **Chores**
* Unified and upgraded linting/config, reorganized imports, and
standardized binary handling for more consistent builds and tooling.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
DarkSky
2026-02-16 13:52:08 +08:00
committed by GitHub
parent 792164edd1
commit 728e02cab7
156 changed files with 1230 additions and 1066 deletions
@@ -22,8 +22,8 @@ import {
CalendarProviderListCalendarsParams,
CalendarProviderListEventsParams,
CalendarProviderListEventsResult,
CalendarProviderName,
} from './def';
import { CalendarProviderName } from './factory';
import { CalendarSyncTokenInvalid } from './google';
const XML_PARSER = new XMLParser({
@@ -113,7 +113,7 @@ const isRedirectStatus = (status: number) =>
const splitHeaderTokens = (value: string) =>
value
.split(/,(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)/)
.split(/,(?=(?:[^"]*"[^"]*")*[^"]*$)/)
.map(token => token.trim())
.filter(Boolean);
@@ -2,12 +2,7 @@ import { Inject, Injectable, Logger } from '@nestjs/common';
import type { CalendarAccount } from '@prisma/client';
import { CalendarProviderRequestError, Config, OnEvent } from '../../../base';
import { CalendarProviderFactory } from './factory';
export enum CalendarProviderName {
Google = 'google',
CalDAV = 'caldav',
}
import { CalendarProviderFactory, CalendarProviderName } from './factory';
export interface CalendarProviderTokens {
accessToken: string;
@@ -1,12 +1,20 @@
import { Injectable, Logger } from '@nestjs/common';
import type { CalendarProvider } from './def';
import { CalendarProviderName } from './def';
export enum CalendarProviderName {
Google = 'google',
CalDAV = 'caldav',
}
export interface CalendarProviderRef {
provider: CalendarProviderName;
}
@Injectable()
export class CalendarProviderFactory {
export class CalendarProviderFactory<
TProvider extends CalendarProviderRef = CalendarProviderRef,
> {
private readonly logger = new Logger(CalendarProviderFactory.name);
readonly #providers = new Map<CalendarProviderName, CalendarProvider>();
readonly #providers = new Map<CalendarProviderName, TProvider>();
get providers() {
return Array.from(this.#providers.keys());
@@ -16,12 +24,12 @@ export class CalendarProviderFactory {
return this.#providers.get(name);
}
register(provider: CalendarProvider) {
register(provider: TProvider) {
this.#providers.set(provider.provider, provider);
this.logger.log(`Calendar provider [${provider.provider}] registered.`);
}
unregister(provider: CalendarProvider) {
unregister(provider: TProvider) {
this.#providers.delete(provider.provider);
this.logger.log(`Calendar provider [${provider.provider}] unregistered.`);
}
@@ -1,17 +1,17 @@
import { Injectable } from '@nestjs/common';
import { CalendarProviderRequestError } from '../../../base';
import { CalendarProvider } from './def';
import {
CalendarProvider,
CalendarProviderEvent,
CalendarProviderListCalendarsParams,
CalendarProviderListEventsParams,
CalendarProviderListEventsResult,
CalendarProviderName,
CalendarProviderTokens,
CalendarProviderWatchParams,
CalendarProviderWatchResult,
} from './def';
import { CalendarProviderName } from './factory';
export class CalendarSyncTokenInvalid extends Error {
readonly code = 'calendar_sync_token_invalid';
@@ -14,9 +14,8 @@ export type {
CalendarProviderWatchParams,
CalendarProviderWatchResult,
} from './def';
export { CalendarProviderName } from './def';
export { CalendarProvider } from './def';
export { CalendarProviderFactory } from './factory';
export { CalendarProviderFactory, CalendarProviderName } from './factory';
export { CalendarSyncTokenInvalid, GoogleCalendarProvider } from './google';
export const CalendarProviders = [GoogleCalendarProvider, CalDAVProvider];
@@ -18,10 +18,10 @@ import {
CalendarProvider,
CalendarProviderEvent,
CalendarProviderEventTime,
CalendarProviderFactory,
CalendarProviderName,
CalendarSyncTokenInvalid,
} from './providers';
import { CalendarProviderFactory } from './providers';
import type { LinkCalDAVAccountInput } from './types';
const TOKEN_REFRESH_SKEW_MS = 60 * 1000;
@@ -35,7 +35,7 @@ export class CalendarService {
constructor(
private readonly models: Models,
private readonly providerFactory: CalendarProviderFactory,
private readonly providerFactory: CalendarProviderFactory<CalendarProvider>,
private readonly mutex: Mutex,
private readonly config: Config,
private readonly url: URLHelper
@@ -105,11 +105,11 @@ export class CalendarService {
const accessToken = accountTokens.accessToken;
if (accessToken) {
await Promise.allSettled(
needToStopChannel.map(s => {
needToStopChannel.map(async s => {
if (!s.customChannelId || !s.customResourceId) {
return Promise.resolve();
return;
}
return provider.stopChannel?.({
return await provider.stopChannel?.({
accessToken,
channelId: s.customChannelId,
resourceId: s.customResourceId,
@@ -654,8 +654,11 @@ export class CalendarService {
}
const zone = time.timeZone ?? fallbackTimezone ?? 'UTC';
if (!time.date) {
throw new Error('Calendar provider returned all-day event without date');
}
return {
date: this.convertDateToUtc(time.date!, zone),
date: this.convertDateToUtc(time.date, zone),
allDay: true,
};
}
@@ -49,7 +49,7 @@ import {
FileChunkSimilarity,
Models,
} from '../../../models';
import { CopilotEmbeddingJob } from '../embedding';
import { CopilotEmbeddingJob } from '../embedding/job';
import { COPILOT_LOCKER, CopilotType } from '../resolver';
import { ChatSessionService } from '../session';
import { CopilotStorage } from '../storage';
@@ -15,7 +15,8 @@ import {
ContextFile,
Models,
} from '../../../models';
import { type EmbeddingClient, getEmbeddingClient } from '../embedding';
import { getEmbeddingClient } from '../embedding/client';
import type { EmbeddingClient } from '../embedding/types';
import { ContextSession } from './session';
const CONTEXT_SESSION_KEY = 'context-session';
@@ -11,7 +11,7 @@ import {
FileChunkSimilarity,
Models,
} from '../../../models';
import { EmbeddingClient } from '../embedding';
import { EmbeddingClient } from '../embedding/types';
export class ContextSession implements AsyncDisposable {
constructor(
@@ -47,14 +47,14 @@ import {
} from '../../base';
import { ServerFeature, ServerService } from '../../core';
import { CurrentUser, Public } from '../../core/auth';
import { CopilotContextService } from './context';
import { CopilotContextService } from './context/service';
import { CopilotProviderFactory } from './providers/factory';
import type { CopilotProvider } from './providers/provider';
import {
CopilotProvider,
CopilotProviderFactory,
ModelInputType,
ModelOutputType,
StreamObject,
} from './providers';
type StreamObject,
} from './providers/types';
import { StreamObjectParser } from './providers/utils';
import { ChatSession, ChatSessionService } from './session';
import { CopilotStorage } from './storage';
@@ -12,14 +12,14 @@ import {
Embedding,
EMBEDDING_DIMENSIONS,
} from '../../../models';
import { PromptService } from '../prompt';
import { PromptService } from '../prompt/service';
import { CopilotProviderFactory } from '../providers/factory';
import type { CopilotProvider } from '../providers/provider';
import {
type CopilotProvider,
CopilotProviderFactory,
type ModelFullConditions,
ModelInputType,
ModelOutputType,
} from '../providers';
} from '../providers/types';
import { EmbeddingClient, type ReRankResult } from './types';
const EMBEDDING_MODEL = 'gemini-embedding-001';
@@ -8,7 +8,7 @@ import { DocReader, DocWriter } from '../../../core/doc';
import { AccessController } from '../../../core/permission';
import { clearEmbeddingChunk } from '../../../models';
import { IndexerService } from '../../indexer';
import { CopilotContextService } from '../context';
import { CopilotContextService } from '../context/service';
@Injectable()
export class WorkspaceMcpProvider {
@@ -4,7 +4,11 @@ import { AiPrompt } from '@prisma/client';
import Mustache from 'mustache';
import { getTokenEncoder } from '../../../native';
import { PromptConfig, PromptMessage, PromptParams } from '../providers';
import type {
PromptConfig,
PromptMessage,
PromptParams,
} from '../providers/types';
// disable escaping
Mustache.escape = (text: string) => text;
@@ -1,7 +1,7 @@
import { Logger } from '@nestjs/common';
import { AiPrompt, PrismaClient } from '@prisma/client';
import { PromptConfig, PromptMessage } from '../providers';
import type { PromptConfig, PromptMessage } from '../providers/types';
type Prompt = Omit<
AiPrompt,
@@ -8,7 +8,7 @@ import {
PromptConfigSchema,
PromptMessage,
PromptMessageSchema,
} from '../providers';
} from '../providers/types';
import { ChatPrompt } from './chat-prompt';
import {
CopilotPromptScenario,
@@ -13,8 +13,8 @@ import { DocReader, DocWriter } from '../../../core/doc';
import { AccessController } from '../../../core/permission';
import { Models } from '../../../models';
import { IndexerService } from '../../indexer';
import { CopilotContextService } from '../context';
import { PromptService } from '../prompt';
import { CopilotContextService } from '../context/service';
import { PromptService } from '../prompt/service';
import {
buildBlobContentGetter,
buildContentGetter,
@@ -42,9 +42,9 @@ import { AccessController, DocAction } from '../../core/permission';
import { UserType } from '../../core/user';
import type { ListSessionOptions, UpdateChatSession } from '../../models';
import { CopilotCronJobs } from './cron';
import { PromptService } from './prompt';
import { PromptMessage, StreamObject } from './providers';
import { PromptService } from './prompt/service';
import { CopilotProviderFactory } from './providers/factory';
import type { PromptMessage, StreamObject } from './providers/types';
import { ChatSessionService } from './session';
import { CopilotStorage } from './storage';
import { type ChatHistory, type ChatMessage, SubmittedMessage } from './types';
@@ -28,13 +28,14 @@ import {
import { SubscriptionService } from '../payment/service';
import { SubscriptionPlan, SubscriptionStatus } from '../payment/types';
import { ChatMessageCache } from './message';
import { ChatPrompt, PromptService } from './prompt';
import { ChatPrompt } from './prompt/chat-prompt';
import { PromptService } from './prompt/service';
import { CopilotProviderFactory } from './providers/factory';
import {
CopilotProviderFactory,
ModelOutputType,
PromptMessage,
PromptParams,
} from './providers';
type PromptMessage,
type PromptParams,
} from './providers/types';
import {
type ChatHistory,
type ChatMessage,
@@ -322,7 +323,7 @@ export class ChatSessionService {
private stripNullBytes(value?: string | null): string {
if (!value) return '';
return value.replace(/\u0000/g, '');
return value.replaceAll('\0', '');
}
private isNullByteError(error: unknown): boolean {
@@ -3,9 +3,8 @@ import { tool } from 'ai';
import { z } from 'zod';
import { AccessController } from '../../../core/permission';
import type { ContextSession } from '../context/session';
import type { CopilotChatOptions } from '../providers';
import { toolError } from './error';
import type { ContextSession, CopilotChatOptions } from './types';
const logger = new Logger('ContextBlobReadTool');
@@ -2,9 +2,9 @@ import { Logger } from '@nestjs/common';
import { tool } from 'ai';
import { z } from 'zod';
import type { PromptService } from '../prompt';
import type { CopilotProviderFactory } from '../providers';
import { toolError } from './error';
import type { CopilotProviderFactory, PromptService } from './types';
const logger = new Logger('CodeArtifactTool');
/**
* A copilot tool that produces a completely self-contained HTML artifact.
@@ -2,9 +2,8 @@ import { Logger } from '@nestjs/common';
import { tool } from 'ai';
import { z } from 'zod';
import type { PromptService } from '../prompt';
import type { CopilotProviderFactory } from '../providers';
import { toolError } from './error';
import type { CopilotProviderFactory, PromptService } from './types';
const logger = new Logger('ConversationSummaryTool');
@@ -2,9 +2,8 @@ import { Logger } from '@nestjs/common';
import { tool } from 'ai';
import { z } from 'zod';
import type { PromptService } from '../prompt';
import type { CopilotProviderFactory } from '../providers';
import { toolError } from './error';
import type { CopilotProviderFactory, PromptService } from './types';
const logger = new Logger('DocComposeTool');
@@ -3,8 +3,11 @@ import { z } from 'zod';
import { DocReader } from '../../../core/doc';
import { AccessController } from '../../../core/permission';
import { type PromptService } from '../prompt';
import type { CopilotChatOptions, CopilotProviderFactory } from '../providers';
import type {
CopilotChatOptions,
CopilotProviderFactory,
PromptService,
} from './types';
const CodeEditSchema = z
.array(
@@ -3,8 +3,8 @@ import { z } from 'zod';
import type { AccessController } from '../../../core/permission';
import type { IndexerService, SearchDoc } from '../../indexer';
import type { CopilotChatOptions } from '../providers';
import { toolError } from './error';
import type { CopilotChatOptions } from './types';
export const buildDocKeywordSearchGetter = (
ac: AccessController,
@@ -5,8 +5,8 @@ import { z } from 'zod';
import { DocReader } from '../../../core/doc';
import { AccessController } from '../../../core/permission';
import { Models, publicUserSelect } from '../../../models';
import type { CopilotChatOptions } from '../providers';
import { toolError } from './error';
import type { CopilotChatOptions } from './types';
const logger = new Logger('DocReadTool');
@@ -8,10 +8,12 @@ import {
clearEmbeddingChunk,
type Models,
} from '../../../models';
import type { CopilotContextService } from '../context';
import type { ContextSession } from '../context/session';
import type { CopilotChatOptions } from '../providers';
import { toolError } from './error';
import type {
ContextSession,
CopilotChatOptions,
CopilotContextService,
} from './types';
export const buildDocSearchGetter = (
ac: AccessController,
@@ -4,8 +4,8 @@ import { z } from 'zod';
import { DocWriter } from '../../../core/doc';
import { AccessController } from '../../../core/permission';
import type { CopilotChatOptions } from '../providers';
import { toolError } from './error';
import type { CopilotChatOptions } from './types';
const logger = new Logger('DocWriteTool');
@@ -2,9 +2,8 @@ import { Logger } from '@nestjs/common';
import { tool } from 'ai';
import { z } from 'zod';
import type { PromptService } from '../prompt';
import type { CopilotProviderFactory } from '../providers';
import { toolError } from './error';
import type { CopilotProviderFactory, PromptService } from './types';
const logger = new Logger('SectionEditTool');
@@ -0,0 +1,5 @@
export type { CopilotContextService } from '../context/service';
export type { ContextSession } from '../context/session';
export type { PromptService } from '../prompt/service';
export type { CopilotProviderFactory } from '../providers/factory';
export type { CopilotChatOptions } from '../providers/types';
@@ -125,6 +125,7 @@ export class CopilotTranscriptionResolver {
user.id,
workspaceId,
blobId,
// eslint-disable-next-line @typescript-eslint/await-thenable
await Promise.all(allBlobs)
);
@@ -15,14 +15,10 @@ import {
sniffMime,
} from '../../../base';
import { Models } from '../../../models';
import { PromptService } from '../prompt';
import {
CopilotProvider,
CopilotProviderFactory,
CopilotProviderType,
ModelOutputType,
PromptMessage,
} from '../providers';
import { PromptService } from '../prompt/service';
import type { CopilotProvider, PromptMessage } from '../providers';
import { CopilotProviderFactory } from '../providers/factory';
import { CopilotProviderType, ModelOutputType } from '../providers/types';
import { CopilotStorage } from '../storage';
import {
AudioBlobInfos,
@@ -171,7 +167,7 @@ export class CopilotTranscriptionService {
if (payload.success) {
let { url, mimeType, infos } = payload.data;
infos = infos || [];
if (url && mimeType && !infos.find(i => i.url === url)) {
if (url && mimeType && !infos.some(i => i.url === url)) {
infos.push({ url, mimeType });
}
@@ -1,7 +1,7 @@
import { z } from 'zod';
import type { ChatPrompt } from './prompt';
import { PromptMessageSchema, PureMessageSchema } from './providers';
import type { ChatPrompt } from './prompt/chat-prompt';
import { PromptMessageSchema, PureMessageSchema } from './providers/types';
const takeFirst = (v: unknown) => (Array.isArray(v) ? v[0] : v);
@@ -3,7 +3,7 @@ import { Readable } from 'node:stream';
import type { Request } from 'express';
import { OneMB, readBufferWithLimit } from '../../base';
import type { PromptTools } from './providers';
import type { PromptTools } from './providers/types';
import type { ToolsConfig } from './types';
export const MAX_EMBEDDABLE_SIZE = 50 * OneMB;
@@ -4,7 +4,7 @@ import { fileURLToPath } from 'node:url';
import { Logger } from '@nestjs/common';
import Piscina from 'piscina';
import { CopilotChatOptions } from '../providers';
import type { CopilotChatOptions } from '../providers/types';
import type { NodeExecuteResult, NodeExecutor } from './executor';
import { getWorkflowExecutor, NodeExecuteState } from './executor';
import type {
@@ -1,6 +1,6 @@
import { Injectable, Logger } from '@nestjs/common';
import { CopilotChatOptions } from '../providers';
import type { CopilotChatOptions } from '../providers/types';
import { WorkflowGraphList } from './graph';
import { WorkflowNode } from './node';
import type { WorkflowGraph, WorkflowGraphInstances } from './types';
@@ -1,6 +1,6 @@
import { Logger } from '@nestjs/common';
import { CopilotChatOptions } from '../providers';
import type { CopilotChatOptions } from '../providers/types';
import { NodeExecuteState } from './executor';
import { WorkflowNode } from './node';
import type { WorkflowGraphInstances, WorkflowNodeState } from './types';
@@ -132,10 +132,11 @@ export class AppleOAuthProvider extends OAuthProvider {
{ method: 'GET' },
{ treatServerErrorAsInvalid: true }
);
const idToken = tokens.idToken;
const payload = await new Promise<JwtPayload>((resolve, reject) => {
jwt.verify(
tokens.idToken!,
idToken,
(header, callback) => {
const key = keys.find(key => key.kid === header.kid);
if (!key) {