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
@@ -1,4 +1,5 @@
import { getStoreManager } from '@affine/core/blocksuite/manager/store';
import { toArrayBuffer } from '@affine/core/utils/array-buffer';
import { Container } from '@blocksuite/affine/global/di';
import {
customImageProxyMiddleware,
@@ -46,7 +47,9 @@ export class SnapshotHelper extends Service {
get: async key => {
const record =
await this.workspaceService.workspace.engine.blob.get(key);
return record ? new Blob([record.data], { type: record.mime }) : null;
return record
? new Blob([toArrayBuffer(record.data)], { type: record.mime })
: null;
},
set() {
return Promise.resolve('');
@@ -112,7 +112,7 @@ const DatabaseBacklinkRow = ({
useMemo(
() =>
row?.docId ? templateDocService.list.isTemplate$(row.docId) : undefined,
[row?.docId, templateDocService.list]
[row, templateDocService.list]
)
);
@@ -9,7 +9,8 @@ export { DocsService } from './services/docs';
import type { Framework } from '@toeverything/infra';
import { WorkspaceDBService } from '../db/services/db';
import { WorkspaceScope, WorkspaceService } from '../workspace';
import { WorkspaceScope } from '../workspace/scopes/workspace';
import { WorkspaceService } from '../workspace/services/workspace';
import { Doc } from './entities/doc';
import { DocRecord } from './entities/record';
import { DocRecordList } from './entities/record-list';
@@ -8,7 +8,7 @@ import { ObjectPool, Service } from '@toeverything/infra';
import { combineLatest, map } from 'rxjs';
import { initDocFromProps } from '../../../blocksuite/initialization';
import { getAFFiNEWorkspaceSchema } from '../../workspace';
import { getAFFiNEWorkspaceSchema } from '../../workspace/global-schema';
import type { Doc } from '../entities/doc';
import { DocRecordList } from '../entities/record-list';
import { DocCreated, DocInitialized } from '../events';
@@ -1,3 +1,4 @@
import { toArrayBuffer } from '@affine/core/utils/array-buffer';
import type { DocMode } from '@blocksuite/affine/model';
import { ZipTransformer } from '@blocksuite/affine/widgets/linked-doc';
import { Service } from '@toeverything/infra';
@@ -27,7 +28,7 @@ export class ImportTemplateService extends Service {
const [importedDoc] = await ZipTransformer.importDocs(
workspace.docCollection,
getAFFiNEWorkspaceSchema(),
new Blob([docBinary], {
new Blob([toArrayBuffer(docBinary)], {
type: 'application/zip',
})
);
@@ -234,7 +234,7 @@ export class ReadwiseIntegration extends Entity<{ writer: IntegrationWriter }> {
async deleteAll() {
const refs = await this.getRefs();
await Promise.all(
refs.map(ref => {
refs.map(async ref => {
const doc = this.docsService.list.doc$(ref.id).value;
if (doc) {
doc.moveToTrash();
@@ -3,6 +3,7 @@ import {
type TranscriptionBlockModel,
} from '@affine/core/blocksuite/ai/blocks/transcription-block/model';
import { insertFromMarkdown } from '@affine/core/blocksuite/utils';
import { toArrayBuffer } from '@affine/core/utils/array-buffer';
import { encodeAudioBlobToOpusSlices } from '@affine/core/utils/opus-encoding';
import { DebugLogger } from '@affine/debug';
import { AiJobStatus } from '@affine/graphql';
@@ -137,7 +138,7 @@ export class AudioAttachmentBlock extends Entity<AttachmentBlockModel> {
}
const slices = await encodeAudioBlobToOpusSlices(buffer, 64000);
const files = slices.map((slice, index) => {
const blob = new Blob([slice], { type: 'audio/opus' });
const blob = new Blob([toArrayBuffer(slice)], { type: 'audio/opus' });
return new File([blob], this.props.props.name + `-${index}.opus`, {
type: 'audio/opus',
});
@@ -1,3 +1,4 @@
import { toArrayBuffer } from '@affine/core/utils/array-buffer';
import { DebugLogger } from '@affine/debug';
import {
catchErrorInto,
@@ -170,7 +171,7 @@ export class AudioMedia extends Entity<AudioSource> {
private async loadAudioBuffer() {
const uint8Array = await this.getBuffer();
return new Blob([uint8Array]);
return new Blob([toArrayBuffer(uint8Array)]);
}
readonly revalidateBuffer = effect(
@@ -1,3 +1,4 @@
import { toArrayBuffer } from '@affine/core/utils/array-buffer';
import { Entity, LiveData, ObjectPool } from '@toeverything/infra';
import { catchError, from, map, of, startWith, switchMap } from 'rxjs';
@@ -41,7 +42,7 @@ export class PDF extends Entity<{ blobId: string }> {
.then(blobRecord => {
if (blobRecord) {
const { data, mime: type } = blobRecord;
const blob = new Blob([data], { type });
const blob = new Blob([toArrayBuffer(data)], { type });
return blob.arrayBuffer();
}
@@ -16,7 +16,7 @@ import { firstValueFrom, map, race } from 'rxjs';
import type { AIChatBlockModel } from '../../../blocksuite/ai/blocks';
import { resolveLinkToDoc } from '../../navigation';
import type { WorkbenchService } from '../../workbench';
import type { WorkbenchService } from '../../workbench/services/workbench';
import type { ImagePreviewData } from '../view/image-preview';
export type DocReferenceInfo = {
@@ -1,6 +1,6 @@
import { type Framework } from '@toeverything/infra';
import { WorkbenchService } from '../workbench';
import { WorkbenchService } from '../workbench/services/workbench';
import { WorkspaceScope } from '../workspace';
import { PeekViewEntity } from './entities/peek-view';
import { PeekViewService } from './services/peek-view';
@@ -22,7 +22,7 @@ import clsx from 'clsx';
import { lazy, Suspense, useCallback, useEffect } from 'react';
import type { Subscription } from 'rxjs';
import { WorkbenchService } from '../../../workbench';
import { WorkbenchService } from '../../../workbench/services/workbench';
import type { DocReferenceInfo } from '../../entities/peek-view';
import { PeekViewService } from '../../services/peek-view';
import { useEditor } from '../utils';
@@ -153,7 +153,6 @@ export const PeekViewModalContainer = forwardRef<
!target.getBoundingClientRect().width &&
iteration < 10
) {
// eslint-disable-next-line react-hooks/exhaustive-deps
target = target.parentElement || undefined;
iteration++;
}
@@ -27,7 +27,7 @@ import { ServerService } from '../../cloud';
import { WorkspaceDialogService } from '../../dialogs';
import { DocsService } from '../../doc/services/docs';
import { toDocSearchParams } from '../../navigation';
import { WorkbenchService } from '../../workbench';
import { WorkbenchService } from '../../workbench/services/workbench';
import type {
AttachmentPeekViewInfo,
DocReferenceInfo,
@@ -14,7 +14,7 @@ export {
import { type Framework } from '@toeverything/infra';
import { WorkspaceServerService } from '../cloud';
import { WorkspaceServerService } from '../cloud/services/workspace-server';
import { DocScope, DocService } from '../doc';
import {
WorkspaceLocalState,
@@ -1,3 +1,4 @@
import { toArrayBuffer } from '@affine/core/utils/array-buffer';
import { DebugLogger } from '@affine/debug';
import {
createWorkspaceMutation,
@@ -192,7 +193,9 @@ class CloudWorkspaceFlavourProvider implements WorkspaceFlavourProvider {
blobSource: {
get: async key => {
const record = await blobStorage.get(key);
return record ? new Blob([record.data], { type: record.mime }) : null;
return record
? new Blob([toArrayBuffer(record.data)], { type: record.mime })
: null;
},
delete: async () => {
return;
@@ -391,7 +394,9 @@ class CloudWorkspaceFlavourProvider implements WorkspaceFlavourProvider {
storage.connection.disconnect();
if (localBlob) {
return new Blob([localBlob.data], { type: localBlob.mime });
return new Blob([toArrayBuffer(localBlob.data)], {
type: localBlob.mime,
});
}
const cloudBlob = await new CloudBlobStorage({
@@ -401,7 +406,7 @@ class CloudWorkspaceFlavourProvider implements WorkspaceFlavourProvider {
if (!cloudBlob) {
return null;
}
return new Blob([cloudBlob.data], { type: cloudBlob.mime });
return new Blob([toArrayBuffer(cloudBlob.data)], { type: cloudBlob.mime });
}
async listBlobs(id: string): Promise<ListedBlobRecord[]> {
@@ -1,3 +1,4 @@
import { toArrayBuffer } from '@affine/core/utils/array-buffer';
import { DebugLogger } from '@affine/debug';
import {
type BlobStorage,
@@ -266,7 +267,9 @@ class LocalWorkspaceFlavourProvider implements WorkspaceFlavourProvider {
blobSource: {
get: async key => {
const record = await blobStorage.get(key);
return record ? new Blob([record.data], { type: record.mime }) : null;
return record
? new Blob([toArrayBuffer(record.data)], { type: record.mime })
: null;
},
delete: async () => {
return;
@@ -394,7 +397,9 @@ class LocalWorkspaceFlavourProvider implements WorkspaceFlavourProvider {
storage.connection.connect();
await storage.connection.waitForConnected();
const blob = await storage.get(blobKey);
return blob ? new Blob([blob.data], { type: blob.mime }) : null;
return blob
? new Blob([toArrayBuffer(blob.data)], { type: blob.mime })
: null;
}
async listBlobs(id: string): Promise<ListedBlobRecord[]> {
@@ -1,3 +1,4 @@
import { toArrayBuffer } from '@affine/core/utils/array-buffer';
import isSvg from 'is-svg';
function fastCheckIsNotSvg(buffer: Uint8Array) {
@@ -49,11 +50,10 @@ export function isSvgBuffer(buffer: Uint8Array) {
}
export function bufferToBlob(buffer: Uint8Array | ArrayBuffer) {
const isSVG = isSvgBuffer(
buffer instanceof ArrayBuffer ? new Uint8Array(buffer) : buffer
);
const arrayBuffer = toArrayBuffer(buffer);
const isSVG = isSvgBuffer(new Uint8Array(arrayBuffer));
// for svg blob, we need to explicitly set the type to image/svg+xml
return isSVG
? new Blob([buffer], { type: 'image/svg+xml' })
: new Blob([buffer]);
? new Blob([arrayBuffer], { type: 'image/svg+xml' })
: new Blob([arrayBuffer]);
}
@@ -1,10 +1,11 @@
import type { FeatureFlagService } from '@affine/core/modules/feature-flag';
import { toArrayBuffer } from '@affine/core/utils/array-buffer';
import type { Workspace as WorkspaceInterface } from '@blocksuite/affine/store';
import { Entity, LiveData, yjsGetPath } from '@toeverything/infra';
import type { Observable } from 'rxjs';
import { Doc as YDoc, transact } from 'yjs';
import { DocsService } from '../../doc';
import { DocsService } from '../../doc/services/docs';
import { WorkspaceImpl } from '../impls/workspace';
import type { WorkspaceScope } from '../scopes/workspace';
import { WorkspaceEngineService } from '../services/engine';
@@ -39,7 +40,7 @@ export class Workspace extends Entity {
get: async key => {
const record = await this.engine.blob.get(key);
return record
? new Blob([record.data], { type: record.mime })
? new Blob([toArrayBuffer(record.data)], { type: record.mime })
: null;
},
delete: async () => {