@purview-dev/astroc4 1.0.0-prerelease.7 → 1.0.0-prerelease.8

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.
@@ -34,6 +34,45 @@ var translations = {
34
34
  }
35
35
  };
36
36
 
37
+ // src/validation.ts
38
+ function globToRegExp(pattern) {
39
+ let body = "";
40
+ for (let index = 0;index < pattern.length; index += 1) {
41
+ const char = pattern[index];
42
+ if (char === "*") {
43
+ if (pattern[index + 1] === "*") {
44
+ body += ".*";
45
+ index += 1;
46
+ } else {
47
+ body += "[^/]*";
48
+ }
49
+ } else if (char === "?") {
50
+ body += "[^/]";
51
+ } else if (".+^${}()|[]\\".includes(char)) {
52
+ body += `\\${char}`;
53
+ } else {
54
+ body += char;
55
+ }
56
+ }
57
+ return new RegExp(`^(?:.*/)?${body}$`);
58
+ }
59
+ var toSlashes = (value) => value.replaceAll("\\", "/");
60
+ function validationModeFor(options, relativePath, collection) {
61
+ if (options === undefined)
62
+ return "strict";
63
+ if (typeof options === "string")
64
+ return options;
65
+ const fallback = options.default ?? "strict";
66
+ const collections = options.collections === undefined ? [] : [options.collections].flat();
67
+ if (collection !== undefined && collections.includes(collection))
68
+ return "relaxed";
69
+ if (relativePath === undefined)
70
+ return fallback;
71
+ const patterns = options.relaxed === undefined ? [] : [options.relaxed].flat();
72
+ const path = toSlashes(relativePath);
73
+ return patterns.some((pattern) => globToRegExp(pattern).test(path)) ? "relaxed" : fallback;
74
+ }
75
+
37
76
  // src/fences.ts
38
77
  var require2 = createRequire(import.meta.url);
39
78
  var likec4ApiPromise;
@@ -53,6 +92,7 @@ var IMPORTS = {
53
92
  [PROJECT_COMPONENT]: `${PACKAGE_NAME}/components/LikeC4View.astro`
54
93
  };
55
94
  var STRINGS = translations.en;
95
+ var RELAXED_NOTE = "Left as a highlighted code block because this page is validated in `relaxed` mode.";
56
96
  var layoutCache = new Map;
57
97
  function parseFenceMeta(meta) {
58
98
  const options = {};
@@ -120,7 +160,23 @@ function describe(fileURL) {
120
160
  return String(fileURL);
121
161
  }
122
162
  }
123
- function likec4Fences({ root, projects } = {}) {
163
+ function pagePath(fileURL, root) {
164
+ if (!fileURL || !root)
165
+ return;
166
+ try {
167
+ return relative(resolve(root), fileURLToPath(fileURL));
168
+ } catch {
169
+ return;
170
+ }
171
+ }
172
+ function collectionOf(fileURL, contentDir) {
173
+ const within = pagePath(fileURL, contentDir);
174
+ if (!within || within.startsWith(".."))
175
+ return;
176
+ const [first, ...rest] = within.split(/[\\/]/);
177
+ return rest.length > 0 ? first : undefined;
178
+ }
179
+ function likec4Fences({ root, projects, validation, contentDir, onInvalid } = {}) {
124
180
  return (factory) => {
125
181
  if (!factory.source.includes("```" + FENCE_LANG))
126
182
  return null;
@@ -131,9 +187,21 @@ function likec4Fences({ root, projects } = {}) {
131
187
  async code(node, ctx) {
132
188
  if (node.lang !== FENCE_LANG)
133
189
  return;
190
+ const mode = validationModeFor(validation, pagePath(ctx.fileURL, root), collectionOf(ctx.fileURL, contentDir));
191
+ const fail = (reason) => {
192
+ if (mode === "strict")
193
+ throw new Error(reason);
194
+ onInvalid?.(`${reason} ${RELAXED_NOTE}`);
195
+ };
134
196
  const where = `${describe(ctx.fileURL)}: \`\`\`${FENCE_LANG} fence`;
135
197
  const options = parseFenceMeta(node.meta);
136
- const source = options.file ? await readFenceFile(options.file, ctx.fileURL, root, where) : (node.value ?? "").trim();
198
+ let source;
199
+ try {
200
+ source = options.file ? await readFenceFile(options.file, ctx.fileURL, root, where) : (node.value ?? "").trim();
201
+ } catch (error) {
202
+ fail(error instanceof Error ? error.message : String(error));
203
+ return;
204
+ }
137
205
  const common = {
138
206
  title: options.title,
139
207
  description: options.description,
@@ -143,9 +211,14 @@ function likec4Fences({ root, projects } = {}) {
143
211
  };
144
212
  if (source.length === 0) {
145
213
  if (!options.view) {
146
- throw new Error(`${where} is empty, so it needs \`view="<id>"\` to name a view in the project model.`);
214
+ fail(`${where} is empty, so it needs \`view="<id>"\` to name a view in the project model.`);
215
+ return;
216
+ }
217
+ const projectFailure = projectError(options.project, projects, where);
218
+ if (projectFailure !== undefined) {
219
+ fail(projectFailure);
220
+ return;
147
221
  }
148
- checkProject(options.project, projects, where);
149
222
  if (markdown) {
150
223
  ctx.replaceNode(node, {
151
224
  raw: fencePlaceholder({ ...placeholderOptions(options), viewId: options.view, project: options.project }),
@@ -166,11 +239,13 @@ function likec4Fences({ root, projects } = {}) {
166
239
  try {
167
240
  layout = await layoutSource(source);
168
241
  } catch (error) {
169
- throw new Error(`${where} is not valid LikeC4 — ${error instanceof Error ? error.message : String(error)}`);
242
+ fail(`${where} is not valid LikeC4 — ${error instanceof Error ? error.message : String(error)}`);
243
+ return;
170
244
  }
171
245
  const viewId = options.view ?? defaultView(source, layout.viewIds);
172
246
  if (!viewId || !layout.viewIds.includes(viewId)) {
173
- throw new Error(`${where} has no view "${viewId ?? "(none)"}". Declared: ${layout.viewIds.join(", ") || "(none)"}.`);
247
+ fail(`${where} has no view "${viewId ?? "(none)"}". Declared: ${layout.viewIds.join(", ") || "(none)"}.`);
248
+ return;
174
249
  }
175
250
  if (markdown) {
176
251
  ctx.replaceNode(node, {
@@ -195,20 +270,18 @@ function likec4Fences({ root, projects } = {}) {
195
270
  };
196
271
  };
197
272
  }
198
- function checkProject(project, projects, where) {
273
+ function projectError(project, projects, where) {
199
274
  if (projects === undefined)
200
275
  return;
201
276
  const requested = project?.trim();
202
277
  const available = projects.join(", ");
203
278
  if (!requested) {
204
- if (projects.length > 1) {
205
- throw new Error(`${where}: ${STRINGS["likec4.error.projectRequired"].replace("{available}", available)}`);
206
- }
207
- return;
279
+ return projects.length > 1 ? `${where}: ${STRINGS["likec4.error.projectRequired"].replace("{available}", available)}` : undefined;
208
280
  }
209
281
  if (!projects.includes(requested)) {
210
- throw new Error(`${where}: ${STRINGS["likec4.error.unknownProject"].replace("{projectId}", requested).replace("{available}", available || "(none)")}`);
282
+ return `${where}: ${STRINGS["likec4.error.unknownProject"].replace("{projectId}", requested).replace("{available}", available || "(none)")}`;
211
283
  }
284
+ return;
212
285
  }
213
286
  function defaultView(source, viewIds) {
214
287
  for (const match of source.matchAll(/(?<![\w-])view\s+([\w-]+)/g)) {
@@ -725,7 +798,8 @@ function resolvesFrom(specifier, root) {
725
798
  function likec4Integration({
726
799
  vitePlugin = {},
727
800
  projects,
728
- fences = true
801
+ fences = true,
802
+ validation
729
803
  } = {}) {
730
804
  let icons;
731
805
  return {
@@ -744,7 +818,7 @@ function likec4Integration({
744
818
  }
745
819
  });
746
820
  if (fences) {
747
- await registerFences(config, updateConfig, logger, resolved);
821
+ await registerFences(config, updateConfig, logger, resolved, validation);
748
822
  injectScript("page", MD_FENCES_SCRIPT);
749
823
  }
750
824
  await ensureReactRenderer(config, updateConfig, logger);
@@ -793,12 +867,15 @@ async function ensureReactRenderer(config, updateConfig, logger) {
793
867
  logger.warn("@astrojs/react is not installed, so <LikeC4View> cannot render. Install it (`astro add react`).");
794
868
  }
795
869
  }
796
- async function registerFences(config, updateConfig, logger, projects) {
870
+ async function registerFences(config, updateConfig, logger, projects, validation) {
797
871
  const { satteri, isSatteriProcessor } = await import("@astrojs/markdown-satteri");
798
872
  const existing = config.markdown?.processor;
799
873
  const fences = () => likec4Fences({
800
874
  root: fileURLToPath4(config.root),
801
- projects: projects.length > 0 ? projects.map((project) => project.name) : undefined
875
+ contentDir: config.srcDir ? fileURLToPath4(new URL("content/", config.srcDir)) : undefined,
876
+ projects: projects.length > 0 ? projects.map((project) => project.name) : undefined,
877
+ validation,
878
+ onInvalid: (message) => logger.warn(message)
802
879
  });
803
880
  if (existing === undefined) {
804
881
  updateConfig({ markdown: { processor: satteri({ mdastPlugins: [fences()] }) } });
@@ -826,5 +903,5 @@ export {
826
903
  missingOptimizedDependencies
827
904
  };
828
905
 
829
- //# debugId=7D3E2F75E2D8075C64756E2164756E21
906
+ //# debugId=8CC5199B7D8470E564756E2164756E21
830
907
  //# sourceMappingURL=integration.js.map
@@ -1,17 +1,18 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../src/integration.ts", "../src/fences.ts", "../src/translations.ts", "../src/file-layout.ts", "../src/icon-plugin.ts", "../src/icon-assets.ts", "../src/projects.ts", "../src/workspace.ts"],
3
+ "sources": ["../src/integration.ts", "../src/fences.ts", "../src/translations.ts", "../src/validation.ts", "../src/file-layout.ts", "../src/icon-plugin.ts", "../src/icon-assets.ts", "../src/projects.ts", "../src/workspace.ts"],
4
4
  "sourcesContent": [
5
- "import { existsSync } from 'node:fs';\nimport { dirname, join, resolve } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nimport type { AstroConfig, AstroIntegration, AstroIntegrationLogger } from 'astro';\nimport { LikeC4VitePlugin } from 'likec4/vite-plugin';\nimport type { Plugin as VitePlugin } from 'vite';\n\nimport { likec4Fences, preloadLikeC4 } from './fences.ts';\nimport { fileLayoutPlugin } from './file-layout.ts';\nimport { astroc4IconPlugin, type Astroc4IconPlugin } from './icon-plugin.ts';\nimport { discoverProjects, resolveProjects, type ResolvedProject } from './projects.ts';\nimport { prepareWorkspace, PROJECTS_MODULE_ID, projectsModule } from './workspace.ts';\n\n/** Scoped because npm refuses the unscoped `astroc4` as too similar to `astro`. */\nexport const PACKAGE_NAME = '@purview-dev/astroc4';\n\nexport interface LikeC4IntegrationOptions {\n\t/**\n\t * Passed through to `LikeC4VitePlugin`. Setting `workspace` or\n\t * `languageServices` takes project discovery over, and `projects` is ignored.\n\t */\n\tvitePlugin?: Parameters<typeof LikeC4VitePlugin>[0];\n\t/**\n\t * Named LikeC4 projects, compiled alongside those discovered under the site\n\t * root: `{ architecture: '../../docs/architecture/likec4' }`. Folders are\n\t * relative to the site root or absolute.\n\t */\n\tprojects?: Record<string, string>;\n\t/** Render ```likec4 fences in .md and .mdx pages as diagrams. Defaults to `true`. */\n\tfences?: boolean;\n}\n\n/**\n * `likec4/react` is built with the React Compiler and imports `c` from\n * `react/compiler-runtime`, which React 19 ships as CommonJS. Unless Vite\n * pre-bundles it, `astro dev` serves it raw and every island fails with\n * \"does not provide an export named 'c'\" — while `astro build` stays green.\n */\nconst OPTIMIZED_DEPENDENCIES = ['react/compiler-runtime'];\n\n/**\n * Mounts the fences of .md pages. Injected into every page, so React and LikeC4\n * are only `import()`ed on a page that has a placeholder.\n *\n * In dev, @astrojs/react installs React's fast-refresh preamble only on pages with\n * an island, and a .md page has none, so the script installs it first. Outside dev,\n * @vitejs/plugin-react serves the preamble module empty.\n */\nconst MD_FENCES_SCRIPT = [\n\t`const mountLikeC4Fences = () => {`,\n\t` if (!document.querySelector('[data-astroc4-fence]:not([data-astroc4-mounted])')) return;`,\n\t` const preamble = window.$RefreshReg$ ? Promise.resolve() : import('@vitejs/plugin-react/preamble');`,\n\t` preamble`,\n\t` .then(() => import('${PACKAGE_NAME}/components/md-fences'))`,\n\t` .then((module) => module.mountFences());`,\n\t`};`,\n\t`if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', mountLikeC4Fences);`,\n\t`else mountLikeC4Fences();`,\n\t`document.addEventListener('astro:page-load', mountLikeC4Fences);`,\n].join('\\n');\n\n/**\n * The `optimizeDeps.include` entries the site still lacks. Only missing ones:\n * Vite's `mergeConfig` concatenates arrays. Unresolvable ones are skipped, since\n * naming a package Vite cannot find breaks the optimizer.\n */\nexport function missingOptimizedDependencies(include: unknown, root: string): string[] {\n\tconst existing = Array.isArray(include) ? include : [];\n\n\treturn OPTIMIZED_DEPENDENCIES.filter(\n\t\t(dependency) => !existing.includes(dependency) && resolvesFrom(dependency, root),\n\t);\n}\n\n// Walks node_modules as Vite does: under Bun, `createRequire` also finds\n// packages in Bun's global cache, which Vite never looks in.\nfunction resolvesFrom(specifier: string, root: string): boolean {\n\tconst name = specifier.split('/', specifier.startsWith('@') ? 2 : 1).join('/');\n\n\tfor (let dir = resolve(root); ; dir = dirname(dir)) {\n\t\tif (existsSync(join(dir, 'node_modules', name, 'package.json'))) return true;\n\t\tif (dirname(dir) === dir) return false;\n\t}\n}\n\nexport function likec4Integration({\n\tvitePlugin = {},\n\tprojects,\n\tfences = true,\n}: LikeC4IntegrationOptions = {}): AstroIntegration {\n\tlet icons: Astroc4IconPlugin | undefined;\n\n\treturn {\n\t\tname: `${PACKAGE_NAME}/integration`,\n\t\thooks: {\n\t\t\t'astro:config:setup': async ({ command, config, updateConfig, injectScript, logger }) => {\n\t\t\t\tconst root = fileURLToPath(config.root);\n\t\t\t\tconst optimizeDeps = missingOptimizedDependencies(config.vite?.optimizeDeps?.include, root);\n\t\t\t\tconst { pluginOptions, resolved, stagingDir } = await workspaceFor(root, vitePlugin, projects, logger);\n\n\t\t\t\ticons = astroc4IconPlugin({ projects: resolved, base: config.base ?? '/', siteRoot: root, stagingDir });\n\n\t\t\t\tupdateConfig({\n\t\t\t\t\tvite: {\n\t\t\t\t\t\tplugins: [LikeC4VitePlugin(pluginOptions), projectsPlugin(resolved), icons, fileLayoutPlugin()],\n\t\t\t\t\t\t// The components ship as .astro/.tsx source for Vite to transform.\n\t\t\t\t\t\tssr: { noExternal: [PACKAGE_NAME] },\n\t\t\t\t\t\t...(optimizeDeps.length > 0 ? { optimizeDeps: { include: optimizeDeps } } : {}),\n\t\t\t\t\t},\n\t\t\t\t});\n\n\t\t\t\tif (fences) {\n\t\t\t\t\tawait registerFences(config, updateConfig, logger, resolved);\n\t\t\t\t\tinjectScript('page', MD_FENCES_SCRIPT);\n\t\t\t\t}\n\n\t\t\t\tawait ensureReactRenderer(config, updateConfig, logger);\n\n\t\t\t\t// Build only: loading LikeC4 eagerly in dev restarts the server (see ./fences.ts).\n\t\t\t\tif (command === 'build') {\n\t\t\t\t\tawait preloadLikeC4();\n\t\t\t\t}\n\t\t\t},\n\t\t\t'astro:build:done': async ({ dir }) => {\n\t\t\t\tawait icons?.emit(fileURLToPath(dir));\n\t\t\t},\n\t\t},\n\t};\n}\n\n/**\n * The options `LikeC4VitePlugin` gets, and the projects pages can name. With\n * `projects`, every project is linked into one staging workspace, because the\n * plugin compiles a single folder.\n */\nasync function workspaceFor(\n\troot: string,\n\tvitePlugin: NonNullable<LikeC4IntegrationOptions['vitePlugin']>,\n\tconfigured: Record<string, string> | undefined,\n\tlogger: AstroIntegrationLogger,\n): Promise<{\n\tpluginOptions: NonNullable<LikeC4IntegrationOptions['vitePlugin']>;\n\tresolved: ResolvedProject[];\n\tstagingDir?: string;\n}> {\n\tconst hasConfigured = configured !== undefined && Object.keys(configured).length > 0;\n\n\tif (vitePlugin.workspace !== undefined || 'languageServices' in vitePlugin) {\n\t\tif (hasConfigured) {\n\t\t\tlogger.warn(\n\t\t\t\t'`projects` is ignored because `vitePlugin.workspace` or `vitePlugin.languageServices` is set; remove one of them.',\n\t\t\t);\n\t\t}\n\n\t\treturn { pluginOptions: vitePlugin, resolved: [] };\n\t}\n\n\tconst discovered = await discoverProjects(root);\n\n\tif (!hasConfigured) {\n\t\treturn { pluginOptions: vitePlugin, resolved: discovered };\n\t}\n\n\tconst resolved = await resolveProjects({ root, configured, discovered });\n\tconst workspace = await prepareWorkspace(resolved, join(root, '.astro', 'astroc4'));\n\n\treturn { pluginOptions: { ...(vitePlugin as { workspace?: string }), workspace }, resolved, stagingDir: workspace };\n}\n\n/** Serves `virtual:astroc4/projects`: the names components may pass as `project`. */\nfunction projectsPlugin(projects: ResolvedProject[]): VitePlugin {\n\tconst resolvedId = `\\0${PROJECTS_MODULE_ID}`;\n\n\treturn {\n\t\tname: `${PACKAGE_NAME}/projects`,\n\t\tresolveId: (id) => (id === PROJECTS_MODULE_ID ? resolvedId : undefined),\n\t\tload: (id) => (id === resolvedId ? projectsModule(projects) : undefined),\n\t};\n}\n\n/**\n * Add `@astrojs/react` when the site has not: without a renderer the\n * `client:only=\"react\"` islands fail with Astro's generic \"no renderer\" error.\n * Integrations pushed here still have their hooks run in this pass. MDX and\n * Expressive Code are left to the site, because they change its content types\n * and code blocks.\n */\nasync function ensureReactRenderer(\n\tconfig: AstroConfig,\n\tupdateConfig: (config: Record<string, unknown>) => void,\n\tlogger: AstroIntegrationLogger,\n): Promise<void> {\n\tif (config.integrations.some((integration) => integration.name === '@astrojs/react')) return;\n\n\ttry {\n\t\tconst { default: react } = await import('@astrojs/react');\n\n\t\tupdateConfig({ integrations: [react()] });\n\t\tlogger.info('added @astrojs/react: the LikeC4 diagrams are React islands (client:only=\"react\").');\n\t} catch {\n\t\tlogger.warn(\n\t\t\t'@astrojs/react is not installed, so <LikeC4View> cannot render. Install it (`astro add react`).',\n\t\t);\n\t}\n}\n\n/** Append the fence transform to the site's Sätteri processor, keeping its plugins. */\nasync function registerFences(\n\tconfig: AstroConfig,\n\tupdateConfig: (config: Record<string, unknown>) => void,\n\tlogger: AstroIntegrationLogger,\n\tprojects: ResolvedProject[],\n): Promise<void> {\n\tconst { satteri, isSatteriProcessor } = await import('@astrojs/markdown-satteri');\n\tconst existing = config.markdown?.processor;\n\tconst fences = () =>\n\t\tlikec4Fences({\n\t\t\troot: fileURLToPath(config.root),\n\t\t\t// Empty when the site took discovery over: then only the browser knows.\n\t\t\tprojects: projects.length > 0 ? projects.map((project) => project.name) : undefined,\n\t\t});\n\n\t// No processor configured means Astro's default, which is Sätteri.\n\tif (existing === undefined) {\n\t\tupdateConfig({ markdown: { processor: satteri({ mdastPlugins: [fences()] }) } });\n\t\treturn;\n\t}\n\n\tif (!isSatteriProcessor(existing)) {\n\t\tlogger.warn(\n\t\t\t'```likec4 fences are disabled: the site is not using the Sätteri Markdown processor. ' +\n\t\t\t\t'<LikeC4View /> still works.',\n\t\t);\n\t\treturn;\n\t}\n\n\tconst existingOptions = existing.options ?? {};\n\n\tupdateConfig({\n\t\tmarkdown: {\n\t\t\tprocessor: satteri({\n\t\t\t\t...existingOptions,\n\t\t\t\tmdastPlugins: [...(existingOptions.mdastPlugins ?? []), fences()],\n\t\t\t}),\n\t\t},\n\t});\n}\n\nexport default likec4Integration;\n",
6
- "// Turns ```likec4 fences into diagrams: an empty fence with `view=` shows a\n// project view, a fence with DSL (or `file=`) is compiled and laid out here, at\n// build time, because layout needs LikeC4's WASM graph engine.\n//\n// A Sätteri mdast plugin, not a remark one: Astro 7's default processor is\n// Sätteri, and `remarkPlugins` is silently ignored without\n// @astrojs/markdown-remark.\n\nimport { createHash } from 'node:crypto';\nimport { readFile } from 'node:fs/promises';\nimport { dirname, isAbsolute, relative, resolve } from 'node:path';\nimport { createRequire } from 'node:module';\nimport { fileURLToPath } from 'node:url';\n\nimport type { MdastPluginEntry, PluginFactoryContext } from 'satteri';\n\nimport { translations } from './translations.ts';\n\nconst require = createRequire(import.meta.url);\n\n// Not imported at module scope: `likec4` pulls in Langium, an LSP and the WASM\n// layout engine, and loading that with astro.config made Astro restart on a\n// cold start, which killed the content layer.\nlet likec4ApiPromise: Promise<LikeC4Api> | undefined;\n\ntype LikeC4Api = typeof import('likec4').LikeC4;\n\nfunction loadLikeC4(): Promise<LikeC4Api> {\n\t// `require`, not `import()`: Vite's SSR module runner intercepts dynamic\n\t// imports from modules it loaded, and on Windows it can already be tearing\n\t// down when a page's fence gets here, which crashed `astro build`.\n\tlikec4ApiPromise ??= Promise.resolve(require('likec4').LikeC4);\n\n\treturn likec4ApiPromise;\n}\n\n/**\n * Finishes loading LikeC4 before the first page renders, so the load cannot race\n * the module runner's teardown. Called for builds only.\n */\nexport function preloadLikeC4(): Promise<LikeC4Api> {\n\treturn loadLikeC4();\n}\n\nconst FENCE_LANG = 'likec4';\n\nconst INLINE_COMPONENT = '__LikeC4Fence';\nconst PROJECT_COMPONENT = '__LikeC4View';\n\n// Package specifiers: the import is written into the site's page.\nconst PACKAGE_NAME = '@purview-dev/astroc4';\n\nconst IMPORTS = {\n\t[INLINE_COMPONENT]: `${PACKAGE_NAME}/components/LikeC4Fence.astro`,\n\t[PROJECT_COMPONENT]: `${PACKAGE_NAME}/components/LikeC4View.astro`,\n} as const;\n\ntype ComponentName = keyof typeof IMPORTS;\n\nconst STRINGS = translations.en;\n\ninterface Layout {\n\tdump: any;\n\tviewIds: string[];\n}\n\n/** Keyed by source: a compile costs ~250ms and dev re-renders a page on every edit. */\nconst layoutCache = new Map<string, Layout>();\n\nexport interface FenceMeta {\n\ttitle?: string;\n\tdescription?: string;\n\theight?: string;\n\tcollapsible?: string;\n\tdefaultOpen?: string;\n\tview?: string;\n\tproject?: string;\n\tfile?: string;\n\t[key: string]: string | undefined;\n}\n\n/** Parse `key=\"value\"` / `key='value'` / `key=value` pairs from the fence's meta string. */\nexport function parseFenceMeta(meta: string | null | undefined): FenceMeta {\n\tconst options: FenceMeta = {};\n\n\tif (!meta) return options;\n\n\tconst pattern = /(\\w+)=(?:\"([^\"]*)\"|'([^']*)'|(\\S+))/g;\n\tlet match;\n\n\twhile ((match = pattern.exec(meta)) !== null) {\n\t\tconst key = match[1];\n\t\tif (!key) continue;\n\n\t\toptions[key] = match[2] ?? match[3] ?? match[4] ?? '';\n\t}\n\n\treturn options;\n}\n\n/** Compile and lay out LikeC4 source; shared by fences and `<LikeC4View file>`. */\nexport async function layoutSource(source: string): Promise<Layout> {\n\tconst key = createHash('sha256').update(source).digest('hex');\n\tconst cached = layoutCache.get(key);\n\n\tif (cached) return cached;\n\n\tconst LikeC4 = await loadLikeC4();\n\tconst likec4 = await LikeC4.fromSource(source);\n\n\tif (likec4.hasErrors()) {\n\t\t// First line only: parser errors list every expected token.\n\t\tconst detail = likec4\n\t\t\t.getErrors()\n\t\t\t.map((error) => String(error.message).split('\\n')[0]?.trim() ?? '')\n\t\t\t.slice(0, 3)\n\t\t\t.join('; ');\n\n\t\tthrow new Error(detail || 'the snippet could not be parsed');\n\t}\n\n\tconst model = await likec4.layoutedModel();\n\tconst dump = JSON.parse(JSON.stringify(model.$data));\n\n\tconst result: Layout = { dump, viewIds: Object.keys(dump.views ?? {}) };\n\tlayoutCache.set(key, result);\n\n\treturn result;\n}\n\ninterface JsxAttribute {\n\ttype: 'mdxJsxAttribute';\n\tname: string;\n\tvalue: string;\n}\n\n/** `import <local> from '<source>';` as the MDX compiler expects it. */\nfunction importNode(local: string, source: string) {\n\treturn {\n\t\ttype: 'mdxjsEsm',\n\t\tvalue: `import ${local} from ${JSON.stringify(source)};`,\n\t\tdata: {\n\t\t\testree: {\n\t\t\t\ttype: 'Program',\n\t\t\t\tsourceType: 'module',\n\t\t\t\tbody: [\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: 'ImportDeclaration',\n\t\t\t\t\t\tspecifiers: [\n\t\t\t\t\t\t\t{ type: 'ImportDefaultSpecifier', local: { type: 'Identifier', name: local } },\n\t\t\t\t\t\t],\n\t\t\t\t\t\tsource: { type: 'Literal', value: source, raw: JSON.stringify(source) },\n\t\t\t\t\t\tattributes: [],\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t},\n\t};\n}\n\nfunction attributes(pairs: Record<string, string | undefined>): JsxAttribute[] {\n\treturn Object.entries(pairs)\n\t\t.filter(([, value]) => value !== undefined && value !== null && value !== '')\n\t\t.map(([name, value]) => ({ type: 'mdxJsxAttribute', name, value: String(value) }));\n}\n\nfunction describe(fileURL: URL | undefined): string {\n\tif (!fileURL) return 'a content file';\n\n\ttry {\n\t\treturn fileURLToPath(fileURL);\n\t} catch {\n\t\treturn String(fileURL);\n\t}\n}\n\nexport interface FenceReporter {\n\twarn: (message: string) => void;\n}\n\nexport interface FenceOptions {\n\t/** @deprecated Unused since 1.0.0-prerelease.6. */\n\treporter?: FenceReporter;\n\t/** @deprecated Unused since 1.0.0-prerelease.6. */\n\tmdx?: boolean;\n\t/** The site root. A fence's `file=\"…\"` must stay inside it; without one, `file=` is refused. */\n\troot?: string;\n\t/**\n\t * The project names a page may pass as `project`. When given, an empty fence's\n\t * `project` is checked at build time; without it, only the browser can.\n\t */\n\tprojects?: string[];\n}\n\n// region plugin\nexport function likec4Fences({ root, projects }: FenceOptions = {}): MdastPluginEntry {\n\t// A factory runs once per document, so `used` is per page.\n\treturn (factory: PluginFactoryContext) => {\n\t\tif (!factory.source.includes('```' + FENCE_LANG)) return null;\n\n\t\t// A .md page cannot hold a component, so it gets a placeholder that the\n\t\t// injected page script mounts (src/components/md-fences.tsx).\n\t\tconst markdown = factory.sourceFormat !== 'mdx';\n\t\tconst used = new Set<ComponentName>();\n\n\t\treturn {\n\t\t\tname: 'likec4-fences',\n\n\t\t\tasync code(node, ctx) {\n\t\t\t\tif (node.lang !== FENCE_LANG) return;\n\n\t\t\t\tconst where = `${describe(ctx.fileURL)}: \\`\\`\\`${FENCE_LANG} fence`;\n\t\t\t\tconst options = parseFenceMeta(node.meta);\n\t\t\t\tconst source = options.file\n\t\t\t\t\t? await readFenceFile(options.file, ctx.fileURL, root, where)\n\t\t\t\t\t: (node.value ?? '').trim();\n\n\t\t\t\tconst common = {\n\t\t\t\t\ttitle: options.title,\n\t\t\t\t\tdescription: options.description,\n\t\t\t\t\theight: options.height,\n\t\t\t\t\tcollapsible: options.collapsible,\n\t\t\t\t\tdefaultOpen: options.defaultOpen,\n\t\t\t\t};\n\n\t\t\t\tif (source.length === 0) {\n\t\t\t\t\tif (!options.view) {\n\t\t\t\t\t\tthrow new Error(`${where} is empty, so it needs \\`view=\"<id>\"\\` to name a view in the project model.`);\n\t\t\t\t\t}\n\n\t\t\t\t\tcheckProject(options.project, projects, where);\n\n\t\t\t\t\tif (markdown) {\n\t\t\t\t\t\tctx.replaceNode(node, {\n\t\t\t\t\t\t\traw: fencePlaceholder({ ...placeholderOptions(options), viewId: options.view, project: options.project }),\n\t\t\t\t\t\t\tmdxExpressions: false,\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tused.add(PROJECT_COMPONENT);\n\n\t\t\t\t\tctx.replaceNode(node, {\n\t\t\t\t\t\ttype: 'mdxJsxFlowElement',\n\t\t\t\t\t\tname: PROJECT_COMPONENT,\n\t\t\t\t\t\tattributes: attributes({ ...common, viewId: options.view, project: options.project }),\n\t\t\t\t\t\tchildren: [],\n\t\t\t\t\t});\n\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tlet layout;\n\n\t\t\t\ttry {\n\t\t\t\t\tlayout = await layoutSource(source);\n\t\t\t\t} catch (error) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`${where} is not valid LikeC4 — ${error instanceof Error ? error.message : String(error)}`,\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tconst viewId = options.view ?? defaultView(source, layout.viewIds);\n\n\t\t\t\tif (!viewId || !layout.viewIds.includes(viewId)) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`${where} has no view \"${viewId ?? '(none)'}\". Declared: ${layout.viewIds.join(', ') || '(none)'}.`,\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tif (markdown) {\n\t\t\t\t\tctx.replaceNode(node, {\n\t\t\t\t\t\traw: fencePlaceholder({ ...placeholderOptions(options), viewId, model: layout.dump }),\n\t\t\t\t\t\tmdxExpressions: false,\n\t\t\t\t\t});\n\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tused.add(INLINE_COMPONENT);\n\n\t\t\t\tctx.replaceNode(node, {\n\t\t\t\t\ttype: 'mdxJsxFlowElement',\n\t\t\t\t\tname: INLINE_COMPONENT,\n\t\t\t\t\tattributes: attributes({ ...common, viewId, model: JSON.stringify(layout.dump) }),\n\t\t\t\t\tchildren: [],\n\t\t\t\t});\n\t\t\t},\n\n\t\t\tafter(root, ctx) {\n\t\t\t\tif (used.size === 0) return;\n\n\t\t\t\tctx.insertChildAt(\n\t\t\t\t\troot,\n\t\t\t\t\t0,\n\t\t\t\t\t[...used].map((local) => importNode(local, IMPORTS[local])),\n\t\t\t\t);\n\t\t\t},\n\t\t};\n\t};\n}\n// endregion\n\n/** The same rule `<LikeC4View>` applies: required with several projects, and must exist. */\nfunction checkProject(project: string | undefined, projects: string[] | undefined, where: string): void {\n\tif (projects === undefined) return;\n\n\tconst requested = project?.trim();\n\tconst available = projects.join(', ');\n\n\tif (!requested) {\n\t\tif (projects.length > 1) {\n\t\t\tthrow new Error(`${where}: ${STRINGS['likec4.error.projectRequired'].replace('{available}', available)}`);\n\t\t}\n\n\t\treturn;\n\t}\n\n\tif (!projects.includes(requested)) {\n\t\tthrow new Error(\n\t\t\t`${where}: ${STRINGS['likec4.error.unknownProject']\n\t\t\t\t.replace('{projectId}', requested)\n\t\t\t\t.replace('{available}', available || '(none)')}`,\n\t\t);\n\t}\n}\n\n/**\n * The first `view <id>` the source declares. LikeC4 adds an automatic `index`\n * view and lists it first, so the first laid-out view would be that overview.\n */\nfunction defaultView(source: string, viewIds: string[]): string | undefined {\n\t// Skips matches that are not laid-out views, such as \"a view of …\" in a title.\n\tfor (const match of source.matchAll(/(?<![\\w-])view\\s+([\\w-]+)/g)) {\n\t\tif (viewIds.includes(match[1]!)) return match[1];\n\t}\n\n\treturn viewIds[0];\n}\n\nexport interface FencePlaceholder {\n\tviewId: string;\n\t/** The laid-out model of an inline or `file=` fence; absent for a project view. */\n\tmodel?: unknown;\n\tproject?: string;\n\ttitle?: string;\n\tdescription?: string;\n\theight?: number;\n\tcollapsible?: boolean;\n\tdefaultOpen?: boolean;\n}\n\n/** A theme token with the same fallbacks the Astro components use. */\nconst token = {\n\tborder: 'var(--likec4-border, var(--sl-color-gray-5, rgba(128, 128, 128, 0.35)))',\n\tsurface: 'var(--likec4-surface, var(--sl-color-bg, transparent))',\n\tsurfaceAlt: 'var(--likec4-surface-alt, var(--sl-color-bg-nav, rgba(128, 128, 128, 0.06)))',\n\ttext: 'var(--likec4-text, var(--sl-color-white, inherit))',\n\ttextMuted: 'var(--likec4-text-muted, var(--sl-color-gray-2, rgba(128, 128, 128, 0.95)))',\n};\n\n/**\n * The HTML a .md fence becomes: the shell, and a sized frame carrying the view\n * and model for `md-fences.tsx`. Everything is escaped — titles and model labels\n * are author text.\n */\nexport function fencePlaceholder({\n\tviewId,\n\tmodel,\n\tproject,\n\ttitle = STRINGS['likec4.fence.title'],\n\tdescription,\n\theight = 420,\n\tcollapsible = true,\n\tdefaultOpen = true,\n}: FencePlaceholder): string {\n\tconst data = [\n\t\t`data-astroc4-fence`,\n\t\t`data-view-id=\"${escapeHtml(viewId)}\"`,\n\t\tproject ? `data-project=\"${escapeHtml(project)}\"` : '',\n\t\tmodel === undefined ? '' : `data-model=\"${escapeHtml(JSON.stringify(model))}\"`,\n\t]\n\t\t.filter(Boolean)\n\t\t.join(' ');\n\n\tconst headerStyle = `display: block; padding: 1em 1.25rem; border-bottom: 1px solid ${token.border}; background: ${token.surface};`;\n\tconst heading = [\n\t\t`<h3 style=\"display: inline; margin: 0; font-size: 1rem; font-weight: 600; color: ${token.text};\">${escapeHtml(title)}</h3>`,\n\t\tdescription\n\t\t\t? `<p style=\"margin: 0.25rem 0 0; font-size: 0.875rem; color: ${token.textMuted};\">${escapeHtml(description)}</p>`\n\t\t\t: '',\n\t].join('');\n\n\tconst body = [\n\t\t`<div style=\"padding: 1em 1.25rem;\">`,\n\t\t`<div class=\"likec4-frame\" style=\"position: relative; width: 100%; height: ${height}px; min-height: ${height}px;\">`,\n\t\t`<p class=\"likec4-loading\" aria-live=\"polite\" style=\"color: ${token.textMuted};\">${escapeHtml(STRINGS['likec4.fence.loading'])}</p>`,\n\t\t`</div>`,\n\t\t`</div>`,\n\t].join('');\n\n\tconst shell = collapsible\n\t\t? `<details${defaultOpen ? ' open' : ''}><summary style=\"cursor: pointer; ${headerStyle}\">${heading}</summary>${body}</details>`\n\t\t: `<header style=\"${headerStyle}\">${heading}</header>${body}`;\n\n\treturn [\n\t\t`<section class=\"not-content likec4-md-fence\" ${data} style=\"margin: 1.5rem 0; overflow: hidden; border: 1px solid ${token.border}; border-radius: 0.75rem; background: ${token.surfaceAlt};\">`,\n\t\tshell,\n\t\t`</section>`,\n\t].join('');\n}\n\nfunction placeholderOptions(\n\toptions: FenceMeta,\n): Pick<FencePlaceholder, 'title' | 'description' | 'height' | 'collapsible' | 'defaultOpen'> {\n\tconst height = Number.parseInt(options.height ?? '', 10);\n\n\treturn {\n\t\ttitle: options.title || undefined,\n\t\tdescription: options.description || undefined,\n\t\theight: Number.isFinite(height) ? height : undefined,\n\t\tcollapsible: options.collapsible !== 'false',\n\t\tdefaultOpen: options.defaultOpen !== 'false',\n\t};\n}\n\nfunction escapeHtml(value: string): string {\n\treturn value\n\t\t.replaceAll('&', '&amp;')\n\t\t.replaceAll('\"', '&quot;')\n\t\t.replaceAll(\"'\", '&#39;')\n\t\t.replaceAll('<', '&lt;')\n\t\t.replaceAll('>', '&gt;');\n}\n\n/**\n * A fence's `file=\"…\"`, relative to its page. Refused outside the site, so a page\n * cannot pull arbitrary files from the build machine.\n */\nasync function readFenceFile(\n\tfile: string,\n\tpageURL: URL | undefined,\n\troot: string | undefined,\n\twhere: string,\n): Promise<string> {\n\tif (!pageURL || !root) {\n\t\tthrow new Error(`${where} uses file=\"${file}\", which needs the page's location and the site root.`);\n\t}\n\n\tconst path = resolve(dirname(fileURLToPath(pageURL)), file);\n\tconst fromRoot = relative(resolve(root), path);\n\n\tif (fromRoot.startsWith('..') || isAbsolute(fromRoot)) {\n\t\tthrow new Error(`${where} uses file=\"${file}\", which is outside the site (${path}).`);\n\t}\n\n\ttry {\n\t\treturn (await readFile(path, 'utf8')).trim();\n\t} catch {\n\t\tthrow new Error(`${where} uses file=\"${file}\", which does not exist (${path}).`);\n\t}\n}\n\nexport default likec4Fences;\n",
5
+ "import { existsSync } from 'node:fs';\nimport { dirname, join, resolve } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nimport type { AstroConfig, AstroIntegration, AstroIntegrationLogger } from 'astro';\nimport { LikeC4VitePlugin } from 'likec4/vite-plugin';\nimport type { Plugin as VitePlugin } from 'vite';\n\nimport { likec4Fences, preloadLikeC4 } from './fences.ts';\nimport { fileLayoutPlugin } from './file-layout.ts';\nimport { astroc4IconPlugin, type Astroc4IconPlugin } from './icon-plugin.ts';\nimport { discoverProjects, resolveProjects, type ResolvedProject } from './projects.ts';\nimport { prepareWorkspace, PROJECTS_MODULE_ID, projectsModule } from './workspace.ts';\nimport type { ValidationOptions } from './validation.ts';\n\n/** Scoped because npm refuses the unscoped `astroc4` as too similar to `astro`. */\nexport const PACKAGE_NAME = '@purview-dev/astroc4';\n\nexport type { ValidationMode, ValidationOptions, ValidationScope } from './validation.ts';\n\nexport interface LikeC4IntegrationOptions {\n\t/**\n\t * Passed through to `LikeC4VitePlugin`. Setting `workspace` or\n\t * `languageServices` takes project discovery over, and `projects` is ignored.\n\t */\n\tvitePlugin?: Parameters<typeof LikeC4VitePlugin>[0];\n\t/**\n\t * Named LikeC4 projects, compiled alongside those discovered under the site\n\t * root: `{ architecture: '../../docs/architecture/likec4' }`. Folders are\n\t * relative to the site root or absolute.\n\t */\n\tprojects?: Record<string, string>;\n\t/** Render ```likec4 fences in .md and .mdx pages as diagrams. Defaults to `true`. */\n\tfences?: boolean;\n\t/**\n\t * How a fence that cannot be turned into a diagram is treated. `strict` (the\n\t * default) fails the build and `astro check`; `relaxed` logs a warning and\n\t * leaves the fence as a highlighted code block. Relaxing can be scoped by\n\t * page path glob or content collection, so a tutorial section or collection\n\t * need not take the whole site's strictness with it.\n\t */\n\tvalidation?: ValidationOptions;\n}\n\n/**\n * `likec4/react` is built with the React Compiler and imports `c` from\n * `react/compiler-runtime`, which React 19 ships as CommonJS. Unless Vite\n * pre-bundles it, `astro dev` serves it raw and every island fails with\n * \"does not provide an export named 'c'\" — while `astro build` stays green.\n */\nconst OPTIMIZED_DEPENDENCIES = ['react/compiler-runtime'];\n\n/**\n * Mounts the fences of .md pages. Injected into every page, so React and LikeC4\n * are only `import()`ed on a page that has a placeholder.\n *\n * In dev, @astrojs/react installs React's fast-refresh preamble only on pages with\n * an island, and a .md page has none, so the script installs it first. Outside dev,\n * @vitejs/plugin-react serves the preamble module empty.\n */\nconst MD_FENCES_SCRIPT = [\n\t`const mountLikeC4Fences = () => {`,\n\t` if (!document.querySelector('[data-astroc4-fence]:not([data-astroc4-mounted])')) return;`,\n\t` const preamble = window.$RefreshReg$ ? Promise.resolve() : import('@vitejs/plugin-react/preamble');`,\n\t` preamble`,\n\t` .then(() => import('${PACKAGE_NAME}/components/md-fences'))`,\n\t` .then((module) => module.mountFences());`,\n\t`};`,\n\t`if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', mountLikeC4Fences);`,\n\t`else mountLikeC4Fences();`,\n\t`document.addEventListener('astro:page-load', mountLikeC4Fences);`,\n].join('\\n');\n\n/**\n * The `optimizeDeps.include` entries the site still lacks. Only missing ones:\n * Vite's `mergeConfig` concatenates arrays. Unresolvable ones are skipped, since\n * naming a package Vite cannot find breaks the optimizer.\n */\nexport function missingOptimizedDependencies(include: unknown, root: string): string[] {\n\tconst existing = Array.isArray(include) ? include : [];\n\n\treturn OPTIMIZED_DEPENDENCIES.filter(\n\t\t(dependency) => !existing.includes(dependency) && resolvesFrom(dependency, root),\n\t);\n}\n\n// Walks node_modules as Vite does: under Bun, `createRequire` also finds\n// packages in Bun's global cache, which Vite never looks in.\nfunction resolvesFrom(specifier: string, root: string): boolean {\n\tconst name = specifier.split('/', specifier.startsWith('@') ? 2 : 1).join('/');\n\n\tfor (let dir = resolve(root); ; dir = dirname(dir)) {\n\t\tif (existsSync(join(dir, 'node_modules', name, 'package.json'))) return true;\n\t\tif (dirname(dir) === dir) return false;\n\t}\n}\n\nexport function likec4Integration({\n\tvitePlugin = {},\n\tprojects,\n\tfences = true,\n\tvalidation,\n}: LikeC4IntegrationOptions = {}): AstroIntegration {\n\tlet icons: Astroc4IconPlugin | undefined;\n\n\treturn {\n\t\tname: `${PACKAGE_NAME}/integration`,\n\t\thooks: {\n\t\t\t'astro:config:setup': async ({ command, config, updateConfig, injectScript, logger }) => {\n\t\t\t\tconst root = fileURLToPath(config.root);\n\t\t\t\tconst optimizeDeps = missingOptimizedDependencies(config.vite?.optimizeDeps?.include, root);\n\t\t\t\tconst { pluginOptions, resolved, stagingDir } = await workspaceFor(root, vitePlugin, projects, logger);\n\n\t\t\t\ticons = astroc4IconPlugin({ projects: resolved, base: config.base ?? '/', siteRoot: root, stagingDir });\n\n\t\t\t\tupdateConfig({\n\t\t\t\t\tvite: {\n\t\t\t\t\t\tplugins: [LikeC4VitePlugin(pluginOptions), projectsPlugin(resolved), icons, fileLayoutPlugin()],\n\t\t\t\t\t\t// The components ship as .astro/.tsx source for Vite to transform.\n\t\t\t\t\t\tssr: { noExternal: [PACKAGE_NAME] },\n\t\t\t\t\t\t...(optimizeDeps.length > 0 ? { optimizeDeps: { include: optimizeDeps } } : {}),\n\t\t\t\t\t},\n\t\t\t\t});\n\n\t\t\t\tif (fences) {\n\t\t\t\t\tawait registerFences(config, updateConfig, logger, resolved, validation);\n\t\t\t\t\tinjectScript('page', MD_FENCES_SCRIPT);\n\t\t\t\t}\n\n\t\t\t\tawait ensureReactRenderer(config, updateConfig, logger);\n\n\t\t\t\t// Build only: loading LikeC4 eagerly in dev restarts the server (see ./fences.ts).\n\t\t\t\tif (command === 'build') {\n\t\t\t\t\tawait preloadLikeC4();\n\t\t\t\t}\n\t\t\t},\n\t\t\t'astro:build:done': async ({ dir }) => {\n\t\t\t\tawait icons?.emit(fileURLToPath(dir));\n\t\t\t},\n\t\t},\n\t};\n}\n\n/**\n * The options `LikeC4VitePlugin` gets, and the projects pages can name. With\n * `projects`, every project is linked into one staging workspace, because the\n * plugin compiles a single folder.\n */\nasync function workspaceFor(\n\troot: string,\n\tvitePlugin: NonNullable<LikeC4IntegrationOptions['vitePlugin']>,\n\tconfigured: Record<string, string> | undefined,\n\tlogger: AstroIntegrationLogger,\n): Promise<{\n\tpluginOptions: NonNullable<LikeC4IntegrationOptions['vitePlugin']>;\n\tresolved: ResolvedProject[];\n\tstagingDir?: string;\n}> {\n\tconst hasConfigured = configured !== undefined && Object.keys(configured).length > 0;\n\n\tif (vitePlugin.workspace !== undefined || 'languageServices' in vitePlugin) {\n\t\tif (hasConfigured) {\n\t\t\tlogger.warn(\n\t\t\t\t'`projects` is ignored because `vitePlugin.workspace` or `vitePlugin.languageServices` is set; remove one of them.',\n\t\t\t);\n\t\t}\n\n\t\treturn { pluginOptions: vitePlugin, resolved: [] };\n\t}\n\n\tconst discovered = await discoverProjects(root);\n\n\tif (!hasConfigured) {\n\t\treturn { pluginOptions: vitePlugin, resolved: discovered };\n\t}\n\n\tconst resolved = await resolveProjects({ root, configured, discovered });\n\tconst workspace = await prepareWorkspace(resolved, join(root, '.astro', 'astroc4'));\n\n\treturn { pluginOptions: { ...(vitePlugin as { workspace?: string }), workspace }, resolved, stagingDir: workspace };\n}\n\n/** Serves `virtual:astroc4/projects`: the names components may pass as `project`. */\nfunction projectsPlugin(projects: ResolvedProject[]): VitePlugin {\n\tconst resolvedId = `\\0${PROJECTS_MODULE_ID}`;\n\n\treturn {\n\t\tname: `${PACKAGE_NAME}/projects`,\n\t\tresolveId: (id) => (id === PROJECTS_MODULE_ID ? resolvedId : undefined),\n\t\tload: (id) => (id === resolvedId ? projectsModule(projects) : undefined),\n\t};\n}\n\n/**\n * Add `@astrojs/react` when the site has not: without a renderer the\n * `client:only=\"react\"` islands fail with Astro's generic \"no renderer\" error.\n * Integrations pushed here still have their hooks run in this pass. MDX and\n * Expressive Code are left to the site, because they change its content types\n * and code blocks.\n */\nasync function ensureReactRenderer(\n\tconfig: AstroConfig,\n\tupdateConfig: (config: Record<string, unknown>) => void,\n\tlogger: AstroIntegrationLogger,\n): Promise<void> {\n\tif (config.integrations.some((integration) => integration.name === '@astrojs/react')) return;\n\n\ttry {\n\t\tconst { default: react } = await import('@astrojs/react');\n\n\t\tupdateConfig({ integrations: [react()] });\n\t\tlogger.info('added @astrojs/react: the LikeC4 diagrams are React islands (client:only=\"react\").');\n\t} catch {\n\t\tlogger.warn(\n\t\t\t'@astrojs/react is not installed, so <LikeC4View> cannot render. Install it (`astro add react`).',\n\t\t);\n\t}\n}\n\n/** Append the fence transform to the site's Sätteri processor, keeping its plugins. */\nasync function registerFences(\n\tconfig: AstroConfig,\n\tupdateConfig: (config: Record<string, unknown>) => void,\n\tlogger: AstroIntegrationLogger,\n\tprojects: ResolvedProject[],\n\tvalidation: ValidationOptions | undefined,\n): Promise<void> {\n\tconst { satteri, isSatteriProcessor } = await import('@astrojs/markdown-satteri');\n\tconst existing = config.markdown?.processor;\n\tconst fences = () =>\n\t\tlikec4Fences({\n\t\t\troot: fileURLToPath(config.root),\n\t\t\t// `validation` can scope by page path and by content collection, and only\n\t\t\t// the content directory says where a collection's folder starts.\n\t\t\tcontentDir: config.srcDir ? fileURLToPath(new URL('content/', config.srcDir)) : undefined,\n\t\t\t// Empty when the site took discovery over: then only the browser knows.\n\t\t\tprojects: projects.length > 0 ? projects.map((project) => project.name) : undefined,\n\t\t\tvalidation,\n\t\t\tonInvalid: (message) => logger.warn(message),\n\t\t});\n\n\t// No processor configured means Astro's default, which is Sätteri.\n\tif (existing === undefined) {\n\t\tupdateConfig({ markdown: { processor: satteri({ mdastPlugins: [fences()] }) } });\n\t\treturn;\n\t}\n\n\tif (!isSatteriProcessor(existing)) {\n\t\tlogger.warn(\n\t\t\t'```likec4 fences are disabled: the site is not using the Sätteri Markdown processor. ' +\n\t\t\t\t'<LikeC4View /> still works.',\n\t\t);\n\t\treturn;\n\t}\n\n\tconst existingOptions = existing.options ?? {};\n\n\tupdateConfig({\n\t\tmarkdown: {\n\t\t\tprocessor: satteri({\n\t\t\t\t...existingOptions,\n\t\t\t\tmdastPlugins: [...(existingOptions.mdastPlugins ?? []), fences()],\n\t\t\t}),\n\t\t},\n\t});\n}\n\nexport default likec4Integration;\n",
6
+ "// Turns ```likec4 fences into diagrams: an empty fence with `view=` shows a\n// project view, a fence with DSL (or `file=`) is compiled and laid out here, at\n// build time, because layout needs LikeC4's WASM graph engine.\n//\n// A Sätteri mdast plugin, not a remark one: Astro 7's default processor is\n// Sätteri, and `remarkPlugins` is silently ignored without\n// @astrojs/markdown-remark.\n\nimport { createHash } from 'node:crypto';\nimport { readFile } from 'node:fs/promises';\nimport { dirname, isAbsolute, relative, resolve } from 'node:path';\nimport { createRequire } from 'node:module';\nimport { fileURLToPath } from 'node:url';\n\nimport type { MdastPluginEntry, PluginFactoryContext } from 'satteri';\n\nimport { translations } from './translations.ts';\nimport { validationModeFor, type ValidationOptions } from './validation.ts';\n\nconst require = createRequire(import.meta.url);\n\n// Not imported at module scope: `likec4` pulls in Langium, an LSP and the WASM\n// layout engine, and loading that with astro.config made Astro restart on a\n// cold start, which killed the content layer.\nlet likec4ApiPromise: Promise<LikeC4Api> | undefined;\n\ntype LikeC4Api = typeof import('likec4').LikeC4;\n\nfunction loadLikeC4(): Promise<LikeC4Api> {\n\t// `require`, not `import()`: Vite's SSR module runner intercepts dynamic\n\t// imports from modules it loaded, and on Windows it can already be tearing\n\t// down when a page's fence gets here, which crashed `astro build`.\n\tlikec4ApiPromise ??= Promise.resolve(require('likec4').LikeC4);\n\n\treturn likec4ApiPromise;\n}\n\n/**\n * Finishes loading LikeC4 before the first page renders, so the load cannot race\n * the module runner's teardown. Called for builds only.\n */\nexport function preloadLikeC4(): Promise<LikeC4Api> {\n\treturn loadLikeC4();\n}\n\nconst FENCE_LANG = 'likec4';\n\nconst INLINE_COMPONENT = '__LikeC4Fence';\nconst PROJECT_COMPONENT = '__LikeC4View';\n\n// Package specifiers: the import is written into the site's page.\nconst PACKAGE_NAME = '@purview-dev/astroc4';\n\nconst IMPORTS = {\n\t[INLINE_COMPONENT]: `${PACKAGE_NAME}/components/LikeC4Fence.astro`,\n\t[PROJECT_COMPONENT]: `${PACKAGE_NAME}/components/LikeC4View.astro`,\n} as const;\n\ntype ComponentName = keyof typeof IMPORTS;\n\nconst STRINGS = translations.en;\n\n/** Appended to every reason `relaxed` validation turns into a warning instead of an error. */\nconst RELAXED_NOTE = 'Left as a highlighted code block because this page is validated in `relaxed` mode.';\n\ninterface Layout {\n\tdump: any;\n\tviewIds: string[];\n}\n\n/** Keyed by source: a compile costs ~250ms and dev re-renders a page on every edit. */\nconst layoutCache = new Map<string, Layout>();\n\nexport interface FenceMeta {\n\ttitle?: string;\n\tdescription?: string;\n\theight?: string;\n\tcollapsible?: string;\n\tdefaultOpen?: string;\n\tview?: string;\n\tproject?: string;\n\tfile?: string;\n\t[key: string]: string | undefined;\n}\n\n/** Parse `key=\"value\"` / `key='value'` / `key=value` pairs from the fence's meta string. */\nexport function parseFenceMeta(meta: string | null | undefined): FenceMeta {\n\tconst options: FenceMeta = {};\n\n\tif (!meta) return options;\n\n\tconst pattern = /(\\w+)=(?:\"([^\"]*)\"|'([^']*)'|(\\S+))/g;\n\tlet match;\n\n\twhile ((match = pattern.exec(meta)) !== null) {\n\t\tconst key = match[1];\n\t\tif (!key) continue;\n\n\t\toptions[key] = match[2] ?? match[3] ?? match[4] ?? '';\n\t}\n\n\treturn options;\n}\n\n/** Compile and lay out LikeC4 source; shared by fences and `<LikeC4View file>`. */\nexport async function layoutSource(source: string): Promise<Layout> {\n\tconst key = createHash('sha256').update(source).digest('hex');\n\tconst cached = layoutCache.get(key);\n\n\tif (cached) return cached;\n\n\tconst LikeC4 = await loadLikeC4();\n\tconst likec4 = await LikeC4.fromSource(source);\n\n\tif (likec4.hasErrors()) {\n\t\t// First line only: parser errors list every expected token.\n\t\tconst detail = likec4\n\t\t\t.getErrors()\n\t\t\t.map((error) => String(error.message).split('\\n')[0]?.trim() ?? '')\n\t\t\t.slice(0, 3)\n\t\t\t.join('; ');\n\n\t\tthrow new Error(detail || 'the snippet could not be parsed');\n\t}\n\n\tconst model = await likec4.layoutedModel();\n\tconst dump = JSON.parse(JSON.stringify(model.$data));\n\n\tconst result: Layout = { dump, viewIds: Object.keys(dump.views ?? {}) };\n\tlayoutCache.set(key, result);\n\n\treturn result;\n}\n\ninterface JsxAttribute {\n\ttype: 'mdxJsxAttribute';\n\tname: string;\n\tvalue: string;\n}\n\n/** `import <local> from '<source>';` as the MDX compiler expects it. */\nfunction importNode(local: string, source: string) {\n\treturn {\n\t\ttype: 'mdxjsEsm',\n\t\tvalue: `import ${local} from ${JSON.stringify(source)};`,\n\t\tdata: {\n\t\t\testree: {\n\t\t\t\ttype: 'Program',\n\t\t\t\tsourceType: 'module',\n\t\t\t\tbody: [\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: 'ImportDeclaration',\n\t\t\t\t\t\tspecifiers: [\n\t\t\t\t\t\t\t{ type: 'ImportDefaultSpecifier', local: { type: 'Identifier', name: local } },\n\t\t\t\t\t\t],\n\t\t\t\t\t\tsource: { type: 'Literal', value: source, raw: JSON.stringify(source) },\n\t\t\t\t\t\tattributes: [],\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t},\n\t};\n}\n\nfunction attributes(pairs: Record<string, string | undefined>): JsxAttribute[] {\n\treturn Object.entries(pairs)\n\t\t.filter(([, value]) => value !== undefined && value !== null && value !== '')\n\t\t.map(([name, value]) => ({ type: 'mdxJsxAttribute', name, value: String(value) }));\n}\n\nfunction describe(fileURL: URL | undefined): string {\n\tif (!fileURL) return 'a content file';\n\n\ttry {\n\t\treturn fileURLToPath(fileURL);\n\t} catch {\n\t\treturn String(fileURL);\n\t}\n}\n\n/** The page's path from the site root, so validation can be scoped by page. */\nfunction pagePath(fileURL: URL | undefined, root: string | undefined): string | undefined {\n\tif (!fileURL || !root) return undefined;\n\n\ttry {\n\t\treturn relative(resolve(root), fileURLToPath(fileURL));\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\n/**\n * The content collection a page belongs to: its first folder under the content\n * directory, which is how Astro's `glob` loader maps a collection to a folder.\n */\nfunction collectionOf(fileURL: URL | undefined, contentDir: string | undefined): string | undefined {\n\tconst within = pagePath(fileURL, contentDir);\n\n\tif (!within || within.startsWith('..')) return undefined;\n\n\tconst [first, ...rest] = within.split(/[\\\\/]/);\n\n\treturn rest.length > 0 ? first : undefined;\n}\n\nexport interface FenceReporter {\n\twarn: (message: string) => void;\n}\n\nexport interface FenceOptions {\n\t/** @deprecated Unused since 1.0.0-prerelease.6. */\n\treporter?: FenceReporter;\n\t/** @deprecated Unused since 1.0.0-prerelease.6. */\n\tmdx?: boolean;\n\t/** The site root. A fence's `file=\"…\"` must stay inside it; without one, `file=` is refused. */\n\troot?: string;\n\t/**\n\t * The project names a page may pass as `project`. When given, an empty fence's\n\t * `project` is checked at build time; without it, only the browser can.\n\t */\n\tprojects?: string[];\n\t/**\n\t * How a fence that cannot be turned into a diagram is treated. `strict` (the\n\t * default) fails the build and `astro check`; `relaxed` logs a warning and\n\t * leaves the fence as a highlighted code block. Relaxing can be scoped by\n\t * page path glob or content collection. See `./validation.ts`.\n\t */\n\tvalidation?: ValidationOptions;\n\t/** The site's content directory, so a page's collection can be resolved. */\n\tcontentDir?: string;\n\t/** Called with the reason for each fence `relaxed` validation leaves as a code block. */\n\tonInvalid?: (message: string) => void;\n}\n\n// region plugin\nexport function likec4Fences({ root, projects, validation, contentDir, onInvalid }: FenceOptions = {}): MdastPluginEntry {\n\t// A factory runs once per document, so `used` is per page.\n\treturn (factory: PluginFactoryContext) => {\n\t\tif (!factory.source.includes('```' + FENCE_LANG)) return null;\n\n\t\t// A .md page cannot hold a component, so it gets a placeholder that the\n\t\t// injected page script mounts (src/components/md-fences.tsx).\n\t\tconst markdown = factory.sourceFormat !== 'mdx';\n\t\tconst used = new Set<ComponentName>();\n\n\t\treturn {\n\t\t\tname: 'likec4-fences',\n\n\t\t\tasync code(node, ctx) {\n\t\t\t\tif (node.lang !== FENCE_LANG) return;\n\n\t\t\t\tconst mode = validationModeFor(validation, pagePath(ctx.fileURL, root), collectionOf(ctx.fileURL, contentDir));\n\t\t\t\tconst fail = (reason: string): void => {\n\t\t\t\t\tif (mode === 'strict') throw new Error(reason);\n\n\t\t\t\t\tonInvalid?.(`${reason} ${RELAXED_NOTE}`);\n\t\t\t\t};\n\t\t\t\tconst where = `${describe(ctx.fileURL)}: \\`\\`\\`${FENCE_LANG} fence`;\n\t\t\t\tconst options = parseFenceMeta(node.meta);\n\t\t\t\tlet source;\n\n\t\t\t\ttry {\n\t\t\t\t\tsource = options.file\n\t\t\t\t\t\t? await readFenceFile(options.file, ctx.fileURL, root, where)\n\t\t\t\t\t\t: (node.value ?? '').trim();\n\t\t\t\t} catch (error) {\n\t\t\t\t\tfail(error instanceof Error ? error.message : String(error));\n\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst common = {\n\t\t\t\t\ttitle: options.title,\n\t\t\t\t\tdescription: options.description,\n\t\t\t\t\theight: options.height,\n\t\t\t\t\tcollapsible: options.collapsible,\n\t\t\t\t\tdefaultOpen: options.defaultOpen,\n\t\t\t\t};\n\n\t\t\t\tif (source.length === 0) {\n\t\t\t\t\tif (!options.view) {\n\t\t\t\t\t\tfail(`${where} is empty, so it needs \\`view=\"<id>\"\\` to name a view in the project model.`);\n\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst projectFailure = projectError(options.project, projects, where);\n\n\t\t\t\t\tif (projectFailure !== undefined) {\n\t\t\t\t\t\tfail(projectFailure);\n\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (markdown) {\n\t\t\t\t\t\tctx.replaceNode(node, {\n\t\t\t\t\t\t\traw: fencePlaceholder({ ...placeholderOptions(options), viewId: options.view, project: options.project }),\n\t\t\t\t\t\t\tmdxExpressions: false,\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tused.add(PROJECT_COMPONENT);\n\n\t\t\t\t\tctx.replaceNode(node, {\n\t\t\t\t\t\ttype: 'mdxJsxFlowElement',\n\t\t\t\t\t\tname: PROJECT_COMPONENT,\n\t\t\t\t\t\tattributes: attributes({ ...common, viewId: options.view, project: options.project }),\n\t\t\t\t\t\tchildren: [],\n\t\t\t\t\t});\n\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tlet layout;\n\n\t\t\t\ttry {\n\t\t\t\t\tlayout = await layoutSource(source);\n\t\t\t\t} catch (error) {\n\t\t\t\t\tfail(`${where} is not valid LikeC4 — ${error instanceof Error ? error.message : String(error)}`);\n\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst viewId = options.view ?? defaultView(source, layout.viewIds);\n\n\t\t\t\tif (!viewId || !layout.viewIds.includes(viewId)) {\n\t\t\t\t\tfail(`${where} has no view \"${viewId ?? '(none)'}\". Declared: ${layout.viewIds.join(', ') || '(none)'}.`);\n\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (markdown) {\n\t\t\t\t\tctx.replaceNode(node, {\n\t\t\t\t\t\traw: fencePlaceholder({ ...placeholderOptions(options), viewId, model: layout.dump }),\n\t\t\t\t\t\tmdxExpressions: false,\n\t\t\t\t\t});\n\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tused.add(INLINE_COMPONENT);\n\n\t\t\t\tctx.replaceNode(node, {\n\t\t\t\t\ttype: 'mdxJsxFlowElement',\n\t\t\t\t\tname: INLINE_COMPONENT,\n\t\t\t\t\tattributes: attributes({ ...common, viewId, model: JSON.stringify(layout.dump) }),\n\t\t\t\t\tchildren: [],\n\t\t\t\t});\n\t\t\t},\n\n\t\t\tafter(root, ctx) {\n\t\t\t\tif (used.size === 0) return;\n\n\t\t\t\tctx.insertChildAt(\n\t\t\t\t\troot,\n\t\t\t\t\t0,\n\t\t\t\t\t[...used].map((local) => importNode(local, IMPORTS[local])),\n\t\t\t\t);\n\t\t\t},\n\t\t};\n\t};\n}\n// endregion\n\n/** The same rule `<LikeC4View>` applies: required with several projects, and must exist. */\nfunction projectError(project: string | undefined, projects: string[] | undefined, where: string): string | undefined {\n\tif (projects === undefined) return undefined;\n\n\tconst requested = project?.trim();\n\tconst available = projects.join(', ');\n\n\tif (!requested) {\n\t\treturn projects.length > 1\n\t\t\t? `${where}: ${STRINGS['likec4.error.projectRequired'].replace('{available}', available)}`\n\t\t\t: undefined;\n\t}\n\n\tif (!projects.includes(requested)) {\n\t\treturn `${where}: ${STRINGS['likec4.error.unknownProject']\n\t\t\t.replace('{projectId}', requested)\n\t\t\t.replace('{available}', available || '(none)')}`;\n\t}\n\n\treturn undefined;\n}\n\n/**\n * The first `view <id>` the source declares. LikeC4 adds an automatic `index`\n * view and lists it first, so the first laid-out view would be that overview.\n */\nfunction defaultView(source: string, viewIds: string[]): string | undefined {\n\t// Skips matches that are not laid-out views, such as \"a view of …\" in a title.\n\tfor (const match of source.matchAll(/(?<![\\w-])view\\s+([\\w-]+)/g)) {\n\t\tif (viewIds.includes(match[1]!)) return match[1];\n\t}\n\n\treturn viewIds[0];\n}\n\nexport interface FencePlaceholder {\n\tviewId: string;\n\t/** The laid-out model of an inline or `file=` fence; absent for a project view. */\n\tmodel?: unknown;\n\tproject?: string;\n\ttitle?: string;\n\tdescription?: string;\n\theight?: number;\n\tcollapsible?: boolean;\n\tdefaultOpen?: boolean;\n}\n\n/** A theme token with the same fallbacks the Astro components use. */\nconst token = {\n\tborder: 'var(--likec4-border, var(--sl-color-gray-5, rgba(128, 128, 128, 0.35)))',\n\tsurface: 'var(--likec4-surface, var(--sl-color-bg, transparent))',\n\tsurfaceAlt: 'var(--likec4-surface-alt, var(--sl-color-bg-nav, rgba(128, 128, 128, 0.06)))',\n\ttext: 'var(--likec4-text, var(--sl-color-white, inherit))',\n\ttextMuted: 'var(--likec4-text-muted, var(--sl-color-gray-2, rgba(128, 128, 128, 0.95)))',\n};\n\n/**\n * The HTML a .md fence becomes: the shell, and a sized frame carrying the view\n * and model for `md-fences.tsx`. Everything is escaped — titles and model labels\n * are author text.\n */\nexport function fencePlaceholder({\n\tviewId,\n\tmodel,\n\tproject,\n\ttitle = STRINGS['likec4.fence.title'],\n\tdescription,\n\theight = 420,\n\tcollapsible = true,\n\tdefaultOpen = true,\n}: FencePlaceholder): string {\n\tconst data = [\n\t\t`data-astroc4-fence`,\n\t\t`data-view-id=\"${escapeHtml(viewId)}\"`,\n\t\tproject ? `data-project=\"${escapeHtml(project)}\"` : '',\n\t\tmodel === undefined ? '' : `data-model=\"${escapeHtml(JSON.stringify(model))}\"`,\n\t]\n\t\t.filter(Boolean)\n\t\t.join(' ');\n\n\tconst headerStyle = `display: block; padding: 1em 1.25rem; border-bottom: 1px solid ${token.border}; background: ${token.surface};`;\n\tconst heading = [\n\t\t`<h3 style=\"display: inline; margin: 0; font-size: 1rem; font-weight: 600; color: ${token.text};\">${escapeHtml(title)}</h3>`,\n\t\tdescription\n\t\t\t? `<p style=\"margin: 0.25rem 0 0; font-size: 0.875rem; color: ${token.textMuted};\">${escapeHtml(description)}</p>`\n\t\t\t: '',\n\t].join('');\n\n\tconst body = [\n\t\t`<div style=\"padding: 1em 1.25rem;\">`,\n\t\t`<div class=\"likec4-frame\" style=\"position: relative; width: 100%; height: ${height}px; min-height: ${height}px;\">`,\n\t\t`<p class=\"likec4-loading\" aria-live=\"polite\" style=\"color: ${token.textMuted};\">${escapeHtml(STRINGS['likec4.fence.loading'])}</p>`,\n\t\t`</div>`,\n\t\t`</div>`,\n\t].join('');\n\n\tconst shell = collapsible\n\t\t? `<details${defaultOpen ? ' open' : ''}><summary style=\"cursor: pointer; ${headerStyle}\">${heading}</summary>${body}</details>`\n\t\t: `<header style=\"${headerStyle}\">${heading}</header>${body}`;\n\n\treturn [\n\t\t`<section class=\"not-content likec4-md-fence\" ${data} style=\"margin: 1.5rem 0; overflow: hidden; border: 1px solid ${token.border}; border-radius: 0.75rem; background: ${token.surfaceAlt};\">`,\n\t\tshell,\n\t\t`</section>`,\n\t].join('');\n}\n\nfunction placeholderOptions(\n\toptions: FenceMeta,\n): Pick<FencePlaceholder, 'title' | 'description' | 'height' | 'collapsible' | 'defaultOpen'> {\n\tconst height = Number.parseInt(options.height ?? '', 10);\n\n\treturn {\n\t\ttitle: options.title || undefined,\n\t\tdescription: options.description || undefined,\n\t\theight: Number.isFinite(height) ? height : undefined,\n\t\tcollapsible: options.collapsible !== 'false',\n\t\tdefaultOpen: options.defaultOpen !== 'false',\n\t};\n}\n\nfunction escapeHtml(value: string): string {\n\treturn value\n\t\t.replaceAll('&', '&amp;')\n\t\t.replaceAll('\"', '&quot;')\n\t\t.replaceAll(\"'\", '&#39;')\n\t\t.replaceAll('<', '&lt;')\n\t\t.replaceAll('>', '&gt;');\n}\n\n/**\n * A fence's `file=\"…\"`, relative to its page. Refused outside the site, so a page\n * cannot pull arbitrary files from the build machine.\n */\nasync function readFenceFile(\n\tfile: string,\n\tpageURL: URL | undefined,\n\troot: string | undefined,\n\twhere: string,\n): Promise<string> {\n\tif (!pageURL || !root) {\n\t\tthrow new Error(`${where} uses file=\"${file}\", which needs the page's location and the site root.`);\n\t}\n\n\tconst path = resolve(dirname(fileURLToPath(pageURL)), file);\n\tconst fromRoot = relative(resolve(root), path);\n\n\tif (fromRoot.startsWith('..') || isAbsolute(fromRoot)) {\n\t\tthrow new Error(`${where} uses file=\"${file}\", which is outside the site (${path}).`);\n\t}\n\n\ttry {\n\t\treturn (await readFile(path, 'utf8')).trim();\n\t} catch {\n\t\tthrow new Error(`${where} uses file=\"${file}\", which does not exist (${path}).`);\n\t}\n}\n\nexport default likec4Fences;\n",
7
7
  "// Placeholders are `{name}`, not i18next's `{{name}}`: some values are only\n// known in the browser, so the template has to reach the island unformatted.\n\nexport const translations = {\n\ten: {\n\t\t'likec4.view.title': 'Architecture diagram',\n\t\t'likec4.view.description': 'Interactive LikeC4 diagram for this section.',\n\t\t'likec4.view.hint': 'Click a node in the diagram to open its details.',\n\t\t'likec4.view.badge': 'Click any node to open the modal',\n\t\t'likec4.view.loading': 'Loading architecture diagram…',\n\t\t'likec4.fence.title': 'Diagram',\n\t\t'likec4.fence.hint': 'Click any node to open its details.',\n\t\t'likec4.fence.loading': 'Loading diagram…',\n\t\t'likec4.error.title': 'We couldn’t load this diagram.',\n\t\t'likec4.error.body': 'Please retry, or refresh the page if the issue persists.',\n\t\t'likec4.error.retry': 'Retry',\n\t\t'likec4.error.viewIdRequired': 'A LikeC4 viewId is required to render the diagram.',\n\t\t'likec4.error.noProjects': 'No LikeC4 projects are available in this workspace.',\n\t\t'likec4.error.unknownProject': 'Unknown LikeC4 projectId \"{projectId}\". Available projects: {available}.',\n\t\t'likec4.error.projectRequired': 'Several LikeC4 projects exist ({available}); pass project=\"…\".',\n\t\t'likec4.error.unresolvedProject': 'Unable to resolve a LikeC4 project.',\n\t\t'likec4.error.loadFailed': 'Unable to load LikeC4 project \"{projectId}\".',\n\t},\n};\n\nexport default translations;\n",
8
+ "// How a fence that cannot be turned into a diagram is treated: `strict` fails the\n// build — and so `astro check`, which runs the same content transform — while\n// `relaxed` logs the reason as a warning and leaves the fence as a highlighted\n// code block. Relaxing can be scoped by content collection or page path, so a\n// tutorial section need not take the whole site's strictness with it.\n\nexport type ValidationMode = 'strict' | 'relaxed';\n\nexport interface ValidationScope {\n\t/** The mode for a page no `relaxed` pattern matches. Defaults to `'strict'`. */\n\tdefault?: ValidationMode;\n\t/**\n\t * Page path globs, relative to the site root, that use `'relaxed'`. `*`\n\t * matches within a path segment, `**` across segments, and a pattern matches\n\t * at any depth — `tutorials/**` finds `src/content/docs/tutorials/…`.\n\t */\n\trelaxed?: string | string[];\n\t/**\n\t * Content collections that use `'relaxed'`, by name. A page's collection is\n\t * its first folder under the content directory (`src/content/<name>/…`),\n\t * which is how Astro's `glob` loader maps a collection to a folder.\n\t */\n\tcollections?: string | string[];\n}\n\n/** A single mode for the whole site, or per-page rules. */\nexport type ValidationOptions = ValidationMode | ValidationScope;\n\n/** A glob as a regexp anchored at both ends, with an implicit \"any folder\" prefix. */\nexport function globToRegExp(pattern: string): RegExp {\n\tlet body = '';\n\n\tfor (let index = 0; index < pattern.length; index += 1) {\n\t\tconst char = pattern[index]!;\n\n\t\tif (char === '*') {\n\t\t\tif (pattern[index + 1] === '*') {\n\t\t\t\tbody += '.*';\n\t\t\t\tindex += 1;\n\t\t\t} else {\n\t\t\t\tbody += '[^/]*';\n\t\t\t}\n\t\t} else if (char === '?') {\n\t\t\tbody += '[^/]';\n\t\t} else if ('.+^${}()|[]\\\\'.includes(char)) {\n\t\t\tbody += `\\\\${char}`;\n\t\t} else {\n\t\t\tbody += char;\n\t\t}\n\t}\n\n\treturn new RegExp(`^(?:.*/)?${body}$`);\n}\n\nconst toSlashes = (value: string): string => value.replaceAll('\\\\', '/');\n\n/**\n * The mode a page uses. `relativePath` is the page's path from the site root and\n * `collection` its content collection; either may be `undefined` when it cannot\n * be worked out — then whatever is left decides, falling back to `default`.\n */\nexport function validationModeFor(\n\toptions: ValidationOptions | undefined,\n\trelativePath: string | undefined,\n\tcollection?: string,\n): ValidationMode {\n\tif (options === undefined) return 'strict';\n\tif (typeof options === 'string') return options;\n\n\tconst fallback = options.default ?? 'strict';\n\tconst collections = options.collections === undefined ? [] : [options.collections].flat();\n\n\tif (collection !== undefined && collections.includes(collection)) return 'relaxed';\n\n\tif (relativePath === undefined) return fallback;\n\n\tconst patterns = options.relaxed === undefined ? [] : [options.relaxed].flat();\n\tconst path = toSlashes(relativePath);\n\n\treturn patterns.some((pattern) => globToRegExp(pattern).test(path)) ? 'relaxed' : fallback;\n}\n",
8
9
  "// Compiles `<LikeC4View file=\"…\">` sources here, in Vite's plugin context,\n// because the SSR module runner cannot safely load LikeC4's Node API.\n\nimport { readFile } from 'node:fs/promises';\n\nimport type { Plugin as VitePlugin } from 'vite';\n\nimport { layoutSource } from './fences.ts';\n\n/** The import query `LikeC4View.astro` adds to a `.c4` file it renders. */\nexport const FILE_LAYOUT_QUERY = '?astroc4-layout';\n\nexport function fileLayoutPlugin(): VitePlugin {\n\treturn {\n\t\tname: '@purview-dev/astroc4/file-layout',\n\t\tasync load(id) {\n\t\t\tif (!id.endsWith(FILE_LAYOUT_QUERY)) return null;\n\n\t\t\tconst file = id.slice(0, -FILE_LAYOUT_QUERY.length);\n\t\t\tthis.addWatchFile(file);\n\n\t\t\tlet layout;\n\n\t\t\ttry {\n\t\t\t\tlayout = await layoutSource(await readFile(file, 'utf8'));\n\t\t\t} catch (error) {\n\t\t\t\tthrow new Error(`[astroc4] ${file} is not valid LikeC4 — ${(error as Error).message}`);\n\t\t\t}\n\n\t\t\treturn `export default ${JSON.stringify(layout)};`;\n\t\t},\n\t};\n}\n",
9
10
  "// LikeC4 serializes its generated modules with `/` escaped as `\\u002F` (so they\n// can be inlined into HTML), so URLs are matched in both forms and written back\n// in the form they were found in.\n\nimport { readFile, copyFile, mkdir } from 'node:fs/promises';\nimport { dirname, extname, join } from 'node:path';\nimport { fileURLToPath, pathToFileURL } from 'node:url';\n\nimport type { Plugin as VitePlugin } from 'vite';\n\nimport { buildIconManifest, ICON_ROUTE, type IconAsset, unstage } from './icon-assets.ts';\nimport type { ResolvedProject } from './projects.ts';\n\n/** The ids LikeC4's Vite plugin resolves its per-project modules to. */\nconst LIKEC4_MODULE = /likec4:plugin\\/(?<projectId>[^/]+)\\/[^/]+$/;\n\n/** A `file:///…` URL, plain or with LikeC4's escaped slashes. */\nconst FILE_URL = /file:(?:\\\\u002F|\\/){3}[^\"'`\\s]+/g;\n\nconst CONTENT_TYPES: Record<string, string> = {\n\t'.svg': 'image/svg+xml',\n\t'.png': 'image/png',\n\t'.jpg': 'image/jpeg',\n\t'.jpeg': 'image/jpeg',\n\t'.gif': 'image/gif',\n\t'.webp': 'image/webp',\n\t'.ico': 'image/x-icon',\n};\n\nexport interface IconPluginState {\n\tprojects: ResolvedProject[];\n\tbase: string;\n\t/** The site root; files under its `public/` are left to Astro. */\n\tsiteRoot: string;\n\tstagingDir?: string;\n}\n\nexport type Astroc4IconPlugin = VitePlugin & {\n\t/** Keyed by compiled `file://` URL. */\n\tmanifest(): Map<string, IconAsset>;\n\temit(outDir: string): Promise<void>;\n};\n\nexport function astroc4IconPlugin(state: IconPluginState): Astroc4IconPlugin {\n\tconst manifest = new Map<string, IconAsset>();\n\tconst byUrl = new Map<string, IconAsset>();\n\tconst base = state.base.replace(/\\/+$/, '');\n\n\tfunction gather(project: ResolvedProject, fileUrl: string): IconAsset | undefined {\n\t\tconst known = manifest.get(fileUrl);\n\t\tif (known) return known;\n\n\t\tconst entries = [\n\t\t\t// Re-validating against what is already served is how a second file at\n\t\t\t// the same URL is caught, whichever module compiled first.\n\t\t\t...[...byUrl.values()].map((asset) => ({\n\t\t\t\tproject: state.projects.find((p) => p.name === asset.projectName)!,\n\t\t\t\tfileUrl: pathToFileURL(asset.file).href,\n\t\t\t\tsource: `LikeC4 project \"${asset.projectName}\"`,\n\t\t\t})),\n\t\t\t{ project, fileUrl, source: `LikeC4 project \"${project.name}\"` },\n\t\t];\n\n\t\tconst asset = buildIconManifest(entries, state.base, state.siteRoot).get(fileUrl);\n\t\tif (!asset) return undefined;\n\n\t\tmanifest.set(fileUrl, asset);\n\n\t\t// Astro serves and copies `public/` itself.\n\t\tif (!asset.public) byUrl.set(asset.url, asset);\n\n\t\treturn asset;\n\t}\n\n\treturn {\n\t\tname: '@purview-dev/astroc4/icons',\n\t\tenforce: 'post',\n\t\ttransform(code, id) {\n\t\t\tconst match = LIKEC4_MODULE.exec(id);\n\t\t\tif (!match) return null;\n\n\t\t\tconst project = state.projects.find((p) => p.likec4Id === match.groups!.projectId);\n\t\t\tif (!project || !code.includes('file:')) return null;\n\n\t\t\tconst rewritten = code.replace(FILE_URL, (found) => {\n\t\t\t\tconst escapedForm = found.includes('\\\\u002F');\n\t\t\t\tconst [fileUrl, query] = found.replaceAll('\\\\u002F', '/').split('?', 2) as [string, string | undefined];\n\t\t\t\tconst real = unstage(fileUrl, project, state.stagingDir);\n\n\t\t\t\t// LikeC4's icons module imports each local icon (`?raw`, `?inline`).\n\t\t\t\t// Point the import at the real file so Vite can load it; only the\n\t\t\t\t// lookup keys and model values become served URLs.\n\t\t\t\tif (query !== undefined) {\n\t\t\t\t\treturn `${fileURLToPath(real).replaceAll('\\\\', '/')}?${query}`;\n\t\t\t\t}\n\n\t\t\t\tconst asset = gather(project, real);\n\n\t\t\t\tif (!asset) return found;\n\n\t\t\t\treturn escapedForm ? asset.url.replaceAll('/', '\\\\u002F') : asset.url;\n\t\t\t});\n\n\t\t\treturn rewritten === code ? null : { code: rewritten, map: null };\n\t\t},\n\t\tconfigureServer(server) {\n\t\t\tconst prefix = `${base}${ICON_ROUTE}`;\n\n\t\t\tserver.middlewares.use(async (req, res, next) => {\n\t\t\t\tconst url = req.url?.split('?')[0];\n\n\t\t\t\tif (!url?.startsWith(prefix)) return next();\n\n\t\t\t\tconst asset = byUrl.get(url);\n\n\t\t\t\t// Only what the model asked for is ever served: no path from the\n\t\t\t\t// request reaches the file system.\n\t\t\t\tif (!asset) {\n\t\t\t\t\tres.statusCode = 404;\n\t\t\t\t\tres.end();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tres.setHeader('Content-Type', CONTENT_TYPES[extname(asset.file).toLowerCase()] ?? 'application/octet-stream');\n\t\t\t\tres.end(await readFile(asset.file));\n\t\t\t});\n\t\t},\n\t\tmanifest: () => manifest,\n\t\tasync emit(outDir) {\n\t\t\tfor (const asset of byUrl.values()) {\n\t\t\t\tconst target = join(outDir, ...decodeURIComponent(asset.url.slice(base.length)).split('/'));\n\n\t\t\t\tawait mkdir(dirname(target), { recursive: true });\n\t\t\t\tawait copyFile(asset.file, target);\n\t\t\t}\n\t\t},\n\t};\n}\n",
10
11
  "// LikeC4 compiles local icons to absolute `file://` URLs, which 404 for\n// visitors and leak the build machine's folders, so each is mapped to a URL\n// under `/_astroc4/`:\n//\n// @ -> <project>/images icon @/azure/entra/x.svg -> /_astroc4/<project>/azure/entra/x.svg\n// @brand -> ../brand icon @brand/logo.svg -> /_astroc4/<project>/brand/logo.svg\n// (no alias) icon ../shared/a.svg -> /_astroc4/<project>/__up/shared/a.svg\n//\n// Files under the site's `public/` get their public URL, and Astro serves them.\n\nimport { realpathSync } from 'node:fs';\nimport { isAbsolute, join, relative, resolve, sep } from 'node:path';\nimport { fileURLToPath, pathToFileURL } from 'node:url';\n\nimport { Astroc4ConfigError, type ResolvedProject } from './projects.ts';\n\n/** After Astro's `base`. */\nexport const ICON_ROUTE = '/_astroc4/';\n\n/** Replaces `..` in a relative icon path, so URLs never climb. */\nconst UP = '__up';\n\nexport interface IconAsset {\n\t/** With links resolved. */\n\tfile: string;\n\t/** Including Astro's `base`. */\n\turl: string;\n\tprojectName: string;\n\t/** Under the site's `public/`: Astro serves and copies it, astroc4 does neither. */\n\tpublic?: boolean;\n}\n\nexport function iconAssetFor(\n\tproject: ResolvedProject,\n\tfileUrl: string,\n\tbase: string,\n\tsiteRoot: string,\n): IconAsset | null {\n\tconst file = realFile(fileUrl);\n\tconst prefix = base.replace(/\\/+$/, '');\n\tconst publicFolder = tryRealpath(join(siteRoot, 'public'));\n\n\tif (isInside(file, publicFolder)) {\n\t\tconst path = split(relative(publicFolder, file)).map(encodeURIComponent).join('/');\n\n\t\treturn { file, url: `${prefix}/${path}`, projectName: project.name, public: true };\n\t}\n\n\tconst segments = aliasSegments(project, file) ?? relativeSegments(tryRealpath(project.folder), file);\n\tconst path = [project.name, ...segments].map(encodeURIComponent).join('/');\n\n\treturn { file, url: `${prefix}${ICON_ROUTE}${path}`, projectName: project.name };\n}\n\n/**\n * LikeC4 resolves relative icon paths and `imageAliases` lexically against the\n * staging link it opened, so `resolve(link, x)` is mapped back to\n * `resolve(project.folder, x)`.\n */\nexport function unstage(fileUrl: string, project: ResolvedProject, stagingDir: string | undefined): string {\n\tif (stagingDir === undefined) return fileUrl;\n\n\tlet path: string;\n\n\ttry {\n\t\tpath = fileURLToPath(decodeDrive(fileUrl));\n\t} catch {\n\t\treturn fileUrl;\n\t}\n\n\tconst fromLink = relative(join(stagingDir, project.name), path);\n\n\treturn pathToFileURL(resolve(project.folder, fromLink)).href;\n}\n\n/**\n * @throws Astroc4ConfigError for a missing icon, or two files that would be\n * served at the same URL.\n */\nexport function buildIconManifest(\n\tentries: Array<{ project: ResolvedProject; fileUrl: string; source: string }>,\n\tbase: string,\n\tsiteRoot: string,\n): Map<string, IconAsset> {\n\tconst manifest = new Map<string, IconAsset>();\n\tconst byUrl = new Map<string, { asset: IconAsset; source: string }>();\n\n\tfor (const { project, fileUrl, source } of entries) {\n\t\tlet asset: IconAsset | null;\n\n\t\ttry {\n\t\t\tasset = iconAssetFor(project, fileUrl, base, siteRoot);\n\t\t} catch (error) {\n\t\t\tthrow new Astroc4ConfigError(`${source}: ${(error as Error).message.replace(/^\\[astroc4\\] /, '')}`);\n\t\t}\n\n\t\tif (asset === null) continue;\n\n\t\tconst existing = byUrl.get(asset.url);\n\n\t\tif (existing && !samePath(existing.asset.file, asset.file)) {\n\t\t\tthrow new Astroc4ConfigError(\n\t\t\t\t`two icons would be served at ${asset.url}: ${existing.asset.file} (${existing.source}) and ${asset.file} (${source}). Rename one, or give its alias another name.`,\n\t\t\t);\n\t\t}\n\n\t\tbyUrl.set(asset.url, { asset, source });\n\t\tmanifest.set(fileUrl, asset);\n\t}\n\n\treturn manifest;\n}\n\n/** The longest alias folder containing `file`: `[alias name?, …path under it]`. */\nfunction aliasSegments(project: ResolvedProject, file: string): string[] | null {\n\tlet best: { folder: string; alias: string } | null = null;\n\n\tfor (const [alias, folder] of Object.entries(project.imageAliases)) {\n\t\tconst real = tryRealpath(folder);\n\n\t\tif (isInside(file, real) && (best === null || real.length > best.folder.length)) {\n\t\t\tbest = { folder: real, alias };\n\t\t}\n\t}\n\n\tif (best === null) return null;\n\n\tconst name = best.alias.replace(/^@/, '');\n\n\treturn [...(name ? [name] : []), ...split(relative(best.folder, file))];\n}\n\nfunction relativeSegments(folder: string, file: string): string[] {\n\treturn split(relative(folder, file)).map((segment) => (segment === '..' ? UP : segment));\n}\n\nfunction realFile(fileUrl: string): string {\n\tlet path: string;\n\n\ttry {\n\t\t// `file:///p%3A/…` is how LikeC4 writes a Windows drive; decoding first\n\t\t// lets `fileURLToPath` read it like `file:///P:/…`.\n\t\tpath = fileURLToPath(decodeDrive(fileUrl));\n\t} catch {\n\t\tthrow new Astroc4ConfigError(`icon ${fileUrl} is not a file URL.`);\n\t}\n\n\ttry {\n\t\treturn realpathSync(path);\n\t} catch {\n\t\tthrow new Astroc4ConfigError(`icon ${path} does not exist.`);\n\t}\n}\n\nfunction decodeDrive(fileUrl: string): string {\n\treturn fileUrl.replace(/^file:\\/\\/\\/([A-Za-z])%3A/i, 'file:///$1:');\n}\n\nfunction tryRealpath(path: string): string {\n\ttry {\n\t\treturn realpathSync(path);\n\t} catch {\n\t\treturn path;\n\t}\n}\n\nfunction isInside(file: string, folder: string): boolean {\n\tconst path = relative(folder, file);\n\n\treturn path.length > 0 && !path.startsWith('..') && !isAbsolute(path);\n}\n\nfunction samePath(a: string, b: string): boolean {\n\treturn sep === '\\\\' ? a.toLowerCase() === b.toLowerCase() : a === b;\n}\n\nfunction split(path: string): string[] {\n\treturn path.split(/[\\\\/]+/).filter((segment) => segment.length > 0);\n}\n",
11
12
  "import { readdir, readFile, stat } from 'node:fs/promises';\nimport { basename, join, resolve } from 'node:path';\n\nimport type { ConfigFilenames } from 'likec4/config';\n\n/**\n * LikeC4's config file names, in the order it prefers them. `satisfies` fails\n * the type-check when LikeC4 adds or renames one.\n */\nconst CONFIG_FILES = [\n\t'.likec4rc',\n\t'.likec4.config.json',\n\t'likec4.config.json',\n\t'likec4.config.js',\n\t'likec4.config.cjs',\n\t'likec4.config.mjs',\n\t'likec4.config.ts',\n\t'likec4.config.cts',\n\t'likec4.config.mts',\n] as const satisfies typeof ConfigFilenames;\n\nconst JSON_CONFIG_FILES: readonly string[] = CONFIG_FILES.slice(0, 3);\n\nexport interface ResolvedProject {\n\t/** The name components pass as `project`. */\n\tname: string;\n\tfolder: string;\n\t/** The `name` in the project's own config — LikeC4's project id. */\n\tlikec4Id: string;\n\tsource: 'configured' | 'discovered';\n\t/** `imageAliases` from the config, each resolved to an absolute folder. */\n\timageAliases: Record<string, string>;\n}\n\nexport class Astroc4ConfigError extends Error {\n\tconstructor(message: string) {\n\t\tsuper(`[astroc4] ${message}`);\n\t\tthis.name = 'Astroc4ConfigError';\n\t}\n}\n\n/** Every LikeC4 project under `root`, skipping `node_modules` and dot folders. */\nexport async function discoverProjects(root: string): Promise<ResolvedProject[]> {\n\tconst found: ResolvedProject[] = [];\n\n\tasync function walk(folder: string): Promise<void> {\n\t\tconst entries = await readdir(folder, { withFileTypes: true });\n\t\tconst file = configFileIn(entries.filter((entry) => entry.isFile()).map((entry) => entry.name));\n\n\t\tif (file) {\n\t\t\tconst config = await readConfig(folder, file);\n\t\t\tfound.push(toProject(config.name, folder, config, 'discovered'));\n\t\t}\n\n\t\tfor (const entry of entries) {\n\t\t\tif (!entry.isDirectory() || entry.name === 'node_modules' || entry.name.startsWith('.')) continue;\n\t\t\tawait walk(join(folder, entry.name));\n\t\t}\n\t}\n\n\tawait walk(resolve(root));\n\treturn found;\n}\n\n/**\n * Configured projects first, in declaration order, then the discovered ones\n * no configured entry already covers.\n */\nexport async function resolveProjects(options: {\n\troot: string;\n\tconfigured?: Record<string, string>;\n\tdiscovered: ResolvedProject[];\n}): Promise<ResolvedProject[]> {\n\tconst configured: ResolvedProject[] = [];\n\n\tfor (const [name, path] of Object.entries(options.configured ?? {})) {\n\t\tconst folder = resolve(options.root, path);\n\n\t\tif (!(await isDirectory(folder))) {\n\t\t\tthrow new Astroc4ConfigError(`project \"${name}\": folder ${folder} does not exist.`);\n\t\t}\n\n\t\tconst file = configFileIn(await readdir(folder));\n\n\t\tif (!file) {\n\t\t\tthrow new Astroc4ConfigError(\n\t\t\t\t`project \"${name}\": no LikeC4 config file (likec4.config.json, .likec4rc, likec4.config.ts, …) in ${folder}.`,\n\t\t\t);\n\t\t}\n\n\t\tconfigured.push(toProject(name, folder, await readConfig(folder, file), 'configured'));\n\t}\n\n\tconst configuredFolders = new Set(configured.map((project) => project.folder));\n\tconst projects = [\n\t\t...configured,\n\t\t...options.discovered.filter((project) => !configuredFolders.has(project.folder)),\n\t];\n\n\tconst byName = new Map<string, ResolvedProject>();\n\n\tfor (const project of projects) {\n\t\tconst existing = byName.get(project.name);\n\n\t\tif (existing) {\n\t\t\tthrow new Astroc4ConfigError(\n\t\t\t\t`two LikeC4 projects are named \"${project.name}\": ${existing.folder} and ${project.folder}.`,\n\t\t\t);\n\t\t}\n\n\t\tbyName.set(project.name, project);\n\t}\n\n\t// LikeC4 registers a project by its config's `name`, so two that share one\n\t// collide inside the compiler however they are named here.\n\tconst byId = new Map<string, ResolvedProject>();\n\n\tfor (const project of projects) {\n\t\tconst existing = byId.get(project.likec4Id);\n\n\t\tif (existing) {\n\t\t\tthrow new Astroc4ConfigError(\n\t\t\t\t`two LikeC4 projects declare \"name\": \"${project.likec4Id}\" in their configs: ${existing.folder} and ${project.folder}. Rename one.`,\n\t\t\t);\n\t\t}\n\n\t\tbyId.set(project.likec4Id, project);\n\t}\n\n\treturn projects;\n}\n\ninterface LikeC4Config {\n\tname: string;\n\timageAliases?: Record<string, string>;\n}\n\nfunction configFileIn(names: string[]): string | undefined {\n\treturn CONFIG_FILES.find((file) => names.includes(file));\n}\n\n/**\n * A project's config, read the way LikeC4 reads it: JSON files as JSON5, the\n * rest bundled and evaluated, and `name` defaulting to the folder's name.\n */\nasync function readConfig(folder: string, file: string): Promise<LikeC4Config> {\n\tconst path = join(folder, file);\n\tlet config: unknown;\n\n\ttry {\n\t\tconfig = JSON_CONFIG_FILES.includes(file) ? await readJsonConfig(path) : await evaluateConfig(path, folder);\n\t} catch (error) {\n\t\tthrow new Astroc4ConfigError(`${path} could not be read: ${(error as Error).message}`);\n\t}\n\n\tif (typeof config !== 'object' || config === null || Array.isArray(config)) {\n\t\tthrow new Astroc4ConfigError(`${path} must define a config object.`);\n\t}\n\n\tconst { name = basename(folder), imageAliases } = config as { name?: unknown; imageAliases?: unknown };\n\n\tif (typeof name !== 'string' || name.trim().length === 0) {\n\t\tthrow new Astroc4ConfigError(`${path} has an empty \"name\".`);\n\t}\n\n\treturn { name, imageAliases: isRecord(imageAliases) ? imageAliases : undefined };\n}\n\nasync function readJsonConfig(path: string): Promise<unknown> {\n\tconst { default: JSON5 } = await import('json5');\n\tconst text = (await readFile(path, 'utf8')).trim();\n\n\treturn JSON5.parse(text || '{}');\n}\n\n/**\n * `likec4/config`'s helpers are identity functions, so they are replaced with\n * one, as LikeC4 does: a project outside the site need not be able to resolve\n * the package.\n */\nasync function evaluateConfig(path: string, folder: string): Promise<unknown> {\n\tconst { bundleRequire } = await import('bundle-require');\n\n\tconst { mod } = await bundleRequire({\n\t\tfilepath: path,\n\t\tcwd: folder,\n\t\tesbuildOptions: {\n\t\t\tresolveExtensions: ['.ts', '.mts', '.cts', '.mjs', '.js', '.cjs'],\n\t\t\tplugins: [\n\t\t\t\t{\n\t\t\t\t\tname: 'astroc4-likec4-config',\n\t\t\t\t\tsetup(build) {\n\t\t\t\t\t\tbuild.onResolve({ filter: /^@?likec4\\/config$/ }, (args) => ({\n\t\t\t\t\t\t\tpath: args.path,\n\t\t\t\t\t\t\tnamespace: 'astroc4-likec4-config',\n\t\t\t\t\t\t}));\n\t\t\t\t\t\tbuild.onLoad({ filter: /.*/, namespace: 'astroc4-likec4-config' }, () => ({\n\t\t\t\t\t\t\tcontents: [\n\t\t\t\t\t\t\t\t'const identity = (value) => value;',\n\t\t\t\t\t\t\t\t'export { identity as defineConfig, identity as defineGenerators, identity as defineStyle, identity as defineTheme, identity as defineThemeColor };',\n\t\t\t\t\t\t\t].join('\\n'),\n\t\t\t\t\t\t\tloader: 'js',\n\t\t\t\t\t\t}));\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t],\n\t\t},\n\t});\n\n\treturn (mod as { default?: unknown }).default ?? mod;\n}\n\nfunction toProject(\n\tname: string,\n\tfolder: string,\n\tconfig: LikeC4Config,\n\tsource: ResolvedProject['source'],\n): ResolvedProject {\n\tconst imageAliases = Object.fromEntries(\n\t\tObject.entries(config.imageAliases ?? {}).map(([alias, path]) => [alias, resolve(folder, path)]),\n\t);\n\n\treturn { name, folder: resolve(folder), likec4Id: config.name, source, imageAliases };\n}\n\nfunction isRecord(value: unknown): value is Record<string, string> {\n\treturn (\n\t\ttypeof value === 'object' &&\n\t\tvalue !== null &&\n\t\t!Array.isArray(value) &&\n\t\tObject.values(value).every((entry) => typeof entry === 'string')\n\t);\n}\n\nasync function isDirectory(path: string): Promise<boolean> {\n\treturn (await stat(path).catch(() => null))?.isDirectory() ?? false;\n}\n",
12
13
  "// `LikeC4VitePlugin` takes a single `workspace`, so every project is linked\n// (not copied, so LikeC4 sees edits) under one staging folder. It lives in\n// `.astro/`, never `node_modules/`: LikeC4 excludes `**/node_modules/**`.\n\nimport { lstat, mkdir, readdir, readlink, realpath, rm, symlink } from 'node:fs/promises';\nimport { join, resolve } from 'node:path';\n\nimport type { ResolvedProject } from './projects.ts';\n\nexport const PROJECTS_MODULE_ID = 'virtual:astroc4/projects';\n\n/** @returns The staging folder to hand `LikeC4VitePlugin` as its `workspace`. */\nexport async function prepareWorkspace(projects: ResolvedProject[], cacheDir: string): Promise<string> {\n\tconst staging = join(cacheDir, 'workspace');\n\tawait mkdir(staging, { recursive: true });\n\n\tconst wanted = new Map(projects.map((project) => [project.name, resolve(project.folder)]));\n\n\tfor (const entry of await readdir(staging)) {\n\t\tconst target = wanted.get(entry);\n\n\t\tif (target === undefined || !(await pointsAt(join(staging, entry), target))) {\n\t\t\t// `rm` on a link removes the link, never what it points at.\n\t\t\tawait rm(join(staging, entry), { recursive: false, force: true });\n\t\t}\n\t}\n\n\tfor (const [name, folder] of wanted) {\n\t\tconst link = join(staging, name);\n\n\t\tif (await exists(link)) continue;\n\n\t\t// A junction needs no elevated rights on Windows; elsewhere the type\n\t\t// argument is ignored and a plain directory symlink is made.\n\t\tawait symlink(folder, link, 'junction');\n\t}\n\n\treturn staging;\n}\n\nexport function projectsModule(projects: ResolvedProject[]): string {\n\tconst names = projects.map((project) => project.name);\n\tconst ids = Object.fromEntries(projects.map((project) => [project.name, project.likec4Id]));\n\n\treturn [\n\t\t`export const projectNames = ${JSON.stringify(names)};`,\n\t\t`export const likec4IdFor = ${JSON.stringify(ids)};`,\n\t].join('\\n');\n}\n\nasync function pointsAt(link: string, target: string): Promise<boolean> {\n\ttry {\n\t\tconst stats = await lstat(link);\n\n\t\tif (!stats.isSymbolicLink()) return false;\n\n\t\tawait readlink(link);\n\t\treturn (await realpath(link)) === (await realpath(target));\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nasync function exists(path: string): Promise<boolean> {\n\treturn (await lstat(path).catch(() => null)) !== null;\n}\n"
13
14
  ],
14
- "mappings": "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",
15
- "debugId": "7D3E2F75E2D8075C64756E2164756E21",
15
+ "mappings": "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",
16
+ "debugId": "8CC5199B7D8470E564756E2164756E21",
16
17
  "names": []
17
18
  }
@@ -0,0 +1,27 @@
1
+ export type ValidationMode = 'strict' | 'relaxed';
2
+ export interface ValidationScope {
3
+ /** The mode for a page no `relaxed` pattern matches. Defaults to `'strict'`. */
4
+ default?: ValidationMode;
5
+ /**
6
+ * Page path globs, relative to the site root, that use `'relaxed'`. `*`
7
+ * matches within a path segment, `**` across segments, and a pattern matches
8
+ * at any depth — `tutorials/**` finds `src/content/docs/tutorials/…`.
9
+ */
10
+ relaxed?: string | string[];
11
+ /**
12
+ * Content collections that use `'relaxed'`, by name. A page's collection is
13
+ * its first folder under the content directory (`src/content/<name>/…`),
14
+ * which is how Astro's `glob` loader maps a collection to a folder.
15
+ */
16
+ collections?: string | string[];
17
+ }
18
+ /** A single mode for the whole site, or per-page rules. */
19
+ export type ValidationOptions = ValidationMode | ValidationScope;
20
+ /** A glob as a regexp anchored at both ends, with an implicit "any folder" prefix. */
21
+ export declare function globToRegExp(pattern: string): RegExp;
22
+ /**
23
+ * The mode a page uses. `relativePath` is the page's path from the site root and
24
+ * `collection` its content collection; either may be `undefined` when it cannot
25
+ * be worked out — then whatever is left decides, falling back to `default`.
26
+ */
27
+ export declare function validationModeFor(options: ValidationOptions | undefined, relativePath: string | undefined, collection?: string): ValidationMode;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@purview-dev/astroc4",
3
- "version": "1.0.0-prerelease.7",
3
+ "version": "1.0.0-prerelease.8",
4
4
  "description": "Interactive LikeC4 architecture diagrams for Astro and Starlight: <LikeC4View>, ```likec4 fences, and LikeC4 syntax highlighting derived from the live Langium grammar.",
5
5
  "license": "MIT",
6
6
  "author": {