@valkyrianlabs/payload-markdown 1.3.4 → 1.4.0

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.
Files changed (99) hide show
  1. package/README.md +63 -14
  2. package/dist/components/MarkdownRenderer/index.css +150 -0
  3. package/dist/components/MarkdownRenderer/index.scss +158 -0
  4. package/dist/core/plugins/rehypeResolveIcons.d.ts +4 -0
  5. package/dist/core/plugins/rehypeResolveIcons.js +27 -0
  6. package/dist/core/plugins/rehypeResolveIcons.js.map +1 -0
  7. package/dist/core/plugins/remarkButtonDirectives.d.ts +4 -0
  8. package/dist/core/plugins/remarkButtonDirectives.js +237 -0
  9. package/dist/core/plugins/remarkButtonDirectives.js.map +1 -0
  10. package/dist/core/plugins/remarkCompileLayouts.js +6 -5
  11. package/dist/core/plugins/remarkCompileLayouts.js.map +1 -1
  12. package/dist/core/plugins/remarkLayoutDirectives.js +17 -7
  13. package/dist/core/plugins/remarkLayoutDirectives.js.map +1 -1
  14. package/dist/core/plugins/remarkLiftLayoutDirectives.js +42 -4
  15. package/dist/core/plugins/remarkLiftLayoutDirectives.js.map +1 -1
  16. package/dist/core/renderMarkdown.js +27 -2
  17. package/dist/core/renderMarkdown.js.map +1 -1
  18. package/dist/directives/attributeDiagnostics.d.ts +2 -0
  19. package/dist/directives/attributeDiagnostics.js +35 -0
  20. package/dist/directives/attributeDiagnostics.js.map +1 -0
  21. package/dist/directives/attributes.d.ts +8 -0
  22. package/dist/directives/attributes.js +56 -5
  23. package/dist/directives/attributes.js.map +1 -1
  24. package/dist/directives/buttonSyntax.d.ts +7 -0
  25. package/dist/directives/buttonSyntax.js +26 -0
  26. package/dist/directives/buttonSyntax.js.map +1 -0
  27. package/dist/directives/closeLabels.d.ts +8 -0
  28. package/dist/directives/closeLabels.js +76 -0
  29. package/dist/directives/closeLabels.js.map +1 -0
  30. package/dist/directives/definitions/button.d.ts +15 -0
  31. package/dist/directives/definitions/button.js +96 -0
  32. package/dist/directives/definitions/button.js.map +1 -0
  33. package/dist/directives/definitions/buttons.d.ts +8 -0
  34. package/dist/directives/definitions/buttons.js +82 -0
  35. package/dist/directives/definitions/buttons.js.map +1 -0
  36. package/dist/directives/definitions/callout.js +20 -9
  37. package/dist/directives/definitions/callout.js.map +1 -1
  38. package/dist/directives/definitions/card.d.ts +4 -0
  39. package/dist/directives/definitions/card.js +90 -9
  40. package/dist/directives/definitions/card.js.map +1 -1
  41. package/dist/directives/definitions/cards.d.ts +4 -0
  42. package/dist/directives/definitions/cards.js +119 -4
  43. package/dist/directives/definitions/cards.js.map +1 -1
  44. package/dist/directives/definitions/details.js +4 -3
  45. package/dist/directives/definitions/details.js.map +1 -1
  46. package/dist/directives/definitions/tab.d.ts +1 -0
  47. package/dist/directives/definitions/tab.js +10 -3
  48. package/dist/directives/definitions/tab.js.map +1 -1
  49. package/dist/directives/definitions/tabs.js +3 -3
  50. package/dist/directives/definitions/tabs.js.map +1 -1
  51. package/dist/directives/definitions/toc.js +4 -3
  52. package/dist/directives/definitions/toc.js.map +1 -1
  53. package/dist/directives/diagnostics.js +97 -7
  54. package/dist/directives/diagnostics.js.map +1 -1
  55. package/dist/directives/iconPlaceholder.d.ts +12 -0
  56. package/dist/directives/iconPlaceholder.js +19 -0
  57. package/dist/directives/iconPlaceholder.js.map +1 -0
  58. package/dist/directives/labels.d.ts +3 -0
  59. package/dist/directives/labels.js +12 -0
  60. package/dist/directives/labels.js.map +1 -0
  61. package/dist/directives/registry.d.ts +1 -1
  62. package/dist/directives/registry.js +46 -6
  63. package/dist/directives/registry.js.map +1 -1
  64. package/dist/directives/renderData.d.ts +2 -2
  65. package/dist/directives/renderData.js.map +1 -1
  66. package/dist/directives/types.d.ts +6 -4
  67. package/dist/directives/types.js.map +1 -1
  68. package/dist/editor/MarkdownCodeMirror/Component.client.js +2 -0
  69. package/dist/editor/MarkdownCodeMirror/Component.client.js.map +1 -1
  70. package/dist/editor/directives/closeLabels.d.ts +2 -0
  71. package/dist/editor/directives/closeLabels.js +75 -0
  72. package/dist/editor/directives/closeLabels.js.map +1 -0
  73. package/dist/editor/directives/completions.js +49 -7
  74. package/dist/editor/directives/completions.js.map +1 -1
  75. package/dist/editor/themes/payload.js +197 -9
  76. package/dist/editor/themes/payload.js.map +1 -1
  77. package/dist/exports/advanced.d.ts +1 -0
  78. package/dist/exports/advanced.js +1 -0
  79. package/dist/exports/advanced.js.map +1 -1
  80. package/dist/icons/generateRegistry.d.ts +8 -0
  81. package/dist/icons/generateRegistry.js +36 -0
  82. package/dist/icons/generateRegistry.js.map +1 -0
  83. package/dist/icons/refs.d.ts +10 -0
  84. package/dist/icons/refs.js +42 -0
  85. package/dist/icons/refs.js.map +1 -0
  86. package/dist/icons/resolve.d.ts +9 -0
  87. package/dist/icons/resolve.js +95 -0
  88. package/dist/icons/resolve.js.map +1 -0
  89. package/dist/index.d.ts +1 -1
  90. package/dist/index.js.map +1 -1
  91. package/dist/runtime/index.d.ts +1 -0
  92. package/dist/runtime/index.js +8 -1
  93. package/dist/runtime/index.js.map +1 -1
  94. package/dist/types/core.d.ts +9 -0
  95. package/dist/types/core.js.map +1 -1
  96. package/dist/types/mdast.d.js.map +1 -1
  97. package/dist/types.d.ts +5 -1
  98. package/dist/types.js.map +1 -1
  99. package/package.json +1 -1
@@ -0,0 +1,36 @@
1
+ import path from 'node:path';
2
+ import { hasUnsafeIconPathSegments } from './refs.js';
3
+ function toPascalCase(value) {
4
+ const normalized = value.replace(/\.svg$/i, '').split(/[^a-z0-9]+/i).filter(Boolean).map((part)=>`${part.charAt(0).toUpperCase()}${part.slice(1)}`).join('');
5
+ return normalized || 'Icon';
6
+ }
7
+ export function createPayloadMarkdownIconRegistrySource(entries) {
8
+ const imports = entries.map((entry, index)=>{
9
+ return `import ${toPascalCase(entry.key)}${index} from '${entry.importPath}'`;
10
+ });
11
+ const values = entries.map((entry, index)=>{
12
+ return ` '${entry.key}': ${toPascalCase(entry.key)}${index},`;
13
+ });
14
+ return [
15
+ ...imports,
16
+ '',
17
+ 'export const payloadMarkdownIcons = {',
18
+ ...values,
19
+ '} as const',
20
+ '',
21
+ 'export type PayloadMarkdownIconName = keyof typeof payloadMarkdownIcons',
22
+ ''
23
+ ].join('\n');
24
+ }
25
+ export function createPayloadMarkdownIconRegistryEntry(config, packAlias, iconPath) {
26
+ const pack = config.packs.find((entry)=>entry.alias === packAlias);
27
+ if (!pack) return undefined;
28
+ const normalizedIconPath = iconPath.replace(/\.svg$/i, '');
29
+ if (hasUnsafeIconPathSegments(normalizedIconPath)) return undefined;
30
+ return {
31
+ importPath: path.posix.join(config.baseDir, pack.path, `${normalizedIconPath}.svg`),
32
+ key: `${packAlias}/${normalizedIconPath}`
33
+ };
34
+ }
35
+
36
+ //# sourceMappingURL=generateRegistry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/icons/generateRegistry.ts"],"sourcesContent":["import path from 'node:path'\n\nimport type { PayloadMarkdownIconsConfig } from '../types/core.js'\n\nimport { hasUnsafeIconPathSegments } from './refs.js'\n\ntype IconRegistryEntry = {\n importPath: string\n key: string\n}\n\nfunction toPascalCase(value: string): string {\n const normalized = value\n .replace(/\\.svg$/i, '')\n .split(/[^a-z0-9]+/i)\n .filter(Boolean)\n .map((part) => `${part.charAt(0).toUpperCase()}${part.slice(1)}`)\n .join('')\n\n return normalized || 'Icon'\n}\n\nexport function createPayloadMarkdownIconRegistrySource(entries: IconRegistryEntry[]): string {\n const imports = entries.map((entry, index) => {\n return `import ${toPascalCase(entry.key)}${index} from '${entry.importPath}'`\n })\n const values = entries.map((entry, index) => {\n return ` '${entry.key}': ${toPascalCase(entry.key)}${index},`\n })\n\n return [\n ...imports,\n '',\n 'export const payloadMarkdownIcons = {',\n ...values,\n '} as const',\n '',\n 'export type PayloadMarkdownIconName = keyof typeof payloadMarkdownIcons',\n '',\n ].join('\\n')\n}\n\nexport function createPayloadMarkdownIconRegistryEntry(\n config: PayloadMarkdownIconsConfig,\n packAlias: string,\n iconPath: string,\n): IconRegistryEntry | undefined {\n const pack = config.packs.find((entry) => entry.alias === packAlias)\n if (!pack) return undefined\n\n const normalizedIconPath = iconPath.replace(/\\.svg$/i, '')\n if (hasUnsafeIconPathSegments(normalizedIconPath)) return undefined\n\n return {\n importPath: path.posix.join(config.baseDir, pack.path, `${normalizedIconPath}.svg`),\n key: `${packAlias}/${normalizedIconPath}`,\n }\n}\n"],"names":["path","hasUnsafeIconPathSegments","toPascalCase","value","normalized","replace","split","filter","Boolean","map","part","charAt","toUpperCase","slice","join","createPayloadMarkdownIconRegistrySource","entries","imports","entry","index","key","importPath","values","createPayloadMarkdownIconRegistryEntry","config","packAlias","iconPath","pack","packs","find","alias","undefined","normalizedIconPath","posix","baseDir"],"mappings":"AAAA,OAAOA,UAAU,YAAW;AAI5B,SAASC,yBAAyB,QAAQ,YAAW;AAOrD,SAASC,aAAaC,KAAa;IACjC,MAAMC,aAAaD,MAChBE,OAAO,CAAC,WAAW,IACnBC,KAAK,CAAC,eACNC,MAAM,CAACC,SACPC,GAAG,CAAC,CAACC,OAAS,GAAGA,KAAKC,MAAM,CAAC,GAAGC,WAAW,KAAKF,KAAKG,KAAK,CAAC,IAAI,EAC/DC,IAAI,CAAC;IAER,OAAOV,cAAc;AACvB;AAEA,OAAO,SAASW,wCAAwCC,OAA4B;IAClF,MAAMC,UAAUD,QAAQP,GAAG,CAAC,CAACS,OAAOC;QAClC,OAAO,CAAC,OAAO,EAAEjB,aAAagB,MAAME,GAAG,IAAID,MAAM,OAAO,EAAED,MAAMG,UAAU,CAAC,CAAC,CAAC;IAC/E;IACA,MAAMC,SAASN,QAAQP,GAAG,CAAC,CAACS,OAAOC;QACjC,OAAO,CAAC,GAAG,EAAED,MAAME,GAAG,CAAC,GAAG,EAAElB,aAAagB,MAAME,GAAG,IAAID,MAAM,CAAC,CAAC;IAChE;IAEA,OAAO;WACFF;QACH;QACA;WACGK;QACH;QACA;QACA;QACA;KACD,CAACR,IAAI,CAAC;AACT;AAEA,OAAO,SAASS,uCACdC,MAAkC,EAClCC,SAAiB,EACjBC,QAAgB;IAEhB,MAAMC,OAAOH,OAAOI,KAAK,CAACC,IAAI,CAAC,CAACX,QAAUA,MAAMY,KAAK,KAAKL;IAC1D,IAAI,CAACE,MAAM,OAAOI;IAElB,MAAMC,qBAAqBN,SAASrB,OAAO,CAAC,WAAW;IACvD,IAAIJ,0BAA0B+B,qBAAqB,OAAOD;IAE1D,OAAO;QACLV,YAAYrB,KAAKiC,KAAK,CAACnB,IAAI,CAACU,OAAOU,OAAO,EAAEP,KAAK3B,IAAI,EAAE,GAAGgC,mBAAmB,IAAI,CAAC;QAClFZ,KAAK,GAAGK,UAAU,CAAC,EAAEO,oBAAoB;IAC3C;AACF"}
@@ -0,0 +1,10 @@
1
+ export type NormalizedIconRef = {
2
+ iconPath: string;
3
+ key: string;
4
+ packAlias: string;
5
+ };
6
+ export declare function hasUnsafeIconPathSegments(value: string): boolean;
7
+ export declare function normalizePayloadMarkdownIconRef(ref: string): {
8
+ icon?: NormalizedIconRef;
9
+ warning?: string;
10
+ };
@@ -0,0 +1,42 @@
1
+ export function hasUnsafeIconPathSegments(value) {
2
+ if (!value.trim()) return true;
3
+ if (value.includes('\\')) return true;
4
+ if (/^[a-z]:/i.test(value)) return true;
5
+ if (value.startsWith('/')) return true;
6
+ return value.split('/').some((segment)=>!segment || segment === '..');
7
+ }
8
+ function getExtension(value) {
9
+ const basename = value.split('/').pop() ?? '';
10
+ const dotIndex = basename.lastIndexOf('.');
11
+ return dotIndex >= 0 ? basename.slice(dotIndex) : '';
12
+ }
13
+ export function normalizePayloadMarkdownIconRef(ref) {
14
+ const trimmed = ref.trim();
15
+ if (!trimmed.startsWith('@')) return {
16
+ warning: `Malformed icon ref "${ref}". Expected "@pack/name".`
17
+ };
18
+ const body = trimmed.slice(1);
19
+ const slashIndex = body.indexOf('/');
20
+ if (slashIndex <= 0 || slashIndex === body.length - 1) return {
21
+ warning: `Malformed icon ref "${ref}". Expected "@pack/name".`
22
+ };
23
+ const packAlias = body.slice(0, slashIndex);
24
+ const rawIconPath = body.slice(slashIndex + 1);
25
+ const extension = getExtension(rawIconPath);
26
+ if (extension && extension !== '.svg') return {
27
+ warning: `Icon ref "${ref}" must target an SVG file.`
28
+ };
29
+ const iconPath = extension === '.svg' ? rawIconPath.slice(0, -4) : rawIconPath;
30
+ if (hasUnsafeIconPathSegments(iconPath)) return {
31
+ warning: `Malformed icon ref "${ref}". Icon paths must be relative SVG paths.`
32
+ };
33
+ return {
34
+ icon: {
35
+ iconPath,
36
+ key: `${packAlias}/${iconPath}`,
37
+ packAlias
38
+ }
39
+ };
40
+ }
41
+
42
+ //# sourceMappingURL=refs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/icons/refs.ts"],"sourcesContent":["export type NormalizedIconRef = {\n iconPath: string\n key: string\n packAlias: string\n}\n\nexport function hasUnsafeIconPathSegments(value: string): boolean {\n if (!value.trim()) return true\n if (value.includes('\\\\')) return true\n if (/^[a-z]:/i.test(value)) return true\n if (value.startsWith('/')) return true\n\n return value.split('/').some((segment) => !segment || segment === '..')\n}\n\nfunction getExtension(value: string): string {\n const basename = value.split('/').pop() ?? ''\n const dotIndex = basename.lastIndexOf('.')\n\n return dotIndex >= 0 ? basename.slice(dotIndex) : ''\n}\n\nexport function normalizePayloadMarkdownIconRef(ref: string): {\n icon?: NormalizedIconRef\n warning?: string\n} {\n const trimmed = ref.trim()\n\n if (!trimmed.startsWith('@'))\n return { warning: `Malformed icon ref \"${ref}\". Expected \"@pack/name\".` }\n\n const body = trimmed.slice(1)\n const slashIndex = body.indexOf('/')\n\n if (slashIndex <= 0 || slashIndex === body.length - 1)\n return { warning: `Malformed icon ref \"${ref}\". Expected \"@pack/name\".` }\n\n const packAlias = body.slice(0, slashIndex)\n const rawIconPath = body.slice(slashIndex + 1)\n const extension = getExtension(rawIconPath)\n\n if (extension && extension !== '.svg')\n return { warning: `Icon ref \"${ref}\" must target an SVG file.` }\n\n const iconPath = extension === '.svg' ? rawIconPath.slice(0, -4) : rawIconPath\n\n if (hasUnsafeIconPathSegments(iconPath))\n return { warning: `Malformed icon ref \"${ref}\". Icon paths must be relative SVG paths.` }\n\n return {\n icon: {\n iconPath,\n key: `${packAlias}/${iconPath}`,\n packAlias,\n },\n }\n}\n"],"names":["hasUnsafeIconPathSegments","value","trim","includes","test","startsWith","split","some","segment","getExtension","basename","pop","dotIndex","lastIndexOf","slice","normalizePayloadMarkdownIconRef","ref","trimmed","warning","body","slashIndex","indexOf","length","packAlias","rawIconPath","extension","iconPath","icon","key"],"mappings":"AAMA,OAAO,SAASA,0BAA0BC,KAAa;IACrD,IAAI,CAACA,MAAMC,IAAI,IAAI,OAAO;IAC1B,IAAID,MAAME,QAAQ,CAAC,OAAO,OAAO;IACjC,IAAI,WAAWC,IAAI,CAACH,QAAQ,OAAO;IACnC,IAAIA,MAAMI,UAAU,CAAC,MAAM,OAAO;IAElC,OAAOJ,MAAMK,KAAK,CAAC,KAAKC,IAAI,CAAC,CAACC,UAAY,CAACA,WAAWA,YAAY;AACpE;AAEA,SAASC,aAAaR,KAAa;IACjC,MAAMS,WAAWT,MAAMK,KAAK,CAAC,KAAKK,GAAG,MAAM;IAC3C,MAAMC,WAAWF,SAASG,WAAW,CAAC;IAEtC,OAAOD,YAAY,IAAIF,SAASI,KAAK,CAACF,YAAY;AACpD;AAEA,OAAO,SAASG,gCAAgCC,GAAW;IAIzD,MAAMC,UAAUD,IAAId,IAAI;IAExB,IAAI,CAACe,QAAQZ,UAAU,CAAC,MACtB,OAAO;QAAEa,SAAS,CAAC,oBAAoB,EAAEF,IAAI,yBAAyB,CAAC;IAAC;IAE1E,MAAMG,OAAOF,QAAQH,KAAK,CAAC;IAC3B,MAAMM,aAAaD,KAAKE,OAAO,CAAC;IAEhC,IAAID,cAAc,KAAKA,eAAeD,KAAKG,MAAM,GAAG,GAClD,OAAO;QAAEJ,SAAS,CAAC,oBAAoB,EAAEF,IAAI,yBAAyB,CAAC;IAAC;IAE1E,MAAMO,YAAYJ,KAAKL,KAAK,CAAC,GAAGM;IAChC,MAAMI,cAAcL,KAAKL,KAAK,CAACM,aAAa;IAC5C,MAAMK,YAAYhB,aAAae;IAE/B,IAAIC,aAAaA,cAAc,QAC7B,OAAO;QAAEP,SAAS,CAAC,UAAU,EAAEF,IAAI,0BAA0B,CAAC;IAAC;IAEjE,MAAMU,WAAWD,cAAc,SAASD,YAAYV,KAAK,CAAC,GAAG,CAAC,KAAKU;IAEnE,IAAIxB,0BAA0B0B,WAC5B,OAAO;QAAER,SAAS,CAAC,oBAAoB,EAAEF,IAAI,yCAAyC,CAAC;IAAC;IAE1F,OAAO;QACLW,MAAM;YACJD;YACAE,KAAK,GAAGL,UAAU,CAAC,EAAEG,UAAU;YAC/BH;QACF;IACF;AACF"}
@@ -0,0 +1,9 @@
1
+ import type { RootContent } from 'hast';
2
+ import type { PayloadMarkdownIconsConfig } from '../types/core.js';
3
+ export type PayloadMarkdownIconResolution = {
4
+ iconKey?: string;
5
+ nodes: RootContent[];
6
+ warnings: string[];
7
+ };
8
+ export declare function validatePayloadMarkdownIconsConfig(config: PayloadMarkdownIconsConfig | undefined): string[];
9
+ export declare function resolvePayloadMarkdownIcon(ref: string | undefined, config: PayloadMarkdownIconsConfig | undefined, className: string): PayloadMarkdownIconResolution;
@@ -0,0 +1,95 @@
1
+ import { fromHtml } from 'hast-util-from-html';
2
+ import fs from 'node:fs';
3
+ import path from 'node:path';
4
+ import { hasUnsafeIconPathSegments, normalizePayloadMarkdownIconRef } from './refs.js';
5
+ function isWithin(parent, child) {
6
+ const relative = path.relative(parent, child);
7
+ return Boolean(relative) && !relative.startsWith('..') && !path.isAbsolute(relative);
8
+ }
9
+ export function validatePayloadMarkdownIconsConfig(config) {
10
+ if (!config) return [];
11
+ const warnings = [];
12
+ const seenAliases = new Set();
13
+ if (!config.baseDir?.trim()) warnings.push('Icon config baseDir must not be empty.');
14
+ for (const pack of config.packs ?? []){
15
+ const alias = pack.alias.trim();
16
+ const packPath = pack.path.trim();
17
+ if (!alias) {
18
+ warnings.push('Icon pack aliases must not be empty.');
19
+ continue;
20
+ }
21
+ if (seenAliases.has(alias)) warnings.push(`Duplicate icon pack alias "${alias}".`);
22
+ seenAliases.add(alias);
23
+ if (!packPath) warnings.push(`Icon pack "${alias}" path must not be empty.`);
24
+ else if (hasUnsafeIconPathSegments(packPath)) warnings.push(`Icon pack "${alias}" path must be a safe relative path.`);
25
+ }
26
+ return warnings;
27
+ }
28
+ function sanitizeSvg(value) {
29
+ return value.replace(/<\?xml[\s\S]*?\?>/gi, '').replace(/<!doctype[\s\S]*?>/gi, '').replace(/<!--[\s\S]*?-->/g, '').replace(/<script\b[\s\S]*?<\/script>/gi, '').replace(/<foreignObject\b[\s\S]*?<\/foreignObject>/gi, '').replace(/\son[a-z]+\s*=\s*(?:".*?"|'.*?'|[^\s>]+)/gi, '').replace(/\s(?:href|xlink:href)\s*=\s*(['"])\s*javascript:[\s\S]*?\1/gi, '');
30
+ }
31
+ function addSvgRuntimeAttributes(svg, className) {
32
+ return svg.replace(/<svg\b([^>]*)>/i, (_match, attributes)=>{
33
+ const nextAttributes = attributes.replace(/\sclass=(["'])(.*?)\1/i, (_classMatch, quote, value)=>{
34
+ return ` class=${quote}${value} ${className}${quote}`;
35
+ });
36
+ const hasClass = /\sclass=/.test(attributes);
37
+ return `<svg${hasClass ? nextAttributes : `${nextAttributes} class="${className}"`} aria-hidden="true" focusable="false">`;
38
+ });
39
+ }
40
+ function parseSvgFragment(svg) {
41
+ const root = fromHtml(svg, {
42
+ fragment: true
43
+ });
44
+ return root.children.filter((node)=>node.type === 'element');
45
+ }
46
+ export function resolvePayloadMarkdownIcon(ref, config, className) {
47
+ if (!ref) return {
48
+ nodes: [],
49
+ warnings: []
50
+ };
51
+ const normalized = normalizePayloadMarkdownIconRef(ref);
52
+ if (normalized.warning) return {
53
+ nodes: [],
54
+ warnings: [
55
+ normalized.warning
56
+ ]
57
+ };
58
+ if (!normalized.icon) return {
59
+ nodes: [],
60
+ warnings: []
61
+ };
62
+ const pack = config?.packs?.find((entry)=>entry.alias === normalized.icon?.packAlias);
63
+ if (!pack) return {
64
+ iconKey: normalized.icon.key,
65
+ nodes: [],
66
+ warnings: [
67
+ `Unknown icon pack "${normalized.icon.packAlias}".`
68
+ ]
69
+ };
70
+ const baseDir = path.resolve(process.cwd(), config?.baseDir ?? '');
71
+ const packRoot = path.resolve(baseDir, pack.path);
72
+ const iconFile = path.resolve(packRoot, `${normalized.icon.iconPath}.svg`);
73
+ if (!isWithin(packRoot, iconFile)) return {
74
+ iconKey: normalized.icon.key,
75
+ nodes: [],
76
+ warnings: [
77
+ `Malformed icon ref "${ref}". Icon paths must stay within their icon pack.`
78
+ ]
79
+ };
80
+ if (!fs.existsSync(iconFile)) return {
81
+ iconKey: normalized.icon.key,
82
+ nodes: [],
83
+ warnings: [
84
+ `Unknown icon "${normalized.icon.key}".`
85
+ ]
86
+ };
87
+ const svg = addSvgRuntimeAttributes(sanitizeSvg(fs.readFileSync(iconFile, 'utf8')), className);
88
+ return {
89
+ iconKey: normalized.icon.key,
90
+ nodes: parseSvgFragment(svg),
91
+ warnings: []
92
+ };
93
+ }
94
+
95
+ //# sourceMappingURL=resolve.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/icons/resolve.ts"],"sourcesContent":["import type { Element, RootContent } from 'hast'\n\nimport { fromHtml } from 'hast-util-from-html'\nimport fs from 'node:fs'\nimport path from 'node:path'\n\nimport type { PayloadMarkdownIconsConfig } from '../types/core.js'\n\nimport {\n hasUnsafeIconPathSegments,\n normalizePayloadMarkdownIconRef,\n} from './refs.js'\n\nexport type PayloadMarkdownIconResolution = {\n iconKey?: string\n nodes: RootContent[]\n warnings: string[]\n}\n\nfunction isWithin(parent: string, child: string): boolean {\n const relative = path.relative(parent, child)\n\n return Boolean(relative) && !relative.startsWith('..') && !path.isAbsolute(relative)\n}\n\nexport function validatePayloadMarkdownIconsConfig(\n config: PayloadMarkdownIconsConfig | undefined,\n): string[] {\n if (!config) return []\n\n const warnings: string[] = []\n const seenAliases = new Set<string>()\n\n if (!config.baseDir?.trim()) warnings.push('Icon config baseDir must not be empty.')\n\n for (const pack of config.packs ?? []) {\n const alias = pack.alias.trim()\n const packPath = pack.path.trim()\n\n if (!alias) {\n warnings.push('Icon pack aliases must not be empty.')\n continue\n }\n\n if (seenAliases.has(alias)) warnings.push(`Duplicate icon pack alias \"${alias}\".`)\n seenAliases.add(alias)\n\n if (!packPath) warnings.push(`Icon pack \"${alias}\" path must not be empty.`)\n else if (hasUnsafeIconPathSegments(packPath))\n warnings.push(`Icon pack \"${alias}\" path must be a safe relative path.`)\n }\n\n return warnings\n}\n\nfunction sanitizeSvg(value: string): string {\n return value\n .replace(/<\\?xml[\\s\\S]*?\\?>/gi, '')\n .replace(/<!doctype[\\s\\S]*?>/gi, '')\n .replace(/<!--[\\s\\S]*?-->/g, '')\n .replace(/<script\\b[\\s\\S]*?<\\/script>/gi, '')\n .replace(/<foreignObject\\b[\\s\\S]*?<\\/foreignObject>/gi, '')\n .replace(/\\son[a-z]+\\s*=\\s*(?:\".*?\"|'.*?'|[^\\s>]+)/gi, '')\n .replace(/\\s(?:href|xlink:href)\\s*=\\s*(['\"])\\s*javascript:[\\s\\S]*?\\1/gi, '')\n}\n\nfunction addSvgRuntimeAttributes(svg: string, className: string): string {\n return svg.replace(/<svg\\b([^>]*)>/i, (_match, attributes: string) => {\n const nextAttributes = attributes.replace(/\\sclass=([\"'])(.*?)\\1/i, (_classMatch, quote, value) => {\n return ` class=${quote}${value} ${className}${quote}`\n })\n const hasClass = /\\sclass=/.test(attributes)\n\n return `<svg${hasClass ? nextAttributes : `${nextAttributes} class=\"${className}\"`} aria-hidden=\"true\" focusable=\"false\">`\n })\n}\n\nfunction parseSvgFragment(svg: string): RootContent[] {\n const root = fromHtml(svg, { fragment: true })\n\n return root.children.filter((node): node is Element => node.type === 'element')\n}\n\nexport function resolvePayloadMarkdownIcon(\n ref: string | undefined,\n config: PayloadMarkdownIconsConfig | undefined,\n className: string,\n): PayloadMarkdownIconResolution {\n if (!ref) return { nodes: [], warnings: [] }\n\n const normalized = normalizePayloadMarkdownIconRef(ref)\n if (normalized.warning) return { nodes: [], warnings: [normalized.warning] }\n if (!normalized.icon) return { nodes: [], warnings: [] }\n\n const pack = config?.packs?.find((entry) => entry.alias === normalized.icon?.packAlias)\n if (!pack)\n return {\n iconKey: normalized.icon.key,\n nodes: [],\n warnings: [`Unknown icon pack \"${normalized.icon.packAlias}\".`],\n }\n\n const baseDir = path.resolve(process.cwd(), config?.baseDir ?? '')\n const packRoot = path.resolve(baseDir, pack.path)\n const iconFile = path.resolve(packRoot, `${normalized.icon.iconPath}.svg`)\n\n if (!isWithin(packRoot, iconFile))\n return {\n iconKey: normalized.icon.key,\n nodes: [],\n warnings: [`Malformed icon ref \"${ref}\". Icon paths must stay within their icon pack.`],\n }\n\n if (!fs.existsSync(iconFile))\n return {\n iconKey: normalized.icon.key,\n nodes: [],\n warnings: [`Unknown icon \"${normalized.icon.key}\".`],\n }\n\n const svg = addSvgRuntimeAttributes(sanitizeSvg(fs.readFileSync(iconFile, 'utf8')), className)\n\n return {\n iconKey: normalized.icon.key,\n nodes: parseSvgFragment(svg),\n warnings: [],\n }\n}\n"],"names":["fromHtml","fs","path","hasUnsafeIconPathSegments","normalizePayloadMarkdownIconRef","isWithin","parent","child","relative","Boolean","startsWith","isAbsolute","validatePayloadMarkdownIconsConfig","config","warnings","seenAliases","Set","baseDir","trim","push","pack","packs","alias","packPath","has","add","sanitizeSvg","value","replace","addSvgRuntimeAttributes","svg","className","_match","attributes","nextAttributes","_classMatch","quote","hasClass","test","parseSvgFragment","root","fragment","children","filter","node","type","resolvePayloadMarkdownIcon","ref","nodes","normalized","warning","icon","find","entry","packAlias","iconKey","key","resolve","process","cwd","packRoot","iconFile","iconPath","existsSync","readFileSync"],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -7,4 +7,4 @@ import { markdownField } from './field/MarkdownField/config.js';
7
7
  export declare const payloadMarkdown: (pluginOptions?: PayloadMarkdownConfig) => Plugin;
8
8
  export { DEFAULT_CALLOUT_THEMES, DEFAULT_CARD_THEMES, DEFAULT_CARDS_THEMES, DEFAULT_CELL_THEMES, DEFAULT_CODE_LANGS, DEFAULT_COLUMNS_THEMES, DEFAULT_DETAILS_THEMES, DEFAULT_SECTION_THEMES, DEFAULT_STEPS_THEMES, DEFAULT_TAB_THEMES, DEFAULT_TABS_THEMES, DEFAULT_TOC_THEMES, MarkdownBlock, markdownField, };
9
9
  export type { MarkdownFieldOptions, PayloadMarkdownConfig };
10
- export type { MarkdownCodeConfig, MarkdownDirectiveTheme, MarkdownDirectiveThemeGroup, MarkdownDirectiveThemes, } from './types/core.js';
10
+ export type { MarkdownCodeConfig, MarkdownDirectiveTheme, MarkdownDirectiveThemeGroup, MarkdownDirectiveThemes, PayloadMarkdownIconPack, PayloadMarkdownIconsConfig, } from './types/core.js';
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import type { Block, CollectionConfig, Config, Field, Plugin } from 'payload'\n\nimport type { MarkdownFieldOptions, PayloadMarkdownCollectionConfig, PayloadMarkdownConfig } from './types.js'\n\nimport { MarkdownBlock } from './blocks/MarkdownBlock/config.js'\nimport { DEFAULT_CODE_LANGS } from './core/codeToHtml.js'\nimport {\n DEFAULT_CALLOUT_THEMES,\n DEFAULT_CARD_THEMES,\n DEFAULT_CARDS_THEMES,\n DEFAULT_CELL_THEMES,\n DEFAULT_COLUMNS_THEMES,\n DEFAULT_DETAILS_THEMES,\n DEFAULT_SECTION_THEMES,\n DEFAULT_STEPS_THEMES,\n DEFAULT_TAB_THEMES,\n DEFAULT_TABS_THEMES,\n DEFAULT_TOC_THEMES,\n} from './directives/themes.js'\nimport { markdownField } from './field/MarkdownField/config.js'\nimport { setPayloadMarkdownSettings } from './runtime/index.js'\n\nfunction ensureMarkdownBlock(config: Config) {\n if (!config.blocks) config.blocks = []\n\n const alreadyExists = config.blocks.some((block) => block.slug === MarkdownBlock.slug)\n if (alreadyExists) return\n\n config.blocks.push(MarkdownBlock)\n}\n\nfunction ensureMarkdownField(\n collection: CollectionConfig,\n fieldName: string,\n fieldOptions?: Omit<MarkdownFieldOptions, 'name'>,\n) {\n const alreadyExists = collection.fields.some(\n (field) => 'name' in field && field.name === fieldName,\n )\n\n if (alreadyExists) return\n\n collection.fields.push(\n markdownField({\n name: fieldName,\n label: 'Markdown',\n ...(fieldOptions || {}),\n }),\n )\n}\n\nfunction ensureBlockInBlocksField(field: Field, block: Block) {\n if (field.type !== 'blocks') return\n\n if (!field.blocks) field.blocks = []\n\n const alreadyExists = field.blocks.some((entry) => entry.slug === block.slug)\n if (alreadyExists) return\n\n field.blocks.push(block)\n}\n\nfunction walkFieldsAndInstallBlock(fields: Field[], block: Block) {\n for (const field of fields) {\n ensureBlockInBlocksField(field, block)\n\n if ('fields' in field && Array.isArray(field.fields))\n walkFieldsAndInstallBlock(field.fields, block)\n\n if (field.type === 'tabs' && Array.isArray(field.tabs)) {\n for (const tab of field.tabs)\n if ('fields' in tab && Array.isArray(tab.fields))\n walkFieldsAndInstallBlock(tab.fields, block)\n }\n }\n}\n\nfunction ensureMarkdownBlockInCollectionBlocks(collection: CollectionConfig) {\n walkFieldsAndInstallBlock(collection.fields, MarkdownBlock)\n}\n\nfunction collectionHasBlocksField(fields: Field[]): boolean {\n for (const field of fields) {\n if (field.type === 'blocks') return true\n\n if ('fields' in field && Array.isArray(field.fields))\n if (collectionHasBlocksField(field.fields)) return true\n\n if (field.type === 'tabs' && Array.isArray(field.tabs))\n for (const tab of field.tabs)\n if ('fields' in tab && Array.isArray(tab.fields))\n if (collectionHasBlocksField(tab.fields)) return true\n }\n\n return false\n}\n\nfunction resolveCollectionInstallBehavior(\n collection: CollectionConfig,\n collectionOptions: PayloadMarkdownCollectionConfig | true,\n) {\n const hasBlocksField = collectionHasBlocksField(collection.fields)\n\n if (collectionOptions === true) {\n return {\n fieldName: 'content',\n fieldOptions: undefined,\n installField: !hasBlocksField,\n installIntoBlocks: hasBlocksField,\n }\n }\n\n return {\n fieldName: collectionOptions.fieldName || 'content',\n fieldOptions: collectionOptions.field,\n installField: collectionOptions.installField ?? !hasBlocksField,\n installIntoBlocks: collectionOptions.installIntoBlocks ?? hasBlocksField,\n }\n}\n\nexport const payloadMarkdown =\n (pluginOptions: PayloadMarkdownConfig = {}): Plugin =>\n (incomingConfig: Config): Config => {\n const config = { ...incomingConfig }\n\n if (pluginOptions.enabled === false) return config\n\n setPayloadMarkdownSettings(pluginOptions)\n\n ensureMarkdownBlock(config)\n\n if (!pluginOptions.collections || !config.collections) return config\n\n for (const [collectionSlug, collectionOptions] of Object.entries(pluginOptions.collections)) {\n if (!collectionOptions) continue\n\n const collection = config.collections.find((entry) => entry.slug === collectionSlug)\n if (!collection) continue\n\n const resolved = resolveCollectionInstallBehavior(collection, collectionOptions)\n\n if (resolved.installIntoBlocks) ensureMarkdownBlockInCollectionBlocks(collection)\n\n if (resolved.installField)\n ensureMarkdownField(collection, resolved.fieldName, resolved.fieldOptions)\n }\n\n return config\n }\n\nexport {\n DEFAULT_CALLOUT_THEMES,\n DEFAULT_CARD_THEMES,\n DEFAULT_CARDS_THEMES,\n DEFAULT_CELL_THEMES,\n DEFAULT_CODE_LANGS,\n DEFAULT_COLUMNS_THEMES,\n DEFAULT_DETAILS_THEMES,\n DEFAULT_SECTION_THEMES,\n DEFAULT_STEPS_THEMES,\n DEFAULT_TAB_THEMES,\n DEFAULT_TABS_THEMES,\n DEFAULT_TOC_THEMES,\n MarkdownBlock,\n markdownField,\n}\nexport type { MarkdownFieldOptions, PayloadMarkdownConfig }\nexport type {\n MarkdownCodeConfig,\n MarkdownDirectiveTheme,\n MarkdownDirectiveThemeGroup,\n MarkdownDirectiveThemes,\n} from './types/core.js'\n"],"names":["MarkdownBlock","DEFAULT_CODE_LANGS","DEFAULT_CALLOUT_THEMES","DEFAULT_CARD_THEMES","DEFAULT_CARDS_THEMES","DEFAULT_CELL_THEMES","DEFAULT_COLUMNS_THEMES","DEFAULT_DETAILS_THEMES","DEFAULT_SECTION_THEMES","DEFAULT_STEPS_THEMES","DEFAULT_TAB_THEMES","DEFAULT_TABS_THEMES","DEFAULT_TOC_THEMES","markdownField","setPayloadMarkdownSettings","ensureMarkdownBlock","config","blocks","alreadyExists","some","block","slug","push","ensureMarkdownField","collection","fieldName","fieldOptions","fields","field","name","label","ensureBlockInBlocksField","type","entry","walkFieldsAndInstallBlock","Array","isArray","tabs","tab","ensureMarkdownBlockInCollectionBlocks","collectionHasBlocksField","resolveCollectionInstallBehavior","collectionOptions","hasBlocksField","undefined","installField","installIntoBlocks","payloadMarkdown","pluginOptions","incomingConfig","enabled","collections","collectionSlug","Object","entries","find","resolved"],"mappings":"AAIA,SAASA,aAAa,QAAQ,mCAAkC;AAChE,SAASC,kBAAkB,QAAQ,uBAAsB;AACzD,SACEC,sBAAsB,EACtBC,mBAAmB,EACnBC,oBAAoB,EACpBC,mBAAmB,EACnBC,sBAAsB,EACtBC,sBAAsB,EACtBC,sBAAsB,EACtBC,oBAAoB,EACpBC,kBAAkB,EAClBC,mBAAmB,EACnBC,kBAAkB,QACb,yBAAwB;AAC/B,SAASC,aAAa,QAAQ,kCAAiC;AAC/D,SAASC,0BAA0B,QAAQ,qBAAoB;AAE/D,SAASC,oBAAoBC,MAAc;IACzC,IAAI,CAACA,OAAOC,MAAM,EAAED,OAAOC,MAAM,GAAG,EAAE;IAEtC,MAAMC,gBAAgBF,OAAOC,MAAM,CAACE,IAAI,CAAC,CAACC,QAAUA,MAAMC,IAAI,KAAKrB,cAAcqB,IAAI;IACrF,IAAIH,eAAe;IAEnBF,OAAOC,MAAM,CAACK,IAAI,CAACtB;AACrB;AAEA,SAASuB,oBACPC,UAA4B,EAC5BC,SAAiB,EACjBC,YAAiD;IAEjD,MAAMR,gBAAgBM,WAAWG,MAAM,CAACR,IAAI,CAC1C,CAACS,QAAU,UAAUA,SAASA,MAAMC,IAAI,KAAKJ;IAG/C,IAAIP,eAAe;IAEnBM,WAAWG,MAAM,CAACL,IAAI,CACpBT,cAAc;QACZgB,MAAMJ;QACNK,OAAO;QACP,GAAIJ,gBAAgB,CAAC,CAAC;IACxB;AAEJ;AAEA,SAASK,yBAAyBH,KAAY,EAAER,KAAY;IAC1D,IAAIQ,MAAMI,IAAI,KAAK,UAAU;IAE7B,IAAI,CAACJ,MAAMX,MAAM,EAAEW,MAAMX,MAAM,GAAG,EAAE;IAEpC,MAAMC,gBAAgBU,MAAMX,MAAM,CAACE,IAAI,CAAC,CAACc,QAAUA,MAAMZ,IAAI,KAAKD,MAAMC,IAAI;IAC5E,IAAIH,eAAe;IAEnBU,MAAMX,MAAM,CAACK,IAAI,CAACF;AACpB;AAEA,SAASc,0BAA0BP,MAAe,EAAEP,KAAY;IAC9D,KAAK,MAAMQ,SAASD,OAAQ;QAC1BI,yBAAyBH,OAAOR;QAEhC,IAAI,YAAYQ,SAASO,MAAMC,OAAO,CAACR,MAAMD,MAAM,GACjDO,0BAA0BN,MAAMD,MAAM,EAAEP;QAE1C,IAAIQ,MAAMI,IAAI,KAAK,UAAUG,MAAMC,OAAO,CAACR,MAAMS,IAAI,GAAG;YACtD,KAAK,MAAMC,OAAOV,MAAMS,IAAI,CAC1B,IAAI,YAAYC,OAAOH,MAAMC,OAAO,CAACE,IAAIX,MAAM,GAC7CO,0BAA0BI,IAAIX,MAAM,EAAEP;QAC5C;IACF;AACF;AAEA,SAASmB,sCAAsCf,UAA4B;IACzEU,0BAA0BV,WAAWG,MAAM,EAAE3B;AAC/C;AAEA,SAASwC,yBAAyBb,MAAe;IAC/C,KAAK,MAAMC,SAASD,OAAQ;QAC1B,IAAIC,MAAMI,IAAI,KAAK,UAAU,OAAO;QAEpC,IAAI,YAAYJ,SAASO,MAAMC,OAAO,CAACR,MAAMD,MAAM,GACjD;YAAA,IAAIa,yBAAyBZ,MAAMD,MAAM,GAAG,OAAO;QAAG;QAExD,IAAIC,MAAMI,IAAI,KAAK,UAAUG,MAAMC,OAAO,CAACR,MAAMS,IAAI,GACnD;YAAA,KAAK,MAAMC,OAAOV,MAAMS,IAAI,CAC1B,IAAI,YAAYC,OAAOH,MAAMC,OAAO,CAACE,IAAIX,MAAM,GAC7C;gBAAA,IAAIa,yBAAyBF,IAAIX,MAAM,GAAG,OAAO;YAAG;QAAA;IAC5D;IAEA,OAAO;AACT;AAEA,SAASc,iCACPjB,UAA4B,EAC5BkB,iBAAyD;IAEzD,MAAMC,iBAAiBH,yBAAyBhB,WAAWG,MAAM;IAEjE,IAAIe,sBAAsB,MAAM;QAC9B,OAAO;YACLjB,WAAW;YACXC,cAAckB;YACdC,cAAc,CAACF;YACfG,mBAAmBH;QACrB;IACF;IAEA,OAAO;QACLlB,WAAWiB,kBAAkBjB,SAAS,IAAI;QAC1CC,cAAcgB,kBAAkBd,KAAK;QACrCiB,cAAcH,kBAAkBG,YAAY,IAAI,CAACF;QACjDG,mBAAmBJ,kBAAkBI,iBAAiB,IAAIH;IAC5D;AACF;AAEA,OAAO,MAAMI,kBACX,CAACC,gBAAuC,CAAC,CAAC,GAC1C,CAACC;QACC,MAAMjC,SAAS;YAAE,GAAGiC,cAAc;QAAC;QAEnC,IAAID,cAAcE,OAAO,KAAK,OAAO,OAAOlC;QAE5CF,2BAA2BkC;QAE3BjC,oBAAoBC;QAEpB,IAAI,CAACgC,cAAcG,WAAW,IAAI,CAACnC,OAAOmC,WAAW,EAAE,OAAOnC;QAE9D,KAAK,MAAM,CAACoC,gBAAgBV,kBAAkB,IAAIW,OAAOC,OAAO,CAACN,cAAcG,WAAW,EAAG;YAC3F,IAAI,CAACT,mBAAmB;YAExB,MAAMlB,aAAaR,OAAOmC,WAAW,CAACI,IAAI,CAAC,CAACtB,QAAUA,MAAMZ,IAAI,KAAK+B;YACrE,IAAI,CAAC5B,YAAY;YAEjB,MAAMgC,WAAWf,iCAAiCjB,YAAYkB;YAE9D,IAAIc,SAASV,iBAAiB,EAAEP,sCAAsCf;YAEtE,IAAIgC,SAASX,YAAY,EACvBtB,oBAAoBC,YAAYgC,SAAS/B,SAAS,EAAE+B,SAAS9B,YAAY;QAC7E;QAEA,OAAOV;IACT,EAAC;AAEH,SACEd,sBAAsB,EACtBC,mBAAmB,EACnBC,oBAAoB,EACpBC,mBAAmB,EACnBJ,kBAAkB,EAClBK,sBAAsB,EACtBC,sBAAsB,EACtBC,sBAAsB,EACtBC,oBAAoB,EACpBC,kBAAkB,EAClBC,mBAAmB,EACnBC,kBAAkB,EAClBZ,aAAa,EACba,aAAa,KACd"}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import type { Block, CollectionConfig, Config, Field, Plugin } from 'payload'\n\nimport type { MarkdownFieldOptions, PayloadMarkdownCollectionConfig, PayloadMarkdownConfig } from './types.js'\n\nimport { MarkdownBlock } from './blocks/MarkdownBlock/config.js'\nimport { DEFAULT_CODE_LANGS } from './core/codeToHtml.js'\nimport {\n DEFAULT_CALLOUT_THEMES,\n DEFAULT_CARD_THEMES,\n DEFAULT_CARDS_THEMES,\n DEFAULT_CELL_THEMES,\n DEFAULT_COLUMNS_THEMES,\n DEFAULT_DETAILS_THEMES,\n DEFAULT_SECTION_THEMES,\n DEFAULT_STEPS_THEMES,\n DEFAULT_TAB_THEMES,\n DEFAULT_TABS_THEMES,\n DEFAULT_TOC_THEMES,\n} from './directives/themes.js'\nimport { markdownField } from './field/MarkdownField/config.js'\nimport { setPayloadMarkdownSettings } from './runtime/index.js'\n\nfunction ensureMarkdownBlock(config: Config) {\n if (!config.blocks) config.blocks = []\n\n const alreadyExists = config.blocks.some((block) => block.slug === MarkdownBlock.slug)\n if (alreadyExists) return\n\n config.blocks.push(MarkdownBlock)\n}\n\nfunction ensureMarkdownField(\n collection: CollectionConfig,\n fieldName: string,\n fieldOptions?: Omit<MarkdownFieldOptions, 'name'>,\n) {\n const alreadyExists = collection.fields.some(\n (field) => 'name' in field && field.name === fieldName,\n )\n\n if (alreadyExists) return\n\n collection.fields.push(\n markdownField({\n name: fieldName,\n label: 'Markdown',\n ...(fieldOptions || {}),\n }),\n )\n}\n\nfunction ensureBlockInBlocksField(field: Field, block: Block) {\n if (field.type !== 'blocks') return\n\n if (!field.blocks) field.blocks = []\n\n const alreadyExists = field.blocks.some((entry) => entry.slug === block.slug)\n if (alreadyExists) return\n\n field.blocks.push(block)\n}\n\nfunction walkFieldsAndInstallBlock(fields: Field[], block: Block) {\n for (const field of fields) {\n ensureBlockInBlocksField(field, block)\n\n if ('fields' in field && Array.isArray(field.fields))\n walkFieldsAndInstallBlock(field.fields, block)\n\n if (field.type === 'tabs' && Array.isArray(field.tabs)) {\n for (const tab of field.tabs)\n if ('fields' in tab && Array.isArray(tab.fields))\n walkFieldsAndInstallBlock(tab.fields, block)\n }\n }\n}\n\nfunction ensureMarkdownBlockInCollectionBlocks(collection: CollectionConfig) {\n walkFieldsAndInstallBlock(collection.fields, MarkdownBlock)\n}\n\nfunction collectionHasBlocksField(fields: Field[]): boolean {\n for (const field of fields) {\n if (field.type === 'blocks') return true\n\n if ('fields' in field && Array.isArray(field.fields))\n if (collectionHasBlocksField(field.fields)) return true\n\n if (field.type === 'tabs' && Array.isArray(field.tabs))\n for (const tab of field.tabs)\n if ('fields' in tab && Array.isArray(tab.fields))\n if (collectionHasBlocksField(tab.fields)) return true\n }\n\n return false\n}\n\nfunction resolveCollectionInstallBehavior(\n collection: CollectionConfig,\n collectionOptions: PayloadMarkdownCollectionConfig | true,\n) {\n const hasBlocksField = collectionHasBlocksField(collection.fields)\n\n if (collectionOptions === true) {\n return {\n fieldName: 'content',\n fieldOptions: undefined,\n installField: !hasBlocksField,\n installIntoBlocks: hasBlocksField,\n }\n }\n\n return {\n fieldName: collectionOptions.fieldName || 'content',\n fieldOptions: collectionOptions.field,\n installField: collectionOptions.installField ?? !hasBlocksField,\n installIntoBlocks: collectionOptions.installIntoBlocks ?? hasBlocksField,\n }\n}\n\nexport const payloadMarkdown =\n (pluginOptions: PayloadMarkdownConfig = {}): Plugin =>\n (incomingConfig: Config): Config => {\n const config = { ...incomingConfig }\n\n if (pluginOptions.enabled === false) return config\n\n setPayloadMarkdownSettings(pluginOptions)\n\n ensureMarkdownBlock(config)\n\n if (!pluginOptions.collections || !config.collections) return config\n\n for (const [collectionSlug, collectionOptions] of Object.entries(pluginOptions.collections)) {\n if (!collectionOptions) continue\n\n const collection = config.collections.find((entry) => entry.slug === collectionSlug)\n if (!collection) continue\n\n const resolved = resolveCollectionInstallBehavior(collection, collectionOptions)\n\n if (resolved.installIntoBlocks) ensureMarkdownBlockInCollectionBlocks(collection)\n\n if (resolved.installField)\n ensureMarkdownField(collection, resolved.fieldName, resolved.fieldOptions)\n }\n\n return config\n }\n\nexport {\n DEFAULT_CALLOUT_THEMES,\n DEFAULT_CARD_THEMES,\n DEFAULT_CARDS_THEMES,\n DEFAULT_CELL_THEMES,\n DEFAULT_CODE_LANGS,\n DEFAULT_COLUMNS_THEMES,\n DEFAULT_DETAILS_THEMES,\n DEFAULT_SECTION_THEMES,\n DEFAULT_STEPS_THEMES,\n DEFAULT_TAB_THEMES,\n DEFAULT_TABS_THEMES,\n DEFAULT_TOC_THEMES,\n MarkdownBlock,\n markdownField,\n}\nexport type { MarkdownFieldOptions, PayloadMarkdownConfig }\nexport type {\n MarkdownCodeConfig,\n MarkdownDirectiveTheme,\n MarkdownDirectiveThemeGroup,\n MarkdownDirectiveThemes,\n PayloadMarkdownIconPack,\n PayloadMarkdownIconsConfig,\n} from './types/core.js'\n"],"names":["MarkdownBlock","DEFAULT_CODE_LANGS","DEFAULT_CALLOUT_THEMES","DEFAULT_CARD_THEMES","DEFAULT_CARDS_THEMES","DEFAULT_CELL_THEMES","DEFAULT_COLUMNS_THEMES","DEFAULT_DETAILS_THEMES","DEFAULT_SECTION_THEMES","DEFAULT_STEPS_THEMES","DEFAULT_TAB_THEMES","DEFAULT_TABS_THEMES","DEFAULT_TOC_THEMES","markdownField","setPayloadMarkdownSettings","ensureMarkdownBlock","config","blocks","alreadyExists","some","block","slug","push","ensureMarkdownField","collection","fieldName","fieldOptions","fields","field","name","label","ensureBlockInBlocksField","type","entry","walkFieldsAndInstallBlock","Array","isArray","tabs","tab","ensureMarkdownBlockInCollectionBlocks","collectionHasBlocksField","resolveCollectionInstallBehavior","collectionOptions","hasBlocksField","undefined","installField","installIntoBlocks","payloadMarkdown","pluginOptions","incomingConfig","enabled","collections","collectionSlug","Object","entries","find","resolved"],"mappings":"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"}
@@ -5,6 +5,7 @@ export type PayloadMarkdownResolvedSettings = {
5
5
  collections: Partial<Record<string, PayloadMarkdownCollectionConfig | true>>;
6
6
  config?: ConfigOptions;
7
7
  enabled: boolean;
8
+ icons?: MarkdownRenderConfig['icons'];
8
9
  themes?: MarkdownRenderConfig['themes'];
9
10
  };
10
11
  export declare function setPayloadMarkdownSettings(pluginOptions?: PayloadMarkdownConfig): void;
@@ -7,6 +7,7 @@ export function setPayloadMarkdownSettings(pluginOptions = {}) {
7
7
  collections: pluginOptions.collections ?? {},
8
8
  config: pluginOptions.config,
9
9
  enabled: pluginOptions.enabled !== false,
10
+ icons: pluginOptions.icons,
10
11
  themes: pluginOptions.themes
11
12
  };
12
13
  }
@@ -70,13 +71,18 @@ export function mergeMarkdownConfigs(...configs) {
70
71
  export function mergeMarkdownRenderConfigs(...configs) {
71
72
  const merged = mergeMarkdownConfigs(...configs);
72
73
  const code = mergeCodeConfigFromRenderConfigs(...configs);
74
+ let icons;
73
75
  const themes = mergeMarkdownDirectiveThemes(...configs.map((config)=>config?.themes));
74
- if (!merged && !code && !themes) return undefined;
76
+ for (const config of configs)if (config?.icons !== undefined) icons = config.icons;
77
+ if (!merged && !code && !icons && !themes) return undefined;
75
78
  return {
76
79
  ...merged ?? {},
77
80
  ...code ? {
78
81
  code
79
82
  } : {},
83
+ ...icons ? {
84
+ icons
85
+ } : {},
80
86
  ...themes ? {
81
87
  themes
82
88
  } : {}
@@ -88,6 +94,7 @@ export function resolveGlobalMarkdownConfigs() {
88
94
  const resolved = resolveConfigOptions(current.config);
89
95
  const shared = {
90
96
  code: current.code,
97
+ icons: current.icons,
91
98
  themes: current.themes
92
99
  };
93
100
  return {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/runtime/index.ts"],"sourcesContent":["import type {\n ConfigOptions,\n DualMarkdownFieldConfig,\n PayloadMarkdownCollectionConfig,\n PayloadMarkdownConfig,\n} from '../types.js'\nimport type { MarkdownCodeConfig, MarkdownConfig, MarkdownRenderConfig } from '../types/core.js'\n\nimport { mergeCodeConfigFromRenderConfigs } from '../core/codeConfig.js'\nimport { mergeMarkdownDirectiveThemes } from '../directives/themes.js'\n\nexport type PayloadMarkdownResolvedSettings = {\n code?: MarkdownCodeConfig\n collections: Partial<Record<string, PayloadMarkdownCollectionConfig | true>>\n config?: ConfigOptions\n enabled: boolean\n themes?: MarkdownRenderConfig['themes']\n}\n\nlet settings: null | PayloadMarkdownResolvedSettings = null\n\nexport function setPayloadMarkdownSettings(pluginOptions: PayloadMarkdownConfig = {}) {\n settings = {\n code: pluginOptions.code,\n collections: pluginOptions.collections ?? {},\n config: pluginOptions.config,\n enabled: pluginOptions.enabled !== false,\n themes: pluginOptions.themes,\n }\n}\n\nexport function getPayloadMarkdownSettings(): PayloadMarkdownResolvedSettings {\n if (!settings) {\n throw new Error(\n '[payload-markdown] Settings have not been initialized. ' +\n 'Make sure payloadMarkdown(...) is included in your Payload plugins array before using runtime helpers.',\n )\n }\n\n return settings\n}\n\nexport function maybeGetPayloadMarkdownSettings(): null | PayloadMarkdownResolvedSettings {\n return settings\n}\n\nexport function clearPayloadMarkdownSettings() {\n settings = null\n}\n\nexport function isDualMarkdownFieldConfig(\n value: ConfigOptions | undefined,\n): value is DualMarkdownFieldConfig {\n if (!value || typeof value !== 'object') return false\n return 'blocks' in value || 'field' in value\n}\n\nexport function resolveConfigOptions(value?: ConfigOptions): {\n blocks?: MarkdownConfig\n field?: MarkdownConfig\n} {\n if (!value) return {}\n\n if (isDualMarkdownFieldConfig(value)) {\n return {\n blocks: value.blocks,\n field: value.field,\n }\n }\n\n return {\n blocks: value,\n field: value,\n }\n}\n\nfunction joinClassNames(...values: Array<string | undefined>) {\n return values.filter(Boolean).join(' ')\n}\n\nexport function mergeMarkdownConfigs(\n ...configs: Array<MarkdownConfig | undefined>\n): MarkdownConfig | undefined {\n const filtered = configs.filter(Boolean)\n if (filtered.length === 0) return undefined\n\n const merged: MarkdownConfig = {}\n\n for (const config of filtered) {\n if (!config) continue\n\n if (config.className) merged.className = joinClassNames(merged.className, config.className)\n\n if (config.wrapperClassName)\n merged.wrapperClassName = joinClassNames(merged.wrapperClassName, config.wrapperClassName)\n\n if (config.columnClassName)\n merged.columnClassName = joinClassNames(merged.columnClassName, config.columnClassName)\n\n if (config.sectionClassName)\n merged.sectionClassName = joinClassNames(merged.sectionClassName, config.sectionClassName)\n\n if (config.variant !== undefined) merged.variant = config.variant\n if (config.size !== undefined) merged.size = config.size\n if (config.lead !== undefined) merged.lead = config.lead\n if (config.fullBleedCode !== undefined) merged.fullBleedCode = config.fullBleedCode\n if (config.mutedHeadings !== undefined) merged.mutedHeadings = config.mutedHeadings\n if (config.enableGutter !== undefined) merged.enableGutter = config.enableGutter\n\n if (config.options) {\n merged.options = {\n ...(merged.options ?? {}),\n ...config.options,\n }\n }\n }\n\n return merged\n}\n\nexport function mergeMarkdownRenderConfigs(\n ...configs: Array<MarkdownRenderConfig | undefined>\n): MarkdownRenderConfig | undefined {\n const merged = mergeMarkdownConfigs(...configs)\n const code = mergeCodeConfigFromRenderConfigs(...configs)\n const themes = mergeMarkdownDirectiveThemes(...configs.map((config) => config?.themes))\n\n if (!merged && !code && !themes) return undefined\n\n return {\n ...(merged ?? {}),\n ...(code ? { code } : {}),\n ...(themes ? { themes } : {}),\n }\n}\n\nexport function resolveGlobalMarkdownConfigs() {\n const current = maybeGetPayloadMarkdownSettings()\n if (!current) return {}\n\n const resolved = resolveConfigOptions(current.config)\n const shared: MarkdownRenderConfig = {\n code: current.code,\n themes: current.themes,\n }\n\n return {\n blocks: mergeMarkdownRenderConfigs(resolved.blocks, shared),\n field: mergeMarkdownRenderConfigs(resolved.field, shared),\n }\n}\n\nexport function resolveCollectionMarkdownConfigs(collectionSlug?: string) {\n const globalResolved = resolveGlobalMarkdownConfigs()\n\n if (!collectionSlug) return globalResolved\n\n const current = maybeGetPayloadMarkdownSettings()\n if (!current) return globalResolved\n\n const collectionEntry = current.collections?.[collectionSlug]\n\n if (!collectionEntry || collectionEntry === true) {\n return globalResolved\n }\n\n const collectionResolved = resolveConfigOptions(collectionEntry.config)\n const shared: MarkdownRenderConfig = {\n code: collectionEntry.code,\n themes: collectionEntry.themes,\n }\n\n return {\n blocks: mergeMarkdownRenderConfigs(globalResolved.blocks, collectionResolved.blocks, shared),\n field: mergeMarkdownRenderConfigs(globalResolved.field, collectionResolved.field, shared),\n }\n}\n\nexport function resolveMarkdownBlockDefaults(collectionSlug?: string) {\n return resolveCollectionMarkdownConfigs(collectionSlug).blocks\n}\n\nexport function resolveMarkdownFieldDefaults(collectionSlug?: string) {\n return resolveCollectionMarkdownConfigs(collectionSlug).field\n}\n"],"names":["mergeCodeConfigFromRenderConfigs","mergeMarkdownDirectiveThemes","settings","setPayloadMarkdownSettings","pluginOptions","code","collections","config","enabled","themes","getPayloadMarkdownSettings","Error","maybeGetPayloadMarkdownSettings","clearPayloadMarkdownSettings","isDualMarkdownFieldConfig","value","resolveConfigOptions","blocks","field","joinClassNames","values","filter","Boolean","join","mergeMarkdownConfigs","configs","filtered","length","undefined","merged","className","wrapperClassName","columnClassName","sectionClassName","variant","size","lead","fullBleedCode","mutedHeadings","enableGutter","options","mergeMarkdownRenderConfigs","map","resolveGlobalMarkdownConfigs","current","resolved","shared","resolveCollectionMarkdownConfigs","collectionSlug","globalResolved","collectionEntry","collectionResolved","resolveMarkdownBlockDefaults","resolveMarkdownFieldDefaults"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/runtime/index.ts"],"sourcesContent":["import type {\n ConfigOptions,\n DualMarkdownFieldConfig,\n PayloadMarkdownCollectionConfig,\n PayloadMarkdownConfig,\n} from '../types.js'\nimport type { MarkdownCodeConfig, MarkdownConfig, MarkdownRenderConfig } from '../types/core.js'\n\nimport { mergeCodeConfigFromRenderConfigs } from '../core/codeConfig.js'\nimport { mergeMarkdownDirectiveThemes } from '../directives/themes.js'\n\nexport type PayloadMarkdownResolvedSettings = {\n code?: MarkdownCodeConfig\n collections: Partial<Record<string, PayloadMarkdownCollectionConfig | true>>\n config?: ConfigOptions\n enabled: boolean\n icons?: MarkdownRenderConfig['icons']\n themes?: MarkdownRenderConfig['themes']\n}\n\nlet settings: null | PayloadMarkdownResolvedSettings = null\n\nexport function setPayloadMarkdownSettings(pluginOptions: PayloadMarkdownConfig = {}) {\n settings = {\n code: pluginOptions.code,\n collections: pluginOptions.collections ?? {},\n config: pluginOptions.config,\n enabled: pluginOptions.enabled !== false,\n icons: pluginOptions.icons,\n themes: pluginOptions.themes,\n }\n}\n\nexport function getPayloadMarkdownSettings(): PayloadMarkdownResolvedSettings {\n if (!settings) {\n throw new Error(\n '[payload-markdown] Settings have not been initialized. ' +\n 'Make sure payloadMarkdown(...) is included in your Payload plugins array before using runtime helpers.',\n )\n }\n\n return settings\n}\n\nexport function maybeGetPayloadMarkdownSettings(): null | PayloadMarkdownResolvedSettings {\n return settings\n}\n\nexport function clearPayloadMarkdownSettings() {\n settings = null\n}\n\nexport function isDualMarkdownFieldConfig(\n value: ConfigOptions | undefined,\n): value is DualMarkdownFieldConfig {\n if (!value || typeof value !== 'object') return false\n return 'blocks' in value || 'field' in value\n}\n\nexport function resolveConfigOptions(value?: ConfigOptions): {\n blocks?: MarkdownConfig\n field?: MarkdownConfig\n} {\n if (!value) return {}\n\n if (isDualMarkdownFieldConfig(value)) {\n return {\n blocks: value.blocks,\n field: value.field,\n }\n }\n\n return {\n blocks: value,\n field: value,\n }\n}\n\nfunction joinClassNames(...values: Array<string | undefined>) {\n return values.filter(Boolean).join(' ')\n}\n\nexport function mergeMarkdownConfigs(\n ...configs: Array<MarkdownConfig | undefined>\n): MarkdownConfig | undefined {\n const filtered = configs.filter(Boolean)\n if (filtered.length === 0) return undefined\n\n const merged: MarkdownConfig = {}\n\n for (const config of filtered) {\n if (!config) continue\n\n if (config.className) merged.className = joinClassNames(merged.className, config.className)\n\n if (config.wrapperClassName)\n merged.wrapperClassName = joinClassNames(merged.wrapperClassName, config.wrapperClassName)\n\n if (config.columnClassName)\n merged.columnClassName = joinClassNames(merged.columnClassName, config.columnClassName)\n\n if (config.sectionClassName)\n merged.sectionClassName = joinClassNames(merged.sectionClassName, config.sectionClassName)\n\n if (config.variant !== undefined) merged.variant = config.variant\n if (config.size !== undefined) merged.size = config.size\n if (config.lead !== undefined) merged.lead = config.lead\n if (config.fullBleedCode !== undefined) merged.fullBleedCode = config.fullBleedCode\n if (config.mutedHeadings !== undefined) merged.mutedHeadings = config.mutedHeadings\n if (config.enableGutter !== undefined) merged.enableGutter = config.enableGutter\n\n if (config.options) {\n merged.options = {\n ...(merged.options ?? {}),\n ...config.options,\n }\n }\n }\n\n return merged\n}\n\nexport function mergeMarkdownRenderConfigs(\n ...configs: Array<MarkdownRenderConfig | undefined>\n): MarkdownRenderConfig | undefined {\n const merged = mergeMarkdownConfigs(...configs)\n const code = mergeCodeConfigFromRenderConfigs(...configs)\n let icons: MarkdownRenderConfig['icons']\n const themes = mergeMarkdownDirectiveThemes(...configs.map((config) => config?.themes))\n\n for (const config of configs)\n if (config?.icons !== undefined) icons = config.icons\n\n if (!merged && !code && !icons && !themes) return undefined\n\n return {\n ...(merged ?? {}),\n ...(code ? { code } : {}),\n ...(icons ? { icons } : {}),\n ...(themes ? { themes } : {}),\n }\n}\n\nexport function resolveGlobalMarkdownConfigs() {\n const current = maybeGetPayloadMarkdownSettings()\n if (!current) return {}\n\n const resolved = resolveConfigOptions(current.config)\n const shared: MarkdownRenderConfig = {\n code: current.code,\n icons: current.icons,\n themes: current.themes,\n }\n\n return {\n blocks: mergeMarkdownRenderConfigs(resolved.blocks, shared),\n field: mergeMarkdownRenderConfigs(resolved.field, shared),\n }\n}\n\nexport function resolveCollectionMarkdownConfigs(collectionSlug?: string) {\n const globalResolved = resolveGlobalMarkdownConfigs()\n\n if (!collectionSlug) return globalResolved\n\n const current = maybeGetPayloadMarkdownSettings()\n if (!current) return globalResolved\n\n const collectionEntry = current.collections?.[collectionSlug]\n\n if (!collectionEntry || collectionEntry === true) {\n return globalResolved\n }\n\n const collectionResolved = resolveConfigOptions(collectionEntry.config)\n const shared: MarkdownRenderConfig = {\n code: collectionEntry.code,\n themes: collectionEntry.themes,\n }\n\n return {\n blocks: mergeMarkdownRenderConfigs(globalResolved.blocks, collectionResolved.blocks, shared),\n field: mergeMarkdownRenderConfigs(globalResolved.field, collectionResolved.field, shared),\n }\n}\n\nexport function resolveMarkdownBlockDefaults(collectionSlug?: string) {\n return resolveCollectionMarkdownConfigs(collectionSlug).blocks\n}\n\nexport function resolveMarkdownFieldDefaults(collectionSlug?: string) {\n return resolveCollectionMarkdownConfigs(collectionSlug).field\n}\n"],"names":["mergeCodeConfigFromRenderConfigs","mergeMarkdownDirectiveThemes","settings","setPayloadMarkdownSettings","pluginOptions","code","collections","config","enabled","icons","themes","getPayloadMarkdownSettings","Error","maybeGetPayloadMarkdownSettings","clearPayloadMarkdownSettings","isDualMarkdownFieldConfig","value","resolveConfigOptions","blocks","field","joinClassNames","values","filter","Boolean","join","mergeMarkdownConfigs","configs","filtered","length","undefined","merged","className","wrapperClassName","columnClassName","sectionClassName","variant","size","lead","fullBleedCode","mutedHeadings","enableGutter","options","mergeMarkdownRenderConfigs","map","resolveGlobalMarkdownConfigs","current","resolved","shared","resolveCollectionMarkdownConfigs","collectionSlug","globalResolved","collectionEntry","collectionResolved","resolveMarkdownBlockDefaults","resolveMarkdownFieldDefaults"],"mappings":"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"}
@@ -113,6 +113,14 @@ export type MarkdownDirectiveThemes = {
113
113
  tabs?: MarkdownDirectiveThemeGroup;
114
114
  toc?: MarkdownDirectiveThemeGroup;
115
115
  };
116
+ export type PayloadMarkdownIconPack = {
117
+ alias: string;
118
+ path: string;
119
+ };
120
+ export type PayloadMarkdownIconsConfig = {
121
+ baseDir: string;
122
+ packs: PayloadMarkdownIconPack[];
123
+ };
116
124
  /**
117
125
  * The result of compiling markdown into sanitized HTML.
118
126
  */
@@ -209,6 +217,7 @@ export type MarkdownConfig = {
209
217
  };
210
218
  export type MarkdownRenderConfig = {
211
219
  code?: MarkdownCodeConfig;
220
+ icons?: PayloadMarkdownIconsConfig;
212
221
  themes?: MarkdownDirectiveThemes;
213
222
  } & MarkdownConfig;
214
223
  /**
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/types/core.ts"],"sourcesContent":["import type { JSX, ReactNode } from 'react'\n\nexport type MarkdownRendererScope = 'blocks' | 'field'\n\n/**\n * Options that control how fenced code blocks are rendered inside markdown content.\n *\n * By default, code blocks use the plugin's enhanced rendering mode:\n * - `enhancedCodeBlocks` defaults to `true`\n * - `lineNumbers` defaults to `true`\n * - `theme` defaults to `'github-dark'`\n *\n * When enhanced rendering is enabled, the plugin applies its normalized code block\n * pipeline on top of Shiki output. This includes layout cleanup, background\n * normalization, and support for features like line numbers.\n *\n * When enhanced rendering is disabled, code blocks are rendered closer to raw\n * Shiki output and plugin-specific enhancements are bypassed.\n *\n * These options are passed through the markdown rendering pipeline and primarily\n * affect Shiki-rendered code fences.\n */\nexport type RenderMarkdownOptions = {\n /**\n * Whether to apply the plugin's enhanced code block rendering pipeline.\n *\n * Defaults to `true`.\n *\n * When enabled, the renderer performs structural and visual normalization on\n * Shiki output to produce a consistent, content-focused appearance.\n *\n * When disabled, code blocks are rendered closer to raw Shiki output.\n */\n enhancedCodeBlocks?: boolean\n\n /**\n * An optional list of language identifiers to load for Shiki syntax highlighting.\n *\n * By default, the plugin loads a core set of popular languages. You can replace\n * that set entirely or extend it using spread syntax:\n *\n * ```ts\n * options: {\n * langs: [...DEFAULT_CODE_LANGS, 'latex']\n * }\n * ```\n */\n langs?: string[]\n\n /**\n * Whether to show line numbers for fenced code blocks.\n *\n * Defaults to `true` when `enhancedCodeBlocks` is enabled.\n *\n * Line numbers require the enhanced rendering pipeline and are automatically\n * disabled when `enhancedCodeBlocks` is set to `false`.\n */\n lineNumbers?: boolean\n\n /**\n * The Shiki theme to use for syntax highlighting.\n *\n * Defaults to `'github-dark'`.\n *\n * The plugin's enhanced renderer is tuned around its default theme. When using a\n * non-default theme:\n *\n * - `enhancedCodeBlocks: true` opts into the plugin's normalized rendering pipeline\n * - `enhancedCodeBlocks: false` preserves the theme's native appearance more closely\n *\n * This allows you to choose between a more controlled presentation and a more\n * theme-faithful rendering mode.\n */\n theme?: string\n}\n\nexport type MarkdownCodeConfig = {\n /**\n * Whether to apply the plugin's enhanced code block rendering pipeline.\n */\n enhanced?: boolean\n\n /**\n * Whether fenced code blocks should extend beyond the normal content width\n * on larger screens.\n */\n fullBleed?: boolean\n\n /**\n * Optional list of language identifiers to load for Shiki syntax highlighting.\n */\n langs?: string[]\n\n /**\n * Whether to show line numbers for fenced code blocks.\n */\n lineNumbers?: boolean\n\n /**\n * The Shiki theme to use for syntax highlighting.\n */\n shikiTheme?: string\n}\n\nexport type MarkdownDirectiveTheme = {\n classes: string\n label?: string\n name: string\n}\n\nexport type MarkdownDirectiveThemeGroup = {\n extendDefaults?: boolean\n items?: MarkdownDirectiveTheme[]\n} | MarkdownDirectiveTheme[]\n\nexport type MarkdownDirectiveThemes = {\n callout?: MarkdownDirectiveThemeGroup\n card?: MarkdownDirectiveThemeGroup\n cards?: MarkdownDirectiveThemeGroup\n cell?: MarkdownDirectiveThemeGroup\n columns?: MarkdownDirectiveThemeGroup\n details?: MarkdownDirectiveThemeGroup\n section?: MarkdownDirectiveThemeGroup\n steps?: MarkdownDirectiveThemeGroup\n tab?: MarkdownDirectiveThemeGroup\n tabs?: MarkdownDirectiveThemeGroup\n toc?: MarkdownDirectiveThemeGroup\n}\n\n/**\n * The result of compiling markdown into sanitized HTML.\n */\nexport type RenderMarkdownResult = {\n /**\n * The rendered HTML output.\n */\n html: string\n\n /**\n * Non-fatal warnings produced during rendering.\n */\n warnings: string[]\n}\n\n/**\n * Preset visual styles for rendered markdown content.\n */\nexport type MarkdownVariant = 'blog' | 'compact' | 'docs' | 'unstyled'\n\n/**\n * Preset typography sizes for rendered markdown content.\n */\nexport type MarkdownSize = 'lg' | 'md' | 'sm'\n\n/**\n * Core markdown presentation configuration.\n *\n * This type represents the configurable styling and behavior layer that can be\n * sourced from plugin defaults, globals, collection defaults, or block-level\n * overrides. It intentionally excludes runtime-only renderer props such as\n * `markdown`, `as`, and fallback nodes.\n */\nexport type MarkdownConfig = {\n /**\n * Additional classes applied to the rendered markdown element itself.\n */\n className?: string\n\n /**\n * Additional classes applied to column elements within the rendered markdown, if applicable.\n *\n * @deprecated Use directive themes instead.\n */\n columnClassName?: string\n\n /**\n * Whether to apply horizontal gutter padding to the outer wrapper.\n *\n * Defaults to `false`.\n */\n enableGutter?: boolean\n\n /**\n * Whether fenced code blocks should extend beyond the normal content width\n * on larger screens.\n *\n * Defaults to `false`.\n *\n * @deprecated Use top-level or renderer-level `code.fullBleed` instead.\n */\n fullBleedCode?: boolean\n\n /**\n * Optional content rendered above the markdown body.\n */\n lead?: ReactNode\n\n /**\n * Whether heading colors should be slightly muted.\n *\n * Defaults to `false`.\n */\n mutedHeadings?: boolean\n\n /**\n * Options that control fenced code block rendering.\n *\n * @deprecated Use top-level or renderer-level `code` instead.\n */\n options?: RenderMarkdownOptions\n\n /**\n * Additional classes applied to section elements within the rendered markdown, if applicable.\n *\n * @deprecated Use directive themes instead.\n */\n sectionClassName?: string\n\n /**\n * Typography size preset for the rendered markdown.\n *\n * Defaults to `'lg'`.\n */\n size?: MarkdownSize\n\n /**\n * Visual style preset for the rendered markdown.\n *\n * Defaults to `'blog'`.\n */\n variant?: MarkdownVariant\n\n /**\n * Additional classes applied to the outer wrapper element.\n */\n wrapperClassName?: string\n}\n\nexport type MarkdownRenderConfig = {\n code?: MarkdownCodeConfig\n themes?: MarkdownDirectiveThemes\n} & MarkdownConfig\n\n/**\n * Runtime-only props shared by markdown renderer components.\n */\nexport type BaseMarkdownRendererProps = {\n /**\n * The HTML tag used for the rendered markdown container.\n *\n * Defaults to `'article'`.\n */\n as?: keyof JSX.IntrinsicElements\n\n /**\n * Content rendered when the markdown input is empty or missing.\n */\n emptyFallback?: ReactNode\n\n /**\n * Content rendered when markdown compilation fails and a fallback is desired.\n */\n errorFallback?: ReactNode\n\n /**\n * The markdown source string to render.\n */\n markdown?: null | string\n}\n\n/**\n * Props for the main markdown renderer component.\n *\n * This merges persisted/configurable markdown presentation settings with the\n * runtime-only rendering props required by the component itself.\n */\nexport type MarkdownRendererProps = {\n collectionSlug?: string\n scope?: MarkdownRendererScope\n} & BaseMarkdownRendererProps & MarkdownRenderConfig\n\n/**\n * Options available while rendering an individual fenced code block.\n */\nexport interface CodeBlockOptions extends RenderMarkdownOptions {\n /**\n * The parsed language identifier for the fenced code block, if present.\n */\n lang?: string\n}\n\n/**\n * Stored Payload block data for a markdown block instance.\n */\nexport interface MarkdownBlockData {\n /**\n * Optional block display name assigned by Payload.\n */\n blockName?: null | string\n\n /**\n * The Payload block slug.\n */\n blockType: 'vlMdBlock'\n\n /**\n * Markdown source content for this block.\n */\n content: string\n\n /**\n * Optional Payload-generated block identifier.\n */\n id?: null | string\n}\n\n/**\n * Props for the markdown block component wrapper.\n */\nexport interface MarkdownBlockProps extends MarkdownBlockData {\n /**\n * The slug of the collection this block is rendered within, if applicable.\n */\n collectionSlug?: string\n}\n"],"names":[],"mappings":"AA4TA;;CAEC,GACD,WAKC"}
1
+ {"version":3,"sources":["../../src/types/core.ts"],"sourcesContent":["import type { JSX, ReactNode } from 'react'\n\nexport type MarkdownRendererScope = 'blocks' | 'field'\n\n/**\n * Options that control how fenced code blocks are rendered inside markdown content.\n *\n * By default, code blocks use the plugin's enhanced rendering mode:\n * - `enhancedCodeBlocks` defaults to `true`\n * - `lineNumbers` defaults to `true`\n * - `theme` defaults to `'github-dark'`\n *\n * When enhanced rendering is enabled, the plugin applies its normalized code block\n * pipeline on top of Shiki output. This includes layout cleanup, background\n * normalization, and support for features like line numbers.\n *\n * When enhanced rendering is disabled, code blocks are rendered closer to raw\n * Shiki output and plugin-specific enhancements are bypassed.\n *\n * These options are passed through the markdown rendering pipeline and primarily\n * affect Shiki-rendered code fences.\n */\nexport type RenderMarkdownOptions = {\n /**\n * Whether to apply the plugin's enhanced code block rendering pipeline.\n *\n * Defaults to `true`.\n *\n * When enabled, the renderer performs structural and visual normalization on\n * Shiki output to produce a consistent, content-focused appearance.\n *\n * When disabled, code blocks are rendered closer to raw Shiki output.\n */\n enhancedCodeBlocks?: boolean\n\n /**\n * An optional list of language identifiers to load for Shiki syntax highlighting.\n *\n * By default, the plugin loads a core set of popular languages. You can replace\n * that set entirely or extend it using spread syntax:\n *\n * ```ts\n * options: {\n * langs: [...DEFAULT_CODE_LANGS, 'latex']\n * }\n * ```\n */\n langs?: string[]\n\n /**\n * Whether to show line numbers for fenced code blocks.\n *\n * Defaults to `true` when `enhancedCodeBlocks` is enabled.\n *\n * Line numbers require the enhanced rendering pipeline and are automatically\n * disabled when `enhancedCodeBlocks` is set to `false`.\n */\n lineNumbers?: boolean\n\n /**\n * The Shiki theme to use for syntax highlighting.\n *\n * Defaults to `'github-dark'`.\n *\n * The plugin's enhanced renderer is tuned around its default theme. When using a\n * non-default theme:\n *\n * - `enhancedCodeBlocks: true` opts into the plugin's normalized rendering pipeline\n * - `enhancedCodeBlocks: false` preserves the theme's native appearance more closely\n *\n * This allows you to choose between a more controlled presentation and a more\n * theme-faithful rendering mode.\n */\n theme?: string\n}\n\nexport type MarkdownCodeConfig = {\n /**\n * Whether to apply the plugin's enhanced code block rendering pipeline.\n */\n enhanced?: boolean\n\n /**\n * Whether fenced code blocks should extend beyond the normal content width\n * on larger screens.\n */\n fullBleed?: boolean\n\n /**\n * Optional list of language identifiers to load for Shiki syntax highlighting.\n */\n langs?: string[]\n\n /**\n * Whether to show line numbers for fenced code blocks.\n */\n lineNumbers?: boolean\n\n /**\n * The Shiki theme to use for syntax highlighting.\n */\n shikiTheme?: string\n}\n\nexport type MarkdownDirectiveTheme = {\n classes: string\n label?: string\n name: string\n}\n\nexport type MarkdownDirectiveThemeGroup = {\n extendDefaults?: boolean\n items?: MarkdownDirectiveTheme[]\n} | MarkdownDirectiveTheme[]\n\nexport type MarkdownDirectiveThemes = {\n callout?: MarkdownDirectiveThemeGroup\n card?: MarkdownDirectiveThemeGroup\n cards?: MarkdownDirectiveThemeGroup\n cell?: MarkdownDirectiveThemeGroup\n columns?: MarkdownDirectiveThemeGroup\n details?: MarkdownDirectiveThemeGroup\n section?: MarkdownDirectiveThemeGroup\n steps?: MarkdownDirectiveThemeGroup\n tab?: MarkdownDirectiveThemeGroup\n tabs?: MarkdownDirectiveThemeGroup\n toc?: MarkdownDirectiveThemeGroup\n}\n\nexport type PayloadMarkdownIconPack = {\n alias: string\n path: string\n}\n\nexport type PayloadMarkdownIconsConfig = {\n baseDir: string\n packs: PayloadMarkdownIconPack[]\n}\n\n/**\n * The result of compiling markdown into sanitized HTML.\n */\nexport type RenderMarkdownResult = {\n /**\n * The rendered HTML output.\n */\n html: string\n\n /**\n * Non-fatal warnings produced during rendering.\n */\n warnings: string[]\n}\n\n/**\n * Preset visual styles for rendered markdown content.\n */\nexport type MarkdownVariant = 'blog' | 'compact' | 'docs' | 'unstyled'\n\n/**\n * Preset typography sizes for rendered markdown content.\n */\nexport type MarkdownSize = 'lg' | 'md' | 'sm'\n\n/**\n * Core markdown presentation configuration.\n *\n * This type represents the configurable styling and behavior layer that can be\n * sourced from plugin defaults, globals, collection defaults, or block-level\n * overrides. It intentionally excludes runtime-only renderer props such as\n * `markdown`, `as`, and fallback nodes.\n */\nexport type MarkdownConfig = {\n /**\n * Additional classes applied to the rendered markdown element itself.\n */\n className?: string\n\n /**\n * Additional classes applied to column elements within the rendered markdown, if applicable.\n *\n * @deprecated Use directive themes instead.\n */\n columnClassName?: string\n\n /**\n * Whether to apply horizontal gutter padding to the outer wrapper.\n *\n * Defaults to `false`.\n */\n enableGutter?: boolean\n\n /**\n * Whether fenced code blocks should extend beyond the normal content width\n * on larger screens.\n *\n * Defaults to `false`.\n *\n * @deprecated Use top-level or renderer-level `code.fullBleed` instead.\n */\n fullBleedCode?: boolean\n\n /**\n * Optional content rendered above the markdown body.\n */\n lead?: ReactNode\n\n /**\n * Whether heading colors should be slightly muted.\n *\n * Defaults to `false`.\n */\n mutedHeadings?: boolean\n\n /**\n * Options that control fenced code block rendering.\n *\n * @deprecated Use top-level or renderer-level `code` instead.\n */\n options?: RenderMarkdownOptions\n\n /**\n * Additional classes applied to section elements within the rendered markdown, if applicable.\n *\n * @deprecated Use directive themes instead.\n */\n sectionClassName?: string\n\n /**\n * Typography size preset for the rendered markdown.\n *\n * Defaults to `'lg'`.\n */\n size?: MarkdownSize\n\n /**\n * Visual style preset for the rendered markdown.\n *\n * Defaults to `'blog'`.\n */\n variant?: MarkdownVariant\n\n /**\n * Additional classes applied to the outer wrapper element.\n */\n wrapperClassName?: string\n}\n\nexport type MarkdownRenderConfig = {\n code?: MarkdownCodeConfig\n icons?: PayloadMarkdownIconsConfig\n themes?: MarkdownDirectiveThemes\n} & MarkdownConfig\n\n/**\n * Runtime-only props shared by markdown renderer components.\n */\nexport type BaseMarkdownRendererProps = {\n /**\n * The HTML tag used for the rendered markdown container.\n *\n * Defaults to `'article'`.\n */\n as?: keyof JSX.IntrinsicElements\n\n /**\n * Content rendered when the markdown input is empty or missing.\n */\n emptyFallback?: ReactNode\n\n /**\n * Content rendered when markdown compilation fails and a fallback is desired.\n */\n errorFallback?: ReactNode\n\n /**\n * The markdown source string to render.\n */\n markdown?: null | string\n}\n\n/**\n * Props for the main markdown renderer component.\n *\n * This merges persisted/configurable markdown presentation settings with the\n * runtime-only rendering props required by the component itself.\n */\nexport type MarkdownRendererProps = {\n collectionSlug?: string\n scope?: MarkdownRendererScope\n} & BaseMarkdownRendererProps & MarkdownRenderConfig\n\n/**\n * Options available while rendering an individual fenced code block.\n */\nexport interface CodeBlockOptions extends RenderMarkdownOptions {\n /**\n * The parsed language identifier for the fenced code block, if present.\n */\n lang?: string\n}\n\n/**\n * Stored Payload block data for a markdown block instance.\n */\nexport interface MarkdownBlockData {\n /**\n * Optional block display name assigned by Payload.\n */\n blockName?: null | string\n\n /**\n * The Payload block slug.\n */\n blockType: 'vlMdBlock'\n\n /**\n * Markdown source content for this block.\n */\n content: string\n\n /**\n * Optional Payload-generated block identifier.\n */\n id?: null | string\n}\n\n/**\n * Props for the markdown block component wrapper.\n */\nexport interface MarkdownBlockProps extends MarkdownBlockData {\n /**\n * The slug of the collection this block is rendered within, if applicable.\n */\n collectionSlug?: string\n}\n"],"names":[],"mappings":"AAuUA;;CAEC,GACD,WAKC"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/types/mdast.d.ts"],"sourcesContent":["/**\n * @import {} from 'mdast-util-directive'\n */\n\nimport 'mdast-util-directive'\n\nimport type { LayoutToken } from './layoutToken'\n\ndeclare module 'mdast-util-directive' {\n interface ContainerDirectiveData {\n vlCellHeadingDepth?: number\n vlParentHeadingDepth?: number\n }\n}\n\ndeclare module 'mdast' {\n interface RootContentMap {\n vlLayoutToken: LayoutToken\n }\n}\n"],"names":[],"mappings":"AAAA;;CAEC,GAED,OAAO,uBAAsB"}
1
+ {"version":3,"sources":["../../src/types/mdast.d.ts"],"sourcesContent":["/**\n * @import {} from 'mdast-util-directive'\n */\n\nimport 'mdast-util-directive'\n\nimport type { LayoutToken } from './layoutToken'\n\ndeclare module 'mdast-util-directive' {\n interface ContainerDirectiveData {\n vlCellHeadingDepth?: number\n vlDirectiveLabel?: string\n vlParentHeadingDepth?: number\n }\n\n interface LeafDirectiveData {\n hChildren?: unknown[]\n hName?: string\n hProperties?: Record<string, unknown>\n }\n}\n\ndeclare module 'mdast' {\n interface RootContentMap {\n vlLayoutToken: LayoutToken\n }\n}\n"],"names":[],"mappings":"AAAA;;CAEC,GAED,OAAO,uBAAsB"}
package/dist/types.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import type { CollectionSlug, TextField } from 'payload';
2
- import type { MarkdownCodeConfig, MarkdownConfig, MarkdownDirectiveThemes } from './types/core.js';
2
+ import type { MarkdownCodeConfig, MarkdownConfig, MarkdownDirectiveThemes, PayloadMarkdownIconsConfig } from './types/core.js';
3
3
  export type DualMarkdownFieldConfig = {
4
4
  blocks?: MarkdownConfig;
5
5
  field?: MarkdownConfig;
@@ -73,6 +73,10 @@ export interface PayloadMarkdownConfig {
73
73
  * @default false
74
74
  */
75
75
  enabled?: boolean;
76
+ /**
77
+ * Local SVG icon pack configuration for markdown directives.
78
+ */
79
+ icons?: PayloadMarkdownIconsConfig;
76
80
  /**
77
81
  * Directive theme registry extensions.
78
82
  */
package/dist/types.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/types.ts"],"sourcesContent":["import type { CollectionSlug, TextField } from 'payload'\n\nimport type { MarkdownCodeConfig, MarkdownConfig, MarkdownDirectiveThemes } from './types/core.js'\n\nexport type DualMarkdownFieldConfig = {\n blocks?: MarkdownConfig\n field?: MarkdownConfig\n}\n\nexport type ConfigOptions = DualMarkdownFieldConfig | MarkdownConfig\n\nexport type MarkdownFieldOptions = {\n admin?: Partial<TextField['admin']>\n defaultValue?: string\n label?: string\n localized?: boolean\n name?: string\n required?: boolean\n}\n\nexport type PayloadMarkdownCollectionConfig = {\n /**\n * Code fence / Shiki rendering options for markdown in this collection.\n */\n code?: MarkdownCodeConfig\n\n /**\n * Styling options for markdown fields added to the collection, and/or markdown fields added within blocks to the collection.\n */\n config?: ConfigOptions\n\n /**\n * Options for the markdown field.\n */\n field?: Omit<MarkdownFieldOptions, 'name'>\n\n /**\n * The name of the markdown field to add to the collection. Defaults to 'content'.\n */\n fieldName?: string\n\n /**\n * Whether to add a standalone markdown field to the collection.\n *\n * If not specified, this is inferred automatically:\n * - `true` when the collection does not contain any `blocks` fields\n * - `false` when the collection does contain `blocks` fields\n */\n installField?: boolean\n\n /**\n * Whether to install the markdown block into any `blocks` fields in the collection.\n *\n * If not specified, this is inferred automatically:\n * - `true` when the collection contains one or more `blocks` fields\n * - `false` when the collection does not contain any `blocks` fields\n *\n * Note: You must still add the MarkdownBlockComponent to your RenderBlocks.tsx\n * or equivalent for the block to render properly.\n */\n installIntoBlocks?: boolean\n\n /**\n * Directive theme registry extensions for markdown in this collection.\n */\n themes?: MarkdownDirectiveThemes\n}\n\nexport interface PayloadMarkdownConfig {\n /**\n * Code fence / Shiki rendering options.\n */\n code?: MarkdownCodeConfig\n\n /**\n * Add markdown field to collections.\n * Set to `true` to add a field with default options, or an object to configure the field.\n */\n collections?: Partial<Record<CollectionSlug, PayloadMarkdownCollectionConfig | true>>\n\n /**\n * Add a global for markdown block settings, which can be used to provide default configuration values for all markdown in the project.\n */\n config?: ConfigOptions\n\n /**\n * Enable or disable plugin\n * @default false\n */\n enabled?: boolean\n\n /**\n * Directive theme registry extensions.\n */\n themes?: MarkdownDirectiveThemes\n}\n"],"names":[],"mappings":"AAoEA,WA2BC"}
1
+ {"version":3,"sources":["../src/types.ts"],"sourcesContent":["import type { CollectionSlug, TextField } from 'payload'\n\nimport type {\n MarkdownCodeConfig,\n MarkdownConfig,\n MarkdownDirectiveThemes,\n PayloadMarkdownIconsConfig,\n} from './types/core.js'\n\nexport type DualMarkdownFieldConfig = {\n blocks?: MarkdownConfig\n field?: MarkdownConfig\n}\n\nexport type ConfigOptions = DualMarkdownFieldConfig | MarkdownConfig\n\nexport type MarkdownFieldOptions = {\n admin?: Partial<TextField['admin']>\n defaultValue?: string\n label?: string\n localized?: boolean\n name?: string\n required?: boolean\n}\n\nexport type PayloadMarkdownCollectionConfig = {\n /**\n * Code fence / Shiki rendering options for markdown in this collection.\n */\n code?: MarkdownCodeConfig\n\n /**\n * Styling options for markdown fields added to the collection, and/or markdown fields added within blocks to the collection.\n */\n config?: ConfigOptions\n\n /**\n * Options for the markdown field.\n */\n field?: Omit<MarkdownFieldOptions, 'name'>\n\n /**\n * The name of the markdown field to add to the collection. Defaults to 'content'.\n */\n fieldName?: string\n\n /**\n * Whether to add a standalone markdown field to the collection.\n *\n * If not specified, this is inferred automatically:\n * - `true` when the collection does not contain any `blocks` fields\n * - `false` when the collection does contain `blocks` fields\n */\n installField?: boolean\n\n /**\n * Whether to install the markdown block into any `blocks` fields in the collection.\n *\n * If not specified, this is inferred automatically:\n * - `true` when the collection contains one or more `blocks` fields\n * - `false` when the collection does not contain any `blocks` fields\n *\n * Note: You must still add the MarkdownBlockComponent to your RenderBlocks.tsx\n * or equivalent for the block to render properly.\n */\n installIntoBlocks?: boolean\n\n /**\n * Directive theme registry extensions for markdown in this collection.\n */\n themes?: MarkdownDirectiveThemes\n}\n\nexport interface PayloadMarkdownConfig {\n /**\n * Code fence / Shiki rendering options.\n */\n code?: MarkdownCodeConfig\n\n /**\n * Add markdown field to collections.\n * Set to `true` to add a field with default options, or an object to configure the field.\n */\n collections?: Partial<Record<CollectionSlug, PayloadMarkdownCollectionConfig | true>>\n\n /**\n * Add a global for markdown block settings, which can be used to provide default configuration values for all markdown in the project.\n */\n config?: ConfigOptions\n\n /**\n * Enable or disable plugin\n * @default false\n */\n enabled?: boolean\n\n /**\n * Local SVG icon pack configuration for markdown directives.\n */\n icons?: PayloadMarkdownIconsConfig\n\n /**\n * Directive theme registry extensions.\n */\n themes?: MarkdownDirectiveThemes\n}\n"],"names":[],"mappings":"AAyEA,WAgCC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@valkyrianlabs/payload-markdown",
3
- "version": "1.3.4",
3
+ "version": "1.4.0",
4
4
  "description": "Structured Markdown editing and rendering for Payload CMS with CodeMirror, Shiki, directives, themes, and server-first output.",
5
5
  "repository": {
6
6
  "url": "https://github.com/valkyrianlabs/payload-markdown"