@kekonic/diagrams-cli 1.0.0-rc.4
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/LICENSE +21 -0
- package/README.md +142 -0
- package/dist/cli.d.mts +1 -0
- package/dist/cli.mjs +1273 -0
- package/dist/cli.mjs.map +1 -0
- package/dist/lsp-bin.d.mts +1 -0
- package/dist/lsp-bin.mjs +8 -0
- package/dist/lsp-bin.mjs.map +1 -0
- package/dist/lsp-server-uxE48S7X.mjs +325 -0
- package/dist/lsp-server-uxE48S7X.mjs.map +1 -0
- package/dist/lsp-server.d.mts +7 -0
- package/dist/lsp-server.mjs +2 -0
- package/package.json +62 -0
- package/schema/kekonic-diagrams.config.schema.json +43 -0
package/dist/cli.mjs.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.mjs","names":["COMMANDS","require","require"],"sources":["../src/command-model.ts","../src/completions.ts","../src/project-config.ts","../src/doctor.ts","../src/input-resolver.ts","../src/output.ts","../src/output-paths.ts","../src/portable-svg.ts","../src/studio-server.ts","../src/cli.ts"],"sourcesContent":["export type CommandName =\n | \"render\"\n | \"check\"\n | \"analyze\"\n | \"capabilities\"\n | \"ast\"\n | \"graph\"\n | \"format\"\n | \"studio\"\n | \"lsp\"\n | \"doctor\"\n | \"completions\";\n\nexport type ColorMode = \"auto\" | \"always\" | \"never\";\n\nexport type CommandOptions = {\n output?: string;\n outDir?: string;\n outputTemplate?: string;\n theme?: string;\n snapshot: boolean;\n liveTheme: boolean;\n config?: string;\n profile?: string;\n themeFile?: string;\n background?: \"transparent\" | \"theme\";\n embedFonts: boolean;\n printSafe: boolean;\n open: boolean;\n noOpen: boolean;\n allowWrite: boolean;\n stdio: boolean;\n port?: string;\n color: ColorMode;\n quiet: boolean;\n verbose: boolean;\n debug: boolean;\n json: boolean;\n pretty: boolean;\n write: boolean;\n check: boolean;\n excludes: string[];\n ignoreFile?: string;\n stdinFilename?: string;\n filesFrom?: string;\n};\n\nexport type ParsedCommand = {\n name: CommandName;\n inputs: string[];\n options: CommandOptions;\n};\n\nexport class CliUsageError extends Error {\n readonly exitCode = 2;\n}\n\nconst COMMANDS = new Set<CommandName>([\n \"render\",\n \"check\",\n \"analyze\",\n \"capabilities\",\n \"ast\",\n \"graph\",\n \"format\",\n \"studio\",\n \"lsp\",\n \"doctor\",\n \"completions\",\n]);\n\nconst VALUE_OPTIONS = new Map<\n string,\n | \"output\"\n | \"outDir\"\n | \"outputTemplate\"\n | \"theme\"\n | \"exclude\"\n | \"ignoreFile\"\n | \"stdinFilename\"\n | \"filesFrom\"\n | \"color\"\n | \"config\"\n | \"profile\"\n | \"themeFile\"\n | \"background\"\n | \"port\"\n>([\n [\"-o\", \"output\"],\n [\"--output\", \"output\"],\n [\"--out-dir\", \"outDir\"],\n [\"--output-template\", \"outputTemplate\"],\n [\"--theme\", \"theme\"],\n [\"--exclude\", \"exclude\"],\n [\"--ignore-file\", \"ignoreFile\"],\n [\"--stdin-filename\", \"stdinFilename\"],\n [\"--files-from\", \"filesFrom\"],\n [\"--color\", \"color\"],\n [\"--config\", \"config\"],\n [\"--profile\", \"profile\"],\n [\"--theme-file\", \"themeFile\"],\n [\"--background\", \"background\"],\n [\"--port\", \"port\"],\n] as const);\n\nconst BOOLEAN_OPTIONS = new Map<\n string,\n | \"snapshot\"\n | \"liveTheme\"\n | \"json\"\n | \"pretty\"\n | \"write\"\n | \"check\"\n | \"quiet\"\n | \"verbose\"\n | \"debug\"\n | \"embedFonts\"\n | \"printSafe\"\n | \"open\"\n | \"noOpen\"\n | \"allowWrite\"\n | \"stdio\"\n>([\n [\"--snapshot\", \"snapshot\"],\n [\"--live-theme\", \"liveTheme\"],\n [\"--json\", \"json\"],\n [\"--pretty\", \"pretty\"],\n [\"--write\", \"write\"],\n [\"--check\", \"check\"],\n [\"--quiet\", \"quiet\"],\n [\"--verbose\", \"verbose\"],\n [\"--debug\", \"debug\"],\n [\"--embed-fonts\", \"embedFonts\"],\n [\"--print-safe\", \"printSafe\"],\n [\"--open\", \"open\"],\n [\"--no-open\", \"noOpen\"],\n [\"--allow-write\", \"allowWrite\"],\n [\"--stdio\", \"stdio\"],\n] as const);\n\nconst DISCOVERY = [\"exclude\", \"ignoreFile\", \"stdinFilename\", \"filesFrom\"];\nconst PRESENTATION = [\"color\", \"quiet\", \"verbose\", \"debug\"];\n\nconst ALLOWED_OPTIONS: Record<CommandName, ReadonlySet<string>> = {\n render: new Set([\n \"output\",\n \"outDir\",\n \"outputTemplate\",\n \"theme\",\n \"snapshot\",\n \"liveTheme\",\n \"config\",\n \"profile\",\n \"themeFile\",\n \"background\",\n \"embedFonts\",\n \"printSafe\",\n ...DISCOVERY,\n ...PRESENTATION,\n ]),\n check: new Set([\"json\", ...DISCOVERY, ...PRESENTATION]),\n analyze: new Set([\"json\", \"pretty\", ...DISCOVERY, ...PRESENTATION]),\n capabilities: new Set([\"pretty\"]),\n ast: new Set([\"pretty\", \"json\", ...DISCOVERY, ...PRESENTATION]),\n graph: new Set([\"pretty\", \"json\", ...DISCOVERY, ...PRESENTATION]),\n format: new Set([\"output\", \"write\", \"check\", ...DISCOVERY, ...PRESENTATION]),\n studio: new Set([\"open\", \"noOpen\", \"allowWrite\", \"port\", ...DISCOVERY, ...PRESENTATION]),\n lsp: new Set([\"stdio\"]),\n doctor: new Set([\"json\", ...PRESENTATION]),\n completions: new Set([]),\n};\n\nfunction defaults(): CommandOptions {\n return {\n snapshot: false,\n liveTheme: false,\n color: \"auto\",\n quiet: false,\n verbose: false,\n debug: false,\n embedFonts: false,\n printSafe: false,\n open: false,\n noOpen: false,\n allowWrite: false,\n stdio: false,\n json: false,\n pretty: false,\n write: false,\n check: false,\n excludes: [],\n };\n}\n\nfunction optionParts(raw: string): { flag: string; inlineValue?: string } {\n if (!raw.startsWith(\"--\")) return { flag: raw };\n const equals = raw.indexOf(\"=\");\n return equals < 0\n ? { flag: raw }\n : { flag: raw.slice(0, equals), inlineValue: raw.slice(equals + 1) };\n}\n\nexport function parseCommand(argv: readonly string[]): ParsedCommand {\n const name = argv[0];\n if (!COMMANDS.has(name as CommandName)) {\n const suggestion = name ? nearest(name, [...COMMANDS]) : undefined;\n throw new CliUsageError(\n name\n ? `Unknown command: ${name}${suggestion ? `. Did you mean ${suggestion}?` : \"\"}`\n : \"Missing command\",\n );\n }\n\n const command = name as CommandName;\n const inputs: string[] = [];\n const options = defaults();\n let positionalOnly = false;\n\n for (let index = 1; index < argv.length; index++) {\n const raw = argv[index]!;\n if (raw === \"--\" && !positionalOnly) {\n positionalOnly = true;\n continue;\n }\n if (raw === \"-\" || positionalOnly || !raw.startsWith(\"-\")) {\n inputs.push(raw);\n continue;\n }\n\n const { flag, inlineValue } = optionParts(raw);\n const valueKey = VALUE_OPTIONS.get(flag);\n const booleanKey = BOOLEAN_OPTIONS.get(flag);\n const allowed = ALLOWED_OPTIONS[command];\n\n if (valueKey) {\n if (!allowed.has(valueKey)) throw new CliUsageError(`Unknown option for ${command}: ${flag}`);\n const value = inlineValue ?? argv[++index];\n if (!value || (inlineValue == null && value.startsWith(\"-\") && value !== \"-\")) {\n throw new CliUsageError(`Missing value for ${flag}`);\n }\n if (valueKey === \"exclude\") options.excludes.push(value);\n else if (valueKey === \"color\") {\n if (value !== \"auto\" && value !== \"always\" && value !== \"never\") {\n throw new CliUsageError(\n `Invalid --color value: ${value} (expected auto, always, or never)`,\n );\n }\n options.color = value;\n } else if (valueKey === \"background\") {\n if (value !== \"transparent\" && value !== \"theme\") {\n throw new CliUsageError(\n `Invalid --background value: ${value} (expected transparent or theme)`,\n );\n }\n options.background = value;\n } else if (valueKey === \"theme\") {\n options.theme = value;\n } else {\n options[valueKey] = value;\n }\n continue;\n }\n\n if (booleanKey) {\n if (inlineValue != null) throw new CliUsageError(`${flag} does not accept a value`);\n if (!allowed.has(booleanKey)) {\n throw new CliUsageError(`Unknown option for ${command}: ${flag}`);\n }\n options[booleanKey] = true;\n continue;\n }\n\n const candidates = [...VALUE_OPTIONS.keys(), ...BOOLEAN_OPTIONS.keys(), \"--help\", \"--version\"];\n const suggestion = nearest(flag, candidates);\n throw new CliUsageError(\n `Unknown option: ${flag}${suggestion ? `. Did you mean ${suggestion}?` : \"\"}`,\n );\n }\n\n validateOptions(command, options);\n return { name: command, inputs, options };\n}\n\nfunction nearest(value: string, candidates: readonly string[]): string | undefined {\n let best: { value: string; distance: number } | undefined;\n for (const candidate of candidates) {\n const distance = editDistance(value, candidate);\n if (!best || distance < best.distance) best = { value: candidate, distance };\n }\n return best && best.distance <= Math.max(2, Math.floor(value.length / 3))\n ? best.value\n : undefined;\n}\n\nfunction editDistance(left: string, right: string): number {\n const previous = Array.from({ length: right.length + 1 }, (_, index) => index);\n for (let i = 1; i <= left.length; i++) {\n const current = [i];\n for (let j = 1; j <= right.length; j++) {\n current[j] = Math.min(\n current[j - 1]! + 1,\n previous[j]! + 1,\n previous[j - 1]! + (left[i - 1] === right[j - 1] ? 0 : 1),\n );\n }\n previous.splice(0, previous.length, ...current);\n }\n return previous[right.length]!;\n}\n\nfunction validateOptions(command: CommandName, options: CommandOptions): void {\n if (command === \"render\") {\n const destinations = [options.output, options.outDir, options.outputTemplate].filter(Boolean);\n if (options.output && destinations.length > 1) {\n throw new CliUsageError(\"--output cannot be combined with --out-dir or --output-template\");\n }\n if (options.snapshot && options.liveTheme) {\n throw new CliUsageError(\"--snapshot and --live-theme cannot be combined\");\n }\n }\n if (command === \"format\") {\n if (options.write && options.check) {\n throw new CliUsageError(\"--write and --check cannot be combined\");\n }\n if (options.output && (options.write || options.check)) {\n throw new CliUsageError(\"--output cannot be combined with --write or --check\");\n }\n }\n if (command === \"studio\") {\n if (options.open && options.noOpen) {\n throw new CliUsageError(\"--open and --no-open cannot be combined\");\n }\n if (options.port != null && (!/^\\d+$/.test(options.port) || Number(options.port) > 65535)) {\n throw new CliUsageError(\"--port must be an integer from 0 to 65535\");\n }\n }\n if (command === \"lsp\" && !options.stdio) {\n throw new CliUsageError(\"lsp requires --stdio\");\n }\n if (options.quiet && options.verbose) {\n throw new CliUsageError(\"--quiet and --verbose cannot be combined\");\n }\n if (command === \"completions\" && options.excludes.length > 0) {\n throw new CliUsageError(\"completions does not accept discovery options\");\n }\n}\n","import { CliUsageError } from \"./command-model.ts\";\n\nconst COMMANDS = \"render check analyze capabilities format studio lsp ast graph doctor completions\";\nconst OPTIONS =\n \"--help --version --color --quiet --verbose --debug --exclude --ignore-file --stdin-filename --files-from --output --out-dir --output-template --theme --theme-file --config --profile --live-theme --snapshot --background --embed-fonts --print-safe --json --pretty --check --write --open --no-open --allow-write --port --stdio\";\n\nexport function shellCompletions(shell: string | undefined): string {\n switch (shell) {\n case \"bash\":\n return `# Kekonic Diagrams completion\\n_kdiagrams() {\\n local cur=\"\\${COMP_WORDS[COMP_CWORD]}\"\\n COMPREPLY=( $(compgen -W \"${COMMANDS} ${OPTIONS}\" -- \"$cur\") )\\n}\\ncomplete -F _kdiagrams kdiagrams\\n`;\n case \"zsh\":\n return `#compdef kdiagrams\\n_arguments '1:command:(${COMMANDS})' '*:option:(${OPTIONS})'\\n`;\n case \"fish\":\n return `${COMMANDS.split(\" \")\n .map((command) => `complete -c kdiagrams -f -n '__fish_use_subcommand' -a '${command}'`)\n .join(\"\\n\")}\\n`;\n default:\n throw new CliUsageError(\"completions requires one shell: bash, zsh, or fish\");\n }\n}\n","import { existsSync, readFileSync } from \"node:fs\";\nimport { dirname, isAbsolute, join, parse, resolve } from \"node:path\";\nimport { registerTheme, type PresentationOptions } from \"@kekonic/diagrams\";\nimport { CliUsageError, type ParsedCommand } from \"./command-model.ts\";\n\nconst DEFAULT_CONFIG = \"kekonic-diagrams.config.json\";\n\nexport type ExportProfile = {\n theme?: string;\n snapshotTheme?: boolean;\n background?: \"transparent\" | \"theme\";\n embedFonts?: boolean;\n printSafe?: boolean;\n presentation?: PresentationOptions;\n format?: \"svg\" | \"png\" | \"pdf\";\n};\n\nexport type ProjectConfig = {\n version: 1;\n defaultProfile?: string;\n themes?: Record<string, Record<string, string>>;\n profiles?: Record<string, ExportProfile>;\n};\n\nexport type ResolvedRenderSettings = Required<\n Pick<ExportProfile, \"theme\" | \"snapshotTheme\" | \"background\" | \"embedFonts\" | \"printSafe\">\n> & {\n presentation?: PresentationOptions;\n configPath?: string;\n profileName?: string;\n warnings: string[];\n};\n\nexport function resolveRenderSettings(\n command: ParsedCommand,\n cwd = process.cwd(),\n): ResolvedRenderSettings {\n const loaded = loadProjectConfig(command.options.config, cwd);\n const config = loaded?.config;\n const configDir = loaded ? dirname(loaded.path) : cwd;\n\n for (const [name, tokens] of Object.entries(config?.themes ?? {})) {\n validateTokens(tokens, `themes.${name}`);\n registerTheme(name, tokens);\n }\n if (command.options.themeFile) {\n const themePath = resolve(configDir, command.options.themeFile);\n const parsed = readJson(themePath);\n const name = command.options.theme ?? \"custom\";\n const tokens = isRecord(parsed) && isRecord(parsed.tokens) ? parsed.tokens : parsed;\n validateTokens(tokens, themePath);\n registerTheme(name, tokens);\n }\n\n const profileName = command.options.profile ?? config?.defaultProfile;\n const profile = profileName ? config?.profiles?.[profileName] : undefined;\n if (profileName && !profile) {\n throw new CliUsageError(`Unknown export profile: ${profileName}`);\n }\n if (profile?.format && profile.format !== \"svg\") {\n throw new CliUsageError(\n `Export profile ${profileName} requests ${profile.format}; this CLI build supports SVG output`,\n );\n }\n\n const printSafe = command.options.printSafe || profile?.printSafe === true;\n const snapshotTheme = command.options.liveTheme\n ? false\n : command.options.snapshot || profile?.snapshotTheme !== false;\n const settings: ResolvedRenderSettings = {\n theme: command.options.theme ?? profile?.theme ?? (printSafe ? \"light\" : \"dark\"),\n snapshotTheme,\n background:\n command.options.background ?? profile?.background ?? (printSafe ? \"theme\" : \"transparent\"),\n embedFonts: command.options.embedFonts || profile?.embedFonts === true,\n printSafe,\n presentation: profile?.presentation,\n configPath: loaded?.path,\n profileName,\n warnings: [],\n };\n if (!snapshotTheme) {\n settings.warnings.push(\n \"live-theme SVG retains unresolved CSS custom properties and requires KDiagram theme tokens from its host\",\n );\n }\n return settings;\n}\n\nexport function findProjectConfig(cwd: string): string | undefined {\n let current = resolve(cwd);\n const root = parse(current).root;\n while (true) {\n const candidate = join(current, DEFAULT_CONFIG);\n if (existsSync(candidate)) return candidate;\n if (current === root) return undefined;\n current = dirname(current);\n }\n}\n\nfunction loadProjectConfig(\n explicitPath: string | undefined,\n cwd: string,\n): { path: string; config: ProjectConfig } | undefined {\n const path = explicitPath\n ? isAbsolute(explicitPath)\n ? explicitPath\n : resolve(cwd, explicitPath)\n : findProjectConfig(cwd);\n if (!path) return undefined;\n if (!existsSync(path)) throw new CliUsageError(`Config file does not exist: ${path}`);\n const parsed = readJson(path);\n if (!isRecord(parsed) || parsed.version !== 1) {\n throw new CliUsageError(`${path}: expected { \"version\": 1, ... }`);\n }\n validateConfigKeys(parsed, path);\n return { path, config: parsed as ProjectConfig };\n}\n\nfunction validateConfigKeys(value: Record<string, unknown>, path: string): void {\n const allowed = new Set([\"version\", \"defaultProfile\", \"themes\", \"profiles\", \"$schema\"]);\n for (const key of Object.keys(value)) {\n if (!allowed.has(key)) throw new CliUsageError(`${path}: unknown config property ${key}`);\n }\n if (value.profiles != null && !isRecord(value.profiles)) {\n throw new CliUsageError(`${path}: profiles must be an object`);\n }\n for (const [name, profile] of Object.entries((value.profiles as object | undefined) ?? {})) {\n if (!isRecord(profile)) throw new CliUsageError(`${path}: profile ${name} must be an object`);\n const profileKeys = new Set([\n \"theme\",\n \"snapshotTheme\",\n \"background\",\n \"embedFonts\",\n \"printSafe\",\n \"presentation\",\n \"format\",\n ]);\n for (const key of Object.keys(profile)) {\n if (!profileKeys.has(key)) {\n throw new CliUsageError(`${path}: unknown profiles.${name}.${key}`);\n }\n }\n }\n}\n\nfunction readJson(path: string): unknown {\n try {\n return JSON.parse(readFileSync(path, \"utf8\"));\n } catch (error) {\n throw new CliUsageError(\n `${path}: ${error instanceof Error ? error.message : \"could not read JSON\"}`,\n );\n }\n}\n\nfunction validateTokens(value: unknown, label: string): asserts value is Record<string, string> {\n if (!isRecord(value)) throw new CliUsageError(`${label}: theme tokens must be an object`);\n for (const [key, token] of Object.entries(value)) {\n if (!/^--[a-zA-Z0-9_-]+$/.test(key) || typeof token !== \"string\") {\n throw new CliUsageError(`${label}: theme tokens must map --custom-properties to strings`);\n }\n if (/[;{}<>@]/.test(token) || /url\\s*\\(/i.test(token)) {\n throw new CliUsageError(`${label}.${key}: theme token contains unsupported CSS syntax`);\n }\n }\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value != null && typeof value === \"object\" && !Array.isArray(value);\n}\n","import { existsSync } from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport { findProjectConfig } from \"./project-config.ts\";\n\nconst require = createRequire(import.meta.url);\n\nexport type DoctorCheck = {\n name: string;\n status: \"pass\" | \"warn\" | \"fail\";\n detail: string;\n};\n\nexport function runDoctor(cwd = process.cwd()): DoctorCheck[] {\n const nodeMajor = Number(process.versions.node.split(\".\")[0]);\n const config = findProjectConfig(cwd);\n let font = \"unavailable\";\n try {\n const path = require.resolve(\"@fontsource/inter/files/inter-latin-500-normal.woff\");\n if (existsSync(path)) font = path;\n } catch {\n // Reported as a structured failure below.\n }\n return [\n {\n name: \"runtime\",\n status: nodeMajor >= 22 ? \"pass\" : \"fail\",\n detail: `Node ${process.versions.node} (requires >=22.18.0)`,\n },\n {\n name: \"font\",\n status: font === \"unavailable\" ? \"fail\" : \"pass\",\n detail:\n font === \"unavailable\"\n ? \"Bundled Inter measurement font not found\"\n : \"Bundled Inter font available\",\n },\n {\n name: \"config\",\n status: config ? \"pass\" : \"warn\",\n detail:\n config ?? \"No kekonic-diagrams.config.json discovered; built-in export defaults apply\",\n },\n {\n name: \"renderer\",\n status: \"pass\",\n detail: \"SVG renderer available; portable snapshot export is the default\",\n },\n ];\n}\n","import { existsSync, readFileSync, statSync } from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport { basename, dirname, extname, isAbsolute, relative, resolve, sep } from \"node:path\";\nimport type { Ignore } from \"ignore\";\nimport { globSync, isDynamicPattern } from \"tinyglobby\";\nimport { CliUsageError, type ParsedCommand } from \"./command-model.ts\";\n\nconst SOURCE_EXTENSION = \".kdiagram\";\nconst DEFAULT_IGNORE_FILE = \".kdiagramignore\";\nconst CRAWL_IGNORES = [\"**/.git/**\", \"**/node_modules/**\"];\nconst require = createRequire(import.meta.url);\n// `ignore` v5 is CommonJS; createRequire preserves its callable runtime export under NodeNext.\nconst createIgnore = require(\"ignore\") as () => Ignore;\n\nexport type ResolvedInput = {\n kind: \"file\" | \"stdin\";\n absolutePath?: string;\n displayPath: string;\n relativePath: string;\n source?: string;\n};\n\nexport type ResolveInputOptions = {\n cwd?: string;\n stdinIsTTY?: boolean;\n readStdin?: () => string;\n};\n\ntype Candidate = { absolutePath: string; relativePath: string };\n\nexport function resolveCommandInputs(\n command: ParsedCommand,\n options: ResolveInputOptions = {},\n): ResolvedInput[] {\n const cwd = resolve(options.cwd ?? process.cwd());\n const readStdin = options.readStdin ?? (() => readFileSync(0, \"utf-8\"));\n const requested = [...command.inputs];\n\n if (command.options.filesFrom) {\n const listSource = command.options.filesFrom;\n let pathList: string;\n if (listSource === \"-\") {\n if (requested.includes(\"-\")) {\n throw new CliUsageError(\"stdin cannot contain both diagram source and --files-from paths\");\n }\n pathList = readStdin();\n } else {\n pathList = readFileSync(resolve(cwd, listSource), \"utf-8\");\n }\n requested.push(...parsePathList(pathList));\n }\n\n if (requested.length === 0) {\n if (command.options.filesFrom) {\n throw new CliUsageError(\"--files-from did not provide any input paths\");\n }\n if (options.stdinIsTTY ?? process.stdin.isTTY) {\n throw new CliUsageError(\"Missing input (pass a path, '-' or pipe diagram source on stdin)\");\n }\n requested.push(\"-\");\n }\n\n const files: Candidate[] = [];\n let stdinInput: ResolvedInput | undefined;\n for (const input of requested) {\n if (input === \"-\") {\n if (stdinInput) throw new CliUsageError(\"stdin source may be supplied only once\");\n const filename = command.options.stdinFilename;\n const absolutePath = filename ? resolve(cwd, filename) : undefined;\n stdinInput = {\n kind: \"stdin\",\n absolutePath,\n displayPath: filename ?? \"<stdin>\",\n relativePath: filename ? portableRelativePath(cwd, absolutePath!) : \"stdin.kdiagram\",\n source: readStdin(),\n };\n continue;\n }\n files.push(...expandInput(input, cwd));\n }\n\n const filtered = filterIgnoredFiles(\n files,\n cwd,\n command.options.ignoreFile,\n command.options.excludes,\n );\n const unique = new Map<string, Candidate>();\n for (const candidate of filtered) unique.set(resolve(candidate.absolutePath), candidate);\n const resolvedFiles = [...unique.values()]\n .sort((left, right) => comparePaths(left.absolutePath, right.absolutePath))\n .map<ResolvedInput>(({ absolutePath, relativePath }) => ({\n kind: \"file\",\n absolutePath,\n displayPath: absolutePath,\n relativePath,\n }));\n const result = stdinInput ? [...resolvedFiles, stdinInput] : resolvedFiles;\n if (result.length === 0) throw new CliUsageError(\"No .kdiagram input files matched\");\n return result;\n}\n\nexport function readResolvedInput(input: ResolvedInput): string {\n if (input.kind === \"stdin\") return input.source ?? \"\";\n return readFileSync(input.absolutePath!, \"utf-8\");\n}\n\nfunction expandInput(input: string, cwd: string): Candidate[] {\n const absolute = resolve(cwd, input);\n if (existsSync(absolute)) {\n const stats = statSync(absolute);\n if (stats.isDirectory()) {\n const matches = globSync(\"**/*.kdiagram\", {\n cwd: absolute,\n absolute: true,\n dot: true,\n followSymbolicLinks: false,\n ignore: CRAWL_IGNORES,\n });\n const insideCwd = isWithin(cwd, absolute);\n return matches.map((file) => ({\n absolutePath: file,\n relativePath: insideCwd\n ? portableRelativePath(cwd, file)\n : toPosix(relative(absolute, file)),\n }));\n }\n if (!stats.isFile()) throw new CliUsageError(`Input is not a file or directory: ${input}`);\n if (extname(absolute).toLowerCase() !== SOURCE_EXTENSION) {\n throw new CliUsageError(`Input file must end in ${SOURCE_EXTENSION}: ${input}`);\n }\n return [{ absolutePath: absolute, relativePath: portableRelativePath(cwd, absolute) }];\n }\n\n if (!isDynamicPattern(input)) throw new CliUsageError(`Input path does not exist: ${input}`);\n return globSync(input, {\n cwd,\n absolute: true,\n dot: true,\n followSymbolicLinks: false,\n onlyFiles: true,\n ignore: CRAWL_IGNORES,\n })\n .filter((file) => extname(file).toLowerCase() === SOURCE_EXTENSION)\n .map((file) => ({\n absolutePath: file,\n relativePath: portableRelativePath(cwd, file),\n }));\n}\n\nfunction filterIgnoredFiles(\n files: readonly Candidate[],\n cwd: string,\n ignoreFileOption: string | undefined,\n excludes: readonly string[],\n): Candidate[] {\n const ignoreFile = resolve(cwd, ignoreFileOption ?? DEFAULT_IGNORE_FILE);\n const ignoreRoot = dirname(ignoreFile);\n const ignoreMatcher = existsSync(ignoreFile)\n ? createIgnore().add(readFileSync(ignoreFile, \"utf-8\"))\n : undefined;\n const excludeMatcher = excludes.length > 0 ? createIgnore().add(excludes) : undefined;\n if (!ignoreMatcher && !excludeMatcher) return [...files];\n\n return files.filter((candidate) => {\n if (ignoreMatcher && isWithin(ignoreRoot, candidate.absolutePath)) {\n const ignoredPath = toPosix(relative(ignoreRoot, candidate.absolutePath));\n if (ignoreMatcher.ignores(ignoredPath)) return false;\n }\n return !excludeMatcher?.ignores(candidate.relativePath);\n });\n}\n\nfunction isWithin(parent: string, child: string): boolean {\n const rel = relative(parent, child);\n return !rel.startsWith(`..${sep}`) && !isAbsolute(rel);\n}\n\nfunction parsePathList(contents: string): string[] {\n return contents\n .split(/\\r?\\n/)\n .map((line) => line.trim())\n .filter((line) => line.length > 0 && !line.startsWith(\"#\"));\n}\n\nfunction portableRelativePath(cwd: string, absolutePath: string): string {\n const rel = relative(cwd, absolutePath);\n if (!rel || rel.startsWith(`..${sep}`) || isAbsolute(rel)) return basename(absolutePath);\n return toPosix(rel);\n}\n\nfunction toPosix(path: string): string {\n return path.split(sep).join(\"/\");\n}\n\nfunction comparePaths(left: string, right: string): number {\n const a = toPosix(left);\n const b = toPosix(right);\n return a < b ? -1 : a > b ? 1 : 0;\n}\n","import type { Diagnostic } from \"@kekonic/diagrams\";\nimport type { ColorMode, CommandOptions } from \"./command-model.ts\";\n\nexport const EXIT_SUCCESS = 0;\nexport const EXIT_DIAGNOSTICS = 1;\nexport const EXIT_USAGE = 2;\nexport const EXIT_OPERATIONAL = 3;\nexport const MACHINE_OUTPUT_VERSION = 1;\n\ntype Writable = Pick<NodeJS.WritableStream, \"write\"> & { isTTY?: boolean };\n\nexport type OutputContext = {\n color: boolean;\n quiet: boolean;\n verbose: boolean;\n debug: boolean;\n stderr: Writable;\n};\n\nexport function createOutputContext(\n options: Pick<CommandOptions, \"color\" | \"quiet\" | \"verbose\" | \"debug\">,\n stderr: Writable = process.stderr,\n env: NodeJS.ProcessEnv = process.env,\n): OutputContext {\n return {\n color: shouldUseColor(options.color, stderr.isTTY === true, env),\n quiet: options.quiet,\n verbose: options.verbose,\n debug: options.debug,\n stderr,\n };\n}\n\nexport function shouldUseColor(mode: ColorMode, isTTY: boolean, env: NodeJS.ProcessEnv): boolean {\n if (mode === \"always\") return true;\n if (mode === \"never\") return false;\n if (env.NO_COLOR != null || env.FORCE_COLOR === \"0\") return false;\n if (env.FORCE_COLOR != null) return true;\n return isTTY;\n}\n\nexport function printDiagnostic(\n context: OutputContext,\n diagnostic: Diagnostic,\n source: string,\n path: string,\n): void {\n const { start, end } = diagnostic.range;\n const severity = colorizeSeverity(context, diagnostic.severity);\n context.stderr.write(\n `${bold(context, `${path}:${start.line}:${start.column}`)} ${severity}[${diagnostic.code}] ${diagnostic.message}\\n`,\n );\n\n const lines = source.split(/\\r?\\n/);\n const line = lines[start.line - 1] ?? \"\";\n const lineNumber = String(start.line);\n const gutter = \" \".repeat(lineNumber.length);\n const startColumn = Math.max(1, start.column);\n const endColumn =\n end.line === start.line ? Math.max(startColumn + 1, end.column) : line.length + 1;\n const markerLength = Math.max(\n 1,\n Math.min(endColumn - startColumn, line.length - startColumn + 2),\n );\n context.stderr.write(`${dim(context, `${gutter} |`)}\\n`);\n context.stderr.write(`${dim(context, `${lineNumber} |`)} ${line}\\n`);\n context.stderr.write(\n `${dim(context, `${gutter} |`)} ${\" \".repeat(startColumn - 1)}${severityColor(context, diagnostic.severity, \"^\".repeat(markerLength))}\\n`,\n );\n if (diagnostic.hint) {\n context.stderr.write(\n `${dim(context, `${gutter} =`)} ${cyan(context, \"hint:\")} ${diagnostic.hint}\\n`,\n );\n }\n}\n\nexport function printSummary(context: OutputContext, message: string): void {\n if (!context.quiet) context.stderr.write(`${message}\\n`);\n}\n\nexport function printProgress(context: OutputContext, message: string): void {\n if (!context.quiet && context.verbose) context.stderr.write(`${dim(context, message)}\\n`);\n}\n\nexport function machineEnvelope<T>(\n command: string,\n payload: T,\n): {\n version: 1;\n command: string;\n payload: T;\n} {\n return { version: MACHINE_OUTPUT_VERSION, command, payload };\n}\n\nexport function installPipeErrorHandlers(): void {\n for (const stream of [process.stdout, process.stderr]) {\n stream.on(\"error\", (error: NodeJS.ErrnoException) => {\n if (error.code === \"EPIPE\") {\n process.exit(EXIT_SUCCESS);\n }\n throw error;\n });\n }\n}\n\nfunction printCode(code: number): string {\n return `\\u001b[${code}m`;\n}\n\nfunction styled(context: OutputContext, code: number, text: string): string {\n return context.color ? `${printCode(code)}${text}${printCode(0)}` : text;\n}\n\nfunction bold(context: OutputContext, text: string): string {\n return styled(context, 1, text);\n}\n\nfunction dim(context: OutputContext, text: string): string {\n return styled(context, 2, text);\n}\n\nfunction cyan(context: OutputContext, text: string): string {\n return styled(context, 36, text);\n}\n\nfunction severityColor(\n context: OutputContext,\n severity: Diagnostic[\"severity\"],\n text: string,\n): string {\n return styled(context, severity === \"error\" ? 31 : severity === \"warning\" ? 33 : 36, text);\n}\n\nfunction colorizeSeverity(context: OutputContext, severity: Diagnostic[\"severity\"]): string {\n return severityColor(context, severity, severity);\n}\n","import { basename, dirname, extname, resolve } from \"node:path\";\nimport { CliUsageError, type ParsedCommand } from \"./command-model.ts\";\nimport type { ResolvedInput } from \"./input-resolver.ts\";\n\nexport function renderOutputPaths(\n command: ParsedCommand,\n inputs: readonly ResolvedInput[],\n cwd = process.cwd(),\n): Array<string | undefined> {\n const { output, outDir, outputTemplate } = command.options;\n if (inputs.length > 1 && output) {\n throw new CliUsageError(\"--output accepts only one resolved input\");\n }\n if (inputs.length > 1 && !outDir && !outputTemplate) {\n throw new CliUsageError(\n \"Multiple render inputs require --out-dir or --output-template; SVG documents are never concatenated\",\n );\n }\n\n const paths = inputs.map((input) => {\n if (output) return resolve(cwd, output);\n if (!outDir && !outputTemplate) return undefined;\n const rendered = applyTemplate(outputTemplate ?? \"{path}.svg\", input.relativePath);\n return outDir ? resolve(cwd, outDir, rendered) : resolve(cwd, rendered);\n });\n rejectCollisions(paths);\n return paths;\n}\n\nfunction applyTemplate(template: string, relativeInput: string): string {\n const extension = extname(relativeInput);\n const pathWithoutExtension = extension\n ? relativeInput.slice(0, relativeInput.length - extension.length)\n : relativeInput;\n const directory = dirname(pathWithoutExtension) === \".\" ? \"\" : dirname(pathWithoutExtension);\n const name = basename(pathWithoutExtension);\n const rendered = template\n .replaceAll(\"{path}\", pathWithoutExtension)\n .replaceAll(\"{dir}\", directory)\n .replaceAll(\"{name}\", name)\n .replaceAll(\"{ext}\", \"svg\");\n if (!rendered || rendered.endsWith(\"/\")) {\n throw new CliUsageError(`Invalid --output-template result for ${relativeInput}: ${rendered}`);\n }\n return rendered;\n}\n\nfunction rejectCollisions(paths: readonly (string | undefined)[]): void {\n const seen = new Set<string>();\n for (const path of paths) {\n if (!path) continue;\n if (seen.has(path))\n throw new CliUsageError(`Multiple inputs resolve to the same output: ${path}`);\n seen.add(path);\n }\n}\n","import { readFileSync } from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport type { ResolvedRenderSettings } from \"./project-config.ts\";\n\nconst require = createRequire(import.meta.url);\n\nexport function finalizePortableSvg(svg: string, settings: ResolvedRenderSettings): string {\n let output = svg;\n if (settings.embedFonts) output = embedInter(output);\n if (settings.background === \"theme\") {\n const background = `<rect class=\"kdiagram-export-background\" width=\"100%\" height=\"100%\" fill=\"var(--kd-bg)\"/>`;\n output = output.replace(/(<desc\\b[^>]*>[^<]*<\\/desc>)/, `$1\\n${background}`);\n }\n return output;\n}\n\nfunction embedInter(svg: string): string {\n const fontPath = require.resolve(\"@fontsource/inter/files/inter-latin-500-normal.woff\");\n const font = readFileSync(fontPath).toString(\"base64\");\n const css = `@font-face{font-family:\"Inter\";src:url(data:font/woff;base64,${font}) format(\"woff\");font-style:normal;font-weight:100 900;font-display:block;}`;\n const styleIndex = svg.indexOf(\"<style>\");\n if (styleIndex >= 0) return svg.slice(0, styleIndex + 7) + css + svg.slice(styleIndex + 7);\n return svg.replace(/(<svg\\b[^>]*>)/, `$1\\n<style>${css}</style>`);\n}\n","import { spawn } from \"node:child_process\";\nimport { randomBytes } from \"node:crypto\";\nimport {\n createReadStream,\n existsSync,\n readFileSync,\n statSync,\n watch,\n writeFileSync,\n} from \"node:fs\";\nimport { createServer, type IncomingMessage, type ServerResponse } from \"node:http\";\nimport { basename, dirname, extname, relative, resolve, sep } from \"node:path\";\nimport { createRequire } from \"node:module\";\nimport { renderPipeline } from \"@kekonic/diagrams\";\nimport { loadIconSubset } from \"@kekonic/diagrams-icons\";\nimport {\n STUDIO_PROTOCOL_VERSION,\n createStudioPreviewCoordinator,\n parseStudioClientMessage,\n studioMessageJson,\n type StudioDocument,\n type StudioPresentation,\n type StudioRender,\n type StudioServerMessage,\n} from \"@kekonic/diagrams-studio\";\n\nconst require = createRequire(import.meta.url);\nconst ICON_NAME = /^[a-z0-9][a-z0-9-]*$/;\nconst MAX_ICONS_PER_REQUEST = 64;\n\nexport type StudioServer = {\n url: string;\n port: number;\n token: string;\n closed: Promise<void>;\n close(): Promise<void>;\n};\n\nexport type StartStudioServerOptions = {\n files: string[];\n allowWrite?: boolean;\n port?: number;\n browserRoot?: string;\n};\n\nexport async function startStudioServer(options: StartStudioServerOptions): Promise<StudioServer> {\n const files = [...new Set(options.files.map((file) => resolve(file)))].sort();\n if (files.length === 0) throw new Error(\"Studio requires at least one .kdiagram file\");\n for (const file of files) {\n if (!existsSync(file) || !statSync(file).isFile())\n throw new Error(`Studio input is not a file: ${file}`);\n }\n const roots = minimalRoots(files.map(dirname));\n const documents = new Map<string, StudioDocument>();\n for (const file of files) {\n const id = relative(commonRoot(files), file).split(sep).join(\"/\") || basename(file);\n documents.set(id, {\n id,\n path: file,\n label: id,\n revision: 0,\n source: readFileSync(file, \"utf8\"),\n });\n }\n let activeDocumentId = documents.keys().next().value as string;\n let presentation: StudioPresentation = { theme: \"dark\", options: { theme: \"dark\" } };\n const token = randomBytes(32).toString(\"base64url\");\n const sessionId = randomBytes(16).toString(\"hex\");\n const browserRoot = resolve(\n options.browserRoot ?? dirname(require.resolve(\"@kekonic/diagrams-studio/browser\")),\n );\n const clients = new Set<ServerResponse>();\n const renders = new Map<string, StudioRender>();\n const coordinator = createStudioPreviewCoordinator((source, renderOptions) =>\n renderPipeline(source, { ...renderOptions, snapshotTheme: true, shadows: false }),\n );\n\n const broadcast = (message: StudioServerMessage): void => {\n const line = `data: ${studioMessageJson(message)}\\n\\n`;\n for (const client of clients) client.write(line);\n };\n const renderDocument = async (document: StudioDocument): Promise<void> => {\n const result = await coordinator.render(\n document.id,\n document.revision,\n document.source,\n presentation.options,\n );\n if (result) {\n renders.set(document.id, result);\n broadcast({ version: STUDIO_PROTOCOL_VERSION, type: \"render\", ...result });\n }\n };\n\n const server = createServer(async (request, response) => {\n try {\n const url = new URL(request.url ?? \"/\", \"http://127.0.0.1\");\n const cookieToken = request.headers.cookie\n ?.split(\";\")\n .map((item) => item.trim())\n .find((item) => item.startsWith(\"kdiagram_studio=\"))\n ?.slice(\"kdiagram_studio=\".length);\n if (url.searchParams.get(\"token\") !== token && cookieToken !== token) {\n return respond(response, 403, \"Forbidden\");\n }\n if (request.method === \"GET\" && url.pathname === \"/events\") {\n response.writeHead(200, {\n \"Content-Type\": \"text/event-stream\",\n \"Cache-Control\": \"no-cache, no-transform\",\n Connection: \"keep-alive\",\n \"X-Content-Type-Options\": \"nosniff\",\n });\n clients.add(response);\n response.write(\n `data: ${studioMessageJson({\n version: 1,\n type: \"ready\",\n sessionId,\n documents: [...documents.values()],\n activeDocumentId,\n capabilities: { write: options.allowWrite === true, export: true },\n presentation,\n })}\\n\\n`,\n );\n request.on(\"close\", () => clients.delete(response));\n void renderDocument(documents.get(activeDocumentId)!);\n return;\n }\n if (request.method === \"POST\" && url.pathname === \"/message\") {\n const message = parseStudioClientMessage(JSON.parse(await readBody(request)));\n const document = \"documentId\" in message ? documents.get(message.documentId) : undefined;\n if (\"documentId\" in message && !document) return respond(response, 404, \"Unknown document\");\n switch (message.type) {\n case \"open\":\n activeDocumentId = message.documentId;\n broadcast({ version: 1, type: \"document\", reason: \"open\", ...document! });\n void renderDocument(document!);\n break;\n case \"source\":\n if (message.revision <= document!.revision)\n return respond(response, 409, \"Stale revision\");\n document!.revision = message.revision;\n document!.source = message.source;\n void renderDocument(document!);\n break;\n case \"save\":\n if (!options.allowWrite)\n return respond(response, 403, \"Studio writes are not authorized\");\n assertWithinRoots(document!.path, roots);\n if (message.revision < document!.revision)\n return respond(response, 409, \"Stale revision\");\n writeFileSync(\n document!.path,\n message.source.endsWith(\"\\n\") ? message.source : `${message.source}\\n`,\n \"utf8\",\n );\n document!.source = readFileSync(document!.path, \"utf8\");\n document!.revision = message.revision;\n broadcast({\n version: 1,\n type: \"saved\",\n documentId: document!.id,\n revision: document!.revision,\n });\n break;\n case \"selection\":\n if (message.selection.graphElement && !message.selection.range) {\n const graph = renders.get(message.selection.documentId)?.graph;\n const collection =\n message.selection.graphElement.type === \"node\" ? graph?.nodes : graph?.edges;\n const element = collection?.find(\n (item) => item.id === message.selection.graphElement?.id,\n );\n if (element?.sourceRange) message.selection.range = element.sourceRange;\n }\n broadcast({ version: 1, type: \"selection\", selection: message.selection });\n break;\n case \"viewport\":\n broadcast({ version: 1, type: \"viewport\", viewport: message.viewport });\n break;\n case \"presentation\":\n presentation = message.presentation;\n broadcast({ version: 1, type: \"presentation\", presentation });\n void renderDocument(documents.get(activeDocumentId)!);\n break;\n }\n return respond(response, 204, \"\");\n }\n if (request.method === \"GET\" && url.pathname.startsWith(\"/__kdiagram/icons/\")) {\n return serveIconSubset(url, response);\n }\n if (request.method !== \"GET\") return respond(response, 405, \"Method not allowed\");\n const requestedPath =\n url.pathname === \"/\" ? \"index.html\" : decodeURIComponent(url.pathname.slice(1));\n const assetPath = resolve(browserRoot, requestedPath);\n assertWithinRoots(assetPath, [browserRoot]);\n if (!existsSync(assetPath) || !statSync(assetPath).isFile())\n return respond(response, 404, \"Not found\");\n response.writeHead(200, {\n \"Content-Type\": contentType(assetPath),\n \"Cache-Control\":\n requestedPath === \"index.html\" ? \"no-store\" : \"public, max-age=31536000, immutable\",\n \"Content-Security-Policy\":\n \"default-src 'self'; script-src 'self' 'wasm-unsafe-eval'; style-src 'self' 'unsafe-inline'; font-src 'self'; img-src 'self' data:; connect-src 'self'; object-src 'none'; base-uri 'none'; frame-ancestors 'none'\",\n \"X-Content-Type-Options\": \"nosniff\",\n \"Referrer-Policy\": \"no-referrer\",\n ...(requestedPath === \"index.html\"\n ? { \"Set-Cookie\": `kdiagram_studio=${token}; HttpOnly; SameSite=Strict; Path=/` }\n : {}),\n });\n createReadStream(assetPath).pipe(response);\n } catch (error) {\n respond(response, 400, error instanceof Error ? error.message : String(error));\n }\n });\n\n const watchers = files.map((file) =>\n watch(file, { persistent: false }, () => {\n const document = [...documents.values()].find((item) => item.path === file);\n if (!document) return;\n const source = readFileSync(file, \"utf8\");\n if (source === document.source) return;\n document.source = source;\n document.revision += 1;\n broadcast({ version: 1, type: \"document\", reason: \"external\", ...document });\n void renderDocument(document);\n }),\n );\n const heartbeat = setInterval(() => {\n for (const client of clients) client.write(\": heartbeat\\n\\n\");\n }, 15_000);\n heartbeat.unref();\n\n await new Promise<void>((resolveListen, reject) => {\n server.once(\"error\", reject);\n server.listen(options.port ?? 0, \"127.0.0.1\", resolveListen);\n });\n const address = server.address();\n if (!address || typeof address === \"string\")\n throw new Error(\"Studio server did not bind a TCP port\");\n let resolveClosed!: () => void;\n const closed = new Promise<void>((resolvePromise) => (resolveClosed = resolvePromise));\n server.once(\"close\", resolveClosed);\n const close = async (): Promise<void> => {\n clearInterval(heartbeat);\n for (const watcher of watchers) watcher.close();\n for (const client of clients) client.end();\n await new Promise<void>((resolveClose, reject) =>\n server.close((error) => (error ? reject(error) : resolveClose())),\n );\n };\n return {\n url: `http://127.0.0.1:${address.port}/?token=${encodeURIComponent(token)}`,\n port: address.port,\n token,\n closed,\n close,\n };\n}\n\nexport async function openStudioBrowser(url: string): Promise<void> {\n const command =\n process.platform === \"darwin\"\n ? { executable: \"open\", args: [url] }\n : process.platform === \"win32\"\n ? { executable: \"cmd\", args: [\"/c\", \"start\", \"\", url] }\n : { executable: \"xdg-open\", args: [url] };\n const child = spawn(command.executable, command.args, { detached: true, stdio: \"ignore\" });\n child.unref();\n await new Promise<void>((resolveSpawn, reject) => {\n child.once(\"spawn\", resolveSpawn);\n child.once(\"error\", reject);\n });\n}\n\nfunction respond(response: ServerResponse, status: number, body: string): void {\n response.writeHead(status, {\n \"Content-Type\": \"text/plain; charset=utf-8\",\n \"X-Content-Type-Options\": \"nosniff\",\n });\n response.end(body);\n}\n\nasync function serveIconSubset(url: URL, response: ServerResponse): Promise<void> {\n const match = /^\\/__kdiagram\\/icons\\/([a-z0-9-]+)\\.json$/.exec(url.pathname);\n const names = parseIconNames(url.searchParams.get(\"icons\"));\n if (!match || !names) return respondJson(response, 400, { error: \"Invalid icon request\" });\n const subset = await loadIconSubset(match[1]!, names);\n if (!subset) return respondJson(response, 404, { error: \"Unknown icon collection\" });\n return respondJson(response, 200, subset);\n}\n\nfunction parseIconNames(value: string | null): string[] | null {\n if (!value) return null;\n const names = [...new Set(value.split(\",\"))];\n if (\n names.length === 0 ||\n names.length > MAX_ICONS_PER_REQUEST ||\n names.some((name) => !ICON_NAME.test(name))\n ) {\n return null;\n }\n return names;\n}\n\nfunction respondJson(response: ServerResponse, status: number, body: unknown): void {\n response.writeHead(status, {\n \"Content-Type\": \"application/json; charset=utf-8\",\n \"Cache-Control\": \"public, max-age=86400\",\n \"X-Content-Type-Options\": \"nosniff\",\n });\n response.end(JSON.stringify(body));\n}\n\nasync function readBody(request: IncomingMessage): Promise<string> {\n const chunks: Buffer[] = [];\n let bytes = 0;\n for await (const chunk of request) {\n const buffer = Buffer.from(chunk);\n bytes += buffer.byteLength;\n if (bytes > 2_000_000) throw new Error(\"Studio message exceeds 2 MB\");\n chunks.push(buffer);\n }\n return Buffer.concat(chunks).toString(\"utf8\");\n}\n\nfunction assertWithinRoots(path: string, roots: string[]): void {\n const absolute = resolve(path);\n if (!roots.some((root) => absolute === root || absolute.startsWith(`${resolve(root)}${sep}`))) {\n throw new Error(\"Path is outside the studio session roots\");\n }\n}\n\nfunction minimalRoots(directories: string[]): string[] {\n const sorted = [...new Set(directories.map((directory) => resolve(directory)))].sort();\n return sorted.filter(\n (directory, index) =>\n !sorted.some(\n (other, otherIndex) => otherIndex !== index && directory.startsWith(`${other}${sep}`),\n ),\n );\n}\n\nfunction commonRoot(files: string[]): string {\n let root = dirname(files[0]!);\n while (!files.every((file) => file === root || file.startsWith(`${root}${sep}`)))\n root = dirname(root);\n return root;\n}\n\nfunction contentType(path: string): string {\n switch (extname(path)) {\n case \".html\":\n return \"text/html; charset=utf-8\";\n case \".js\":\n return \"text/javascript; charset=utf-8\";\n case \".css\":\n return \"text/css; charset=utf-8\";\n case \".ttf\":\n return \"font/ttf\";\n case \".map\":\n return \"application/json\";\n default:\n return \"application/octet-stream\";\n }\n}\n","#!/usr/bin/env node\nimport { mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { dirname, resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport {\n analyzeDiagramQuality,\n compileSource,\n getCapabilities,\n parseSource,\n renderPipeline,\n type Diagnostic,\n} from \"@kekonic/diagrams\";\nimport { KDiagramLanguageService } from \"@kekonic/diagrams-language-service\";\nimport { CliUsageError, parseCommand, type ParsedCommand } from \"./command-model.ts\";\nimport { shellCompletions } from \"./completions.ts\";\nimport { runDoctor } from \"./doctor.ts\";\nimport { readResolvedInput, resolveCommandInputs, type ResolvedInput } from \"./input-resolver.ts\";\nimport {\n createOutputContext,\n EXIT_DIAGNOSTICS,\n EXIT_OPERATIONAL,\n EXIT_SUCCESS,\n EXIT_USAGE,\n installPipeErrorHandlers,\n machineEnvelope,\n printDiagnostic,\n printProgress,\n printSummary,\n type OutputContext,\n} from \"./output.ts\";\nimport { renderOutputPaths } from \"./output-paths.ts\";\nimport { finalizePortableSvg } from \"./portable-svg.ts\";\nimport { resolveRenderSettings } from \"./project-config.ts\";\nimport { openStudioBrowser, startStudioServer } from \"./studio-server.ts\";\nimport { runLanguageServer } from \"./lsp-server.ts\";\n\nconst argv = process.argv.slice(2);\nconst languageService = new KDiagramLanguageService();\nlet activeCommand: ParsedCommand | undefined;\ninstallPipeErrorHandlers();\n\nfunction usage(stream: NodeJS.WritableStream = process.stdout): void {\n stream.write(`kdiagrams — deterministic text-to-diagram tooling\n\nCommon jobs:\n kdiagrams check .\n kdiagrams format diagrams/ --check\n kdiagrams render diagrams/ --out-dir public/diagrams\n kdiagrams render architecture.kdiagram -o architecture.svg --print-safe\n\nCommands:\n render [inputs...] Render portable SVG\n check [inputs...] Validate source and semantics\n analyze [inputs...] Analyze rendered layout quality as JSON\n capabilities Describe the active language and renderer as JSON\n format [inputs...] Format or check source\n studio [inputs...] Launch the local browser authoring studio\n lsp --stdio Run the Language Server Protocol over stdio\n ast [input] Emit a versioned AST envelope\n graph [input] Emit a versioned semantic-model envelope\n doctor Inspect runtime, font, config, and renderer health\n completions <shell> Print Bash, Zsh, or Fish completion source\n\nStudio:\n --no-open Start without opening the browser (opens by default)\n --allow-write Authorize saving resolved input files\n --port number Loopback port (default: random available port)\n\nInput discovery:\n --exclude pattern Git-ignore-style exclusion (repeatable)\n --ignore-file file Rules file (default: .kdiagramignore)\n --stdin-filename file Logical filename for piped diagram source\n --files-from file|- Read additional input paths, one per line\n\nPortable render output:\n -o, --output file Single output file\n --out-dir dir Batch output directory; preserves relative paths\n --output-template text Template using {path}, {dir}, {name}, and {ext}\n --theme name Built-in or configured theme\n --config file Project config (default: discovered kekonic-diagrams.config.json)\n --profile name Named export profile from config\n --theme-file file JSON custom-property token map\n --live-theme Retain host-resolved CSS variables (snapshot is default)\n --background mode transparent or theme\n --embed-fonts Embed bundled Inter in SVG\n --print-safe Light snapshot with explicit theme background\n\nHuman and machine output:\n --json Versioned JSON envelope (check/doctor)\n --pretty Pretty versioned JSON (ast/graph)\n --color mode auto, always, or never\n --quiet Suppress summaries and progress\n --verbose Include progress details\n --debug Include stack traces for operational failures\n -v, --version Print installed version\n -h, --help Show help\n\nExit status: 0 success, 1 source/check failure, 2 usage error, 3 operational failure.\n`);\n}\n\nfunction version(): string {\n const manifestPath = fileURLToPath(new URL(\"../package.json\", import.meta.url));\n const manifest = JSON.parse(readFileSync(manifestPath, \"utf-8\")) as { version?: string };\n return manifest.version ?? \"unknown\";\n}\n\nfunction printDiagnostics(\n context: OutputContext,\n diagnostics: readonly Diagnostic[],\n source: string,\n path: string,\n): void {\n for (const diagnostic of diagnostics) printDiagnostic(context, diagnostic, source, path);\n}\n\nasync function cmdRender(\n command: ParsedCommand,\n inputs: ResolvedInput[],\n context: OutputContext,\n): Promise<number> {\n const outputPaths = renderOutputPaths(command, inputs);\n const settings = resolveRenderSettings(command);\n for (const warning of settings.warnings) {\n if (!context.quiet) context.stderr.write(`warning[FMCLI101] ${warning}\\n`);\n }\n if (settings.configPath) printProgress(context, `Using config ${settings.configPath}`);\n if (settings.profileName) printProgress(context, `Using export profile ${settings.profileName}`);\n\n let failed = false;\n for (let index = 0; index < inputs.length; index++) {\n const input = inputs[index]!;\n const source = readResolvedInput(input);\n printProgress(context, `Rendering ${input.displayPath}`);\n const result = await renderPipeline(source, {\n theme: settings.theme,\n snapshotTheme: settings.snapshotTheme,\n presentation: settings.presentation,\n shadows: false,\n });\n printDiagnostics(context, result.diagnostics, source, input.displayPath);\n if (!result.ok || !result.svg) {\n failed = true;\n continue;\n }\n\n const svg = finalizePortableSvg(result.svg, settings);\n const outputPath = outputPaths[index];\n if (!outputPath) {\n process.stdout.write(svg);\n continue;\n }\n mkdirSync(dirname(outputPath), { recursive: true });\n writeFileSync(outputPath, svg, \"utf-8\");\n printSummary(context, `Wrote ${outputPath}`);\n }\n return failed ? EXIT_DIAGNOSTICS : EXIT_SUCCESS;\n}\n\nasync function cmdAnalyze(command: ParsedCommand, inputs: ResolvedInput[]): Promise<number> {\n const files = [];\n let errorCount = 0;\n let warningCount = 0;\n for (const input of inputs) {\n const source = readResolvedInput(input);\n const result = await renderPipeline(source, { shadows: false });\n const diagnostics = result.diagnostics;\n errorCount += diagnostics.filter((item) => item.severity === \"error\").length;\n warningCount += diagnostics.filter((item) => item.severity === \"warning\").length;\n files.push({\n path: input.displayPath,\n diagnostics,\n artifact:\n result.layout && result.graph && result.routing\n ? {\n ...analyzeDiagramQuality(result.graph, result.layout, result.routing.edges).metrics,\n nodes: result.stats.nodeCount,\n edges: result.stats.edgeCount,\n layoutAlgorithm: result.stats.layoutAlgorithm,\n routerAlgorithm: result.stats.routerAlgorithm,\n }\n : undefined,\n });\n }\n process.stdout.write(\n `${JSON.stringify(\n machineEnvelope(\"analyze\", {\n files,\n summary: { files: inputs.length, errors: errorCount, warnings: warningCount },\n }),\n null,\n command.options.pretty ? 2 : undefined,\n )}\\n`,\n );\n return errorCount > 0 ? EXIT_DIAGNOSTICS : EXIT_SUCCESS;\n}\n\nfunction cmdCheck(command: ParsedCommand, inputs: ResolvedInput[], context: OutputContext): number {\n const files: Array<{ path: string; diagnostics: Diagnostic[] }> = [];\n let errorCount = 0;\n let warningCount = 0;\n for (const input of inputs) {\n const source = readResolvedInput(input);\n const diagnostics = languageService.updateDocument(inputUri(input), source, 1).diagnostics;\n files.push({ path: input.displayPath, diagnostics });\n errorCount += diagnostics.filter((diagnostic) => diagnostic.severity === \"error\").length;\n warningCount += diagnostics.filter((diagnostic) => diagnostic.severity === \"warning\").length;\n if (!command.options.json) {\n printDiagnostics(context, diagnostics, source, input.displayPath);\n }\n }\n\n if (command.options.json) {\n process.stdout.write(\n `${JSON.stringify(\n machineEnvelope(\"check\", {\n files,\n summary: { files: inputs.length, errors: errorCount, warnings: warningCount },\n }),\n )}\\n`,\n );\n } else {\n printSummary(\n context,\n `${inputs.length} file(s): ${errorCount} error(s), ${warningCount} warning(s)`,\n );\n }\n return errorCount > 0 ? EXIT_DIAGNOSTICS : EXIT_SUCCESS;\n}\n\nfunction cmdInspect(\n command: ParsedCommand,\n inputs: ResolvedInput[],\n context: OutputContext,\n): number {\n requireSingleInput(command.name, inputs);\n const input = inputs[0]!;\n const source = readResolvedInput(input);\n if (command.name === \"ast\") {\n const result = parseSource(source);\n printDiagnostics(context, result.diagnostics, source, input.displayPath);\n writeInspectionEnvelope(command, input, result.ast, result.diagnostics);\n return result.diagnostics.some((diagnostic) => diagnostic.severity === \"error\")\n ? EXIT_DIAGNOSTICS\n : EXIT_SUCCESS;\n }\n const result = compileSource(source);\n printDiagnostics(context, result.diagnostics, source, input.displayPath);\n writeInspectionEnvelope(command, input, result.graph, result.diagnostics);\n return result.diagnostics.some((diagnostic) => diagnostic.severity === \"error\")\n ? EXIT_DIAGNOSTICS\n : EXIT_SUCCESS;\n}\n\nfunction writeInspectionEnvelope(\n command: ParsedCommand,\n input: ResolvedInput,\n data: unknown,\n diagnostics: readonly Diagnostic[],\n): void {\n process.stdout.write(\n `${JSON.stringify(\n machineEnvelope(command.name, {\n path: input.displayPath,\n data,\n diagnostics,\n }),\n null,\n command.options.pretty ? 2 : undefined,\n )}\\n`,\n );\n}\n\nfunction cmdFormat(\n command: ParsedCommand,\n inputs: ResolvedInput[],\n context: OutputContext,\n): number {\n if (command.options.output) requireSingleInput(command.name, inputs);\n if (!command.options.write && !command.options.check && !command.options.output) {\n requireSingleInput(command.name, inputs);\n }\n if (command.options.write && inputs.some((input) => input.kind === \"stdin\")) {\n throw new CliUsageError(\"--write cannot be used with stdin\");\n }\n\n let changed = false;\n for (const input of inputs) {\n const source = readResolvedInput(input);\n const uri = inputUri(input);\n languageService.updateDocument(uri, source, 1);\n const formatted = languageService.format(uri)[0]?.newText ?? source;\n if (command.options.check) {\n if (source !== formatted) {\n changed = true;\n context.stderr.write(`${input.displayPath}: not formatted\\n`);\n }\n continue;\n }\n\n const target = command.options.output\n ? resolve(command.options.output)\n : command.options.write\n ? input.absolutePath\n : undefined;\n if (target) {\n mkdirSync(dirname(target), { recursive: true });\n writeFileSync(target, formatted, \"utf-8\");\n printSummary(context, `Wrote ${target}`);\n } else {\n process.stdout.write(formatted);\n }\n }\n return changed ? EXIT_DIAGNOSTICS : EXIT_SUCCESS;\n}\n\nfunction cmdDoctor(command: ParsedCommand, context: OutputContext): number {\n const checks = runDoctor();\n if (command.options.json) {\n process.stdout.write(`${JSON.stringify(machineEnvelope(\"doctor\", { checks }))}\\n`);\n } else {\n for (const check of checks) {\n context.stderr.write(\n `${check.status.toUpperCase().padEnd(4)} ${check.name}: ${check.detail}\\n`,\n );\n }\n }\n return checks.some((check) => check.status === \"fail\") ? EXIT_OPERATIONAL : EXIT_SUCCESS;\n}\n\nfunction requireSingleInput(command: string, inputs: readonly ResolvedInput[]): void {\n if (inputs.length !== 1) {\n throw new CliUsageError(\n `${command} requires exactly one resolved input; received ${inputs.length}`,\n );\n }\n}\n\nasync function main(): Promise<number> {\n if (argv.includes(\"-v\") || argv.includes(\"--version\")) {\n process.stdout.write(`${version()}\\n`);\n return EXIT_SUCCESS;\n }\n if (argv.includes(\"-h\") || argv.includes(\"--help\")) {\n usage();\n return EXIT_SUCCESS;\n }\n if (argv.length === 0) {\n usage(process.stderr);\n return EXIT_USAGE;\n }\n\n const command = parseCommand(argv);\n activeCommand = command;\n const context = createOutputContext(command.options);\n if (command.name === \"completions\") {\n if (command.inputs.length !== 1) throw new CliUsageError(\"completions requires one shell\");\n process.stdout.write(shellCompletions(command.inputs[0]));\n return EXIT_SUCCESS;\n }\n if (command.name === \"doctor\") {\n if (command.inputs.length > 0) throw new CliUsageError(\"doctor does not accept inputs\");\n return cmdDoctor(command, context);\n }\n if (command.name === \"capabilities\") {\n if (command.inputs.length > 0) throw new CliUsageError(\"capabilities does not accept inputs\");\n process.stdout.write(\n `${JSON.stringify(machineEnvelope(\"capabilities\", getCapabilities()), null, command.options.pretty ? 2 : undefined)}\\n`,\n );\n return EXIT_SUCCESS;\n }\n if (command.name === \"lsp\") {\n if (command.inputs.length !== 0) throw new CliUsageError(\"lsp does not accept inputs\");\n return runLanguageServer();\n }\n\n if (command.name === \"studio\") {\n const studioCommand = command.inputs.length === 0 ? { ...command, inputs: [\".\"] } : command;\n const studioInputs = resolveCommandInputs(studioCommand);\n if (studioInputs.some((input) => input.kind === \"stdin\" || !input.absolutePath)) {\n throw new CliUsageError(\"studio accepts files, directories, and globs, not stdin\");\n }\n const server = await startStudioServer({\n files: studioInputs.map((input) => input.absolutePath!),\n allowWrite: command.options.allowWrite,\n port: Number(command.options.port ?? 0),\n });\n context.stderr.write(`Kekonic Diagrams Studio: ${server.url}\\n`);\n if (!command.options.noOpen) await openStudioBrowser(server.url);\n await server.closed;\n return EXIT_SUCCESS;\n }\n\n const inputs = resolveCommandInputs(command);\n switch (command.name) {\n case \"render\":\n return cmdRender(command, inputs, context);\n case \"check\":\n return cmdCheck(command, inputs, context);\n case \"analyze\":\n return cmdAnalyze(command, inputs);\n case \"ast\":\n case \"graph\":\n return cmdInspect(command, inputs, context);\n case \"format\":\n return cmdFormat(command, inputs, context);\n }\n}\n\nmain()\n .then((exitCode) => {\n process.exitCode = exitCode;\n })\n .catch((error: unknown) => {\n if (error instanceof CliUsageError) {\n process.stderr.write(`${error.message}\\n`);\n process.exitCode = EXIT_USAGE;\n return;\n }\n const message = operationalMessage(error);\n process.stderr.write(`Operational error: ${message}\\n`);\n if (activeCommand?.options.debug && error instanceof Error && error.stack) {\n process.stderr.write(`${error.stack}\\n`);\n }\n process.exitCode = EXIT_OPERATIONAL;\n });\n\nfunction operationalMessage(error: unknown): string {\n if (error instanceof Error) {\n const code = (error as NodeJS.ErrnoException).code;\n if (code === \"ENOENT\")\n return `File not found: ${(error as NodeJS.ErrnoException).path ?? error.message}`;\n if (code === \"EACCES\")\n return `Permission denied: ${(error as NodeJS.ErrnoException).path ?? error.message}`;\n return error.message;\n }\n return String(error);\n}\n\nfunction inputUri(input: ResolvedInput): string {\n return input.absolutePath ? `file://${input.absolutePath}` : `stdin://${input.displayPath}`;\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { };
|
package/dist/lsp-bin.mjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lsp-bin.mjs","names":[],"sources":["../src/lsp-bin.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { runLanguageServer } from \"./lsp-server.ts\";\n\nprocess.exitCode = await runLanguageServer();\n"],"mappings":";;;AAGA,QAAQ,WAAW,MAAM,kBAAkB"}
|
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
import { KDiagramLanguageService } from "@kekonic/diagrams-language-service";
|
|
2
|
+
//#region src/lsp-server.ts
|
|
3
|
+
const TOKEN_TYPES = [
|
|
4
|
+
"keyword",
|
|
5
|
+
"string",
|
|
6
|
+
"number",
|
|
7
|
+
"operator",
|
|
8
|
+
"property",
|
|
9
|
+
"type",
|
|
10
|
+
"variable",
|
|
11
|
+
"class"
|
|
12
|
+
];
|
|
13
|
+
async function runLanguageServer(input = process.stdin, output = process.stdout) {
|
|
14
|
+
const service = new KDiagramLanguageService();
|
|
15
|
+
let buffer = Buffer.alloc(0);
|
|
16
|
+
let shutdown = false;
|
|
17
|
+
let exited = false;
|
|
18
|
+
const send = (message) => {
|
|
19
|
+
const body = Buffer.from(JSON.stringify(message), "utf8");
|
|
20
|
+
output.write(`Content-Length: ${body.byteLength}\r\n\r\n`);
|
|
21
|
+
output.write(body);
|
|
22
|
+
};
|
|
23
|
+
const respond = (id, result) => send({
|
|
24
|
+
jsonrpc: "2.0",
|
|
25
|
+
id,
|
|
26
|
+
result
|
|
27
|
+
});
|
|
28
|
+
const fail = (id, code, message) => send({
|
|
29
|
+
jsonrpc: "2.0",
|
|
30
|
+
id,
|
|
31
|
+
error: {
|
|
32
|
+
code,
|
|
33
|
+
message
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
const publish = (uri) => send({
|
|
37
|
+
jsonrpc: "2.0",
|
|
38
|
+
method: "textDocument/publishDiagnostics",
|
|
39
|
+
params: {
|
|
40
|
+
uri,
|
|
41
|
+
diagnostics: service.diagnostics(uri).map(toLspDiagnostic)
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
const handle = (message) => {
|
|
45
|
+
const id = message.id ?? null;
|
|
46
|
+
try {
|
|
47
|
+
switch (message.method) {
|
|
48
|
+
case "initialize":
|
|
49
|
+
respond(id, {
|
|
50
|
+
serverInfo: {
|
|
51
|
+
name: "kdiagram",
|
|
52
|
+
version: "1"
|
|
53
|
+
},
|
|
54
|
+
capabilities: {
|
|
55
|
+
textDocumentSync: {
|
|
56
|
+
openClose: true,
|
|
57
|
+
change: 2
|
|
58
|
+
},
|
|
59
|
+
completionProvider: { triggerCharacters: [
|
|
60
|
+
":",
|
|
61
|
+
" ",
|
|
62
|
+
"-",
|
|
63
|
+
"("
|
|
64
|
+
] },
|
|
65
|
+
hoverProvider: true,
|
|
66
|
+
definitionProvider: true,
|
|
67
|
+
referencesProvider: true,
|
|
68
|
+
renameProvider: { prepareProvider: false },
|
|
69
|
+
documentSymbolProvider: true,
|
|
70
|
+
foldingRangeProvider: true,
|
|
71
|
+
documentFormattingProvider: true,
|
|
72
|
+
codeActionProvider: true,
|
|
73
|
+
semanticTokensProvider: {
|
|
74
|
+
legend: {
|
|
75
|
+
tokenTypes: TOKEN_TYPES,
|
|
76
|
+
tokenModifiers: []
|
|
77
|
+
},
|
|
78
|
+
full: true
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
return;
|
|
83
|
+
case "initialized": return;
|
|
84
|
+
case "shutdown":
|
|
85
|
+
shutdown = true;
|
|
86
|
+
respond(id, null);
|
|
87
|
+
return;
|
|
88
|
+
case "exit":
|
|
89
|
+
exited = true;
|
|
90
|
+
return;
|
|
91
|
+
case "textDocument/didOpen": {
|
|
92
|
+
const params = message.params;
|
|
93
|
+
service.updateDocument(params.textDocument.uri, params.textDocument.text, params.textDocument.version);
|
|
94
|
+
publish(params.textDocument.uri);
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
case "textDocument/didChange": {
|
|
98
|
+
const params = message.params;
|
|
99
|
+
service.applyDocumentChanges(params.textDocument.uri, params.textDocument.version, params.contentChanges.map((change) => ({
|
|
100
|
+
text: change.text,
|
|
101
|
+
range: change.range ? {
|
|
102
|
+
start: fromLspPosition(change.range.start),
|
|
103
|
+
end: fromLspPosition(change.range.end)
|
|
104
|
+
} : void 0
|
|
105
|
+
})));
|
|
106
|
+
publish(params.textDocument.uri);
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
case "textDocument/didClose": {
|
|
110
|
+
const params = message.params;
|
|
111
|
+
service.closeDocument(params.textDocument.uri);
|
|
112
|
+
send({
|
|
113
|
+
jsonrpc: "2.0",
|
|
114
|
+
method: "textDocument/publishDiagnostics",
|
|
115
|
+
params: {
|
|
116
|
+
uri: params.textDocument.uri,
|
|
117
|
+
diagnostics: []
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
case "textDocument/completion": {
|
|
123
|
+
const params = message.params;
|
|
124
|
+
respond(id, service.complete(params.textDocument.uri, fromLspPosition(params.position)).map(toLspCompletion));
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
case "textDocument/hover": {
|
|
128
|
+
const params = message.params;
|
|
129
|
+
const hover = service.hover(params.textDocument.uri, fromLspPosition(params.position));
|
|
130
|
+
respond(id, hover ? {
|
|
131
|
+
contents: {
|
|
132
|
+
kind: "markdown",
|
|
133
|
+
value: hover.markdown
|
|
134
|
+
},
|
|
135
|
+
range: toLspRange(hover.range)
|
|
136
|
+
} : null);
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
case "textDocument/definition": {
|
|
140
|
+
const params = message.params;
|
|
141
|
+
const location = service.definition(params.textDocument.uri, fromLspPosition(params.position));
|
|
142
|
+
respond(id, location ? {
|
|
143
|
+
uri: location.uri,
|
|
144
|
+
range: toLspRange(location.range)
|
|
145
|
+
} : null);
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
case "textDocument/references": {
|
|
149
|
+
const params = message.params;
|
|
150
|
+
respond(id, service.references(params.textDocument.uri, fromLspPosition(params.position), params.context?.includeDeclaration ?? true).map((item) => ({
|
|
151
|
+
uri: item.uri,
|
|
152
|
+
range: toLspRange(item.range)
|
|
153
|
+
})));
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
case "textDocument/rename": {
|
|
157
|
+
const params = message.params;
|
|
158
|
+
const edits = service.renameWorkspace(params.textDocument.uri, fromLspPosition(params.position), params.newName);
|
|
159
|
+
const changes = {};
|
|
160
|
+
for (const edit of edits) (changes[edit.uri] ??= []).push(toLspTextEdit(edit));
|
|
161
|
+
respond(id, { changes });
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
case "textDocument/documentSymbol": {
|
|
165
|
+
const params = message.params;
|
|
166
|
+
respond(id, service.documentSymbols(params.textDocument.uri).map((item) => ({
|
|
167
|
+
name: item.name,
|
|
168
|
+
kind: symbolKind(item.kind),
|
|
169
|
+
range: toLspRange(item.range),
|
|
170
|
+
selectionRange: toLspRange(item.range)
|
|
171
|
+
})));
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
case "textDocument/foldingRange": {
|
|
175
|
+
const params = message.params;
|
|
176
|
+
respond(id, service.foldingRanges(params.textDocument.uri).map((item) => ({
|
|
177
|
+
startLine: item.startLine - 1,
|
|
178
|
+
endLine: item.endLine - 1
|
|
179
|
+
})));
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
case "textDocument/formatting": {
|
|
183
|
+
const params = message.params;
|
|
184
|
+
respond(id, service.format(params.textDocument.uri).map(toLspTextEdit));
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
case "textDocument/codeAction": {
|
|
188
|
+
const params = message.params;
|
|
189
|
+
respond(id, service.codeActions(params.textDocument.uri).map((action) => toLspCodeAction(params.textDocument.uri, action)));
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
case "textDocument/semanticTokens/full": {
|
|
193
|
+
const params = message.params;
|
|
194
|
+
respond(id, { data: encodeSemanticTokens(service.semanticTokens(params.textDocument.uri)) });
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
case "$/cancelRequest": return;
|
|
198
|
+
default: if (message.id !== void 0) fail(id, -32601, `Method not found: ${message.method ?? "<missing>"}`);
|
|
199
|
+
}
|
|
200
|
+
} catch (error) {
|
|
201
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
202
|
+
if (message.id !== void 0) fail(id, -32603, detail);
|
|
203
|
+
else send({
|
|
204
|
+
jsonrpc: "2.0",
|
|
205
|
+
method: "window/logMessage",
|
|
206
|
+
params: {
|
|
207
|
+
type: 1,
|
|
208
|
+
message: detail
|
|
209
|
+
}
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
};
|
|
213
|
+
return await new Promise((resolve) => {
|
|
214
|
+
input.on("data", (chunk) => {
|
|
215
|
+
buffer = Buffer.concat([buffer, Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk)]);
|
|
216
|
+
while (true) {
|
|
217
|
+
const headerEnd = buffer.indexOf("\r\n\r\n");
|
|
218
|
+
if (headerEnd < 0) break;
|
|
219
|
+
const header = buffer.subarray(0, headerEnd).toString("ascii");
|
|
220
|
+
const length = /(?:^|\r\n)Content-Length:\s*(\d+)/iu.exec(header)?.[1];
|
|
221
|
+
if (!length) {
|
|
222
|
+
buffer = Buffer.alloc(0);
|
|
223
|
+
break;
|
|
224
|
+
}
|
|
225
|
+
const bodyStart = headerEnd + 4;
|
|
226
|
+
const bodyEnd = bodyStart + Number(length);
|
|
227
|
+
if (buffer.length < bodyEnd) break;
|
|
228
|
+
const body = buffer.subarray(bodyStart, bodyEnd).toString("utf8");
|
|
229
|
+
buffer = buffer.subarray(bodyEnd);
|
|
230
|
+
try {
|
|
231
|
+
handle(JSON.parse(body));
|
|
232
|
+
} catch {
|
|
233
|
+
fail(null, -32700, "Parse error");
|
|
234
|
+
}
|
|
235
|
+
if (exited) {
|
|
236
|
+
resolve(shutdown ? 0 : 1);
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
});
|
|
241
|
+
input.on("end", () => resolve(shutdown ? 0 : 1));
|
|
242
|
+
input.on("error", () => resolve(1));
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
function fromLspPosition(position) {
|
|
246
|
+
return {
|
|
247
|
+
line: position.line + 1,
|
|
248
|
+
column: position.character + 1
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
function toLspRange(range) {
|
|
252
|
+
return {
|
|
253
|
+
start: {
|
|
254
|
+
line: Math.max(0, range.start.line - 1),
|
|
255
|
+
character: Math.max(0, range.start.column - 1)
|
|
256
|
+
},
|
|
257
|
+
end: {
|
|
258
|
+
line: Math.max(0, range.end.line - 1),
|
|
259
|
+
character: Math.max(0, range.end.column - 1)
|
|
260
|
+
}
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
function toLspDiagnostic(diagnostic) {
|
|
264
|
+
return {
|
|
265
|
+
range: toLspRange(diagnostic.range),
|
|
266
|
+
severity: diagnostic.severity === "error" ? 1 : diagnostic.severity === "warning" ? 2 : 3,
|
|
267
|
+
code: diagnostic.code,
|
|
268
|
+
source: "kdiagram",
|
|
269
|
+
message: diagnostic.message,
|
|
270
|
+
data: diagnostic.hint ? { hint: diagnostic.hint } : void 0
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
function toLspCompletion(item) {
|
|
274
|
+
return {
|
|
275
|
+
label: item.label,
|
|
276
|
+
kind: {
|
|
277
|
+
keyword: 14,
|
|
278
|
+
kind: 7,
|
|
279
|
+
property: 10,
|
|
280
|
+
value: 12,
|
|
281
|
+
reference: 6,
|
|
282
|
+
style: 7,
|
|
283
|
+
icon: 12,
|
|
284
|
+
"theme-token": 21
|
|
285
|
+
}[item.kind],
|
|
286
|
+
detail: item.detail,
|
|
287
|
+
documentation: item.documentation,
|
|
288
|
+
insertText: item.insertText
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
function toLspTextEdit(edit) {
|
|
292
|
+
return {
|
|
293
|
+
range: toLspRange(edit.range),
|
|
294
|
+
newText: edit.newText
|
|
295
|
+
};
|
|
296
|
+
}
|
|
297
|
+
function toLspCodeAction(uri, action) {
|
|
298
|
+
return {
|
|
299
|
+
title: action.title,
|
|
300
|
+
kind: action.kind,
|
|
301
|
+
diagnostics: action.diagnosticCode ? [{ code: action.diagnosticCode }] : void 0,
|
|
302
|
+
edit: action.edits.length ? { changes: { [uri]: action.edits.map(toLspTextEdit) } } : void 0
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
function symbolKind(kind) {
|
|
306
|
+
return kind === "diagram" ? 2 : kind === "group" ? 3 : kind === "style" ? 5 : kind === "animation" ? 12 : 13;
|
|
307
|
+
}
|
|
308
|
+
function encodeSemanticTokens(tokens) {
|
|
309
|
+
const sorted = [...tokens].sort((left, right) => left.line - right.line || left.column - right.column);
|
|
310
|
+
const data = [];
|
|
311
|
+
let lastLine = 1;
|
|
312
|
+
let lastColumn = 1;
|
|
313
|
+
for (const token of sorted) {
|
|
314
|
+
const deltaLine = token.line - lastLine;
|
|
315
|
+
const deltaColumn = deltaLine === 0 ? token.column - lastColumn : token.column - 1;
|
|
316
|
+
data.push(deltaLine, deltaColumn, token.length, TOKEN_TYPES.indexOf(token.type), 0);
|
|
317
|
+
lastLine = token.line;
|
|
318
|
+
lastColumn = token.column;
|
|
319
|
+
}
|
|
320
|
+
return data;
|
|
321
|
+
}
|
|
322
|
+
//#endregion
|
|
323
|
+
export { runLanguageServer as t };
|
|
324
|
+
|
|
325
|
+
//# sourceMappingURL=lsp-server-uxE48S7X.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lsp-server-uxE48S7X.mjs","names":[],"sources":["../src/lsp-server.ts"],"sourcesContent":["import type { Readable, Writable } from \"node:stream\";\nimport {\n KDiagramLanguageService,\n type CodeAction,\n type CompletionItem,\n type LanguagePosition,\n type LanguageRange,\n type SemanticToken,\n type TextEdit,\n} from \"@kekonic/diagrams-language-service\";\n\ntype JsonRpcId = string | number | null;\ntype JsonRpcMessage = { jsonrpc: \"2.0\"; id?: JsonRpcId; method?: string; params?: unknown };\ntype RpcResponse = {\n jsonrpc: \"2.0\";\n id: JsonRpcId;\n result?: unknown;\n error?: { code: number; message: string };\n};\ntype OpenParams = { textDocument: { uri: string; version: number; text: string } };\ntype ChangeParams = {\n textDocument: { uri: string; version: number };\n contentChanges: Array<{\n text: string;\n range?: {\n start: { line: number; character: number };\n end: { line: number; character: number };\n };\n }>;\n};\ntype CloseParams = { textDocument: { uri: string } };\ntype PositionParams = {\n textDocument: { uri: string };\n position: { line: number; character: number };\n};\ntype RenameParams = PositionParams & { newName: string };\ntype ReferenceParams = PositionParams & { context?: { includeDeclaration?: boolean } };\n\nconst TOKEN_TYPES: SemanticToken[\"type\"][] = [\n \"keyword\",\n \"string\",\n \"number\",\n \"operator\",\n \"property\",\n \"type\",\n \"variable\",\n \"class\",\n];\n\nexport async function runLanguageServer(\n input: Readable = process.stdin,\n output: Writable = process.stdout,\n): Promise<number> {\n const service = new KDiagramLanguageService();\n let buffer = Buffer.alloc(0);\n let shutdown = false;\n let exited = false;\n\n const send = (message: object): void => {\n const body = Buffer.from(JSON.stringify(message), \"utf8\");\n output.write(`Content-Length: ${body.byteLength}\\r\\n\\r\\n`);\n output.write(body);\n };\n const respond = (id: JsonRpcId, result: unknown): void =>\n send({ jsonrpc: \"2.0\", id, result } satisfies RpcResponse);\n const fail = (id: JsonRpcId, code: number, message: string): void =>\n send({ jsonrpc: \"2.0\", id, error: { code, message } } satisfies RpcResponse);\n const publish = (uri: string): void =>\n send({\n jsonrpc: \"2.0\",\n method: \"textDocument/publishDiagnostics\",\n params: { uri, diagnostics: service.diagnostics(uri).map(toLspDiagnostic) },\n });\n\n const handle = (message: JsonRpcMessage): void => {\n const id = message.id ?? null;\n try {\n switch (message.method) {\n case \"initialize\":\n respond(id, {\n serverInfo: { name: \"kdiagram\", version: \"1\" },\n capabilities: {\n textDocumentSync: { openClose: true, change: 2 },\n completionProvider: { triggerCharacters: [\":\", \" \", \"-\", \"(\"] },\n hoverProvider: true,\n definitionProvider: true,\n referencesProvider: true,\n renameProvider: { prepareProvider: false },\n documentSymbolProvider: true,\n foldingRangeProvider: true,\n documentFormattingProvider: true,\n codeActionProvider: true,\n semanticTokensProvider: {\n legend: { tokenTypes: TOKEN_TYPES, tokenModifiers: [] },\n full: true,\n },\n },\n });\n return;\n case \"initialized\":\n return;\n case \"shutdown\":\n shutdown = true;\n respond(id, null);\n return;\n case \"exit\":\n exited = true;\n return;\n case \"textDocument/didOpen\": {\n const params = message.params as OpenParams;\n service.updateDocument(\n params.textDocument.uri,\n params.textDocument.text,\n params.textDocument.version,\n );\n publish(params.textDocument.uri);\n return;\n }\n case \"textDocument/didChange\": {\n const params = message.params as ChangeParams;\n service.applyDocumentChanges(\n params.textDocument.uri,\n params.textDocument.version,\n params.contentChanges.map((change) => ({\n text: change.text,\n range: change.range\n ? {\n start: fromLspPosition(change.range.start),\n end: fromLspPosition(change.range.end),\n }\n : undefined,\n })),\n );\n publish(params.textDocument.uri);\n return;\n }\n case \"textDocument/didClose\": {\n const params = message.params as CloseParams;\n service.closeDocument(params.textDocument.uri);\n send({\n jsonrpc: \"2.0\",\n method: \"textDocument/publishDiagnostics\",\n params: { uri: params.textDocument.uri, diagnostics: [] },\n });\n return;\n }\n case \"textDocument/completion\": {\n const params = message.params as PositionParams;\n respond(\n id,\n service\n .complete(params.textDocument.uri, fromLspPosition(params.position))\n .map(toLspCompletion),\n );\n return;\n }\n case \"textDocument/hover\": {\n const params = message.params as PositionParams;\n const hover = service.hover(params.textDocument.uri, fromLspPosition(params.position));\n respond(\n id,\n hover\n ? {\n contents: { kind: \"markdown\", value: hover.markdown },\n range: toLspRange(hover.range),\n }\n : null,\n );\n return;\n }\n case \"textDocument/definition\": {\n const params = message.params as PositionParams;\n const location = service.definition(\n params.textDocument.uri,\n fromLspPosition(params.position),\n );\n respond(id, location ? { uri: location.uri, range: toLspRange(location.range) } : null);\n return;\n }\n case \"textDocument/references\": {\n const params = message.params as ReferenceParams;\n respond(\n id,\n service\n .references(\n params.textDocument.uri,\n fromLspPosition(params.position),\n params.context?.includeDeclaration ?? true,\n )\n .map((item) => ({ uri: item.uri, range: toLspRange(item.range) })),\n );\n return;\n }\n case \"textDocument/rename\": {\n const params = message.params as RenameParams;\n const edits = service.renameWorkspace(\n params.textDocument.uri,\n fromLspPosition(params.position),\n params.newName,\n );\n const changes: Record<string, object[]> = {};\n for (const edit of edits) (changes[edit.uri] ??= []).push(toLspTextEdit(edit));\n respond(id, { changes });\n return;\n }\n case \"textDocument/documentSymbol\": {\n const params = message.params as Pick<PositionParams, \"textDocument\">;\n respond(\n id,\n service.documentSymbols(params.textDocument.uri).map((item) => ({\n name: item.name,\n kind: symbolKind(item.kind),\n range: toLspRange(item.range),\n selectionRange: toLspRange(item.range),\n })),\n );\n return;\n }\n case \"textDocument/foldingRange\": {\n const params = message.params as Pick<PositionParams, \"textDocument\">;\n respond(\n id,\n service\n .foldingRanges(params.textDocument.uri)\n .map((item) => ({ startLine: item.startLine - 1, endLine: item.endLine - 1 })),\n );\n return;\n }\n case \"textDocument/formatting\": {\n const params = message.params as Pick<PositionParams, \"textDocument\">;\n respond(id, service.format(params.textDocument.uri).map(toLspTextEdit));\n return;\n }\n case \"textDocument/codeAction\": {\n const params = message.params as Pick<PositionParams, \"textDocument\">;\n respond(\n id,\n service\n .codeActions(params.textDocument.uri)\n .map((action) => toLspCodeAction(params.textDocument.uri, action)),\n );\n return;\n }\n case \"textDocument/semanticTokens/full\": {\n const params = message.params as Pick<PositionParams, \"textDocument\">;\n respond(id, {\n data: encodeSemanticTokens(service.semanticTokens(params.textDocument.uri)),\n });\n return;\n }\n case \"$/cancelRequest\":\n return;\n default:\n if (message.id !== undefined)\n fail(id, -32601, `Method not found: ${message.method ?? \"<missing>\"}`);\n }\n } catch (error) {\n const detail = error instanceof Error ? error.message : String(error);\n if (message.id !== undefined) fail(id, -32603, detail);\n else\n send({ jsonrpc: \"2.0\", method: \"window/logMessage\", params: { type: 1, message: detail } });\n }\n };\n\n return await new Promise<number>((resolve) => {\n input.on(\"data\", (chunk: Buffer | string) => {\n buffer = Buffer.concat([buffer, Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk)]);\n while (true) {\n const headerEnd = buffer.indexOf(\"\\r\\n\\r\\n\");\n if (headerEnd < 0) break;\n const header = buffer.subarray(0, headerEnd).toString(\"ascii\");\n const length = /(?:^|\\r\\n)Content-Length:\\s*(\\d+)/iu.exec(header)?.[1];\n if (!length) {\n buffer = Buffer.alloc(0);\n break;\n }\n const bodyStart = headerEnd + 4;\n const bodyEnd = bodyStart + Number(length);\n if (buffer.length < bodyEnd) break;\n const body = buffer.subarray(bodyStart, bodyEnd).toString(\"utf8\");\n buffer = buffer.subarray(bodyEnd);\n try {\n handle(JSON.parse(body) as JsonRpcMessage);\n } catch {\n fail(null, -32700, \"Parse error\");\n }\n if (exited) {\n resolve(shutdown ? 0 : 1);\n return;\n }\n }\n });\n input.on(\"end\", () => resolve(shutdown ? 0 : 1));\n input.on(\"error\", () => resolve(1));\n });\n}\n\nfunction fromLspPosition(position: { line: number; character: number }): LanguagePosition {\n return { line: position.line + 1, column: position.character + 1 };\n}\n\nfunction toLspRange(range: LanguageRange): object {\n return {\n start: {\n line: Math.max(0, range.start.line - 1),\n character: Math.max(0, range.start.column - 1),\n },\n end: { line: Math.max(0, range.end.line - 1), character: Math.max(0, range.end.column - 1) },\n };\n}\n\nfunction toLspDiagnostic(\n diagnostic: ReturnType<KDiagramLanguageService[\"diagnostics\"]>[number],\n): object {\n return {\n range: toLspRange(diagnostic.range),\n severity: diagnostic.severity === \"error\" ? 1 : diagnostic.severity === \"warning\" ? 2 : 3,\n code: diagnostic.code,\n source: \"kdiagram\",\n message: diagnostic.message,\n data: diagnostic.hint ? { hint: diagnostic.hint } : undefined,\n };\n}\n\nfunction toLspCompletion(item: CompletionItem): object {\n const kinds: Record<CompletionItem[\"kind\"], number> = {\n keyword: 14,\n kind: 7,\n property: 10,\n value: 12,\n reference: 6,\n style: 7,\n icon: 12,\n \"theme-token\": 21,\n };\n return {\n label: item.label,\n kind: kinds[item.kind],\n detail: item.detail,\n documentation: item.documentation,\n insertText: item.insertText,\n };\n}\n\nfunction toLspTextEdit(edit: TextEdit): object {\n return { range: toLspRange(edit.range), newText: edit.newText };\n}\n\nfunction toLspCodeAction(uri: string, action: CodeAction): object {\n return {\n title: action.title,\n kind: action.kind,\n diagnostics: action.diagnosticCode ? [{ code: action.diagnosticCode }] : undefined,\n edit: action.edits.length ? { changes: { [uri]: action.edits.map(toLspTextEdit) } } : undefined,\n };\n}\n\nfunction symbolKind(kind: string): number {\n return kind === \"diagram\"\n ? 2\n : kind === \"group\"\n ? 3\n : kind === \"style\"\n ? 5\n : kind === \"animation\"\n ? 12\n : 13;\n}\n\nfunction encodeSemanticTokens(tokens: SemanticToken[]): number[] {\n const sorted = [...tokens].sort(\n (left, right) => left.line - right.line || left.column - right.column,\n );\n const data: number[] = [];\n let lastLine = 1;\n let lastColumn = 1;\n for (const token of sorted) {\n const deltaLine = token.line - lastLine;\n const deltaColumn = deltaLine === 0 ? token.column - lastColumn : token.column - 1;\n data.push(deltaLine, deltaColumn, token.length, TOKEN_TYPES.indexOf(token.type), 0);\n lastLine = token.line;\n lastColumn = token.column;\n }\n return data;\n}\n"],"mappings":"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"}
|