diff --git a/package.json b/package.json index bf354d48..f4916006 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,8 @@ "bump": "node commit-and-tag-version.js", "postbump": "git push --follow-tags origin master", "predeploy": "pnpm run bump", - "deploy": "pnpm run export" + "deploy": "pnpm run export", + "tsc": "tsc --noEmit --skipLibCheck" }, "commit-and-tag-version": { "t": "" @@ -73,4 +74,4 @@ "got@<11.8.5": ">=11.8.5" } } -} +} \ No newline at end of file diff --git a/src/GitHub/branch.ts b/src/GitHub/branch.ts index 9680c571..c465cfe8 100644 --- a/src/GitHub/branch.ts +++ b/src/GitHub/branch.ts @@ -229,6 +229,7 @@ export class GithubBranch extends FilesManagement { async updateRepositoryOnOne( repoFrontmatter: RepoFrontmatter ): Promise { + if (this.settings.github.dryRun.enable) return true; try { const pullRequest = await this.pullRequestOnRepo( repoFrontmatter diff --git a/src/GitHub/delete.ts b/src/GitHub/delete.ts index 126ebd83..9ac4202f 100644 --- a/src/GitHub/delete.ts +++ b/src/GitHub/delete.ts @@ -14,6 +14,7 @@ import { } from "../settings/interface"; import { logs, notif, trimObject} from "../utils"; import {isAttachment, verifyRateLimitAPI} from "../utils/data_validation_test"; +import { frontmatterSettingsRepository } from "../utils/parse_frontmatter"; import { FilesManagement } from "./files"; /** @@ -39,7 +40,7 @@ export async function deleteFromGithub( const monoProperties: MonoRepoProperties = { frontmatter: repo, repo: repoProperties.repo, - convert: repoProperties.convert, + convert: frontmatterSettingsRepository(filesManagement.plugin, repo), }; deleted.push(await deleteFromGithubOneRepo( silent, diff --git a/src/GitHub/files.ts b/src/GitHub/files.ts index 54b3fbdb..8cec471f 100644 --- a/src/GitHub/files.ts +++ b/src/GitHub/files.ts @@ -89,18 +89,19 @@ export class FilesManagement extends Publisher { getAllFileWithPath(repo: Repository | null, convert: FrontmatterConvert): ConvertedLink[] { const files = this.vault.getFiles().filter((x) => !x.path.startsWith(this.settings.github.dryRun.folderName)); const allFileWithPath: ConvertedLink[] = []; + const sourceFrontmatter = getRepoFrontmatter(this.plugin, repo, null, true); for (const file of files) { if (isAttachment(file.name, this.settings.embed.unHandledObsidianExt)) { - const filepath = getImagePath(file, this.settings, convert); + const filepath = getImagePath(file, this.plugin, convert, sourceFrontmatter ); allFileWithPath.push({ converted: filepath, real: file.path, }); } else if (file.extension == "md") { - const frontMatter = frontmatterFromFile(file, this.plugin); + const frontMatter = frontmatterFromFile(file, this.plugin, repo); if (isShared(frontMatter, this.settings, file, repo)) { const repoFrontmatter = getRepoFrontmatter( - this.settings, + this.plugin, repo, frontMatter ); @@ -108,7 +109,7 @@ export class FilesManagement extends Publisher { allFileWithPath.push({ converted: filepath, real: file.path, - repoFrontmatter: repoFrontmatter, + repoFrontmatter, }); } } diff --git a/src/GitHub/upload.ts b/src/GitHub/upload.ts index cc08b82a..893884da 100644 --- a/src/GitHub/upload.ts +++ b/src/GitHub/upload.ts @@ -3,6 +3,7 @@ import i18next from "i18next"; import { Base64 } from "js-base64"; import { arrayBufferToBase64, + FrontMatterCache, MetadataCache, normalizePath, Notice, @@ -10,6 +11,7 @@ import { TFolder, Vault, } from "obsidian"; +import merge from "ts-deepmerge"; import { mainConverting } from "../conversion"; import { convertToHTMLSVG } from "../conversion/compiler/excalidraw"; @@ -41,7 +43,7 @@ import { isShared, } from "../utils/data_validation_test"; import { LOADING_ICON } from "../utils/icons"; -import { frontmatterFromFile, getFrontmatterSettings, getRepoFrontmatter } from "../utils/parse_frontmatter"; +import { frontmatterFromFile, frontmatterSettingsRepository, getFrontmatterSettings, getRepoFrontmatter } from "../utils/parse_frontmatter"; import { ShareStatusBar } from "../utils/status_bar"; import { deleteFromGithub } from "./delete"; import { FilesManagement } from "./files"; @@ -88,6 +90,7 @@ export default class Publisher { fileHistory: TFile[], deepScan: boolean, properties: MonoProperties, + ) { const uploadedFile: UploadedFiles[] = []; const fileError: string[] = []; @@ -115,7 +118,8 @@ export default class Publisher { false, repoProperties, fileHistory, - true + true, + properties.frontmatter.source ); if (published) { uploadedFile.push(...published.uploaded); @@ -173,13 +177,15 @@ export default class Publisher { repo: MultiRepoProperties | MonoRepoProperties, fileHistory: TFile[] = [], deepScan: boolean = false, + sourceFrontmatter: FrontMatterCache | null | undefined, ) { const shareFiles = new FilesManagement( this.octokit, this.plugin, ); - const frontmatter = frontmatterFromFile(file, this.plugin); - const repoFrontmatter = getRepoFrontmatter(this.settings, repo.repo, frontmatter); + let frontmatter = frontmatterFromFile(file, this.plugin, null); + if (sourceFrontmatter && frontmatter) frontmatter = merge(frontmatter, sourceFrontmatter); + const repoFrontmatter = getRepoFrontmatter(this.plugin, repo.repo, frontmatter); const isNotEmpty = await checkEmptyConfiguration(repoFrontmatter, this.plugin); repo.frontmatter = repoFrontmatter; if ( @@ -195,11 +201,13 @@ export default class Publisher { try { logs({ settings: this.settings }, `Publishing file: ${file.path}`); fileHistory.push(file); - const frontmatterSettings = getFrontmatterSettings( + const frontmatterSettingsFromFile = getFrontmatterSettings( frontmatter, this.settings, repo.repo ); + const frontmatterRepository = frontmatterSettingsRepository(this.plugin, repo.repo); + const frontmatterSettings = merge(frontmatterRepository, frontmatterSettingsFromFile); let embedFiles = shareFiles.getSharedEmbed( file, frontmatterSettings, @@ -240,7 +248,8 @@ export default class Publisher { plugin: this.plugin, frontmatter: { general: frontmatterSettings, - repo + repo, + source: sourceFrontmatter }, repository: multiProperties.repository, filepath: multiProperties.filepath, @@ -444,8 +453,9 @@ export default class Publisher { } const path = getImagePath( imageFile, - this.settings, - properties.frontmatter.general + this.plugin, + properties.frontmatter.general, + properties.frontmatter.repo ); if (this.settings.github.dryRun.enable) { const folderName = this.settings.github.dryRun.folderName @@ -633,8 +643,9 @@ export default class Publisher { if (isAttachment(file.name, this.settings.embed.unHandledObsidianExt)) { const imagePath = getImagePath( file, - this.settings, - properties.frontmatter.general + this.plugin, + properties.frontmatter.general, + properties.frontmatter.repo ); const repoFrontmatter = properties.frontmatter; if (this.settings.github.dryRun.enable) { diff --git a/src/commands/callback.ts b/src/commands/callback.ts index 391146b3..7c2ee2b5 100644 --- a/src/commands/callback.ts +++ b/src/commands/callback.ts @@ -11,7 +11,7 @@ import GithubPublisher from "../main"; import {MonoRepoProperties, MultiRepoProperties, Repository} from "../settings/interface"; import {createLink} from "../utils"; import {checkRepositoryValidity, isShared} from "../utils/data_validation_test"; -import { frontmatterFromFile, getFrontmatterSettings, getRepoFrontmatter } from "../utils/parse_frontmatter"; +import { frontmatterFromFile, frontmatterSettingsRepository, getRepoFrontmatter } from "../utils/parse_frontmatter"; import {purgeNotesRemote, shareOneNote} from "."; import {shareEditedOnly, uploadAllEditedNotes, uploadAllNotes, uploadNewNotes} from "./plugin_commands"; @@ -32,13 +32,13 @@ export async function createLinkCallback(repo: Repository | null, plugin: Github hotkeys: [], checkCallback: (checking) => { const file = plugin.app.workspace.getActiveFile(); - const frontmatter = frontmatterFromFile(file, plugin); + const frontmatter = frontmatterFromFile(file, plugin, repo); if ( file && frontmatter && isShared(frontmatter, plugin.settings, file, repo) ) { if (!checking) { const multiRepo: MultiRepoProperties = { - frontmatter: getRepoFrontmatter(plugin.settings, repo, frontmatter), + frontmatter: getRepoFrontmatter(plugin, repo, frontmatter, true), repo, }; createLink( @@ -76,17 +76,12 @@ export async function purgeNotesRemoteCallback(plugin: GithubPublisher, repo: Re hotkeys: [], //@ts-ignore callback: async () => { - const frontmatter = getRepoFrontmatter(plugin.settings, repo); + const frontmatter = getRepoFrontmatter(plugin, repo, undefined, true); const monoRepo: MonoRepoProperties = { frontmatter: Array.isArray(frontmatter) ? frontmatter[0] : frontmatter, repo, - convert: getFrontmatterSettings( - null, - plugin.settings, - repo - ) + convert: frontmatterSettingsRepository(plugin, repo) }; - //@ts-ignore const publisher = await plugin.reloadOctokit(repo?.smartKey); await purgeNotesRemote( publisher, @@ -102,7 +97,6 @@ export async function purgeNotesRemoteCallback(plugin: GithubPublisher, repo: Re * @call shareOneNote * @param {Repository | null} repo - Other repo if the command is called from the suggest_other_repo_command.ts * @param {GithubPublisher} plugin - The plugin instance - * @param {string} branchName - The branch name to upload the file * @return {Promise} */ export async function shareOneNoteCallback(repo: Repository|null, plugin: GithubPublisher): Promise { @@ -118,7 +112,7 @@ export async function shareOneNoteCallback(repo: Repository|null, plugin: Github hotkeys: [], checkCallback: (checking) => { const file = plugin.app.workspace.getActiveFile(); - const frontmatter = frontmatterFromFile(file, plugin); + const frontmatter = frontmatterFromFile(file, plugin, repo); if ( file && frontmatter && isShared(frontmatter, plugin.settings, file, repo) ) { @@ -127,6 +121,7 @@ export async function shareOneNoteCallback(repo: Repository|null, plugin: Github octokit, file, repo, + frontmatter, file.basename, ); } diff --git a/src/commands/file_menu.ts b/src/commands/file_menu.ts index 63b4c0d6..2615697f 100644 --- a/src/commands/file_menu.ts +++ b/src/commands/file_menu.ts @@ -4,7 +4,7 @@ import { Menu, MenuItem, Platform, TFile, TFolder} from "obsidian"; import GithubPublisher from "../main"; import {MonoRepoProperties, Repository} from "../settings/interface"; import {defaultRepo, getRepoSharedKey, isExcludedPath, isInDryRunFolder, isShared, multipleSharedKey} from "../utils/data_validation_test"; -import { frontmatterFromFile, getFrontmatterSettings, getRepoFrontmatter } from "../utils/parse_frontmatter"; +import { frontmatterFromFile, frontmatterSettingsRepository, getRepoFrontmatter } from "../utils/parse_frontmatter"; import {shareAllMarkedNotes, shareOneNote} from "."; import {ChooseRepoToRun} from "./suggest_other_repo_commands_modal"; @@ -18,15 +18,11 @@ import {ChooseRepoToRun} from "./suggest_other_repo_commands_modal"; export async function shareFolderRepo(plugin: GithubPublisher, folder: TFolder, branchName: string, repo: Repository | null) { const publisher = await plugin.reloadOctokit(repo?.smartKey); const statusBarItems = plugin.addStatusBarItem(); - const repoFrontmatter = getRepoFrontmatter(plugin.settings, repo, null); + const repoFrontmatter = getRepoFrontmatter(plugin, repo, null, true); const monoProperties: MonoRepoProperties = { frontmatter: Array.isArray(repoFrontmatter) ? repoFrontmatter[0] : repoFrontmatter, repo, - convert: getFrontmatterSettings( - null, - plugin.settings, - repo - ) + convert: frontmatterSettingsRepository(plugin, repo) }; await shareAllMarkedNotes( publisher, @@ -104,15 +100,16 @@ export function addSubMenuCommandsFolder(plugin: GithubPublisher, item: MenuItem * @param {Menu} menu - The menu to add the item to */ export function addMenuFile(plugin: GithubPublisher, file: TFile, branchName: string, menu: Menu) { - const frontmatter = frontmatterFromFile(file, plugin); - let getSharedKey = getRepoSharedKey(plugin, frontmatter, file); + const frontmatterSharedKey = frontmatterFromFile(file, plugin, null); + let getSharedKey = getRepoSharedKey(plugin, frontmatterSharedKey, file); + const frontmatter = frontmatterFromFile(file, plugin, getSharedKey); const allKeysFromFile = multipleSharedKey(frontmatter, file, plugin); if ( !(isShared(frontmatter, plugin.settings, file, getSharedKey) && plugin.settings.plugin.fileMenu) ) return; - const repoFrontmatter = getRepoFrontmatter(plugin.settings, getSharedKey, frontmatter); + const repoFrontmatter = getRepoFrontmatter(plugin, getSharedKey, frontmatter, true); menu.addItem((item) => { /** @@ -159,6 +156,7 @@ export function addMenuFile(plugin: GithubPublisher, file: TFile, branchName: st await plugin.reloadOctokit(getSharedKey?.smartKey), file, getSharedKey, + frontmatter, fileName ); }); @@ -177,11 +175,11 @@ export function addMenuFile(plugin: GithubPublisher, file: TFile, branchName: st * @return {Menu} - The submenu created */ export function subMenuCommandsFile(plugin: GithubPublisher, item: MenuItem, file: TFile, branchName: string, repo: Repository | null, originalMenu: Menu): Menu { - const frontmatter = frontmatterFromFile(file, plugin); + const frontmatter = frontmatterFromFile(file, plugin, repo); const fileName = plugin.getTitleFieldForCommand(file, frontmatter).replace(".md", ""); //@ts-ignore const subMenu = Platform.isDesktop ? item.setSubmenu() as Menu : originalMenu; - let repoFrontmatter = getRepoFrontmatter(plugin.settings, repo, frontmatter); + let repoFrontmatter = getRepoFrontmatter(plugin, repo, frontmatter, true); repoFrontmatter = repoFrontmatter instanceof Array ? repoFrontmatter : [repoFrontmatter]; /** * default repo @@ -200,6 +198,7 @@ export function subMenuCommandsFile(plugin: GithubPublisher, item: MenuItem, fil await plugin.reloadOctokit(), file, defaultRepo(plugin.settings), + null, fileName ); }); @@ -222,6 +221,7 @@ export function subMenuCommandsFile(plugin: GithubPublisher, item: MenuItem, fil await plugin.reloadOctokit(otherRepo?.smartKey), file, otherRepo, + frontmatter, fileName ); }); @@ -243,6 +243,7 @@ export function subMenuCommandsFile(plugin: GithubPublisher, item: MenuItem, fil await plugin.reloadOctokit(), file, repo, + frontmatter, fileName ); }); @@ -256,10 +257,12 @@ export function subMenuCommandsFile(plugin: GithubPublisher, item: MenuItem, fil .setIcon("file-input") .onClick(async () => { new ChooseRepoToRun(plugin.app, plugin, repo?.shareKey, branchName, "file", file.basename, async (item: Repository) => { + const sourceFrontmatter = frontmatterFromFile(file, plugin, item); await shareOneNote( await plugin.reloadOctokit(item.smartKey), file, item, + sourceFrontmatter, fileName ); }).open(); diff --git a/src/commands/index.ts b/src/commands/index.ts index 93ae3acb..34de5245 100644 --- a/src/commands/index.ts +++ b/src/commands/index.ts @@ -1,6 +1,7 @@ import i18next from "i18next"; -import { Notice, Platform, TFile } from "obsidian"; +import { FrontMatterCache, Notice, Platform, TFile } from "obsidian"; import { ERROR_ICONS } from "src/utils/icons"; +import merge from "ts-deepmerge"; import { GithubBranch } from "../GitHub/branch"; import { deleteFromGithub } from "../GitHub/delete"; @@ -33,6 +34,7 @@ export async function shareAllMarkedNotes( monoRepo: MonoRepoProperties, sharedFiles: TFile[], createGithubBranch: boolean = true, + sourceFrontmatter: FrontMatterCache | undefined | null = null, ) { const statusBar = new ShareStatusBar(statusBarItems, sharedFiles.length); const repoFrontmatter = monoRepo.frontmatter; @@ -51,7 +53,10 @@ export async function shareAllMarkedNotes( const uploaded = await PublisherManager.publish( sharedFile, false, - monoRepo + monoRepo, + undefined, + undefined, + sourceFrontmatter, ) ; if (uploaded) { listStateUploaded.push(...uploaded.uploaded); @@ -163,13 +168,15 @@ export async function shareOneNote( PublisherManager: GithubBranch, file: TFile, repository: Repository | null = null, - title?: string + sourceFrontmatter: FrontMatterCache | undefined | null, + title?: string, ): Promise { const {settings, plugin} = PublisherManager; const app = PublisherManager.plugin.app; - const frontmatter = frontmatterFromFile(file, PublisherManager.plugin); + let frontmatter = frontmatterFromFile(file, PublisherManager.plugin, null); + if (sourceFrontmatter && frontmatter) frontmatter = merge(sourceFrontmatter, frontmatter); try { - const repoFrontmatter = getRepoFrontmatter(settings, repository, frontmatter); + const repoFrontmatter = getRepoFrontmatter(plugin, repository, frontmatter); let isValid: boolean; if (repoFrontmatter instanceof Array) { const isValidArray = []; @@ -191,7 +198,8 @@ export async function shareOneNote( true, multiRepo, [], - true + true, + sourceFrontmatter ); if (publishSuccess) { if ( @@ -236,7 +244,7 @@ export async function shareOneNote( } catch (error) { if (!(error instanceof DOMException)) { logs({settings, e: true}, error); - notifError(getRepoFrontmatter(settings, repository, frontmatter)); + notifError(getRepoFrontmatter(plugin, repository, frontmatter, true)); } } } diff --git a/src/commands/plugin_commands.ts b/src/commands/plugin_commands.ts index 87ee7958..2dc2f527 100644 --- a/src/commands/plugin_commands.ts +++ b/src/commands/plugin_commands.ts @@ -10,7 +10,7 @@ import GithubPublisher from "../main"; import {MonoRepoProperties, MultiRepoProperties, Repository} from "../settings/interface"; import {createLink} from "../utils"; import {checkRepositoryValidity, isShared} from "../utils/data_validation_test"; -import { frontmatterFromFile, getFrontmatterSettings, getRepoFrontmatter } from "../utils/parse_frontmatter"; +import { frontmatterFromFile, frontmatterSettingsRepository, getRepoFrontmatter } from "../utils/parse_frontmatter"; import { purgeNotesRemote, shareAllEditedNotes, @@ -28,13 +28,13 @@ import { */ export async function createLinkOnActiveFile(repo: Repository | null, plugin: GithubPublisher): Promise { const file = plugin.app.workspace.getActiveFile(); - const frontmatter = frontmatterFromFile(file, plugin); + const frontmatter = frontmatterFromFile(file, plugin, repo); if ( file && frontmatter && isShared(frontmatter, plugin.settings, file, repo) ) { const multiRepo: MultiRepoProperties = { - frontmatter: getRepoFrontmatter(plugin.settings, repo, frontmatter), + frontmatter: getRepoFrontmatter(plugin, repo, frontmatter), repo }; await createLink( @@ -58,12 +58,13 @@ export async function createLinkOnActiveFile(repo: Repository | null, plugin: Gi */ export async function shareActiveFile(plugin: GithubPublisher, repo: Repository | null): Promise { const file = plugin.app.workspace.getActiveFile(); - const frontmatter = file ? plugin.app.metadataCache.getFileCache(file)?.frontmatter : null; + const frontmatter = frontmatterFromFile(file, plugin, repo); if (file && frontmatter && isShared(frontmatter, plugin.settings, file, repo)) { await shareOneNote( await plugin.reloadOctokit(repo?.smartKey), file, repo, + frontmatter, ); } else { new Notice(i18next.t("commands.runOtherRepo.noFile")); @@ -79,16 +80,12 @@ export async function shareActiveFile(plugin: GithubPublisher, repo: Repository * @return {Promise} */ export async function deleteCommands(plugin : GithubPublisher, repo: Repository | null, branchName: string): Promise { - const repoFrontmatter = getRepoFrontmatter(plugin.settings, repo); + const repoFrontmatter = getRepoFrontmatter(plugin, repo, null, true); const publisher = await plugin.reloadOctokit(repo?.smartKey); const mono: MonoRepoProperties = { frontmatter: Array.isArray(repoFrontmatter) ? repoFrontmatter[0] : repoFrontmatter, repo, - convert: getFrontmatterSettings( - null, - plugin.settings, - repo - ) + convert: frontmatterSettingsRepository(plugin, repo) }; await purgeNotesRemote( publisher, @@ -110,13 +107,12 @@ export async function uploadAllNotes(plugin: GithubPublisher, repo: Repository | const statusBarItems = plugin.addStatusBarItem(); const publisher = await plugin.reloadOctokit(repo?.smartKey); const sharedFiles = publisher.getSharedFiles(repo); - const repoFrontmatter = getRepoFrontmatter(plugin.settings, repo); + const repoFrontmatter = getRepoFrontmatter(plugin, repo, undefined, true); const mono: MonoRepoProperties = { frontmatter: Array.isArray(repoFrontmatter) ? repoFrontmatter[0] : repoFrontmatter, repo, - convert: getFrontmatterSettings( - null, - plugin.settings, + convert: frontmatterSettingsRepository( + plugin, repo ) }; @@ -141,14 +137,14 @@ export async function uploadAllNotes(plugin: GithubPublisher, repo: Repository | export async function uploadNewNotes(plugin: GithubPublisher, branchName: string, repo: Repository|null): Promise { const publisher = await plugin.reloadOctokit(repo?.smartKey); - const repoFrontmatter = getRepoFrontmatter(plugin.settings, repo); + const repoFrontmatter = getRepoFrontmatter(plugin, repo, null, true); await shareNewNote( publisher, branchName, { frontmatter: Array.isArray(repoFrontmatter) ? repoFrontmatter[0] : repoFrontmatter, repo, - convert: getFrontmatterSettings(null, plugin.settings, repo) + convert: frontmatterSettingsRepository(plugin, repo) }, ); } @@ -183,7 +179,7 @@ export async function repositoryValidityActiveFile(plugin:GithubPublisher, repo: */ export async function uploadAllEditedNotes(plugin: GithubPublisher ,branchName: string, repo: Repository|null=null): Promise { const publisher = await plugin.reloadOctokit(repo?.smartKey); - const repoFrontmatter = getRepoFrontmatter(plugin.settings, repo); + const repoFrontmatter = getRepoFrontmatter(plugin, repo, null, true); await shareAllEditedNotes( publisher, @@ -191,7 +187,7 @@ export async function uploadAllEditedNotes(plugin: GithubPublisher ,branchName: { frontmatter: Array.isArray(repoFrontmatter) ? repoFrontmatter[0] : repoFrontmatter, repo, - convert: getFrontmatterSettings(null, plugin.settings, repo) + convert: frontmatterSettingsRepository(plugin, repo) }, ); } @@ -206,14 +202,14 @@ export async function uploadAllEditedNotes(plugin: GithubPublisher ,branchName: */ export async function shareEditedOnly(branchName: string, repo: Repository|null, plugin: GithubPublisher): Promise { const publisher = await plugin.reloadOctokit(repo?.smartKey); - const repoFrontmatter = getRepoFrontmatter(plugin.settings, repo); + const repoFrontmatter = getRepoFrontmatter(plugin, repo, null, true); await shareOnlyEdited( publisher, branchName, { frontmatter: Array.isArray(repoFrontmatter) ? repoFrontmatter[0] : repoFrontmatter, repo, - convert: getFrontmatterSettings(null, plugin.settings, repo) + convert: frontmatterSettingsRepository(plugin, repo) }, ); } diff --git a/src/conversion/file_path.ts b/src/conversion/file_path.ts index ef384497..c9504d85 100644 --- a/src/conversion/file_path.ts +++ b/src/conversion/file_path.ts @@ -6,6 +6,7 @@ import { Vault, } from "obsidian"; import GithubPublisher from "src/main"; +import merge from "ts-deepmerge"; import { FIND_REGEX, @@ -21,7 +22,7 @@ import { logs, } from "../utils"; import {checkIfRepoIsInAnother, isInternalShared, isShared} from "../utils/data_validation_test"; -import { frontmatterFromFile, getCategory, getFrontmatterSettings, getRepoFrontmatter } from "../utils/parse_frontmatter"; +import { frontmatterFromFile, frontmatterSettingsRepository, getCategory, getFrontmatterSettings, getRepoFrontmatter } from "../utils/parse_frontmatter"; import { createRegexFromText } from "./find_and_replace_text"; @@ -76,8 +77,8 @@ export async function createRelativePath( const settings = properties.plugin.settings; const shortRepo = properties.repository; const sourcePath = getReceiptFolder(sourceFile, shortRepo, properties.plugin, properties.frontmatter.repo); - const frontmatterTarget = frontmatterFromFile(targetFile.linked, properties.plugin); - const targetRepo = getRepoFrontmatter(settings, shortRepo, frontmatterTarget); + const frontmatterTarget = frontmatterFromFile(targetFile.linked, properties.plugin, properties.repository); + const targetRepo = getRepoFrontmatter(properties.plugin, shortRepo, frontmatterTarget); const isFromAnotherRepo = checkIfRepoIsInAnother(properties.frontmatter.repo, targetRepo); const shared = isInternalShared( frontmatterTarget, @@ -94,13 +95,18 @@ export async function createRelativePath( return getReceiptFolder(targetFile.linked, shortRepo, properties.plugin, targetRepo).split("/").at(-1) as string; } + const frontmatterSettingsFromFile = getFrontmatterSettings(frontmatter, settings, shortRepo); + const frontmatterSettingsFromRepository = frontmatterSettingsRepository(properties.plugin, shortRepo); + const frontmatterSettings = merge(frontmatterSettingsFromRepository, frontmatterSettingsFromFile); + const targetPath = targetFile.linked.extension === "md" && !targetFile.linked.name.includes("excalidraw") ? getReceiptFolder(targetFile.linked, shortRepo, properties.plugin, targetRepo) : getImagePath( targetFile.linked, - settings, - getFrontmatterSettings(frontmatter, settings, shortRepo) + properties.plugin, + frontmatterSettings, + targetRepo ); const sourceList = sourcePath.split("/"); const targetList = targetPath.split("/"); @@ -368,8 +374,8 @@ export function getReceiptFolder( const { vault} = plugin.app; const settings = plugin.settings; if (file.extension === "md") { - const frontmatter = frontmatterFromFile(file, plugin); - if (!repoFrontmatter) repoFrontmatter = getRepoFrontmatter(settings, otherRepo, frontmatter); + const frontmatter = frontmatterFromFile(file, plugin, otherRepo); + if (!repoFrontmatter) repoFrontmatter = getRepoFrontmatter(plugin, otherRepo, frontmatter); repoFrontmatter = repoFrontmatter instanceof Array ? repoFrontmatter : [repoFrontmatter]; let targetRepo = repoFrontmatter.find((repo) => repo.path?.smartkey === otherRepo?.smartKey || "default"); if (!targetRepo) targetRepo = repoFrontmatter[0]; @@ -409,10 +415,13 @@ export function getReceiptFolder( export function getImagePath( file: TFile, - settings: GitHubPublisherSettings, - sourceFrontmatter: FrontmatterConvert | null + plugin: GithubPublisher, + sourceFrontmatter: FrontmatterConvert | null, + repository: RepoFrontmatter | RepoFrontmatter[], ): string { - const imagePath = createImagePath(file, settings, sourceFrontmatter); + const settings = plugin.settings; + const overridePath = repository instanceof Array ? repository[0] : repository; + const imagePath = createImagePath(file, settings, sourceFrontmatter, overridePath); const path = regexOnPath(imagePath.path, settings); const name = regexOnFileName(imagePath.name, settings); return normalizePath(path.replace(file.name, name)); @@ -429,7 +438,9 @@ export function getImagePath( function createImagePath(file: TFile, settings: GitHubPublisherSettings, - sourceFrontmatter: FrontmatterConvert | null): { path: string, name: string } { + sourceFrontmatter: FrontmatterConvert | null, + overridePath?: RepoFrontmatter, +): { path: string, name: string } { let fileName = file.name; let filePath = file.path; if (file.name.includes(".excalidraw")) { @@ -437,18 +448,21 @@ function createImagePath(file: TFile, filePath = filePath.replace(".excalidraw.md", ".svg"); } const result : { path: string, name: string } = { path: filePath, name: fileName }; + const behavior = overridePath?.path?.type ? overridePath.path.type : settings.upload.behavior; + const rootFolder = overridePath?.path?.rootFolder ? overridePath.path.rootFolder : settings.upload.rootFolder; + const defaultFolderName = overridePath?.path?.defaultName ? overridePath.path.defaultName : settings.upload.defaultName; if (!sourceFrontmatter || !sourceFrontmatter.attachmentLinks) { if (settings.embed.useObsidianFolder) { - if (settings.upload.behavior === FolderSettings.yaml) { - result.path = settings.upload.rootFolder.length > 0 ? normalizePath(`${settings.upload.rootFolder}/${filePath}`) : filePath; + if (behavior === FolderSettings.yaml) { + result.path = rootFolder.length > 0 ? normalizePath(`${rootFolder}/${filePath}`) : filePath; } else { //no root, but default folder name - result.path = settings.upload.defaultName.length > 0 ? normalizePath(`${settings.upload.defaultName}/${filePath}`) : filePath; + result.path = defaultFolderName.length > 0 ? normalizePath(`${defaultFolderName}/${filePath}`) : filePath; } return result; } - const defaultImageFolder = settings.embed.folder; + const defaultImageFolder = overridePath?.path?.attachment?.folder ? overridePath.path?.attachment?.folder : settings.embed.folder; //find in override const isOverridden = settings.embed.overrideAttachments.filter((override) => { const isRegex = override.path.match(FIND_REGEX); @@ -469,10 +483,9 @@ function createImagePath(file: TFile, result.path = filePath; } else if (defaultImageFolder.length > 0) { - result.path = normalizePath(`${defaultImageFolder}/${filePath}`); - - } else if (settings.upload.defaultName.length > 0) { - result.path = normalizePath(`${settings.upload.defaultName}/${fileName}`); + result.path = normalizePath(`${defaultImageFolder}/${fileName}`); + } else if (defaultFolderName.length > 0) { + result.path = normalizePath(`${defaultFolderName}/${fileName}`); } else { result.path = filePath; } diff --git a/src/i18n/locales/af.json b/src/i18n/locales/af.json index befeca07..cf6f48e7 100644 --- a/src/i18n/locales/af.json +++ b/src/i18n/locales/af.json @@ -531,6 +531,10 @@ "desc": "", "title": "" }, + "setImport": { + "desc": "", + "title": "" + }, "shareKey": { "all": { "desc": "", diff --git a/src/i18n/locales/ar.json b/src/i18n/locales/ar.json index befeca07..cf6f48e7 100644 --- a/src/i18n/locales/ar.json +++ b/src/i18n/locales/ar.json @@ -531,6 +531,10 @@ "desc": "", "title": "" }, + "setImport": { + "desc": "", + "title": "" + }, "shareKey": { "all": { "desc": "", diff --git a/src/i18n/locales/ca.json b/src/i18n/locales/ca.json index befeca07..cf6f48e7 100644 --- a/src/i18n/locales/ca.json +++ b/src/i18n/locales/ca.json @@ -531,6 +531,10 @@ "desc": "", "title": "" }, + "setImport": { + "desc": "", + "title": "" + }, "shareKey": { "all": { "desc": "", diff --git a/src/i18n/locales/cs.json b/src/i18n/locales/cs.json index befeca07..cf6f48e7 100644 --- a/src/i18n/locales/cs.json +++ b/src/i18n/locales/cs.json @@ -531,6 +531,10 @@ "desc": "", "title": "" }, + "setImport": { + "desc": "", + "title": "" + }, "shareKey": { "all": { "desc": "", diff --git a/src/i18n/locales/da.json b/src/i18n/locales/da.json index befeca07..cf6f48e7 100644 --- a/src/i18n/locales/da.json +++ b/src/i18n/locales/da.json @@ -531,6 +531,10 @@ "desc": "", "title": "" }, + "setImport": { + "desc": "", + "title": "" + }, "shareKey": { "all": { "desc": "", diff --git a/src/i18n/locales/de.json b/src/i18n/locales/de.json index befeca07..cf6f48e7 100644 --- a/src/i18n/locales/de.json +++ b/src/i18n/locales/de.json @@ -531,6 +531,10 @@ "desc": "", "title": "" }, + "setImport": { + "desc": "", + "title": "" + }, "shareKey": { "all": { "desc": "", diff --git a/src/i18n/locales/el.json b/src/i18n/locales/el.json index befeca07..cf6f48e7 100644 --- a/src/i18n/locales/el.json +++ b/src/i18n/locales/el.json @@ -531,6 +531,10 @@ "desc": "", "title": "" }, + "setImport": { + "desc": "", + "title": "" + }, "shareKey": { "all": { "desc": "", diff --git a/src/i18n/locales/en.json b/src/i18n/locales/en.json index 0921b0e0..175bbc71 100644 --- a/src/i18n/locales/en.json +++ b/src/i18n/locales/en.json @@ -535,6 +535,10 @@ "desc": "Choose the property key you want to use to link the property of a file to another, without rewrite them each time. Work only for file linked by a wikilink in the frontmatter.", "title": "Set of options" }, + "setImport": { + "desc": "Import a set of options from the frontmatter of a file", + "title": "Import an option group" + }, "shareKey": { "all": { "desc": "Share all files regardless of the state of the share key of the notes", diff --git a/src/i18n/locales/es.json b/src/i18n/locales/es.json index befeca07..cf6f48e7 100644 --- a/src/i18n/locales/es.json +++ b/src/i18n/locales/es.json @@ -531,6 +531,10 @@ "desc": "", "title": "" }, + "setImport": { + "desc": "", + "title": "" + }, "shareKey": { "all": { "desc": "", diff --git a/src/i18n/locales/fi.json b/src/i18n/locales/fi.json index befeca07..cf6f48e7 100644 --- a/src/i18n/locales/fi.json +++ b/src/i18n/locales/fi.json @@ -531,6 +531,10 @@ "desc": "", "title": "" }, + "setImport": { + "desc": "", + "title": "" + }, "shareKey": { "all": { "desc": "", diff --git a/src/i18n/locales/fr.json b/src/i18n/locales/fr.json index 1e7d870c..d66a98c9 100644 --- a/src/i18n/locales/fr.json +++ b/src/i18n/locales/fr.json @@ -535,6 +535,10 @@ "desc": "Choisissez la clé de propriété que vous souhaitez utiliser pour lier la propriété d'un fichier à un autre, sans les réécrire à chaque fois. Ne fonctionne que pour les fichiers liés par un lien wiki dans le frontmatter.", "title": "Set d'options" }, + "setImport": { + "desc": "Importer un set d'options depuis le frontmatter d'un fichier", + "title": "Importer un groupe d'option" + }, "shareKey": { "all": { "desc": "Autoriser le partage de tous les fichiers et ignorer l'état de la clé de partage", diff --git a/src/i18n/locales/he.json b/src/i18n/locales/he.json index befeca07..cf6f48e7 100644 --- a/src/i18n/locales/he.json +++ b/src/i18n/locales/he.json @@ -531,6 +531,10 @@ "desc": "", "title": "" }, + "setImport": { + "desc": "", + "title": "" + }, "shareKey": { "all": { "desc": "", diff --git a/src/i18n/locales/hu.json b/src/i18n/locales/hu.json index befeca07..cf6f48e7 100644 --- a/src/i18n/locales/hu.json +++ b/src/i18n/locales/hu.json @@ -531,6 +531,10 @@ "desc": "", "title": "" }, + "setImport": { + "desc": "", + "title": "" + }, "shareKey": { "all": { "desc": "", diff --git a/src/i18n/locales/it.json b/src/i18n/locales/it.json index 8814e32f..817b72e6 100644 --- a/src/i18n/locales/it.json +++ b/src/i18n/locales/it.json @@ -529,6 +529,10 @@ "desc": "", "title": "" }, + "setImport": { + "desc": "", + "title": "" + }, "shareKey": { "all": { "desc": "", diff --git a/src/i18n/locales/ja.json b/src/i18n/locales/ja.json index befeca07..cf6f48e7 100644 --- a/src/i18n/locales/ja.json +++ b/src/i18n/locales/ja.json @@ -531,6 +531,10 @@ "desc": "", "title": "" }, + "setImport": { + "desc": "", + "title": "" + }, "shareKey": { "all": { "desc": "", diff --git a/src/i18n/locales/ko.json b/src/i18n/locales/ko.json index befeca07..cf6f48e7 100644 --- a/src/i18n/locales/ko.json +++ b/src/i18n/locales/ko.json @@ -531,6 +531,10 @@ "desc": "", "title": "" }, + "setImport": { + "desc": "", + "title": "" + }, "shareKey": { "all": { "desc": "", diff --git a/src/i18n/locales/nl.json b/src/i18n/locales/nl.json index 8814e32f..817b72e6 100644 --- a/src/i18n/locales/nl.json +++ b/src/i18n/locales/nl.json @@ -529,6 +529,10 @@ "desc": "", "title": "" }, + "setImport": { + "desc": "", + "title": "" + }, "shareKey": { "all": { "desc": "", diff --git a/src/i18n/locales/no.json b/src/i18n/locales/no.json index 8814e32f..817b72e6 100644 --- a/src/i18n/locales/no.json +++ b/src/i18n/locales/no.json @@ -529,6 +529,10 @@ "desc": "", "title": "" }, + "setImport": { + "desc": "", + "title": "" + }, "shareKey": { "all": { "desc": "", diff --git a/src/i18n/locales/pl.json b/src/i18n/locales/pl.json index befeca07..cf6f48e7 100644 --- a/src/i18n/locales/pl.json +++ b/src/i18n/locales/pl.json @@ -531,6 +531,10 @@ "desc": "", "title": "" }, + "setImport": { + "desc": "", + "title": "" + }, "shareKey": { "all": { "desc": "", diff --git a/src/i18n/locales/pt-BR.json b/src/i18n/locales/pt-BR.json index befeca07..cf6f48e7 100644 --- a/src/i18n/locales/pt-BR.json +++ b/src/i18n/locales/pt-BR.json @@ -531,6 +531,10 @@ "desc": "", "title": "" }, + "setImport": { + "desc": "", + "title": "" + }, "shareKey": { "all": { "desc": "", diff --git a/src/i18n/locales/pt.json b/src/i18n/locales/pt.json index befeca07..cf6f48e7 100644 --- a/src/i18n/locales/pt.json +++ b/src/i18n/locales/pt.json @@ -531,6 +531,10 @@ "desc": "", "title": "" }, + "setImport": { + "desc": "", + "title": "" + }, "shareKey": { "all": { "desc": "", diff --git a/src/i18n/locales/ro.json b/src/i18n/locales/ro.json index 8814e32f..817b72e6 100644 --- a/src/i18n/locales/ro.json +++ b/src/i18n/locales/ro.json @@ -529,6 +529,10 @@ "desc": "", "title": "" }, + "setImport": { + "desc": "", + "title": "" + }, "shareKey": { "all": { "desc": "", diff --git a/src/i18n/locales/ru.json b/src/i18n/locales/ru.json index befeca07..cf6f48e7 100644 --- a/src/i18n/locales/ru.json +++ b/src/i18n/locales/ru.json @@ -531,6 +531,10 @@ "desc": "", "title": "" }, + "setImport": { + "desc": "", + "title": "" + }, "shareKey": { "all": { "desc": "", diff --git a/src/i18n/locales/sr.json b/src/i18n/locales/sr.json index befeca07..cf6f48e7 100644 --- a/src/i18n/locales/sr.json +++ b/src/i18n/locales/sr.json @@ -531,6 +531,10 @@ "desc": "", "title": "" }, + "setImport": { + "desc": "", + "title": "" + }, "shareKey": { "all": { "desc": "", diff --git a/src/i18n/locales/sv.json b/src/i18n/locales/sv.json index befeca07..cf6f48e7 100644 --- a/src/i18n/locales/sv.json +++ b/src/i18n/locales/sv.json @@ -531,6 +531,10 @@ "desc": "", "title": "" }, + "setImport": { + "desc": "", + "title": "" + }, "shareKey": { "all": { "desc": "", diff --git a/src/i18n/locales/tr.json b/src/i18n/locales/tr.json index befeca07..cf6f48e7 100644 --- a/src/i18n/locales/tr.json +++ b/src/i18n/locales/tr.json @@ -531,6 +531,10 @@ "desc": "", "title": "" }, + "setImport": { + "desc": "", + "title": "" + }, "shareKey": { "all": { "desc": "", diff --git a/src/i18n/locales/uk.json b/src/i18n/locales/uk.json index befeca07..cf6f48e7 100644 --- a/src/i18n/locales/uk.json +++ b/src/i18n/locales/uk.json @@ -531,6 +531,10 @@ "desc": "", "title": "" }, + "setImport": { + "desc": "", + "title": "" + }, "shareKey": { "all": { "desc": "", diff --git a/src/i18n/locales/vi.json b/src/i18n/locales/vi.json index befeca07..cf6f48e7 100644 --- a/src/i18n/locales/vi.json +++ b/src/i18n/locales/vi.json @@ -531,6 +531,10 @@ "desc": "", "title": "" }, + "setImport": { + "desc": "", + "title": "" + }, "shareKey": { "all": { "desc": "", diff --git a/src/i18n/locales/zh-CN.json b/src/i18n/locales/zh-CN.json index befeca07..cf6f48e7 100644 --- a/src/i18n/locales/zh-CN.json +++ b/src/i18n/locales/zh-CN.json @@ -531,6 +531,10 @@ "desc": "", "title": "" }, + "setImport": { + "desc": "", + "title": "" + }, "shareKey": { "all": { "desc": "", diff --git a/src/i18n/locales/zh-TW.json b/src/i18n/locales/zh-TW.json index befeca07..cf6f48e7 100644 --- a/src/i18n/locales/zh-TW.json +++ b/src/i18n/locales/zh-TW.json @@ -531,6 +531,10 @@ "desc": "", "title": "" }, + "setImport": { + "desc": "", + "title": "" + }, "shareKey": { "all": { "desc": "", diff --git a/src/settings/interface.ts b/src/settings/interface.ts index 8cc4e731..0bcda8f6 100644 --- a/src/settings/interface.ts +++ b/src/settings/interface.ts @@ -1,4 +1,4 @@ -import { TFile } from "obsidian"; +import { FrontMatterCache, TFile } from "obsidian"; import GithubPublisher from "../main"; @@ -56,8 +56,8 @@ export interface Repository { replacement: string; }[] } - } - + }, + set: string; } /** @@ -214,10 +214,12 @@ export interface MonoProperties { plugin: GithubPublisher; frontmatter: { general: FrontmatterConvert; - repo: RepoFrontmatter + repo: RepoFrontmatter; + source: FrontMatterCache | null | undefined; }, repository: Repository | null; filepath: string; + } export interface MonoRepoProperties { @@ -229,6 +231,7 @@ export interface MonoRepoProperties { export interface MultiRepoProperties { frontmatter: RepoFrontmatter[] | RepoFrontmatter; repo: Repository | null; + } diff --git a/src/settings/modals/manage_repo.ts b/src/settings/modals/manage_repo.ts index 045c28d7..0346cfe6 100644 --- a/src/settings/modals/manage_repo.ts +++ b/src/settings/modals/manage_repo.ts @@ -1,11 +1,44 @@ import i18next from "i18next"; -import {App, Modal, Notice, Setting} from "obsidian"; +import {AbstractInputSuggest, App, Modal, Notice, Setting} from "obsidian"; import GithubPublisher from "../../main"; import {checkRepositoryValidity, verifyRateLimitAPI} from "../../utils/data_validation_test"; import {GitHubPublisherSettings, GithubTiersVersion, Repository} from "../interface"; import { migrateToken } from "../migrate"; + +class SetClassSuggester extends AbstractInputSuggest { + plugin: GithubPublisher; + constructor(private inputEl: HTMLInputElement, plugin: GithubPublisher, private onSubmit: (value: string) => void) { + super(plugin.app, inputEl); + this.plugin = plugin; + } + + renderSuggestion(value: string, el: HTMLElement): void { + el.setText(value); + } + + getSuggestions(query: string): string[] { + const markdownFile = this.plugin.app.vault.getFiles().filter((file) => { + if (file.extension === "md" && file.path.toLowerCase().contains(query.toLowerCase())) { + const frontmatter = this.plugin.app.metadataCache.getFileCache(file)?.frontmatter; + if (frontmatter) return true; + } + return false; + }); + return markdownFile.map((file) => file.path); + } + + //eslint-disable-next-line @typescript-eslint/no-unused-vars + selectSuggestion(value: string, evt: MouseEvent | KeyboardEvent): void { + this.onSubmit(value); + this.inputEl.value = value; + this.inputEl.focus(); + this.inputEl.trigger("input"); + this.close(); + } +} + /** * @description This class is used to add a new repo to the settings in the "otherRepo" in the github setting section * It will list all the repo in the settings and allow the user to add a new one, edit or delete an existing one @@ -74,7 +107,8 @@ export class ModalAddingNewRepository extends Modal { slugify: this.settings.plugin.copyLink.transform.slugify, applyRegex: this.settings.plugin.copyLink.transform.applyRegex } - } + }, + set: "" }; new Setting(contentEl) @@ -409,6 +443,18 @@ class ModalEditingRepository extends Modal { contentEl.createEl("h3", { text: i18next.t("settings.github.smartRepo.modals.otherConfig") }); + new Setting(contentEl) + .setName(i18next.t("settings.plugin.setImport.title")) + .setDesc(i18next.t("settings.plugin.setImport.desc")) + .addSearch((search) => { + search + .setValue("") + .setPlaceholder("path/to/file.md"); + new SetClassSuggester(search.inputEl, this.plugin, (result) => { + this.repository.set = result; + }); + }); + new Setting(contentEl) .setName(i18next.t("settings.plugin.shareKey.all.title")) .setDesc(i18next.t("settings.plugin.shareKey.all.desc")) diff --git a/src/utils/data_validation_test.ts b/src/utils/data_validation_test.ts index c24cfebd..5719d281 100644 --- a/src/utils/data_validation_test.ts +++ b/src/utils/data_validation_test.ts @@ -3,6 +3,7 @@ import { Octokit } from "@octokit/core"; import i18next from "i18next"; import { FrontMatterCache, normalizePath,Notice, TFile, TFolder} from "obsidian"; import GithubPublisher from "src/main"; +import merge from "ts-deepmerge"; import {GithubBranch} from "../GitHub/branch"; import {FIND_REGEX, FrontmatterConvert, GitHubPublisherSettings, GithubTiersVersion, MultiProperties, RepoFrontmatter, Repository} from "../settings/interface"; @@ -55,7 +56,7 @@ export function getRepoSharedKey(plugin: GithubPublisher, frontmatter?: FrontMat return defaultRepo(settings); } else if (!frontmatter) return null; const linkedFrontmatter = getLinkedFrontmatter(frontmatter, file, plugin); - frontmatter = linkedFrontmatter ? {...linkedFrontmatter, ...frontmatter} : frontmatter; + frontmatter = linkedFrontmatter ? merge(linkedFrontmatter, frontmatter) : frontmatter; for (const repo of allOtherRepo) { if (frontmatter[repo.shareKey]) { return repo; @@ -150,7 +151,7 @@ export function multipleSharedKey(frontmatter: FrontMatterCache | undefined | nu } if (!frontmatter) return keysInFile; const linkedRepo = getLinkedFrontmatter(frontmatter, file, plugin); - frontmatter = linkedRepo ? {...linkedRepo, ...frontmatter} : frontmatter; + frontmatter = linkedRepo ? merge(linkedRepo, frontmatter) : frontmatter; const allKey = settings.github.otherRepo.map((repo) => repo.shareKey); allKey.push(settings.plugin.shareKey); @@ -325,8 +326,8 @@ export async function checkRepositoryValidity( silent: boolean=false): Promise { const settings = PublisherManager.settings; try { - const frontmatter = frontmatterFromFile(file, PublisherManager.plugin); - const repoFrontmatter = getRepoFrontmatter(settings, repository, frontmatter); + const frontmatter = frontmatterFromFile(file, PublisherManager.plugin, repository); + const repoFrontmatter = getRepoFrontmatter(PublisherManager.plugin, repository, frontmatter); const isNotEmpty = await checkEmptyConfiguration(repoFrontmatter, PublisherManager.plugin, silent); if (isNotEmpty) { await PublisherManager.checkRepository(repoFrontmatter, silent); @@ -408,6 +409,7 @@ export function defaultRepo(settings: GitHubPublisherSettings): Repository { applyRegex: settings.plugin.copyLink.transform.applyRegex, }, }, + set: "" }; } diff --git a/src/utils/index.ts b/src/utils/index.ts index 1bfe8930..d0eaa746 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -255,7 +255,7 @@ export async function createLink( if (baseLink.length === 0) { baseLink = repo instanceof Array ? `https://${github.user}.github.io/${settings.github.repo}/` : `https://${repo.owner}.github.io/${repo.repo}/`; } - const frontmatter = frontmatterFromFile(file, plugin); + const frontmatter = frontmatterFromFile(file, plugin, otherRepo); let removePart = copyLink.removePart; const smartKey = otherRepo?.smartKey ? `${otherRepo.smartKey}.` : ""; if (frontmatter) { diff --git a/src/utils/parse_frontmatter.ts b/src/utils/parse_frontmatter.ts index 6d57245e..0d9aacb0 100644 --- a/src/utils/parse_frontmatter.ts +++ b/src/utils/parse_frontmatter.ts @@ -5,9 +5,31 @@ import { FrontMatterCache, normalizePath, TFile } from "obsidian"; import GithubPublisher from "src/main"; +import merge from "ts-deepmerge"; import { FolderSettings, FrontmatterConvert, GitHubPublisherSettings, Path, RepoFrontmatter, Repository } from "../settings/interface"; +export function frontmatterSettingsRepository(plugin: GithubPublisher, repo: Repository | null) { + const defaultConvert = getFrontmatterSettings(null, plugin.settings, repo); + if (!repo?.set) return defaultConvert; + const fileAsTFile = plugin.app.vault.getFileByPath(repo.set); + if (!fileAsTFile) return defaultConvert; + return getFrontmatterSettings( + plugin.app.metadataCache.getFileCache(fileAsTFile)?.frontmatter, + plugin.settings, + repo + ); +} + +export function getDefaultRepoFrontmatter(repository: Repository | null, plugin: GithubPublisher) { + const defaultSettings = getRepoFrontmatter(plugin, repository); + if (!repository) return defaultSettings; + const fileAsTFile = plugin.app.vault.getFileByPath(repository.set); + if (!fileAsTFile) return defaultSettings; + return getRepoFrontmatter(plugin, repository, plugin.app.metadataCache.getFileCache(fileAsTFile)?.frontmatter); +} + + /** * Retrieves the frontmatter settings for a given file. * @@ -73,20 +95,31 @@ function booleanRemoveEmbed(removeEmbed: unknown) { } else return "keep"; } + /** * Retrieves the repository frontmatter based on the provided settings and repository information. * - * @param {GitHubPublisherSettings} settings - The GitHub Publisher settings. + * @param {GithubPublisher} plugin - The plugin instance * @param {Repository | null} repository - The repository information. * @param {FrontMatterCache | null} frontmatter - The frontmatter cache. + * @param {boolean} [checkSet] - Whether to check the set file for frontmatter (preventing multiple reading of the same file) * @returns {RepoFrontmatter[] | RepoFrontmatter} - The repository frontmatter. */ export function getRepoFrontmatter( - settings: GitHubPublisherSettings, + plugin: GithubPublisher, repository: Repository | null, frontmatter?: FrontMatterCache | null, + checkSet?: boolean ): RepoFrontmatter[] | RepoFrontmatter { + const settings = plugin.settings; let github = repository ?? settings.github; + if (checkSet && repository?.set && repository.set.length > 0) { + const file = plugin.app.vault.getAbstractFileByPath(repository.set) instanceof TFile ? plugin.app.vault.getAbstractFileByPath(repository.set) : null; + if (file) { + const setFrontmatter = plugin.app.metadataCache.getFileCache(file as TFile)?.frontmatter; + frontmatter = frontmatter && setFrontmatter ? merge(frontmatter, setFrontmatter) : setFrontmatter ?? frontmatter ; + } + } if (frontmatter && typeof frontmatter["shortRepo"] === "string" && frontmatter["shortRepo"] !== "default") { const smartKey = frontmatter.shortRepo.toLowerCase(); const allOtherRepo = settings.github.otherRepo; @@ -114,12 +147,12 @@ export function getRepoFrontmatter( repoFrontmatter.autoclean = false; } if (!frontmatter || (frontmatter.multipleRepo === undefined && frontmatter.repo === undefined && frontmatter.shortRepo === undefined)) { - return parsePath(settings, repository, repoFrontmatter, frontmatter); + return parsePath(plugin, repository, repoFrontmatter, frontmatter); } let isFrontmatterAutoClean = null; if (frontmatter.multipleRepo) { const multipleRepo = parseMultipleRepo(frontmatter, repoFrontmatter); - return parsePath(settings, repository, multipleRepo, frontmatter); + return parsePath(plugin, repository, multipleRepo, frontmatter); } else if (frontmatter.repo) { if (typeof frontmatter.repo === "object") { if (frontmatter.repo.branch != undefined) { @@ -141,12 +174,12 @@ export function getRepoFrontmatter( repoFrontmatter = repositoryStringSlice(repo, repoFrontmatter); } } else if (frontmatter.shortRepo instanceof Array) { - return multipleShortKeyRepo(frontmatter, settings.github.otherRepo, repoFrontmatter, settings); + return multipleShortKeyRepo(frontmatter, settings.github.otherRepo, repoFrontmatter, plugin); } if (frontmatter.autoclean != undefined && isFrontmatterAutoClean === null) { repoFrontmatter.autoclean = frontmatter.autoclean; } - return parsePath(settings, repository, repoFrontmatter); + return parsePath(plugin, repository, repoFrontmatter); } /** @@ -230,7 +263,7 @@ function removeDuplicateRepo(multipleRepo: RepoFrontmatter[]) { * @param {Repository[]} allRepo - The list of all repo from the settings * @param {RepoFrontmatter} repoFrontmatter - The default repoFrontmatter (from the default settings) */ -function multipleShortKeyRepo(frontmatter: FrontMatterCache, allRepo: Repository[], repoFrontmatter: RepoFrontmatter, setting: GitHubPublisherSettings) { +function multipleShortKeyRepo(frontmatter: FrontMatterCache, allRepo: Repository[], repoFrontmatter: RepoFrontmatter, plugin: GithubPublisher) { if (frontmatter.shortRepo instanceof Array) { const multipleRepo: RepoFrontmatter[] = []; for (const repo of frontmatter.shortRepo) { @@ -252,7 +285,7 @@ function multipleShortKeyRepo(frontmatter: FrontMatterCache, allRepo: Repository commitMsg: shortRepo.workflow.commitMessage, dryRun: repoFrontmatter.dryRun } as RepoFrontmatter; - const parsedPath = parsePath(setting, shortRepo, repo); + const parsedPath = parsePath(plugin, shortRepo, repo); repo = Array.isArray(parsedPath) ? parsedPath[0] : parsedPath; multipleRepo.push(repo); } @@ -318,12 +351,13 @@ export function getCategory( } export function parsePath( - settings: GitHubPublisherSettings, + plugin: GithubPublisher, repository: Repository | null, repoFrontmatter: RepoFrontmatter | RepoFrontmatter[], frontmatter?: FrontMatterCache | null | undefined ): RepoFrontmatter[] | RepoFrontmatter { repoFrontmatter = repoFrontmatter instanceof Array ? repoFrontmatter : [repoFrontmatter]; + const settings = plugin.settings; const splitArrayPath = (path?: string[] | string):string|undefined => { if (!path) return; if (path instanceof Array) { @@ -340,6 +374,7 @@ export function parsePath( for (const repo of repoFrontmatter) { const smartKey = repository ? repository.smartKey : "default"; + const path: Path = { type: matchType(frontmatter?.type), defaultName: frontmatter?.defaultName ?? settings.upload.defaultName, @@ -414,7 +449,7 @@ function getFrontmatterSettingRepository( if (frontmatter?.[`${key}includeLinks`] != undefined) { frontConvert.includeLinks = frontmatter[`${smartKey}.includeLinks`]; } - + return frontConvert; } @@ -445,12 +480,20 @@ export function getLinkedFrontmatter( return linked; } -export function frontmatterFromFile(file: TFile | null, plugin: GithubPublisher) { +export function frontmatterFromFile(file: TFile | null, plugin: GithubPublisher, repo: Repository | null) { let frontmatter = null; + if (file) { frontmatter = plugin.app.metadataCache.getFileCache(file)?.frontmatter; const linkedFrontmatter = getLinkedFrontmatter(frontmatter, file, plugin); - frontmatter = linkedFrontmatter ? { ...linkedFrontmatter, ...frontmatter } : frontmatter; + frontmatter = merge(linkedFrontmatter ?? {}, frontmatter ?? {}); + } + if (repo && repo.set.length > 0) { + const fileAsTFile = plugin.app.vault.getFileByPath(repo.set); + if (fileAsTFile) { + const setFrontmatter = plugin.app.metadataCache.getFileCache(fileAsTFile)?.frontmatter; + frontmatter = frontmatter && setFrontmatter ? merge(frontmatter, setFrontmatter) : setFrontmatter ?? frontmatter; + } } return frontmatter; }