mirror of
https://github.com/outline/outline.git
synced 2026-06-13 11:25:03 +03:00
chore: promote no-explicit-any from warn to error (#12244)
* chore: promote no-explicit-any from warn to error and resolve violations Upgrades the oxlint rule severity and removes all 40 existing `no-explicit-any` warnings across the codebase. Most call sites gained proper types (SharedEditor refs, JSONNode/JSONMark for ProseMirror JSON walking, DocumentsStore, dd-trace `Span` parameter inference, prosemirror Fragment public API in place of internal `(fragment as any).content`). A few load-bearing `any` uses were preserved with scoped disable comments where changing the type would cascade widely (Sequelize JSONB columns on `Event`, the `withTracing` higher-order function generic, `Extension.options` consumed by many subclasses, dd-trace's `req` patching). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
+1
-1
@@ -31,7 +31,7 @@
|
|||||||
"no-empty-pattern": "error",
|
"no-empty-pattern": "error",
|
||||||
"no-empty-static-block": "error",
|
"no-empty-static-block": "error",
|
||||||
"no-ex-assign": "error",
|
"no-ex-assign": "error",
|
||||||
"no-explicit-any": "warn",
|
"no-explicit-any": "error",
|
||||||
"no-extra-boolean-cast": "error",
|
"no-extra-boolean-cast": "error",
|
||||||
"no-fallthrough": "error",
|
"no-fallthrough": "error",
|
||||||
"no-func-assign": "error",
|
"no-func-assign": "error",
|
||||||
|
|||||||
@@ -119,10 +119,12 @@ export default class ComponentView {
|
|||||||
// Apply classes from inline decorations.
|
// Apply classes from inline decorations.
|
||||||
this.decorations.forEach((decoration) => {
|
this.decorations.forEach((decoration) => {
|
||||||
// For inline decorations, attrs contain the class property.
|
// For inline decorations, attrs contain the class property.
|
||||||
const attrs = (decoration as any).type?.attrs;
|
const attrs = (
|
||||||
|
decoration as Decoration & { type?: { attrs?: { class?: string } } }
|
||||||
|
).type?.attrs;
|
||||||
if (attrs?.class) {
|
if (attrs?.class) {
|
||||||
const classes = attrs.class.split(" ");
|
const classes = attrs.class.split(" ");
|
||||||
classes.forEach((className: string) => {
|
classes.forEach((className) => {
|
||||||
if (className && this.dom) {
|
if (className && this.dom) {
|
||||||
this.dom.classList.add(className);
|
this.dom.classList.add(className);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -345,7 +345,7 @@ function SuggestionsMenu<T extends MenuItem>(props: Props<T>) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const triggerFilePick = (accept: string, attrs?: Record<string, any>) => {
|
const triggerFilePick = (accept: string, attrs?: Record<string, unknown>) => {
|
||||||
if (inputRef.current) {
|
if (inputRef.current) {
|
||||||
if (accept) {
|
if (accept) {
|
||||||
inputRef.current.accept = accept;
|
inputRef.current.accept = accept;
|
||||||
@@ -887,7 +887,7 @@ function SuggestionsMenu<T extends MenuItem>(props: Props<T>) {
|
|||||||
onPointerMove={handlePointerMove}
|
onPointerMove={handlePointerMove}
|
||||||
onPointerDown={handlePointerDown}
|
onPointerDown={handlePointerDown}
|
||||||
>
|
>
|
||||||
{props.renderMenuItem(item as any, index, {
|
{props.renderMenuItem(item as unknown as T, index, {
|
||||||
selected: index === selectedIndex,
|
selected: index === selectedIndex,
|
||||||
disclosure: hasChildren,
|
disclosure: hasChildren,
|
||||||
onClick: handleOnClick,
|
onClick: handleOnClick,
|
||||||
@@ -1053,7 +1053,7 @@ function SuggestionsMenu<T extends MenuItem>(props: Props<T>) {
|
|||||||
key={`sub-${childIndex}-${child.name}`}
|
key={`sub-${childIndex}-${child.name}`}
|
||||||
onPointerMove={handleChildPointerMove}
|
onPointerMove={handleChildPointerMove}
|
||||||
>
|
>
|
||||||
{props.renderMenuItem(child as any, childIndex, {
|
{props.renderMenuItem(child as unknown as T, childIndex, {
|
||||||
selected: childIndex === submenu.selectedIndex,
|
selected: childIndex === submenu.selectedIndex,
|
||||||
onClick: handleChildClick,
|
onClick: handleChildClick,
|
||||||
})}
|
})}
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import some from "lodash/some";
|
|
||||||
import { action, observable } from "mobx";
|
import { action, observable } from "mobx";
|
||||||
import type { EditorState, Selection } from "prosemirror-state";
|
import type { EditorState, Selection } from "prosemirror-state";
|
||||||
import { NodeSelection, Plugin, TextSelection } from "prosemirror-state";
|
import { NodeSelection, Plugin, TextSelection } from "prosemirror-state";
|
||||||
@@ -82,12 +81,12 @@ export default class SelectionToolbarExtension extends Extension {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const slice = selection.content();
|
const fragment = selection.content().content;
|
||||||
const fragment = slice.content;
|
|
||||||
const nodes = (fragment as any).content;
|
|
||||||
|
|
||||||
if (some(nodes, (n) => n.content.size)) {
|
for (let i = 0; i < fragment.childCount; i++) {
|
||||||
return selection;
|
if (fragment.child(i).content.size) {
|
||||||
|
return selection;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -28,9 +28,9 @@ export default class UpArrowAtStart extends Extension {
|
|||||||
const isAtDocStart = $pos.parentOffset === 0 && $pos.depth <= 1;
|
const isAtDocStart = $pos.parentOffset === 0 && $pos.depth <= 1;
|
||||||
|
|
||||||
if (isAtDocStart) {
|
if (isAtDocStart) {
|
||||||
// Call the onUpArrowAtStart callback if it exists
|
const props = this.editor.props as {
|
||||||
// Cast to any to access the custom prop since it's not in the base Props type
|
onUpArrowAtStart?: () => void;
|
||||||
const props = this.editor.props as any;
|
};
|
||||||
if (props.onUpArrowAtStart) {
|
if (props.onUpArrowAtStart) {
|
||||||
props.onUpArrowAtStart();
|
props.onUpArrowAtStart();
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
+12
-7
@@ -38,7 +38,11 @@ import { basicExtensions as extensions } from "@shared/editor/nodes";
|
|||||||
import type Node from "@shared/editor/nodes/Node";
|
import type Node from "@shared/editor/nodes/Node";
|
||||||
import type ReactNode from "@shared/editor/nodes/ReactNode";
|
import type ReactNode from "@shared/editor/nodes/ReactNode";
|
||||||
import type { ComponentProps } from "@shared/editor/types";
|
import type { ComponentProps } from "@shared/editor/types";
|
||||||
import type { ProsemirrorData, UserPreferences } from "@shared/types";
|
import type {
|
||||||
|
ProsemirrorData,
|
||||||
|
ProsemirrorMark,
|
||||||
|
UserPreferences,
|
||||||
|
} from "@shared/types";
|
||||||
import { ProsemirrorHelper } from "@shared/utils/ProsemirrorHelper";
|
import { ProsemirrorHelper } from "@shared/utils/ProsemirrorHelper";
|
||||||
import EventEmitter from "@shared/utils/events";
|
import EventEmitter from "@shared/utils/events";
|
||||||
import type Document from "~/models/Document";
|
import type Document from "~/models/Document";
|
||||||
@@ -117,7 +121,8 @@ export type Props = {
|
|||||||
/** Callback when user uses cancel key combo */
|
/** Callback when user uses cancel key combo */
|
||||||
onCancel?: () => void;
|
onCancel?: () => void;
|
||||||
/** Callback when user changes editor content */
|
/** Callback when user changes editor content */
|
||||||
onChange?: (value: () => any) => void;
|
// oxlint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
onChange?: (value: (asString?: boolean, trim?: boolean) => any) => void;
|
||||||
/** Callback when a comment mark is clicked */
|
/** Callback when a comment mark is clicked */
|
||||||
onClickCommentMark?: (commentId: string) => void;
|
onClickCommentMark?: (commentId: string) => void;
|
||||||
/**
|
/**
|
||||||
@@ -755,9 +760,9 @@ export class Editor extends React.PureComponent<
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (isArray(node.attrs?.marks)) {
|
if (isArray(node.attrs?.marks)) {
|
||||||
const existingMarks = node.attrs.marks;
|
const existingMarks = node.attrs.marks as ProsemirrorMark[];
|
||||||
const updatedMarks = existingMarks.filter(
|
const updatedMarks = existingMarks.filter(
|
||||||
(mark: any) => mark.attrs.id !== commentId
|
(mark) => mark.attrs?.id !== commentId
|
||||||
);
|
);
|
||||||
const attrs = {
|
const attrs = {
|
||||||
...node.attrs,
|
...node.attrs,
|
||||||
@@ -800,9 +805,9 @@ export class Editor extends React.PureComponent<
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (isArray(node.attrs?.marks)) {
|
if (isArray(node.attrs?.marks)) {
|
||||||
const existingMarks = node.attrs.marks;
|
const existingMarks = node.attrs.marks as ProsemirrorMark[];
|
||||||
const updatedMarks = existingMarks.map((mark: any) =>
|
const updatedMarks = existingMarks.map((mark) =>
|
||||||
mark.type === "comment" && mark.attrs.id === commentId
|
mark.type === "comment" && mark.attrs?.id === commentId
|
||||||
? { ...mark, attrs: { ...mark.attrs, ...attrs } }
|
? { ...mark, attrs: { ...mark.attrs, ...attrs } }
|
||||||
: mark
|
: mark
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import styled from "styled-components";
|
|||||||
import { s } from "@shared/styles";
|
import { s } from "@shared/styles";
|
||||||
import { StatusFilter } from "@shared/types";
|
import { StatusFilter } from "@shared/types";
|
||||||
import type Collection from "~/models/Collection";
|
import type Collection from "~/models/Collection";
|
||||||
|
import type DocumentsStore from "~/stores/DocumentsStore";
|
||||||
import CenteredContent from "~/components/CenteredContent";
|
import CenteredContent from "~/components/CenteredContent";
|
||||||
import { CollectionBreadcrumb } from "~/components/CollectionBreadcrumb";
|
import { CollectionBreadcrumb } from "~/components/CollectionBreadcrumb";
|
||||||
import Heading from "~/components/Heading";
|
import Heading from "~/components/Heading";
|
||||||
@@ -362,7 +363,13 @@ const Content = styled.div`
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
const RecentDocuments = observer(
|
const RecentDocuments = observer(
|
||||||
({ collection, documents }: { collection: Collection; documents: any }) => {
|
({
|
||||||
|
collection,
|
||||||
|
documents,
|
||||||
|
}: {
|
||||||
|
collection: Collection;
|
||||||
|
documents: DocumentsStore;
|
||||||
|
}) => {
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
void collection.fetchDocuments();
|
void collection.fetchDocuments();
|
||||||
}, [collection]);
|
}, [collection]);
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import type { RefHandle } from "~/components/ContentEditable";
|
|||||||
import { useDocumentContext } from "~/components/DocumentContext";
|
import { useDocumentContext } from "~/components/DocumentContext";
|
||||||
import type { Props as EditorProps } from "~/components/Editor";
|
import type { Props as EditorProps } from "~/components/Editor";
|
||||||
import Editor from "~/components/Editor";
|
import Editor from "~/components/Editor";
|
||||||
|
import type { Editor as SharedEditor } from "~/editor";
|
||||||
import Flex from "~/components/Flex";
|
import Flex from "~/components/Flex";
|
||||||
import Time from "~/components/Time";
|
import Time from "~/components/Time";
|
||||||
import { withUIExtensions } from "~/editor/extensions";
|
import { withUIExtensions } from "~/editor/extensions";
|
||||||
@@ -59,7 +60,8 @@ type Props = Omit<EditorProps, "editorStyle"> & {
|
|||||||
* The main document editor includes an editable title with metadata below it,
|
* The main document editor includes an editable title with metadata below it,
|
||||||
* and support for commenting.
|
* and support for commenting.
|
||||||
*/
|
*/
|
||||||
function DocumentEditor(props: Props, ref: React.RefObject<any>) {
|
function DocumentEditor(props: Props, ref: React.ForwardedRef<SharedEditor>) {
|
||||||
|
const editorRef = React.useRef<SharedEditor>(null);
|
||||||
const titleRef = React.useRef<RefHandle>(null);
|
const titleRef = React.useRef<RefHandle>(null);
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const match = useRouteMatch();
|
const match = useRouteMatch();
|
||||||
@@ -87,10 +89,10 @@ function DocumentEditor(props: Props, ref: React.RefObject<any>) {
|
|||||||
const iconColor = document.color ?? (first(colorPalette) as string);
|
const iconColor = document.color ?? (first(colorPalette) as string);
|
||||||
const childRef = React.useRef<HTMLDivElement>(null);
|
const childRef = React.useRef<HTMLDivElement>(null);
|
||||||
const focusAtStart = React.useCallback(() => {
|
const focusAtStart = React.useCallback(() => {
|
||||||
if (ref.current) {
|
if (editorRef.current) {
|
||||||
ref.current.focusAtStart();
|
editorRef.current.focusAtStart();
|
||||||
}
|
}
|
||||||
}, [ref]);
|
}, []);
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
if (focusedComment && focusedComment.documentId === document.id) {
|
if (focusedComment && focusedComment.documentId === document.id) {
|
||||||
@@ -113,15 +115,15 @@ function DocumentEditor(props: Props, ref: React.RefObject<any>) {
|
|||||||
|
|
||||||
const handleGoToNextInput = React.useCallback(
|
const handleGoToNextInput = React.useCallback(
|
||||||
(insertParagraph: boolean) => {
|
(insertParagraph: boolean) => {
|
||||||
if (insertParagraph && ref.current) {
|
if (insertParagraph && editorRef.current) {
|
||||||
const { view } = ref.current;
|
const { view } = editorRef.current;
|
||||||
const { dispatch, state } = view;
|
const { dispatch, state } = view;
|
||||||
dispatch(state.tr.insert(0, state.schema.nodes.paragraph.create()));
|
dispatch(state.tr.insert(0, state.schema.nodes.paragraph.create()));
|
||||||
}
|
}
|
||||||
|
|
||||||
focusAtStart();
|
focusAtStart();
|
||||||
},
|
},
|
||||||
[focusAtStart, ref]
|
[focusAtStart]
|
||||||
);
|
);
|
||||||
|
|
||||||
// Create a Comment model in local store when a comment mark is created, this
|
// Create a Comment model in local store when a comment mark is created, this
|
||||||
@@ -231,7 +233,7 @@ function DocumentEditor(props: Props, ref: React.RefObject<any>) {
|
|||||||
/>
|
/>
|
||||||
) : null}
|
) : null}
|
||||||
<EditorComponent
|
<EditorComponent
|
||||||
ref={mergeRefs([ref, handleRefChanged])}
|
ref={mergeRefs([ref, editorRef, handleRefChanged])}
|
||||||
lang={getLangFor(document.language)}
|
lang={getLangFor(document.language)}
|
||||||
autoFocus={!!document.title && !props.defaultValue}
|
autoFocus={!!document.title && !props.defaultValue}
|
||||||
placeholder={t("Type '/' to insert, or start writing…")}
|
placeholder={t("Type '/' to insert, or start writing…")}
|
||||||
|
|||||||
@@ -13,8 +13,8 @@ type Item = Revision | Event<Document>;
|
|||||||
type Props = {
|
type Props = {
|
||||||
items: Item[];
|
items: Item[];
|
||||||
document: Document;
|
document: Document;
|
||||||
fetch: (options: Record<string, any> | undefined) => Promise<Item[]>;
|
fetch: (options: Record<string, unknown> | undefined) => Promise<Item[]>;
|
||||||
options?: Record<string, any>;
|
options?: Record<string, unknown>;
|
||||||
heading?: React.ReactNode;
|
heading?: React.ReactNode;
|
||||||
empty?: JSX.Element;
|
empty?: JSX.Element;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import {
|
|||||||
useEffect,
|
useEffect,
|
||||||
forwardRef,
|
forwardRef,
|
||||||
useRef,
|
useRef,
|
||||||
|
type ForwardedRef,
|
||||||
} from "react";
|
} from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { useHistory } from "react-router-dom";
|
import { useHistory } from "react-router-dom";
|
||||||
@@ -18,6 +19,7 @@ import EDITOR_VERSION from "@shared/editor/version";
|
|||||||
import { supportsPassiveListener } from "@shared/utils/browser";
|
import { supportsPassiveListener } from "@shared/utils/browser";
|
||||||
import type { Props as EditorProps } from "~/components/Editor";
|
import type { Props as EditorProps } from "~/components/Editor";
|
||||||
import Editor from "~/components/Editor";
|
import Editor from "~/components/Editor";
|
||||||
|
import type { Editor as SharedEditor } from "~/editor";
|
||||||
import MultiplayerExtension from "~/editor/extensions/Multiplayer";
|
import MultiplayerExtension from "~/editor/extensions/Multiplayer";
|
||||||
import env from "~/env";
|
import env from "~/env";
|
||||||
import useCurrentUser from "~/hooks/useCurrentUser";
|
import useCurrentUser from "~/hooks/useCurrentUser";
|
||||||
@@ -50,7 +52,10 @@ type MessageEvent = {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
function MultiplayerEditor({ onSynced, ...props }: Props, ref: any) {
|
function MultiplayerEditor(
|
||||||
|
{ onSynced, ...props }: Props,
|
||||||
|
ref: ForwardedRef<SharedEditor>
|
||||||
|
) {
|
||||||
const documentId = props.id;
|
const documentId = props.id;
|
||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
@@ -352,4 +357,4 @@ function MultiplayerEditor({ onSynced, ...props }: Props, ref: any) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default forwardRef<typeof MultiplayerEditor, Props>(MultiplayerEditor);
|
export default forwardRef<SharedEditor, Props>(MultiplayerEditor);
|
||||||
|
|||||||
+10
-24
@@ -1,6 +1,7 @@
|
|||||||
import data from "@emoji-mart/data";
|
import data from "@emoji-mart/data";
|
||||||
import type { EmojiMartData } from "@emoji-mart/data";
|
import type { EmojiMartData } from "@emoji-mart/data";
|
||||||
import { Schema } from "prosemirror-model";
|
import { Schema } from "prosemirror-model";
|
||||||
|
import type { Editor } from "~/editor";
|
||||||
import ExtensionManager from "@shared/editor/lib/ExtensionManager";
|
import ExtensionManager from "@shared/editor/lib/ExtensionManager";
|
||||||
import { populateEmojiData } from "@shared/editor/lib/emoji";
|
import { populateEmojiData } from "@shared/editor/lib/emoji";
|
||||||
import {
|
import {
|
||||||
@@ -12,6 +13,12 @@ import Mention from "@shared/editor/nodes/Mention";
|
|||||||
|
|
||||||
populateEmojiData(data as EmojiMartData);
|
populateEmojiData(data as EmojiMartData);
|
||||||
|
|
||||||
|
// Server-side parsing/serializing only requires schema and a few static props,
|
||||||
|
// but the Extension API expects a full Editor. This stub satisfies bindEditor
|
||||||
|
// without instantiating the React component.
|
||||||
|
const stubEditor = (s: Schema): Editor =>
|
||||||
|
({ schema: s, props: { theme: { isDark: false } } }) as unknown as Editor;
|
||||||
|
|
||||||
const extensions = withComments(richExtensions);
|
const extensions = withComments(richExtensions);
|
||||||
export const extensionManager = new ExtensionManager(extensions);
|
export const extensionManager = new ExtensionManager(extensions);
|
||||||
|
|
||||||
@@ -21,14 +28,7 @@ export const schema = new Schema({
|
|||||||
});
|
});
|
||||||
|
|
||||||
for (const extension of extensionManager.extensions) {
|
for (const extension of extensionManager.extensions) {
|
||||||
extension.bindEditor({
|
extension.bindEditor(stubEditor(schema));
|
||||||
schema,
|
|
||||||
props: {
|
|
||||||
theme: {
|
|
||||||
isDark: false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} as any);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const parser = extensionManager.parser({
|
export const parser = extensionManager.parser({
|
||||||
@@ -48,14 +48,7 @@ export const basicSchema = new Schema({
|
|||||||
});
|
});
|
||||||
|
|
||||||
for (const extension of basicExtensionManager.extensions) {
|
for (const extension of basicExtensionManager.extensions) {
|
||||||
extension.bindEditor({
|
extension.bindEditor(stubEditor(basicSchema));
|
||||||
schema: basicSchema,
|
|
||||||
props: {
|
|
||||||
theme: {
|
|
||||||
isDark: false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} as any);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const basicParser = basicExtensionManager.parser({
|
export const basicParser = basicExtensionManager.parser({
|
||||||
@@ -72,14 +65,7 @@ export const commentSchema = new Schema({
|
|||||||
});
|
});
|
||||||
|
|
||||||
for (const extension of commentExtensionManager.extensions) {
|
for (const extension of commentExtensionManager.extensions) {
|
||||||
extension.bindEditor({
|
extension.bindEditor(stubEditor(commentSchema));
|
||||||
schema: commentSchema,
|
|
||||||
props: {
|
|
||||||
theme: {
|
|
||||||
isDark: false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} as any);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const commentParser = commentExtensionManager.parser({
|
export const commentParser = commentExtensionManager.parser({
|
||||||
|
|||||||
@@ -194,12 +194,11 @@ class Logger {
|
|||||||
// Errors have non-enumerable message/stack which are dropped by spreads
|
// Errors have non-enumerable message/stack which are dropped by spreads
|
||||||
// and JSON serialization, so convert them to a plain object up-front.
|
// and JSON serialization, so convert them to a plain object up-front.
|
||||||
if (input instanceof Error) {
|
if (input instanceof Error) {
|
||||||
// oxlint-disable-next-line @typescript-eslint/no-explicit-any
|
|
||||||
return {
|
return {
|
||||||
name: input.name,
|
name: input.name,
|
||||||
message: input.message,
|
message: input.message,
|
||||||
stack: input.stack,
|
stack: input.stack,
|
||||||
} as any as T;
|
} as unknown as T;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Short circuit if we're not in production to enable easier debugging
|
// Short circuit if we're not in production to enable easier debugging
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ function isExplicitlyNonReportable(error: Error): error is ReportableError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type PrivateDatadogContext = {
|
type PrivateDatadogContext = {
|
||||||
|
// oxlint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
req: Record<string, any> & {
|
req: Record<string, any> & {
|
||||||
_datadog?: {
|
_datadog?: {
|
||||||
span?: Span;
|
span?: Span;
|
||||||
@@ -41,7 +42,10 @@ const getCurrentSpan = (): Span | null => tracer.scope().active();
|
|||||||
* @param tags An object with the tags to add to the span
|
* @param tags An object with the tags to add to the span
|
||||||
* @param span An optional span object to add the tags to. If none provided,the current span will be used.
|
* @param span An optional span object to add the tags to. If none provided,the current span will be used.
|
||||||
*/
|
*/
|
||||||
export function addTags(tags: Record<string, any>, span?: Span | null): void {
|
export function addTags(
|
||||||
|
tags: Parameters<Span["addTags"]>[0],
|
||||||
|
span?: Span | null
|
||||||
|
): void {
|
||||||
if (tracer) {
|
if (tracer) {
|
||||||
const currentSpan = span || getCurrentSpan();
|
const currentSpan = span || getCurrentSpan();
|
||||||
|
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ class Event extends IdModel<
|
|||||||
* Note that the `data` column will be visible to the client and API requests.
|
* Note that the `data` column will be visible to the client and API requests.
|
||||||
*/
|
*/
|
||||||
@Column(DataType.JSONB)
|
@Column(DataType.JSONB)
|
||||||
|
// oxlint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
data: Record<string, any> | null;
|
data: Record<string, any> | null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -67,6 +68,7 @@ class Event extends IdModel<
|
|||||||
* used for arbitrary data associated with the event.
|
* used for arbitrary data associated with the event.
|
||||||
*/
|
*/
|
||||||
@Column(DataType.JSONB)
|
@Column(DataType.JSONB)
|
||||||
|
// oxlint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
changes: Record<string, any> | null;
|
changes: Record<string, any> | null;
|
||||||
|
|
||||||
// hooks
|
// hooks
|
||||||
|
|||||||
@@ -757,7 +757,7 @@ export class ProsemirrorHelper extends SharedProsemirrorHelper {
|
|||||||
// Create a new document with the emoji removed from the text
|
// Create a new document with the emoji removed from the text
|
||||||
const json = doc.toJSON();
|
const json = doc.toJSON();
|
||||||
|
|
||||||
function removeEmojiFromNode(node: any): any {
|
function removeEmojiFromNode(node: ProsemirrorData): ProsemirrorData {
|
||||||
if (node.type === "text" && node.text && node.text.startsWith(emoji)) {
|
if (node.type === "text" && node.text && node.text.startsWith(emoji)) {
|
||||||
return {
|
return {
|
||||||
...node,
|
...node,
|
||||||
@@ -768,7 +768,7 @@ export class ProsemirrorHelper extends SharedProsemirrorHelper {
|
|||||||
let found = false;
|
let found = false;
|
||||||
return {
|
return {
|
||||||
...node,
|
...node,
|
||||||
content: node.content.map((child: any) => {
|
content: node.content.map((child) => {
|
||||||
if (found) {
|
if (found) {
|
||||||
return child;
|
return child;
|
||||||
}
|
}
|
||||||
@@ -783,7 +783,7 @@ export class ProsemirrorHelper extends SharedProsemirrorHelper {
|
|||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
const modifiedJson = removeEmojiFromNode(json);
|
const modifiedJson = removeEmojiFromNode(json as ProsemirrorData);
|
||||||
return {
|
return {
|
||||||
emoji,
|
emoji,
|
||||||
doc: Node.fromJSON(schema, modifiedJson),
|
doc: Node.fromJSON(schema, modifiedJson),
|
||||||
@@ -798,7 +798,7 @@ export class ProsemirrorHelper extends SharedProsemirrorHelper {
|
|||||||
* @returns A cleanup function to restore the global environment.
|
* @returns A cleanup function to restore the global environment.
|
||||||
*/
|
*/
|
||||||
public static patchGlobalEnv(domWindow: JSDOM["window"]) {
|
public static patchGlobalEnv(domWindow: JSDOM["window"]) {
|
||||||
const g = global as any;
|
const g = global as unknown as Record<string, unknown>;
|
||||||
|
|
||||||
const globalParams = {
|
const globalParams = {
|
||||||
window: g.window,
|
window: g.window,
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { BaseTask } from "./base/BaseTask";
|
|||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
templateName: string;
|
templateName: string;
|
||||||
props: Record<string, any>;
|
props: Record<string, unknown>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default class EmailTask extends BaseTask<Props> {
|
export default class EmailTask extends BaseTask<Props> {
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ export default function init(
|
|||||||
if (ioHandleUpgrade) {
|
if (ioHandleUpgrade) {
|
||||||
server.removeListener(
|
server.removeListener(
|
||||||
"upgrade",
|
"upgrade",
|
||||||
ioHandleUpgrade as (...args: any[]) => void
|
ioHandleUpgrade as (...args: unknown[]) => void
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -237,7 +237,8 @@ export function monkeyPatchSequelizeErrorsForJest(instance: Sequelize) {
|
|||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
const sequelizeVersion = (Sequelize as any).version;
|
const sequelizeVersion = (Sequelize as unknown as { version: string })
|
||||||
|
.version;
|
||||||
const major = sequelizeVersion.split(".").map(Number)[0];
|
const major = sequelizeVersion.split(".").map(Number)[0];
|
||||||
|
|
||||||
if (major >= 7) {
|
if (major >= 7) {
|
||||||
@@ -250,12 +251,13 @@ export function monkeyPatchSequelizeErrorsForJest(instance: Sequelize) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const origQueryFunc = instance.query.bind(instance);
|
const origQueryFunc = instance.query.bind(instance);
|
||||||
instance.query = (async (...args: any[]) => {
|
instance.query = (async (...args: Parameters<typeof origQueryFunc>) => {
|
||||||
try {
|
try {
|
||||||
return await origQueryFunc(...(args as Parameters<typeof origQueryFunc>));
|
return await origQueryFunc(...args);
|
||||||
} catch (err: any) {
|
} catch (err) {
|
||||||
// Ensure error appears in Jest output, not swallowed by Sequelize internals
|
// Ensure error appears in Jest output, not swallowed by Sequelize internals
|
||||||
Logger.error(err.message, err.parent);
|
const error = err as Error & { parent?: Error };
|
||||||
|
Logger.error(error.message, error.parent ?? error);
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
}) as typeof instance.query;
|
}) as typeof instance.query;
|
||||||
|
|||||||
@@ -86,6 +86,7 @@ export function error(err: unknown): CallToolResult {
|
|||||||
* @param handler - the handler function to wrap.
|
* @param handler - the handler function to wrap.
|
||||||
* @returns the wrapped handler with tracing enabled.
|
* @returns the wrapped handler with tracing enabled.
|
||||||
*/
|
*/
|
||||||
|
/* oxlint-disable @typescript-eslint/no-explicit-any */
|
||||||
export function withTracing<F extends (...args: any[]) => any>(
|
export function withTracing<F extends (...args: any[]) => any>(
|
||||||
toolName: string,
|
toolName: string,
|
||||||
handler: F
|
handler: F
|
||||||
@@ -107,6 +108,7 @@ export function withTracing<F extends (...args: any[]) => any>(
|
|||||||
return handler.apply(this, args);
|
return handler.apply(this, args);
|
||||||
} as F);
|
} as F);
|
||||||
}
|
}
|
||||||
|
/* oxlint-enable @typescript-eslint/no-explicit-any */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Builds a map from document ID to its zero-based index among siblings,
|
* Builds a map from document ID to its zero-based index among siblings,
|
||||||
|
|||||||
@@ -23,11 +23,14 @@ export async function getVersionInfo(currentVersion: string): Promise<{
|
|||||||
// Continue fetching pages until the required versions are found or no more pages
|
// Continue fetching pages until the required versions are found or no more pages
|
||||||
while (nextUrl) {
|
while (nextUrl) {
|
||||||
const response = await fetch(nextUrl);
|
const response = await fetch(nextUrl);
|
||||||
const data = await response.json();
|
const data = (await response.json()) as {
|
||||||
|
results: { name: string }[];
|
||||||
|
next?: string | null;
|
||||||
|
};
|
||||||
|
|
||||||
// Map and filter the versions to keep only full releases
|
// Map and filter the versions to keep only full releases
|
||||||
const pageVersions = data.results
|
const pageVersions = data.results
|
||||||
.map((result: any) => result.name)
|
.map((result) => result.name)
|
||||||
.filter(isFullReleaseVersion);
|
.filter(isFullReleaseVersion);
|
||||||
|
|
||||||
allVersions = allVersions.concat(pageVersions);
|
allVersions = allVersions.concat(pageVersions);
|
||||||
|
|||||||
@@ -55,7 +55,11 @@ export function assertKeysIn(
|
|||||||
Object.keys(obj).forEach((key) => assertIn(key, Object.values(type)));
|
Object.keys(obj).forEach((key) => assertIn(key, Object.values(type)));
|
||||||
}
|
}
|
||||||
|
|
||||||
export const assertSort = (value: string, model: any, message?: string) => {
|
export const assertSort = (
|
||||||
|
value: string,
|
||||||
|
model: { rawAttributes: Record<string, unknown> },
|
||||||
|
message?: string
|
||||||
|
) => {
|
||||||
if (!Object.keys(model.rawAttributes).includes(value)) {
|
if (!Object.keys(model.rawAttributes).includes(value)) {
|
||||||
throw ValidationError(
|
throw ValidationError(
|
||||||
message ?? `${String(value)} is not a valid sort field`
|
message ?? `${String(value)} is not a valid sort field`
|
||||||
|
|||||||
@@ -13,9 +13,11 @@ export type WidgetProps = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export default class Extension {
|
export default class Extension {
|
||||||
|
// oxlint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
options: any;
|
options: any;
|
||||||
editor: Editor;
|
editor: Editor;
|
||||||
|
|
||||||
|
// oxlint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
constructor(options: Record<string, any> = {}) {
|
constructor(options: Record<string, any> = {}) {
|
||||||
this.options = {
|
this.options = {
|
||||||
...this.defaultOptions,
|
...this.defaultOptions,
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
const env = typeof window === "undefined" ? process.env : window.env;
|
const env = typeof window === "undefined" ? process.env : window.env;
|
||||||
|
|
||||||
|
// oxlint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
export default env as Record<string, any>;
|
export default env as Record<string, any>;
|
||||||
|
|||||||
+6
-4
@@ -688,15 +688,17 @@ export type JSONValue =
|
|||||||
|
|
||||||
export type JSONObject = { [x: string]: JSONValue };
|
export type JSONObject = { [x: string]: JSONValue };
|
||||||
|
|
||||||
|
export type ProsemirrorMark = {
|
||||||
|
type: string;
|
||||||
|
attrs?: JSONObject;
|
||||||
|
};
|
||||||
|
|
||||||
export type ProsemirrorData = {
|
export type ProsemirrorData = {
|
||||||
type: string;
|
type: string;
|
||||||
content?: ProsemirrorData[];
|
content?: ProsemirrorData[];
|
||||||
text?: string;
|
text?: string;
|
||||||
attrs?: JSONObject;
|
attrs?: JSONObject;
|
||||||
marks?: {
|
marks?: ProsemirrorMark[];
|
||||||
type: string;
|
|
||||||
attrs?: JSONObject;
|
|
||||||
}[];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export type ProsemirrorDoc = {
|
export type ProsemirrorDoc = {
|
||||||
|
|||||||
Reference in New Issue
Block a user