@riebeckite/plugin-icons 0.0.35 → 0.0.36

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -417,30 +417,30 @@ function readSource(source, target, manual) {
417
417
  exists: found !== void 0
418
418
  };
419
419
  }
420
- const path3 = target.path;
420
+ const path4 = target.path;
421
421
  switch (source) {
422
422
  case "icon":
423
423
  return { kind: "string", value: manual?.icon ?? "" };
424
424
  case "color":
425
425
  return { kind: "string", value: manual?.color ?? "" };
426
426
  case "name": {
427
- const name = path3.split("/").pop() ?? path3;
427
+ const name = path4.split("/").pop() ?? path4;
428
428
  return {
429
429
  kind: "string",
430
430
  value: name.replace(/\.[^.]+$/, "")
431
431
  };
432
432
  }
433
433
  case "filename":
434
- return { kind: "string", value: path3.split("/").pop() ?? path3 };
434
+ return { kind: "string", value: path4.split("/").pop() ?? path4 };
435
435
  case "extension": {
436
- const name = path3.split("/").pop() ?? path3;
436
+ const name = path4.split("/").pop() ?? path4;
437
437
  const dot = name.lastIndexOf(".");
438
438
  return { kind: "string", value: dot > 0 ? name.slice(dot + 1) : "" };
439
439
  }
440
440
  case "tree":
441
- return { kind: "string", value: path3.split("/").slice(0, -1).join("/") };
441
+ return { kind: "string", value: path4.split("/").slice(0, -1).join("/") };
442
442
  case "path":
443
- return { kind: "string", value: path3 };
443
+ return { kind: "string", value: path4 };
444
444
  case "tags":
445
445
  return { kind: "array", value: target.tags ?? [] };
446
446
  case "links":
@@ -601,15 +601,99 @@ function toBoolean(value) {
601
601
  }
602
602
 
603
603
  // src/settings.ts
604
- import { promises as fs } from "node:fs";
605
- import path from "node:path";
604
+ import { promises as fs2 } from "node:fs";
605
+ import path2 from "node:path";
606
606
  import {
607
607
  fingerprintExternalValue
608
608
  } from "@riebeckite/core";
609
+
610
+ // src/icon_packs.ts
611
+ import { promises as fs } from "node:fs";
612
+ import path from "node:path";
613
+ var MAX_SVG_BYTES = 256 * 1024;
614
+ function normalizeIconName(name) {
615
+ return name.split(/[\s_-]+/).filter(Boolean).map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join("");
616
+ }
617
+ async function loadIconPacks(root, diagnostics) {
618
+ const packs = /* @__PURE__ */ new Map();
619
+ let entries;
620
+ try {
621
+ entries = await fs.readdir(root, { withFileTypes: true });
622
+ } catch {
623
+ return packs;
624
+ }
625
+ let zipCount = 0;
626
+ for (const entry of entries) {
627
+ if (entry.isSymbolicLink()) continue;
628
+ if (entry.isFile() && entry.name.toLowerCase().endsWith(".zip")) {
629
+ zipCount += 1;
630
+ continue;
631
+ }
632
+ if (!entry.isDirectory()) continue;
633
+ const packPath = path.join(root, entry.name);
634
+ const realPack = await safeRealPath(packPath);
635
+ if (!realPack || !isWithin(root, realPack)) continue;
636
+ let files;
637
+ try {
638
+ files = await fs.readdir(realPack, { withFileTypes: true });
639
+ } catch {
640
+ continue;
641
+ }
642
+ const pack = /* @__PURE__ */ new Map();
643
+ for (const file of files) {
644
+ if (!file.isFile() || !file.name.toLowerCase().endsWith(".svg")) {
645
+ continue;
646
+ }
647
+ const filePath = path.join(realPack, file.name);
648
+ const realFile = await safeRealPath(filePath);
649
+ if (!realFile || !isWithin(root, realFile)) continue;
650
+ try {
651
+ const stat = await fs.stat(realFile);
652
+ if (stat.size > MAX_SVG_BYTES) continue;
653
+ const iconName = normalizeIconName(
654
+ file.name.slice(0, -".svg".length)
655
+ ).toLowerCase();
656
+ if (!iconName) continue;
657
+ pack.set(iconName, {
658
+ name: file.name,
659
+ filePath: realFile,
660
+ size: stat.size,
661
+ modified: stat.mtimeMs
662
+ });
663
+ } catch {
664
+ }
665
+ }
666
+ if (pack.size > 0) {
667
+ const packName = normalizeIconName(entry.name).toLowerCase();
668
+ if (packName) packs.set(packName, pack);
669
+ }
670
+ }
671
+ if (zipCount > 0) {
672
+ diagnostics.push({
673
+ code: "icons-unsupported-zip-pack",
674
+ severity: "info",
675
+ message: "Zip-based Iconize icon packs are not read; extract them into folders under the icon packs directory.",
676
+ meta: { packCount: zipCount }
677
+ });
678
+ }
679
+ return packs;
680
+ }
681
+ function isWithin(root, target) {
682
+ const relative = path.relative(path.resolve(root), path.resolve(target));
683
+ return relative === "" || !relative.startsWith("..") && !path.isAbsolute(relative);
684
+ }
685
+ async function safeRealPath(value) {
686
+ try {
687
+ return await fs.realpath(value);
688
+ } catch {
689
+ return void 0;
690
+ }
691
+ }
692
+
693
+ // src/settings.ts
609
694
  var ICONIZE_ID = "obsidian-icon-folder";
610
695
  var ICONIC_ID = "iconic";
611
696
  var MAX_SETTINGS_BYTES = 2 * 1024 * 1024;
612
- var MAX_SVG_BYTES = 256 * 1024;
613
697
  var DEFAULT_ICONIZE_SETTINGS = {
614
698
  iconPacksPath: ".obsidian/icons",
615
699
  iconColor: null,
@@ -686,9 +770,6 @@ function findIconPackFile(packs, packName, iconName) {
686
770
  if (!pack) return void 0;
687
771
  return pack.get(normalizeIconName(iconName).toLowerCase());
688
772
  }
689
- function normalizeIconName(name) {
690
- return name.split(/[\s_-]+/).filter(Boolean).map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join("");
691
- }
692
773
  function normalizeVaultPath(value) {
693
774
  const normalized = value.normalize("NFC").replace(/\\/g, "/").replace(/^\.\//, "").replace(/^\/+/, "").replace(/\/{2,}/g, "/");
694
775
  if (!normalized || normalized.includes("\0")) return void 0;
@@ -700,18 +781,18 @@ function normalizeVaultPath(value) {
700
781
  }
701
782
  async function resolveVaultRoot(options, contentDirectory) {
702
783
  if (options.vaultRoot) {
703
- const explicit = path.resolve(options.vaultRoot);
704
- const root = path.basename(explicit) === ".obsidian" ? path.dirname(explicit) : explicit;
784
+ const explicit = path2.resolve(options.vaultRoot);
785
+ const root = path2.basename(explicit) === ".obsidian" ? path2.dirname(explicit) : explicit;
705
786
  return await isDirectory(root) ? root : void 0;
706
787
  }
707
788
  const starts = [contentDirectory, process.cwd()].filter(
708
789
  (value) => typeof value === "string"
709
790
  );
710
791
  for (const start of starts) {
711
- let current = path.resolve(start);
792
+ let current = path2.resolve(start);
712
793
  for (; ; ) {
713
- if (await isDirectory(path.join(current, ".obsidian"))) return current;
714
- const parent = path.dirname(current);
794
+ if (await isDirectory(path2.join(current, ".obsidian"))) return current;
795
+ const parent = path2.dirname(current);
715
796
  if (parent === current) break;
716
797
  current = parent;
717
798
  }
@@ -723,8 +804,8 @@ function resolveVaultPrefix(options, vaultRoot, contentDirectory) {
723
804
  return normalizeVaultPath(options.vaultPrefix) ?? "";
724
805
  }
725
806
  if (!vaultRoot || !contentDirectory) return "";
726
- const relative = path.relative(vaultRoot, path.resolve(contentDirectory));
727
- if (!relative || relative.startsWith("..") || path.isAbsolute(relative)) {
807
+ const relative = path2.relative(vaultRoot, path2.resolve(contentDirectory));
808
+ if (!relative || relative.startsWith("..") || path2.isAbsolute(relative)) {
728
809
  return "";
729
810
  }
730
811
  return `${normalizeVaultPath(relative) ?? ""}/`.replace(/^\/+/, "");
@@ -732,8 +813,8 @@ function resolveVaultPrefix(options, vaultRoot, contentDirectory) {
732
813
  async function resolveDataFile(input) {
733
814
  const root = input.vaultRoot ?? input.root;
734
815
  if (input.explicit) {
735
- const resolved = path.resolve(input.root, input.explicit);
736
- if (!isWithin(root, resolved)) {
816
+ const resolved = path2.resolve(input.root, input.explicit);
817
+ if (!isWithin2(root, resolved)) {
737
818
  input.diagnostics.push({
738
819
  code: "icons-untrusted-settings-path",
739
820
  severity: "warning",
@@ -744,7 +825,7 @@ async function resolveDataFile(input) {
744
825
  }
745
826
  return await isFile(resolved) ? resolved : void 0;
746
827
  }
747
- const candidate = path.join(
828
+ const candidate = path2.join(
748
829
  root,
749
830
  ".obsidian",
750
831
  "plugins",
@@ -778,10 +859,10 @@ async function readJsonFile(filePath, source, diagnostics) {
778
859
  }
779
860
  async function readTextFile(filePath, maxBytes) {
780
861
  try {
781
- const stat = await fs.lstat(filePath);
862
+ const stat = await fs2.lstat(filePath);
782
863
  if (!stat.isFile() || stat.isSymbolicLink()) return void 0;
783
864
  if (stat.size > maxBytes) return void 0;
784
- return await fs.readFile(filePath, "utf8");
865
+ return await fs2.readFile(filePath, "utf8");
785
866
  } catch {
786
867
  return void 0;
787
868
  }
@@ -928,73 +1009,9 @@ function parseIconicRules(value) {
928
1009
  }
929
1010
  return rules;
930
1011
  }
931
- async function loadIconPacks(root, diagnostics) {
932
- const packs = /* @__PURE__ */ new Map();
933
- let entries;
934
- try {
935
- entries = await fs.readdir(root, { withFileTypes: true });
936
- } catch {
937
- return packs;
938
- }
939
- let zipCount = 0;
940
- for (const entry of entries) {
941
- if (entry.isSymbolicLink()) continue;
942
- if (entry.isFile() && entry.name.toLowerCase().endsWith(".zip")) {
943
- zipCount += 1;
944
- continue;
945
- }
946
- if (!entry.isDirectory()) continue;
947
- const packPath = path.join(root, entry.name);
948
- const realPack = await safeRealPath(packPath);
949
- if (!realPack || !isWithin(root, realPack)) continue;
950
- let files;
951
- try {
952
- files = await fs.readdir(realPack, { withFileTypes: true });
953
- } catch {
954
- continue;
955
- }
956
- const pack = /* @__PURE__ */ new Map();
957
- for (const file of files) {
958
- if (!file.isFile() || !file.name.toLowerCase().endsWith(".svg")) {
959
- continue;
960
- }
961
- const filePath = path.join(realPack, file.name);
962
- const realFile = await safeRealPath(filePath);
963
- if (!realFile || !isWithin(root, realFile)) continue;
964
- try {
965
- const stat = await fs.stat(realFile);
966
- if (stat.size > MAX_SVG_BYTES) continue;
967
- const iconName = normalizeIconName(
968
- file.name.slice(0, -".svg".length)
969
- ).toLowerCase();
970
- if (!iconName) continue;
971
- pack.set(iconName, {
972
- name: file.name,
973
- filePath: realFile,
974
- size: stat.size,
975
- modified: stat.mtimeMs
976
- });
977
- } catch {
978
- }
979
- }
980
- if (pack.size > 0) {
981
- const packName = normalizeIconName(entry.name).toLowerCase();
982
- if (packName) packs.set(packName, pack);
983
- }
984
- }
985
- if (zipCount > 0) {
986
- diagnostics.push({
987
- code: "icons-unsupported-zip-pack",
988
- severity: "info",
989
- message: "Zip-based Iconize icon packs are not read; extract them into folders under the icon packs directory.",
990
- meta: { packCount: zipCount }
991
- });
992
- }
993
- return packs;
994
- }
995
1012
  function resolvePackRoot(vaultRoot, value) {
996
- const resolved = path.resolve(vaultRoot, value);
997
- return isWithin(vaultRoot, resolved) ? resolved : void 0;
1013
+ const resolved = path2.resolve(vaultRoot, value);
1014
+ return isWithin2(vaultRoot, resolved) ? resolved : void 0;
998
1015
  }
999
1016
  function isLucidePackType(value) {
1000
1017
  return value === "none" || value === "custom" || value === "native";
@@ -1005,13 +1022,13 @@ function nonEmptyString(value) {
1005
1022
  function isRecord(value) {
1006
1023
  return typeof value === "object" && value !== null && !Array.isArray(value);
1007
1024
  }
1008
- function isWithin(root, target) {
1009
- const relative = path.relative(path.resolve(root), path.resolve(target));
1010
- return relative === "" || !relative.startsWith("..") && !path.isAbsolute(relative);
1025
+ function isWithin2(root, target) {
1026
+ const relative = path2.relative(path2.resolve(root), path2.resolve(target));
1027
+ return relative === "" || !relative.startsWith("..") && !path2.isAbsolute(relative);
1011
1028
  }
1012
1029
  async function isDirectory(value) {
1013
1030
  try {
1014
- const stat = await fs.lstat(value);
1031
+ const stat = await fs2.lstat(value);
1015
1032
  return stat.isDirectory() && !stat.isSymbolicLink();
1016
1033
  } catch {
1017
1034
  return false;
@@ -1019,19 +1036,12 @@ async function isDirectory(value) {
1019
1036
  }
1020
1037
  async function isFile(value) {
1021
1038
  try {
1022
- const stat = await fs.lstat(value);
1039
+ const stat = await fs2.lstat(value);
1023
1040
  return stat.isFile() && !stat.isSymbolicLink();
1024
1041
  } catch {
1025
1042
  return false;
1026
1043
  }
1027
1044
  }
1028
- async function safeRealPath(value) {
1029
- try {
1030
- return await fs.realpath(value);
1031
- } catch {
1032
- return void 0;
1033
- }
1034
- }
1035
1045
 
1036
1046
  // src/iconize.ts
1037
1047
  function resolveIconize(data, target, options) {
@@ -1101,7 +1111,7 @@ function matchesRule2(pattern, value) {
1101
1111
  // src/render.ts
1102
1112
  import { readFileSync } from "node:fs";
1103
1113
  import { createRequire } from "node:module";
1104
- import path2 from "node:path";
1114
+ import path3 from "node:path";
1105
1115
  import {
1106
1116
  escapeHtml,
1107
1117
  escapeHtmlAttribute
@@ -1220,7 +1230,7 @@ var IconRenderer = class {
1220
1230
  const name = reference.slice("lucide:".length);
1221
1231
  if (/^[a-z0-9-]+$/.test(name) && this.#lucideDirectory) {
1222
1232
  html = renderSvg(
1223
- readSvg(path2.join(this.#lucideDirectory, `${name}.svg`))
1233
+ readSvg(path3.join(this.#lucideDirectory, `${name}.svg`))
1224
1234
  );
1225
1235
  }
1226
1236
  } else if (reference.startsWith("text:")) {
@@ -1254,17 +1264,17 @@ function resolveLucideDirectory() {
1254
1264
  try {
1255
1265
  const require2 = createRequire(import.meta.url);
1256
1266
  try {
1257
- return path2.join(
1258
- path2.dirname(require2.resolve("lucide-static/package.json")),
1267
+ return path3.join(
1268
+ path3.dirname(require2.resolve("lucide-static/package.json")),
1259
1269
  "icons"
1260
1270
  );
1261
1271
  } catch {
1262
- let current = path2.dirname(require2.resolve("lucide-static"));
1272
+ let current = path3.dirname(require2.resolve("lucide-static"));
1263
1273
  for (; ; ) {
1264
- if (path2.basename(current) === "lucide-static") {
1265
- return path2.join(current, "icons");
1274
+ if (path3.basename(current) === "lucide-static") {
1275
+ return path3.join(current, "icons");
1266
1276
  }
1267
- const parent = path2.dirname(current);
1277
+ const parent = path3.dirname(current);
1268
1278
  if (parent === current) return void 0;
1269
1279
  current = parent;
1270
1280
  }
@@ -0,0 +1,15 @@
1
+ export type IconDiagnostic = {
2
+ readonly code: string;
3
+ readonly severity: "info" | "warning";
4
+ readonly message: string;
5
+ readonly meta?: Readonly<Record<string, unknown>>;
6
+ };
7
+ export type IconPackFile = {
8
+ readonly name: string;
9
+ readonly filePath: string;
10
+ readonly size: number;
11
+ readonly modified: number;
12
+ };
13
+ export type IconPacks = ReadonlyMap<string, ReadonlyMap<string, IconPackFile>>;
14
+ export declare function normalizeIconName(name: string): string;
15
+ export declare function loadIconPacks(root: string, diagnostics: IconDiagnostic[]): Promise<IconPacks>;
@@ -1,18 +1,8 @@
1
1
  import { type ResolvedRiebeckiteConfig } from "@riebeckite/core";
2
+ import { type IconDiagnostic, type IconPackFile, type IconPacks } from "./icon_packs.js";
2
3
  import type { IconicData, IconizeData, ResolvedIconsOptions } from "./types.js";
3
- type IconDiagnostic = {
4
- readonly code: string;
5
- readonly severity: "info" | "warning";
6
- readonly message: string;
7
- readonly meta?: Readonly<Record<string, unknown>>;
8
- };
9
- type IconPackFile = {
10
- readonly name: string;
11
- readonly filePath: string;
12
- readonly size: number;
13
- readonly modified: number;
14
- };
15
- export type IconPacks = ReadonlyMap<string, ReadonlyMap<string, IconPackFile>>;
4
+ export type { IconPacks } from "./icon_packs.js";
5
+ export { normalizeIconName } from "./icon_packs.js";
16
6
  export type LoadedIconsSettings = {
17
7
  readonly iconize?: IconizeData;
18
8
  readonly iconic?: IconicData;
@@ -24,6 +14,4 @@ export type LoadedIconsSettings = {
24
14
  };
25
15
  export declare function loadIconsSettings(options: ResolvedIconsOptions, config: ResolvedRiebeckiteConfig | undefined): Promise<LoadedIconsSettings>;
26
16
  export declare function findIconPackFile(packs: IconPacks, packName: string, iconName: string): IconPackFile | undefined;
27
- export declare function normalizeIconName(name: string): string;
28
17
  export declare function normalizeVaultPath(value: string): string | undefined;
29
- export {};
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "@riebeckite/plugin-icons",
3
- "version": "0.0.35",
3
+ "version": "0.0.36",
4
4
  "license": "Apache-2.0",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
7
7
  "dependencies": {
8
- "@riebeckite/core": "0.0.35",
8
+ "@riebeckite/core": "0.0.36",
9
9
  "@types/mdast": "^4.0.4",
10
10
  "lucide-static": "^1.61.0",
11
11
  "sanitize-html": "^2.18.1"