Lint fixes

This commit is contained in:
Hakan Shehu
2024-12-01 23:51:33 +01:00
parent a19c6274b9
commit 1c204a17dc
90 changed files with 1914 additions and 396 deletions

View File

@@ -16,7 +16,13 @@
"es6": true
},
"rules": {
"no-unused-vars": "error",
"no-unused-vars": "off",
"import/no-unresolved": "off",
"@typescript-eslint/no-unused-vars": [
"error",
{ "vars": "all", "varsIgnorePattern": "^_", "argsIgnorePattern": "^_" }
],
"no-console": "off"
}
},
"ignorePatterns": ["dist", "node_modules"]
}

View File

@@ -10,7 +10,7 @@
"package": "electron-forge package",
"make": "electron-forge make",
"publish": "electron-forge publish",
"lint": "eslint --ext .ts,.tsx .",
"lint": "eslint --ext .ts,.tsx src",
"postinstall": "electron-rebuild"
},
"devDependencies": {

View File

@@ -4,14 +4,11 @@ import { eventBus } from '@/shared/lib/event-bus';
import { avatarService } from '@/main/services/avatar-service';
import { fileService } from '@/main/services/file-service';
import { assetService } from '@/main/services/asset-service';
import { MutationMap } from '@/shared/mutations';
import { MutationInput } from '@/shared/mutations';
import { QueryMap } from '@/shared/queries';
import { MutationMap, MutationInput } from '@/shared/mutations';
import { QueryMap, QueryInput } from '@/shared/queries';
import { mutationService } from '@/main/services/mutation-service';
import { queryService } from '@/main/services/query-service';
import { QueryInput } from '@/shared/queries';
import { CommandMap } from '@/shared/commands';
import { CommandInput } from '@/shared/commands';
import { CommandMap, CommandInput } from '@/shared/commands';
import { commandService } from '@/main/services/command-service';
import { bootstrapper } from '@/main/bootstrapper';
import started from 'electron-squirrel-startup';

View File

@@ -1,8 +1,4 @@
import {
InteractionAttribute,
InteractionAttributes,
NodeType,
} from '@colanode/core';
import { InteractionAttribute, NodeType } from '@colanode/core';
import { ColumnType, Insertable, Selectable, Updateable } from 'kysely';
interface NodeTable {

View File

@@ -1,11 +1,10 @@
import { databaseService } from '@/main/data/database-service';
import { generateId, IdType } from '@colanode/core';
import { generateId, IdType, ChannelAttributes } from '@colanode/core';
import { MutationHandler } from '@/main/types';
import {
ChannelCreateMutationInput,
ChannelCreateMutationOutput,
} from '@/shared/mutations/channel-create';
import { ChannelAttributes } from '@colanode/core';
import { nodeService } from '@/main/services/node-service';
export class ChannelCreateMutationHandler

View File

@@ -1,12 +1,11 @@
import { databaseService } from '@/main/data/database-service';
import { generateId, IdType, NodeTypes, NodeRoles } from '@colanode/core';
import { generateId, IdType, NodeTypes, ChatAttributes } from '@colanode/core';
import { MutationHandler } from '@/main/types';
import {
ChatCreateMutationInput,
ChatCreateMutationOutput,
} from '@/shared/mutations/chat-create';
import { sql } from 'kysely';
import { ChatAttributes } from '@colanode/core';
import { nodeService } from '@/main/services/node-service';
interface ChatRow {

View File

@@ -1,11 +1,15 @@
import { MutationHandler } from '@/main/types';
import { extractFileType, generateId, IdType } from '@colanode/core';
import {
extractFileType,
generateId,
IdType,
FileAttributes,
} from '@colanode/core';
import {
FileCreateMutationInput,
FileCreateMutationOutput,
} from '@/shared/mutations/file-create';
import { fileService } from '@/main/services/file-service';
import { FileAttributes } from '@colanode/core';
import { nodeService } from '@/main/services/node-service';
export class FileCreateMutationHandler

View File

@@ -1,10 +1,9 @@
import { generateId, IdType } from '@colanode/core';
import { generateId, IdType, FolderAttributes } from '@colanode/core';
import { MutationHandler } from '@/main/types';
import {
FolderCreateMutationInput,
FolderCreateMutationOutput,
} from '@/shared/mutations/folder-create';
import { FolderAttributes } from '@colanode/core';
import { nodeService } from '@/main/services/node-service';
export class FolderCreateMutationHandler

View File

@@ -4,6 +4,9 @@ import {
EditorNodeTypes,
NodeTypes,
extractFileType,
Block,
FileAttributes,
MessageAttributes,
} from '@colanode/core';
import { MutationHandler } from '@/main/types';
import {
@@ -12,7 +15,6 @@ import {
} from '@/shared/mutations/message-create';
import { mapContentsToBlocks } from '@/shared/lib/editor';
import { fileService } from '@/main/services/file-service';
import { Block, FileAttributes, MessageAttributes } from '@colanode/core';
import { CreateNodeInput, nodeService } from '@/main/services/node-service';
export class MessageCreateMutationHandler

View File

@@ -1,10 +1,9 @@
import { generateId, IdType } from '@colanode/core';
import { generateId, IdType, PageAttributes } from '@colanode/core';
import { MutationHandler } from '@/main/types';
import {
PageCreateMutationInput,
PageCreateMutationOutput,
} from '@/shared/mutations/page-create';
import { PageAttributes } from '@colanode/core';
import { nodeService } from '@/main/services/node-service';
export class PageCreateMutationHandler

View File

@@ -1,10 +1,9 @@
import { generateId, IdType } from '@colanode/core';
import { generateId, IdType, RecordAttributes } from '@colanode/core';
import { MutationHandler } from '@/main/types';
import {
RecordCreateMutationInput,
RecordCreateMutationOutput,
} from '@/shared/mutations/record-create';
import { RecordAttributes } from '@colanode/core';
import { nodeService } from '@/main/services/node-service';
export class RecordCreateMutationHandler

View File

@@ -1,14 +1,15 @@
import { generateId, IdType, NodeRoles } from '@colanode/core';
import {
generateId,
IdType,
ChannelAttributes,
PageAttributes,
SpaceAttributes,
} from '@colanode/core';
import { MutationHandler } from '@/main/types';
import {
SpaceCreateMutationInput,
SpaceCreateMutationOutput,
} from '@/shared/mutations/space-create';
import {
ChannelAttributes,
PageAttributes,
SpaceAttributes,
} from '@colanode/core';
import { nodeService } from '@/main/services/node-service';
import { databaseService } from '@/main/data/database-service';

View File

@@ -49,7 +49,7 @@ export class WorkspaceUsersInviteMutationHandler
};
}
const { data } = await httpClient.post<WorkspaceUsersInviteOutput>(
await httpClient.post<WorkspaceUsersInviteOutput>(
`/v1/workspaces/${workspace.workspace_id}/users`,
{
emails: input.emails,

View File

@@ -22,8 +22,7 @@ export class AccountGetQueryHandler
public async checkForChanges(
event: Event,
input: AccountGetQueryInput,
output: Account | null
input: AccountGetQueryInput
): Promise<ChangeCheckResult<AccountGetQueryInput>> {
if (
event.type === 'account_created' &&

View File

@@ -1,9 +1,8 @@
import { databaseService } from '@/main/data/database-service';
import { mapNode } from '@/main/utils';
import { mapNode, fetchNodeAncestors } from '@/main/utils';
import { SelectNode } from '@/main/data/workspace/schema';
import { ChangeCheckResult, QueryHandler } from '@/main/types';
import { NodeTreeGetQueryInput } from '@/shared/queries/node-tree-get';
import { fetchNodeAncestors } from '@/main/utils';
import { Event } from '@/shared/types/events';
import { Node } from '@colanode/core';

View File

@@ -21,9 +21,9 @@ import {
DatabaseNode,
RecordNode,
isStringArray,
NodeTypes,
} from '@colanode/core';
import { mapNode } from '@/main/utils';
import { NodeTypes } from '@colanode/core';
import { Event } from '@/shared/types/events';
export class RecordListQueryHandler

View File

@@ -2,8 +2,7 @@ import { UserSearchQueryInput } from '@/shared/queries/user-search';
import { databaseService } from '@/main/data/database-service';
import { sql } from 'kysely';
import { SelectNode } from '@/main/data/workspace/schema';
import { NodeTypes } from '@colanode/core';
import { UserNode } from '@colanode/core';
import { NodeTypes, UserNode } from '@colanode/core';
import { ChangeCheckResult, QueryHandler } from '@/main/types';
import { mapNode } from '@/main/utils';
import { Event } from '@/shared/types/events';

View File

@@ -1,9 +1,8 @@
import { WorkspaceUserListQueryInput } from '@/shared/queries/workspace-user-list';
import { databaseService } from '@/main/data/database-service';
import { NodeTypes } from '@colanode/core';
import { NodeTypes, UserNode } from '@colanode/core';
import { mapNode } from '@/main/utils';
import { SelectNode } from '@/main/data/workspace/schema';
import { UserNode } from '@colanode/core';
import { ChangeCheckResult, QueryHandler } from '@/main/types';
import { Event } from '@/shared/types/events';

View File

@@ -7,8 +7,8 @@ import {
getWorkspaceDirectoryPath,
mapAccount,
mapWorkspace,
getAccountAvatarsDirectoryPath,
} from '@/main/utils';
import { getAccountAvatarsDirectoryPath } from '@/main/utils';
import { eventBus } from '@/shared/lib/event-bus';
import { serverService } from '@/main/services/server-service';
import { createLogger } from '@/main/logger';
@@ -282,7 +282,7 @@ class AccountService {
this.logger.debug(
`Logged out account ${deletedToken.account_id} from server ${deletedToken.domain}`
);
} catch (error) {
} catch {
this.logger.warn(
`Failed to logout account ${deletedToken.account_id} from server ${deletedToken.domain}`
);

View File

@@ -42,11 +42,14 @@ class AvatarService {
return new Response(null, { status: 404 });
}
const response = await httpClient.get<any>(`/v1/avatars/${avatarId}`, {
domain: credentials.domain,
token: credentials.token,
responseType: 'stream',
});
const response = await httpClient.get<NodeJS.ReadableStream>(
`/v1/avatars/${avatarId}`,
{
domain: credentials.domain,
token: credentials.token,
responseType: 'stream',
}
);
if (response.status !== 200 || !response.data) {
this.logger.warn(

View File

@@ -1,6 +1,5 @@
import { CommandInput } from '@/shared/commands';
import { CommandInput, CommandMap } from '@/shared/commands';
import { createLogger } from '@/main/logger';
import { CommandMap } from '@/shared/commands';
import { commandHandlerMap } from '@/main/commands';
import { CommandHandler } from '@/main/types';

View File

@@ -1,5 +1,4 @@
import { MutationInput } from '@/shared/mutations';
import { MutationMap } from '@/shared/mutations';
import { MutationInput, MutationMap } from '@/shared/mutations';
import { mutationHandlerMap } from '@/main/mutations';
import { MutationHandler } from '@/main/types';
import { createLogger } from '@/main/logger';

View File

@@ -8,9 +8,10 @@ import {
ServerNodeDeleteTransaction,
ServerNodeTransaction,
ServerNodeUpdateTransaction,
generateId,
IdType,
} from '@colanode/core';
import { decodeState, YDoc } from '@colanode/crdt';
import { generateId, IdType } from '@colanode/core';
import { databaseService } from '@/main/data/database-service';
import {
fetchNodeAncestors,
@@ -274,7 +275,7 @@ class NodeService {
}
const ancestors = ancestorRows.map(mapNode);
let node = mapNode(nodeRow);
const node = mapNode(nodeRow);
if (!node) {
throw new Error('Node not found');

View File

@@ -85,7 +85,8 @@ class QueryService {
typeof query.input
>;
let result: any = query.result;
type QueryOutput = QueryMap[(typeof query.input)['type']]['output'];
let result: QueryOutput = query.result;
let hasChanges = false;
for (const event of events) {
const changeCheckResult = await handler.checkForChanges(
@@ -95,7 +96,7 @@ class QueryService {
);
if (changeCheckResult.hasChanges) {
result = changeCheckResult.result;
result = changeCheckResult.result as QueryOutput;
hasChanges = true;
}
}

View File

@@ -94,7 +94,7 @@ class ServerService {
try {
const { status, data } = await axios.get<ServerConfig>(configUrl);
return status === 200 ? data : null;
} catch (error) {
} catch {
return null;
}
}

View File

@@ -1,5 +1,4 @@
import { CommandMap } from '@/shared/commands';
import { CommandInput } from '@/shared/commands';
import { CommandMap, CommandInput } from '@/shared/commands';
import { MutationInput, MutationMap } from '@/shared/mutations';
import { QueryInput, QueryMap } from '@/shared/queries';
import { Event } from '@/shared/types/events';

View File

@@ -15,7 +15,7 @@ import {
SelectUpload,
WorkspaceDatabaseSchema,
} from '@/main/data/workspace/schema';
import { LocalNodeTransaction, Node, NodeTypes } from '@colanode/core';
import { LocalNodeTransaction, Node } from '@colanode/core';
import { Account } from '@/shared/types/accounts';
import {
SelectAccount,
@@ -102,7 +102,7 @@ export const fetchNodeAncestors = (
export const mapNode = (row: SelectNode): Node => {
return {
id: row.id,
type: row.type as any,
type: row.type,
parentId: row.parent_id,
attributes: JSON.parse(row.attributes),
createdAt: row.created_at,

View File

@@ -1,9 +1,7 @@
// See the Electron documentation for details on how to use preload scripts:
// https://www.electronjs.org/docs/latest/tutorial/process-model#preload-scripts
import { CommandMap } from '@/shared/commands';
import { CommandInput } from '@/shared/commands';
import { MutationMap } from '@/shared/mutations';
import { MutationInput } from '@/shared/mutations';
import { CommandMap, CommandInput } from '@/shared/commands';
import { MutationMap, MutationInput } from '@/shared/mutations';
import { QueryInput, QueryMap } from '@/shared/queries';
import { contextBridge, ipcRenderer } from 'electron';
import { eventBus } from '@/shared/lib/event-bus';

View File

@@ -1,13 +1,10 @@
import { Outlet } from 'react-router-dom';
import { AppContext } from '@/renderer/contexts/app';
import { RadarProvider } from '@/renderer/radar-provider';
export const App = () => {
return (
<AppContext.Provider value={{}}>
<RadarProvider>
<Outlet />
</RadarProvider>
</AppContext.Provider>
<RadarProvider>
<Outlet />
</RadarProvider>
);
};

View File

@@ -7,9 +7,8 @@ import {
DialogTitle,
} from '@/renderer/components/ui/dialog';
import { useMutation } from '@/renderer/hooks/use-mutation';
import { IdType } from '@colanode/core';
import { IdType, generateId } from '@colanode/core';
import { ChannelForm } from '@/renderer/components/channels/channel-form';
import { generateId } from '@colanode/core';
interface ChannelCreateDialogProps {
spaceId: string;

View File

@@ -29,7 +29,7 @@ export const BoardViewColumn = ({ field, option }: BoardViewColumnProps) => {
const lightClass = getSelectOptionLightColorClass(option.color ?? 'gray');
return (
<div
ref={dropRef as any}
ref={dropRef as React.LegacyRef<HTMLDivElement>}
className={cn('min-h-[400px] border-r p-1', isDragging && lightClass)}
style={{
minWidth: '250px',

View File

@@ -47,7 +47,7 @@ export const BoardViewRecordCard = () => {
return (
<div
ref={dragRef as any}
ref={dragRef as React.LegacyRef<HTMLDivElement>}
role="presentation"
key={record.id}
className="animate-fade-in flex cursor-pointer flex-col gap-1 rounded-md border p-2 text-left hover:bg-gray-50"

View File

@@ -7,8 +7,7 @@ import {
DialogTitle,
} from '@/renderer/components/ui/dialog';
import { useMutation } from '@/renderer/hooks/use-mutation';
import { IdType } from '@colanode/core';
import { generateId } from '@colanode/core';
import { IdType, generateId } from '@colanode/core';
import { DatabaseForm } from '@/renderer/components/databases/database-form';
interface DatabaseCreateDialogProps {

View File

@@ -8,7 +8,6 @@ import {
} from '@/renderer/components/ui/dialog';
import { useMutation } from '@/renderer/hooks/use-mutation';
import { DatabaseNode, hasEditorAccess, NodeRole } from '@colanode/core';
import { ChannelForm } from '@/renderer/components/channels/channel-form';
import { toast } from '@/renderer/hooks/use-toast';
import { DatabaseForm } from './database-form';

View File

@@ -108,7 +108,7 @@ export const TableViewFieldHeader = ({
? 'border-r-2 border-blue-300'
: 'border-r'
)}
ref={dragDropRef as any}
ref={dragDropRef as React.LegacyRef<HTMLDivElement>}
>
<FieldIcon type={viewField.field.type} className="size-4" />
<p>{viewField.field.name}</p>

View File

@@ -7,9 +7,8 @@ import {
DialogTitle,
} from '@/renderer/components/ui/dialog';
import { useMutation } from '@/renderer/hooks/use-mutation';
import { IdType } from '@colanode/core';
import { generateId } from '@colanode/core';
import { FolderForm } from './folder-form';
import { IdType, generateId } from '@colanode/core';
import { FolderForm } from '@/renderer/components/folders/folder-form';
interface FolderCreateDialogProps {
spaceId: string;

View File

@@ -1,5 +1,4 @@
import { MessageNode, SpaceNode } from '@colanode/core';
import { Avatar } from '@/renderer/components/avatars/avatar';
import { MessageNode } from '@colanode/core';
import { MessageCircleMore } from 'lucide-react';
interface MessageBreadcrumbItemProps {
@@ -8,7 +7,7 @@ interface MessageBreadcrumbItemProps {
export const MessageBreadcrumbItem = ({ node }: MessageBreadcrumbItemProps) => {
return (
<div className="flex items-center space-x-2">
<div key={node.id} className="flex items-center space-x-2">
<MessageCircleMore className="size-5" />
<span>Message</span>
</div>

View File

@@ -7,9 +7,8 @@ import {
DialogTitle,
} from '@/renderer/components/ui/dialog';
import { useMutation } from '@/renderer/hooks/use-mutation';
import { IdType } from '@colanode/core';
import { IdType, generateId } from '@colanode/core';
import { PageForm } from '@/renderer/components/pages/page-form';
import { generateId } from '@colanode/core';
interface PageCreateDialogProps {
spaceId: string;

View File

@@ -7,15 +7,9 @@ import {
DialogTitle,
} from '@/renderer/components/ui/dialog';
import { useMutation } from '@/renderer/hooks/use-mutation';
import {
ChannelNode,
hasEditorAccess,
NodeRole,
PageNode,
} from '@colanode/core';
import { ChannelForm } from '@/renderer/components/channels/channel-form';
import { hasEditorAccess, NodeRole, PageNode } from '@colanode/core';
import { toast } from '@/renderer/hooks/use-toast';
import { PageForm } from './page-form';
import { PageForm } from '@/renderer/components/pages/page-form';
interface PageUpdateDialogProps {
page: PageNode;

View File

@@ -21,9 +21,7 @@ const Command = React.forwardRef<
));
Command.displayName = CommandPrimitive.displayName;
interface CommandDialogProps extends DialogProps {}
const CommandDialog = ({ children, ...props }: CommandDialogProps) => {
const CommandDialog = ({ children, ...props }: DialogProps) => {
return (
<Dialog {...props}>
<DialogContent className="overflow-hidden p-0">

View File

@@ -25,7 +25,7 @@ const Dropzone = ({ text, children, onDrop }: DropzoneProps) => {
const isActive = canDrop && isOver;
return (
<div ref={dropRef as any}>
<div ref={dropRef as React.LegacyRef<HTMLDivElement>}>
{isActive && (
<div className="fixed bottom-0 left-0 right-0 top-0 z-50">
<div className="absolute inset-0 flex items-center justify-center bg-gray-500 opacity-50 transition-all duration-100 ease-in-out">

View File

@@ -2,24 +2,22 @@ import * as React from 'react';
import { cn } from '@/shared/lib/utils';
export interface InputProps
extends React.InputHTMLAttributes<HTMLInputElement> {}
const Input = React.forwardRef<HTMLInputElement, InputProps>(
({ className, type, ...props }, ref) => {
return (
<input
type={type}
className={cn(
'flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50',
className
)}
ref={ref}
{...props}
/>
);
}
);
const Input = React.forwardRef<
HTMLInputElement,
React.InputHTMLAttributes<HTMLInputElement>
>(({ className, type, ...props }, ref) => {
return (
<input
type={type}
className={cn(
'flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50',
className
)}
ref={ref}
{...props}
/>
);
});
Input.displayName = 'Input';
export { Input };

View File

@@ -155,7 +155,7 @@ const Sidebar = React.forwardRef<
},
ref
) => {
const { state, open, setOpen, toggleSidebar } = useSidebar();
const { state } = useSidebar();
if (collapsible === 'none') {
return (

View File

@@ -2,23 +2,21 @@ import * as React from 'react';
import { cn } from '@/shared/lib/utils';
export interface TextareaProps
extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {}
const Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(
({ className, ...props }, ref) => {
return (
<textarea
className={cn(
'flex min-h-[60px] w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50',
className
)}
ref={ref}
{...props}
/>
);
}
);
const Textarea = React.forwardRef<
HTMLTextAreaElement,
React.TextareaHTMLAttributes<HTMLTextAreaElement>
>(({ className, ...props }, ref) => {
return (
<textarea
className={cn(
'flex min-h-[60px] w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50',
className
)}
ref={ref}
{...props}
/>
);
});
Textarea.displayName = 'Textarea';
export { Textarea };

View File

@@ -1,7 +0,0 @@
import { createContext, useContext } from 'react';
interface AppContext {}
export const AppContext = createContext<AppContext>({} as AppContext);
export const useApp = () => useContext(AppContext);

View File

@@ -1,6 +1,5 @@
import { NodeRole } from '@colanode/core';
import { NodeRole, MessageNode } from '@colanode/core';
import { createContext, useContext } from 'react';
import { MessageNode } from '@colanode/core';
interface ConversationContext {
id: string;

View File

@@ -1,4 +1,4 @@
import Blockquote from '@tiptap/extension-blockquote';
import { Blockquote } from '@tiptap/extension-blockquote';
import { defaultClasses } from '@/renderer/editor/classes';

View File

@@ -1,4 +1,4 @@
import BulletList from '@tiptap/extension-bullet-list';
import { BulletList } from '@tiptap/extension-bullet-list';
import { defaultClasses } from '@/renderer/editor/classes';

View File

@@ -1,4 +1,4 @@
import CodeBlockLowlight from '@tiptap/extension-code-block-lowlight';
import { CodeBlockLowlight } from '@tiptap/extension-code-block-lowlight';
import { ReactNodeViewRenderer } from '@tiptap/react';
import { defaultClasses } from '@/renderer/editor/classes';

View File

@@ -1,4 +1,4 @@
import Code from '@tiptap/extension-code';
import { Code } from '@tiptap/extension-code';
import { defaultClasses } from '@/renderer/editor/classes';

View File

@@ -2,7 +2,8 @@ import React from 'react';
import type { Range } from '@tiptap/core';
import { Editor, Extension } from '@tiptap/core';
import { ReactRenderer } from '@tiptap/react';
import Suggestion, {
import {
Suggestion,
type SuggestionKeyDownProps,
type SuggestionProps,
} from '@tiptap/suggestion';
@@ -43,8 +44,8 @@ const CommandList = ({
range,
}: {
items: EditorCommand[];
command: any;
range: any;
command: (item: EditorCommand, range: Range) => void;
range: Range;
}) => {
const [selectedIndex, setSelectedIndex] = React.useState(0);
@@ -129,6 +130,8 @@ const CommandList = ({
const renderItems = () => {
let component: ReactRenderer | null = null;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
let popup: any | null = null;
return {
@@ -138,7 +141,7 @@ const renderItems = () => {
editor: props.editor,
});
// @ts-ignore
// @ts-expect-error Tippy instance type is complex, ignoring for simplicity
popup = tippy('body', {
getReferenceClientRect: props.clientRect,
appendTo: () => document.body,
@@ -152,10 +155,11 @@ const renderItems = () => {
onUpdate: (props: SuggestionProps<EditorCommand>) => {
component?.updateProps(props);
popup &&
if (popup) {
popup[0].setProps({
getReferenceClientRect: props.clientRect,
});
}
},
onKeyDown: (props: SuggestionKeyDownProps) => {
if (props.event.key === 'Escape') {
@@ -168,7 +172,7 @@ const renderItems = () => {
return true;
}
// @ts-ignore
// @ts-expect-error Tippy instance type is complex, ignoring for simplicity
return component?.ref?.onKeyDown(props);
},
onExit: () => {

View File

@@ -1,5 +1,5 @@
import { InputRule } from '@tiptap/core';
import HorizontalRule from '@tiptap/extension-horizontal-rule';
import { HorizontalRule } from '@tiptap/extension-horizontal-rule';
export const DividerNode = HorizontalRule.extend({
addInputRules() {

View File

@@ -1,4 +1,4 @@
import Dropcursor from '@tiptap/extension-dropcursor';
import { Dropcursor } from '@tiptap/extension-dropcursor';
export const DropcursorExtension = Dropcursor.configure({
width: 5,

View File

@@ -2,7 +2,7 @@ import { mergeAttributes, Node, textblockTypeInputRule } from '@tiptap/core';
import { defaultClasses } from '@/renderer/editor/classes';
export interface Heading1Options {
HTMLAttributes: Record<string, any>;
HTMLAttributes: Record<string, unknown>;
}
declare module '@tiptap/core' {

View File

@@ -2,7 +2,7 @@ import { mergeAttributes, Node, textblockTypeInputRule } from '@tiptap/core';
import { defaultClasses } from '@/renderer/editor/classes';
export interface Heading2Options {
HTMLAttributes: Record<string, any>;
HTMLAttributes: Record<string, unknown>;
}
declare module '@tiptap/core' {

View File

@@ -2,7 +2,7 @@ import { mergeAttributes, Node, textblockTypeInputRule } from '@tiptap/core';
import { defaultClasses } from '@/renderer/editor/classes';
export interface Heading3Options {
HTMLAttributes: Record<string, any>;
HTMLAttributes: Record<string, unknown>;
}
declare module '@tiptap/core' {

View File

@@ -1,4 +1,4 @@
import Link from '@tiptap/extension-link';
import { Link } from '@tiptap/extension-link';
import { defaultClasses } from '@/renderer/editor/classes';

View File

@@ -1,4 +1,4 @@
import ListItem from '@tiptap/extension-list-item';
import { ListItem } from '@tiptap/extension-list-item';
import { defaultClasses } from '@/renderer/editor/classes';

View File

@@ -1,4 +1,4 @@
import ListKeymap from '@tiptap/extension-list-keymap';
import { ListKeymap } from '@tiptap/extension-list-keymap';
export const ListKeymapExtension = ListKeymap.configure({
listTypes: [

View File

@@ -1,4 +1,4 @@
import OrderedList from '@tiptap/extension-ordered-list';
import { OrderedList } from '@tiptap/extension-ordered-list';
import { defaultClasses } from '@/renderer/editor/classes';

View File

@@ -1,4 +1,4 @@
import Paragraph from '@tiptap/extension-paragraph';
import { Paragraph } from '@tiptap/extension-paragraph';
import { defaultClasses } from '@/renderer/editor/classes';

View File

@@ -1,4 +1,4 @@
import Placeholder, { PlaceholderOptions } from '@tiptap/extension-placeholder';
import { Placeholder, PlaceholderOptions } from '@tiptap/extension-placeholder';
interface PlaceholderProps extends PlaceholderOptions {
message: string;

View File

@@ -1,8 +1,6 @@
import { Extension } from '@tiptap/core';
interface TabKeymapExtensionOptions {}
export const TabKeymapExtension = Extension.create<TabKeymapExtensionOptions>({
export const TabKeymapExtension = Extension.create({
name: 'tabKeymap',
addKeyboardShortcuts() {
return {

View File

@@ -1,4 +1,4 @@
import TaskItem from '@tiptap/extension-task-item';
import { TaskItem } from '@tiptap/extension-task-item';
import { defaultClasses } from '@/renderer/editor/classes';

View File

@@ -1,4 +1,4 @@
import TaskList from '@tiptap/extension-task-list';
import { TaskList } from '@tiptap/extension-task-list';
import { defaultClasses } from '@/renderer/editor/classes';

View File

@@ -1,11 +1,15 @@
import { Extension } from '@tiptap/core';
import { NodeType } from '@tiptap/pm/model';
import { NodeType, Node } from '@tiptap/pm/model';
import { Plugin, PluginKey } from '@tiptap/pm/state';
const nodeEqualsType = ({ types, node }: { types: NodeType[]; node: any }) => {
return (
(Array.isArray(types) && types.includes(node?.type)) || node?.type === types
);
const nodeEqualsType = ({
types,
node,
}: {
types: NodeType[];
node: Node | null;
}) => {
return Array.isArray(types) && node?.type && types.includes(node.type);
};
export interface TrailingNodeOptions {

View File

@@ -13,7 +13,7 @@ const isValidUrl = (url: string) => {
try {
new URL(url);
return true;
} catch (e) {
} catch {
return false;
}
};
@@ -24,7 +24,7 @@ const getUrlFromString = (str: string): string | null => {
if (str.includes('.') && !str.includes(' ')) {
return new URL(`https://${str}`).toString();
}
} catch (e) {
} catch {
return null;
}

View File

@@ -4,7 +4,7 @@ import { JSONContent } from '@tiptap/core';
interface MarkRendererProps {
node: JSONContent;
children: any | any[];
children: React.ReactNode | React.ReactNode[];
}
export const MarkRenderer = ({ node, children }: MarkRendererProps) => {

View File

@@ -16,13 +16,6 @@ type ToasterToast = ToastProps & {
action?: ToastActionElement;
};
const actionTypes = {
ADD_TOAST: 'ADD_TOAST',
UPDATE_TOAST: 'UPDATE_TOAST',
DISMISS_TOAST: 'DISMISS_TOAST',
REMOVE_TOAST: 'REMOVE_TOAST',
} as const;
let count = 0;
function genId() {
@@ -30,7 +23,12 @@ function genId() {
return count.toString();
}
type ActionType = typeof actionTypes;
type ActionType = {
ADD_TOAST: 'ADD_TOAST';
UPDATE_TOAST: 'UPDATE_TOAST';
DISMISS_TOAST: 'DISMISS_TOAST';
REMOVE_TOAST: 'REMOVE_TOAST';
};
type Action =
| {

View File

@@ -1,3 +1,4 @@
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
export interface CommandMap {}
export type CommandInput = CommandMap[keyof CommandMap]['input'];

View File

@@ -994,7 +994,7 @@ const recordMatchesUrlFilter = (
return false;
};
export const isFilterableField = (field: FieldAttributes) => {
export const isFilterableField = (_: FieldAttributes) => {
// TODO: Implement this
return true;
};

View File

@@ -4,9 +4,10 @@ import {
getIdTypeFromNode,
generateNodeIndex,
compareString,
Block,
BlockLeaf,
} from '@colanode/core';
import { JSONContent } from '@tiptap/core';
import { Block, BlockLeaf } from '@colanode/core';
const leafBlockTypes = new Set([
EditorNodeTypes.Paragraph,

View File

@@ -1,6 +1,12 @@
import { serverService } from '@/main/services/server-service';
import { BackoffCalculator } from '@/shared/lib/backoff-calculator';
import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios';
import axios, {
isAxiosError,
AxiosInstance,
AxiosRequestConfig,
AxiosResponse,
AxiosError,
} from 'axios';
interface HttpClientRequestConfig extends AxiosRequestConfig {
domain: string;
@@ -38,9 +44,9 @@ class HttpClient {
}
return response;
} catch (error: any) {
} catch (error) {
// If error is related to server availability, increase backoff
if (this.isServerError(error)) {
if (isAxiosError(error) && this.isServerError(error)) {
if (!this.backoffs.has(config.domain)) {
this.backoffs.set(config.domain, new BackoffCalculator());
}
@@ -53,11 +59,11 @@ class HttpClient {
}
}
private isServerError(error: any): boolean {
private isServerError(error: AxiosError): boolean {
if (error.code === 'ECONNABORTED' || error.code === 'ETIMEDOUT') {
return true;
}
const status = error.response?.status;
const status = error.response?.status ?? 0;
return (status >= 500 && status < 600) || status === 429;
}
@@ -76,15 +82,15 @@ class HttpClient {
public async get<T>(
path: string,
config: HttpClientRequestConfig
): Promise<AxiosResponse<T, any>> {
): Promise<AxiosResponse<T>> {
return this.request<T>('get', path, config);
}
public async post<T>(
path: string,
data: any,
data: unknown,
config: HttpClientRequestConfig
): Promise<AxiosResponse<T, any>> {
): Promise<AxiosResponse<T>> {
return this.request<T>('post', path, {
...config,
data,
@@ -93,9 +99,9 @@ class HttpClient {
public async put<T>(
path: string,
data: any,
data: unknown,
config: HttpClientRequestConfig
): Promise<AxiosResponse<T, any>> {
): Promise<AxiosResponse<T>> {
return this.request<T>('put', path, {
...config,
data,
@@ -105,7 +111,7 @@ class HttpClient {
public async delete<T>(
path: string,
config: HttpClientRequestConfig
): Promise<AxiosResponse<T, any>> {
): Promise<AxiosResponse<T>> {
return this.request<T>('delete', path, config);
}
}

View File

@@ -213,6 +213,7 @@ export const languages: CodeLanguage[] = [
];
const parseNodes = (
// eslint-disable-next-line @typescript-eslint/no-explicit-any
nodes: any[],
className: string[] = []
): CodeHighlightNode[] => {

View File

@@ -1,3 +1,4 @@
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
export interface MutationMap {}
export type MutationInput = MutationMap[keyof MutationMap]['input'];

View File

@@ -3,7 +3,7 @@ export type NodeAttributeSetMutationInput = {
userId: string;
nodeId: string;
path: string;
value: any;
value: unknown;
};
export type NodeAttributeSetMutationOutput = {

View File

@@ -1,3 +1,4 @@
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
export interface QueryMap {}
export type QueryInput = QueryMap[keyof QueryMap]['input'];

View File

@@ -102,7 +102,7 @@ export type UploadDeletedEvent = {
export type QueryResultUpdatedEvent = {
type: 'query_result_updated';
id: string;
result: any;
result: unknown;
};
export type RadarDataUpdatedEvent = {

View File

@@ -1,8 +1,6 @@
import { CommandMap } from '@/shared/commands';
import { QueryInput } from '@/shared/queries';
import { CommandMap, CommandInput } from '@/shared/commands';
import { QueryInput, QueryMap } from '@/shared/queries';
import { MutationInput, MutationMap } from '@/shared/mutations';
import { QueryMap } from '@/shared/queries';
import { CommandInput } from '@/shared/commands';
import { EventBus } from '@/shared/lib/event-bus';
export interface ColanodeApi {

1875
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -13,6 +13,7 @@
"type": "git",
"url": "https://github.com/colanode/colanode"
},
"packageManager": "npm@10.9.0",
"scripts": {
"compile": "turbo run compile",
"build": "turbo run build",
@@ -25,7 +26,9 @@
},
"devDependencies": {
"@types/lodash-es": "^4.17.12",
"eslint": "^9.16.0",
"@typescript-eslint/eslint-plugin": "^8.16.0",
"eslint": "^8.57.1",
"eslint-plugin-import": "^2.31.0",
"prettier": "^3.4.1",
"turbo": "^2.3.3",
"typescript": "^5.7.2",

View File

@@ -0,0 +1,8 @@
{
"env": {
"browser": true,
"es6": true,
"node": true
},
"extends": ["../../.eslintrc.json"]
}

View File

@@ -13,7 +13,7 @@
"scripts": {
"compile": "tsc --noEmit",
"test": "vitest",
"lint": "eslint . --max-warnings 0",
"lint": "eslint src --ext .ts --max-warnings 0",
"build": "tsc",
"coverage": "vitest run --coverage "
},

View File

@@ -33,7 +33,7 @@ export enum IdType {
Record = 'rc',
Folder = 'fl',
View = 'vw',
Field = 'fi',
Field = 'fd',
SelectOption = 'so',
ViewFilter = 'vf',
ViewSort = 'vs',

View File

@@ -47,7 +47,7 @@ export const isValidUrl = (url: string) => {
try {
new URL(url);
return true;
} catch (err) {
} catch {
return false;
}
};

View File

@@ -1,4 +1,4 @@
import { NodeType } from '~/registry';
import { NodeType } from '../registry';
import {
ServerInteraction,
ServerCollaboration,

View File

@@ -5,4 +5,4 @@ export type ServerConfig = {
attributes: ServerAttributes;
};
export type ServerAttributes = {};
export type ServerAttributes = Record<string, unknown>;

View File

@@ -1,6 +1,6 @@
import { NodeRole } from '~/registry/core';
import { NodeRole } from '../registry/core';
import { InteractionAttributes } from './interactions';
import { NodeType } from '~/registry';
import { NodeType } from '../registry';
export type SyncNodeTransactionsInput = {
transactions: LocalNodeTransaction[];

View File

@@ -0,0 +1,8 @@
{
"env": {
"browser": true,
"es6": true,
"node": true
},
"extends": ["../../.eslintrc.json"]
}

View File

@@ -1,3 +1,4 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import { z, ZodSchema } from 'zod';
import * as Y from 'yjs';
import { ZodText } from '@colanode/core';
@@ -170,7 +171,7 @@ export class YDoc {
}
const deletedKeys = Array.from(yMap.keys()).filter(
(key) => !attributes.hasOwnProperty(key)
(key) => !Object.prototype.hasOwnProperty.call(attributes, key)
);
for (const key of deletedKeys) {
@@ -324,7 +325,7 @@ export class YDoc {
}
const deletedKeys = Array.from(yMap.keys()).filter(
(key) => !record.hasOwnProperty(key)
(key) => !Object.prototype.hasOwnProperty.call(record, key)
);
for (const key of deletedKeys) {