mirror of
https://github.com/EthanMarti/infio-copilot.git
synced 2026-05-08 08:00:10 +00:00
use eslint auto fix
This commit is contained in:
@@ -9,7 +9,7 @@ import { manualApplyChangesToFile } from '../../utils/apply';
|
||||
import { removeAITags } from '../../utils/content-filter';
|
||||
import { PromptGenerator } from '../../utils/prompt-generator';
|
||||
|
||||
interface InlineEditProps {
|
||||
type InlineEditProps = {
|
||||
source: string;
|
||||
secStartLine: number;
|
||||
secEndLine: number;
|
||||
@@ -17,7 +17,7 @@ interface InlineEditProps {
|
||||
settings: InfioSettings;
|
||||
}
|
||||
|
||||
interface InputAreaProps {
|
||||
type InputAreaProps = {
|
||||
value: string;
|
||||
onChange: (value: string) => void;
|
||||
}
|
||||
@@ -43,7 +43,7 @@ const InputArea: React.FC<InputAreaProps> = ({ value, onChange }) => {
|
||||
);
|
||||
};
|
||||
|
||||
interface ControlAreaProps {
|
||||
type ControlAreaProps = {
|
||||
settings: InfioSettings;
|
||||
onSubmit: () => void;
|
||||
selectedModel: string;
|
||||
@@ -144,15 +144,15 @@ export const InlineEdit: React.FC<InlineEditProps> = ({
|
||||
};
|
||||
|
||||
const parseSmartComposeBlock = (content: string) => {
|
||||
const match = content.match(/<infio_block[^>]*>([\s\S]*?)<\/infio_block>/);
|
||||
const match = /<infio_block[^>]*>([\s\S]*?)<\/infio_block>/.exec(content);
|
||||
if (!match) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const blockContent = match[1].trim();
|
||||
const attributes = match[0].match(/startLine="(\d+)"/);
|
||||
const attributes = /startLine="(\d+)"/.exec(match[0]);
|
||||
const startLine = attributes ? parseInt(attributes[1]) : undefined;
|
||||
const endLineMatch = match[0].match(/endLine="(\d+)"/);
|
||||
const endLineMatch = /endLine="(\d+)"/.exec(match[0]);
|
||||
const endLine = endLineMatch ? parseInt(endLineMatch[1]) : undefined;
|
||||
|
||||
return {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import * as Handlebars from "handlebars";
|
||||
import { err, ok, Result } from "neverthrow";
|
||||
import { Result, err, ok } from "neverthrow";
|
||||
|
||||
import { FewShotExample } from "../../settings/versions";
|
||||
import { CustomLLMModel } from "../../types/llm/model";
|
||||
|
||||
@@ -90,7 +90,7 @@ function startLocationOfEachWord(text: string): number[] {
|
||||
}
|
||||
|
||||
function isWhiteSpaceChar(char: string | undefined): boolean {
|
||||
return char !== undefined && char.match(/\s/) !== null;
|
||||
return char !== undefined && (/\s/.exec(char)) !== null;
|
||||
}
|
||||
|
||||
export default RemoveOverlap;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { generateRandomString } from "../utils";
|
||||
import Context from "../context-detection";
|
||||
import { PrefixAndSuffix, PreProcessor } from "../types";
|
||||
import { PreProcessor, PrefixAndSuffix } from "../types";
|
||||
import { generateRandomString } from "../utils";
|
||||
|
||||
const DATA_VIEW_REGEX = /```dataview(js){0,1}(.|\n)*?```/gm;
|
||||
const UNIQUE_CURSOR = `${generateRandomString(16)}`;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import Context from "../context-detection";
|
||||
import { PrefixAndSuffix, PreProcessor } from "../types";
|
||||
import { PreProcessor, PrefixAndSuffix } from "../types";
|
||||
|
||||
class LengthLimiter implements PreProcessor {
|
||||
private readonly maxPrefixChars: number;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { TFile } from "obsidian";
|
||||
|
||||
import { InfioSettings } from "../../../types/settings";
|
||||
import { DocumentChanges } from "../../../render-plugin/document-changes-listener";
|
||||
import { InfioSettings } from "../../../types/settings";
|
||||
|
||||
import { EventHandler } from "./types";
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { Notice } from "obsidian";
|
||||
|
||||
import Context from "../context-detection";
|
||||
import EventListener from "../../../event-listener";
|
||||
import { DocumentChanges } from "../../../render-plugin/document-changes-listener";
|
||||
import Context from "../context-detection";
|
||||
|
||||
import State from "./state";
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import Context from "../context-detection";
|
||||
import EventListener from "../../../event-listener";
|
||||
import { DocumentChanges } from "../../../render-plugin/document-changes-listener";
|
||||
import Context from "../context-detection";
|
||||
|
||||
import State from "./state";
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
|
||||
import { TFile } from "obsidian";
|
||||
|
||||
import { InfioSettings } from "../../../types/settings";
|
||||
import { DocumentChanges } from "../../../render-plugin/document-changes-listener";
|
||||
import { InfioSettings } from "../../../types/settings";
|
||||
|
||||
export interface EventHandler {
|
||||
export type EventHandler = {
|
||||
handleSettingChanged(settings: InfioSettings): void;
|
||||
|
||||
handleDocumentChange(documentChanges: DocumentChanges): Promise<void>;
|
||||
|
||||
@@ -2,14 +2,14 @@ import { Result } from "neverthrow";
|
||||
|
||||
import Context from "./context-detection";
|
||||
|
||||
export interface AutocompleteService {
|
||||
export type AutocompleteService = {
|
||||
fetchPredictions(
|
||||
prefix: string,
|
||||
suffix: string
|
||||
): Promise<Result<string, Error>>;
|
||||
}
|
||||
|
||||
export interface PostProcessor {
|
||||
export type PostProcessor = {
|
||||
process(
|
||||
prefix: string,
|
||||
suffix: string,
|
||||
@@ -18,23 +18,23 @@ export interface PostProcessor {
|
||||
): string;
|
||||
}
|
||||
|
||||
export interface PreProcessor {
|
||||
export type PreProcessor = {
|
||||
process(prefix: string, suffix: string, context: Context): PrefixAndSuffix;
|
||||
removesCursor(prefix: string, suffix: string): boolean;
|
||||
}
|
||||
|
||||
export interface PrefixAndSuffix {
|
||||
export type PrefixAndSuffix = {
|
||||
prefix: string;
|
||||
suffix: string;
|
||||
}
|
||||
|
||||
export interface ChatMessage {
|
||||
export type ChatMessage = {
|
||||
content: string;
|
||||
role: "user" | "assistant" | "system";
|
||||
}
|
||||
|
||||
|
||||
export interface UserMessageFormattingInputs {
|
||||
export type UserMessageFormattingInputs = {
|
||||
prefix: string;
|
||||
suffix: string;
|
||||
}
|
||||
@@ -43,12 +43,12 @@ export type UserMessageFormatter = (
|
||||
inputs: UserMessageFormattingInputs
|
||||
) => string;
|
||||
|
||||
export interface ApiClient {
|
||||
export type ApiClient = {
|
||||
queryChatModel(messages: ChatMessage[]): Promise<Result<string, Error>>;
|
||||
checkIfConfiguredCorrectly?(): Promise<string[]>;
|
||||
}
|
||||
|
||||
export interface ModelOptions {
|
||||
export type ModelOptions = {
|
||||
temperature: number;
|
||||
top_p: number;
|
||||
frequency_penalty: number;
|
||||
|
||||
@@ -40,7 +40,7 @@ export function isMatchBetweenPathAndPatterns(
|
||||
}
|
||||
|
||||
export function extractNextWordAndRemaining(suggestion: string): [string | undefined, string | undefined] {
|
||||
const leadingWhitespacesMatch = suggestion.match(/^(\s*)/);
|
||||
const leadingWhitespacesMatch = /^(\s*)/.exec(suggestion);
|
||||
const leadingWhitespaces = leadingWhitespacesMatch ? leadingWhitespacesMatch[0] : '';
|
||||
const trimmedSuggestion = suggestion.slice(leadingWhitespaces.length);
|
||||
|
||||
@@ -48,11 +48,11 @@ export function extractNextWordAndRemaining(suggestion: string): [string | undef
|
||||
let nextWord: string | undefined;
|
||||
let remaining: string | undefined = undefined;
|
||||
|
||||
const whitespaceAfterNextWordMatch = trimmedSuggestion.match(/\s+/);
|
||||
const whitespaceAfterNextWordMatch = /\s+/.exec(trimmedSuggestion);
|
||||
if (!whitespaceAfterNextWordMatch) {
|
||||
nextWord = trimmedSuggestion || undefined;
|
||||
} else {
|
||||
const whitespaceAfterNextWordStartingIndex = whitespaceAfterNextWordMatch.index!;
|
||||
const whitespaceAfterNextWordStartingIndex = whitespaceAfterNextWordMatch.index;
|
||||
const whitespaceAfterNextWord = whitespaceAfterNextWordMatch[0];
|
||||
const whitespaceLength = whitespaceAfterNextWord.length;
|
||||
const startOfWhitespaceAfterNextWordIndex = whitespaceAfterNextWordStartingIndex + whitespaceLength;
|
||||
|
||||
@@ -22,12 +22,12 @@ import {
|
||||
LLMAPIKeyNotSetException,
|
||||
} from './exception'
|
||||
|
||||
export interface RangeFilter {
|
||||
export type RangeFilter = {
|
||||
gte?: number;
|
||||
lte?: number;
|
||||
}
|
||||
|
||||
export interface ChunkFilter {
|
||||
export type ChunkFilter = {
|
||||
field: string;
|
||||
match_all?: string[];
|
||||
range?: RangeFilter;
|
||||
@@ -36,7 +36,7 @@ export interface ChunkFilter {
|
||||
/**
|
||||
* Interface for making requests to the Infio API
|
||||
*/
|
||||
export interface InfioRequest {
|
||||
export type InfioRequest = {
|
||||
/** Required: The content of the user message to attach to the topic and then generate an assistant message in response to */
|
||||
messages: RequestMessage[];
|
||||
// /** Required: The ID of the topic to attach the message to */
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { PGlite } from '@electric-sql/pglite'
|
||||
// @ts-ignore
|
||||
// @ts-expect-error
|
||||
import { type PGliteWithLive, live } from '@electric-sql/pglite/live'
|
||||
import { App, normalizePath } from 'obsidian'
|
||||
|
||||
|
||||
@@ -271,7 +271,7 @@ export class VectorManager {
|
||||
}
|
||||
return null
|
||||
}),
|
||||
).then((files) => files.filter(Boolean) as TFile[])
|
||||
).then((files) => files.filter(Boolean))
|
||||
|
||||
return filesToIndex
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ import { SUPPORT_EMBEDDING_SIMENTION } from '../constants'
|
||||
import { EmbeddingModelId } from '../types/embedding'
|
||||
|
||||
// PostgreSQL column types
|
||||
interface ColumnDefinition {
|
||||
type ColumnDefinition = {
|
||||
type: string
|
||||
notNull?: boolean
|
||||
primaryKey?: boolean
|
||||
@@ -14,7 +14,7 @@ interface ColumnDefinition {
|
||||
dimensions?: number
|
||||
}
|
||||
|
||||
interface TableDefinition {
|
||||
type TableDefinition = {
|
||||
name: string
|
||||
columns: Record<string, ColumnDefinition>
|
||||
indices?: Record<string, {
|
||||
@@ -61,7 +61,7 @@ export const vectorTables = SUPPORT_EMBEDDING_SIMENTION.reduce<
|
||||
}, {})
|
||||
|
||||
// Type definitions for vector table
|
||||
export interface VectorRecord {
|
||||
export type VectorRecord = {
|
||||
id: number
|
||||
path: string
|
||||
mtime: number
|
||||
@@ -91,7 +91,7 @@ export type TemplateContent = {
|
||||
nodes: SerializedLexicalNode[]
|
||||
}
|
||||
|
||||
export interface TemplateRecord {
|
||||
export type TemplateRecord = {
|
||||
id: string
|
||||
name: string
|
||||
content: TemplateContent
|
||||
@@ -113,14 +113,14 @@ export const templateTable: TableDefinition = {
|
||||
}
|
||||
}
|
||||
|
||||
export interface Conversation {
|
||||
export type Conversation = {
|
||||
id: string // uuid
|
||||
title: string
|
||||
createdAt: Date
|
||||
updatedAt: Date
|
||||
}
|
||||
|
||||
export interface Message {
|
||||
export type Message = {
|
||||
id: string // uuid
|
||||
conversationId: string // uuid
|
||||
role: 'user' | 'assistant'
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
export interface SqlMigration {
|
||||
export type SqlMigration = {
|
||||
description: string;
|
||||
sql: string;
|
||||
}
|
||||
|
||||
@@ -258,7 +258,7 @@ class EventListener implements EventHandler {
|
||||
if (trigger.type === "string" && documentChanges.getPrefix().endsWith(trigger.value)) {
|
||||
return true;
|
||||
}
|
||||
if (trigger.type === "regex" && documentChanges.getPrefix().match(trigger.value)) {
|
||||
if (trigger.type === "regex" && (RegExp(trigger.value).exec(documentChanges.getPrefix()))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ import {
|
||||
WidgetType,
|
||||
} from "@codemirror/view";
|
||||
|
||||
import { cancelSuggestion, InlineSuggestionState } from "./states";
|
||||
import { InlineSuggestionState, cancelSuggestion } from "./states";
|
||||
import { OptionalSuggestion, Suggestion } from "./types";
|
||||
|
||||
const RenderSuggestionPlugin = () =>
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
// @ts-nocheck
|
||||
import { Text } from "@codemirror/state";
|
||||
|
||||
export interface Suggestion {
|
||||
export type Suggestion = {
|
||||
value: string;
|
||||
render: boolean;
|
||||
}
|
||||
export type OptionalSuggestion = Suggestion | null;
|
||||
|
||||
export interface InlineSuggestion {
|
||||
export type InlineSuggestion = {
|
||||
suggestion: OptionalSuggestion;
|
||||
doc: Text | null;
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ import {
|
||||
MIN_TOP_P
|
||||
} from "./versions";
|
||||
|
||||
interface IProps {
|
||||
type IProps = {
|
||||
onSettingsChanged(settings: InfioSettings): void;
|
||||
|
||||
settings: InfioSettings;
|
||||
|
||||
@@ -5,7 +5,7 @@ import { InfioSettings } from "../types/settings";
|
||||
|
||||
import ModelsSettings from "./ModelsSettings";
|
||||
|
||||
interface CustomSettingsProps {
|
||||
type CustomSettingsProps = {
|
||||
plugin: InfioPlugin;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React from "react";
|
||||
|
||||
export interface DropdownComponentProps {
|
||||
export type DropdownComponentProps = {
|
||||
name: string;
|
||||
description?: string;
|
||||
options: string[];
|
||||
@@ -32,7 +32,7 @@ export const DropdownComponent: React.FC<DropdownComponentProps> = ({
|
||||
</div>
|
||||
);
|
||||
|
||||
export interface TextComponentProps {
|
||||
export type TextComponentProps = {
|
||||
name: string;
|
||||
description?: string;
|
||||
placeholder: string;
|
||||
@@ -62,7 +62,7 @@ export const TextComponent: React.FC<TextComponentProps> = ({
|
||||
</div>
|
||||
);
|
||||
|
||||
export interface ToggleComponentProps {
|
||||
export type ToggleComponentProps = {
|
||||
name?: string;
|
||||
description?: string;
|
||||
value: boolean;
|
||||
|
||||
@@ -6,7 +6,7 @@ import { InfioSettings } from "../types/settings";
|
||||
|
||||
import { DropdownComponent, TextComponent, ToggleComponent } from "./FormComponents";
|
||||
|
||||
interface ModelRowProps {
|
||||
type ModelRowProps = {
|
||||
model: CustomLLMModel;
|
||||
canDelete: boolean;
|
||||
onToggle: (enabled: boolean) => void;
|
||||
@@ -31,7 +31,7 @@ const ModelRow: React.FC<ModelRowProps> = ({ model, canDelete, onToggle, onDelet
|
||||
</tr>
|
||||
);
|
||||
|
||||
interface ModelFormProps {
|
||||
type ModelFormProps = {
|
||||
providers: string[];
|
||||
onSubmit: (model: CustomLLMModel) => void;
|
||||
isEmbeddingModel: boolean;
|
||||
@@ -96,7 +96,7 @@ const ModelForm: React.FC<ModelFormProps> = ({ providers, onSubmit, isEmbeddingM
|
||||
);
|
||||
};
|
||||
|
||||
interface ModelListProps {
|
||||
type ModelListProps = {
|
||||
models: CustomLLMModel[];
|
||||
chatModelKey: string;
|
||||
applyModelKey: string;
|
||||
@@ -139,7 +139,7 @@ const ModelList: React.FC<ModelListProps> = ({
|
||||
</div>
|
||||
);
|
||||
|
||||
interface ModelsSettingsProps {
|
||||
type ModelsSettingsProps = {
|
||||
settings: InfioSettings;
|
||||
setSettings: (settings: InfioSettings) => void;
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ import * as React from "react";
|
||||
|
||||
import SettingsItem from "./SettingsItem";
|
||||
|
||||
interface IProps {
|
||||
type IProps = {
|
||||
name: string;
|
||||
description: string;
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ import * as React from "react";
|
||||
|
||||
import SettingsItem from "./SettingsItem";
|
||||
|
||||
interface IProps {
|
||||
type IProps = {
|
||||
name: string;
|
||||
description: string;
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ import * as React from "react";
|
||||
import Context from "../../core/autocomplete/context-detection";
|
||||
import { FewShotExample } from "../versions";
|
||||
|
||||
interface IProps {
|
||||
type IProps = {
|
||||
name: string;
|
||||
description: string;
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import * as React from "react";
|
||||
|
||||
interface IProps {
|
||||
type IProps = {
|
||||
name: string;
|
||||
description: string | React.ReactNode;
|
||||
errorMessage?: string;
|
||||
|
||||
@@ -3,7 +3,7 @@ import { useRef } from "react";
|
||||
|
||||
import SettingsItem from "./SettingsItem";
|
||||
|
||||
interface IProps {
|
||||
type IProps = {
|
||||
name: string;
|
||||
description: string;
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ import * as React from "react";
|
||||
|
||||
import SettingsItem from "./SettingsItem";
|
||||
|
||||
interface IProps {
|
||||
type IProps = {
|
||||
name: string;
|
||||
description: string;
|
||||
placeholder: string;
|
||||
|
||||
@@ -3,7 +3,7 @@ import * as React from "react";
|
||||
import { Trigger } from "../versions";
|
||||
|
||||
|
||||
interface IProps {
|
||||
type IProps = {
|
||||
name: string;
|
||||
description: string;
|
||||
triggers: Trigger[];
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
import { z } from "zod";
|
||||
|
||||
import { azureOAIApiSettingsSchema, fewShotExampleSchema, MAX_DELAY, MAX_MAX_CHAR_LIMIT, MIN_DELAY, MIN_MAX_CHAR_LIMIT, modelOptionsSchema, openAIApiSettingsSchema } from "../shared";
|
||||
import { MAX_DELAY, MAX_MAX_CHAR_LIMIT, MIN_DELAY, MIN_MAX_CHAR_LIMIT, azureOAIApiSettingsSchema, fewShotExampleSchema, modelOptionsSchema, openAIApiSettingsSchema } from "../shared";
|
||||
|
||||
import block_qoute_example from "./few-shot-examples/block-qoute-example";
|
||||
import codeblock_function_completion from "./few-shot-examples/codeblock-function-completion";
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
import { z } from "zod";
|
||||
|
||||
import { isRegexValid, isValidIgnorePattern } from "../../../utils/auto-complete";
|
||||
|
||||
import {
|
||||
azureOAIApiSettingsSchema, fewShotExampleSchema,
|
||||
MAX_DELAY,
|
||||
MAX_MAX_CHAR_LIMIT,
|
||||
MAX_DELAY, MAX_MAX_CHAR_LIMIT,
|
||||
MIN_DELAY,
|
||||
MIN_MAX_CHAR_LIMIT,
|
||||
azureOAIApiSettingsSchema,
|
||||
fewShotExampleSchema,
|
||||
modelOptionsSchema,
|
||||
ollamaApiSettingsSchema,
|
||||
openAIApiSettingsSchema,
|
||||
|
||||
@@ -3,11 +3,11 @@ import { z } from 'zod';
|
||||
|
||||
import { DEFAULT_MODELS } from '../constants';
|
||||
import {
|
||||
fewShotExampleSchema,
|
||||
MAX_DELAY,
|
||||
MAX_MAX_CHAR_LIMIT,
|
||||
MIN_DELAY,
|
||||
MIN_MAX_CHAR_LIMIT,
|
||||
fewShotExampleSchema,
|
||||
modelOptionsSchema
|
||||
} from '../settings/versions/shared';
|
||||
import { DEFAULT_AUTOCOMPLETE_SETTINGS } from "../settings/versions/v1/v1";
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
// @ts-nocheck
|
||||
import { cloneDeep, each, get, has, isArray, isEqual, isNumber, isObject, isString, set, unset } from "lodash";
|
||||
import * as mm from "micromatch";
|
||||
import { err, ok, Result } from "neverthrow";
|
||||
import { z, ZodError, ZodIssueCode, ZodType } from 'zod';
|
||||
import { Result, err, ok } from "neverthrow";
|
||||
import { ZodError, ZodIssueCode, ZodType, z } from 'zod';
|
||||
|
||||
import { DEFAULT_SETTINGS, PluginData, Settings } from "../settings/versions";
|
||||
import { isSettingsV0, isSettingsV1, migrateFromV0ToV1 } from "../settings/versions/migration";
|
||||
@@ -77,7 +77,7 @@ function replaceValueWithDefaultValue<V, T>(
|
||||
paths: string[],
|
||||
defaultValue: T,
|
||||
): V {
|
||||
const result = cloneDeep(value) as any;
|
||||
const result = cloneDeep(value);
|
||||
paths.forEach(path => {
|
||||
const originalValue = has(defaultValue, path) ? get(defaultValue, path) : undefined;
|
||||
set(result, path, originalValue);
|
||||
@@ -100,7 +100,7 @@ function removeUnrecognizedKeys(value: JSONObject | null | undefined, error: Zod
|
||||
// Array path will be handled separately by the value replacement function
|
||||
.filter(issue => !isAnArrayPath(issue.path))
|
||||
.flatMap(issue => {
|
||||
// @ts-ignore
|
||||
// @ts-expect-error
|
||||
const keys = issue.keys;
|
||||
return keys.map(key => [...issue.path, key].join('.'));
|
||||
});
|
||||
|
||||
@@ -4,7 +4,7 @@ export function parseImageDataUrl(dataUrl: string): {
|
||||
mimeType: string
|
||||
base64Data: string
|
||||
} {
|
||||
const matches = dataUrl.match(/^data:([^;]+);base64,(.+)/)
|
||||
const matches = /^data:([^;]+);base64,(.+)/.exec(dataUrl)
|
||||
if (!matches) {
|
||||
throw new Error('Invalid image data URL format')
|
||||
}
|
||||
|
||||
@@ -4,55 +4,59 @@ import { calculateFileDistance } from './obsidian'
|
||||
|
||||
describe('calculateFileDistance', () => {
|
||||
// Mock TFile class
|
||||
class MockTFile {
|
||||
class MockTFile extends TFile {
|
||||
path: string
|
||||
constructor(path: string) {
|
||||
super()
|
||||
this.path = path
|
||||
}
|
||||
}
|
||||
|
||||
it('should calculate the correct distance between files in the same folder', () => {
|
||||
const file1 = new MockTFile('folder/file1.md') as TFile
|
||||
const file2 = new MockTFile('folder/file2.md') as TFile
|
||||
const file1 = new MockTFile('folder/file1.md')
|
||||
const file2 = new MockTFile('folder/file2.md')
|
||||
|
||||
const result = calculateFileDistance(file1, file2)
|
||||
expect(result).toBe(2)
|
||||
})
|
||||
|
||||
it('should calculate the correct distance between files in different subfolders', () => {
|
||||
const file1 = new MockTFile('folder1/folder2/file1.md') as TFile
|
||||
const file2 = new MockTFile('folder1/folder3/file2.md') as TFile
|
||||
const file1 = new MockTFile('folder1/folder2/file1.md')
|
||||
const file2 = new MockTFile('folder1/folder3/file2.md')
|
||||
|
||||
const result = calculateFileDistance(file1, file2)
|
||||
expect(result).toBe(4)
|
||||
})
|
||||
|
||||
it('should return null for files in different top-level folders', () => {
|
||||
const file1 = new MockTFile('folder1/file1.md') as TFile
|
||||
const file2 = new MockTFile('folder2/file2.md') as TFile
|
||||
const file1 = new MockTFile('folder1/file1.md')
|
||||
const file2 = new MockTFile('folder2/file2.md')
|
||||
|
||||
const result = calculateFileDistance(file1, file2)
|
||||
expect(result).toBeNull()
|
||||
})
|
||||
|
||||
it('should handle files at different depths', () => {
|
||||
const file1 = new MockTFile('folder1/folder2/subfolder/file1.md') as TFile
|
||||
const file2 = new MockTFile('folder1/folder3/file2.md') as TFile
|
||||
const file1 = new MockTFile('folder1/folder2/subfolder/file1.md')
|
||||
const file2 = new MockTFile('folder1/folder3/file2.md')
|
||||
|
||||
const result = calculateFileDistance(file1, file2)
|
||||
expect(result).toBe(5)
|
||||
})
|
||||
|
||||
it('should return 0 for the same file', () => {
|
||||
const file = new MockTFile('folder/file.md') as TFile
|
||||
const file = new MockTFile('folder/file.md')
|
||||
|
||||
const result = calculateFileDistance(file, file)
|
||||
expect(result).toBe(0)
|
||||
})
|
||||
|
||||
it('should calculate the correct distance between a folder and a file', () => {
|
||||
const file = new MockTFile('folder1/folder2/file1.md') as TFile
|
||||
const folder = new MockTFile('folder1/folder2') as TFolder
|
||||
const file = new MockTFile('folder1/folder2/file1.md')
|
||||
const folder = new MockTFile('folder1/folder2')
|
||||
if (!(folder instanceof TFolder)) {
|
||||
throw new Error('Expected folder to be a TFolder instance')
|
||||
}
|
||||
|
||||
const result = calculateFileDistance(file, folder)
|
||||
expect(result).toBe(1)
|
||||
|
||||
@@ -98,7 +98,7 @@ export class YoutubeTranscript {
|
||||
const videoPageBody = videoPageResponse.text
|
||||
|
||||
// Extract title using regex from <title> tags
|
||||
const titleMatch = videoPageBody.match(/<title>(.*?)<\/title>/)
|
||||
const titleMatch = /<title>(.*?)<\/title>/.exec(videoPageBody)
|
||||
const title = titleMatch
|
||||
? titleMatch[1].replace(' - YouTube', '').trim()
|
||||
: ''
|
||||
@@ -189,7 +189,7 @@ export class YoutubeTranscript {
|
||||
if (videoId.length === 11) {
|
||||
return videoId
|
||||
}
|
||||
const matchId = videoId.match(RE_YOUTUBE)
|
||||
const matchId = RE_YOUTUBE.exec(videoId)
|
||||
if (matchId?.length) {
|
||||
return matchId[1]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user