From b48764cc8eded8929eeed5223f9ae816eb86affc Mon Sep 17 00:00:00 2001 From: Aurailus Date: Sun, 13 Aug 2023 23:23:38 -0700 Subject: [PATCH] Change the delimiter for option-multi to an emoji sequence to avoid Aliases with commas being incorrectly split. --- .gitignore | 5 +- package-lock.json | 60 ++++++++----------- .../ContextView/ContextListView.tsx | 1 + .../ContextView/DataTypeView/DataTypeView.tsx | 1 + src/components/ContextView/MDBContext.tsx | 2 + src/dispatch/mdb.ts | 13 ++-- src/superstate/cacheParsers.ts | 13 ++-- src/utils/contexts/mdb.ts | 12 ++-- src/utils/metadata/dv.ts | 2 + .../metadata/frontmatter/parseFrontMatter.ts | 7 ++- src/utils/parser.tsx | 3 +- src/utils/serializer.ts | 11 +++- 12 files changed, 70 insertions(+), 60 deletions(-) diff --git a/.gitignore b/.gitignore index ece2d46..14f99dd 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,7 @@ node_modules .env .DS_Store undefined -.vscode \ No newline at end of file +.vscode +backups +Spaces.mdb +data.json diff --git a/package-lock.json b/package-lock.json index 3d3e706..6826113 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "make-md", - "version": "0.7.6", + "version": "0.7.18", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "make-md", - "version": "0.7.6", + "version": "0.7.18", "license": "MIT", "dependencies": { "@codemirror/language": "^6.3.0", @@ -340,9 +340,10 @@ } }, "node_modules/@types/codemirror": { - "version": "0.0.108", + "version": "5.60.8", + "resolved": "https://registry.npmjs.org/@types/codemirror/-/codemirror-5.60.8.tgz", + "integrity": "sha512-VjFgDF/eB+Aklcy15TtOTLQeMjTo07k7KAjql8OK5Dirr7a6sJY4T1uVBDuTVG9VEmn1uUsohOpYnVfgC6/jyw==", "dev": true, - "license": "MIT", "dependencies": { "@types/tern": "*" } @@ -358,9 +359,10 @@ "license": "MIT" }, "node_modules/@types/estree": { - "version": "1.0.0", - "dev": true, - "license": "MIT" + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz", + "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==", + "dev": true }, "node_modules/@types/hoist-non-react-statics": { "version": "3.3.1", @@ -543,8 +545,9 @@ }, "node_modules/@types/tern": { "version": "0.23.4", + "resolved": "https://registry.npmjs.org/@types/tern/-/tern-0.23.4.tgz", + "integrity": "sha512-JAUw1iXGO1qaWwEOzxTKJZ/5JxVeON9kvGZ/osgZaJImBnyjyn0cjovPsf6FNLmyGY8Vw9DoXZCMlfMkMwHRWg==", "dev": true, - "license": "MIT", "dependencies": { "@types/estree": "*" } @@ -3348,11 +3351,12 @@ } }, "node_modules/obsidian": { - "version": "1.1.1", + "version": "1.4.0", + "resolved": "git+ssh://git@github.com/obsidianmd/obsidian-api.git#90517f4fa762838008a638069d8e151f071a8ef7", "dev": true, "license": "MIT", "dependencies": { - "@types/codemirror": "0.0.108", + "@types/codemirror": "5.60.8", "moment": "2.29.4" }, "peerDependencies": { @@ -3387,19 +3391,6 @@ "obsidian-daily-notes-interface": "dist/main.js" } }, - "node_modules/obsidian-daily-notes-interface/node_modules/obsidian": { - "version": "1.1.13", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/codemirror": "0.0.108", - "moment": "2.29.4" - }, - "peerDependencies": { - "@codemirror/state": "^6.0.0", - "@codemirror/view": "^6.0.0" - } - }, "node_modules/obsidian-daily-notes-interface/node_modules/tslib": { "version": "2.1.0", "dev": true, @@ -4425,7 +4416,9 @@ "version": "8.7.9" }, "@types/codemirror": { - "version": "0.0.108", + "version": "5.60.8", + "resolved": "https://registry.npmjs.org/@types/codemirror/-/codemirror-5.60.8.tgz", + "integrity": "sha512-VjFgDF/eB+Aklcy15TtOTLQeMjTo07k7KAjql8OK5Dirr7a6sJY4T1uVBDuTVG9VEmn1uUsohOpYnVfgC6/jyw==", "dev": true, "requires": { "@types/tern": "*" @@ -4440,7 +4433,9 @@ "dev": true }, "@types/estree": { - "version": "1.0.0", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz", + "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==", "dev": true }, "@types/hoist-non-react-statics": { @@ -4619,6 +4614,8 @@ }, "@types/tern": { "version": "0.23.4", + "resolved": "https://registry.npmjs.org/@types/tern/-/tern-0.23.4.tgz", + "integrity": "sha512-JAUw1iXGO1qaWwEOzxTKJZ/5JxVeON9kvGZ/osgZaJImBnyjyn0cjovPsf6FNLmyGY8Vw9DoXZCMlfMkMwHRWg==", "dev": true, "requires": { "@types/estree": "*" @@ -6492,10 +6489,11 @@ } }, "obsidian": { - "version": "1.1.1", + "version": "git+ssh://git@github.com/obsidianmd/obsidian-api.git#90517f4fa762838008a638069d8e151f071a8ef7", "dev": true, + "from": "obsidian@^1.1.1", "requires": { - "@types/codemirror": "0.0.108", + "@types/codemirror": "5.60.8", "moment": "2.29.4" } }, @@ -6522,14 +6520,6 @@ "tslib": "2.1.0" }, "dependencies": { - "obsidian": { - "version": "1.1.13", - "dev": true, - "requires": { - "@types/codemirror": "0.0.108", - "moment": "2.29.4" - } - }, "tslib": { "version": "2.1.0", "dev": true diff --git a/src/components/ContextView/ContextListView.tsx b/src/components/ContextView/ContextListView.tsx index 567d49a..2dd7a01 100644 --- a/src/components/ContextView/ContextListView.tsx +++ b/src/components/ContextView/ContextListView.tsx @@ -9,6 +9,7 @@ export const ContextListView = (props: { plugin: MakeMDPlugin }) => { const { schema } = useContext(MDBContext); const [error, resetError] = useErrorBoundary(); if (error) console.log(error); + return schema ? ( schema.type == "flow" ? ( diff --git a/src/components/ContextView/DataTypeView/DataTypeView.tsx b/src/components/ContextView/DataTypeView/DataTypeView.tsx index 22e7e2e..14fed4b 100644 --- a/src/components/ContextView/DataTypeView/DataTypeView.tsx +++ b/src/components/ContextView/DataTypeView/DataTypeView.tsx @@ -96,6 +96,7 @@ export const DataTypeView: React.FC = ( > ); } else if (fieldType.type == "fileprop") { + return ; } else if (fieldType.type == "number") { return ; diff --git a/src/components/ContextView/MDBContext.tsx b/src/components/ContextView/MDBContext.tsx index e54eda1..43d138b 100644 --- a/src/components/ContextView/MDBContext.tsx +++ b/src/components/ContextView/MDBContext.tsx @@ -220,6 +220,7 @@ export const MDBProvider: React.FC< ) ?? [], [tableData, schema, contextTable] ); + const sortedColumns = useMemo(() => { return cols .filter( @@ -342,6 +343,7 @@ export const MDBProvider: React.FC< const col = (table == "" ? tableData : contextTable[table])?.cols.find( (f) => f.name == column ); + if (col) saveFrontmatterValue( props.plugin, diff --git a/src/dispatch/mdb.ts b/src/dispatch/mdb.ts index 5896154..10d6e19 100644 --- a/src/dispatch/mdb.ts +++ b/src/dispatch/mdb.ts @@ -154,7 +154,7 @@ export const insertContextColumn = async ( context: ContextInfo, field: MDBField ): Promise => { - + let tagFileExists = abstractFileAtPathExists(app, context.dbPath); if (!tagFileExists) { tagFileExists = await createDefaultDB(plugin, context); @@ -207,7 +207,9 @@ const fileToFM = (afile: TAbstractFile, cols: string[], plugin: MakeMDPlugin) => const fm = frontMatterForFile(file); const fmKeys = frontMatterKeys(fm).filter((f) => cols.some((g) => f == g)); const rows = fmKeys.reduce( - (p, c) => ({ ...p, [c]: parseFrontMatter(c, fm[c]) }), + (p, c) => { + return ({ ...p, [c]: parseFrontMatter(c, fm[c]) }) + }, {} ); if (plugin.dataViewAPI()) { @@ -246,6 +248,7 @@ export const onMetadataChange = async ( file: TAbstractFile, contexts: ContextInfo[] ): Promise => { + // console.log(contexts); const promises = contexts.map((context) => { return processContextFile(plugin, context, async (mdb, context) => { const newDB = { @@ -327,7 +330,7 @@ export const renameTagInContexts = async ( plugin: MakeMDPlugin, export const addFileInContexts = async (plugin: MakeMDPlugin, path: string, contexts: ContextInfo[]): Promise => { - + const promises = contexts.map((context) => { return processContextFile(plugin, context, async (mdb, context) => { const newDB = insertRowsIfUnique(mdb, [{ File: path }]); @@ -338,7 +341,7 @@ export const addFileInContexts = async (plugin: MakeMDPlugin, }) }); return Promise.all(promises); - + } export const renameLinkInContexts = async (plugin: MakeMDPlugin, @@ -406,7 +409,7 @@ export const removeFileInContexts = async (plugin: MakeMDPlugin, saveContextToFrontmatter(path, mdb.cols, removeRow, plugin) } const newDB = removeRowForFile(mdb, path); - + if (!_.isEqual(mdb, newDB)) { await saveDB(plugin, context, newDB);} diff --git a/src/superstate/cacheParsers.ts b/src/superstate/cacheParsers.ts index 6f8a8c5..8b8ee1f 100644 --- a/src/superstate/cacheParsers.ts +++ b/src/superstate/cacheParsers.ts @@ -113,7 +113,7 @@ export const parseFileContetxs = (file: AFile, tags: string[], contextsCache: Ma contexts.push(...tags.filter(t => contextsCache.has(t))) if (file.parent != '/') contexts.push(file.parent); - spaces.forEach(space => + spaces.forEach(space => { if (contextsCache.has(spaceContextPathFromName(space))) { contexts.push(spaceContextPathFromName(space)); @@ -132,12 +132,12 @@ export const parseMetadata = (file: AFile, settings: MakeMDPluginSettings, conte } const tags : string[] = []; const fileTags : string[] = tagsForCachedMetadata(metadataCache); - + if (contextsCache.has(file.parent)) { for (const def of contextsCache.get(file.parent).def) { if (def.type == 'tag') { tags.push(def.value); - } + } } } @@ -169,7 +169,7 @@ export const parseMetadata = (file: AFile, settings: MakeMDPluginSettings, conte } let banner = ''; if (fm) { - + const fmKeys = uniqCaseInsensitive(frontMatterKeys(fm)); const cols: Record = fmKeys.reduce((p, c) => ({ ...p, [c]: { @@ -192,6 +192,7 @@ export const parseMetadata = (file: AFile, settings: MakeMDPluginSettings, conte } if (properties[settings.fmKeyAlias] && settings.spacesUseAlias) { name = fm[settings.fmKeyAlias]; + if (Array.isArray(name)) name = name[0]; } } const fileCache = { @@ -239,8 +240,8 @@ export const parseMetadata = (file: AFile, settings: MakeMDPluginSettings, conte let changed = true; if (oldMetadata && _.isEqual(metadata, oldMetadata)) { - + changed = false; } return {changed, cache: metadata } -} \ No newline at end of file +} diff --git a/src/utils/contexts/mdb.ts b/src/utils/contexts/mdb.ts index 6998ae9..20cacbe 100644 --- a/src/utils/contexts/mdb.ts +++ b/src/utils/contexts/mdb.ts @@ -368,7 +368,7 @@ export const connectContext = async ( tag: string, source: string ) => { - + }; export const disconnectContext = async ( @@ -376,7 +376,7 @@ export const disconnectContext = async ( tag: string, source: string ) => { - + }; export const renameSpaceContextFile = async ( @@ -394,7 +394,7 @@ export const renameSpaceContextFile = async ( "/" + newSpaceDBPath ) ) { - await renameFile(plugin, + await renameFile(plugin, getAbstractFileAtPath(app, context.dbPath), newSpaceDBPath ); @@ -413,7 +413,7 @@ export const renameSpaceContextFile = async ( }); } }, app.workspace["rootSplit"]!); - + }; @@ -434,7 +434,7 @@ export const renameTagContextFile = async ( ".mdb" ) ) { - await renameFile(plugin, + await renameFile(plugin, getAbstractFileAtPath(app, context.dbPath), tagToTagPath(newTag) + ".mdb" ); @@ -454,5 +454,5 @@ export const renameTagContextFile = async ( }); } }, app.workspace["rootSplit"]!); - + }; diff --git a/src/utils/metadata/dv.ts b/src/utils/metadata/dv.ts index 302a356..6c918e7 100644 --- a/src/utils/metadata/dv.ts +++ b/src/utils/metadata/dv.ts @@ -117,6 +117,7 @@ export async function replaceValues( input: string, previousItemsCount: number = 0 ): Promise { + let file: TFile; if (fileOrFilePath instanceof TFile) { file = fileOrFilePath; @@ -139,6 +140,7 @@ export async function replaceValues( } = frontmatter ? frontmatter : { position: { start: undefined, end: undefined } }; + const newContent = content.map((line, i) => { const encodedInput = encodeLink(input); let encodedLine = encodeLink(line); diff --git a/src/utils/metadata/frontmatter/parseFrontMatter.ts b/src/utils/metadata/frontmatter/parseFrontMatter.ts index c1909cd..6aa8229 100644 --- a/src/utils/metadata/frontmatter/parseFrontMatter.ts +++ b/src/utils/metadata/frontmatter/parseFrontMatter.ts @@ -1,9 +1,10 @@ -import { serializeMultiDisplayString, serializeMultiString } from "utils/serializer"; +import { MULTI_STRING_DELIMITER, serializeMultiDisplayString, serializeMultiString } from "utils/serializer"; import { detectYAMLType } from "./detectYAMLType"; export const parseFrontMatter = (field: string, value: any) => { - const YAMLtype = detectYAMLType(value, field); + // We need to always treat Aliases as an option-multi field, even if it's a string. + const YAMLtype = field === 'aliases' ? 'option-multi' : detectYAMLType(value, field); switch (YAMLtype) { case "object": return JSON.stringify(value); @@ -30,7 +31,7 @@ export const parseFrontMatter = (field: string, value: any) => { case "option-multi": case "link-multi": if (typeof value === "string") { - return value; + return value.split(',').join(MULTI_STRING_DELIMITER); } return serializeMultiString(value .map((v: any) => { diff --git a/src/utils/parser.tsx b/src/utils/parser.tsx index 066018b..834fcf3 100644 --- a/src/utils/parser.tsx +++ b/src/utils/parser.tsx @@ -4,6 +4,7 @@ import { DBRow } from "types/mdb"; import { SpaceDef } from "types/space"; import { safelyParseJSON } from "./json"; import { filePathToString, indexOfCharElseEOS } from "./strings"; +import { MULTI_STRING_DELIMITER } from "./serializer"; //named parsers for converting strings to values @@ -13,7 +14,7 @@ export const parseSortStrat = (str: string): [string, boolean] => { }; export const parseMultiString = (str: string): string[] => - str?.match(/(\\.|[^,])+/g) ?? []; + str?.match(new RegExp(`(\\.|[^${MULTI_STRING_DELIMITER}])+`, 'g')) ?? []; export const parseLinkString = (string: string) => { if (!string) return ""; diff --git a/src/utils/serializer.ts b/src/utils/serializer.ts index 85dee7f..6801b81 100644 --- a/src/utils/serializer.ts +++ b/src/utils/serializer.ts @@ -2,14 +2,19 @@ import { Space } from "schemas/spaces"; import { ContextDef } from "types/context"; import { DBRow } from "types/mdb"; +// Joining multi-strings with commas causes issues when there's a comma in the key. +// This can happen if the value is specified as a YAML array. +// This is common with aliases, as they might include commas. +export const MULTI_STRING_DELIMITER = '🚲🐭'; + //named serializers for converting values to string export const serializeDefString = (def: ContextDef[]) => JSON.stringify(def); export const serializeSpace = (space: Space) : DBRow => ({...space, def: JSON.stringify(space.def)}); -export const serializeMultiString = (value: string[]) => value.join(','); -export const serializeMultiDisplayString = (value: string[]) => value.join(', '); +export const serializeMultiString = (value: string[]) => value.join(MULTI_STRING_DELIMITER); +export const serializeMultiDisplayString = (value: string[]) => value.join(MULTI_STRING_DELIMITER); export const serializeSQLValues = (value: string[]) => value.join(', '); export const serializeSQLStatements = (value: string[]) => value.join('; '); -export const serializeSQLFieldNames = (value: string[]) => value.join(','); \ No newline at end of file +export const serializeSQLFieldNames = (value: string[]) => value.join(',');