diff --git a/CHANGELOG.md b/CHANGELOG.md index eb6ab32e..12454144 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,16 @@ # Obsidian Meta Bind Changelog +# 1.4.11 + +Bug Fixes + +- Fixed button templates loading invalid buttons in some cases [#664](https://github.com/mProjectsCode/obsidian-meta-bind-plugin/issues/664) + +Misc + +- Redid monorepo setup +- Fix more Obsidian review warnings + # 1.4.10 Misc diff --git a/bun.lock b/bun.lock index ba9a17f2..92415af3 100644 --- a/bun.lock +++ b/bun.lock @@ -55,7 +55,7 @@ "@types/codemirror": "^5.60.17", "itertools-ts": "^2.5.0", "meta-bind-core": "workspace:*", - "obsidian": "latest", + "obsidian": "obsidianmd/obsidian-api#cf9ef454f6e0fa0f1f275b3e51991dfc557cc7be", "svelte": "^5.55.5", "zod": "^4.3.6", }, @@ -151,41 +151,41 @@ "@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@0.2.12", "", { "dependencies": { "@emnapi/core": "^1.4.3", "@emnapi/runtime": "^1.4.3", "@tybys/wasm-util": "^0.10.0" } }, "sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ=="], - "@oxc-project/types": ["@oxc-project/types@0.129.0", "", {}, "sha512-3oz8m3FGdr2nDXVqmFUw7jolKliC4MoyXYIG2c7gpjBnzUWQpUGIYcXYKxTdTi+N2jusvt610ckTMkxdwHkYEg=="], + "@oxc-project/types": ["@oxc-project/types@0.132.0", "", {}, "sha512-FESMOxil5Se014ui/Eq8fT5uHJo6nIRwH0PfJrZJXs6Gek3ZVFOrpUv3YIZT20m+extU98Hg1Ym72U58rlsxUQ=="], "@package-json/types": ["@package-json/types@0.0.12", "", {}, "sha512-uu43FGU34B5VM9mCNjXCwLaGHYjXdNincqKLaraaCW+7S2+SmiBg1Nv8bPnmschrIfZmfKNY9f3fC376MRrObw=="], "@pkgr/core": ["@pkgr/core@0.1.2", "", {}, "sha512-fdDH1LSGfZdTH2sxdpVMw31BanV28K/Gry0cVFxaNP77neJSkd82mM8ErPNYs9e+0O7SdHBLTDzDgwUuy18RnQ=="], - "@rolldown/binding-android-arm64": ["@rolldown/binding-android-arm64@1.0.0", "", { "os": "android", "cpu": "arm64" }, "sha512-TWMZnRLMe63C2Lhyicviu7ZHaU4kxa6PS3rofvc9GmcvptzNN11BcfQ4Sl7MwTOsisQoa2keB/EBdNCAnUo8vA=="], + "@rolldown/binding-android-arm64": ["@rolldown/binding-android-arm64@1.0.2", "", { "os": "android", "cpu": "arm64" }, "sha512-ZS4D1JPGn/MYQN/SYDWftIE/nVsM8j/AFOYEzAoOE2O3NktQOZru+/vYXGbR/qtdLdIfGCP0lcoJiYVzsEz+iQ=="], - "@rolldown/binding-darwin-arm64": ["@rolldown/binding-darwin-arm64@1.0.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-6XcD+8k0gPVItNagEw78/qqcBDwKcwDYS8V2hRmVsfUSIrd8cWe/CBvRDI5toqFyPfj+FJr6t8U6Xj2P2prEew=="], + "@rolldown/binding-darwin-arm64": ["@rolldown/binding-darwin-arm64@1.0.2", "", { "os": "darwin", "cpu": "arm64" }, "sha512-vdFA9+C/rekyGce7WqHs/xoT0ioZEWaOFyZLIV1mEeNFaFDUQrPIo8Vs2GvJ6eetb3rzDUtUBgzto3ExpXJB3w=="], - "@rolldown/binding-darwin-x64": ["@rolldown/binding-darwin-x64@1.0.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-iN/tWVXRQDWvmZlKdceP1Dwug9GDpEymhb9p4xnEe6zvCg5lFmzVljl+1qR1NVx3yfGpr2Na+CuLmv5IU8uzfQ=="], + "@rolldown/binding-darwin-x64": ["@rolldown/binding-darwin-x64@1.0.2", "", { "os": "darwin", "cpu": "x64" }, "sha512-BewSOwTHazv77DTYiAZXSqqKZ4KP/KonFisDMVU7PImxoWfB2aepnPhd2E4SWz3zDzYgDNbs6jBmTdgNnF02GA=="], - "@rolldown/binding-freebsd-x64": ["@rolldown/binding-freebsd-x64@1.0.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-jjQMDvvwSOuhOwMszD/klSOjyWMM3zI64hWTj9KT5x4MxRbZAf+7vLQ6qouRhtsLVFHr3f0ILaJAfgENPiQdAQ=="], + "@rolldown/binding-freebsd-x64": ["@rolldown/binding-freebsd-x64@1.0.2", "", { "os": "freebsd", "cpu": "x64" }, "sha512-m41o7M0YWtUdqk61Tb+jnKb2rN++iRdIASlExkUoKfIAH30DOHCB8fVLzSUpbWHHU8esmEioY62PxzexE8MBuA=="], - "@rolldown/binding-linux-arm-gnueabihf": ["@rolldown/binding-linux-arm-gnueabihf@1.0.0", "", { "os": "linux", "cpu": "arm" }, "sha512-d//Dtg2x6/m3mbV64yUGNnDGNZaDGRpDLLNGerHQUVObuNaIQaaDp25yUiqGXtHEXX+NP2d0wAlmKgpYgIAJ2A=="], + "@rolldown/binding-linux-arm-gnueabihf": ["@rolldown/binding-linux-arm-gnueabihf@1.0.2", "", { "os": "linux", "cpu": "arm" }, "sha512-jcojB9H7W/jS29pMKWAK1N+fU99vXodHDTatS3b3y/XSOCiHo0kkA74pL3jJmkoQtYpOCxDvaKs1fo2Ij/1X5w=="], - "@rolldown/binding-linux-arm64-gnu": ["@rolldown/binding-linux-arm64-gnu@1.0.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-n7Ofp0mx+aB2cC+Sdy5YtMnXtY9lchnHbY+3Yt0uq9JsWQExf4f5Whu0tK0R8Jdc9S6RchTHjIFY7uc92puOVQ=="], + "@rolldown/binding-linux-arm64-gnu": ["@rolldown/binding-linux-arm64-gnu@1.0.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-1jn6qDU5iiOgFgygDzKUuKP0maTi0/f1+sBLgvij/76C77Nm3ts6ufz9Bjg5q5dduxiUIxtq86JIoBvo1xQ4Ig=="], - "@rolldown/binding-linux-arm64-musl": ["@rolldown/binding-linux-arm64-musl@1.0.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-EIVjy2cgd7uuMMo94FVkBp7F6DhcZAUwNURkSG3RwUmvAXR6s0ISxM81U+IydcZByPG0pZIHsf1b6kTxoFDgJA=="], + "@rolldown/binding-linux-arm64-musl": ["@rolldown/binding-linux-arm64-musl@1.0.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-QVLO/czFMdoMFSqlX3bcswcJNm/23r+qoa/jgtmFc/qEp6/jXmIkDjF/XIo8dPfGaiwy1xfQn8o77L79GeXFgw=="], - "@rolldown/binding-linux-ppc64-gnu": ["@rolldown/binding-linux-ppc64-gnu@1.0.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-JEwwOPcwTLAcpDQlqSmjEmfs63xJnSiUNIGvLcDLUHCWK4XowpS/7c7tUsUH6uT/ct6bMUTdXKfI8967FYj6mg=="], + "@rolldown/binding-linux-ppc64-gnu": ["@rolldown/binding-linux-ppc64-gnu@1.0.2", "", { "os": "linux", "cpu": "ppc64" }, "sha512-hgO5Abm0w5UL6FEa2iFnZqo2KlK7TQ5QhV5x09hujBf7t5KzHQ1VmfPuTpqRy/rNlSxua3eWH374xxiVrP+lcA=="], - "@rolldown/binding-linux-s390x-gnu": ["@rolldown/binding-linux-s390x-gnu@1.0.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-0wjCFhLrihtAubnT9iA0N++0pSV0z5Hg7tNGdNJ4RFaINceHadoF+kiFGyY1qSSNVIAZtLotG8Ju1bgDPkjnFA=="], + "@rolldown/binding-linux-s390x-gnu": ["@rolldown/binding-linux-s390x-gnu@1.0.2", "", { "os": "linux", "cpu": "s390x" }, "sha512-fy8rXxuYEu602abC8MUNaPjYLIFzReOaEIEMKMUa0rFEUxNpVXhs15KSSQ4qlqSaM7B6rcj9rDZgADh/IGDzLQ=="], - "@rolldown/binding-linux-x64-gnu": ["@rolldown/binding-linux-x64-gnu@1.0.0", "", { "os": "linux", "cpu": "x64" }, "sha512-Dfn7iak9BcMMePxcoJfpSbWqnEyrp/dRF63/8qW/eHBdOZov6x5aShLLEYGYdIeSJ6vMLK/XCVB+lGIxm41bQA=="], + "@rolldown/binding-linux-x64-gnu": ["@rolldown/binding-linux-x64-gnu@1.0.2", "", { "os": "linux", "cpu": "x64" }, "sha512-0+bOkiQ779+r1WpoHOWHqncvyySci0vKph+myNDYb+im6meJAzHQXay6oEgnkHuUGouM1LKTZwqKpBow6Kj7CQ=="], - "@rolldown/binding-linux-x64-musl": ["@rolldown/binding-linux-x64-musl@1.0.0", "", { "os": "linux", "cpu": "x64" }, "sha512-5/utzzDmD/pD/bmuaUcbTf/sZYy0aztwIVlfpoW1fTjCZ0BaPOMVWGZL1zvgxyi7ZIVYWlxKONHmSbHuiOh8Jw=="], + "@rolldown/binding-linux-x64-musl": ["@rolldown/binding-linux-x64-musl@1.0.2", "", { "os": "linux", "cpu": "x64" }, "sha512-mjSkrzZK5Qsl0a9d1JgILOiuZOSDTVdKENcSXBoqbzSrspLR/4/IRVDo5wd2GgZjNss/viBFJdeq+j7qH2nypw=="], - "@rolldown/binding-openharmony-arm64": ["@rolldown/binding-openharmony-arm64@1.0.0", "", { "os": "none", "cpu": "arm64" }, "sha512-ouJs8VcUomfLfpbUECqFMRqdV4x6aeAK3MA4m6vTrJJjKyWTV5KnxZx7Jd9G+GlDaQQxubcba00x16OyJ1meig=="], + "@rolldown/binding-openharmony-arm64": ["@rolldown/binding-openharmony-arm64@1.0.2", "", { "os": "none", "cpu": "arm64" }, "sha512-1v5vHasdfQAZoEHakBV72LIFAC9JjnymsiKxp+GEr/ma3+NJCPSaYK+qavInOovJkgwFrs7GccX2d6IgDA3Z5w=="], - "@rolldown/binding-wasm32-wasi": ["@rolldown/binding-wasm32-wasi@1.0.0", "", { "dependencies": { "@emnapi/core": "1.10.0", "@emnapi/runtime": "1.10.0", "@napi-rs/wasm-runtime": "^1.1.4" }, "cpu": "none" }, "sha512-E+oHKGiDA+lsKMmFtffDDw91EryDT7uJocrIuCHqhm6bCTM6xFK+3gaCkYOHfPwQr0cCNarSM2xaELoQDz9jJg=="], + "@rolldown/binding-wasm32-wasi": ["@rolldown/binding-wasm32-wasi@1.0.2", "", { "dependencies": { "@emnapi/core": "1.10.0", "@emnapi/runtime": "1.10.0", "@napi-rs/wasm-runtime": "^1.1.4" }, "cpu": "none" }, "sha512-mb1VobWn6NheziTk5/WEaR6AKVbrwT5sOi6C7zk3gy/pD1qtJfU1j4PgTo2NJnOtbL9Dl3Aeei8w9jJ7qC2jZQ=="], - "@rolldown/binding-win32-arm64-msvc": ["@rolldown/binding-win32-arm64-msvc@1.0.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-yYK02n8Rngo+gbm1y6G0+7jk1sJ/2Wt7K0me0Y7k/ErBpyf+LJ2gFpqWVTcRV1rUepBlQRmpgWkTQCiiwrK0Ow=="], + "@rolldown/binding-win32-arm64-msvc": ["@rolldown/binding-win32-arm64-msvc@1.0.2", "", { "os": "win32", "cpu": "arm64" }, "sha512-SqKonF56vA/L2yHwHYcEp2P34URpOZ7d1fS635cTkpDnUtEGdUbhI6NzsPdqeSWvAAeGDrxjWjNmibDIdFf9/A=="], - "@rolldown/binding-win32-x64-msvc": ["@rolldown/binding-win32-x64-msvc@1.0.0", "", { "os": "win32", "cpu": "x64" }, "sha512-14bpChMahXRRXiTwahSl+zzHPW6qQTXtkMuJBFlbo+pqSAews2d4BdCSHfrJ/MBsCZtpmTafsY+1QhBzitcmdg=="], + "@rolldown/binding-win32-x64-msvc": ["@rolldown/binding-win32-x64-msvc@1.0.2", "", { "os": "win32", "cpu": "x64" }, "sha512-v7qRI7gXLRINcOGXt+7YmAZ6iFuyZVMIoXAxhd8oP+DR9dLfL9GfNIx7PLMxmhZdvq8waUJBQiWN9EKNy+TRBQ=="], "@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.0", "", {}, "sha512-aKs/3GSWyV0mrhNmt/96/Z3yczC3yvrzYATCiCXQebBsGyYzjNdUphRVLeJQ67ySKVXRfMxt2lm12pmXvbPFQQ=="], @@ -221,25 +221,25 @@ "@types/ws": ["@types/ws@8.18.1", "", { "dependencies": { "@types/node": "*" } }, "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg=="], - "@typescript-eslint/eslint-plugin": ["@typescript-eslint/eslint-plugin@8.59.3", "", { "dependencies": { "@eslint-community/regexpp": "^4.12.2", "@typescript-eslint/scope-manager": "8.59.3", "@typescript-eslint/type-utils": "8.59.3", "@typescript-eslint/utils": "8.59.3", "@typescript-eslint/visitor-keys": "8.59.3", "ignore": "^7.0.5", "natural-compare": "^1.4.0", "ts-api-utils": "^2.5.0" }, "peerDependencies": { "@typescript-eslint/parser": "^8.59.3", "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.1.0" } }, "sha512-PwFvSKsXGShKGW6n5bZOhGHEcCZXM8HofLK9fNsEwZXzFRjoY+XT1Vsf1zgyXdwTr0ZYz1/2tkZ0DBTT9jZjhw=="], + "@typescript-eslint/eslint-plugin": ["@typescript-eslint/eslint-plugin@8.60.0", "", { "dependencies": { "@eslint-community/regexpp": "^4.12.2", "@typescript-eslint/scope-manager": "8.60.0", "@typescript-eslint/type-utils": "8.60.0", "@typescript-eslint/utils": "8.60.0", "@typescript-eslint/visitor-keys": "8.60.0", "ignore": "^7.0.5", "natural-compare": "^1.4.0", "ts-api-utils": "^2.5.0" }, "peerDependencies": { "@typescript-eslint/parser": "^8.60.0", "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.1.0" } }, "sha512-QYb/sa74/s7OKMbACMjrYnGspj9Hs5YI5aaffSL65UfeBUzVzBJfVo3oWSpbzPurvm7yaCCo2Lk7lVj610HqKw=="], - "@typescript-eslint/parser": ["@typescript-eslint/parser@8.59.3", "", { "dependencies": { "@typescript-eslint/scope-manager": "8.59.3", "@typescript-eslint/types": "8.59.3", "@typescript-eslint/typescript-estree": "8.59.3", "@typescript-eslint/visitor-keys": "8.59.3", "debug": "^4.4.3" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.1.0" } }, "sha512-HPwA+hVkfcriajbNvTmZv4VRauibay+cWArYUYq7u7W7PmGShMxbPxLvrwDme55a6d5alG3nrYfhyJ/G28XlLg=="], + "@typescript-eslint/parser": ["@typescript-eslint/parser@8.60.0", "", { "dependencies": { "@typescript-eslint/scope-manager": "8.60.0", "@typescript-eslint/types": "8.60.0", "@typescript-eslint/typescript-estree": "8.60.0", "@typescript-eslint/visitor-keys": "8.60.0", "debug": "^4.4.3" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.1.0" } }, "sha512-fcqpj/MyK4sxDPcbe7STNPbpQL4RLZOPWuaTmwZYuc+hJKzRf58yRxfhqGpc6PIq9ZyfSBpfHgmUHmHs0KwHwg=="], - "@typescript-eslint/project-service": ["@typescript-eslint/project-service@8.59.3", "", { "dependencies": { "@typescript-eslint/tsconfig-utils": "^8.59.3", "@typescript-eslint/types": "^8.59.3", "debug": "^4.4.3" }, "peerDependencies": { "typescript": ">=4.8.4 <6.1.0" } }, "sha512-ECiUWa/KYRGDFUqTNehaRgzDshnJfkTABJxVemHk4ko22gcr0ukloKjWvyQ64g8YCV/UI47kN1dbmjf/GaQYng=="], + "@typescript-eslint/project-service": ["@typescript-eslint/project-service@8.60.0", "", { "dependencies": { "@typescript-eslint/tsconfig-utils": "^8.60.0", "@typescript-eslint/types": "^8.60.0", "debug": "^4.4.3" }, "peerDependencies": { "typescript": ">=4.8.4 <6.1.0" } }, "sha512-aZu74NNKJeUWqCjDddzdiKaS82dgYgV/vmf+Ui3ZdZejmgfXR/q+pRumgobnQ2cCJTgGTWp4ypiwsuofFubavg=="], "@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@8.59.3", "", { "dependencies": { "@typescript-eslint/types": "8.59.3", "@typescript-eslint/visitor-keys": "8.59.3" } }, "sha512-t2LvZnoEfzKtnPjgeEu41xw5gxq9mQVfYy4OoZ4Vlt0sk3JwxmhCca/AR7DwOiHrjWgjAj6as4AhRLKSDfvZIA=="], - "@typescript-eslint/tsconfig-utils": ["@typescript-eslint/tsconfig-utils@8.59.3", "", { "peerDependencies": { "typescript": ">=4.8.4 <6.1.0" } }, "sha512-PcIJHjmaREXLgIAIzLnSY9VucEzz8FKXsRgFa1DmdGCK/5tJpW03TKJF01Q6VZd1lLdz2sIKPWaDUZN9dp//dw=="], + "@typescript-eslint/tsconfig-utils": ["@typescript-eslint/tsconfig-utils@8.60.0", "", { "peerDependencies": { "typescript": ">=4.8.4 <6.1.0" } }, "sha512-BZPR3RGYlAXnly6ymAxfkVn5rCbZzQNou0rxv3GfWZ8cTQp+hhVd73khbGLAd8k1TlAPLISH337M+tAgAnaJDQ=="], "@typescript-eslint/type-utils": ["@typescript-eslint/type-utils@8.59.3", "", { "dependencies": { "@typescript-eslint/types": "8.59.3", "@typescript-eslint/typescript-estree": "8.59.3", "@typescript-eslint/utils": "8.59.3", "debug": "^4.4.3", "ts-api-utils": "^2.5.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.1.0" } }, "sha512-g71d8QD8UaiHGvrJwyIS1hCX5r63w6Jll+4VEYhEAHXTDIqX1JgxhTAbEHtKntL9kuc4jRo7/GWw5xfCepSccQ=="], "@typescript-eslint/types": ["@typescript-eslint/types@8.59.3", "", {}, "sha512-ePFoH0g4ludssdRFqqDxQePCxU4WQyRa9+XVwjm7yLn0FKhMeoetC+qBEEI1Eyb1pGSDveTIT09Bvw2WhlGayg=="], - "@typescript-eslint/typescript-estree": ["@typescript-eslint/typescript-estree@8.59.3", "", { "dependencies": { "@typescript-eslint/project-service": "8.59.3", "@typescript-eslint/tsconfig-utils": "8.59.3", "@typescript-eslint/types": "8.59.3", "@typescript-eslint/visitor-keys": "8.59.3", "debug": "^4.4.3", "minimatch": "^10.2.2", "semver": "^7.7.3", "tinyglobby": "^0.2.15", "ts-api-utils": "^2.5.0" }, "peerDependencies": { "typescript": ">=4.8.4 <6.1.0" } }, "sha512-CbRjVRAf7Lr9Kr8RopKcbY45p2VfmmHrm0ygOCYFi7oU8q19m0Fs/6iHS7kNOmwpp+ob07ZVcAqlxUod9lYdmg=="], + "@typescript-eslint/typescript-estree": ["@typescript-eslint/typescript-estree@8.60.0", "", { "dependencies": { "@typescript-eslint/project-service": "8.60.0", "@typescript-eslint/tsconfig-utils": "8.60.0", "@typescript-eslint/types": "8.60.0", "@typescript-eslint/visitor-keys": "8.60.0", "debug": "^4.4.3", "minimatch": "^10.2.2", "semver": "^7.7.3", "tinyglobby": "^0.2.15", "ts-api-utils": "^2.5.0" }, "peerDependencies": { "typescript": ">=4.8.4 <6.1.0" } }, "sha512-3AcZNBGMClm6CXDyo8kYvVGT/sx29sS0oBsIb9oZI2gunA4Vm2M3YHzRLPvsUBBsl+yB5FPtltq7gGH0iTlp9g=="], "@typescript-eslint/utils": ["@typescript-eslint/utils@8.59.3", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", "@typescript-eslint/scope-manager": "8.59.3", "@typescript-eslint/types": "8.59.3", "@typescript-eslint/typescript-estree": "8.59.3" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.1.0" } }, "sha512-JAvT14goBzRzzzZyqq3P9BLArIxTtQURUtFgQ/V7FO+eU+Gg6ES+5ymOPP1wRxXcxAYeivCk4uS3jCKWI1K8Zg=="], - "@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.59.3", "", { "dependencies": { "@typescript-eslint/types": "8.59.3", "eslint-visitor-keys": "^5.0.0" } }, "sha512-f1UQF7ggd42YiwI5wGrRaPsa+P0CINBlrkLPmGfpq/u/I/oVtecoEIfFR9ag/oa1sLOsRNZ6xehf6qMZhQGBDg=="], + "@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.60.0", "", { "dependencies": { "@typescript-eslint/types": "8.60.0", "eslint-visitor-keys": "^5.0.0" } }, "sha512-9WI52t8ZGLVGrPMBet25yAftqY/n95+zmoUUtJBBQTKDSKUu7OsPTroT2op7U9JatkoRccL0YkWDNMFfC4Sjxg=="], "@unrs/resolver-binding-android-arm-eabi": ["@unrs/resolver-binding-android-arm-eabi@1.11.1", "", { "os": "android", "cpu": "arm" }, "sha512-ppLRUgHVaGRWUx0R0Ut06Mjo9gBaBkg3v/8AxusGLhsIotbBLuRk51rAzqLC8gq6NyyAojEXglNjzf6R948DNw=="], @@ -711,7 +711,7 @@ "object.values": ["object.values@1.2.1", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.3", "define-properties": "^1.2.1", "es-object-atoms": "^1.0.0" } }, "sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA=="], - "obsidian": ["obsidian@1.12.3", "", { "dependencies": { "@types/codemirror": "5.60.8", "moment": "2.29.4" }, "peerDependencies": { "@codemirror/state": "6.5.0", "@codemirror/view": "6.38.6" } }, "sha512-HxWqe763dOqzXjnNiHmAJTRERN8KILBSqxDSEqbeSr7W8R8Jxezzbca+nz1LiiqXnMpM8lV2jzAezw3CZ4xNUw=="], + "obsidian": ["obsidian@github:obsidianmd/obsidian-api#cf9ef45", { "dependencies": { "@types/codemirror": "5.60.8", "moment": "2.29.4" }, "peerDependencies": { "@codemirror/state": "6.5.0", "@codemirror/view": "6.38.6" } }, "obsidianmd-obsidian-api-cf9ef45", "sha512-KICjKpgtcP6ymaFcAtoeLj1S1NAo8pta6wQscshPnxemJxya4toRm7AHZtCC0HNvFqD1eSI6fo8m6894EJM51w=="], "obug": ["obug@2.1.1", "", {}, "sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ=="], @@ -779,7 +779,7 @@ "ret": ["ret@0.1.15", "", {}, "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg=="], - "rolldown": ["rolldown@1.0.0", "", { "dependencies": { "@oxc-project/types": "=0.129.0", "@rolldown/pluginutils": "1.0.0" }, "optionalDependencies": { "@rolldown/binding-android-arm64": "1.0.0", "@rolldown/binding-darwin-arm64": "1.0.0", "@rolldown/binding-darwin-x64": "1.0.0", "@rolldown/binding-freebsd-x64": "1.0.0", "@rolldown/binding-linux-arm-gnueabihf": "1.0.0", "@rolldown/binding-linux-arm64-gnu": "1.0.0", "@rolldown/binding-linux-arm64-musl": "1.0.0", "@rolldown/binding-linux-ppc64-gnu": "1.0.0", "@rolldown/binding-linux-s390x-gnu": "1.0.0", "@rolldown/binding-linux-x64-gnu": "1.0.0", "@rolldown/binding-linux-x64-musl": "1.0.0", "@rolldown/binding-openharmony-arm64": "1.0.0", "@rolldown/binding-wasm32-wasi": "1.0.0", "@rolldown/binding-win32-arm64-msvc": "1.0.0", "@rolldown/binding-win32-x64-msvc": "1.0.0" }, "bin": { "rolldown": "bin/cli.mjs" } }, "sha512-yD986aXDESFGS95spT1LAv0jssywP4npMEjmMHyN2/5+eE8qQJUype2AaKkRiLgBgyD0LFlubwAht7VmY8rGoA=="], + "rolldown": ["rolldown@1.0.2", "", { "dependencies": { "@oxc-project/types": "=0.132.0", "@rolldown/pluginutils": "^1.0.0" }, "optionalDependencies": { "@rolldown/binding-android-arm64": "1.0.2", "@rolldown/binding-darwin-arm64": "1.0.2", "@rolldown/binding-darwin-x64": "1.0.2", "@rolldown/binding-freebsd-x64": "1.0.2", "@rolldown/binding-linux-arm-gnueabihf": "1.0.2", "@rolldown/binding-linux-arm64-gnu": "1.0.2", "@rolldown/binding-linux-arm64-musl": "1.0.2", "@rolldown/binding-linux-ppc64-gnu": "1.0.2", "@rolldown/binding-linux-s390x-gnu": "1.0.2", "@rolldown/binding-linux-x64-gnu": "1.0.2", "@rolldown/binding-linux-x64-musl": "1.0.2", "@rolldown/binding-openharmony-arm64": "1.0.2", "@rolldown/binding-wasm32-wasi": "1.0.2", "@rolldown/binding-win32-arm64-msvc": "1.0.2", "@rolldown/binding-win32-x64-msvc": "1.0.2" }, "bin": { "rolldown": "./bin/cli.mjs" } }, "sha512-oZx5zVDtVB44AW3eaifgDml1gWRDZGvjcfdxonE4swNPG98PrrXjaO/KrnUjzlMnztCCRVlUueA1kCXhARGk6g=="], "sade": ["sade@1.8.1", "", { "dependencies": { "mri": "^1.1.0" } }, "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A=="], @@ -883,7 +883,7 @@ "typescript": ["typescript@6.0.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw=="], - "typescript-eslint": ["typescript-eslint@8.59.3", "", { "dependencies": { "@typescript-eslint/eslint-plugin": "8.59.3", "@typescript-eslint/parser": "8.59.3", "@typescript-eslint/typescript-estree": "8.59.3", "@typescript-eslint/utils": "8.59.3" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.1.0" } }, "sha512-KgusgyDgG4LI8Ih/sWaCtZ06tckLAS5CvT5A4D1Q7bYVoAAyzwiZvE4BmwDHkhRVkvhRBepKeASoFzQetha7Fg=="], + "typescript-eslint": ["typescript-eslint@8.60.0", "", { "dependencies": { "@typescript-eslint/eslint-plugin": "8.60.0", "@typescript-eslint/parser": "8.60.0", "@typescript-eslint/typescript-estree": "8.60.0", "@typescript-eslint/utils": "8.60.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.1.0" } }, "sha512-9f65qWLZdAW9m1JaxBDUHcqRUfL8bkxxXL7XxEfI+F09q56PkBvIfCjLF3yInsDM/BBmwkqmCQdCZe/RYlIWEw=="], "unbox-primitive": ["unbox-primitive@1.1.0", "", { "dependencies": { "call-bound": "^1.0.3", "has-bigints": "^1.0.2", "has-symbols": "^1.1.0", "which-boxed-primitive": "^1.1.1" } }, "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw=="], @@ -895,7 +895,7 @@ "util-deprecate": ["util-deprecate@1.0.2", "", {}, "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="], - "vite": ["vite@8.0.12", "", { "dependencies": { "lightningcss": "^1.32.0", "picomatch": "^4.0.4", "postcss": "^8.5.14", "rolldown": "1.0.0", "tinyglobby": "^0.2.16" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "@vitejs/devtools": "^0.1.18", "esbuild": "^0.27.0 || ^0.28.0", "jiti": ">=1.21.0", "less": "^4.0.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "@vitejs/devtools", "esbuild", "jiti", "less", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-w2dDofOWv2QB09ZITZBsvKTVAlYvPR4IAmrY/v0ir9KvLs0xybR7i48wxhM1/oyBWO34wPns+bPGw5ZrZqDpZg=="], + "vite": ["vite@8.0.14", "", { "dependencies": { "lightningcss": "^1.32.0", "picomatch": "^4.0.4", "postcss": "^8.5.15", "rolldown": "1.0.2", "tinyglobby": "^0.2.16" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "@vitejs/devtools": "^0.1.18", "esbuild": "^0.27.0 || ^0.28.0", "jiti": ">=1.21.0", "less": "^4.0.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "@vitejs/devtools", "esbuild", "jiti", "less", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-s4BJJ+5y1pYL6Otw51FHhVJQhPnuRinKig64g/1+EUNaJsd3gCKdD31IPFvswUgW9/60QT9oFHbZHbQK5imcxw=="], "vite-plugin-banner": ["vite-plugin-banner@0.8.1", "", {}, "sha512-0+gGguHk3MH0HvzMSOCJC6fGgH4+jtY9KlKVZh+hwwE+PBkGVzY8xe657JL74vEgbeUJD37XjVqTrmve8XvZBQ=="], @@ -937,10 +937,32 @@ "@rolldown/binding-wasm32-wasi/@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.1.4", "", { "dependencies": { "@tybys/wasm-util": "^0.10.1" }, "peerDependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1" } }, "sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow=="], + "@typescript-eslint/eslint-plugin/@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@8.60.0", "", { "dependencies": { "@typescript-eslint/types": "8.60.0", "@typescript-eslint/visitor-keys": "8.60.0" } }, "sha512-pFzqhllJMs+jghLQWzV00ds39xLzuyqPSev5pd8f4Ir0rtKR3ZLUB4/4dhjOFighWb9larvtfJvqL+4yKDI3Xw=="], + + "@typescript-eslint/eslint-plugin/@typescript-eslint/type-utils": ["@typescript-eslint/type-utils@8.60.0", "", { "dependencies": { "@typescript-eslint/types": "8.60.0", "@typescript-eslint/typescript-estree": "8.60.0", "@typescript-eslint/utils": "8.60.0", "debug": "^4.4.3", "ts-api-utils": "^2.5.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.1.0" } }, "sha512-SX46wEUtitCpq7AN38HkUU/+zvUpdKf7ephtWAFgckH8O7PQIyL5gvrhQgBLuEYgLfuKWOVvWVskMbuFHAz5xg=="], + + "@typescript-eslint/eslint-plugin/@typescript-eslint/utils": ["@typescript-eslint/utils@8.60.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", "@typescript-eslint/scope-manager": "8.60.0", "@typescript-eslint/types": "8.60.0", "@typescript-eslint/typescript-estree": "8.60.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.1.0" } }, "sha512-HtXuPfrHTyBDkameWpl+vJb1Uevu2tznAyahM1Oc4AENidCLTPiZDWIo4GfcxNdC/RcfGcadzzkqbRG87dUrQA=="], + "@typescript-eslint/eslint-plugin/ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="], + "@typescript-eslint/parser/@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@8.60.0", "", { "dependencies": { "@typescript-eslint/types": "8.60.0", "@typescript-eslint/visitor-keys": "8.60.0" } }, "sha512-pFzqhllJMs+jghLQWzV00ds39xLzuyqPSev5pd8f4Ir0rtKR3ZLUB4/4dhjOFighWb9larvtfJvqL+4yKDI3Xw=="], + + "@typescript-eslint/parser/@typescript-eslint/types": ["@typescript-eslint/types@8.60.0", "", {}, "sha512-AsE7x2XaAK+CVbeih0Fvbn+r1qHxtpLDJ3XUuFcIinT318T90yHMJC+Zgv+jUuDjQQd06HKwxnDu6sz1IcTilA=="], + + "@typescript-eslint/project-service/@typescript-eslint/types": ["@typescript-eslint/types@8.60.0", "", {}, "sha512-AsE7x2XaAK+CVbeih0Fvbn+r1qHxtpLDJ3XUuFcIinT318T90yHMJC+Zgv+jUuDjQQd06HKwxnDu6sz1IcTilA=="], + + "@typescript-eslint/scope-manager/@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.59.3", "", { "dependencies": { "@typescript-eslint/types": "8.59.3", "eslint-visitor-keys": "^5.0.0" } }, "sha512-f1UQF7ggd42YiwI5wGrRaPsa+P0CINBlrkLPmGfpq/u/I/oVtecoEIfFR9ag/oa1sLOsRNZ6xehf6qMZhQGBDg=="], + + "@typescript-eslint/type-utils/@typescript-eslint/typescript-estree": ["@typescript-eslint/typescript-estree@8.59.3", "", { "dependencies": { "@typescript-eslint/project-service": "8.59.3", "@typescript-eslint/tsconfig-utils": "8.59.3", "@typescript-eslint/types": "8.59.3", "@typescript-eslint/visitor-keys": "8.59.3", "debug": "^4.4.3", "minimatch": "^10.2.2", "semver": "^7.7.3", "tinyglobby": "^0.2.15", "ts-api-utils": "^2.5.0" }, "peerDependencies": { "typescript": ">=4.8.4 <6.1.0" } }, "sha512-CbRjVRAf7Lr9Kr8RopKcbY45p2VfmmHrm0ygOCYFi7oU8q19m0Fs/6iHS7kNOmwpp+ob07ZVcAqlxUod9lYdmg=="], + + "@typescript-eslint/typescript-estree/@typescript-eslint/types": ["@typescript-eslint/types@8.60.0", "", {}, "sha512-AsE7x2XaAK+CVbeih0Fvbn+r1qHxtpLDJ3XUuFcIinT318T90yHMJC+Zgv+jUuDjQQd06HKwxnDu6sz1IcTilA=="], + "@typescript-eslint/typescript-estree/minimatch": ["minimatch@10.2.5", "", { "dependencies": { "brace-expansion": "^5.0.5" } }, "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg=="], + "@typescript-eslint/utils/@typescript-eslint/typescript-estree": ["@typescript-eslint/typescript-estree@8.59.3", "", { "dependencies": { "@typescript-eslint/project-service": "8.59.3", "@typescript-eslint/tsconfig-utils": "8.59.3", "@typescript-eslint/types": "8.59.3", "@typescript-eslint/visitor-keys": "8.59.3", "debug": "^4.4.3", "minimatch": "^10.2.2", "semver": "^7.7.3", "tinyglobby": "^0.2.15", "ts-api-utils": "^2.5.0" }, "peerDependencies": { "typescript": ">=4.8.4 <6.1.0" } }, "sha512-CbRjVRAf7Lr9Kr8RopKcbY45p2VfmmHrm0ygOCYFi7oU8q19m0Fs/6iHS7kNOmwpp+ob07ZVcAqlxUod9lYdmg=="], + + "@typescript-eslint/visitor-keys/@typescript-eslint/types": ["@typescript-eslint/types@8.60.0", "", {}, "sha512-AsE7x2XaAK+CVbeih0Fvbn+r1qHxtpLDJ3XUuFcIinT318T90yHMJC+Zgv+jUuDjQQd06HKwxnDu6sz1IcTilA=="], + "@typescript-eslint/visitor-keys/eslint-visitor-keys": ["eslint-visitor-keys@5.0.1", "", {}, "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA=="], "anymatch/picomatch": ["picomatch@2.3.2", "", {}, "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA=="], @@ -955,6 +977,8 @@ "eslint-plugin-import-x/minimatch": ["minimatch@10.2.5", "", { "dependencies": { "brace-expansion": "^5.0.5" } }, "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg=="], + "eslint-plugin-isaacscript/typescript-eslint": ["typescript-eslint@8.59.3", "", { "dependencies": { "@typescript-eslint/eslint-plugin": "8.59.3", "@typescript-eslint/parser": "8.59.3", "@typescript-eslint/typescript-estree": "8.59.3", "@typescript-eslint/utils": "8.59.3" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.1.0" } }, "sha512-KgusgyDgG4LI8Ih/sWaCtZ06tckLAS5CvT5A4D1Q7bYVoAAyzwiZvE4BmwDHkhRVkvhRBepKeASoFzQetha7Fg=="], + "eslint-plugin-json-schema-validator/ajv": ["ajv@8.20.0", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA=="], "eslint-plugin-json-schema-validator/minimatch": ["minimatch@8.0.7", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-V+1uQNdzybxa14e/p00HZnQNNcTjnRJjDxg2V8wtkjFctq4M7hXFws4oekyTP0Jebeq7QYtpFyOeBAjc88zvYg=="], @@ -965,8 +989,12 @@ "eslint-plugin-obsidianmd/@types/node": ["@types/node@20.12.12", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-eWLDGF/FOSPtAvEqeRAQ4C8LSA7M1I7i0ky1I8U7kD1J5ITyW3AsRhQrKVoWf5pFKZ2kILsEGJhsI9r93PYnOw=="], + "eslint-plugin-obsidianmd/obsidian": ["obsidian@1.12.3", "", { "dependencies": { "@types/codemirror": "5.60.8", "moment": "2.29.4" }, "peerDependencies": { "@codemirror/state": "6.5.0", "@codemirror/view": "6.38.6" } }, "sha512-HxWqe763dOqzXjnNiHmAJTRERN8KILBSqxDSEqbeSr7W8R8Jxezzbca+nz1LiiqXnMpM8lV2jzAezw3CZ4xNUw=="], + "eslint-plugin-obsidianmd/typescript": ["typescript@5.4.5", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ=="], + "eslint-plugin-obsidianmd/typescript-eslint": ["typescript-eslint@8.59.3", "", { "dependencies": { "@typescript-eslint/eslint-plugin": "8.59.3", "@typescript-eslint/parser": "8.59.3", "@typescript-eslint/typescript-estree": "8.59.3", "@typescript-eslint/utils": "8.59.3" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.1.0" } }, "sha512-KgusgyDgG4LI8Ih/sWaCtZ06tckLAS5CvT5A4D1Q7bYVoAAyzwiZvE4BmwDHkhRVkvhRBepKeASoFzQetha7Fg=="], + "eslint-plugin-react/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], "eslint-plugin-svelte/globals": ["globals@16.5.0", "", {}, "sha512-c/c15i26VrJ4IRt5Z89DnIzCGDn9EcebibhAOjw5ibqEHsE1wLUgkPn9RDmNcUKyU87GeaL633nyJ+pplFR2ZQ=="], @@ -977,6 +1005,8 @@ "jsonc-eslint-parser/espree": ["espree@9.6.1", "", { "dependencies": { "acorn": "^8.9.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^3.4.1" } }, "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ=="], + "meta-bind-publish/obsidian": ["obsidian@1.12.3", "", { "dependencies": { "@types/codemirror": "5.60.8", "moment": "2.29.4" }, "peerDependencies": { "@codemirror/state": "6.5.0", "@codemirror/view": "6.38.6" } }, "sha512-HxWqe763dOqzXjnNiHmAJTRERN8KILBSqxDSEqbeSr7W8R8Jxezzbca+nz1LiiqXnMpM8lV2jzAezw3CZ4xNUw=="], + "node-exports-info/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], "obsidian/@types/codemirror": ["@types/codemirror@5.60.8", "", { "dependencies": { "@types/tern": "*" } }, "sha512-VjFgDF/eB+Aklcy15TtOTLQeMjTo07k7KAjql8OK5Dirr7a6sJY4T1uVBDuTVG9VEmn1uUsohOpYnVfgC6/jyw=="], @@ -987,16 +1017,50 @@ "toml-eslint-parser/eslint-visitor-keys": ["eslint-visitor-keys@3.4.3", "", {}, "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="], + "typescript-eslint/@typescript-eslint/utils": ["@typescript-eslint/utils@8.60.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", "@typescript-eslint/scope-manager": "8.60.0", "@typescript-eslint/types": "8.60.0", "@typescript-eslint/typescript-estree": "8.60.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.1.0" } }, "sha512-HtXuPfrHTyBDkameWpl+vJb1Uevu2tznAyahM1Oc4AENidCLTPiZDWIo4GfcxNdC/RcfGcadzzkqbRG87dUrQA=="], + + "vite/postcss": ["postcss@8.5.15", "", { "dependencies": { "nanoid": "^3.3.12", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A=="], + "vite-plugin-static-copy/chokidar": ["chokidar@3.6.0", "", { "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", "readdirp": "~3.6.0" }, "optionalDependencies": { "fsevents": "~2.3.2" } }, "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw=="], "yaml-eslint-parser/eslint-visitor-keys": ["eslint-visitor-keys@3.4.3", "", {}, "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="], "@microsoft/eslint-plugin-sdl/eslint-plugin-security/safe-regex": ["safe-regex@1.1.0", "", { "dependencies": { "ret": "~0.1.10" } }, "sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg=="], + "@typescript-eslint/eslint-plugin/@typescript-eslint/scope-manager/@typescript-eslint/types": ["@typescript-eslint/types@8.60.0", "", {}, "sha512-AsE7x2XaAK+CVbeih0Fvbn+r1qHxtpLDJ3XUuFcIinT318T90yHMJC+Zgv+jUuDjQQd06HKwxnDu6sz1IcTilA=="], + + "@typescript-eslint/eslint-plugin/@typescript-eslint/type-utils/@typescript-eslint/types": ["@typescript-eslint/types@8.60.0", "", {}, "sha512-AsE7x2XaAK+CVbeih0Fvbn+r1qHxtpLDJ3XUuFcIinT318T90yHMJC+Zgv+jUuDjQQd06HKwxnDu6sz1IcTilA=="], + + "@typescript-eslint/eslint-plugin/@typescript-eslint/utils/@typescript-eslint/types": ["@typescript-eslint/types@8.60.0", "", {}, "sha512-AsE7x2XaAK+CVbeih0Fvbn+r1qHxtpLDJ3XUuFcIinT318T90yHMJC+Zgv+jUuDjQQd06HKwxnDu6sz1IcTilA=="], + + "@typescript-eslint/scope-manager/@typescript-eslint/visitor-keys/eslint-visitor-keys": ["eslint-visitor-keys@5.0.1", "", {}, "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA=="], + + "@typescript-eslint/type-utils/@typescript-eslint/typescript-estree/@typescript-eslint/project-service": ["@typescript-eslint/project-service@8.59.3", "", { "dependencies": { "@typescript-eslint/tsconfig-utils": "^8.59.3", "@typescript-eslint/types": "^8.59.3", "debug": "^4.4.3" }, "peerDependencies": { "typescript": ">=4.8.4 <6.1.0" } }, "sha512-ECiUWa/KYRGDFUqTNehaRgzDshnJfkTABJxVemHk4ko22gcr0ukloKjWvyQ64g8YCV/UI47kN1dbmjf/GaQYng=="], + + "@typescript-eslint/type-utils/@typescript-eslint/typescript-estree/@typescript-eslint/tsconfig-utils": ["@typescript-eslint/tsconfig-utils@8.59.3", "", { "peerDependencies": { "typescript": ">=4.8.4 <6.1.0" } }, "sha512-PcIJHjmaREXLgIAIzLnSY9VucEzz8FKXsRgFa1DmdGCK/5tJpW03TKJF01Q6VZd1lLdz2sIKPWaDUZN9dp//dw=="], + + "@typescript-eslint/type-utils/@typescript-eslint/typescript-estree/@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.59.3", "", { "dependencies": { "@typescript-eslint/types": "8.59.3", "eslint-visitor-keys": "^5.0.0" } }, "sha512-f1UQF7ggd42YiwI5wGrRaPsa+P0CINBlrkLPmGfpq/u/I/oVtecoEIfFR9ag/oa1sLOsRNZ6xehf6qMZhQGBDg=="], + + "@typescript-eslint/type-utils/@typescript-eslint/typescript-estree/minimatch": ["minimatch@10.2.5", "", { "dependencies": { "brace-expansion": "^5.0.5" } }, "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg=="], + "@typescript-eslint/typescript-estree/minimatch/brace-expansion": ["brace-expansion@5.0.6", "", { "dependencies": { "balanced-match": "^4.0.2" } }, "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g=="], + "@typescript-eslint/utils/@typescript-eslint/typescript-estree/@typescript-eslint/project-service": ["@typescript-eslint/project-service@8.59.3", "", { "dependencies": { "@typescript-eslint/tsconfig-utils": "^8.59.3", "@typescript-eslint/types": "^8.59.3", "debug": "^4.4.3" }, "peerDependencies": { "typescript": ">=4.8.4 <6.1.0" } }, "sha512-ECiUWa/KYRGDFUqTNehaRgzDshnJfkTABJxVemHk4ko22gcr0ukloKjWvyQ64g8YCV/UI47kN1dbmjf/GaQYng=="], + + "@typescript-eslint/utils/@typescript-eslint/typescript-estree/@typescript-eslint/tsconfig-utils": ["@typescript-eslint/tsconfig-utils@8.59.3", "", { "peerDependencies": { "typescript": ">=4.8.4 <6.1.0" } }, "sha512-PcIJHjmaREXLgIAIzLnSY9VucEzz8FKXsRgFa1DmdGCK/5tJpW03TKJF01Q6VZd1lLdz2sIKPWaDUZN9dp//dw=="], + + "@typescript-eslint/utils/@typescript-eslint/typescript-estree/@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.59.3", "", { "dependencies": { "@typescript-eslint/types": "8.59.3", "eslint-visitor-keys": "^5.0.0" } }, "sha512-f1UQF7ggd42YiwI5wGrRaPsa+P0CINBlrkLPmGfpq/u/I/oVtecoEIfFR9ag/oa1sLOsRNZ6xehf6qMZhQGBDg=="], + + "@typescript-eslint/utils/@typescript-eslint/typescript-estree/minimatch": ["minimatch@10.2.5", "", { "dependencies": { "brace-expansion": "^5.0.5" } }, "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg=="], + "eslint-plugin-import-x/minimatch/brace-expansion": ["brace-expansion@5.0.6", "", { "dependencies": { "balanced-match": "^4.0.2" } }, "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g=="], + "eslint-plugin-isaacscript/typescript-eslint/@typescript-eslint/eslint-plugin": ["@typescript-eslint/eslint-plugin@8.59.3", "", { "dependencies": { "@eslint-community/regexpp": "^4.12.2", "@typescript-eslint/scope-manager": "8.59.3", "@typescript-eslint/type-utils": "8.59.3", "@typescript-eslint/utils": "8.59.3", "@typescript-eslint/visitor-keys": "8.59.3", "ignore": "^7.0.5", "natural-compare": "^1.4.0", "ts-api-utils": "^2.5.0" }, "peerDependencies": { "@typescript-eslint/parser": "^8.59.3", "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.1.0" } }, "sha512-PwFvSKsXGShKGW6n5bZOhGHEcCZXM8HofLK9fNsEwZXzFRjoY+XT1Vsf1zgyXdwTr0ZYz1/2tkZ0DBTT9jZjhw=="], + + "eslint-plugin-isaacscript/typescript-eslint/@typescript-eslint/parser": ["@typescript-eslint/parser@8.59.3", "", { "dependencies": { "@typescript-eslint/scope-manager": "8.59.3", "@typescript-eslint/types": "8.59.3", "@typescript-eslint/typescript-estree": "8.59.3", "@typescript-eslint/visitor-keys": "8.59.3", "debug": "^4.4.3" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.1.0" } }, "sha512-HPwA+hVkfcriajbNvTmZv4VRauibay+cWArYUYq7u7W7PmGShMxbPxLvrwDme55a6d5alG3nrYfhyJ/G28XlLg=="], + + "eslint-plugin-isaacscript/typescript-eslint/@typescript-eslint/typescript-estree": ["@typescript-eslint/typescript-estree@8.59.3", "", { "dependencies": { "@typescript-eslint/project-service": "8.59.3", "@typescript-eslint/tsconfig-utils": "8.59.3", "@typescript-eslint/types": "8.59.3", "@typescript-eslint/visitor-keys": "8.59.3", "debug": "^4.4.3", "minimatch": "^10.2.2", "semver": "^7.7.3", "tinyglobby": "^0.2.15", "ts-api-utils": "^2.5.0" }, "peerDependencies": { "typescript": ">=4.8.4 <6.1.0" } }, "sha512-CbRjVRAf7Lr9Kr8RopKcbY45p2VfmmHrm0ygOCYFi7oU8q19m0Fs/6iHS7kNOmwpp+ob07ZVcAqlxUod9lYdmg=="], + "eslint-plugin-json-schema-validator/ajv/json-schema-traverse": ["json-schema-traverse@1.0.0", "", {}, "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="], "eslint-plugin-json-schema-validator/minimatch/brace-expansion": ["brace-expansion@2.1.0", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w=="], @@ -1005,16 +1069,94 @@ "eslint-plugin-obsidianmd/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="], + "eslint-plugin-obsidianmd/obsidian/@types/codemirror": ["@types/codemirror@5.60.8", "", { "dependencies": { "@types/tern": "*" } }, "sha512-VjFgDF/eB+Aklcy15TtOTLQeMjTo07k7KAjql8OK5Dirr7a6sJY4T1uVBDuTVG9VEmn1uUsohOpYnVfgC6/jyw=="], + + "eslint-plugin-obsidianmd/obsidian/moment": ["moment@2.29.4", "", {}, "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w=="], + + "eslint-plugin-obsidianmd/typescript-eslint/@typescript-eslint/eslint-plugin": ["@typescript-eslint/eslint-plugin@8.59.3", "", { "dependencies": { "@eslint-community/regexpp": "^4.12.2", "@typescript-eslint/scope-manager": "8.59.3", "@typescript-eslint/type-utils": "8.59.3", "@typescript-eslint/utils": "8.59.3", "@typescript-eslint/visitor-keys": "8.59.3", "ignore": "^7.0.5", "natural-compare": "^1.4.0", "ts-api-utils": "^2.5.0" }, "peerDependencies": { "@typescript-eslint/parser": "^8.59.3", "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.1.0" } }, "sha512-PwFvSKsXGShKGW6n5bZOhGHEcCZXM8HofLK9fNsEwZXzFRjoY+XT1Vsf1zgyXdwTr0ZYz1/2tkZ0DBTT9jZjhw=="], + + "eslint-plugin-obsidianmd/typescript-eslint/@typescript-eslint/parser": ["@typescript-eslint/parser@8.59.3", "", { "dependencies": { "@typescript-eslint/scope-manager": "8.59.3", "@typescript-eslint/types": "8.59.3", "@typescript-eslint/typescript-estree": "8.59.3", "@typescript-eslint/visitor-keys": "8.59.3", "debug": "^4.4.3" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.1.0" } }, "sha512-HPwA+hVkfcriajbNvTmZv4VRauibay+cWArYUYq7u7W7PmGShMxbPxLvrwDme55a6d5alG3nrYfhyJ/G28XlLg=="], + + "eslint-plugin-obsidianmd/typescript-eslint/@typescript-eslint/typescript-estree": ["@typescript-eslint/typescript-estree@8.59.3", "", { "dependencies": { "@typescript-eslint/project-service": "8.59.3", "@typescript-eslint/tsconfig-utils": "8.59.3", "@typescript-eslint/types": "8.59.3", "@typescript-eslint/visitor-keys": "8.59.3", "debug": "^4.4.3", "minimatch": "^10.2.2", "semver": "^7.7.3", "tinyglobby": "^0.2.15", "ts-api-utils": "^2.5.0" }, "peerDependencies": { "typescript": ">=4.8.4 <6.1.0" } }, "sha512-CbRjVRAf7Lr9Kr8RopKcbY45p2VfmmHrm0ygOCYFi7oU8q19m0Fs/6iHS7kNOmwpp+ob07ZVcAqlxUod9lYdmg=="], + "json-schema-migrate/ajv/json-schema-traverse": ["json-schema-traverse@1.0.0", "", {}, "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="], + "meta-bind-publish/obsidian/@types/codemirror": ["@types/codemirror@5.60.8", "", { "dependencies": { "@types/tern": "*" } }, "sha512-VjFgDF/eB+Aklcy15TtOTLQeMjTo07k7KAjql8OK5Dirr7a6sJY4T1uVBDuTVG9VEmn1uUsohOpYnVfgC6/jyw=="], + + "meta-bind-publish/obsidian/moment": ["moment@2.29.4", "", {}, "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w=="], + + "typescript-eslint/@typescript-eslint/utils/@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@8.60.0", "", { "dependencies": { "@typescript-eslint/types": "8.60.0", "@typescript-eslint/visitor-keys": "8.60.0" } }, "sha512-pFzqhllJMs+jghLQWzV00ds39xLzuyqPSev5pd8f4Ir0rtKR3ZLUB4/4dhjOFighWb9larvtfJvqL+4yKDI3Xw=="], + + "typescript-eslint/@typescript-eslint/utils/@typescript-eslint/types": ["@typescript-eslint/types@8.60.0", "", {}, "sha512-AsE7x2XaAK+CVbeih0Fvbn+r1qHxtpLDJ3XUuFcIinT318T90yHMJC+Zgv+jUuDjQQd06HKwxnDu6sz1IcTilA=="], + "vite-plugin-static-copy/chokidar/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="], "vite-plugin-static-copy/chokidar/readdirp": ["readdirp@3.6.0", "", { "dependencies": { "picomatch": "^2.2.1" } }, "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA=="], + "@typescript-eslint/type-utils/@typescript-eslint/typescript-estree/@typescript-eslint/visitor-keys/eslint-visitor-keys": ["eslint-visitor-keys@5.0.1", "", {}, "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA=="], + + "@typescript-eslint/type-utils/@typescript-eslint/typescript-estree/minimatch/brace-expansion": ["brace-expansion@5.0.6", "", { "dependencies": { "balanced-match": "^4.0.2" } }, "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g=="], + "@typescript-eslint/typescript-estree/minimatch/brace-expansion/balanced-match": ["balanced-match@4.0.4", "", {}, "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA=="], + "@typescript-eslint/utils/@typescript-eslint/typescript-estree/@typescript-eslint/visitor-keys/eslint-visitor-keys": ["eslint-visitor-keys@5.0.1", "", {}, "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA=="], + + "@typescript-eslint/utils/@typescript-eslint/typescript-estree/minimatch/brace-expansion": ["brace-expansion@5.0.6", "", { "dependencies": { "balanced-match": "^4.0.2" } }, "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g=="], + "eslint-plugin-import-x/minimatch/brace-expansion/balanced-match": ["balanced-match@4.0.4", "", {}, "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA=="], + "eslint-plugin-isaacscript/typescript-eslint/@typescript-eslint/eslint-plugin/@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.59.3", "", { "dependencies": { "@typescript-eslint/types": "8.59.3", "eslint-visitor-keys": "^5.0.0" } }, "sha512-f1UQF7ggd42YiwI5wGrRaPsa+P0CINBlrkLPmGfpq/u/I/oVtecoEIfFR9ag/oa1sLOsRNZ6xehf6qMZhQGBDg=="], + + "eslint-plugin-isaacscript/typescript-eslint/@typescript-eslint/eslint-plugin/ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="], + + "eslint-plugin-isaacscript/typescript-eslint/@typescript-eslint/parser/@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.59.3", "", { "dependencies": { "@typescript-eslint/types": "8.59.3", "eslint-visitor-keys": "^5.0.0" } }, "sha512-f1UQF7ggd42YiwI5wGrRaPsa+P0CINBlrkLPmGfpq/u/I/oVtecoEIfFR9ag/oa1sLOsRNZ6xehf6qMZhQGBDg=="], + + "eslint-plugin-isaacscript/typescript-eslint/@typescript-eslint/typescript-estree/@typescript-eslint/project-service": ["@typescript-eslint/project-service@8.59.3", "", { "dependencies": { "@typescript-eslint/tsconfig-utils": "^8.59.3", "@typescript-eslint/types": "^8.59.3", "debug": "^4.4.3" }, "peerDependencies": { "typescript": ">=4.8.4 <6.1.0" } }, "sha512-ECiUWa/KYRGDFUqTNehaRgzDshnJfkTABJxVemHk4ko22gcr0ukloKjWvyQ64g8YCV/UI47kN1dbmjf/GaQYng=="], + + "eslint-plugin-isaacscript/typescript-eslint/@typescript-eslint/typescript-estree/@typescript-eslint/tsconfig-utils": ["@typescript-eslint/tsconfig-utils@8.59.3", "", { "peerDependencies": { "typescript": ">=4.8.4 <6.1.0" } }, "sha512-PcIJHjmaREXLgIAIzLnSY9VucEzz8FKXsRgFa1DmdGCK/5tJpW03TKJF01Q6VZd1lLdz2sIKPWaDUZN9dp//dw=="], + + "eslint-plugin-isaacscript/typescript-eslint/@typescript-eslint/typescript-estree/@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.59.3", "", { "dependencies": { "@typescript-eslint/types": "8.59.3", "eslint-visitor-keys": "^5.0.0" } }, "sha512-f1UQF7ggd42YiwI5wGrRaPsa+P0CINBlrkLPmGfpq/u/I/oVtecoEIfFR9ag/oa1sLOsRNZ6xehf6qMZhQGBDg=="], + + "eslint-plugin-isaacscript/typescript-eslint/@typescript-eslint/typescript-estree/minimatch": ["minimatch@10.2.5", "", { "dependencies": { "brace-expansion": "^5.0.5" } }, "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg=="], + + "eslint-plugin-obsidianmd/typescript-eslint/@typescript-eslint/eslint-plugin/@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.59.3", "", { "dependencies": { "@typescript-eslint/types": "8.59.3", "eslint-visitor-keys": "^5.0.0" } }, "sha512-f1UQF7ggd42YiwI5wGrRaPsa+P0CINBlrkLPmGfpq/u/I/oVtecoEIfFR9ag/oa1sLOsRNZ6xehf6qMZhQGBDg=="], + + "eslint-plugin-obsidianmd/typescript-eslint/@typescript-eslint/eslint-plugin/ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="], + + "eslint-plugin-obsidianmd/typescript-eslint/@typescript-eslint/parser/@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.59.3", "", { "dependencies": { "@typescript-eslint/types": "8.59.3", "eslint-visitor-keys": "^5.0.0" } }, "sha512-f1UQF7ggd42YiwI5wGrRaPsa+P0CINBlrkLPmGfpq/u/I/oVtecoEIfFR9ag/oa1sLOsRNZ6xehf6qMZhQGBDg=="], + + "eslint-plugin-obsidianmd/typescript-eslint/@typescript-eslint/typescript-estree/@typescript-eslint/project-service": ["@typescript-eslint/project-service@8.59.3", "", { "dependencies": { "@typescript-eslint/tsconfig-utils": "^8.59.3", "@typescript-eslint/types": "^8.59.3", "debug": "^4.4.3" }, "peerDependencies": { "typescript": ">=4.8.4 <6.1.0" } }, "sha512-ECiUWa/KYRGDFUqTNehaRgzDshnJfkTABJxVemHk4ko22gcr0ukloKjWvyQ64g8YCV/UI47kN1dbmjf/GaQYng=="], + + "eslint-plugin-obsidianmd/typescript-eslint/@typescript-eslint/typescript-estree/@typescript-eslint/tsconfig-utils": ["@typescript-eslint/tsconfig-utils@8.59.3", "", { "peerDependencies": { "typescript": ">=4.8.4 <6.1.0" } }, "sha512-PcIJHjmaREXLgIAIzLnSY9VucEzz8FKXsRgFa1DmdGCK/5tJpW03TKJF01Q6VZd1lLdz2sIKPWaDUZN9dp//dw=="], + + "eslint-plugin-obsidianmd/typescript-eslint/@typescript-eslint/typescript-estree/@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.59.3", "", { "dependencies": { "@typescript-eslint/types": "8.59.3", "eslint-visitor-keys": "^5.0.0" } }, "sha512-f1UQF7ggd42YiwI5wGrRaPsa+P0CINBlrkLPmGfpq/u/I/oVtecoEIfFR9ag/oa1sLOsRNZ6xehf6qMZhQGBDg=="], + + "eslint-plugin-obsidianmd/typescript-eslint/@typescript-eslint/typescript-estree/minimatch": ["minimatch@10.2.5", "", { "dependencies": { "brace-expansion": "^5.0.5" } }, "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg=="], + "vite-plugin-static-copy/chokidar/readdirp/picomatch": ["picomatch@2.3.2", "", {}, "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA=="], + + "@typescript-eslint/type-utils/@typescript-eslint/typescript-estree/minimatch/brace-expansion/balanced-match": ["balanced-match@4.0.4", "", {}, "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA=="], + + "@typescript-eslint/utils/@typescript-eslint/typescript-estree/minimatch/brace-expansion/balanced-match": ["balanced-match@4.0.4", "", {}, "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA=="], + + "eslint-plugin-isaacscript/typescript-eslint/@typescript-eslint/eslint-plugin/@typescript-eslint/visitor-keys/eslint-visitor-keys": ["eslint-visitor-keys@5.0.1", "", {}, "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA=="], + + "eslint-plugin-isaacscript/typescript-eslint/@typescript-eslint/parser/@typescript-eslint/visitor-keys/eslint-visitor-keys": ["eslint-visitor-keys@5.0.1", "", {}, "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA=="], + + "eslint-plugin-isaacscript/typescript-eslint/@typescript-eslint/typescript-estree/@typescript-eslint/visitor-keys/eslint-visitor-keys": ["eslint-visitor-keys@5.0.1", "", {}, "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA=="], + + "eslint-plugin-isaacscript/typescript-eslint/@typescript-eslint/typescript-estree/minimatch/brace-expansion": ["brace-expansion@5.0.6", "", { "dependencies": { "balanced-match": "^4.0.2" } }, "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g=="], + + "eslint-plugin-obsidianmd/typescript-eslint/@typescript-eslint/eslint-plugin/@typescript-eslint/visitor-keys/eslint-visitor-keys": ["eslint-visitor-keys@5.0.1", "", {}, "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA=="], + + "eslint-plugin-obsidianmd/typescript-eslint/@typescript-eslint/parser/@typescript-eslint/visitor-keys/eslint-visitor-keys": ["eslint-visitor-keys@5.0.1", "", {}, "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA=="], + + "eslint-plugin-obsidianmd/typescript-eslint/@typescript-eslint/typescript-estree/@typescript-eslint/visitor-keys/eslint-visitor-keys": ["eslint-visitor-keys@5.0.1", "", {}, "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA=="], + + "eslint-plugin-obsidianmd/typescript-eslint/@typescript-eslint/typescript-estree/minimatch/brace-expansion": ["brace-expansion@5.0.6", "", { "dependencies": { "balanced-match": "^4.0.2" } }, "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g=="], + + "eslint-plugin-isaacscript/typescript-eslint/@typescript-eslint/typescript-estree/minimatch/brace-expansion/balanced-match": ["balanced-match@4.0.4", "", {}, "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA=="], + + "eslint-plugin-obsidianmd/typescript-eslint/@typescript-eslint/typescript-estree/minimatch/brace-expansion/balanced-match": ["balanced-match@4.0.4", "", {}, "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA=="], } } diff --git a/manifest-beta.json b/manifest-beta.json index 4a38c1b5..54779b7f 100644 --- a/manifest-beta.json +++ b/manifest-beta.json @@ -1,8 +1,8 @@ { "id": "obsidian-meta-bind-plugin", "name": "Meta Bind", - "version": "1.4.10", - "minAppVersion": "1.10.0", + "version": "1.4.11", + "minAppVersion": "1.13.0", "description": "Make your notes interactive with inline input fields, metadata displays, and buttons.", "author": "Moritz Jung", "authorUrl": "https://www.moritzjung.dev/", diff --git a/manifest.json b/manifest.json index 4a38c1b5..54779b7f 100644 --- a/manifest.json +++ b/manifest.json @@ -1,8 +1,8 @@ { "id": "obsidian-meta-bind-plugin", "name": "Meta Bind", - "version": "1.4.10", - "minAppVersion": "1.10.0", + "version": "1.4.11", + "minAppVersion": "1.13.0", "description": "Make your notes interactive with inline input fields, metadata displays, and buttons.", "author": "Moritz Jung", "authorUrl": "https://www.moritzjung.dev/", diff --git a/package.json b/package.json index 830155c0..bea9002a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "obsidian-meta-bind-plugin", - "version": "1.4.10", + "version": "1.4.11", "description": "Make your notes interactive with inline input fields, metadata displays, and buttons.", "main": "main.js", "scripts": { @@ -41,8 +41,8 @@ "svelte-check": "^4.4.8", "tslib": "^2.8.1", "typescript": "^6.0.3", - "typescript-eslint": "^8.59.3", - "vite": "^8.0.12", + "typescript-eslint": "^8.60.0", + "vite": "^8.0.14", "vite-plugin-banner": "^0.8.1", "vite-plugin-static-copy": "^4.1.0", "yaml": "^2.9.0" diff --git a/packages/core/src/Settings.ts b/packages/core/src/Settings.ts index ca087380..baed523e 100644 --- a/packages/core/src/Settings.ts +++ b/packages/core/src/Settings.ts @@ -59,11 +59,34 @@ export const weekdays: Weekday[] = [ }, ]; +export function getWeekdayByName(name: string): Weekday { + return weekdays.find(weekday => weekday.name === name) ?? weekdays[1]; +} + +export function normalizeFirstWeekday(firstWeekday: unknown): string { + if (typeof firstWeekday === 'string') { + return getWeekdayByName(firstWeekday).name; + } + + if (typeof firstWeekday === 'number') { + return (weekdays.find(weekday => weekday.index === firstWeekday) ?? weekdays[1]).name; + } + + if (typeof firstWeekday === 'object' && firstWeekday !== null && 'name' in firstWeekday) { + const name = firstWeekday.name; + if (typeof name === 'string') { + return getWeekdayByName(name).name; + } + } + + return weekdays[1].name; +} + export interface MetaBindPluginSettings { devMode: boolean; ignoreCodeBlockRestrictions: boolean; preferredDateFormat: string; - firstWeekday: Weekday; + firstWeekday: string; syncInterval: number; enableJs: boolean; viewFieldDisplayNullAsEmpty: boolean; @@ -84,7 +107,7 @@ export const DEFAULT_SETTINGS: MetaBindPluginSettings = { devMode: false, ignoreCodeBlockRestrictions: false, preferredDateFormat: 'YYYY-MM-DD', - firstWeekday: weekdays[1], + firstWeekday: weekdays[1].name, syncInterval: 200, enableJs: false, viewFieldDisplayNullAsEmpty: false, diff --git a/packages/core/src/fields/button/ButtonManager.ts b/packages/core/src/fields/button/ButtonManager.ts index 172dbf16..fa2b75e4 100644 --- a/packages/core/src/fields/button/ButtonManager.ts +++ b/packages/core/src/fields/button/ButtonManager.ts @@ -30,25 +30,35 @@ export class ButtonManager { this.buttonTemplates.clear(); for (const buttonTemplate of buttonTemplates) { - if (buttonTemplate.id === undefined || buttonTemplate.id === '') { + let validatedButtonTemplate: ButtonConfig; + + try { + validatedButtonTemplate = this.mb.buttonParser.validateConfig(buttonTemplate); + Object.assign(buttonTemplate, validatedButtonTemplate); + } catch (e) { + errorCollection.add(e); + continue; + } + + if (validatedButtonTemplate.id === undefined || validatedButtonTemplate.id === '') { errorCollection.add( new MetaBindButtonError({ errorLevel: ErrorLevel.ERROR, - cause: `Button with label "${buttonTemplate.label}" has no id, but button templates must have an id.`, + cause: `Button with label "${validatedButtonTemplate.label}" has no id, but button templates must have an id.`, effect: 'Button templates could not be saved.', }), ); - } else if (idSet.has(buttonTemplate.id)) { + } else if (idSet.has(validatedButtonTemplate.id)) { errorCollection.add( new MetaBindButtonError({ errorLevel: ErrorLevel.ERROR, - cause: `Button id "${buttonTemplate.id}" is not unique. The same id is used by multiple buttons.`, + cause: `Button id "${validatedButtonTemplate.id}" is not unique. The same id is used by multiple buttons.`, effect: 'Button templates could not be saved.', }), ); } else { - idSet.add(buttonTemplate.id); - this.buttonTemplates.set(buttonTemplate.id, buttonTemplate); + idSet.add(validatedButtonTemplate.id); + this.buttonTemplates.set(validatedButtonTemplate.id, validatedButtonTemplate); } } diff --git a/packages/core/src/utils/DatePickerUtils.ts b/packages/core/src/utils/DatePickerUtils.ts index eff63c28..a5f3434d 100644 --- a/packages/core/src/utils/DatePickerUtils.ts +++ b/packages/core/src/utils/DatePickerUtils.ts @@ -1,12 +1,12 @@ import type { Weekday } from 'meta-bind-core/src/Settings'; -import { monthNames, weekdays } from 'meta-bind-core/src/Settings'; +import { getWeekdayByName, monthNames, weekdays } from 'meta-bind-core/src/Settings'; import { mod } from 'meta-bind-core/src/utils/Utils'; import Moment from 'moment/moment'; export let firstWeekday: Weekday = weekdays[1]; -export function setFirstWeekday(w: Weekday): void { - firstWeekday = w; +export function setFirstWeekday(weekdayName: string): void { + firstWeekday = getWeekdayByName(weekdayName); } export function getMonthName(index: number): string { diff --git a/packages/core/tests/fields/Button.test.ts b/packages/core/tests/fields/Button.test.ts index 9815a247..251a5e4e 100644 --- a/packages/core/tests/fields/Button.test.ts +++ b/packages/core/tests/fields/Button.test.ts @@ -1,10 +1,6 @@ import { beforeEach, describe, expect, test } from 'bun:test'; -import { - type ButtonAction, - ButtonActionType, - ButtonClickContext, - ButtonClickType, -} from 'meta-bind-core/src/config/ButtonConfig'; +import type { ButtonAction, ButtonConfig } from 'meta-bind-core/src/config/ButtonConfig'; +import { ButtonActionType, ButtonClickContext, ButtonClickType } from 'meta-bind-core/src/config/ButtonConfig'; import { TestMetaBind } from '../__mocks__/TestPlugin'; let testPlugin: TestMetaBind; @@ -433,4 +429,53 @@ describe('Button', () => { }); } }); + + describe('Button Templates', () => { + beforeEach(() => { + testPlugin = new TestMetaBind(); + }); + + test('normalizes raw template configs before storing them', async () => { + const rawTemplate = { + label: 'Raw Update', + style: 'default', + id: 'raw-update', + actions: [ + { + type: ButtonActionType.UPDATE_METADATA, + bindTarget: 'testProp', + evaluate: true, + value: 1, + }, + ], + } as unknown as ButtonConfig; + + const errors = testPlugin.buttonManager.setButtonTemplates([rawTemplate]); + + expect(errors.hasErrors()).toBe(false); + + const template = testPlugin.buttonManager.getButton(testFilePath, 'raw-update'); + const action = template?.actions?.[0]; + + expect(action).toMatchObject({ value: '1' }); + + testPlugin.internal.jsEngineExecuteCustom = async (code): Promise => { + expect(code).toBe('1'); + return 7; + }; + + await testPlugin.buttonActionRunner.runButtonActions( + template!, + testFilePath, + { + position: undefined, + isInline: false, + isInGroup: false, + }, + defaultClick, + ); + + expect(testPlugin.getCacheMetadata(testFilePath)?.testProp).toBe(7); + }); + }); }); diff --git a/packages/core/tests/utils/Settings.test.ts b/packages/core/tests/utils/Settings.test.ts new file mode 100644 index 00000000..98a48462 --- /dev/null +++ b/packages/core/tests/utils/Settings.test.ts @@ -0,0 +1,25 @@ +import { describe, expect, test } from 'bun:test'; +import { normalizeFirstWeekday } from 'meta-bind-core/src/Settings'; + +describe('settings', () => { + describe('normalizeFirstWeekday', () => { + test('keeps valid weekday names', () => { + expect(normalizeFirstWeekday('Sunday')).toBe('Sunday'); + expect(normalizeFirstWeekday('Wednesday')).toBe('Wednesday'); + }); + + test('migrates legacy weekday objects', () => { + expect(normalizeFirstWeekday({ index: 5, name: 'Friday', shortName: 'Fr' })).toBe('Friday'); + }); + + test('accepts numeric weekday indexes defensively', () => { + expect(normalizeFirstWeekday(6)).toBe('Saturday'); + }); + + test('falls back to Monday for invalid values', () => { + expect(normalizeFirstWeekday('Funday')).toBe('Monday'); + expect(normalizeFirstWeekday({ name: 1 })).toBe('Monday'); + expect(normalizeFirstWeekday(undefined)).toBe('Monday'); + }); + }); +}); diff --git a/packages/obsidian/package.json b/packages/obsidian/package.json index 1ebff96e..5bcce138 100644 --- a/packages/obsidian/package.json +++ b/packages/obsidian/package.json @@ -21,6 +21,6 @@ "@codemirror/lint": "^6.9.5", "@codemirror/state": "^6.6.0", "@codemirror/view": "^6.41.1", - "obsidian": "latest" + "obsidian": "obsidianmd/obsidian-api#cf9ef454f6e0fa0f1f275b3e51991dfc557cc7be" } } diff --git a/packages/obsidian/src/ObsMB.ts b/packages/obsidian/src/ObsMB.ts index f26749ae..3a76bb8d 100644 --- a/packages/obsidian/src/ObsMB.ts +++ b/packages/obsidian/src/ObsMB.ts @@ -128,7 +128,7 @@ export class ObsMetaBind extends MetaBind { ); this.plugin.registerInterval( - window.setInterval(() => this.metadataManager.cycle(), this.getSettings().syncInterval), + window.setInterval(() => void this.metadataManager.cycle(), this.getSettings().syncInterval), ); } diff --git a/packages/obsidian/src/dependencies/DependencyManager.ts b/packages/obsidian/src/dependencies/DependencyManager.ts index 2fe99cab..001159a9 100644 --- a/packages/obsidian/src/dependencies/DependencyManager.ts +++ b/packages/obsidian/src/dependencies/DependencyManager.ts @@ -46,7 +46,7 @@ export class DependencyManager { private checkDependencyVersion(dependency: Dependency, version: Version): void { if (Version.lessThan(version, dependency.minVersion)) { this.throwDependencyError( - `Plugin ${dependency.pluginId} is outdated. Required version is at least ${dependency.minVersion}, installed version is ${version}. Please update the plugin.`, + `Plugin ${dependency.pluginId} is outdated. Required version is at least ${dependency.minVersion.toString()}, installed version is ${version.toString()}. Please update the plugin.`, ); } @@ -55,7 +55,7 @@ export class DependencyManager { (Version.greaterThan(version, dependency.maxVersion) || Version.equals(version, dependency.maxVersion)) ) { this.throwDependencyError( - `Plugin ${dependency.pluginId} is too new. Required version is lower than ${dependency.maxVersion}, installed version is ${version}. Please downgrade the plugin.`, + `Plugin ${dependency.pluginId} is too new. Required version is lower than ${dependency.maxVersion.toString()}, installed version is ${version.toString()}. Please downgrade the plugin.`, ); } } diff --git a/packages/obsidian/src/main.ts b/packages/obsidian/src/main.ts index d2b3e38a..60a0a42e 100644 --- a/packages/obsidian/src/main.ts +++ b/packages/obsidian/src/main.ts @@ -1,5 +1,5 @@ import type { MetaBindPluginSettings } from 'meta-bind-core/src/Settings'; -import { DEFAULT_SETTINGS } from 'meta-bind-core/src/Settings'; +import { DEFAULT_SETTINGS, normalizeFirstWeekday } from 'meta-bind-core/src/Settings'; import { areObjectsEqual } from 'meta-bind-core/src/utils/Utils'; import type { ObsAPI } from 'meta-bind-obsidian/src/ObsAPI'; import { ObsMetaBind } from 'meta-bind-obsidian/src/ObsMB'; @@ -40,13 +40,15 @@ export default class ObsMetaBindPlugin extends Plugin { async loadSettings(): Promise { MB_DEBUG && console.log(`meta-bind | Main >> loading settings`); - const loadedSettings = ((await this.loadData()) ?? {}) as MetaBindPluginSettings; + const loadedSettings = ((await this.loadData()) ?? {}) as Partial; if (typeof loadedSettings === 'object' && loadedSettings != null) { // @ts-expect-error TS2339 remove old config field delete loadedSettings.inputTemplates; // @ts-expect-error TS2339 remove old config field delete loadedSettings.useUsDateInputOrder; + + loadedSettings.firstWeekday = normalizeFirstWeekday(loadedSettings.firstWeekday); } this.settings = Object.assign({}, DEFAULT_SETTINGS, loadedSettings); diff --git a/packages/obsidian/src/settings/ListSettingGroup.ts b/packages/obsidian/src/settings/ListSettingGroup.ts new file mode 100644 index 00000000..55112876 --- /dev/null +++ b/packages/obsidian/src/settings/ListSettingGroup.ts @@ -0,0 +1,60 @@ +import type { MetaBindSettingKey } from 'meta-bind-obsidian/src/settings/SettingsTypes'; +import type { SettingDefinitionItem, SettingGroupItem } from 'obsidian'; + +export interface ListSettingGroupOptions { + heading: string; + emptyState: string; + items: T[]; + renderItem: (item: T, index: number) => SettingGroupItem; + applyItems: (items: T[]) => boolean; + onUpdate: () => void; +} + +export function getListSettingGroup(options: ListSettingGroupOptions): SettingDefinitionItem { + return { + type: 'list', + heading: options.heading, + emptyState: options.emptyState, + items: options.items.map((item, index) => options.renderItem(item, index)), + onDelete: (index: number): void => { + updateListItems( + options.items, + items => { + items.splice(index, 1); + }, + options.applyItems, + options.onUpdate, + ); + }, + onReorder: (oldIndex: number, newIndex: number): void => { + updateListItems( + options.items, + items => { + moveListItem(items, oldIndex, newIndex); + }, + options.applyItems, + options.onUpdate, + ); + }, + }; +} + +export function updateListItems( + items: T[], + updateItems: (items: T[]) => void, + applyItems: (items: T[]) => boolean, + onUpdate: () => void, +): boolean { + const nextItems = structuredClone(items); + updateItems(nextItems); + if (applyItems(nextItems)) { + onUpdate(); + return true; + } + return false; +} + +function moveListItem(items: T[], oldIndex: number, newIndex: number): void { + const [item] = items.splice(oldIndex, 1); + items.splice(newIndex, 0, item); +} diff --git a/packages/obsidian/src/settings/SettingsTab.ts b/packages/obsidian/src/settings/SettingsTab.ts index d52a6877..61cb47f8 100644 --- a/packages/obsidian/src/settings/SettingsTab.ts +++ b/packages/obsidian/src/settings/SettingsTab.ts @@ -1,13 +1,15 @@ import { MetaBindBuild } from 'meta-bind-core/src'; +import type { MetaBindPluginSettings } from 'meta-bind-core/src/Settings'; import { DEFAULT_SETTINGS, MAX_SYNC_INTERVAL, MIN_SYNC_INTERVAL, weekdays } from 'meta-bind-core/src/Settings'; import { DocsUtils } from 'meta-bind-core/src/utils/DocsUtils'; import type { ObsMetaBind } from 'meta-bind-obsidian/src/ObsMB'; import { MB_PLAYGROUND_VIEW_TYPE } from 'meta-bind-obsidian/src/playground/PlaygroundView'; -import { ButtonTemplatesSettingModal } from 'meta-bind-obsidian/src/settings/buttonTemplateSetting/ButtonTemplatesSettingModal'; -import { ExcludedFoldersSettingModal } from 'meta-bind-obsidian/src/settings/excludedFoldersSetting/ExcludedFoldersSettingModal'; -import { InputFieldTemplatesSettingModal } from 'meta-bind-obsidian/src/settings/inputFieldTemplateSetting/InputFieldTemplatesSettingModal'; -import type { App } from 'obsidian'; -import { ButtonComponent, PluginSettingTab, Setting } from 'obsidian'; +import { ButtonTemplateSettings } from 'meta-bind-obsidian/src/settings/buttonTemplateSetting/ButtonTemplateSettings'; +import { ExcludedFolderSettings } from 'meta-bind-obsidian/src/settings/excludedFoldersSetting/ExcludedFolderSettings'; +import { InputFieldTemplateSettings } from 'meta-bind-obsidian/src/settings/inputFieldTemplateSetting/InputFieldTemplateSettings'; +import type { MetaBindSettingKey } from 'meta-bind-obsidian/src/settings/SettingsTypes'; +import type { App, Setting, SettingDefinitionItem } from 'obsidian'; +import { PluginSettingTab } from 'obsidian'; export class MetaBindSettingTab extends PluginSettingTab { mb: ObsMetaBind; @@ -17,26 +19,141 @@ export class MetaBindSettingTab extends PluginSettingTab { this.mb = mb; } - display(): void { - const { containerEl } = this; - - containerEl.empty(); + getSettingDefinitions(): SettingDefinitionItem[] { + const items: SettingDefinitionItem[] = []; if (this.mb.build === MetaBindBuild.DEV || this.mb.build === MetaBindBuild.CANARY) { - containerEl.createEl('p', { - text: `You are using a ${this.mb.build} build (${MB_VERSION}). This build is not intended for production use. Use at your own risk.`, - cls: 'mb-error', - }); - const button = new ButtonComponent(containerEl); - button.setButtonText('Learn about canary builds'); - button.setCta(); - button.onClick(() => { - DocsUtils.open(DocsUtils.linkToCanaryBuilds()); + items.push({ + name: 'Development build', + desc: `You are using a ${this.mb.build} build (${MB_VERSION}). This build is not intended for production use. Use at your own risk.`, + render: (setting: Setting): void => { + setting.setClass('mb-error'); + setting.addButton(cb => { + cb.setCta(); + cb.setButtonText('Learn about canary builds'); + cb.onClick(() => { + DocsUtils.open(DocsUtils.linkToCanaryBuilds()); + }); + }); + }, }); } - new Setting(containerEl) - .setName('Quick access') + items.push( + { + name: 'Quick access', + render: (setting: Setting): void => { + this.addQuickAccessButtons(setting); + }, + }, + { + name: 'Enable syntax highlighting', + desc: 'Enable syntax highlighting for meta bind syntax. Restart required.', + control: { type: 'toggle', key: 'enableSyntaxHighlighting' }, + }, + { + name: 'Enable editor right-click menu', + desc: 'Enable a meta bind menu section in the editor right-click menu. Restart required.', + control: { type: 'toggle', key: 'enableEditorRightClickMenu' }, + }, + { + type: 'page', + name: 'Input field templates', + desc: 'You can specify input field templates here, and access them using `INPUT[template_name][overrides (optional)]` in your notes.', + items: new InputFieldTemplateSettings(this.app, this.mb, () => this.update()).getDefinitions(), + }, + { + type: 'page', + name: 'Button templates', + desc: 'You can specify button field templates here, and access them in inline buttons.', + items: new ButtonTemplateSettings(this.mb, () => this.update()).getDefinitions(), + }, + { + type: 'page', + name: 'Excluded folders', + desc: 'You can specify excluded folders here. The plugin will not work within excluded folders.', + items: new ExcludedFolderSettings(this.app, this.mb, () => this.update()).getDefinitions(), + }, + { + name: 'View fields display null as empty', + desc: 'Display nothing instead of null, if the frontmatter value is empty, in text view fields.', + control: { type: 'toggle', key: 'viewFieldDisplayNullAsEmpty' }, + }, + { + name: 'Enable JavaScript', + desc: "Enable features that run user written JavaScript. This is potentially DANGEROUS, thus it's disabled by default. Restart required.", + control: { type: 'toggle', key: 'enableJs' }, + }, + { + type: 'group', + heading: 'Date and time', + items: [ + { + name: 'Date format', + desc: 'The date format to be used by this plugin. Changing this setting will break the parsing of existing date inputs. Here is a list of all available date tokes https://momentjs.com/docs/#/displaying/.', + control: { type: 'text', key: 'preferredDateFormat' }, + }, + { + name: 'First weekday', + desc: 'Specify the first weekday for the datepicker.', + control: { + type: 'dropdown', + key: 'firstWeekday', + options: Object.fromEntries(weekdays.map(weekday => [weekday.name, weekday.name])), + }, + }, + ], + }, + { + type: 'group', + heading: 'Advanced', + items: [ + { + name: 'Dev mode', + desc: 'Enable dev mode. Not recommended unless you want to debug this plugin.', + control: { type: 'toggle', key: 'devMode' }, + }, + { + name: 'Disable code block restrictions', + desc: 'Disable restrictions on which input fields can be created in which code blocks. Not recommended unless you know what you are doing.', + control: { type: 'toggle', key: 'ignoreCodeBlockRestrictions' }, + }, + { + name: 'Sync interval', + desc: `The interval in milli-seconds between disk writes. Changing this number is not recommended except if your hard drive is exceptionally slow. Standard: ${DEFAULT_SETTINGS.syncInterval}; Minimum: ${MIN_SYNC_INTERVAL}; Maximum: ${MAX_SYNC_INTERVAL}`, + control: { + type: 'number', + key: 'syncInterval', + defaultValue: DEFAULT_SETTINGS.syncInterval, + min: MIN_SYNC_INTERVAL, + max: MAX_SYNC_INTERVAL, + step: 1, + validate: (value: number): string | void => { + if (value < MIN_SYNC_INTERVAL || value > MAX_SYNC_INTERVAL) { + return `Sync interval must be between ${MIN_SYNC_INTERVAL} and ${MAX_SYNC_INTERVAL}.`; + } + }, + }, + }, + ], + }, + ); + + return items; + } + + getControlValue(key: MetaBindSettingKey): unknown { + return this.mb.getSettings()[key]; + } + + setControlValue(key: MetaBindSettingKey, value: unknown): void { + this.mb.updateSettings(settings => { + settings[key] = value as never; + }); + } + + private addQuickAccessButtons(setting: Setting): void { + setting .addButton(cb => { cb.setCta(); cb.setButtonText('Docs'); @@ -62,169 +179,5 @@ export class MetaBindSettingTab extends PluginSettingTab { DocsUtils.open(DocsUtils.linkToIssues()); }); }); - - new Setting(containerEl) - .setName('Enable syntax highlighting') - .setDesc(`Enable syntax highlighting for meta bind syntax. Restart required.`) - .addToggle(cb => { - cb.setValue(this.mb.getSettings().enableSyntaxHighlighting); - cb.onChange(data => { - this.mb.updateSettings(settings => { - settings.enableSyntaxHighlighting = data; - }); - }); - }); - - new Setting(containerEl) - .setName('Enable editor right-click menu') - .setDesc(`Enable a meta bind menu section in the editor right-click menu. Restart required.`) - .addToggle(cb => { - cb.setValue(this.mb.getSettings().enableEditorRightClickMenu); - cb.onChange(data => { - this.mb.updateSettings(settings => { - settings.enableEditorRightClickMenu = data; - }); - }); - }); - - new Setting(containerEl) - .setName('Input field templates') - .setDesc( - `You can specify input field templates here, and access them using \`INPUT[template_name][overrides (optional)]\` in your notes.`, - ) - .addButton(cb => { - cb.setButtonText('Edit templates'); - cb.onClick(() => { - new InputFieldTemplatesSettingModal(this.app, this.mb).open(); - }); - }); - - new Setting(containerEl) - .setName('Button templates') - .setDesc(`You can specify button field templates here, and access them in inline buttons.`) - .addButton(cb => { - cb.setButtonText('Edit templates'); - cb.onClick(() => { - new ButtonTemplatesSettingModal(this.app, this.mb).open(); - }); - }); - - new Setting(containerEl) - .setName('Excluded folders') - .setDesc(`You can specify excluded folders here. The plugin will not work within excluded folders.`) - .addButton(cb => { - cb.setButtonText('Edit excluded folders'); - cb.onClick(() => { - new ExcludedFoldersSettingModal(this.app, this.mb).open(); - }); - }); - - new Setting(containerEl) - .setName('View fields display null as empty') - .setDesc('Display nothing instead of null, if the frontmatter value is empty, in text view fields.') - .addToggle(cb => { - cb.setValue(this.mb.getSettings().viewFieldDisplayNullAsEmpty); - cb.onChange(data => { - this.mb.updateSettings(settings => { - settings.viewFieldDisplayNullAsEmpty = data; - }); - }); - }); - - new Setting(containerEl) - .setName('Enable JavaScript') - .setDesc( - "Enable features that run user written JavaScript. This is potentially DANGEROUS, thus it's disabled by default. Restart required.", - ) - .addToggle(cb => { - cb.setValue(this.mb.getSettings().enableJs); - cb.onChange(data => { - this.mb.updateSettings(settings => { - settings.enableJs = data; - }); - }); - }); - - new Setting(containerEl).setName('Date and time').setHeading(); - - new Setting(containerEl) - .setName('Date format') - .setDesc( - `The date format to be used by this plugin. Changing this setting will break the parsing of existing date inputs. Here is a list of all available date tokes https://momentjs.com/docs/#/displaying/.`, - ) - .addText(cb => { - cb.setValue(this.mb.getSettings().preferredDateFormat); - cb.onChange(data => { - this.mb.updateSettings(settings => { - settings.preferredDateFormat = data; - }); - }); - }); - - new Setting(containerEl) - .setName('First weekday') - .setDesc(`Specify the first weekday for the datepicker.`) - .addDropdown(cb => { - for (const weekday of weekdays) { - cb.addOption(weekday.name, weekday.name); - } - cb.setValue(this.mb.getSettings().firstWeekday.name); - cb.onChange(data => { - this.mb.updateSettings(settings => { - settings.firstWeekday = weekdays.find(x => x.name === data)!; - }); - }); - }); - - new Setting(containerEl).setName('Advanced').setHeading(); - - new Setting(containerEl) - .setName('Dev mode') - .setDesc('Enable dev mode. Not recommended unless you want to debug this plugin.') - .addToggle(cb => { - cb.setValue(this.mb.getSettings().devMode); - cb.onChange(data => { - this.mb.updateSettings(settings => { - settings.devMode = data; - }); - }); - }); - - new Setting(containerEl) - .setName('Disable code block restrictions') - .setDesc( - 'Disable restrictions on which input fields can be created in which code blocks. Not recommended unless you know what you are doing.', - ) - .addToggle(cb => { - cb.setValue(this.mb.getSettings().ignoreCodeBlockRestrictions); - cb.onChange(data => { - this.mb.updateSettings(settings => { - settings.ignoreCodeBlockRestrictions = data; - }); - }); - }); - - new Setting(containerEl) - .setName('Sync interval') - .setDesc( - `The interval in milli-seconds between disk writes. Changing this number is not recommended except if your hard drive is exceptionally slow. Standard: ${DEFAULT_SETTINGS.syncInterval}; Minimum: ${MIN_SYNC_INTERVAL}; Maximum: ${MAX_SYNC_INTERVAL}`, - ) - .addText(cb => { - cb.setValue(this.mb.getSettings().syncInterval.toString()); - cb.onChange(data => { - this.mb.updateSettings(settings => { - settings.syncInterval = Number.parseInt(data); - if (Number.isNaN(settings.syncInterval)) { - settings.syncInterval = DEFAULT_SETTINGS.syncInterval; - } - if (settings.syncInterval < MIN_SYNC_INTERVAL) { - settings.syncInterval = MIN_SYNC_INTERVAL; - } - if (settings.syncInterval > MAX_SYNC_INTERVAL) { - settings.syncInterval = MAX_SYNC_INTERVAL; - } - }); - }); - }); } } diff --git a/packages/obsidian/src/settings/SettingsTypes.ts b/packages/obsidian/src/settings/SettingsTypes.ts new file mode 100644 index 00000000..031a8ccb --- /dev/null +++ b/packages/obsidian/src/settings/SettingsTypes.ts @@ -0,0 +1,3 @@ +import type { MetaBindPluginSettings } from 'meta-bind-core/src/Settings'; + +export type MetaBindSettingKey = keyof MetaBindPluginSettings; diff --git a/packages/obsidian/src/settings/buttonTemplateSetting/ButtonTemplateSettingComponent.svelte b/packages/obsidian/src/settings/buttonTemplateSetting/ButtonTemplateSettingComponent.svelte deleted file mode 100644 index 9e92d0e5..00000000 --- a/packages/obsidian/src/settings/buttonTemplateSetting/ButtonTemplateSettingComponent.svelte +++ /dev/null @@ -1,51 +0,0 @@ - - -
- - {template.id} - - - - -
{stringifyYaml(template)}
-
diff --git a/packages/obsidian/src/settings/buttonTemplateSetting/ButtonTemplateSettings.ts b/packages/obsidian/src/settings/buttonTemplateSetting/ButtonTemplateSettings.ts new file mode 100644 index 00000000..20344bd8 --- /dev/null +++ b/packages/obsidian/src/settings/buttonTemplateSetting/ButtonTemplateSettings.ts @@ -0,0 +1,169 @@ +import type { ButtonConfig } from 'meta-bind-core/src/config/ButtonConfig'; +import type { ObsMetaBind } from 'meta-bind-obsidian/src/ObsMB'; +import { getListSettingGroup, updateListItems } from 'meta-bind-obsidian/src/settings/ListSettingGroup'; +import type { MetaBindSettingKey } from 'meta-bind-obsidian/src/settings/SettingsTypes'; +import type { Setting, SettingDefinitionItem, SettingGroupItem } from 'obsidian'; +import { Notice, parseYaml, stringifyYaml } from 'obsidian'; + +export class ButtonTemplateSettings { + constructor( + private readonly mb: ObsMetaBind, + private readonly onUpdate: () => void, + ) {} + + getDefinitions(): SettingDefinitionItem[] { + const templates = this.mb.getSettings().buttonTemplates; + + return [ + { + name: 'Add template', + action: (): void => { + this.mb.internal.openButtonBuilderModal({ + submitText: 'Add', + config: this.createDefaultButtonTemplate(), + onOkay: newTemplate => { + updateListItems( + this.mb.getSettings().buttonTemplates, + templates => { + templates.push(newTemplate); + }, + templates => this.applyButtonTemplates(templates), + this.onUpdate, + ); + }, + }); + }, + }, + { + name: 'Add template from clipboard', + action: (): void => { + void this.addButtonTemplateFromClipboard(); + }, + }, + getListSettingGroup({ + heading: 'Templates', + emptyState: 'No button templates configured.', + items: templates, + renderItem: (template, index) => this.getButtonTemplateSetting(template, index), + applyItems: templates => this.applyButtonTemplates(templates), + onUpdate: this.onUpdate, + }), + ]; + } + + private getButtonTemplateSetting(template: ButtonConfig, index: number): SettingGroupItem { + const actionCount = template.actions?.length ?? (template.action ? 1 : 0); + + return { + name: template.id ?? template.label ?? `Button template ${index + 1}`, + desc: `${template.label ?? 'No label'} - ${actionCount} action${actionCount === 1 ? '' : 's'}`, + searchable: true, + aliases: [template.id, template.label, template.tooltip].filter(x => x !== undefined), + render: (setting: Setting): void => { + setting.addExtraButton(cb => { + cb.setIcon('pencil'); + cb.setTooltip('Edit template'); + cb.onClick(() => { + this.mb.internal.openButtonBuilderModal({ + submitText: 'Submit', + config: structuredClone(template), + onOkay: newTemplate => { + updateListItems( + this.mb.getSettings().buttonTemplates, + templates => { + templates[index] = newTemplate; + }, + templates => this.applyButtonTemplates(templates), + this.onUpdate, + ); + }, + }); + }); + }); + setting.addExtraButton(cb => { + cb.setIcon('copy'); + cb.setTooltip('Copy template YAML'); + cb.onClick(() => { + void navigator.clipboard.writeText(stringifyYaml(template)); + new Notice('meta-bind | Copied to clipboard'); + }); + }); + }, + }; + } + + private applyButtonTemplates(templates: ButtonConfig[]): boolean { + const previousTemplates = this.mb.getSettings().buttonTemplates; + const errorCollection = this.mb.buttonManager.setButtonTemplates(templates); + if (errorCollection.hasErrors()) { + const errors = errorCollection.getErrors(); + this.mb.buttonManager.setButtonTemplates(previousTemplates); + console.warn('meta-bind | failed to save button templates', errors); + new Notice( + `meta-bind | Button template could not be saved: ${errors[0]?.message ?? 'Unknown validation error.'}`, + ); + return false; + } + + this.mb.updateSettings(settings => { + settings.buttonTemplates = templates; + }); + + return true; + } + + private async addButtonTemplateFromClipboard(): Promise { + let template: ButtonConfig; + try { + template = parseYaml(await navigator.clipboard.readText()) as ButtonConfig; + if (template.id === undefined || template.id === '') { + template.id = this.createUniqueButtonTemplateId(); + } + } catch (e) { + console.warn(e); + new Notice('meta-bind | Can not parse button config. Check your button syntax.'); + return; + } + + this.mb.internal.openButtonBuilderModal({ + submitText: 'Add', + config: template, + onOkay: newTemplate => { + updateListItems( + this.mb.getSettings().buttonTemplates, + templates => { + templates.push(newTemplate); + }, + templates => this.applyButtonTemplates(templates), + this.onUpdate, + ); + }, + }); + } + + private createDefaultButtonTemplate(): ButtonConfig { + return { + ...this.mb.buttonActionRunner.createDefaultButtonConfig(), + id: this.createUniqueButtonTemplateId(), + }; + } + + private createUniqueButtonTemplateId(): string { + const ids = new Set( + this.mb + .getSettings() + .buttonTemplates.map(template => template.id) + .filter(x => x), + ); + const baseId = 'button-template'; + let id = baseId; + let counter = 2; + + while (ids.has(id)) { + id = `${baseId}-${counter}`; + counter += 1; + } + + return id; + } +} diff --git a/packages/obsidian/src/settings/buttonTemplateSetting/ButtonTemplatesSettingComponent.svelte b/packages/obsidian/src/settings/buttonTemplateSetting/ButtonTemplatesSettingComponent.svelte deleted file mode 100644 index 97e15850..00000000 --- a/packages/obsidian/src/settings/buttonTemplateSetting/ButtonTemplatesSettingComponent.svelte +++ /dev/null @@ -1,118 +0,0 @@ - - -
-

Meta Bind Button Templates

- - {#each buttonConfigs as _, i} - - {/each} - - - - - {#if errorCollection} -
-

Some Templates Failed to Parse

- - -
- {/if} - - - - - -
diff --git a/packages/obsidian/src/settings/buttonTemplateSetting/ButtonTemplatesSettingModal.ts b/packages/obsidian/src/settings/buttonTemplateSetting/ButtonTemplatesSettingModal.ts deleted file mode 100644 index 91687f34..00000000 --- a/packages/obsidian/src/settings/buttonTemplateSetting/ButtonTemplatesSettingModal.ts +++ /dev/null @@ -1,53 +0,0 @@ -import type { ButtonConfig } from 'meta-bind-core/src/config/ButtonConfig'; -import type { ErrorCollection } from 'meta-bind-core/src/utils/errors/ErrorCollection'; -import type { ObsMetaBind } from 'meta-bind-obsidian/src/ObsMB'; -import type { App } from 'obsidian'; -import { Modal } from 'obsidian'; -import type { Component as SvelteComponent } from 'svelte'; -import { mount, unmount } from 'svelte'; -import ButtonTemplatesSettingComponent from 'meta-bind-obsidian/src/settings/buttonTemplateSetting/ButtonTemplatesSettingComponent.svelte'; - -export class ButtonTemplatesSettingModal extends Modal { - readonly mb: ObsMetaBind; - private component: ReturnType | undefined; - - constructor(app: App, mb: ObsMetaBind) { - super(app); - this.mb = mb; - } - - public onOpen(): void { - this.contentEl.empty(); - if (this.component) { - void unmount(this.component); - } - - this.component = mount(ButtonTemplatesSettingComponent, { - target: this.contentEl, - props: { - buttonConfigs: structuredClone(this.mb.getSettings().buttonTemplates), - modal: this, - }, - }); - } - - public onClose(): void { - this.contentEl.empty(); - if (this.component) { - void unmount(this.component); - } - } - - public save(templates: ButtonConfig[]): ErrorCollection | undefined { - const errorCollection = this.mb.buttonManager.setButtonTemplates(templates); - if (errorCollection.hasErrors()) { - return errorCollection; - } - - this.mb.updateSettings(settings => { - settings.buttonTemplates = templates; - }); - - return undefined; - } -} diff --git a/packages/obsidian/src/settings/excludedFoldersSetting/ExcludedFolderSettingModal.ts b/packages/obsidian/src/settings/excludedFoldersSetting/ExcludedFolderSettingModal.ts new file mode 100644 index 00000000..b49fb7ff --- /dev/null +++ b/packages/obsidian/src/settings/excludedFoldersSetting/ExcludedFolderSettingModal.ts @@ -0,0 +1,53 @@ +import type { App } from 'obsidian'; +import { Modal, Notice, Setting } from 'obsidian'; + +export class ExcludedFolderSettingModal extends Modal { + private readonly initialFolder: string; + private readonly onSubmit: (folder: string) => void; + private draft: string; + + constructor(app: App, folder: string | undefined, onSubmit: (folder: string) => void) { + super(app); + this.initialFolder = folder ?? ''; + this.draft = this.initialFolder; + this.onSubmit = onSubmit; + } + + onOpen(): void { + this.contentEl.empty(); + this.setTitle(this.initialFolder === '' ? 'Add excluded folder' : 'Edit excluded folder'); + + new Setting(this.contentEl).setName('Folder path').addText(cb => { + cb.setPlaceholder('path/to/folder'); + cb.setValue(this.draft); + cb.onChange(value => { + this.draft = value; + }); + }); + + this.addModalButtons(); + } + + private addModalButtons(): void { + new Setting(this.contentEl) + .addButton(cb => { + cb.setCta(); + cb.setButtonText('Save'); + cb.onClick(() => { + if (this.draft === '') { + new Notice('meta-bind | Folder path may not be empty.'); + return; + } + + this.onSubmit(this.draft); + this.close(); + }); + }) + .addButton(cb => { + cb.setButtonText('Cancel'); + cb.onClick(() => { + this.close(); + }); + }); + } +} diff --git a/packages/obsidian/src/settings/excludedFoldersSetting/ExcludedFolderSettings.ts b/packages/obsidian/src/settings/excludedFoldersSetting/ExcludedFolderSettings.ts new file mode 100644 index 00000000..8360753f --- /dev/null +++ b/packages/obsidian/src/settings/excludedFoldersSetting/ExcludedFolderSettings.ts @@ -0,0 +1,81 @@ +import type { ObsMetaBind } from 'meta-bind-obsidian/src/ObsMB'; +import { ExcludedFolderSettingModal } from 'meta-bind-obsidian/src/settings/excludedFoldersSetting/ExcludedFolderSettingModal'; +import { getListSettingGroup, updateListItems } from 'meta-bind-obsidian/src/settings/ListSettingGroup'; +import type { MetaBindSettingKey } from 'meta-bind-obsidian/src/settings/SettingsTypes'; +import type { App, Setting, SettingDefinitionItem, SettingGroupItem } from 'obsidian'; + +export class ExcludedFolderSettings { + constructor( + private readonly app: App, + private readonly mb: ObsMetaBind, + private readonly onUpdate: () => void, + ) {} + + getDefinitions(): SettingDefinitionItem[] { + const folders = this.mb.getSettings().excludedFolders; + + return [ + { + name: 'Add folder', + action: (): void => { + this.openExcludedFolderModal(undefined, folder => { + updateListItems( + this.mb.getSettings().excludedFolders, + folders => { + folders.push(folder); + }, + folders => this.applyExcludedFolders(folders), + this.onUpdate, + ); + }); + }, + }, + getListSettingGroup({ + heading: 'Folders', + emptyState: 'No excluded folders configured.', + items: folders, + renderItem: (folder, index) => this.getExcludedFolderSetting(folder, index), + applyItems: folders => this.applyExcludedFolders(folders), + onUpdate: this.onUpdate, + }), + ]; + } + + private getExcludedFolderSetting(folder: string, index: number): SettingGroupItem { + return { + name: folder || `Excluded folder ${index + 1}`, + desc: folder === '' ? 'Folder path may not be empty.' : 'Plugin behavior is disabled in this folder.', + searchable: folder !== '', + render: (setting: Setting): void => { + setting.addExtraButton(cb => { + cb.setIcon('pencil'); + cb.setTooltip('Edit folder'); + cb.onClick(() => { + this.openExcludedFolderModal(folder, newFolder => { + updateListItems( + this.mb.getSettings().excludedFolders, + folders => { + folders[index] = newFolder; + }, + folders => this.applyExcludedFolders(folders), + this.onUpdate, + ); + }); + }); + }); + }, + }; + } + + private applyExcludedFolders(folders: string[]): boolean { + this.mb.updateSettings(settings => { + settings.excludedFolders = folders; + }); + + return true; + } + + private openExcludedFolderModal(folder: string | undefined, onSubmit: (folder: string) => void): void { + new ExcludedFolderSettingModal(this.app, folder, onSubmit).open(); + } +} diff --git a/packages/obsidian/src/settings/excludedFoldersSetting/ExcludedFoldersSettingComponent.svelte b/packages/obsidian/src/settings/excludedFoldersSetting/ExcludedFoldersSettingComponent.svelte deleted file mode 100644 index 6ed0fa21..00000000 --- a/packages/obsidian/src/settings/excludedFoldersSetting/ExcludedFoldersSettingComponent.svelte +++ /dev/null @@ -1,85 +0,0 @@ - - -
- - - - - - - - - {#each excludedFolders as folder, i (i)} - - - - - {/each} - -
Folder Path
- - - -
- - - - {#if errorCollection} -
-

Some folder paths are invalid

- - -
- {/if} - - - - - -
diff --git a/packages/obsidian/src/settings/excludedFoldersSetting/ExcludedFoldersSettingModal.ts b/packages/obsidian/src/settings/excludedFoldersSetting/ExcludedFoldersSettingModal.ts deleted file mode 100644 index f0f39121..00000000 --- a/packages/obsidian/src/settings/excludedFoldersSetting/ExcludedFoldersSettingModal.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { ErrorCollection } from 'meta-bind-core/src/utils/errors/ErrorCollection'; -import type { ObsMetaBind } from 'meta-bind-obsidian/src/ObsMB'; -import type { App } from 'obsidian'; -import { Modal } from 'obsidian'; -import type { Component as SvelteComponent } from 'svelte'; -import { mount, unmount } from 'svelte'; -import ExcludedFoldersSettingComponent from 'meta-bind-obsidian/src/settings/excludedFoldersSetting/ExcludedFoldersSettingComponent.svelte'; - -export class ExcludedFoldersSettingModal extends Modal { - private readonly mb: ObsMetaBind; - private component: ReturnType | undefined; - - constructor(app: App, mb: ObsMetaBind) { - super(app); - this.mb = mb; - } - - public onOpen(): void { - this.contentEl.empty(); - if (this.component) { - void unmount(this.component); - } - - this.component = mount(ExcludedFoldersSettingComponent, { - target: this.contentEl, - props: { - excludedFolders: structuredClone(this.mb.getSettings().excludedFolders), - modal: this, - mb: this.mb, - }, - }); - } - - public onClose(): void { - this.contentEl.empty(); - if (this.component) { - void unmount(this.component); - } - } - - public save(folders: string[]): ErrorCollection | undefined { - for (const folder of folders) { - if (folder === '') { - const errorCollection = new ErrorCollection('Excluded folders'); - - errorCollection.add(new Error(`Invalid Folder Path '${folder}'. Folder path may not be empty.`)); - - return errorCollection; - } - } - - this.mb.updateSettings(settings => { - settings.excludedFolders = folders; - }); - - return undefined; - } -} diff --git a/packages/obsidian/src/settings/inputFieldTemplateSetting/InputFieldTemplateSettingComponent.svelte b/packages/obsidian/src/settings/inputFieldTemplateSetting/InputFieldTemplateSettingComponent.svelte deleted file mode 100644 index 39453042..00000000 --- a/packages/obsidian/src/settings/inputFieldTemplateSetting/InputFieldTemplateSettingComponent.svelte +++ /dev/null @@ -1,28 +0,0 @@ - - -
- - - - - -
diff --git a/packages/obsidian/src/settings/inputFieldTemplateSetting/InputFieldTemplateSettingModal.ts b/packages/obsidian/src/settings/inputFieldTemplateSetting/InputFieldTemplateSettingModal.ts new file mode 100644 index 00000000..65640cd0 --- /dev/null +++ b/packages/obsidian/src/settings/inputFieldTemplateSetting/InputFieldTemplateSettingModal.ts @@ -0,0 +1,67 @@ +import type { InputFieldTemplate } from 'meta-bind-core/src/Settings'; +import type { App } from 'obsidian'; +import { Modal, Setting } from 'obsidian'; + +export class InputFieldTemplateSettingModal extends Modal { + private readonly initialTemplate: InputFieldTemplate; + private readonly onSubmit: (template: InputFieldTemplate) => boolean | void; + private draft: InputFieldTemplate; + + constructor( + app: App, + template: InputFieldTemplate | undefined, + onSubmit: (template: InputFieldTemplate) => boolean | void, + ) { + super(app); + this.initialTemplate = structuredClone(template ?? { name: '', declaration: '' }); + this.draft = structuredClone(this.initialTemplate); + this.onSubmit = onSubmit; + } + + onOpen(): void { + this.contentEl.empty(); + this.setTitle(this.initialTemplate.name === '' ? 'Add input field template' : 'Edit input field template'); + + new Setting(this.contentEl).setName('Name').addText(cb => { + cb.setPlaceholder('template-name'); + cb.setValue(this.draft.name); + cb.onChange(value => { + this.draft.name = value; + }); + }); + + new Setting(this.contentEl) + .setName('Declaration') + .setDesc('Template declaration used after the template name.') + .addTextArea(cb => { + cb.setPlaceholder('INPUT[slider(addLabels)]'); + cb.setValue(this.draft.declaration); + cb.inputEl.addClass('mb-settings-list-modal-textarea'); + cb.onChange(value => { + this.draft.declaration = value; + }); + }); + + this.addModalButtons(); + } + + private addModalButtons(): void { + new Setting(this.contentEl) + .addButton(cb => { + cb.setCta(); + cb.setButtonText('Save'); + cb.onClick(() => { + if (this.onSubmit(structuredClone(this.draft)) === false) { + return; + } + this.close(); + }); + }) + .addButton(cb => { + cb.setButtonText('Cancel'); + cb.onClick(() => { + this.close(); + }); + }); + } +} diff --git a/packages/obsidian/src/settings/inputFieldTemplateSetting/InputFieldTemplateSettings.ts b/packages/obsidian/src/settings/inputFieldTemplateSetting/InputFieldTemplateSettings.ts new file mode 100644 index 00000000..430be857 --- /dev/null +++ b/packages/obsidian/src/settings/inputFieldTemplateSetting/InputFieldTemplateSettings.ts @@ -0,0 +1,102 @@ +import type { InputFieldTemplate } from 'meta-bind-core/src/Settings'; +import type { ObsMetaBind } from 'meta-bind-obsidian/src/ObsMB'; +import { InputFieldTemplateSettingModal } from 'meta-bind-obsidian/src/settings/inputFieldTemplateSetting/InputFieldTemplateSettingModal'; +import { getListSettingGroup, updateListItems } from 'meta-bind-obsidian/src/settings/ListSettingGroup'; +import type { MetaBindSettingKey } from 'meta-bind-obsidian/src/settings/SettingsTypes'; +import type { App, Setting, SettingDefinitionItem, SettingGroupItem } from 'obsidian'; +import { Notice } from 'obsidian'; + +export class InputFieldTemplateSettings { + constructor( + private readonly app: App, + private readonly mb: ObsMetaBind, + private readonly onUpdate: () => void, + ) {} + + getDefinitions(): SettingDefinitionItem[] { + const templates = this.mb.getSettings().inputFieldTemplates; + + return [ + { + name: 'Add template', + action: (): void => { + this.openInputFieldTemplateModal(undefined, template => { + return updateListItems( + this.mb.getSettings().inputFieldTemplates, + templates => { + templates.push(template); + }, + templates => this.applyInputFieldTemplates(templates), + this.onUpdate, + ); + }); + }, + }, + getListSettingGroup({ + heading: 'Templates', + emptyState: 'No input field templates configured.', + items: templates, + renderItem: (template, index) => this.getInputFieldTemplateSetting(template, index), + applyItems: templates => this.applyInputFieldTemplates(templates), + onUpdate: this.onUpdate, + }), + ]; + } + + private getInputFieldTemplateSetting( + template: InputFieldTemplate, + index: number, + ): SettingGroupItem { + return { + name: template.name || `Input field template ${index + 1}`, + desc: template.declaration || 'No declaration.', + searchable: true, + aliases: [template.name, template.declaration].filter(x => x !== ''), + render: (setting: Setting): void => { + setting.addExtraButton(cb => { + cb.setIcon('pencil'); + cb.setTooltip('Edit template'); + cb.onClick(() => { + this.openInputFieldTemplateModal(template, newTemplate => { + return updateListItems( + this.mb.getSettings().inputFieldTemplates, + templates => { + templates[index] = newTemplate; + }, + templates => this.applyInputFieldTemplates(templates), + this.onUpdate, + ); + }); + }); + }); + }, + }; + } + + private applyInputFieldTemplates(templates: InputFieldTemplate[]): boolean { + const previousTemplates = this.mb.getSettings().inputFieldTemplates; + const errorCollection = this.mb.inputFieldParser.parseTemplates(templates); + if (errorCollection.hasErrors()) { + const errors = errorCollection.getErrors(); + this.mb.inputFieldParser.parseTemplates(previousTemplates); + console.warn('meta-bind | failed to save input field templates', errors); + new Notice( + `meta-bind | Input field template could not be saved: ${errors[0]?.message ?? 'Unknown validation error.'}`, + ); + return false; + } + + this.mb.updateSettings(settings => { + settings.inputFieldTemplates = templates; + }); + + return true; + } + + private openInputFieldTemplateModal( + template: InputFieldTemplate | undefined, + onSubmit: (template: InputFieldTemplate) => boolean | void, + ): void { + new InputFieldTemplateSettingModal(this.app, template, onSubmit).open(); + } +} diff --git a/packages/obsidian/src/settings/inputFieldTemplateSetting/InputFieldTemplatesSettingComponent.svelte b/packages/obsidian/src/settings/inputFieldTemplateSetting/InputFieldTemplatesSettingComponent.svelte deleted file mode 100644 index ce09f937..00000000 --- a/packages/obsidian/src/settings/inputFieldTemplateSetting/InputFieldTemplatesSettingComponent.svelte +++ /dev/null @@ -1,74 +0,0 @@ - - -
-

Meta Bind Input Field Templates

- - {#each inputFieldTemplates as template} - - {/each} - - - - {#if errorCollection} -
-

Some Templates Failed to Parse

- - -
- {/if} - - - - - -
diff --git a/packages/obsidian/src/settings/inputFieldTemplateSetting/InputFieldTemplatesSettingModal.ts b/packages/obsidian/src/settings/inputFieldTemplateSetting/InputFieldTemplatesSettingModal.ts deleted file mode 100644 index 97090e80..00000000 --- a/packages/obsidian/src/settings/inputFieldTemplateSetting/InputFieldTemplatesSettingModal.ts +++ /dev/null @@ -1,53 +0,0 @@ -import type { InputFieldTemplate } from 'meta-bind-core/src/Settings'; -import type { ErrorCollection } from 'meta-bind-core/src/utils/errors/ErrorCollection'; -import type { ObsMetaBind } from 'meta-bind-obsidian/src/ObsMB'; -import type { App } from 'obsidian'; -import { Modal } from 'obsidian'; -import type { Component as SvelteComponent } from 'svelte'; -import { mount, unmount } from 'svelte'; -import InputFieldTemplatesSettingComponent from 'meta-bind-obsidian/src/settings/inputFieldTemplateSetting/InputFieldTemplatesSettingComponent.svelte'; - -export class InputFieldTemplatesSettingModal extends Modal { - readonly mb: ObsMetaBind; - private component: ReturnType | undefined; - - constructor(app: App, mb: ObsMetaBind) { - super(app); - this.mb = mb; - } - - public onOpen(): void { - this.contentEl.empty(); - if (this.component) { - void unmount(this.component); - } - - this.component = mount(InputFieldTemplatesSettingComponent, { - target: this.contentEl, - props: { - inputFieldTemplates: structuredClone(this.mb.getSettings().inputFieldTemplates), - modal: this, - }, - }); - } - - public onClose(): void { - this.contentEl.empty(); - if (this.component) { - void unmount(this.component); - } - } - - public save(templates: InputFieldTemplate[]): ErrorCollection | undefined { - const errorCollection = this.mb.inputFieldParser.parseTemplates(templates); - if (errorCollection.hasErrors()) { - return errorCollection; - } - - this.mb.updateSettings(settings => { - settings.inputFieldTemplates = templates; - }); - - return undefined; - } -} diff --git a/packages/obsidian/src/styles.css b/packages/obsidian/src/styles.css index cca20605..d06643d7 100644 --- a/packages/obsidian/src/styles.css +++ b/packages/obsidian/src/styles.css @@ -15,9 +15,9 @@ body { } /* Input Wrappers */ -.mb-input { - background-color: transparent !important; - border: none !important; +.mb-input.mb-input { + background-color: transparent; + border: none; } .mb-input-wrapper { @@ -26,11 +26,11 @@ body { } .mb-input-inline { - display: inline !important; + display: inline; } .mb-input-block { - display: block !important; + display: block; } /* View Wrappers */ @@ -54,24 +54,24 @@ div.mb-view-wrapper { display: inline; } -.mb-button { - background-color: transparent !important; - border: none !important; +.mb-button.mb-button { + background-color: transparent; + border: none; font-family: var(--font-text); color: var(--text-normal); } .mb-button-inline { - display: inline !important; + display: inline; } .mb-button-block { - display: block !important; + display: block; } .mb-button-group.mb-button-group { - background-color: transparent !important; - border: none !important; + background-color: transparent; + border: none; padding-inline: 0; & > .mb-button { @@ -136,8 +136,8 @@ div.mb-view-wrapper { .mb-slider-input { align-self: center; - margin-left: var(--mb-slider-spacing) !important; - margin-right: var(--mb-slider-spacing) !important; + margin-left: var(--mb-slider-spacing); + margin-right: var(--mb-slider-spacing); } .mb-slider-input-label { @@ -464,12 +464,6 @@ div.mb-view-wrapper { object-fit: contain; } -.mb-image-card-text { - display: block; - margin: var(--size-4-2); - margin-bottom: var(--size-4-4); -} - .mb-image-card-footer { display: flex; align-items: center; @@ -496,14 +490,6 @@ div.mb-view-wrapper { opacity: 1; } -.mb-image-suggest-input { - background: var(--background-secondary); - border-radius: var(--mb-border-radius); - border: var(--mb-border-width) solid var(--background-modifier-border); - padding: var(--size-4-2); - width: 100%; -} - .mb-image-empty { display: flex; flex-direction: column; @@ -682,41 +668,26 @@ div.mb-view-wrapper { /* Error */ .mb-error { - color: var(--text-error) !important; + color: var(--text-error); font-weight: bold; font-family: var(--font-monospace); } code.mb-error { - color: var(--text-error) !important; + color: var(--text-error); } .mb-warning { - color: var(--text-warning) !important; + color: var(--text-warning); font-weight: bold; font-family: var(--font-monospace); } code.mb-warning { - color: var(--text-warning) !important; -} - -/* Code */ -.mb-code { - color: var(--text-normal); - font-family: var(--font-monospace); + color: var(--text-warning); } /* Error Collection */ -.mb-error-collection-card { - padding: var(--size-4-2); - margin: var(--size-4-2) 0; - border-radius: var(--mb-border-radius); - border: var(--mb-border-width) solid var(--background-modifier-border); - color: var(--text-normal); - font-family: var(--font-default); -} - .mb-error-collection { display: inline-block; position: relative; @@ -759,11 +730,11 @@ code.mb-warning { } .mb-error-text { - color: var(--text-error) !important; + color: var(--text-error); } .mb-warning-text { - color: var(--text-warning) !important; + color: var(--text-warning); } /* --- Misc --- */ @@ -772,20 +743,6 @@ code.mb-warning { white-space: pre; } -.mb-excluded-folders-table-input-cell { - width: 100%; -} - -.mb-excluded-folders-table-input-cell > input { - width: 100%; -} - -.mb-textarea { - width: 100%; - height: 100px; - resize: vertical; -} - .mb-icon-wrapper { display: block; position: relative; @@ -793,10 +750,6 @@ code.mb-warning { height: 18px; } -.mb-icon-wrapper.mb-icon-wrapper-inline { - display: inline-block; -} - .mb-icon-wrapper > svg { position: absolute; top: 0; @@ -882,15 +835,17 @@ div.setting-item > div.setting-item-control.mb-vertical-control { width: 100%; } +.mb-settings-list-modal-textarea { + width: 100%; + min-height: 120px; + resize: vertical; +} + .mb-search-modal-element-description { color: var(--text-faint); } /* --- HIGHLIGHTING CLASSES --- */ -.mb-highlight-test { - color: #00bfbc; -} - .mb-highlight-ident, .cm-mb-highlight-ident { color: var(--code-normal); diff --git a/packages/publish/src/main.ts b/packages/publish/src/main.ts index 6d9ea551..741c7d4c 100644 --- a/packages/publish/src/main.ts +++ b/packages/publish/src/main.ts @@ -64,7 +64,7 @@ export class PublishMetaBind extends MetaBind { ); this.metadataManager.setDefaultSource(BindTargetStorageType.FRONTMATTER); - window.setInterval(() => this.metadataManager.cycle(), this.settings.syncInterval); + window.setInterval(() => void this.metadataManager.cycle(), this.settings.syncInterval); } onLoad(): void { diff --git a/versions.json b/versions.json index 04bd0d7a..377ecc00 100644 --- a/versions.json +++ b/versions.json @@ -47,5 +47,6 @@ "1.4.7": "1.4.0", "1.4.8": "1.4.0", "1.4.9": "1.10.0", - "1.4.10": "1.10.0" + "1.4.10": "1.10.0", + "1.4.11": "1.10.0" }