From 2d4c1c300e24982b13d63d0a4fd3ad95798c4aa5 Mon Sep 17 00:00:00 2001 From: Mara-Li Date: Fri, 26 Jan 2024 12:41:34 +0100 Subject: [PATCH] fix(yaml): prevent empty and wrong yaml Also fixes error with token (related to #200) --- src/GitHub/branch.ts | 4 +- src/GitHub/upload.ts | 16 ++--- .../suggest_other_repo_commands_modal.ts | 32 ++++----- src/conversion/compiler/dataview.ts | 39 +++++----- src/conversion/compiler/embeds.ts | 33 +++++---- src/conversion/convert_text.ts | 71 ++++++++++--------- src/conversion/file_path.ts | 13 ++-- src/conversion/links.ts | 19 +++-- src/settings/interface.ts | 8 ++- src/settings/migrate.ts | 68 +++++++++--------- src/settings/modals/manage_repo.ts | 16 ++--- src/settings/style.ts | 18 ++--- src/utils/data_validation_test.ts | 11 +-- src/utils/index.ts | 4 +- 14 files changed, 175 insertions(+), 177 deletions(-) diff --git a/src/GitHub/branch.ts b/src/GitHub/branch.ts index 020cbaf8..43b5f46e 100644 --- a/src/GitHub/branch.ts +++ b/src/GitHub/branch.ts @@ -2,7 +2,7 @@ import { Octokit } from "@octokit/core"; import i18next from "i18next"; import {Notice } from "obsidian"; -import GithubPublisherPlugin from "../main"; +import GithubPublisher from "../main"; import { RepoFrontmatter, } from "../settings/interface"; @@ -14,7 +14,7 @@ export class GithubBranch extends FilesManagement { constructor( octokit: Octokit, - plugin: GithubPublisherPlugin, + plugin: GithubPublisher, ) { super(octokit, plugin); } diff --git a/src/GitHub/upload.ts b/src/GitHub/upload.ts index 2c7cf8f8..eb5b664b 100644 --- a/src/GitHub/upload.ts +++ b/src/GitHub/upload.ts @@ -17,7 +17,7 @@ import { getImagePath, getReceiptFolder, } from "../conversion/file_path"; -import GithubPublisherPlugin from "../main"; +import GithubPublisher from "../main"; import { Deleted, GitHubPublisherSettings, @@ -51,7 +51,7 @@ import { FilesManagement } from "./files"; export default class Publisher { octokit: Octokit; - plugin: GithubPublisherPlugin; + plugin: GithubPublisher; vault: Vault; metadataCache: MetadataCache; settings: GitHubPublisherSettings; @@ -65,7 +65,7 @@ export default class Publisher { constructor( octokit: Octokit, - plugin: GithubPublisherPlugin, + plugin: GithubPublisher, ) { this.vault = plugin.app.vault; this.metadataCache = plugin.app.metadataCache; @@ -214,7 +214,7 @@ export default class Publisher { let text = await this.vault.cachedRead(file); const multiProperties: MultiProperties = { - settings: this.settings, + plugin: this.plugin, frontmatter: { general: frontmatterSettings, repo: repo.frontmatter, @@ -222,7 +222,7 @@ export default class Publisher { repository: repo.repo, filepath: getReceiptFolder(file, repo.repo, this.plugin, repo.frontmatter), }; - text = await mainConverting(text, file, this.plugin.app, frontmatter, linkedFiles, this.plugin, multiProperties); + text = await mainConverting(text, file, frontmatter, linkedFiles, multiProperties); const path = multiProperties.filepath; const repoFrontmatter = Array.isArray(repo.frontmatter) ? repo.frontmatter @@ -238,7 +238,7 @@ export default class Publisher { const fileError: string[] = []; for (const repo of repoFrontmatter) { const monoProperties: MonoProperties = { - settings: this.settings, + plugin: this.plugin, frontmatter: { general: frontmatterSettings, repo @@ -465,12 +465,12 @@ export default class Publisher { isUpdated: needToByUpdated, file: imageFile.name }; - } + } const folder = dryRunPath.split("/").slice(0, -1).join("/"); const folderExists = this.vault.getAbstractFileByPath(folder); if (!folderExists || !(folderExists instanceof TFolder)) await this.vault.createFolder(folder); - await this.vault.createBinary(path, imageBin); + await this.vault.createBinary(dryRunPath, imageBin); return { isUpdated: true, file: imageFile.name diff --git a/src/commands/suggest_other_repo_commands_modal.ts b/src/commands/suggest_other_repo_commands_modal.ts index 405b8412..fb30c433 100644 --- a/src/commands/suggest_other_repo_commands_modal.ts +++ b/src/commands/suggest_other_repo_commands_modal.ts @@ -1,10 +1,10 @@ import i18next from "i18next"; -import {App, FuzzySuggestModal } from "obsidian"; +import { App, FuzzySuggestModal } from "obsidian"; import { defaultRepo } from "src/utils/data_validation_test"; -import GithubPublisherPlugin from "../main"; -import {FolderSettings, Repository} from "../settings/interface"; -import {logs} from "../utils"; +import GithubPublisher from "../main"; +import { FolderSettings, Repository } from "../settings/interface"; +import { logs } from "../utils"; import { createLinkOnActiveFile, deleteCommands, repositoryValidityActiveFile, shareActiveFile, @@ -23,15 +23,15 @@ interface GithubPublisherCommands { * @extends FuzzySuggestModal * @category Command * @category SuggestModal - * @category GithubPublisherPlugin + * @category GithubPublisher * @description This class is used to choose which repo to run the command on */ export class ChooseWhichRepoToRun extends FuzzySuggestModal { - plugin: GithubPublisherPlugin; + plugin: GithubPublisher; branchName: string; - constructor(app: App, plugin: GithubPublisherPlugin, branchName: string) { + constructor(app: App, plugin: GithubPublisher, branchName: string) { super(app); this.plugin = plugin; this.branchName = branchName; @@ -53,14 +53,14 @@ export class ChooseWhichRepoToRun extends FuzzySuggestModal { * Just return the repo data */ export class ChooseRepoToRun extends FuzzySuggestModal { - plugin: GithubPublisherPlugin; + plugin: GithubPublisher; branchName: string; keyToFind: string | null; type: "folder" | "file"; fileName: string | null; onSubmit: (item: Repository) => void; - constructor(app: App, plugin: GithubPublisherPlugin, keyToFind: null|string = null, branchName: string, type:"folder"|"file", fileName: string | null, onSubmit: (item: Repository) => void) { + constructor(app: App, plugin: GithubPublisher, keyToFind: null | string = null, branchName: string, type: "folder" | "file", fileName: string | null, onSubmit: (item: Repository) => void) { super(app); this.plugin = plugin; this.branchName = branchName; @@ -78,15 +78,15 @@ export class ChooseRepoToRun extends FuzzySuggestModal { repoFound.push(defRepo); } if (this.keyToFind) { - repoFound=repoFound.concat(this.plugin.settings.github.otherRepo.filter((repo: Repository) => repo.shareKey == this.keyToFind)); + repoFound = repoFound.concat(this.plugin.settings.github.otherRepo.filter((repo: Repository) => repo.shareKey == this.keyToFind)); if (this.keyToFind === defRepo.shareKey) { repoFound.push(defRepo); } } } - repoFound=repoFound.concat(this.plugin.settings.github.otherRepo.filter((repo: Repository) => repo.shareAll?.enable && !this.fileName?.startsWith(repo.shareAll?.excludedFileName))); + repoFound = repoFound.concat(this.plugin.settings.github.otherRepo.filter((repo: Repository) => repo.shareAll?.enable && !this.fileName?.startsWith(repo.shareAll?.excludedFileName))); repoFound.push(defRepo); - repoFound=[...new Set(repoFound)]; + repoFound = [...new Set(repoFound)]; if (repoFound.length === 0) return this.plugin.settings.github.otherRepo; return repoFound; @@ -106,17 +106,17 @@ export class ChooseRepoToRun extends FuzzySuggestModal { */ export class SuggestOtherRepoCommandsModal extends FuzzySuggestModal { - plugin: GithubPublisherPlugin; + plugin: GithubPublisher; branchName: string; repo: Repository; - constructor(app: App, plugin: GithubPublisherPlugin, branchName: string, repo: Repository) { + constructor(app: App, plugin: GithubPublisher, branchName: string, repo: Repository) { super(app); this.plugin = plugin; this.branchName = branchName; this.repo = repo; } getItems(): GithubPublisherCommands[] { - const cmd = [ + const cmd = [ { commands: "shareAllMarkedNotes", name: i18next.t("commands.uploadAllNotes") @@ -188,7 +188,7 @@ export class SuggestOtherRepoCommandsModal extends FuzzySuggestModal { + const plugin = properties.plugin; + const settings = plugin.settings; let replacedText = text; const dataViewRegex = /```dataview\s(.+?)```/gsm; //@ts-ignore @@ -57,7 +58,7 @@ export async function convertDataviewQueries( const inlineJsDataViewRegex = new RegExp(`\`${escapeRegex(inlineJsQueryPrefix)}(.+?)\``, "gsm"); const inlineJsMatches = text.matchAll(inlineJsDataViewRegex); if (!matches && !inlineMatches && !dataviewJsMatches && !inlineJsMatches) { - logs({ settings: properties.settings }, "No dataview queries found"); + logs({ settings }, "No dataview queries found"); return replacedText; } const error = i18next.t("error.dataview"); @@ -78,8 +79,8 @@ export async function convertDataviewQueries( } replacedText = replacedText.replace(block, markdown); } catch (e) { - logs({ settings: properties.settings, e: true }, e); - notif({ settings: properties.settings }, error); + logs({ settings, e: true }, e); + notif({ settings }, error); return queryBlock[0]; } } @@ -101,8 +102,8 @@ export async function convertDataviewQueries( const markdown = removeDataviewQueries(div.innerHTML, properties.frontmatter.general); replacedText = replacedText.replace(block, markdown); } catch (e) { - logs({ settings: properties.settings, e: true }, e); - notif({ settings: properties.settings }, error); + logs({ settings, e: true }, e); + notif({ settings }, error); return queryBlock[0]; } } @@ -127,8 +128,8 @@ export async function convertDataviewQueries( replacedText = replacedText.replace(code, removeDataviewQueries(dvApi.settings.renderNullAs, properties.frontmatter.general)); } } catch (e) { - logs({ settings: properties.settings, e: true }, e); - notif({ settings: properties.settings }, error); + logs({ settings, e: true }, e); + notif({ settings }, error); return inlineQuery[0]; } } @@ -159,12 +160,12 @@ export async function convertDataviewQueries( const markdown = removeDataviewQueries(htmlToMarkdown(div.innerHTML), properties.frontmatter.general); replacedText = replacedText.replace(code, markdown); } catch (e) { - logs({ settings: properties.settings, e: true }, e); - notif({ settings: properties.settings }, error); + logs({ settings, e: true }, e); + notif({ settings }, error); return inlineJsQuery[0]; } } - return await convertDataviewLinks(replacedText, frontmatter, sourceFile, plugin, properties); + return await convertDataviewLinks(replacedText, frontmatter, sourceFile, properties); } /** @@ -191,14 +192,13 @@ async function convertDataviewLinks( md: string, frontmatter: FrontMatterCache | undefined | null, sourceFile: TFile, - plugin: GithubPublisher, properties: MultiProperties): Promise { - const dataviewPath = getDataviewPath(md, properties.settings, app.vault); + + const dataviewPath = getDataviewPath(md, properties.plugin); md = await convertToInternalGithub( md, dataviewPath, sourceFile, - plugin, frontmatter, properties ); @@ -206,7 +206,7 @@ async function convertDataviewLinks( md, properties.frontmatter.general, dataviewPath, - properties.settings, + properties.plugin.settings, frontmatter ); } @@ -221,9 +221,10 @@ async function convertDataviewLinks( export function getDataviewPath( markdown: string, - settings: GitHubPublisherSettings, - vault: Vault + plugin: GithubPublisher ): LinkedNotes[] { + const { settings} = plugin; + const vault = plugin.app.vault; if (!settings.conversion.dataview) { return []; } diff --git a/src/conversion/compiler/embeds.ts b/src/conversion/compiler/embeds.ts index e699923c..64dd74a0 100644 --- a/src/conversion/compiler/embeds.ts +++ b/src/conversion/compiler/embeds.ts @@ -154,11 +154,11 @@ function extractSubpath( export async function bakeEmbeds( originalFile: TFile, ancestor: Set, - plugin: GithubPublisher, properties: MultiProperties, subpath: string|null, linkedNotes: LinkedNotes[]): Promise { - const { app } = plugin; + const { plugin } = properties; + const { app, settings } = plugin; const { vault, metadataCache } = plugin.app; let text = await vault.cachedRead(originalFile); @@ -187,15 +187,15 @@ export async function bakeEmbeds( const after = text.substring(end); const replaceTarget = async (replacement: string) => { - if (properties.settings.embed.bake?.textAfter) { - let textAfter = await changeURL(properties.settings.embed.bake?.textAfter, properties, linked, originalFile, plugin, linkedNotes); - textAfter = changeTitle(textAfter, linked, app, properties.settings); + if (settings.embed.bake?.textAfter) { + let textAfter = await changeURL(settings.embed.bake?.textAfter, properties, linked, originalFile, linkedNotes); + textAfter = changeTitle(textAfter, linked, app, settings); const newLine = replacement.match(/[\s\n]/g) ? "" : "\n"; replacement = `${replacement}${newLine}${textAfter}`; } - if (properties.settings.embed.bake?.textBefore) { - let textBefore = await changeURL(properties.settings.embed.bake?.textBefore, properties, linked, originalFile, plugin, linkedNotes); - textBefore = changeTitle(textBefore, linked, app, properties.settings); + if (settings.embed.bake?.textBefore) { + let textBefore = await changeURL(settings.embed.bake?.textBefore, properties, linked, originalFile, linkedNotes); + textBefore = changeTitle(textBefore, linked, app, settings); replacement = `${textBefore}\n${replacement}`; } text = before + replacement + after; @@ -203,13 +203,13 @@ export async function bakeEmbeds( }; const frontmatter = metadataCache.getFileCache(linked)?.frontmatter; - const shared = isShared(frontmatter, properties.settings, linked, properties.repository); + const shared = isShared(frontmatter, settings, linked, properties.repository); const listMatch = before.match(/(?:^|\n)([ \t]*)(?:[-*+]|[0-9]+[.)]) +$/); if (newAncestors.has(linked) || !shared) { //do nothing continue; } - const baked = sanitizeBakedContent(await bakeEmbeds(linked, newAncestors, plugin, properties, subpath, linkedNotes)); + const baked = sanitizeBakedContent(await bakeEmbeds(linked, newAncestors, properties, subpath, linkedNotes)); await replaceTarget( listMatch ? applyIndent(stripFirstBullet(baked), listMatch[1]) : baked); } @@ -226,13 +226,14 @@ export async function bakeEmbeds( * @param linkedNotes {LinkedNotes[]} The linked notes embedded in the file * @returns {Promise} */ -async function changeURL(textToAdd: string, properties: MultiProperties, linked: TFile, sourceFile: TFile, plugin: GithubPublisher, linkedNotes: LinkedNotes[]): Promise { +async function changeURL(textToAdd: string, properties: MultiProperties, linked: TFile, sourceFile: TFile, linkedNotes: LinkedNotes[]): Promise { + const app = properties.plugin.app; const frontmatter = app.metadataCache.getFileCache(linked)?.frontmatter; if (!frontmatter) return textToAdd; const linkedNote = linkedNotes.find((note) => note.linked === linked); if (!linkedNote) return textToAdd; if (properties.frontmatter.general.convertInternalLinks) { - const relativePath = await createRelativePath(sourceFile, linkedNote, frontmatter, plugin, properties); + const relativePath = await createRelativePath(sourceFile, linkedNote, frontmatter, properties); return textToAdd.replace(/\{{2}url\}{2}/gmi, relativePath); } return textToAdd.replace(/\{{2}url\}{2}/gmi, linkedNote.linked.path); @@ -259,18 +260,16 @@ function changeTitle(textToAdd: string, linked: TFile, app: App, settings: GitHu * Will be recursive for array * stringify with extract alt text for links * @param {string} text the text to convert - * @param {GitHubPublisherSettings} settings the global settings * @param {TFile} sourceFile the file to process - * @param {App} app obsidian app * @return {Promise} the converted text */ export async function convertInlineDataview( text: string, - settings: GitHubPublisherSettings, + plugin: GithubPublisher, sourceFile: TFile, - app: App ): Promise { + const {settings, app} = plugin; // @ts-ignore if ( settings.conversion.tags.fields.length === 0 || @@ -313,7 +312,7 @@ export async function convertInlineDataview( } } if (valueToAdd.length > 0) { - return addToYaml(text, valueToAdd.filter(Boolean), settings); + return addToYaml(text, valueToAdd.filter(Boolean), plugin, {properties: null, file: sourceFile}); } return text; } diff --git a/src/conversion/convert_text.ts b/src/conversion/convert_text.ts index d7be1b3a..3674eda1 100644 --- a/src/conversion/convert_text.ts +++ b/src/conversion/convert_text.ts @@ -1,5 +1,4 @@ import { - App, FrontMatterCache, MetadataCache, parseFrontMatterTags, @@ -20,7 +19,7 @@ import { notif } from "../utils"; import { convertDataviewQueries } from "./compiler/dataview"; import { bakeEmbeds, convertInlineDataview } from "./compiler/embeds"; import findAndReplaceText from "./find_and_replace_text"; -import { convertToInternalGithub, convertWikilinks } from "./links"; +import { convertToInternalGithub, convertWikilinks, escapeRegex } from "./links"; /** * Convert soft line breaks to hard line breaks, adding two space at the end of the line. @@ -95,28 +94,36 @@ function tagsToYaml(toAdd: string[], settings: GitHubPublisherSettings, yaml: an * @returns {Promise} the converted text */ -export function addToYaml(text: string, toAdd: string[], settings: GitHubPublisherSettings, folderNoteParaMeters?: { properties: MultiProperties, file: TFile}): string { - const yaml = text.split("---")?.[1]; - let yamlObject = yaml ? parseYaml(yaml) : {}; - if (yamlObject && toAdd.length > 0) { - yamlObject = tagsToYaml(toAdd, settings, yamlObject); - } - if (folderNoteParaMeters) { - yamlObject = titleToYaml(yamlObject, folderNoteParaMeters.properties, folderNoteParaMeters.file); - } - if (Object.keys(yamlObject).length > 0) { - const returnToYaml = stringifyYaml(yamlObject); - if (yaml){ - const fileContentsOnly = text.split("---").slice(2).join("---"); - return `---\n${returnToYaml}---\n${fileContentsOnly}`; - } else return `---\n${returnToYaml}---\n${text}`; +export function addToYaml(text: string, toAdd: string[], plugin: GithubPublisher, folderNoteParaMeters: { properties: MultiProperties | null, file: TFile}): string { + const { settings, app } = plugin; + const frontmatter = app.metadataCache.getFileCache(folderNoteParaMeters.file); + let yamlObject = parseYaml(stringifyYaml(frontmatter?.frontmatter)); + try { + if (yamlObject && toAdd.length > 0) { + yamlObject = tagsToYaml(toAdd, settings, yamlObject); + } + if (folderNoteParaMeters?.properties) { + yamlObject = titleToYaml(yamlObject, folderNoteParaMeters.properties, folderNoteParaMeters.file); + } + + if (Object.keys(yamlObject).length > 0) { + //check if valid yaml + const returnToYaml = stringifyYaml(yamlObject); + if (yamlObject) { + const yamlRegex = new RegExp(`---\n${escapeRegex(stringifyYaml(frontmatter?.frontmatter))}---\n`, "g"); + const fileContentsOnly = text.replace(yamlRegex, ""); + return `---\n${returnToYaml}---\n${fileContentsOnly}`; + } else return `---\n${returnToYaml}---\n${text}`; + } + } catch (e) { + return text; //not a valid yaml, skipping } return text; } //eslint-disable-next-line @typescript-eslint/no-explicit-any function titleToYaml(yaml: any, properties: MultiProperties, file: TFile) { - const settings = properties.settings.upload.folderNote.addTitle; + const settings = properties.plugin.settings.upload.folderNote.addTitle; if (!settings) { return yaml; } @@ -145,24 +152,23 @@ function inlineTags(settings: GitHubPublisherSettings, file: TFile, metadataCach /** * Add inlines tags to frontmatter tags keys. * Duplicate tags will be removed. - * @param {GitHubPublisherSettings} settings the global settings * @param {TFile} file the file to process - * @param {MetadataCache} metadataCache the metadataCache * @param {FrontMatterCache} frontmatter the frontmatter cache * @param {string} text the text to convert * @return {Promise} the converted text */ export async function processYaml( - settings: GitHubPublisherSettings, file: TFile, - metadataCache: MetadataCache, frontmatter: FrontMatterCache | undefined | null, text: string, multiProperties: MultiProperties ): Promise { + const { plugin } = multiProperties; + const { settings, app } = plugin; + const metadataCache = app.metadataCache; const toAdd = inlineTags(settings, file, metadataCache, frontmatter); const folderNoteParaMeters = { properties: multiProperties, file }; - return addToYaml(text, toAdd, settings, folderNoteParaMeters); + return addToYaml(text, toAdd, plugin, folderNoteParaMeters); } @@ -173,38 +179,35 @@ export async function processYaml( export async function mainConverting( text: string, file: TFile, - app: App, frontmatter: FrontMatterCache | undefined | null, linkedFiles: LinkedNotes[], - plugin: GithubPublisher, properties: MultiProperties, ): Promise { + const { plugin } = properties; if (properties.frontmatter.general.removeEmbed === "bake") - text = await bakeEmbeds(file, new Set(), plugin, properties, null, linkedFiles); - text = findAndReplaceText(text, properties.settings, false); - text = await processYaml(properties.settings, file, plugin.app.metadataCache, frontmatter, text, properties); + text = await bakeEmbeds(file, new Set(), properties, null, linkedFiles); + text = findAndReplaceText(text, plugin.settings, false); + text = await processYaml(file, frontmatter, text, properties); text = await convertToInternalGithub( text, linkedFiles, file, - plugin, frontmatter, properties ); - text = convertWikilinks(text, properties.frontmatter.general, linkedFiles, properties.settings, frontmatter); + text = convertWikilinks(text, properties.frontmatter.general, linkedFiles, plugin.settings, frontmatter); text = await convertDataviewQueries( text, file.path, - plugin, frontmatter, file, properties ); - text = await convertInlineDataview(text, properties.settings, file, plugin.app); - text = addHardLineBreak(text, properties.settings, properties.frontmatter.general); + text = await convertInlineDataview(text, plugin, file); + text = addHardLineBreak(text, plugin.settings, properties.frontmatter.general); - return findAndReplaceText(text, properties.settings, true); + return findAndReplaceText(text, plugin.settings, true); } diff --git a/src/conversion/file_path.ts b/src/conversion/file_path.ts index 2f8dcb92..5460d69e 100644 --- a/src/conversion/file_path.ts +++ b/src/conversion/file_path.ts @@ -71,13 +71,12 @@ export async function createRelativePath( sourceFile: TFile, targetFile: LinkedNotes, frontmatter: FrontMatterCache | null | undefined, - plugin: GithubPublisher, properties: MultiProperties, ): Promise { - const settings = properties.settings; + const settings = properties.plugin.settings; const shortRepo = properties.repository; - const sourcePath = getReceiptFolder(sourceFile, shortRepo, plugin, properties.frontmatter.repo); - const frontmatterTarget = frontmatterFromFile(targetFile.linked, plugin); + const sourcePath = getReceiptFolder(sourceFile, shortRepo, properties.plugin, properties.frontmatter.repo); + const frontmatterTarget = frontmatterFromFile(targetFile.linked, properties.plugin); const targetRepo = getRepoFrontmatter(settings, shortRepo, frontmatterTarget); const isFromAnotherRepo = checkIfRepoIsInAnother(properties.frontmatter.repo, targetRepo); const shared = isInternalShared( @@ -93,12 +92,12 @@ export async function createRelativePath( return targetFile.destinationFilePath ? targetFile.destinationFilePath: targetFile.linked.basename; } if (targetFile.linked.path === sourceFile.path) { - return getReceiptFolder(targetFile.linked, shortRepo, plugin, targetRepo).split("/").at(-1) as string; + return getReceiptFolder(targetFile.linked, shortRepo, properties.plugin, targetRepo).split("/").at(-1) as string; } const targetPath = targetFile.linked.extension === "md" && !targetFile.linked.name.includes("excalidraw") - ? getReceiptFolder(targetFile.linked, shortRepo, plugin, targetRepo) + ? getReceiptFolder(targetFile.linked, shortRepo, properties.plugin, targetRepo) : getImagePath( targetFile.linked, settings, @@ -146,7 +145,7 @@ export async function createRelativePath( return getReceiptFolder( targetFile.linked, shortRepo, - plugin, + properties.plugin, targetRepo ).split("/").at(-1) as string; } diff --git a/src/conversion/links.ts b/src/conversion/links.ts index 514120b6..c9ff1ec1 100644 --- a/src/conversion/links.ts +++ b/src/conversion/links.ts @@ -1,6 +1,5 @@ import { FrontMatterCache, TFile } from "obsidian"; import slugify from "slugify"; -import GithubPublisher from "src/main"; import { FrontmatterConvert, @@ -12,9 +11,6 @@ import {isAttachment, noTextConversion} from "../utils/data_validation_test"; import { createRelativePath, linkIsInFormatter, textIsInFrontmatter } from "./file_path"; import { replaceText } from "./find_and_replace_text"; - - - /** * Convert wikilinks to markdown * Pretty cursed @@ -249,25 +245,28 @@ export async function convertToInternalGithub( fileContent: string, linkedFiles: LinkedNotes[], sourceFile: TFile, - plugin: GithubPublisher, frontmatter: FrontMatterCache | undefined | null, properties: MultiProperties, ): Promise { const frontmatterSettings = properties.frontmatter.general; - const settings = properties.settings; + const settings = properties.plugin.settings; if (!frontmatterSettings.convertInternalLinks) { return fileContent; } + // let firstKey: boolean | string = false; for (const linkedFile of linkedFiles) { - if (linkIsInFormatter(linkedFile, frontmatter)) { - continue; - } + // const newKey = linkIsInFormatter(linkedFile, frontmatter); + // if (newKey !== false && newKey !== firstKey) { + // logs({settings}, `The link ${linkedFile.linkFrom} is in the frontmatter of ${newKey}, and different of the oldkey (${firstKey}), re-add it in case it is in the content`); + // firstKey = newKey; + // linkedFiles.push(linkedFile); + // continue; + // } let pathInGithub = await createRelativePath( sourceFile, linkedFile, frontmatter, - plugin, properties, ); pathInGithub = pathInGithub.replace(".md", ""); diff --git a/src/settings/interface.ts b/src/settings/interface.ts index ef30726f..60111d95 100644 --- a/src/settings/interface.ts +++ b/src/settings/interface.ts @@ -1,5 +1,7 @@ import { TFile } from "obsidian"; +import GithubPublisher from "../main"; + export enum TypeOfEditRegex { path = "path", title = "title", @@ -179,7 +181,7 @@ export enum GithubTiersVersion { } export interface MultiProperties { - settings: GitHubPublisherSettings; + plugin: GithubPublisher; frontmatter: { general: FrontmatterConvert; repo: RepoFrontmatter | RepoFrontmatter[]; @@ -189,7 +191,7 @@ export interface MultiProperties { } export interface MonoProperties { - settings: GitHubPublisherSettings; + plugin: GithubPublisher; frontmatter: { general: FrontmatterConvert; repo: RepoFrontmatter @@ -213,7 +215,7 @@ export interface MultiRepoProperties { * Just a constant for the token path * @type {string} TOKEN_PATH */ -export const TOKEN_PATH:string = "%configDir%/plugins/%pluginID%/env"; +export const TOKEN_PATH: string = "%configDir%/plugins/%pluginID%/env"; export const DEFAULT_SETTINGS: Partial = { github: { diff --git a/src/settings/migrate.ts b/src/settings/migrate.ts index 54870dcf..b1cb4adc 100644 --- a/src/settings/migrate.ts +++ b/src/settings/migrate.ts @@ -1,8 +1,9 @@ import i18next from "i18next"; +import { normalizePath } from "obsidian"; import GithubPublisher from "../main"; -import {createTokenPath, logs} from "../utils"; -import {FolderSettings, GithubTiersVersion, TextCleaner, TOKEN_PATH, TypeOfEditRegex} from "./interface"; +import { createTokenPath, logs } from "../utils"; +import { FolderSettings, GithubTiersVersion, TextCleaner, TOKEN_PATH, TypeOfEditRegex } from "./interface"; export interface OldSettings { githubRepo: string; @@ -52,7 +53,7 @@ export interface OldSettings { hostname: string; } -export async function migrateSettings(old: OldSettings, plugin: GithubPublisher, imported?:boolean) { +export async function migrateSettings(old: OldSettings, plugin: GithubPublisher, imported?: boolean) { if (plugin.settings.plugin.migrated && !imported) { return; } @@ -71,7 +72,7 @@ async function migrateReplaceTitle(plugin: GithubPublisher) { if ((plugin.settings.upload.replaceTitle instanceof Array)) { return; } - logs({settings: plugin.settings}, i18next.t("informations.migrating.fileReplace")); + logs({ settings: plugin.settings }, i18next.t("informations.migrating.fileReplace")); plugin.settings.upload.replaceTitle = [plugin.settings.upload.replaceTitle]; await plugin.saveSettings(); } @@ -79,7 +80,7 @@ async function migrateReplaceTitle(plugin: GithubPublisher) { async function migrateSubFolder(plugin: GithubPublisher) { //@ts-ignore if (plugin.settings.upload.subFolder && (!plugin.settings.upload.replacePath.find((e) => e.regex === "/" + plugin.settings.upload.subFolder))) { - logs({settings: plugin.settings}, i18next.t("informations.migrating.subFolder")); + logs({ settings: plugin.settings }, i18next.t("informations.migrating.subFolder")); //@ts-ignore if (plugin.settings.upload.subFolder.length > 0) { plugin.settings.upload.replacePath.push({ @@ -110,7 +111,7 @@ async function migrateCensor(plugin: GithubPublisher) { } async function migrateWorFlow(plugin: GithubPublisher) { - logs({settings: plugin.settings}, "Migrating workflow"); + logs({ settings: plugin.settings }, "Migrating workflow"); //@ts-ignore if (!plugin.settings.github.worflow) { return; @@ -129,11 +130,11 @@ async function migrateWorFlow(plugin: GithubPublisher) { } export async function migrateToken(plugin: GithubPublisher, token?: string) { - logs({settings: plugin.settings}, "migrating token"); + logs({ settings: plugin.settings }, "migrating token"); const tokenPath = createTokenPath(plugin, plugin.settings.github.tokenPath); //@ts-ignore if (plugin.settings.github.token && !token) { - logs({settings: plugin.settings}, `Moving the GitHub Token in the file : ${tokenPath}`); + logs({ settings: plugin.settings }, `Moving the GitHub Token in the file : ${tokenPath}`); //@ts-ignore token = plugin.settings.github.token; //@ts-ignore @@ -143,11 +144,14 @@ export async function migrateToken(plugin: GithubPublisher, token?: string) { if (token === undefined) { return; } - logs({settings: plugin.settings}, `Moving the GitHub Token in the file : ${tokenPath}`); + logs({ settings: plugin.settings }, `Moving the GitHub Token in the file : ${tokenPath}`); if (tokenPath.endsWith(".json")) { const envToken = { GITHUB_PUBLISHER_TOKEN: token }; + if (!(await plugin.app.vault.adapter.exists(tokenPath))) { + await plugin.app.vault.adapter.mkdir(normalizePath(tokenPath).split("/").slice(0, -1).join("/")); + } await plugin.app.vault.adapter.write(tokenPath, JSON.stringify(envToken)); } else { const envToken = `GITHUB_TOKEN=${token}`; @@ -158,7 +162,7 @@ export async function migrateToken(plugin: GithubPublisher, token?: string) { async function migrateOtherRepository(plugin: GithubPublisher) { - logs({settings: plugin.settings}, "Configuring other repositories"); + logs({ settings: plugin.settings }, "Configuring other repositories"); const otherRepo = plugin.settings.github?.otherRepo ?? []; for (const repo of otherRepo) { const workflow = { @@ -199,31 +203,31 @@ async function migrateOldSettings(plugin: GithubPublisher, old: OldSettings) { if (!Object.keys(old).includes("editorMenu")) { return; } - logs({settings: plugin.settings}, i18next.t("informations.migrating.oldSettings")); + logs({ settings: plugin.settings }, i18next.t("informations.migrating.oldSettings")); plugin.settings = { github: - { - user: old.githubName ? old.githubName : plugin.settings.github.user ? plugin.settings.github.user : "", - repo: old.githubRepo ? old.githubRepo : plugin.settings.github.repo ? plugin.settings.github.repo : "", - branch: old.githubBranch, - automaticallyMergePR: old.automaticallyMergePR, - tokenPath: TOKEN_PATH, - api: { - tiersForApi: old.tiersForApi, - hostname: old.hostname, - }, - workflow: { - name: old.workflowName, - commitMessage: old.customCommitMsg ?? plugin.settings.github.workflow.commitMessage ?? "[PUBLISHER] MERGE", - }, - otherRepo: [], - rateLimit: 0, - verifiedRepo: false, - dryRun: { - enable: false, - folderName: "", - } + { + user: old.githubName ? old.githubName : plugin.settings.github.user ? plugin.settings.github.user : "", + repo: old.githubRepo ? old.githubRepo : plugin.settings.github.repo ? plugin.settings.github.repo : "", + branch: old.githubBranch, + automaticallyMergePR: old.automaticallyMergePR, + tokenPath: TOKEN_PATH, + api: { + tiersForApi: old.tiersForApi, + hostname: old.hostname, + }, + workflow: { + name: old.workflowName, + commitMessage: old.customCommitMsg ?? plugin.settings.github.workflow.commitMessage ?? "[PUBLISHER] MERGE", }, + otherRepo: [], + rateLimit: 0, + verifiedRepo: false, + dryRun: { + enable: false, + folderName: "", + } + }, upload: { behavior: old.downloadedFolder as FolderSettings, defaultName: old.folderDefaultName, diff --git a/src/settings/modals/manage_repo.ts b/src/settings/modals/manage_repo.ts index 80f9b5ee..334262f0 100644 --- a/src/settings/modals/manage_repo.ts +++ b/src/settings/modals/manage_repo.ts @@ -1,7 +1,7 @@ import i18next from "i18next"; import {App, Modal, Notice, Setting} from "obsidian"; -import GithubPublisherPlugin from "../../main"; +import GithubPublisher from "../../main"; import {checkRepositoryValidity, verifyRateLimitAPI} from "../../utils/data_validation_test"; import {GitHubPublisherSettings, GithubTiersVersion, Repository} from "../interface"; @@ -12,14 +12,14 @@ import {GitHubPublisherSettings, GithubTiersVersion, Repository} from "../interf * @param {App} app - the Obsidian App * @param {GitHubPublisherSettings} settings - the plugin settings * @param {string} branchName - the branch name - * @param {GithubPublisherPlugin} plugin - the plugin + * @param {GithubPublisher} plugin - the plugin * @param {Repository[]} repository - the list of repo in the settings * @param {(result: Repository[]) => void} onSubmit - the function to call when the modal is submitted */ export class ModalAddingNewRepository extends Modal { settings: GitHubPublisherSettings; - plugin: GithubPublisherPlugin; + plugin: GithubPublisher; branchName: string; repository: Repository[]; onSubmit: (result: Repository[]) => void; @@ -28,7 +28,7 @@ export class ModalAddingNewRepository extends Modal { app: App, settings: GitHubPublisherSettings, branchName: string, - plugin: GithubPublisherPlugin, + plugin: GithubPublisher, repository: Repository[], onSubmit: (result: Repository[]) => void) { super(app); @@ -194,7 +194,7 @@ export class ModalAddingNewRepository extends Modal { * @extends Modal * @param {App} app - The Obsidian App instance * @param {Repository} repository - The repository to edit - * @param {GithubPublisherPlugin} GithubPublisherPlugin - The GithubPublisherPlugin instance + * @param {GithubPublisher} GithubPublisher - The GithubPublisher instance * @param {string} brancheName - The name of the branch (for validation) * @param {function} onSubmit - The function to call when the modal is closed (to save the changes) */ @@ -202,20 +202,20 @@ export class ModalAddingNewRepository extends Modal { class ModalEditingRepository extends Modal { repository: Repository; branchName: string; - plugin: GithubPublisherPlugin; + plugin: GithubPublisher; onSubmit: (result: Repository) => void; constructor( app: App, repository: Repository, - GithubPublisherPlugin: GithubPublisherPlugin, + GithubPublisher: GithubPublisher, brancheName: string, onSubmit: (result: Repository) => void) { super(app); this.repository = repository; this.onSubmit = onSubmit; this.branchName = brancheName; - this.plugin = GithubPublisherPlugin; + this.plugin = GithubPublisher; } onOpen() { diff --git a/src/settings/style.ts b/src/settings/style.ts index d2a05c51..f5458629 100644 --- a/src/settings/style.ts +++ b/src/settings/style.ts @@ -2,7 +2,7 @@ import i18next from "i18next"; import { Notice, Setting } from "obsidian"; import { GithubPublisherSettingsTab } from "src/settings"; -import GithubPublisherPlugin from "../main"; +import GithubPublisher from "../main"; import {EnumbSettingsTabId, FolderSettings, GitHubPublisherSettings} from "./interface"; /** * show a settings @@ -55,16 +55,12 @@ export function showHideBasedOnFolder(settings: GitHubPublisherSettings, frontma /** * Show or hide the autoclean settings - * @param {string} value - * @param {Setting} autoCleanSetting - * @param {GithubPublisher} plugin - * @return {Promise} */ export async function autoCleanCondition( value: string, autoCleanSetting: Setting, - plugin: GithubPublisherPlugin, + plugin: GithubPublisher, what: "rootFolder" | "defaultName" = "defaultName", settingsTab: GithubPublisherSettingsTab ) { @@ -110,12 +106,6 @@ export async function autoCleanCondition( * * @example * - If obsidian path or fixed folder : hide the frontmatterKey setting and the rootFolder settings - * @param {Setting} frontmatterKeySettings - * @param {Setting} rootFolderSettings - * @param {Setting} autoCleanSetting - * @param {string} value - * @param {GithubPublisher} plugin - * @return {Promise} */ export async function folderHideShowSettings( @@ -123,7 +113,7 @@ export async function folderHideShowSettings( rootFolderSettings: Setting, autoCleanSetting: Setting, value: string, - plugin: GithubPublisherPlugin, + plugin: GithubPublisher, ) { const settings = plugin.settings.upload; if (value === FolderSettings.yaml) { @@ -154,7 +144,7 @@ export async function folderHideShowSettings( export function autoCleanUpSettingsOnCondition( condition: boolean, autoCleanSetting: Setting, - plugin: GithubPublisherPlugin + plugin: GithubPublisher ) { const settings = plugin.settings.upload; if (condition) { diff --git a/src/utils/data_validation_test.ts b/src/utils/data_validation_test.ts index 200522d6..aba2cb3e 100644 --- a/src/utils/data_validation_test.ts +++ b/src/utils/data_validation_test.ts @@ -31,12 +31,12 @@ export function isInternalShared( if (properties.repository?.shareAll?.enable) { const excludedFileName = properties.repository.shareAll.excludedFileName; - return !file.basename.startsWith(excludedFileName) && !isInDryRunFolder(properties.settings, properties.repository, file); + return !file.basename.startsWith(excludedFileName) && !isInDryRunFolder(properties.plugin.settings, properties.repository, file); } if (!frontmatter) return false; - if (isExcludedPath(properties.settings, file, properties.repository)) return false; - const shareKey = properties.repository?.shareKey || properties.settings.plugin.shareKey; - logs({settings: properties.settings}, "shareKey", shareKey, "frontmatter", frontmatter[shareKey]); + if (isExcludedPath(properties.plugin.settings, file, properties.repository)) return false; + const shareKey = properties.repository?.shareKey || properties.plugin.settings.plugin.shareKey; + logs({settings: properties.plugin.settings}, "shareKey", shareKey, "frontmatter", frontmatter[shareKey]); if (frontmatter[shareKey] == null || frontmatter[shareKey] === undefined || ["false", "0", "no"].includes(frontmatter[shareKey].toString().toLowerCase())) return false; return ["true", "1", "yes"].includes(frontmatter[shareKey].toString().toLowerCase()); @@ -473,7 +473,8 @@ export function forcePushAttachment(file: TFile, settings: GitHubPublisherSettin * @returns True if the file is a folder note, false otherwise. */ export function isFolderNote(properties: MultiProperties): boolean { - const { settings, filepath } = properties; + const {filepath } = properties; + const { settings } = properties.plugin; const { enable, rename } = settings.upload.folderNote; if (enable) { diff --git a/src/utils/index.ts b/src/utils/index.ts index 6aa9c68d..35b1f055 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -1,5 +1,5 @@ import i18next from "i18next"; -import {App, Notice, Platform, TFile} from "obsidian"; +import {App, normalizePath, Notice, Platform, TFile} from "obsidian"; import GithubPublisher from "src/main"; import {getReceiptFolder} from "../conversion/file_path"; @@ -393,6 +393,6 @@ export function createTokenPath(plugin: GithubPublisher, tokenPath?: string) { } tokenPath = tokenPath.replace("%configDir%", vault.configDir); tokenPath = tokenPath.replace("%pluginID%", plugin.manifest.id); - return tokenPath; + return normalizePath(tokenPath); }