@purview-dev/astroc4 1.0.0-prerelease.4 → 1.0.0-prerelease.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +222 -77
- package/dist/expressive-code.d.ts +0 -4
- package/dist/expressive-code.js.map +5 -5
- package/dist/fences.d.ts +45 -16
- package/dist/file-layout.d.ts +4 -0
- package/dist/grammar/langium.d.ts +0 -4
- package/dist/grammar/source.d.ts +0 -12
- package/dist/grammar/textmate.d.ts +0 -2
- package/dist/icon-assets.d.ts +28 -0
- package/dist/icon-plugin.d.ts +16 -0
- package/dist/index.d.ts +21 -43
- package/dist/index.js +707 -97
- package/dist/index.js.map +15 -9
- package/dist/integration.d.ts +27 -0
- package/dist/integration.js +827 -0
- package/dist/integration.js.map +17 -0
- package/dist/projects.d.ts +24 -0
- package/dist/translations.d.ts +1 -0
- package/dist/workspace.d.ts +5 -0
- package/package.json +24 -4
- package/src/components/DiagramFrame.astro +14 -16
- package/src/components/DiagramShell.astro +19 -20
- package/src/components/ErrorBoundary.tsx +1 -5
- package/src/components/LikeC4Fence.astro +3 -6
- package/src/components/LikeC4InlineView.tsx +6 -16
- package/src/components/LikeC4ProjectView.tsx +0 -5
- package/src/components/LikeC4View.astro +75 -21
- package/src/components/LoadingPlaceholder.astro +10 -9
- package/src/components/icon-source.ts +5 -22
- package/src/components/labels.ts +10 -16
- package/src/components/md-fences.tsx +37 -0
- package/src/components/render-icon.tsx +0 -9
- package/src/components/utils.ts +40 -7
- package/src/translations.ts +3 -10
package/dist/index.js.map
CHANGED
|
@@ -1,15 +1,21 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../src/index.ts", "../src/fences.ts", "../src/
|
|
3
|
+
"sources": ["../src/index.ts", "../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", "../src/grammar/source.ts", "../src/grammar/langium.ts", "../src/grammar/textmate.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"// index.ts\n// path: src/index.ts\n// Starlight plugin that renders LikeC4 architecture diagrams:\n//\n// import astroc4 from '@purview-dev/astroc4';\n// starlight({ plugins: [astroc4()] })\n//\n// It wires up everything a site previously had to configure by hand:\n// - LikeC4VitePlugin, which compiles every .c4 project under the site root\n// into the `likec4:model` / `likec4:icons` / `likec4:projects` modules;\n// - the ```likec4 fence transform (./fences.mjs), appended to the site's\n// Sätteri processor;\n// - the build-time preload that avoids a Windows-only crash (see\n// `preloadLikeC4` in ./fences.mjs);\n// - LikeC4 syntax highlighting, resolved from the live Langium grammar and\n// injected into the site's Expressive Code options (see below);\n// - the component UI strings, through Starlight's i18n system.\n//\n// The highlighting injection is why this is a Starlight plugin and not just an\n// integration: Starlight runs plugin `config:setup` hooks *before* it builds\n// its Expressive Code integration, and a plugin can `updateConfig` the\n// `expressiveCode` option — so the grammar reaches Shiki without the site\n// having to create an `ec.config.mjs`. Expressive Code concatenates\n// `shiki.langs` when it merges integration options with an `ec.config.mjs`, so\n// a site that has one keeps its own languages too.\n\nimport { fileURLToPath } from 'node:url';\n\nimport type { StarlightPlugin, StarlightUserConfig } from '@astrojs/starlight/types';\nimport type { AstroConfig, AstroIntegration, AstroIntegrationLogger } from 'astro';\nimport { LikeC4VitePlugin } from 'likec4/vite-plugin';\n\nimport { likec4Fences, preloadLikeC4 } from './fences.js';\nimport { resolveLikeC4Grammar } from './grammar/source.js';\nimport { LANGUAGE_ALIASES, LANGUAGE_NAME } from './grammar/textmate.js';\nimport { translations } from './translations.js';\n\n/**\n * The published package name. Scoped because npm refuses the unscoped\n * `astroc4` — \"too similar to existing package astro\" — and because the scope\n * makes the specifiers this plugin writes into a site's pages unambiguous.\n */\nconst PACKAGE_NAME = '@purview-dev/astroc4';\n\n/**\n * LikeC4 syntax highlighting, derived from the Langium grammar in\n * `likec4/likec4` and registered with the site's Expressive Code.\n */\nexport interface LikeC4HighlightingOptions {\n\t/**\n\t * Branch, tag or commit SHA to read `like-c4.langium` from.\n\t * Defaults to `main`; pin a tag (`v1.59.4`) or a SHA for reproducible CI.\n\t * Also read from `ASTROC4_REF`.\n\t */\n\tref?: string;\n\t/** Repository to read from. Defaults to `likec4/likec4`. */\n\trepo?: string;\n\t/** Use the bundled snapshot and never touch the network. Also `ASTROC4_OFFLINE=1`. */\n\toffline?: boolean;\n\t/**\n\t * What to do when the grammar cannot be fetched. Defaults to `fail`, so\n\t * `astro build` and `astro check` fail like any other build error.\n\t * A `ref` that does not exist always fails.\n\t */\n\tonError?: 'fail' | 'warn' | 'silent';\n\t/** Seconds a cached fetch stays fresh. Defaults to an hour. */\n\tcacheTtl?: number;\n\t/** Ignore the cache and refetch. */\n\trefresh?: boolean;\n\t/** Where to cache. Defaults to `node_modules/.cache/astroc4`. */\n\tcacheDir?: string;\n\t/** Raw host to read from, for mirrors. Defaults to raw.githubusercontent.com. */\n\tbaseUrl?: string;\n\t/** Request timeout in milliseconds. Defaults to 15000. */\n\ttimeout?: number;\n}\n\nexport interface StarlightLikeC4Options {\n\t/**\n\t * Passed through to `LikeC4VitePlugin` — e.g. `{ workspace: 'diagrams' }` to\n\t * look for .c4 files somewhere other than the site root.\n\t */\n\tvitePlugin?: Parameters<typeof LikeC4VitePlugin>[0];\n\t/** Render ```likec4 fences in .mdx pages as diagrams. Defaults to `true`. */\n\tfences?: boolean;\n\t/**\n\t * Highlight ```c4 / ```likec4 source. Defaults to `true`; `false` leaves\n\t * Expressive Code entirely to the site.\n\t */\n\thighlighting?: boolean | LikeC4HighlightingOptions;\n}\n\nexport default function starlightLikeC4(options: StarlightLikeC4Options = {}): StarlightPlugin {\n\treturn {\n\t\tname: PACKAGE_NAME,\n\t\thooks: {\n\t\t\t'i18n:setup'({ injectTranslations }) {\n\t\t\t\tinjectTranslations(translations);\n\t\t\t},\n\t\t\tasync 'config:setup'({ config, astroConfig, updateConfig, addIntegration, logger }) {\n\t\t\t\taddIntegration(likec4Integration(options));\n\n\t\t\t\tif (options.highlighting === false) return;\n\n\t\t\t\tawait injectHighlighting({\n\t\t\t\t\t// `config` is the Starlight config, `astroConfig` the Astro one:\n\t\t\t\t\t// the site root and the cache directory live on the latter.\n\t\t\t\t\troot: fileURLToPath(astroConfig.root),\n\t\t\t\t\texpressiveCode: config.expressiveCode,\n\t\t\t\t\tupdateConfig,\n\t\t\t\t\tlogger,\n\t\t\t\t\t// `true` means \"on with defaults\"; only an object carries options.\n\t\t\t\t\toptions: typeof options.highlighting === 'object' ? options.highlighting : {},\n\t\t\t\t});\n\t\t\t},\n\t\t},\n\t};\n}\n\n/** What Starlight's `config:setup` hook offers, narrowed to what is used here. */\ntype StarlightConfigUpdate = Partial<Omit<StarlightUserConfig, 'routeMiddleware'>>;\n\n/** Everything `injectHighlighting` needs, assembled by the hook below. */\ninterface HighlightingContext {\n\troot: string;\n\texpressiveCode: unknown;\n\tupdateConfig: (config: StarlightConfigUpdate) => void;\n\tlogger: AstroIntegrationLogger;\n\toptions: LikeC4HighlightingOptions;\n}\n\n/**\n * Register the LikeC4 grammar with whatever Expressive Code the site ends up\n * with.\n *\n * This is deliberately not wrapped in a try/catch: a ref that does not exist,\n * or a grammar that cannot be read, fails `astro dev`, `astro build`,\n * `astro check` and `astro sync` exactly like any other build error. Sites that\n * cannot reach github.com on every build opt out with `offline: true` or\n * `onError: 'warn'`.\n */\nasync function injectHighlighting({\n\troot,\n\texpressiveCode,\n\tupdateConfig,\n\tlogger,\n\toptions,\n}: HighlightingContext) {\n\tif (expressiveCode === false) {\n\t\tlogger.warn(\n\t\t\t'LikeC4 syntax highlighting is skipped: `expressiveCode: false` disables the code blocks it ' +\n\t\t\t\t'would highlight. Diagrams are unaffected.',\n\t\t);\n\t\treturn;\n\t}\n\n\tconst source = await resolveLikeC4Grammar({ root, ...options, logger });\n\n\tconst registration = {\n\t\t...source.grammar,\n\t\tname: LANGUAGE_NAME,\n\t\taliases: [...LANGUAGE_ALIASES],\n\t};\n\n\tupdateConfig({\n\t\t// `withLikeC4Language` keeps the option's shape generic so it stays usable\n\t\t// outside Starlight; every field it returns is one Expressive Code accepts.\n\t\texpressiveCode: withLikeC4Language(expressiveCode, registration) as StarlightConfigUpdate['expressiveCode'],\n\t});\n\n\tconst { repo, ref, sha, source: from } = source.meta;\n\tlogger.info(\n\t\t`LikeC4 grammar ${repo}@${ref} (${sha})${from === 'network' ? '' : ` from ${from}`} — ` +\n\t\t\t'highlighting ```c4 and ```likec4 fences',\n\t);\n}\n\n/**\n * Add the LikeC4 language to a site's Expressive Code options without\n * disturbing anything already set.\n *\n * Replacing an existing entry rather than appending matters: a site that\n * pinned `likec4Language` from `@purview-dev/astroc4/expressive-code` should get the\n * grammar for the ref it configured here, not two grammars for the same scope.\n * Expressive Code concatenates `shiki.langs` when it merges these options with\n * an `ec.config.mjs`, so a site's own languages survive either way.\n *\n * @param expressiveCode The site's `expressiveCode` option.\n * @param registration Shiki language registration.\n */\nexport function withLikeC4Language(\n\texpressiveCode: unknown,\n\tregistration: Record<string, unknown>,\n): Record<string, unknown> & { shiki: { langs: unknown[] } } {\n\tconst current = isObject(expressiveCode) ? expressiveCode : {};\n\tconst shiki = isObject(current.shiki) ? current.shiki : {};\n\tconst langs: unknown[] = Array.isArray(shiki.langs) ? [...shiki.langs] : [];\n\tconst existing = langs.findIndex(isLikeC4Language);\n\n\tif (existing === -1) langs.push(registration);\n\telse langs[existing] = registration;\n\n\treturn { ...current, shiki: { ...shiki, langs } };\n}\n\n/** A Shiki `langs` entry that already covers LikeC4, as an id or a registration. */\nfunction isLikeC4Language(entry: unknown): boolean {\n\tif (typeof entry === 'string') return entry === LANGUAGE_NAME || LANGUAGE_ALIASES.includes(entry);\n\tif (!isObject(entry)) return false;\n\n\tif (entry.name === LANGUAGE_NAME || entry.scopeName === 'source.likec4') return true;\n\n\treturn Array.isArray(entry.aliases) && entry.aliases.some((alias) => LANGUAGE_ALIASES.includes(alias));\n}\n\nfunction isObject(value: unknown): value is Record<string, any> {\n\treturn typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\n\nfunction likec4Integration({ vitePlugin = {}, fences = true }: StarlightLikeC4Options): AstroIntegration {\n\treturn {\n\t\tname: `${PACKAGE_NAME}/integration`,\n\t\thooks: {\n\t\t\t'astro:config:setup': async ({ command, config, updateConfig, logger }) => {\n\t\t\t\tupdateConfig({\n\t\t\t\t\tvite: {\n\t\t\t\t\t\tplugins: [LikeC4VitePlugin(vitePlugin)],\n\t\t\t\t\t\t// The components ship as .astro/.tsx source, so Vite has to\n\t\t\t\t\t\t// transform them rather than hand them to Node as-is.\n\t\t\t\t\t\tssr: { noExternal: [PACKAGE_NAME] },\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);\n\t\t\t\t}\n\n\t\t\t\t// `command` is only available here, not in `astro:config:done` — and\n\t\t\t\t// this must stay build-only; see `loadLikeC4` in ./fences.mjs.\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},\n\t};\n}\n\n/**\n * Append the fence transform to the site's existing Sätteri processor, keeping\n * whatever Starlight and other integrations already registered on it.\n */\nasync function registerFences(\n\tconfig: AstroConfig,\n\tupdateConfig: (config: Record<string, unknown>) => void,\n\tlogger: AstroIntegrationLogger,\n): Promise<void> {\n\tconst { satteri, isSatteriProcessor } = await import('@astrojs/markdown-satteri');\n\tconst existing = config.markdown?.processor;\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: [likec4Fences()] }) } });\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 ?? []), likec4Fences()],\n\t\t\t}),\n\t\t},\n\t});\n}\n",
|
|
6
|
-
"// fences.mjs\n// path: src/fences.mjs\n// Turns a ```likec4 code fence into a rendered diagram instead of a code block.\n//\n// Two forms:\n//\n// ```likec4 view=\"requestPath\" title=\"Request path\"\n// ```\n// -> renders a view from the site's LikeC4 project (any likec4.config.json).\n//\n// ```likec4 title=\"Example\"\n// specification { element system }\n// model { a = system 'A' b = system 'B' a -> b }\n// views { view index { include * } }\n// ```\n// -> compiles and lays out this snippet at build time, then renders it.\n//\n// Layout needs LikeC4's WASM graph engine, so it has to happen during the\n// build; the browser only rehydrates the resulting JSON.\n//\n// This is a Sätteri mdast plugin, not a remark one. Astro 7 made Sätteri the\n// default Markdown processor, and `remarkPlugins` is a legacy option that is\n// silently ignored unless @astrojs/markdown-remark is installed. The plugin's\n// integration (src/index.mjs) registers it; sites do not add it themselves.\n\nimport { createHash } from 'node:crypto';\nimport { createRequire } from 'node:module';\nimport { fileURLToPath } from 'node:url';\n\nimport type { MdastPluginEntry, PluginFactoryContext } from 'satteri';\n\nconst require = createRequire(import.meta.url);\n\n// `likec4`'s Node API is deliberately NOT imported at module scope. It pulls in\n// Langium, chevrotain, an LSP and the WASM layout engine, and this module is\n// loaded as part of the site's astro.config — on a cold start that was\n// enough to make Astro report \"Configuration file updated. Restarting...\", and the restart\n// killed the content-layer transport, leaving every page a 500. Load it lazily\n// so the cost is paid only when a page actually contains an inline fence.\nlet likec4ApiPromise: Promise<LikeC4Api> | undefined;\n\n/** The one thing this module needs from `likec4`'s Node API. */\ntype LikeC4Api = typeof import('likec4').LikeC4;\n\nfunction loadLikeC4(): Promise<LikeC4Api> {\n\t// A plain `require('likec4')` rather than `import('likec4')`: Vite's SSR\n\t// module runner intercepts dynamic `import()` from any module it loaded\n\t// (this one included) to route it through the runner's own module graph —\n\t// and on Windows that runner can already be mid-teardown by the time a\n\t// page's ```likec4 fence triggers this, crashing the whole `astro build`\n\t// (see `preloadLikeC4` below). `require()` goes through Node's own\n\t// resolver instead, which Node 22+ supports for ESM-only packages like\n\t// this one, sidestepping the runner entirely.\n\tlikec4ApiPromise ??= Promise.resolve(require('likec4').LikeC4);\n\n\treturn likec4ApiPromise;\n}\n\n/**\n * Kick off (and await) the same lazy load `loadLikeC4()` uses, so a later\n * call inside Satteri's processing reuses the already-resolved promise\n * instead of issuing a fresh `import('likec4')`.\n *\n * `astro build` on Windows crashes mid-build (\"Vite module runner has been\n * closed\", followed by a native libuv assertion that kills the process) if\n * that first `import('likec4')` happens while Vite is tearing down the SSR\n * module runner used for the content layer — which is exactly when the first\n * page containing a ```likec4 fence is rendered. Finishing the import before\n * that point removes the race. src/index.mjs calls this from\n * `astro:config:setup` for builds only — the module-scope comment above\n * `loadLikeC4` explains why eager-loading it in dev is unsafe.\n */\nexport function preloadLikeC4(): Promise<LikeC4Api> {\n\treturn loadLikeC4();\n}\n\nconst FENCE_LANG = 'likec4';\n\n/** Component the fence is rewritten into, per form. */\nconst INLINE_COMPONENT = '__LikeC4Fence';\nconst PROJECT_COMPONENT = '__LikeC4View';\n\n// Package specifiers, not relative paths: the import is written into the page\n// being compiled, so it has to resolve from the site, not from this file.\n/** The published package name; see the comment on `PACKAGE_NAME` in index.ts. */\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\n/** The fence components a page can need. */\ntype ComponentName = keyof typeof IMPORTS;\n\n/** What a fence's layout produces: the serialised model and its view ids. */\ninterface Layout {\n\tdump: any;\n\tviewIds: string[];\n}\n\n/**\n * Compiling a snippet costs ~250ms (a Langium workspace per call) and the same\n * page is re-rendered on every dev edit, so key on the source: a build pays\n * that once per distinct snippet, not once per render.\n */\nconst layoutCache = new Map<string, Layout>();\n\n/** The `key=\"value\"` pairs a fence's meta string can carry. */\nexport interface FenceMeta {\n\ttitle?: string;\n\tdescription?: string;\n\theight?: string;\n\tcollapsible?: string;\n\tdefaultOpen?: string;\n\tview?: string;\n\t[key: string]: string | undefined;\n}\n\n/** Parse `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\nasync function layoutSnippet(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// Only the first line of each error — LikeC4's parser errors enumerate\n\t\t// every token it expected, which runs to hundreds of lines.\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\t// `$data` is the plain serialisable model; `$model` is its deprecated alias.\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\n/** A JSX attribute, as the MDX compiler wants it. */\ninterface JsxAttribute {\n\ttype: 'mdxJsxAttribute';\n\tname: string;\n\tvalue: string;\n}\n\n/** ESTree for `import <local> from '<source>';`, as the MDX compiler expects. */\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// region plugin\nexport function likec4Fences(): MdastPluginEntry {\n\t// A factory runs once per document, so `used` is safely per-file.\n\treturn (factory: PluginFactoryContext) => {\n\t\t// Astro only supports components in .mdx. Leaving the fence as a code\n\t\t// block is the graceful outcome, but say so — a silent code block where\n\t\t// a diagram was intended is easy to miss in review.\n\t\tif (factory.sourceFormat !== 'mdx') {\n\t\t\tif (!factory.source.includes('```' + FENCE_LANG)) return null;\n\n\t\t\treturn {\n\t\t\t\tname: 'likec4-fences:warn',\n\t\t\t\tcode(node, ctx) {\n\t\t\t\t\tif (node.lang !== FENCE_LANG) return;\n\n\t\t\t\t\tconsole.warn(\n\t\t\t\t\t\t`[likec4-fences] ${describe(ctx.fileURL)} has a \\`\\`\\`${FENCE_LANG} fence, but fences only ` +\n\t\t\t\t\t\t\t'render as diagrams in .mdx files. Rename the page to .mdx, or use <LikeC4View /> directly.',\n\t\t\t\t\t);\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\n\t\tif (!factory.source.includes('```' + FENCE_LANG)) return null;\n\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 = (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\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 }),\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 layoutSnippet(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 ?? layout.viewIds[0];\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\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\t// Imports go in once, after every fence on the page is known.\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\nexport default likec4Fences;\n",
|
|
7
|
-
"// source.mjs\n// path: src/grammar/source.mjs\n// Resolves the LikeC4 grammar the site asked for: the Langium grammar from\n// likec4/likec4 at a branch, tag or commit, cached on disk, reduced to a\n// TextMate grammar by ./textmate.mjs.\n//\n// This runs from the site's `astro:config:setup`, so `astro dev`, `astro\n// build`, `astro check` and `astro sync` all go through it — a bad ref or an\n// unreadable grammar fails the command instead of quietly shipping\n// unhighlighted code.\n//\n// Network policy: strict by default (`onError: 'fail'`). A *bad ref* is user\n// error and always fails. A *network failure* may fall back to the cache from\n// the last successful fetch, and then to the bundled snapshot, but only when\n// `onError` says so.\n\nimport { createHash } from 'node:crypto';\nimport { mkdir, readFile, rename, writeFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nimport { parseLangium } from './langium.js';\nimport { buildTmLanguage, type TmGrammar } from './textmate.js';\n\n/** Upstream repository and the paths the grammar is read from. */\nexport const DEFAULT_REPO = 'likec4/likec4';\nexport const DEFAULT_REF = 'main';\nexport const LANGIUM_PATH = 'packages/language-server/src/like-c4.langium';\nexport const DEFAULT_BASE_URL = 'https://raw.githubusercontent.com';\n\n/** Shape of a cache file. Bump when the fields change. */\nconst CACHE_VERSION = 1;\n\nconst BUNDLED_GRAMMAR = new URL('./likec4.tmLanguage.json', import.meta.url);\nconst BUNDLED_LANGIUM = new URL('./like-c4.langium', import.meta.url);\n\n/** The refs a repository actually has: branches, tags, `a1b2c3d`. */\nconst REF_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._/-]*$/;\n\nexport type OnError = 'fail' | 'warn' | 'silent';\n\n/** Everything the resolver accepts. The site only ever sets a few of these. */\nexport interface GrammarSourceOptions {\n\t/** Repository to read from. Defaults to likec4/likec4. */\n\trepo?: string;\n\t/** Branch, tag or commit SHA. Defaults to `main`. */\n\tref?: string;\n\t/** Use the bundled snapshot, never the network. */\n\toffline?: boolean;\n\t/** What to do when the grammar cannot be fetched. */\n\tonError?: OnError;\n\t/** Seconds a cached fetch stays fresh. */\n\tcacheTtl?: number;\n\t/** Ignore the cache and refetch. */\n\trefresh?: boolean;\n\t/** Raw file host, for mirrors and proxies. */\n\tbaseUrl?: string;\n\t/** Request timeout in milliseconds. */\n\ttimeout?: number;\n\t/** Site root, for the default cache directory. */\n\troot?: string;\n\t/** Where to cache, overriding the default. */\n\tcacheDir?: string;\n\t/** Environment, for `ASTROC4_*` overrides. */\n\tenv?: NodeJS.ProcessEnv;\n\t/** Astro's logger. */\n\tlogger?: { info?: (message: string) => void; warn?: (message: string) => void };\n\t/** Injected in tests. */\n\tfetchImpl?: typeof fetch;\n\t/** Bundled Langium text, for tests. */\n\tbundledLangiumPath?: string;\n}\n\n/** Where a grammar came from, for logs and tests. */\nexport interface GrammarMeta {\n\trepo: string;\n\tref: string;\n\t/** Where it came from. */\n\tsource: 'network' | 'cache' | 'bundled';\n\tfetchedAt: number;\n\tetag?: string | undefined;\n\t/** Content hash of the Langium source. */\n\tsha: string;\n\t/** Why the bundled snapshot was used. */\n\treason?: string;\n}\n\nexport interface GrammarSource {\n\t/** The TextMate grammar for Shiki. */\n\tgrammar: TmGrammar;\n\t/** The Langium source it was derived from. */\n\tlangium: string;\n\t/** Where it came from, for logs and tests. */\n\tmeta: GrammarMeta;\n}\n\n/** A repo and ref, which is all a cache entry is keyed on. */\ninterface GrammarIdentity {\n\trepo: string;\n\tref: string;\n}\n\n/** Raised for a ref this repository cannot have — always a user error. */\nexport class GrammarRefError extends Error {\n\toverride name = 'GrammarRefError';\n}\n\n/** Raised when the grammar could not be fetched, or came back unusable. */\nexport class GrammarFetchError extends Error {\n\toverride name = 'GrammarFetchError';\n}\n\nexport async function resolveLikeC4Grammar(options: GrammarSourceOptions = {}): Promise<GrammarSource> {\n\tconst env = options.env ?? process.env;\n\tconst repo = options.repo ?? DEFAULT_REPO;\n\tconst ref = env.ASTROC4_REF || options.ref || DEFAULT_REF;\n\tconst offline = options.offline ?? isTruthy(env.ASTROC4_OFFLINE);\n\tconst onError = options.onError ?? 'fail';\n\tconst logger = options.logger;\n\n\tvalidateRef(ref);\n\n\tif (offline) {\n\t\treturn bundled('offline: true', options);\n\t}\n\n\tconst cache = await readCache(options, { repo, ref });\n\n\tif (cache?.fresh && !options.refresh) {\n\t\treturn derive(cache.langium, { repo, ref, source: 'cache', fetchedAt: cache.fetchedAt, etag: cache.etag });\n\t}\n\n\tlet fetched;\n\n\ttry {\n\t\tfetched = await fetchLangiumSource({ ...options, repo, ref, etag: cache?.etag });\n\t} catch (error) {\n\t\tif (!(error instanceof Error)) throw error;\n\n\t\t// A bad ref will fail the same way forever: never paper over it.\n\t\tif (error instanceof GrammarRefError) throw error;\n\n\t\tif (onError === 'fail') throw error;\n\n\t\tif (onError === 'warn') logger?.warn?.(`[astroc4] ${error.message}`);\n\n\t\tif (cache) {\n\t\t\tif (onError === 'warn') {\n\t\t\t\tlogger?.warn?.(`[astroc4] using the grammar cached at ${new Date(cache.fetchedAt).toISOString()}`);\n\t\t\t}\n\n\t\t\treturn derive(cache.langium, {\n\t\t\t\trepo,\n\t\t\t\tref,\n\t\t\t\tsource: 'cache',\n\t\t\t\tfetchedAt: cache.fetchedAt,\n\t\t\t\tetag: cache.etag,\n\t\t\t});\n\t\t}\n\n\t\treturn bundled(error.message, options);\n\t}\n\n\tif ('notModified' in fetched) {\n\t\tif (!cache) {\n\t\t\tthrow new GrammarFetchError(\n\t\t\t\t'the grammar host answered 304 for a grammar that is not cached — retry with `refresh: true`',\n\t\t\t);\n\t\t}\n\n\t\tawait writeCache(options, { repo, ref }, cache);\n\n\t\treturn derive(cache.langium, { repo, ref, source: 'cache', fetchedAt: cache.fetchedAt, etag: cache.etag });\n\t}\n\n\tconst result = derive(fetched.text, { repo, ref, source: 'network', etag: fetched.etag });\n\tawait writeCache(options, { repo, ref }, { langium: fetched.text, etag: fetched.etag });\n\n\treturn result;\n}\n\n/** Where a derivation came from, before it becomes `GrammarMeta`. */\ninterface DeriveInfo {\n\trepo: string;\n\tref: string;\n\tsource: 'network' | 'cache' | 'bundled';\n\tfetchedAt?: number;\n\tetag?: string | undefined;\n}\n\nfunction derive(langium: string, info: DeriveInfo): GrammarSource {\n\tlet vocabulary;\n\n\ttry {\n\t\tvocabulary = parseLangium(langium);\n\t} catch (cause) {\n\t\tthrow new GrammarFetchError(\n\t\t\t`${info.repo}@${info.ref}: the grammar could not be read — ${cause instanceof Error ? cause.message : String(cause)}`,\n\t\t\t{ cause },\n\t\t);\n\t}\n\n\tconst sha = grammarSha(langium);\n\n\treturn {\n\t\tgrammar: buildTmLanguage(vocabulary, { repo: info.repo, ref: info.ref, sha }),\n\t\tlangium,\n\t\tmeta: {\n\t\t\trepo: info.repo,\n\t\t\tref: info.ref,\n\t\t\tsource: info.source,\n\t\t\tfetchedAt: info.fetchedAt ?? Date.now(),\n\t\t\tetag: info.etag,\n\t\t\tsha,\n\t\t},\n\t};\n}\n\n/**\n * The snapshot shipped with this package, for `offline: true` and for falling\n * back when the network is down and `onError` allows it. It is derived from\n * the committed `like-c4.langium`, so it matches `likec4.tmLanguage.json` (the\n * snapshot test asserts exactly that). Its provenance is the snapshot's own,\n * not the ref that was asked for.\n * @param reason Why it is being used, surfaced in logs.\n */\nasync function bundled(reason: string, options: GrammarSourceOptions): Promise<GrammarSource> {\n\tconst path = options.bundledLangiumPath ?? fileURLToPath(BUNDLED_LANGIUM);\n\tconst snapshot = await bundledProvenance();\n\n\tconst source = derive(await readFile(path, 'utf8'), {\n\t\trepo: snapshot.repo ?? DEFAULT_REPO,\n\t\tref: snapshot.ref ?? DEFAULT_REF,\n\t\tsource: 'bundled',\n\t});\n\n\tsource.meta.reason = reason;\n\n\treturn source;\n}\n\n/** `$generated` from the shipped grammar, so logs name the real snapshot. */\nasync function bundledProvenance(): Promise<{ repo?: string; ref?: string }> {\n\ttry {\n\t\tconst { $generated } = JSON.parse(await readFile(fileURLToPath(BUNDLED_GRAMMAR), 'utf8'));\n\n\t\treturn { repo: $generated?.repo, ref: $generated?.ref };\n\t} catch {\n\t\treturn {};\n\t}\n}\n\n/** Short content hash — the identity that actually changes highlighting. */\nexport function grammarSha(source: string): string {\n\treturn createHash('sha256').update(source).digest('hex').slice(0, 12);\n}\n\n// region refs\n\n/**\n * Rejects anything that cannot name a ref, before it reaches the network.\n */\nexport function validateRef(ref: string): string {\n\tif (typeof ref !== 'string' || ref.length === 0) {\n\t\tthrow new GrammarRefError('the LikeC4 grammar `ref` must be a branch, tag or commit SHA');\n\t}\n\n\tif (!REF_PATTERN.test(ref) || ref.includes('..') || ref.endsWith('/') || ref.includes('//')) {\n\t\tthrow new GrammarRefError(\n\t\t\t`\"${ref}\" is not a usable LikeC4 grammar ref — expected a branch, tag or commit SHA such as \"main\" or \"v1.59.4\"`,\n\t\t);\n\t}\n\n\treturn ref;\n}\n\n\n// endregion\n\n// region fetch\n\n/** What a fetch returns: the text, or the news that the ETag still matches. */\nexport type FetchResult = { text: string; etag?: string | undefined } | { notModified: true };\n\nexport async function fetchLangiumSource(\n\toptions: GrammarSourceOptions & { repo: string; ref: string; etag?: string | undefined },\n): Promise<FetchResult> {\n\tconst repo = options.repo;\n\tconst ref = options.ref;\n\tconst baseUrl = (options.baseUrl ?? DEFAULT_BASE_URL).replace(/\\/+$/, '');\n\tconst url = `${baseUrl}/${repo}/${ref}/${LANGIUM_PATH}`;\n\tconst timeout = options.timeout ?? 15_000;\n\tconst request = options.fetchImpl ?? fetch;\n\n\tconst headers: Record<string, string> = { 'user-agent': 'astroc4', accept: 'text/plain' };\n\tif (options.etag) headers['if-none-match'] = options.etag;\n\n\tlet response;\n\n\ttry {\n\t\tresponse = await request(url, { headers, redirect: 'follow', signal: AbortSignal.timeout(timeout) });\n\t} catch (cause) {\n\t\tthrow new GrammarFetchError(\n\t\t\t`could not fetch the LikeC4 grammar from ${url} — ${cause instanceof Error ? cause.message : String(cause)}. ` +\n\t\t\t\t'Builds are strict by default: pass `highlighting: { offline: true }` to use the bundled grammar instead.',\n\t\t\t{ cause },\n\t\t);\n\t}\n\n\tif (response.status === 304) return { notModified: true };\n\n\tif (response.status === 404) {\n\t\tthrow new GrammarRefError(\n\t\t\t`${repo} has no \"${ref}\", or it no longer has ${LANGIUM_PATH} (${url}). ` +\n\t\t\t\t'Use a tag such as \"v1.59.4\", a commit SHA, or \"main\".',\n\t\t);\n\t}\n\n\tif (!response.ok) {\n\t\tthrow new GrammarFetchError(\n\t\t\t`${url} responded ${response.status} ${response.statusText} — set ` +\n\t\t\t\t'`highlighting: { onError: \"warn\" }` to fall back to the bundled grammar.',\n\t\t);\n\t}\n\n\tconst text = await response.text();\n\n\tif (text.trim().length === 0) {\n\t\tthrow new GrammarFetchError(`${url} returned an empty file — the grammar is not usable`);\n\t}\n\n\treturn { text, etag: response.headers.get('etag') ?? undefined };\n}\n\n// endregion\n\n// region cache\n\n/**\n * Cache location: `node_modules/.cache/astroc4`, which every Astro project\n * already ignores. One file per repo@ref, so switching `ref` never thrashes.\n */\nfunction cachePath(options: GrammarSourceOptions, identity: GrammarIdentity): string {\n\tconst dir =\n\t\toptions.cacheDir ?? join(options.root ?? process.cwd(), 'node_modules', '.cache', 'astroc4');\n\tconst key = createHash('sha256').update(`${identity.repo}@${identity.ref}`).digest('hex').slice(0, 16);\n\n\treturn join(dir, `grammar-${key}.json`);\n}\n\n/** What a cache file holds. */\ntype CacheWriteEntry = { langium: string; etag?: string | undefined };\n/** A cache entry, plus whether it is still inside its TTL. */\ninterface CacheEntry extends CacheWriteEntry {\n\tfetchedAt: number;\n}\ninterface FreshCacheEntry extends CacheEntry {\n\tfresh: boolean;\n}\n\nasync function readCache(\n\toptions: GrammarSourceOptions,\n\tidentity: GrammarIdentity,\n): Promise<FreshCacheEntry | undefined> {\n\tlet raw;\n\n\ttry {\n\t\traw = await readFile(cachePath(options, identity), 'utf8');\n\t} catch {\n\t\treturn undefined;\n\t}\n\n\ttry {\n\t\tconst entry = JSON.parse(raw);\n\n\t\tif (\n\t\t\tentry?.version !== CACHE_VERSION ||\n\t\t\tentry.repo !== identity.repo ||\n\t\t\tentry.ref !== identity.ref ||\n\t\t\ttypeof entry.langium !== 'string' ||\n\t\t\ttypeof entry.fetchedAt !== 'number'\n\t\t) {\n\t\t\t// A cache written by a different version of this package, or a\n\t\t\t// truncated file. Refetching is cheaper than debugging it.\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst ttl = options.cacheTtl ?? 3600;\n\n\t\treturn { ...entry, fresh: Date.now() - entry.fetchedAt < ttl * 1000 };\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\n/**\n * Best effort: a read-only `node_modules` must not fail a build, it only means\n * the next one has to fetch again.\n */\nasync function writeCache(\n\toptions: GrammarSourceOptions,\n\tidentity: GrammarIdentity,\n\tentry: CacheWriteEntry,\n): Promise<void> {\n\tconst path = cachePath(options, identity);\n\tconst temporary = `${path}.${process.pid}.tmp`;\n\n\ttry {\n\t\tawait mkdir(join(path, '..'), { recursive: true });\n\t\tawait writeFile(\n\t\t\ttemporary,\n\t\t\tJSON.stringify({\n\t\t\t\tversion: CACHE_VERSION,\n\t\t\t\trepo: identity.repo,\n\t\t\t\tref: identity.ref,\n\t\t\t\tetag: entry.etag,\n\t\t\t\tfetchedAt: Date.now(),\n\t\t\t\tlangium: entry.langium,\n\t\t\t}),\n\t\t\t'utf8',\n\t\t);\n\t\t// Rename rather than write in place: two Astro processes can resolve the\n\t\t// same cache entry at once during `astro check && astro build`.\n\t\tawait rename(temporary, path);\n\t} catch (error) {\n\t\toptions.logger?.warn?.(\n\t\t\t`[astroc4] could not cache the LikeC4 grammar in ${path} — ${error instanceof Error ? error.message : String(error)}`,\n\t\t);\n\t}\n}\n\n// endregion\n\nfunction isTruthy(value: string | undefined): boolean {\n\treturn typeof value === 'string' && /^(1|true|yes|on)$/i.test(value.trim());\n}\n\nexport default resolveLikeC4Grammar;\n\n",
|
|
8
|
-
"// langium.mjs\n// path: src/grammar/langium.mjs\n// Reduces the LikeC4 Langium grammar to the vocabulary a TextMate grammar\n// needs: which words open a block, which are plain keywords, which are\n// property names, which belong to a closed value domain (shapes, colours,\n// arrow heads…) and which tokens have to be matched structurally (comments,\n// strings, icon ids).\n//\n// The grammar is read from likec4/likec4 at a ref the site chooses:\n// `packages/language-server/src/like-c4.langium`. Deriving from it is what\n// keeps highlighting in step with the language — `ElementShape` gained `agent`\n// after v1.59.4, and the TextMate grammar upstream maintains by hand still\n// does not know about it.\n//\n// Deliberately no Langium dependency: this is a tolerant scanner over one\n// file, not a parser for the grammar language, and it has to survive upstream\n// reformatting. Anything it cannot classify is dropped rather than guessed.\n\n/** Rules that describe a closed set of values are named after what they hold. */\nconst NOT_VALUE_DOMAINS = /Id$/;\n\n/** Property names the grammar matches as `key='…'` assignments. */\nconst PROPERTY_SUPPLEMENTS = ['kind', 'tag'];\n\n/** A token produced by the scanner. */\nexport type TokenType = 'literal' | 'regex' | 'ident' | 'punct';\nexport interface Token {\n\ttype: TokenType;\n\tvalue: string;\n}\n\n/** A `terminal` rule, with its value as written. */\nexport interface Terminal {\n\thidden: boolean;\n\tkind: 'regex' | 'literal';\n\t/** Raw regex source (without slashes) or the literal. */\n\tvalue: string;\n}\n\n/** A parser rule, fragment or terminal, as the scanner reads it. */\nexport interface Rule {\n\tname: string;\n\tkind: 'rule' | 'fragment' | 'terminal';\n\thidden: boolean;\n\treturns?: string | undefined;\n\ttokens: Token[];\n}\n\n/** Everything the TextMate generator needs to know about the language. */\nexport interface Vocabulary {\n\t/** Keywords that open a `{ … }` block. */\n\tblocks: string[];\n\t/** Every remaining word-like literal. */\n\tkeywords: string[];\n\t/** Property names from `key='…'` assignments. */\n\tproperties: string[];\n\t/** Relationship connectors containing `->`. */\n\tarrows: string[];\n\t/** `returns string` value domains, by rule name. */\n\tenums: Record<string, string[]>;\n\t/** Icon packs from the `LIB_ICON` terminal. */\n\ticons: string[];\n\t/** Literals from the `BOOLEAN` terminal. */\n\tbooleans: string[];\n\t/** Parser rules seen — used for sanity checks. */\n\truleCount: number;\n}\n\nexport function parseLangium(source: string): Vocabulary {\n\t// `grammar LikeC4` is a header, not a rule, and it has no `;`: leaving it in\n\t// would glue it to the first real rule and hide that rule from the scanner.\n\tconst statements = splitStatements(\n\t\tstripComments(source).replace(/^[ \\t]*grammar[ \\t]+[A-Za-z_]\\w*[ \\t]*$/gm, ''),\n\t);\n\tconst rules = statements.map(readStatement).filter((rule) => rule !== undefined);\n\n\tconst parserRules = rules.filter((rule) => rule.kind === 'rule' || rule.kind === 'fragment');\n\n\tif (parserRules.length === 0) {\n\t\tthrow new Error(\n\t\t\t'the file contains no Langium parser rules — is this still `packages/language-server/src/like-c4.langium`?',\n\t\t);\n\t}\n\n\tconst enums = resolveEnums(parserRules);\n\tconst blocks = findBlocks(parserRules);\n\tconst properties = unique([...findProperties(parserRules), ...PROPERTY_SUPPLEMENTS]);\n\tconst arrows = findArrows(parserRules);\n\tconst literals = unique(\n\t\tparserRules.flatMap((rule) => rule.tokens.filter((t) => t.type === 'literal').map((t) => t.value)),\n\t);\n\n\tconst classified = new Set([...blocks, ...properties, ...Object.values(enums).flat()]);\n\tconst keywords = literals.filter(\n\t\t(value) => /^[A-Za-z_]\\w*$/.test(value) && !classified.has(value),\n\t);\n\n\tconst terminals = readTerminals(rules);\n\n\t// A grammar with parser rules but no structure at all is not a LikeC4\n\t// grammar — most likely the path now holds something else. A small grammar\n\t// can legitimately have no \"leftover\" keywords, so blocks and value domains\n\t// count too.\n\tif (keywords.length === 0 && blocks.length === 0 && Object.keys(enums).length === 0) {\n\t\tthrow new Error('the file contains no LikeC4 keywords — the Langium grammar could not be read');\n\t}\n\n\treturn {\n\t\tblocks,\n\t\tkeywords,\n\t\tproperties,\n\t\tarrows,\n\t\tenums,\n\t\ticons: terminalAlternatives(terminals.LIB_ICON),\n\t\tbooleans: terminalAlternatives(terminals.BOOLEAN),\n\t\truleCount: parserRules.length,\n\t};\n}\n\n// region scanning\n\n/**\n * Blank out `//` and block comments. String and regex literals are copied\n * verbatim, because a `//` inside `/https?:\\/\\//` is not a comment.\n */\nfunction stripComments(source: string): string {\n\tlet out = '';\n\tlet i = 0;\n\n\twhile (i < source.length) {\n\t\tconst char = source[i];\n\n\t\tif (char === '/' && source[i + 1] === '/') {\n\t\t\twhile (i < source.length && source[i] !== '\\n') i++;\n\t\t\tout += ' ';\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (char === '/' && source[i + 1] === '*') {\n\t\t\ti += 2;\n\t\t\twhile (i < source.length && !(source[i] === '*' && source[i + 1] === '/')) i++;\n\t\t\ti += 2;\n\t\t\tout += ' ';\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (char === \"'\" || char === '\"') {\n\t\t\tconst end = endOfString(source, i);\n\t\t\tout += source.slice(i, end);\n\t\t\ti = end;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (char === '/') {\n\t\t\tconst end = endOfRegex(source, i);\n\t\t\tout += source.slice(i, end);\n\t\t\ti = end;\n\t\t\tcontinue;\n\t\t}\n\n\t\tout += char;\n\t\ti++;\n\t}\n\n\treturn out;\n}\n\n/** Index just past the quoted literal that opens at `start`. */\nfunction endOfString(source: string, start: number): number {\n\tconst quote = source[start];\n\tlet i = start + 1;\n\n\twhile (i < source.length) {\n\t\tif (source[i] === '\\\\') {\n\t\t\ti += 2;\n\t\t\tcontinue;\n\t\t}\n\t\tif (source[i] === quote) return i + 1;\n\t\ti++;\n\t}\n\n\treturn source.length;\n}\n\n/** Index just past the regex literal that opens at `start`. */\nfunction endOfRegex(source: string, start: number): number {\n\tlet i = start + 1;\n\tlet inClass = false;\n\n\twhile (i < source.length) {\n\t\tconst char = source[i];\n\n\t\tif (char === '\\\\') {\n\t\t\ti += 2;\n\t\t\tcontinue;\n\t\t}\n\t\tif (char === '[') inClass = true;\n\t\telse if (char === ']') inClass = false;\n\t\telse if (char === '/' && !inClass) return i + 1;\n\n\t\ti++;\n\t}\n\n\treturn source.length;\n}\n\n/**\n * Split on the `;` that ends each rule, ignoring the ones inside strings,\n * regexes and `{ … }` — interfaces have fields, and rules have `{infer X}`\n * actions, both of which can contain semicolons.\n */\nfunction splitStatements(source: string): string[] {\n\tconst statements: string[] = [];\n\tlet depth = 0;\n\tlet start = 0;\n\tlet i = 0;\n\n\twhile (i < source.length) {\n\t\tconst char = source[i];\n\n\t\tif (char === \"'\" || char === '\"') {\n\t\t\ti = endOfString(source, i);\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (char === '/') {\n\t\t\ti = endOfRegex(source, i);\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (char === '{') depth++;\n\t\telse if (char === '}') depth = Math.max(0, depth - 1);\n\t\telse if (char === ';' && depth === 0) {\n\t\t\tstatements.push(source.slice(start, i));\n\t\t\tstart = i + 1;\n\t\t}\n\n\t\ti++;\n\t}\n\n\tconst tail = source.slice(start).trim();\n\tif (tail.length > 0) statements.push(tail);\n\n\treturn statements.filter((statement) => statement.trim().length > 0);\n}\n\nconst HEADERS: { kind: 'rule' | 'fragment' | 'terminal'; hidden: boolean; pattern: RegExp }[] = [\n\t// `hidden terminal WS: /[ \\t]+/`\n\t{ kind: 'terminal', hidden: true, pattern: /^\\s*hidden\\s+terminal\\s+([A-Za-z_]\\w*)\\s*(?:<[^>]*>)?\\s*:/ },\n\t// `terminal LIB_ICON: /…/`, `terminal fragment HASH: '#'`\n\t{\n\t\tkind: 'terminal',\n\t\thidden: false,\n\t\tpattern:\n\t\t\t/^\\s*terminal\\s+(?:fragment\\s+)?([A-Za-z_]\\w*)\\s*(?:<[^>]*>)?\\s*(?:returns\\s+[A-Za-z_]\\w*\\s*)?:/,\n\t},\n\t// `fragment RelationConnector:`\n\t{ kind: 'fragment', hidden: false, pattern: /^\\s*fragment\\s+([A-Za-z_]\\w*)\\s*:/ },\n\t// `Model:`, `ModelViews:`, `entry LikeC4Grammar:`, `Relation<isExplicit>:`\n\t{\n\t\tkind: 'rule',\n\t\thidden: false,\n\t\tpattern: /^\\s*(?:entry\\s+)?([A-Za-z_]\\w*)\\s*(?:<[^>]*>)?\\s*(?:returns\\s+([A-Za-z_]\\w*)\\s*)?:/,\n\t},\n];\n\nfunction readStatement(statement: string): Rule | undefined {\n\tfor (const header of HEADERS) {\n\t\tconst match = header.pattern.exec(statement);\n\t\tconst name = match?.[1];\n\t\tif (!match || !name) continue;\n\n\t\treturn {\n\t\t\tname,\n\t\t\tkind: header.kind,\n\t\t\thidden: header.hidden,\n\t\t\treturns: header.kind === 'rule' ? match[2] : undefined,\n\t\t\ttokens: tokenize(statement.slice(match[0].length)),\n\t\t};\n\t}\n\n\treturn undefined;\n}\n\nfunction tokenize(body: string): Token[] {\n\tconst tokens: Token[] = [];\n\tlet i = 0;\n\n\twhile (i < body.length) {\n\t\tconst char = body.charAt(i);\n\n\t\tif (/\\s/.test(char)) {\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (char === \"'\" || char === '\"') {\n\t\t\tconst end = endOfString(body, i);\n\t\t\ttokens.push({ type: 'literal', value: unquote(body.slice(i, end)) });\n\t\t\ti = end;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (char === '/') {\n\t\t\tconst end = endOfRegex(body, i);\n\t\t\ttokens.push({ type: 'regex', value: body.slice(i + 1, end - 1) });\n\t\t\ti = end;\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst identifier = /^[A-Za-z_]\\w*/.exec(body.slice(i));\n\t\tif (identifier) {\n\t\t\ttokens.push({ type: 'ident', value: identifier[0] });\n\t\t\ti += identifier[0].length;\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Multi-character punctuation (`+=`, `?=`) is irrelevant: only `=`, `|`,\n\t\t// `(` and `)` are inspected, and per-character tokens give all four.\n\t\ttokens.push({ type: 'punct', value: char });\n\t\ti++;\n\t}\n\n\treturn tokens;\n}\n\n/** Strip the quotes and resolve the escapes Langium allows in literals. */\nfunction unquote(quoted: string): string {\n\tconst inner = quoted.slice(1, -1);\n\tlet out = '';\n\n\tfor (let i = 0; i < inner.length; i++) {\n\t\tif (inner[i] !== '\\\\') {\n\t\t\tout += inner[i];\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst escaped = inner[++i];\n\t\tif (escaped === 'n') out += '\\n';\n\t\telse if (escaped === 't') out += '\\t';\n\t\telse if (escaped === 'r') out += '\\r';\n\t\telse out += escaped ?? '';\n\t}\n\n\treturn out;\n}\n\n// endregion\n\n// region vocabulary\n\n/**\n * Rules of the shape `'specification' '{' …` or `name='model' '{' …` open a\n * block. The first literal of the rule is the keyword, and it only counts when\n * the rule reaches a `{` without branching first: `'element' kind=ElementKind\n * ('{' …)` has an optional body, so `element` stays a keyword.\n */\nfunction findBlocks(rules: Rule[]): string[] {\n\treturn unique(\n\t\trules.flatMap((rule) => {\n\t\t\tconst tokens = rule.tokens;\n\t\t\tconst first = tokens.findIndex((token) => token.type === 'literal');\n\t\t\tconst keyword = first === -1 ? undefined : tokens[first]?.value;\n\n\t\t\tif (!keyword || keyword === '{' || !/^[A-Za-z_]\\w*$/.test(keyword)) return [];\n\n\t\t\tfor (let i = first + 1; i < tokens.length; i++) {\n\t\t\t\tconst token = tokens[i];\n\t\t\t\tif (!token) break;\n\t\t\t\tif (token.value === '(' || token.value === '|') return [];\n\t\t\t\tif (token.type === 'literal' && token.value === '{') return [keyword];\n\t\t\t}\n\n\t\t\treturn [];\n\t\t}),\n\t);\n}\n\n/**\n * `key='title'` and `key=('head' | 'tail')` name a property. Positional\n * arguments (`props+=String`) and `name=` (block headers) are ignored.\n */\nfunction findProperties(rules: Rule[]): string[] {\n\tconst properties: string[] = [];\n\n\tfor (const rule of rules) {\n\t\tconst tokens = rule.tokens;\n\n\t\tfor (let i = 0; i < tokens.length; i++) {\n\t\t\tconst token = tokens[i];\n\t\t\tif (!token || token.type !== 'ident' || token.value !== 'key') continue;\n\n\t\t\tconst equals = equalsIndex(tokens, i);\n\t\t\tif (equals === -1) continue;\n\n\t\t\tlet j = equals + 1;\n\n\t\t\tif (tokens[j]?.value === '(') {\n\t\t\t\tfor (j++; j < tokens.length && tokens[j]?.value !== ')'; j++) {\n\t\t\t\t\tconst inner = tokens[j];\n\t\t\t\t\tif (inner?.type === 'literal') properties.push(inner.value);\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst value = tokens[j];\n\t\t\tif (value?.type === 'literal') properties.push(value.value);\n\t\t}\n\t}\n\n\treturn properties.filter((value) => /^[A-Za-z_]\\w*$/.test(value));\n}\n\n/**\n * Index of the `=` that assigns `tokens[i]` (`key=`, `key?=`, `key+=`), or `-1`\n * when the identifier is not being assigned.\n */\nfunction equalsIndex(tokens: Token[], i: number): number {\n\tif (tokens[i]?.type !== 'ident') return -1;\n\n\tconst next = tokens[i + 1]?.value;\n\tif (next === '=') return i + 1;\n\tif ((next === '?' || next === '+') && tokens[i + 2]?.value === '=') return i + 2;\n\n\treturn -1;\n}\n\n/**\n * The connectors live in one fragment:\n * dotKind=RelationKindDotRef | '-[' kind=[RelationshipKind] (… '->') | … | '->'\n */\nfunction findArrows(rules: Rule[]): string[] {\n\tconst connector = rules.find((rule) => rule.name === 'RelationConnector');\n\tconst fromConnector = (connector?.tokens ?? [])\n\t\t.filter((token) => token.type === 'literal' && token.value.includes('->'))\n\t\t.map((token) => token.value);\n\n\t// Longest first: TextMate alternation is first-match, so `]->` has to be\n\t// tried before `->` at the same position.\n\treturn unique([...fromConnector, '->', '<->']).sort((a, b) => b.length - a.length || a.localeCompare(b));\n}\n\n/**\n * A `returns string` rule whose body is only literals, `|` and references to\n * other such rules is a closed value domain — `BorderStyleValue: LineOptions |\n * 'none'` inherits from `LineOptions` that way. Anything referencing a rule\n * that is not itself a value domain (e.g. `Id returns string`) resolves to\n * nothing and is dropped.\n */\nfunction resolveEnums(rules: Rule[]): Record<string, string[]> {\n\tconst candidates = new Map<string, string[]>();\n\n\tfor (const rule of rules) {\n\t\tif (rule.returns !== 'string' || NOT_VALUE_DOMAINS.test(rule.name)) continue;\n\n\t\tconst onlyValuesAndChoices = rule.tokens.every(\n\t\t\t(token) =>\n\t\t\t\ttoken.type === 'literal' ||\n\t\t\t\ttoken.type === 'ident' ||\n\t\t\t\t(token.type === 'punct' && (token.value === '|' || token.value === ';')),\n\t\t);\n\n\t\tif (onlyValuesAndChoices) candidates.set(rule.name, []);\n\t}\n\n\t// Fixpoint, because `BorderStyleValue` can only resolve once `LineOptions`\n\t// has. One pass per rule is enough for any acyclic grammar.\n\tfor (let pass = 0; pass < rules.length; pass++) {\n\t\tlet changed = false;\n\n\t\tfor (const rule of rules) {\n\t\t\tif (!candidates.has(rule.name)) continue;\n\n\t\t\tconst resolved: string[] = [];\n\t\t\tlet complete = true;\n\n\t\t\tfor (const token of rule.tokens) {\n\t\t\t\tif (token.type === 'literal') {\n\t\t\t\t\tresolved.push(token.value);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tif (token.type !== 'ident') continue;\n\n\t\t\t\tconst inherited = candidates.get(token.value);\n\t\t\t\tif (inherited === undefined) {\n\t\t\t\t\tcomplete = false;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tresolved.push(...inherited);\n\t\t\t}\n\n\t\t\tconst next = unique(resolved);\n\t\t\tif (!complete || next.length === 0) continue;\n\n\t\t\tif ((candidates.get(rule.name) ?? []).length !== next.length) {\n\t\t\t\tcandidates.set(rule.name, next);\n\t\t\t\tchanged = true;\n\t\t\t}\n\t\t}\n\n\t\tif (!changed) break;\n\t}\n\n\tconst enums: Record<string, string[]> = {};\n\tfor (const [name, values] of [...candidates].sort(([a], [b]) => a.localeCompare(b))) {\n\t\tif (values.length > 0) enums[name] = values;\n\t}\n\n\treturn enums;\n}\n\n/** Reads every `terminal` rule, keyed by name. */\nfunction readTerminals(rules: Rule[]): Record<string, Terminal> {\n\tconst terminals: Record<string, Terminal> = {};\n\n\tfor (const rule of rules) {\n\t\tif (rule.kind !== 'terminal') continue;\n\n\t\tconst token = rule.tokens.find((candidate) => candidate.type === 'regex' || candidate.type === 'literal');\n\t\tif (!token) continue;\n\n\t\tterminals[rule.name] = {\n\t\t\thidden: rule.hidden,\n\t\t\tkind: token.type === 'regex' ? 'regex' : 'literal',\n\t\t\tvalue: token.value,\n\t\t};\n\t}\n\n\treturn terminals;\n}\n\n/**\n * The alternatives of the first group in a terminal's regex:\n * `(aws|azure|bootstrap|gcp|md|tech):[-\\w]+` -> the icon packs.\n */\nfunction terminalAlternatives(terminal: Terminal | undefined): string[] {\n\tif (!terminal || terminal.kind !== 'regex') return [];\n\n\tconst group = /\\(([^()]*)\\)/.exec(terminal.value);\n\tif (!group) return [];\n\n\treturn unique((group[1] ?? '').split('|').map((value) => value.trim())).filter((value) =>\n\t\t/^[A-Za-z][\\w-]*$/.test(value),\n\t);\n}\n\nfunction unique(values: string[]): string[] {\n\treturn [...new Set(values)].sort((a, b) => a.localeCompare(b));\n}\n\n// endregion\n\nexport default parseLangium;\n\n",
|
|
9
|
-
"// textmate.mjs\n// path: src/grammar/textmate.mjs\n// Builds the Shiki / TextMate grammar for LikeC4 out of the vocabulary read\n// from the live Langium grammar (./langium.mjs).\n//\n// Two layers:\n// - generated — every word list: blocks, keywords, property names and closed\n// value domains. These are exactly the lists that go stale when the\n// language grows (`agent` was added to `ElementShape` after v1.59.4).\n// - structural — how LikeC4 source is *shaped* rather than which words it\n// uses: comments, quoted and triple-quoted strings, `#tag` vs `#hex`,\n// `tech:astro` icons, `-[https]->` arrows, `element system` declarations.\n// These are curated here because a Langium rule does not say how a token\n// should look, only that it is one.\n//\n// The result must stay plain JSON: Expressive Code JSON-round-trips integration\n// options before the `<Code>` component renders them, and throws on functions\n// or RegExp instances.\n\nimport type { Vocabulary } from './langium.js';\n\n/** Scope name of the grammar, as upstream's VS Code extension uses it. */\nexport const SCOPE_NAME = 'source.likec4';\n\n/** Shiki language id, plus the short alias used by ` ```c4 ` fences. */\nexport const LANGUAGE_NAME = 'likec4';\nexport const LANGUAGE_ALIASES = ['c4'];\n\nconst TMLANGUAGE_SCHEMA =\n\t'https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json';\n\n/**\n * Closed value domains: they colour as values, not as keywords.\n * Anything the grammar adds under these names is picked up automatically.\n */\nconst VALUE_DOMAINS = [\n\t'BorderStyleValue',\n\t'DynamicViewDisplayVariantValue',\n\t'EdgeRoutingValue',\n\t'ElementShape',\n\t'IconPositionValue',\n\t'LineOptions',\n\t'ArrowType',\n\t'RankValue',\n\t'SizeValue',\n\t'SizingValue',\n\t'ThemeColor',\n\t'ViewLayoutDirection',\n];\n\n/** Control-flow keywords read as keywords, not as a value domain. */\nconst KEYWORD_DOMAINS = ['DynamicViewFlowKeyword'];\n\n/** `source` / `target` are the only value-like variables. */\nconst VARIABLE_DOMAINS = ['Participant'];\n\n/** Operators whose scope is a word, kept curated: they are not all literals. */\nconst OPERATOR_WORDS = ['and', 'or', 'not', 'is'];\n\n/** Used when the grammar cannot be read — never expected, never silent. */\nconst FALLBACK_ICON_PACKS = ['aws', 'azure', 'bootstrap', 'gcp', 'tech'];\n\n/** One TextMate pattern. `match`/`begin`/`end` are regex *source*, not `RegExp`. */\nexport interface TmPattern {\n\tname?: string;\n\tcomment?: string;\n\tinclude?: string;\n\tmatch?: string;\n\tbegin?: string;\n\tend?: string;\n\tcontentName?: string;\n\tcaptures?: Record<string, { name: string }>;\n\tbeginCaptures?: Record<string, { name: string }>;\n\tendCaptures?: Record<string, { name: string }>;\n\tpatterns?: TmPattern[];\n}\n\n/** A TextMate grammar: JSON all the way down, never a `RegExp`. */\nexport interface TmGrammar {\n\t$schema: string;\n\tname: string;\n\tdisplayName: string;\n\tscopeName: string;\n\tfileTypes: string[];\n\tpatterns: TmPattern[];\n\t// Each repository entry is a pattern group; the tests index into them.\n\trepository: Record<string, any>;\n\t$generated?: { repo: string; ref: string; sha?: string; by: string };\n}\n\n/** Where the grammar came from, written into the snapshot's `$generated`. */\nexport interface TmProvenance {\n\trepo?: string;\n\tref?: string;\n\tsha?: string;\n}\n\n/** Turns a vocabulary into a TextMate grammar, JSON-serialisable. */\nexport function buildTmLanguage(vocabulary: Vocabulary, meta: TmProvenance = {}): TmGrammar {\n\tconst control = uniqueDomain(vocabulary, KEYWORD_DOMAINS);\n\tconst variables = uniqueDomain(vocabulary, VARIABLE_DOMAINS);\n\tconst icons = vocabulary.icons.length > 0 ? vocabulary.icons : FALLBACK_ICON_PACKS;\n\n\t// Words that are always syntax, never the name of a kind: `deployed =\n\t// instanceOf a` must not paint `instanceOf` as a type.\n\tconst reserved = alternationOf([...vocabulary.keywords, ...vocabulary.blocks, ...control]);\n\n\tconst grammar: TmGrammar = {\n\t\t$schema: TMLANGUAGE_SCHEMA,\n\t\t...(meta.repo && meta.ref\n\t\t\t? {\n\t\t\t\t\t$generated: {\n\t\t\t\t\t\trepo: meta.repo,\n\t\t\t\t\t\tref: meta.ref,\n\t\t\t\t\t\t...(meta.sha ? { sha: meta.sha } : {}),\n\t\t\t\t\t\tby: 'astroc4/scripts/sync-grammar.ts',\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t: {}),\n\t\tname: LANGUAGE_NAME,\n\t\tdisplayName: 'LikeC4',\n\t\tscopeName: SCOPE_NAME,\n\t\tfileTypes: ['c4', 'likec4'],\n\t\tpatterns: [{ include: '#everything' }],\n\t\trepository: {\n\t\t\teverything: {\n\t\t\t\tpatterns: [\n\t\t\t\t\t'comments',\n\t\t\t\t\t'strings',\n\t\t\t\t\t'urls',\n\t\t\t\t\t'icons',\n\t\t\t\t\t'hex-colors',\n\t\t\t\t\t'tags',\n\t\t\t\t\t'typed-arrow',\n\t\t\t\t\t'declarations',\n\t\t\t\t\t'keywords',\n\t\t\t\t\t'numbers',\n\t\t\t\t\t'operators',\n\t\t\t\t\t'punctuation',\n\t\t\t\t].map((name) => ({ include: `#${name}` })),\n\t\t\t},\n\t\t\tcomments: comments(),\n\t\t\tstrings: strings(),\n\t\t\turls: urls(),\n\t\t\ticons: iconIds(icons),\n\t\t\t'hex-colors': hexColours(),\n\t\t\ttags: tags(),\n\t\t\t'typed-arrow': typedArrow(),\n\t\t\tdeclarations: declarations(reserved),\n\t\t\tkeywords: keywords({ ...vocabulary, control, variables }),\n\t\t\tnumbers: numbers(),\n\t\t\toperators: operators(vocabulary.arrows),\n\t\t\tpunctuation: punctuation(),\n\t\t},\n\t};\n\n\tif (meta.repo && meta.ref) {\n\t\tgrammar.$generated = {\n\t\t\trepo: meta.repo,\n\t\t\tref: meta.ref,\n\t\t\t...(meta.sha ? { sha: meta.sha } : {}),\n\t\t\tby: 'astroc4/scripts/sync-grammar.ts',\n\t\t};\n\t}\n\n\treturn grammar;\n}\n// region structural patterns\n\nfunction comments() {\n\treturn {\n\t\tpatterns: [\n\t\t\t{\n\t\t\t\tname: 'comment.block.likec4',\n\t\t\t\tbegin: '/\\\\*',\n\t\t\t\tend: '\\\\*/',\n\t\t\t\tcaptures: { 0: { name: 'punctuation.definition.comment.likec4' } },\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: 'comment.line.double-slash.likec4',\n\t\t\t\tmatch: '//.*$',\n\t\t\t\tcaptures: { 0: { name: 'punctuation.definition.comment.likec4' } },\n\t\t\t},\n\t\t],\n\t};\n}\n\n/**\n * `'…'`, `\"…\"`, and the markdown strings `''' … '''` / `\"\"\" … \"\"\"` that\n * LikeC4 uses for descriptions.\n */\nfunction strings() {\n\tconst triple = (quote: string): TmPattern => ({\n\t\tname: 'string.quoted.triple.likec4',\n\t\tbegin: quote.repeat(3),\n\t\tend: quote.repeat(3),\n\t\tbeginCaptures: { 0: { name: 'punctuation.definition.string.begin.likec4' } },\n\t\tendCaptures: { 0: { name: 'punctuation.definition.string.end.likec4' } },\n\t});\n\n\tconst single = (quote: string, name: string): TmPattern => ({\n\t\tname,\n\t\tbegin: quote,\n\t\tend: `${quote}|$`,\n\t\tbeginCaptures: { 0: { name: 'punctuation.definition.string.begin.likec4' } },\n\t\tendCaptures: { 0: { name: 'punctuation.definition.string.end.likec4' } },\n\t\tpatterns: [{ name: 'constant.character.escape.likec4', match: '\\\\\\\\.' }],\n\t});\n\n\treturn {\n\t\tpatterns: [\n\t\t\ttriple(\"'\"),\n\t\t\ttriple('\"'),\n\t\t\tsingle(\"'\", 'string.quoted.single.likec4'),\n\t\t\tsingle('\"', 'string.quoted.double.likec4'),\n\t\t],\n\t};\n}\n\nfunction urls() {\n\treturn { name: 'markup.underline.link.likec4', match: \"\\\\bhttps?://[^\\\\s'\\\"]+\" };\n}\n\n/**\n * Icon ids (`tech:astro`, `aws:lambda`). The packs come from the `LIB_ICON`\n * terminal, so a pack added upstream highlights without touching this package.\n */\nfunction iconIds(packs: string[]): TmPattern {\n\treturn {\n\t\tcomment: 'Bundled icon ids: `tech:nginx`, `aws:…`, `gcp:…`, …',\n\t\tmatch: `\\\\b(${alternationOf(packs)})(:)([\\\\w-]+)`,\n\t\tcaptures: {\n\t\t\t1: { name: 'support.constant.icon-pack.likec4' },\n\t\t\t2: { name: 'punctuation.separator.likec4' },\n\t\t\t3: { name: 'support.constant.icon.likec4' },\n\t\t},\n\t};\n}\n\n/** `#0046BE` is a colour, `#compute` is a tag — hex first, so it wins. */\nfunction hexColours() {\n\treturn {\n\t\tname: 'constant.other.color.rgb-value.hex.likec4',\n\t\tmatch: '#(?:[0-9A-Fa-f]{8}|[0-9A-Fa-f]{6}|[0-9A-Fa-f]{3})(?![\\\\w-])',\n\t};\n}\n\nfunction tags() {\n\treturn { name: 'entity.name.tag.likec4', match: '#[A-Za-z_][\\\\w-]*' };\n}\n\n/** `a -[https]-> b` — the relationship kind inside the connector. */\nfunction typedArrow() {\n\treturn {\n\t\tcomment: '`a -[https]-> b`',\n\t\tmatch: '(-\\\\[)\\\\s*([A-Za-z_][\\\\w-]*)\\\\s*(\\\\]->)',\n\t\tcaptures: {\n\t\t\t1: { name: 'keyword.operator.arrow.likec4' },\n\t\t\t2: { name: 'entity.name.type.relationship.likec4' },\n\t\t\t3: { name: 'keyword.operator.arrow.likec4' },\n\t\t},\n\t};\n}\n\n/**\n * Declarations: the name being introduced is scoped, the name only being\n * referred to is not. Runs before the keyword patterns so `element system`\n * reads as a declaration rather than as two keywords.\n *\n * `reserved` is the alternation of syntax words (`instanceOf`, `extend`, …), so\n * `deployed = instanceOf a` scopes `instanceOf` as a keyword rather than as the\n * element kind the name is being assigned.\n */\nfunction declarations(reserved: string): TmPattern {\n\tconst notReserved = reserved ? `(?!(?:${reserved})\\\\b)` : '';\n\n\treturn {\n\t\tpatterns: [\n\t\t\t{\n\t\t\t\tcomment:\n\t\t\t\t\t'`element system`, `deploymentNode region`, `tag tls`, `relationship https`. Not `where tag is #x`.',\n\t\t\t\tmatch: '\\\\b(element|deploymentNode|tag|relationship)\\\\s+(?!is\\\\b)([A-Za-z_][\\\\w-]*)(?=\\\\s*(?:\\\\{|$|//))',\n\t\t\t\tcaptures: {\n\t\t\t\t\t1: { name: 'storage.type.likec4' },\n\t\t\t\t\t2: { name: 'entity.name.type.likec4' },\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tcomment:\n\t\t\t\t\t'`color testingBlue #0046BE` declares; `color testingBlue` inside a style block only refers.',\n\t\t\t\tmatch: '\\\\b(color)\\\\s+([A-Za-z_][\\\\w-]*)(?=\\\\s+#)',\n\t\t\t\tcaptures: {\n\t\t\t\t\t1: { name: 'storage.type.likec4' },\n\t\t\t\t\t2: { name: 'entity.name.type.likec4' },\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tcomment: '`view index`, `dynamic view firstRequest`, `deployment view prod`, `view internals of site`',\n\t\t\t\tmatch: '\\\\b(?:(dynamic|deployment)\\\\s+)?(view)\\\\s+([A-Za-z_]\\\\w*)',\n\t\t\t\tcaptures: {\n\t\t\t\t\t1: { name: 'storage.modifier.likec4' },\n\t\t\t\t\t2: { name: 'storage.type.view.likec4' },\n\t\t\t\t\t3: { name: 'entity.name.function.view.likec4' },\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tcomment: \"`reader = actor 'Engineer'`\",\n\t\t\t\tmatch: `\\\\b([A-Za-z_]\\\\w*)\\\\s*(=)(?!=)\\\\s*${notReserved}([A-Za-z_]\\\\w*)?`,\n\t\t\t\tcaptures: {\n\t\t\t\t\t1: { name: 'variable.other.definition.likec4' },\n\t\t\t\t\t2: { name: 'keyword.operator.assignment.likec4' },\n\t\t\t\t\t3: { name: 'entity.name.type.likec4' },\n\t\t\t\t},\n\t\t\t},\n\t\t],\n\t};\n}\n\n// endregion\n\n// region generated keyword patterns\n\n/**\n * Order matters here: blocks before plain keywords (so `model {` is a block),\n * operator words before keywords (`is`, `not`), variables before value domains\n * (so `source`/`target` stay variables even though `RankValue` reuses `source`).\n *\n */\nfunction keywords(vocabulary: Vocabulary & { control: string[]; variables: string[] }): TmPattern {\n\tconst patterns: TmPattern[] = [];\n\n\tconst blocks = alternationOf(vocabulary.blocks);\n\tif (blocks) {\n\t\tpatterns.push({\n\t\t\tcomment: 'Keywords that open a block: `model { … }`.',\n\t\t\tname: 'keyword.control.block.likec4',\n\t\t\tmatch: `\\\\b(?:${blocks})\\\\b(?=\\\\s*\\\\{)`,\n\t\t});\n\t}\n\n\t// Blocks repeat in the keyword list on purpose: `predicateGroup mine { … }`\n\t// is not followed by `{`, and still has to colour as a keyword. The block\n\t// pattern above wins wherever the brace is there.\n\tconst control = alternationOf([...vocabulary.keywords, ...vocabulary.control, ...vocabulary.blocks]);\n\n\t// Word operators (`is`, `not`) come before the keyword list, which also\n\t// contains them: `where tag is #x` reads as an operator, not a keyword.\n\tpatterns.push({\n\t\tname: 'keyword.operator.word.likec4',\n\t\tmatch: `\\\\b(?:${alternationOf(OPERATOR_WORDS)})\\\\b`,\n\t});\n\n\tif (control) {\n\t\tpatterns.push({ name: 'keyword.control.likec4', match: `\\\\b(?:${control})\\\\b` });\n\t}\n\n\tconst variables = alternationOf(vocabulary.variables);\n\tif (variables) {\n\t\tpatterns.push({ name: 'variable.language.likec4', match: `\\\\b(?:${variables})\\\\b` });\n\t}\n\n\tconst properties = alternationOf(vocabulary.properties);\n\tif (properties) {\n\t\tpatterns.push({ name: 'support.type.property-name.likec4', match: `\\\\b(?:${properties})\\\\b` });\n\t}\n\n\tconst values = alternationOf(uniqueDomain(vocabulary, VALUE_DOMAINS));\n\tif (values) {\n\t\tpatterns.push({ name: 'constant.language.likec4', match: `\\\\b(?:${values})\\\\b` });\n\t}\n\n\treturn { patterns };\n}\n\nfunction numbers() {\n\treturn { name: 'constant.numeric.likec4', match: '\\\\b\\\\d+(?:\\\\.\\\\d+)?%?' };\n}\n\n/**\n * Relationship connectors, longest first so `]->` wins over `->`.\n */\nfunction operators(arrows: string[]): TmPattern {\n\tconst patterns: TmPattern[] = [];\n\n\tconst connectors = alternationOf(arrows);\n\tif (connectors) {\n\t\tpatterns.push({ name: 'keyword.operator.arrow.likec4', match: connectors });\n\t}\n\n\tpatterns.push({ name: 'keyword.operator.wildcard.likec4', match: '\\\\.\\\\*\\\\*|\\\\.\\\\*|\\\\*\\\\*|\\\\*' });\n\n\treturn { patterns };\n}\n\nfunction punctuation() {\n\treturn {\n\t\tpatterns: [\n\t\t\t{ name: 'punctuation.section.block.begin.likec4', match: '\\\\{' },\n\t\t\t{ name: 'punctuation.section.block.end.likec4', match: '\\\\}' },\n\t\t\t{ name: 'punctuation.separator.comma.likec4', match: ',' },\n\t\t\t{ name: 'punctuation.accessor.likec4', match: '\\\\.' },\n\t\t],\n\t};\n}\n\n// endregion\n\n// region helpers\n\n/**\n * Every value of the named domains, deduplicated and sorted. Missing domains\n * are skipped rather than failing: upstream is free to rename a rule, and a\n * renamed domain still reaches the grammar through `keywords`.\n */\nfunction uniqueDomain(vocabulary: Vocabulary, names: string[]): string[] {\n\tconst values = names.flatMap((name) => vocabulary.enums[name] ?? []);\n\n\treturn [...new Set(values)].sort((a, b) => a.localeCompare(b));\n}\n\n/**\n * `['a', 'b']` -> `a|b`, escaped for a TextMate regex. Returns '' for an empty\n * list so callers can skip the pattern instead of emitting `\\b(?:)\\b`.\n */\nfunction alternationOf(values: string[]): string {\n\treturn values.map(escapeRegExp).join('|');\n}\n\nfunction escapeRegExp(value: string): string {\n\treturn value.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\n// endregion\n\nexport default buildTmLanguage;\n\n",
|
|
10
|
-
"//
|
|
5
|
+
"// The Starlight plugin: the integration in ./integration.ts plus what only\n// Starlight has — the UI strings (`i18n:setup`) and the `expressiveCode`\n// option. Starlight runs plugin `config:setup` hooks before it builds its\n// Expressive Code integration, which is what lets the grammar reach Shiki\n// without an `ec.config.mjs`.\n\nimport { fileURLToPath } from 'node:url';\n\nimport type { StarlightPlugin, StarlightUserConfig } from '@astrojs/starlight/types';\nimport type { AstroIntegration, AstroIntegrationLogger } from 'astro';\n\nimport { likec4Integration, missingOptimizedDependencies, PACKAGE_NAME } from './integration.ts';\nimport type { LikeC4IntegrationOptions } from './integration.ts';\nimport { resolveLikeC4Grammar } from './grammar/source.ts';\nimport { LANGUAGE_ALIASES, LANGUAGE_NAME } from './grammar/textmate.ts';\nimport { translations } from './translations.ts';\n\nexport { missingOptimizedDependencies };\n\nexport interface LikeC4HighlightingOptions {\n\t/** Branch, tag or commit SHA of `likec4/likec4`. Defaults to `main`; also `ASTROC4_REF`. */\n\tref?: string;\n\t/** Defaults to `likec4/likec4`. */\n\trepo?: string;\n\t/** Use the bundled snapshot and never touch the network. Also `ASTROC4_OFFLINE=1`. */\n\toffline?: boolean;\n\t/** When the grammar cannot be fetched. Defaults to `fail`; a `ref` that does not exist always fails. */\n\tonError?: 'fail' | 'warn' | 'silent';\n\t/** Seconds a cached fetch stays fresh. Defaults to 3600. */\n\tcacheTtl?: number;\n\t/** Ignore the cache and refetch. */\n\trefresh?: boolean;\n\t/** Defaults to `node_modules/.cache/astroc4`. */\n\tcacheDir?: string;\n\t/** Raw host to read from. Defaults to `https://raw.githubusercontent.com`. */\n\tbaseUrl?: string;\n\t/** Request timeout in milliseconds. Defaults to 15000. */\n\ttimeout?: number;\n}\n\nexport interface StarlightLikeC4Options extends LikeC4IntegrationOptions {\n\t/** Highlight ```c4 / ```likec4 source. Defaults to `true`; `false` leaves Expressive Code to the site. */\n\thighlighting?: boolean | LikeC4HighlightingOptions;\n}\n\ntype ConfigSetupArguments = Parameters<NonNullable<AstroIntegration['hooks']['astro:config:setup']>>[0];\n\n/**\n * A Starlight plugin and an Astro integration in one object. The hook sets are\n * disjoint, so `astro add`'s `integrations: [astroc4()]` works too.\n */\nexport type LikeC4StarlightPlugin = StarlightPlugin & Pick<AstroIntegration, 'hooks'>;\n\nexport default function starlightLikeC4(options: StarlightLikeC4Options = {}): LikeC4StarlightPlugin {\n\tconst integration = likec4Integration({\n\t\tvitePlugin: options.vitePlugin,\n\t\tprojects: options.projects,\n\t\tfences: options.fences,\n\t});\n\n\treturn {\n\t\tname: PACKAGE_NAME,\n\t\thooks: {\n\t\t\t...integration.hooks,\n\t\t\t'astro:config:setup': async (arguments_: ConfigSetupArguments) => {\n\t\t\t\twarnIfMiswired(arguments_);\n\n\t\t\t\tawait integration.hooks['astro:config:setup']?.(arguments_);\n\t\t\t},\n\t\t\t'i18n:setup'({ injectTranslations }) {\n\t\t\t\tinjectTranslations(translations);\n\t\t\t},\n\t\t\tasync 'config:setup'({ config, astroConfig, updateConfig, addIntegration, logger }) {\n\t\t\t\taddIntegration(integration);\n\n\t\t\t\tif (options.highlighting === false) return;\n\n\t\t\t\tawait injectHighlighting({\n\t\t\t\t\t// `config` is Starlight's; the site root is on the Astro config.\n\t\t\t\t\troot: fileURLToPath(astroConfig.root),\n\t\t\t\t\texpressiveCode: config.expressiveCode,\n\t\t\t\t\tupdateConfig,\n\t\t\t\t\tlogger,\n\t\t\t\t\toptions: typeof options.highlighting === 'object' ? options.highlighting : {},\n\t\t\t\t});\n\t\t\t},\n\t\t},\n\t} as LikeC4StarlightPlugin;\n}\n\n/**\n * `astro:config:setup` only runs when the plugin is in `integrations` — which on\n * a Starlight site means the translations and highlighting cannot run.\n */\nfunction warnIfMiswired({ config, logger }: ConfigSetupArguments): void {\n\tconst starlight = config.integrations.some((integration) => integration.name === '@astrojs/starlight');\n\n\tif (!starlight) return;\n\n\tlogger.warn(\n\t\t`${PACKAGE_NAME} is in \\`integrations\\`, so this Starlight site gets diagrams only. ` +\n\t\t\t'Move astroc4() into `starlight({ plugins: [astroc4()] })` to get the translated UI and LikeC4 syntax highlighting.',\n\t);\n}\n\ntype StarlightConfigUpdate = Partial<Omit<StarlightUserConfig, 'routeMiddleware'>>;\n\ninterface HighlightingContext {\n\troot: string;\n\texpressiveCode: unknown;\n\tupdateConfig: (config: StarlightConfigUpdate) => void;\n\tlogger: AstroIntegrationLogger;\n\toptions: LikeC4HighlightingOptions;\n}\n\n/**\n * Not wrapped in a try/catch on purpose: a bad ref or an unreadable grammar\n * fails `dev`, `build`, `check` and `sync` like any build error. `offline` and\n * `onError` are the opt-outs.\n */\nasync function injectHighlighting({\n\troot,\n\texpressiveCode,\n\tupdateConfig,\n\tlogger,\n\toptions,\n}: HighlightingContext) {\n\tif (expressiveCode === false) {\n\t\tlogger.warn(\n\t\t\t'LikeC4 syntax highlighting is skipped: `expressiveCode: false` disables the code blocks it ' +\n\t\t\t\t'would highlight. Diagrams are unaffected.',\n\t\t);\n\t\treturn;\n\t}\n\n\tconst source = await resolveLikeC4Grammar({ root, ...options, logger });\n\n\tconst registration = {\n\t\t...source.grammar,\n\t\tname: LANGUAGE_NAME,\n\t\taliases: [...LANGUAGE_ALIASES],\n\t};\n\n\tupdateConfig({\n\t\texpressiveCode: withLikeC4Language(expressiveCode, registration) as StarlightConfigUpdate['expressiveCode'],\n\t});\n\n\tconst { repo, ref, sha, source: from } = source.meta;\n\tlogger.info(\n\t\t`LikeC4 grammar ${repo}@${ref} (${sha})${from === 'network' ? '' : ` from ${from}`} — ` +\n\t\t\t'highlighting ```c4 and ```likec4 fences',\n\t);\n}\n\n/**\n * The site's Expressive Code options plus the LikeC4 language. Starlight's\n * `updateConfig` merges shallowly, so existing options are carried over; an\n * existing LikeC4 entry is replaced so the configured ref wins.\n */\nexport function withLikeC4Language(\n\texpressiveCode: unknown,\n\tregistration: Record<string, unknown>,\n): Record<string, unknown> & { shiki: { langs: unknown[] } } {\n\tconst current = isObject(expressiveCode) ? expressiveCode : {};\n\tconst shiki = isObject(current.shiki) ? current.shiki : {};\n\tconst langs: unknown[] = Array.isArray(shiki.langs) ? [...shiki.langs] : [];\n\tconst existing = langs.findIndex(isLikeC4Language);\n\n\tif (existing === -1) langs.push(registration);\n\telse langs[existing] = registration;\n\n\treturn { ...current, shiki: { ...shiki, langs } };\n}\n\nfunction isLikeC4Language(entry: unknown): boolean {\n\tif (typeof entry === 'string') return entry === LANGUAGE_NAME || LANGUAGE_ALIASES.includes(entry);\n\tif (!isObject(entry)) return false;\n\n\tif (entry.name === LANGUAGE_NAME || entry.scopeName === 'source.likec4') return true;\n\n\treturn Array.isArray(entry.aliases) && entry.aliases.some((alias) => LANGUAGE_ALIASES.includes(alias));\n}\n\nfunction isObject(value: unknown): value is Record<string, any> {\n\treturn typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n",
|
|
6
|
+
"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 */\nconst MD_FENCES_SCRIPT = [\n\t`const mountLikeC4Fences = () => {`,\n\t` if (!document.querySelector('[data-astroc4-fence]:not([data-astroc4-mounted])')) return;`,\n\t` import('${PACKAGE_NAME}/components/md-fences').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",
|
|
7
|
+
"// 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('&', '&')\n\t\t.replaceAll('\"', '"')\n\t\t.replaceAll(\"'\", ''')\n\t\t.replaceAll('<', '<')\n\t\t.replaceAll('>', '>');\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",
|
|
8
|
+
"// 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",
|
|
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",
|
|
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",
|
|
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",
|
|
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",
|
|
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",
|
|
14
|
+
"// Runs from `astro:config:setup`, so a bad ref fails dev, build, check and sync\n// rather than shipping unhighlighted code. A bad ref always fails; a network\n// failure falls back to the cache, then the bundled snapshot, only when\n// `onError` allows it.\n\nimport { createHash } from 'node:crypto';\nimport { mkdir, readFile, rename, writeFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nimport { parseLangium } from './langium.ts';\nimport { buildTmLanguage, type TmGrammar } from './textmate.ts';\n\nexport const DEFAULT_REPO = 'likec4/likec4';\nexport const DEFAULT_REF = 'main';\nexport const LANGIUM_PATH = 'packages/language-server/src/like-c4.langium';\nexport const DEFAULT_BASE_URL = 'https://raw.githubusercontent.com';\n\n/** Shape of a cache file. Bump when the fields change. */\nconst CACHE_VERSION = 1;\n\nconst BUNDLED_GRAMMAR = new URL('./likec4.tmLanguage.json', import.meta.url);\nconst BUNDLED_LANGIUM = new URL('./like-c4.langium', import.meta.url);\n\n/** The refs a repository actually has: branches, tags, `a1b2c3d`. */\nconst REF_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._/-]*$/;\n\nexport type OnError = 'fail' | 'warn' | 'silent';\n\nexport interface GrammarSourceOptions {\n\t/** Repository to read from. Defaults to likec4/likec4. */\n\trepo?: string;\n\t/** Branch, tag or commit SHA. Defaults to `main`. */\n\tref?: string;\n\t/** Use the bundled snapshot, never the network. */\n\toffline?: boolean;\n\t/** What to do when the grammar cannot be fetched. */\n\tonError?: OnError;\n\t/** Seconds a cached fetch stays fresh. */\n\tcacheTtl?: number;\n\t/** Ignore the cache and refetch. */\n\trefresh?: boolean;\n\t/** Raw file host, for mirrors and proxies. */\n\tbaseUrl?: string;\n\t/** Request timeout in milliseconds. */\n\ttimeout?: number;\n\t/** Site root, for the default cache directory. */\n\troot?: string;\n\tcacheDir?: string;\n\t/** Environment, for `ASTROC4_*` overrides. */\n\tenv?: NodeJS.ProcessEnv;\n\tlogger?: { info?: (message: string) => void; warn?: (message: string) => void };\n\t/** Injected in tests. */\n\tfetchImpl?: typeof fetch;\n\t/** Bundled Langium text, for tests. */\n\tbundledLangiumPath?: string;\n}\n\nexport interface GrammarMeta {\n\trepo: string;\n\tref: string;\n\tsource: 'network' | 'cache' | 'bundled';\n\tfetchedAt: number;\n\tetag?: string | undefined;\n\t/** Content hash of the Langium source. */\n\tsha: string;\n\t/** Why the bundled snapshot was used. */\n\treason?: string;\n}\n\nexport interface GrammarSource {\n\tgrammar: TmGrammar;\n\tlangium: string;\n\tmeta: GrammarMeta;\n}\n\ninterface GrammarIdentity {\n\trepo: string;\n\tref: string;\n}\n\n/** Raised for a ref this repository cannot have — always a user error. */\nexport class GrammarRefError extends Error {\n\toverride name = 'GrammarRefError';\n}\n\n/** Raised when the grammar could not be fetched, or came back unusable. */\nexport class GrammarFetchError extends Error {\n\toverride name = 'GrammarFetchError';\n}\n\nexport async function resolveLikeC4Grammar(options: GrammarSourceOptions = {}): Promise<GrammarSource> {\n\tconst env = options.env ?? process.env;\n\tconst repo = options.repo ?? DEFAULT_REPO;\n\tconst ref = env.ASTROC4_REF || options.ref || DEFAULT_REF;\n\tconst offline = options.offline ?? isTruthy(env.ASTROC4_OFFLINE);\n\tconst onError = options.onError ?? 'fail';\n\tconst logger = options.logger;\n\n\tvalidateRef(ref);\n\n\tif (offline) {\n\t\treturn bundled('offline: true', options);\n\t}\n\n\tconst cache = await readCache(options, { repo, ref });\n\n\tif (cache?.fresh && !options.refresh) {\n\t\treturn derive(cache.langium, { repo, ref, source: 'cache', fetchedAt: cache.fetchedAt, etag: cache.etag });\n\t}\n\n\tlet fetched;\n\n\ttry {\n\t\tfetched = await fetchLangiumSource({ ...options, repo, ref, etag: cache?.etag });\n\t} catch (error) {\n\t\tif (!(error instanceof Error)) throw error;\n\n\t\t// A bad ref will fail the same way forever: never paper over it.\n\t\tif (error instanceof GrammarRefError) throw error;\n\n\t\tif (onError === 'fail') throw error;\n\n\t\tif (onError === 'warn') logger?.warn?.(`[astroc4] ${error.message}`);\n\n\t\tif (cache) {\n\t\t\tif (onError === 'warn') {\n\t\t\t\tlogger?.warn?.(`[astroc4] using the grammar cached at ${new Date(cache.fetchedAt).toISOString()}`);\n\t\t\t}\n\n\t\t\treturn derive(cache.langium, {\n\t\t\t\trepo,\n\t\t\t\tref,\n\t\t\t\tsource: 'cache',\n\t\t\t\tfetchedAt: cache.fetchedAt,\n\t\t\t\tetag: cache.etag,\n\t\t\t});\n\t\t}\n\n\t\treturn bundled(error.message, options);\n\t}\n\n\tif ('notModified' in fetched) {\n\t\tif (!cache) {\n\t\t\tthrow new GrammarFetchError(\n\t\t\t\t'the grammar host answered 304 for a grammar that is not cached — retry with `refresh: true`',\n\t\t\t);\n\t\t}\n\n\t\tawait writeCache(options, { repo, ref }, cache);\n\n\t\treturn derive(cache.langium, { repo, ref, source: 'cache', fetchedAt: cache.fetchedAt, etag: cache.etag });\n\t}\n\n\tconst result = derive(fetched.text, { repo, ref, source: 'network', etag: fetched.etag });\n\tawait writeCache(options, { repo, ref }, { langium: fetched.text, etag: fetched.etag });\n\n\treturn result;\n}\n\ninterface DeriveInfo {\n\trepo: string;\n\tref: string;\n\tsource: 'network' | 'cache' | 'bundled';\n\tfetchedAt?: number;\n\tetag?: string | undefined;\n}\n\nfunction derive(langium: string, info: DeriveInfo): GrammarSource {\n\tlet vocabulary;\n\n\ttry {\n\t\tvocabulary = parseLangium(langium);\n\t} catch (cause) {\n\t\tthrow new GrammarFetchError(\n\t\t\t`${info.repo}@${info.ref}: the grammar could not be read — ${cause instanceof Error ? cause.message : String(cause)}`,\n\t\t\t{ cause },\n\t\t);\n\t}\n\n\tconst sha = grammarSha(langium);\n\n\treturn {\n\t\tgrammar: buildTmLanguage(vocabulary, { repo: info.repo, ref: info.ref, sha }),\n\t\tlangium,\n\t\tmeta: {\n\t\t\trepo: info.repo,\n\t\t\tref: info.ref,\n\t\t\tsource: info.source,\n\t\t\tfetchedAt: info.fetchedAt ?? Date.now(),\n\t\t\tetag: info.etag,\n\t\t\tsha,\n\t\t},\n\t};\n}\n\n/**\n * Derived from the committed `like-c4.langium`; its provenance is the\n * snapshot's own, not the ref that was asked for.\n * @param reason Why it is being used, surfaced in logs.\n */\nasync function bundled(reason: string, options: GrammarSourceOptions): Promise<GrammarSource> {\n\tconst path = options.bundledLangiumPath ?? fileURLToPath(BUNDLED_LANGIUM);\n\tconst snapshot = await bundledProvenance();\n\n\tconst source = derive(await readFile(path, 'utf8'), {\n\t\trepo: snapshot.repo ?? DEFAULT_REPO,\n\t\tref: snapshot.ref ?? DEFAULT_REF,\n\t\tsource: 'bundled',\n\t});\n\n\tsource.meta.reason = reason;\n\n\treturn source;\n}\n\n/** `$generated` from the shipped grammar, so logs name the real snapshot. */\nasync function bundledProvenance(): Promise<{ repo?: string; ref?: string }> {\n\ttry {\n\t\tconst { $generated } = JSON.parse(await readFile(fileURLToPath(BUNDLED_GRAMMAR), 'utf8'));\n\n\t\treturn { repo: $generated?.repo, ref: $generated?.ref };\n\t} catch {\n\t\treturn {};\n\t}\n}\n\n/** Short content hash — the identity that actually changes highlighting. */\nexport function grammarSha(source: string): string {\n\treturn createHash('sha256').update(source).digest('hex').slice(0, 12);\n}\n\n// region refs\n\nexport function validateRef(ref: string): string {\n\tif (typeof ref !== 'string' || ref.length === 0) {\n\t\tthrow new GrammarRefError('the LikeC4 grammar `ref` must be a branch, tag or commit SHA');\n\t}\n\n\tif (!REF_PATTERN.test(ref) || ref.includes('..') || ref.endsWith('/') || ref.includes('//')) {\n\t\tthrow new GrammarRefError(\n\t\t\t`\"${ref}\" is not a usable LikeC4 grammar ref — expected a branch, tag or commit SHA such as \"main\" or \"v1.59.4\"`,\n\t\t);\n\t}\n\n\treturn ref;\n}\n\n\n// endregion\n\n// region fetch\n\n/** What a fetch returns: the text, or the news that the ETag still matches. */\nexport type FetchResult = { text: string; etag?: string | undefined } | { notModified: true };\n\nexport async function fetchLangiumSource(\n\toptions: GrammarSourceOptions & { repo: string; ref: string; etag?: string | undefined },\n): Promise<FetchResult> {\n\tconst repo = options.repo;\n\tconst ref = options.ref;\n\tconst baseUrl = (options.baseUrl ?? DEFAULT_BASE_URL).replace(/\\/+$/, '');\n\tconst url = `${baseUrl}/${repo}/${ref}/${LANGIUM_PATH}`;\n\tconst timeout = options.timeout ?? 15_000;\n\tconst request = options.fetchImpl ?? fetch;\n\n\tconst headers: Record<string, string> = { 'user-agent': 'astroc4', accept: 'text/plain' };\n\tif (options.etag) headers['if-none-match'] = options.etag;\n\n\tlet response;\n\n\ttry {\n\t\tresponse = await request(url, { headers, redirect: 'follow', signal: AbortSignal.timeout(timeout) });\n\t} catch (cause) {\n\t\tthrow new GrammarFetchError(\n\t\t\t`could not fetch the LikeC4 grammar from ${url} — ${cause instanceof Error ? cause.message : String(cause)}. ` +\n\t\t\t\t'Builds are strict by default: pass `highlighting: { offline: true }` to use the bundled grammar instead.',\n\t\t\t{ cause },\n\t\t);\n\t}\n\n\tif (response.status === 304) return { notModified: true };\n\n\tif (response.status === 404) {\n\t\tthrow new GrammarRefError(\n\t\t\t`${repo} has no \"${ref}\", or it no longer has ${LANGIUM_PATH} (${url}). ` +\n\t\t\t\t'Use a tag such as \"v1.59.4\", a commit SHA, or \"main\".',\n\t\t);\n\t}\n\n\tif (!response.ok) {\n\t\tthrow new GrammarFetchError(\n\t\t\t`${url} responded ${response.status} ${response.statusText} — set ` +\n\t\t\t\t'`highlighting: { onError: \"warn\" }` to fall back to the bundled grammar.',\n\t\t);\n\t}\n\n\tconst text = await response.text();\n\n\tif (text.trim().length === 0) {\n\t\tthrow new GrammarFetchError(`${url} returned an empty file — the grammar is not usable`);\n\t}\n\n\treturn { text, etag: response.headers.get('etag') ?? undefined };\n}\n\n// endregion\n\n// region cache\n\n/**\n * Cache location: `node_modules/.cache/astroc4`, which every Astro project\n * already ignores. One file per repo@ref, so switching `ref` never thrashes.\n */\nfunction cachePath(options: GrammarSourceOptions, identity: GrammarIdentity): string {\n\tconst dir =\n\t\toptions.cacheDir ?? join(options.root ?? process.cwd(), 'node_modules', '.cache', 'astroc4');\n\tconst key = createHash('sha256').update(`${identity.repo}@${identity.ref}`).digest('hex').slice(0, 16);\n\n\treturn join(dir, `grammar-${key}.json`);\n}\n\ntype CacheWriteEntry = { langium: string; etag?: string | undefined };\ninterface CacheEntry extends CacheWriteEntry {\n\tfetchedAt: number;\n}\ninterface FreshCacheEntry extends CacheEntry {\n\tfresh: boolean;\n}\n\nasync function readCache(\n\toptions: GrammarSourceOptions,\n\tidentity: GrammarIdentity,\n): Promise<FreshCacheEntry | undefined> {\n\tlet raw;\n\n\ttry {\n\t\traw = await readFile(cachePath(options, identity), 'utf8');\n\t} catch {\n\t\treturn undefined;\n\t}\n\n\ttry {\n\t\tconst entry = JSON.parse(raw);\n\n\t\tif (\n\t\t\tentry?.version !== CACHE_VERSION ||\n\t\t\tentry.repo !== identity.repo ||\n\t\t\tentry.ref !== identity.ref ||\n\t\t\ttypeof entry.langium !== 'string' ||\n\t\t\ttypeof entry.fetchedAt !== 'number'\n\t\t) {\n\t\t\t// Another package version's cache, or a truncated file: refetch.\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst ttl = options.cacheTtl ?? 3600;\n\n\t\treturn { ...entry, fresh: Date.now() - entry.fetchedAt < ttl * 1000 };\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\n/**\n * Best effort: a read-only `node_modules` must not fail a build, it only means\n * the next one has to fetch again.\n */\nasync function writeCache(\n\toptions: GrammarSourceOptions,\n\tidentity: GrammarIdentity,\n\tentry: CacheWriteEntry,\n): Promise<void> {\n\tconst path = cachePath(options, identity);\n\tconst temporary = `${path}.${process.pid}.tmp`;\n\n\ttry {\n\t\tawait mkdir(join(path, '..'), { recursive: true });\n\t\tawait writeFile(\n\t\t\ttemporary,\n\t\t\tJSON.stringify({\n\t\t\t\tversion: CACHE_VERSION,\n\t\t\t\trepo: identity.repo,\n\t\t\t\tref: identity.ref,\n\t\t\t\tetag: entry.etag,\n\t\t\t\tfetchedAt: Date.now(),\n\t\t\t\tlangium: entry.langium,\n\t\t\t}),\n\t\t\t'utf8',\n\t\t);\n\t\t// Rename rather than write in place: two Astro processes can resolve the\n\t\t// same cache entry at once during `astro check && astro build`.\n\t\tawait rename(temporary, path);\n\t} catch (error) {\n\t\toptions.logger?.warn?.(\n\t\t\t`[astroc4] could not cache the LikeC4 grammar in ${path} — ${error instanceof Error ? error.message : String(error)}`,\n\t\t);\n\t}\n}\n\n// endregion\n\nfunction isTruthy(value: string | undefined): boolean {\n\treturn typeof value === 'string' && /^(1|true|yes|on)$/i.test(value.trim());\n}\n\nexport default resolveLikeC4Grammar;\n\n",
|
|
15
|
+
"// Reduces the LikeC4 Langium grammar to the vocabulary a TextMate grammar needs.\n// Deliberately no Langium dependency: a tolerant scanner that has to survive\n// upstream reformatting, so anything it cannot classify is dropped, not guessed.\n\n/** `…Id returns string` rules are identifiers, not closed value domains. */\nconst NOT_VALUE_DOMAINS = /Id$/;\n\n/** Property names the grammar matches as `key='…'` assignments. */\nconst PROPERTY_SUPPLEMENTS = ['kind', 'tag'];\n\nexport type TokenType = 'literal' | 'regex' | 'ident' | 'punct';\nexport interface Token {\n\ttype: TokenType;\n\tvalue: string;\n}\n\nexport interface Terminal {\n\thidden: boolean;\n\tkind: 'regex' | 'literal';\n\t/** Raw regex source (without slashes) or the literal. */\n\tvalue: string;\n}\n\nexport interface Rule {\n\tname: string;\n\tkind: 'rule' | 'fragment' | 'terminal';\n\thidden: boolean;\n\treturns?: string | undefined;\n\ttokens: Token[];\n}\n\nexport interface Vocabulary {\n\t/** Keywords that open a `{ … }` block. */\n\tblocks: string[];\n\t/** Every remaining word-like literal. */\n\tkeywords: string[];\n\t/** Property names from `key='…'` assignments. */\n\tproperties: string[];\n\t/** Relationship connectors containing `->`. */\n\tarrows: string[];\n\t/** `returns string` value domains, by rule name. */\n\tenums: Record<string, string[]>;\n\t/** Icon packs from the `LIB_ICON` terminal. */\n\ticons: string[];\n\t/** Literals from the `BOOLEAN` terminal. */\n\tbooleans: string[];\n\t/** Parser rules seen — used for sanity checks. */\n\truleCount: number;\n}\n\nexport function parseLangium(source: string): Vocabulary {\n\t// `grammar LikeC4` is a header, not a rule, and it has no `;`: leaving it in\n\t// would glue it to the first real rule and hide that rule from the scanner.\n\tconst statements = splitStatements(\n\t\tstripComments(source).replace(/^[ \\t]*grammar[ \\t]+[A-Za-z_]\\w*[ \\t]*$/gm, ''),\n\t);\n\tconst rules = statements.map(readStatement).filter((rule) => rule !== undefined);\n\n\tconst parserRules = rules.filter((rule) => rule.kind === 'rule' || rule.kind === 'fragment');\n\n\tif (parserRules.length === 0) {\n\t\tthrow new Error(\n\t\t\t'the file contains no Langium parser rules — is this still `packages/language-server/src/like-c4.langium`?',\n\t\t);\n\t}\n\n\tconst enums = resolveEnums(parserRules);\n\tconst blocks = findBlocks(parserRules);\n\tconst properties = unique([...findProperties(parserRules), ...PROPERTY_SUPPLEMENTS]);\n\tconst arrows = findArrows(parserRules);\n\tconst literals = unique(\n\t\tparserRules.flatMap((rule) => rule.tokens.filter((t) => t.type === 'literal').map((t) => t.value)),\n\t);\n\n\tconst classified = new Set([...blocks, ...properties, ...Object.values(enums).flat()]);\n\tconst keywords = literals.filter(\n\t\t(value) => /^[A-Za-z_]\\w*$/.test(value) && !classified.has(value),\n\t);\n\n\tconst terminals = readTerminals(rules);\n\n\t// A small grammar can legitimately have no leftover keywords, so blocks and\n\t// value domains count too.\n\tif (keywords.length === 0 && blocks.length === 0 && Object.keys(enums).length === 0) {\n\t\tthrow new Error('the file contains no LikeC4 keywords — the Langium grammar could not be read');\n\t}\n\n\treturn {\n\t\tblocks,\n\t\tkeywords,\n\t\tproperties,\n\t\tarrows,\n\t\tenums,\n\t\ticons: terminalAlternatives(terminals.LIB_ICON),\n\t\tbooleans: terminalAlternatives(terminals.BOOLEAN),\n\t\truleCount: parserRules.length,\n\t};\n}\n\n// region scanning\n\n/**\n * Blank out `//` and block comments. String and regex literals are copied\n * verbatim, because a `//` inside `/https?:\\/\\//` is not a comment.\n */\nfunction stripComments(source: string): string {\n\tlet out = '';\n\tlet i = 0;\n\n\twhile (i < source.length) {\n\t\tconst char = source[i];\n\n\t\tif (char === '/' && source[i + 1] === '/') {\n\t\t\twhile (i < source.length && source[i] !== '\\n') i++;\n\t\t\tout += ' ';\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (char === '/' && source[i + 1] === '*') {\n\t\t\ti += 2;\n\t\t\twhile (i < source.length && !(source[i] === '*' && source[i + 1] === '/')) i++;\n\t\t\ti += 2;\n\t\t\tout += ' ';\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (char === \"'\" || char === '\"') {\n\t\t\tconst end = endOfString(source, i);\n\t\t\tout += source.slice(i, end);\n\t\t\ti = end;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (char === '/') {\n\t\t\tconst end = endOfRegex(source, i);\n\t\t\tout += source.slice(i, end);\n\t\t\ti = end;\n\t\t\tcontinue;\n\t\t}\n\n\t\tout += char;\n\t\ti++;\n\t}\n\n\treturn out;\n}\n\n/** Index just past the quoted literal that opens at `start`. */\nfunction endOfString(source: string, start: number): number {\n\tconst quote = source[start];\n\tlet i = start + 1;\n\n\twhile (i < source.length) {\n\t\tif (source[i] === '\\\\') {\n\t\t\ti += 2;\n\t\t\tcontinue;\n\t\t}\n\t\tif (source[i] === quote) return i + 1;\n\t\ti++;\n\t}\n\n\treturn source.length;\n}\n\n/** Index just past the regex literal that opens at `start`. */\nfunction endOfRegex(source: string, start: number): number {\n\tlet i = start + 1;\n\tlet inClass = false;\n\n\twhile (i < source.length) {\n\t\tconst char = source[i];\n\n\t\tif (char === '\\\\') {\n\t\t\ti += 2;\n\t\t\tcontinue;\n\t\t}\n\t\tif (char === '[') inClass = true;\n\t\telse if (char === ']') inClass = false;\n\t\telse if (char === '/' && !inClass) return i + 1;\n\n\t\ti++;\n\t}\n\n\treturn source.length;\n}\n\n/**\n * Split on the `;` that ends each rule, ignoring the ones inside strings,\n * regexes and `{ … }` — interfaces have fields, and rules have `{infer X}`\n * actions, both of which can contain semicolons.\n */\nfunction splitStatements(source: string): string[] {\n\tconst statements: string[] = [];\n\tlet depth = 0;\n\tlet start = 0;\n\tlet i = 0;\n\n\twhile (i < source.length) {\n\t\tconst char = source[i];\n\n\t\tif (char === \"'\" || char === '\"') {\n\t\t\ti = endOfString(source, i);\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (char === '/') {\n\t\t\ti = endOfRegex(source, i);\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (char === '{') depth++;\n\t\telse if (char === '}') depth = Math.max(0, depth - 1);\n\t\telse if (char === ';' && depth === 0) {\n\t\t\tstatements.push(source.slice(start, i));\n\t\t\tstart = i + 1;\n\t\t}\n\n\t\ti++;\n\t}\n\n\tconst tail = source.slice(start).trim();\n\tif (tail.length > 0) statements.push(tail);\n\n\treturn statements.filter((statement) => statement.trim().length > 0);\n}\n\nconst HEADERS: { kind: 'rule' | 'fragment' | 'terminal'; hidden: boolean; pattern: RegExp }[] = [\n\t// `hidden terminal WS: /[ \\t]+/`\n\t{ kind: 'terminal', hidden: true, pattern: /^\\s*hidden\\s+terminal\\s+([A-Za-z_]\\w*)\\s*(?:<[^>]*>)?\\s*:/ },\n\t// `terminal LIB_ICON: /…/`, `terminal fragment HASH: '#'`\n\t{\n\t\tkind: 'terminal',\n\t\thidden: false,\n\t\tpattern:\n\t\t\t/^\\s*terminal\\s+(?:fragment\\s+)?([A-Za-z_]\\w*)\\s*(?:<[^>]*>)?\\s*(?:returns\\s+[A-Za-z_]\\w*\\s*)?:/,\n\t},\n\t// `fragment RelationConnector:`\n\t{ kind: 'fragment', hidden: false, pattern: /^\\s*fragment\\s+([A-Za-z_]\\w*)\\s*:/ },\n\t// `Model:`, `ModelViews:`, `entry LikeC4Grammar:`, `Relation<isExplicit>:`\n\t{\n\t\tkind: 'rule',\n\t\thidden: false,\n\t\tpattern: /^\\s*(?:entry\\s+)?([A-Za-z_]\\w*)\\s*(?:<[^>]*>)?\\s*(?:returns\\s+([A-Za-z_]\\w*)\\s*)?:/,\n\t},\n];\n\nfunction readStatement(statement: string): Rule | undefined {\n\tfor (const header of HEADERS) {\n\t\tconst match = header.pattern.exec(statement);\n\t\tconst name = match?.[1];\n\t\tif (!match || !name) continue;\n\n\t\treturn {\n\t\t\tname,\n\t\t\tkind: header.kind,\n\t\t\thidden: header.hidden,\n\t\t\treturns: header.kind === 'rule' ? match[2] : undefined,\n\t\t\ttokens: tokenize(statement.slice(match[0].length)),\n\t\t};\n\t}\n\n\treturn undefined;\n}\n\nfunction tokenize(body: string): Token[] {\n\tconst tokens: Token[] = [];\n\tlet i = 0;\n\n\twhile (i < body.length) {\n\t\tconst char = body.charAt(i);\n\n\t\tif (/\\s/.test(char)) {\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (char === \"'\" || char === '\"') {\n\t\t\tconst end = endOfString(body, i);\n\t\t\ttokens.push({ type: 'literal', value: unquote(body.slice(i, end)) });\n\t\t\ti = end;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (char === '/') {\n\t\t\tconst end = endOfRegex(body, i);\n\t\t\ttokens.push({ type: 'regex', value: body.slice(i + 1, end - 1) });\n\t\t\ti = end;\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst identifier = /^[A-Za-z_]\\w*/.exec(body.slice(i));\n\t\tif (identifier) {\n\t\t\ttokens.push({ type: 'ident', value: identifier[0] });\n\t\t\ti += identifier[0].length;\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Multi-character punctuation (`+=`, `?=`) is irrelevant: only `=`, `|`,\n\t\t// `(` and `)` are inspected, and per-character tokens give all four.\n\t\ttokens.push({ type: 'punct', value: char });\n\t\ti++;\n\t}\n\n\treturn tokens;\n}\n\n/** Strip the quotes and resolve the escapes Langium allows in literals. */\nfunction unquote(quoted: string): string {\n\tconst inner = quoted.slice(1, -1);\n\tlet out = '';\n\n\tfor (let i = 0; i < inner.length; i++) {\n\t\tif (inner[i] !== '\\\\') {\n\t\t\tout += inner[i];\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst escaped = inner[++i];\n\t\tif (escaped === 'n') out += '\\n';\n\t\telse if (escaped === 't') out += '\\t';\n\t\telse if (escaped === 'r') out += '\\r';\n\t\telse out += escaped ?? '';\n\t}\n\n\treturn out;\n}\n\n// endregion\n\n// region vocabulary\n\n/**\n * Rules of the shape `'specification' '{' …` or `name='model' '{' …` open a\n * block. The first literal of the rule is the keyword, and it only counts when\n * the rule reaches a `{` without branching first: `'element' kind=ElementKind\n * ('{' …)` has an optional body, so `element` stays a keyword.\n */\nfunction findBlocks(rules: Rule[]): string[] {\n\treturn unique(\n\t\trules.flatMap((rule) => {\n\t\t\tconst tokens = rule.tokens;\n\t\t\tconst first = tokens.findIndex((token) => token.type === 'literal');\n\t\t\tconst keyword = first === -1 ? undefined : tokens[first]?.value;\n\n\t\t\tif (!keyword || keyword === '{' || !/^[A-Za-z_]\\w*$/.test(keyword)) return [];\n\n\t\t\tfor (let i = first + 1; i < tokens.length; i++) {\n\t\t\t\tconst token = tokens[i];\n\t\t\t\tif (!token) break;\n\t\t\t\tif (token.value === '(' || token.value === '|') return [];\n\t\t\t\tif (token.type === 'literal' && token.value === '{') return [keyword];\n\t\t\t}\n\n\t\t\treturn [];\n\t\t}),\n\t);\n}\n\n/**\n * `key='title'` and `key=('head' | 'tail')` name a property. Positional\n * arguments (`props+=String`) and `name=` (block headers) are ignored.\n */\nfunction findProperties(rules: Rule[]): string[] {\n\tconst properties: string[] = [];\n\n\tfor (const rule of rules) {\n\t\tconst tokens = rule.tokens;\n\n\t\tfor (let i = 0; i < tokens.length; i++) {\n\t\t\tconst token = tokens[i];\n\t\t\tif (!token || token.type !== 'ident' || token.value !== 'key') continue;\n\n\t\t\tconst equals = equalsIndex(tokens, i);\n\t\t\tif (equals === -1) continue;\n\n\t\t\tlet j = equals + 1;\n\n\t\t\tif (tokens[j]?.value === '(') {\n\t\t\t\tfor (j++; j < tokens.length && tokens[j]?.value !== ')'; j++) {\n\t\t\t\t\tconst inner = tokens[j];\n\t\t\t\t\tif (inner?.type === 'literal') properties.push(inner.value);\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst value = tokens[j];\n\t\t\tif (value?.type === 'literal') properties.push(value.value);\n\t\t}\n\t}\n\n\treturn properties.filter((value) => /^[A-Za-z_]\\w*$/.test(value));\n}\n\n/**\n * Index of the `=` that assigns `tokens[i]` (`key=`, `key?=`, `key+=`), or `-1`\n * when the identifier is not being assigned.\n */\nfunction equalsIndex(tokens: Token[], i: number): number {\n\tif (tokens[i]?.type !== 'ident') return -1;\n\n\tconst next = tokens[i + 1]?.value;\n\tif (next === '=') return i + 1;\n\tif ((next === '?' || next === '+') && tokens[i + 2]?.value === '=') return i + 2;\n\n\treturn -1;\n}\n\n/**\n * The connectors live in one fragment:\n * dotKind=RelationKindDotRef | '-[' kind=[RelationshipKind] (… '->') | … | '->'\n */\nfunction findArrows(rules: Rule[]): string[] {\n\tconst connector = rules.find((rule) => rule.name === 'RelationConnector');\n\tconst fromConnector = (connector?.tokens ?? [])\n\t\t.filter((token) => token.type === 'literal' && token.value.includes('->'))\n\t\t.map((token) => token.value);\n\n\t// Longest first: TextMate alternation is first-match, so `]->` has to be\n\t// tried before `->` at the same position.\n\treturn unique([...fromConnector, '->', '<->']).sort((a, b) => b.length - a.length || a.localeCompare(b));\n}\n\n/**\n * A `returns string` rule whose body is only literals, `|` and references to\n * other such rules is a closed value domain — `BorderStyleValue: LineOptions |\n * 'none'` inherits from `LineOptions` that way. Anything referencing a rule\n * that is not itself a value domain (e.g. `Id returns string`) resolves to\n * nothing and is dropped.\n */\nfunction resolveEnums(rules: Rule[]): Record<string, string[]> {\n\tconst candidates = new Map<string, string[]>();\n\n\tfor (const rule of rules) {\n\t\tif (rule.returns !== 'string' || NOT_VALUE_DOMAINS.test(rule.name)) continue;\n\n\t\tconst onlyValuesAndChoices = rule.tokens.every(\n\t\t\t(token) =>\n\t\t\t\ttoken.type === 'literal' ||\n\t\t\t\ttoken.type === 'ident' ||\n\t\t\t\t(token.type === 'punct' && (token.value === '|' || token.value === ';')),\n\t\t);\n\n\t\tif (onlyValuesAndChoices) candidates.set(rule.name, []);\n\t}\n\n\t// Fixpoint, because `BorderStyleValue` can only resolve once `LineOptions`\n\t// has. One pass per rule is enough for any acyclic grammar.\n\tfor (let pass = 0; pass < rules.length; pass++) {\n\t\tlet changed = false;\n\n\t\tfor (const rule of rules) {\n\t\t\tif (!candidates.has(rule.name)) continue;\n\n\t\t\tconst resolved: string[] = [];\n\t\t\tlet complete = true;\n\n\t\t\tfor (const token of rule.tokens) {\n\t\t\t\tif (token.type === 'literal') {\n\t\t\t\t\tresolved.push(token.value);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tif (token.type !== 'ident') continue;\n\n\t\t\t\tconst inherited = candidates.get(token.value);\n\t\t\t\tif (inherited === undefined) {\n\t\t\t\t\tcomplete = false;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tresolved.push(...inherited);\n\t\t\t}\n\n\t\t\tconst next = unique(resolved);\n\t\t\tif (!complete || next.length === 0) continue;\n\n\t\t\tif ((candidates.get(rule.name) ?? []).length !== next.length) {\n\t\t\t\tcandidates.set(rule.name, next);\n\t\t\t\tchanged = true;\n\t\t\t}\n\t\t}\n\n\t\tif (!changed) break;\n\t}\n\n\tconst enums: Record<string, string[]> = {};\n\tfor (const [name, values] of [...candidates].sort(([a], [b]) => a.localeCompare(b))) {\n\t\tif (values.length > 0) enums[name] = values;\n\t}\n\n\treturn enums;\n}\n\nfunction readTerminals(rules: Rule[]): Record<string, Terminal> {\n\tconst terminals: Record<string, Terminal> = {};\n\n\tfor (const rule of rules) {\n\t\tif (rule.kind !== 'terminal') continue;\n\n\t\tconst token = rule.tokens.find((candidate) => candidate.type === 'regex' || candidate.type === 'literal');\n\t\tif (!token) continue;\n\n\t\tterminals[rule.name] = {\n\t\t\thidden: rule.hidden,\n\t\t\tkind: token.type === 'regex' ? 'regex' : 'literal',\n\t\t\tvalue: token.value,\n\t\t};\n\t}\n\n\treturn terminals;\n}\n\n/**\n * The alternatives of the first group in a terminal's regex:\n * `(aws|azure|bootstrap|gcp|md|tech):[-\\w]+` -> the icon packs.\n */\nfunction terminalAlternatives(terminal: Terminal | undefined): string[] {\n\tif (!terminal || terminal.kind !== 'regex') return [];\n\n\tconst group = /\\(([^()]*)\\)/.exec(terminal.value);\n\tif (!group) return [];\n\n\treturn unique((group[1] ?? '').split('|').map((value) => value.trim())).filter((value) =>\n\t\t/^[A-Za-z][\\w-]*$/.test(value),\n\t);\n}\n\nfunction unique(values: string[]): string[] {\n\treturn [...new Set(values)].sort((a, b) => a.localeCompare(b));\n}\n\n// endregion\n\nexport default parseLangium;\n\n",
|
|
16
|
+
"// Word lists are generated from the Langium vocabulary; the structural patterns\n// (strings, tags vs hex colours, icons, arrows, declarations) are curated,\n// because a Langium rule says a token exists, not how it looks.\n//\n// The result must stay plain JSON: Expressive Code JSON-round-trips integration\n// options and throws on functions or RegExp instances.\n\nimport type { Vocabulary } from './langium.ts';\n\n/** Scope name of the grammar, as upstream's VS Code extension uses it. */\nexport const SCOPE_NAME = 'source.likec4';\n\n/** Shiki language id, plus the short alias used by ` ```c4 ` fences. */\nexport const LANGUAGE_NAME = 'likec4';\nexport const LANGUAGE_ALIASES = ['c4'];\n\nconst TMLANGUAGE_SCHEMA =\n\t'https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json';\n\n/**\n * Closed value domains: they colour as values, not as keywords.\n * Anything the grammar adds under these names is picked up automatically.\n */\nconst VALUE_DOMAINS = [\n\t'BorderStyleValue',\n\t'DynamicViewDisplayVariantValue',\n\t'EdgeRoutingValue',\n\t'ElementShape',\n\t'IconPositionValue',\n\t'LineOptions',\n\t'ArrowType',\n\t'RankValue',\n\t'SizeValue',\n\t'SizingValue',\n\t'ThemeColor',\n\t'ViewLayoutDirection',\n];\n\n/** Control-flow keywords read as keywords, not as a value domain. */\nconst KEYWORD_DOMAINS = ['DynamicViewFlowKeyword'];\n\n/** `source` / `target` are the only value-like variables. */\nconst VARIABLE_DOMAINS = ['Participant'];\n\n/** Operators whose scope is a word, kept curated: they are not all literals. */\nconst OPERATOR_WORDS = ['and', 'or', 'not', 'is'];\n\n/** Used when the grammar has no `LIB_ICON` terminal. */\nconst FALLBACK_ICON_PACKS = ['aws', 'azure', 'bootstrap', 'gcp', 'tech'];\n\n/** One TextMate pattern. `match`/`begin`/`end` are regex *source*, not `RegExp`. */\nexport interface TmPattern {\n\tname?: string;\n\tcomment?: string;\n\tinclude?: string;\n\tmatch?: string;\n\tbegin?: string;\n\tend?: string;\n\tcontentName?: string;\n\tcaptures?: Record<string, { name: string }>;\n\tbeginCaptures?: Record<string, { name: string }>;\n\tendCaptures?: Record<string, { name: string }>;\n\tpatterns?: TmPattern[];\n}\n\nexport interface TmGrammar {\n\t$schema: string;\n\tname: string;\n\tdisplayName: string;\n\tscopeName: string;\n\tfileTypes: string[];\n\tpatterns: TmPattern[];\n\t// Each repository entry is a pattern group; the tests index into them.\n\trepository: Record<string, any>;\n\t$generated?: { repo: string; ref: string; sha?: string; by: string };\n}\n\n/** Where the grammar came from, written into the snapshot's `$generated`. */\nexport interface TmProvenance {\n\trepo?: string;\n\tref?: string;\n\tsha?: string;\n}\n\nexport function buildTmLanguage(vocabulary: Vocabulary, meta: TmProvenance = {}): TmGrammar {\n\tconst control = uniqueDomain(vocabulary, KEYWORD_DOMAINS);\n\tconst variables = uniqueDomain(vocabulary, VARIABLE_DOMAINS);\n\tconst icons = vocabulary.icons.length > 0 ? vocabulary.icons : FALLBACK_ICON_PACKS;\n\n\t// Words that are always syntax, never the name of a kind: `deployed =\n\t// instanceOf a` must not paint `instanceOf` as a type.\n\tconst reserved = alternationOf([...vocabulary.keywords, ...vocabulary.blocks, ...control]);\n\n\tconst grammar: TmGrammar = {\n\t\t$schema: TMLANGUAGE_SCHEMA,\n\t\t...(meta.repo && meta.ref\n\t\t\t? {\n\t\t\t\t\t$generated: {\n\t\t\t\t\t\trepo: meta.repo,\n\t\t\t\t\t\tref: meta.ref,\n\t\t\t\t\t\t...(meta.sha ? { sha: meta.sha } : {}),\n\t\t\t\t\t\tby: 'astroc4/scripts/sync-grammar.ts',\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t: {}),\n\t\tname: LANGUAGE_NAME,\n\t\tdisplayName: 'LikeC4',\n\t\tscopeName: SCOPE_NAME,\n\t\tfileTypes: ['c4', 'likec4'],\n\t\tpatterns: [{ include: '#everything' }],\n\t\trepository: {\n\t\t\teverything: {\n\t\t\t\tpatterns: [\n\t\t\t\t\t'comments',\n\t\t\t\t\t'strings',\n\t\t\t\t\t'urls',\n\t\t\t\t\t'icons',\n\t\t\t\t\t'hex-colors',\n\t\t\t\t\t'tags',\n\t\t\t\t\t'typed-arrow',\n\t\t\t\t\t'declarations',\n\t\t\t\t\t'keywords',\n\t\t\t\t\t'numbers',\n\t\t\t\t\t'operators',\n\t\t\t\t\t'punctuation',\n\t\t\t\t].map((name) => ({ include: `#${name}` })),\n\t\t\t},\n\t\t\tcomments: comments(),\n\t\t\tstrings: strings(),\n\t\t\turls: urls(),\n\t\t\ticons: iconIds(icons),\n\t\t\t'hex-colors': hexColours(),\n\t\t\ttags: tags(),\n\t\t\t'typed-arrow': typedArrow(),\n\t\t\tdeclarations: declarations(reserved),\n\t\t\tkeywords: keywords({ ...vocabulary, control, variables }),\n\t\t\tnumbers: numbers(),\n\t\t\toperators: operators(vocabulary.arrows),\n\t\t\tpunctuation: punctuation(),\n\t\t},\n\t};\n\n\tif (meta.repo && meta.ref) {\n\t\tgrammar.$generated = {\n\t\t\trepo: meta.repo,\n\t\t\tref: meta.ref,\n\t\t\t...(meta.sha ? { sha: meta.sha } : {}),\n\t\t\tby: 'astroc4/scripts/sync-grammar.ts',\n\t\t};\n\t}\n\n\treturn grammar;\n}\n// region structural patterns\n\nfunction comments() {\n\treturn {\n\t\tpatterns: [\n\t\t\t{\n\t\t\t\tname: 'comment.block.likec4',\n\t\t\t\tbegin: '/\\\\*',\n\t\t\t\tend: '\\\\*/',\n\t\t\t\tcaptures: { 0: { name: 'punctuation.definition.comment.likec4' } },\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: 'comment.line.double-slash.likec4',\n\t\t\t\tmatch: '//.*$',\n\t\t\t\tcaptures: { 0: { name: 'punctuation.definition.comment.likec4' } },\n\t\t\t},\n\t\t],\n\t};\n}\n\n/** Includes the triple-quoted markdown strings LikeC4 uses for descriptions. */\nfunction strings() {\n\tconst triple = (quote: string): TmPattern => ({\n\t\tname: 'string.quoted.triple.likec4',\n\t\tbegin: quote.repeat(3),\n\t\tend: quote.repeat(3),\n\t\tbeginCaptures: { 0: { name: 'punctuation.definition.string.begin.likec4' } },\n\t\tendCaptures: { 0: { name: 'punctuation.definition.string.end.likec4' } },\n\t});\n\n\tconst single = (quote: string, name: string): TmPattern => ({\n\t\tname,\n\t\tbegin: quote,\n\t\tend: `${quote}|$`,\n\t\tbeginCaptures: { 0: { name: 'punctuation.definition.string.begin.likec4' } },\n\t\tendCaptures: { 0: { name: 'punctuation.definition.string.end.likec4' } },\n\t\tpatterns: [{ name: 'constant.character.escape.likec4', match: '\\\\\\\\.' }],\n\t});\n\n\treturn {\n\t\tpatterns: [\n\t\t\ttriple(\"'\"),\n\t\t\ttriple('\"'),\n\t\t\tsingle(\"'\", 'string.quoted.single.likec4'),\n\t\t\tsingle('\"', 'string.quoted.double.likec4'),\n\t\t],\n\t};\n}\n\nfunction urls() {\n\treturn { name: 'markup.underline.link.likec4', match: \"\\\\bhttps?://[^\\\\s'\\\"]+\" };\n}\n\n/**\n * Icon ids (`tech:astro`, `aws:lambda`). The packs come from the `LIB_ICON`\n * terminal, so a pack added upstream highlights without touching this package.\n */\nfunction iconIds(packs: string[]): TmPattern {\n\treturn {\n\t\tcomment: 'Bundled icon ids: `tech:nginx`, `aws:…`, `gcp:…`, …',\n\t\tmatch: `\\\\b(${alternationOf(packs)})(:)([\\\\w-]+)`,\n\t\tcaptures: {\n\t\t\t1: { name: 'support.constant.icon-pack.likec4' },\n\t\t\t2: { name: 'punctuation.separator.likec4' },\n\t\t\t3: { name: 'support.constant.icon.likec4' },\n\t\t},\n\t};\n}\n\n/** `#0046BE` is a colour, `#compute` is a tag: hex is included first, so it wins. */\nfunction hexColours() {\n\treturn {\n\t\tname: 'constant.other.color.rgb-value.hex.likec4',\n\t\tmatch: '#(?:[0-9A-Fa-f]{8}|[0-9A-Fa-f]{6}|[0-9A-Fa-f]{3})(?![\\\\w-])',\n\t};\n}\n\nfunction tags() {\n\treturn { name: 'entity.name.tag.likec4', match: '#[A-Za-z_][\\\\w-]*' };\n}\n\nfunction typedArrow() {\n\treturn {\n\t\tcomment: '`a -[https]-> b`',\n\t\tmatch: '(-\\\\[)\\\\s*([A-Za-z_][\\\\w-]*)\\\\s*(\\\\]->)',\n\t\tcaptures: {\n\t\t\t1: { name: 'keyword.operator.arrow.likec4' },\n\t\t\t2: { name: 'entity.name.type.relationship.likec4' },\n\t\t\t3: { name: 'keyword.operator.arrow.likec4' },\n\t\t},\n\t};\n}\n\n/**\n * The name being introduced is scoped, a name only referred to is not. Runs\n * before the keyword patterns so `element system` reads as a declaration.\n */\nfunction declarations(reserved: string): TmPattern {\n\tconst notReserved = reserved ? `(?!(?:${reserved})\\\\b)` : '';\n\n\treturn {\n\t\tpatterns: [\n\t\t\t{\n\t\t\t\tcomment:\n\t\t\t\t\t'`element system`, `deploymentNode region`, `tag tls`, `relationship https`. Not `where tag is #x`.',\n\t\t\t\tmatch: '\\\\b(element|deploymentNode|tag|relationship)\\\\s+(?!is\\\\b)([A-Za-z_][\\\\w-]*)(?=\\\\s*(?:\\\\{|$|//))',\n\t\t\t\tcaptures: {\n\t\t\t\t\t1: { name: 'storage.type.likec4' },\n\t\t\t\t\t2: { name: 'entity.name.type.likec4' },\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tcomment:\n\t\t\t\t\t'`color testingBlue #0046BE` declares; `color testingBlue` inside a style block only refers.',\n\t\t\t\tmatch: '\\\\b(color)\\\\s+([A-Za-z_][\\\\w-]*)(?=\\\\s+#)',\n\t\t\t\tcaptures: {\n\t\t\t\t\t1: { name: 'storage.type.likec4' },\n\t\t\t\t\t2: { name: 'entity.name.type.likec4' },\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tcomment: '`view index`, `dynamic view firstRequest`, `deployment view prod`, `view internals of site`',\n\t\t\t\tmatch: '\\\\b(?:(dynamic|deployment)\\\\s+)?(view)\\\\s+([A-Za-z_]\\\\w*)',\n\t\t\t\tcaptures: {\n\t\t\t\t\t1: { name: 'storage.modifier.likec4' },\n\t\t\t\t\t2: { name: 'storage.type.view.likec4' },\n\t\t\t\t\t3: { name: 'entity.name.function.view.likec4' },\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tcomment: \"`reader = actor 'Engineer'`\",\n\t\t\t\tmatch: `\\\\b([A-Za-z_]\\\\w*)\\\\s*(=)(?!=)\\\\s*${notReserved}([A-Za-z_]\\\\w*)?`,\n\t\t\t\tcaptures: {\n\t\t\t\t\t1: { name: 'variable.other.definition.likec4' },\n\t\t\t\t\t2: { name: 'keyword.operator.assignment.likec4' },\n\t\t\t\t\t3: { name: 'entity.name.type.likec4' },\n\t\t\t\t},\n\t\t\t},\n\t\t],\n\t};\n}\n\n// endregion\n\n// region generated keyword patterns\n\n/**\n * Order matters here: blocks before plain keywords (so `model {` is a block),\n * operator words before keywords (`is`, `not`), variables before value domains\n * (so `source`/`target` stay variables even though `RankValue` reuses `source`).\n */\nfunction keywords(vocabulary: Vocabulary & { control: string[]; variables: string[] }): TmPattern {\n\tconst patterns: TmPattern[] = [];\n\n\tconst blocks = alternationOf(vocabulary.blocks);\n\tif (blocks) {\n\t\tpatterns.push({\n\t\t\tcomment: 'Keywords that open a block: `model { … }`.',\n\t\t\tname: 'keyword.control.block.likec4',\n\t\t\tmatch: `\\\\b(?:${blocks})\\\\b(?=\\\\s*\\\\{)`,\n\t\t});\n\t}\n\n\t// Blocks repeat in the keyword list on purpose: `predicateGroup mine { ... }`\n\t// is not followed by `{`, and still has to colour as a keyword. The block\n\t// pattern above wins wherever the brace is there.\n\tconst control = alternationOf([...vocabulary.keywords, ...vocabulary.control, ...vocabulary.blocks]);\n\n\t// Word operators (`is`, `not`) come before the keyword list, which also\n\t// contains them: `where tag is #x` reads as an operator, not a keyword.\n\tpatterns.push({\n\t\tname: 'keyword.operator.word.likec4',\n\t\tmatch: `\\\\b(?:${alternationOf(OPERATOR_WORDS)})\\\\b`,\n\t});\n\n\tif (control) {\n\t\tpatterns.push({ name: 'keyword.control.likec4', match: `\\\\b(?:${control})\\\\b` });\n\t}\n\n\tconst variables = alternationOf(vocabulary.variables);\n\tif (variables) {\n\t\tpatterns.push({ name: 'variable.language.likec4', match: `\\\\b(?:${variables})\\\\b` });\n\t}\n\n\tconst properties = alternationOf(vocabulary.properties);\n\tif (properties) {\n\t\tpatterns.push({ name: 'support.type.property-name.likec4', match: `\\\\b(?:${properties})\\\\b` });\n\t}\n\n\tconst values = alternationOf(uniqueDomain(vocabulary, VALUE_DOMAINS));\n\tif (values) {\n\t\tpatterns.push({ name: 'constant.language.likec4', match: `\\\\b(?:${values})\\\\b` });\n\t}\n\n\treturn { patterns };\n}\n\nfunction numbers() {\n\treturn { name: 'constant.numeric.likec4', match: '\\\\b\\\\d+(?:\\\\.\\\\d+)?%?' };\n}\n\n/** `arrows` must be longest first so `]->` wins over `->`. */\nfunction operators(arrows: string[]): TmPattern {\n\tconst patterns: TmPattern[] = [];\n\n\tconst connectors = alternationOf(arrows);\n\tif (connectors) {\n\t\tpatterns.push({ name: 'keyword.operator.arrow.likec4', match: connectors });\n\t}\n\n\tpatterns.push({ name: 'keyword.operator.wildcard.likec4', match: '\\\\.\\\\*\\\\*|\\\\.\\\\*|\\\\*\\\\*|\\\\*' });\n\n\treturn { patterns };\n}\n\nfunction punctuation() {\n\treturn {\n\t\tpatterns: [\n\t\t\t{ name: 'punctuation.section.block.begin.likec4', match: '\\\\{' },\n\t\t\t{ name: 'punctuation.section.block.end.likec4', match: '\\\\}' },\n\t\t\t{ name: 'punctuation.separator.comma.likec4', match: ',' },\n\t\t\t{ name: 'punctuation.accessor.likec4', match: '\\\\.' },\n\t\t],\n\t};\n}\n\n// endregion\n\n// region helpers\n\n/**\n * Every value of the named domains, deduplicated and sorted. Missing domains\n * are skipped rather than failing: upstream is free to rename a rule, and a\n * renamed domain still reaches the grammar through `keywords`.\n */\nfunction uniqueDomain(vocabulary: Vocabulary, names: string[]): string[] {\n\tconst values = names.flatMap((name) => vocabulary.enums[name] ?? []);\n\n\treturn [...new Set(values)].sort((a, b) => a.localeCompare(b));\n}\n\n/**\n * `['a', 'b']` -> `a|b`, escaped for a TextMate regex. Returns '' for an empty\n * list so callers can skip the pattern instead of emitting `\\b(?:)\\b`.\n */\nfunction alternationOf(values: string[]): string {\n\treturn values.map(escapeRegExp).join('|');\n}\n\nfunction escapeRegExp(value: string): string {\n\treturn value.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\n// endregion\n\nexport default buildTmLanguage;\n\n"
|
|
11
17
|
],
|
|
12
|
-
"mappings": "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",
|
|
13
|
-
"debugId": "
|
|
18
|
+
"mappings": "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",
|
|
19
|
+
"debugId": "E908D3218F3E812A64756E2164756E21",
|
|
14
20
|
"names": []
|
|
15
21
|
}
|