@oml/server 0.14.0 → 0.14.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/out/cli.d.ts +1 -0
  2. package/{src/cli.ts → out/cli.js} +23 -45
  3. package/out/cli.js.map +1 -0
  4. package/out/index.d.ts +7 -0
  5. package/{src/index.ts → out/index.js} +1 -1
  6. package/out/index.js.map +1 -0
  7. package/out/lsp/diagram-server.d.ts +6 -0
  8. package/out/lsp/diagram-server.js +36 -0
  9. package/out/lsp/diagram-server.js.map +1 -0
  10. package/out/lsp/language-server.d.ts +13 -0
  11. package/{src/lsp/language-server.ts → out/lsp/language-server.js} +62 -120
  12. package/out/lsp/language-server.js.map +1 -0
  13. package/out/lsp/protocol/browser-fs-protocol.d.ts +14 -0
  14. package/{src/lsp/protocol/browser-fs-protocol.ts → out/lsp/protocol/browser-fs-protocol.js} +2 -14
  15. package/out/lsp/protocol/browser-fs-protocol.js.map +1 -0
  16. package/{src/lsp/protocol/reasoner-protocol.ts → out/lsp/protocol/reasoner-protocol.d.ts} +10 -24
  17. package/out/lsp/protocol/reasoner-protocol.js +12 -0
  18. package/out/lsp/protocol/reasoner-protocol.js.map +1 -0
  19. package/out/lsp/providers/browser-fs-provider.d.ts +21 -0
  20. package/{src/lsp/providers/browser-fs-provider.ts → out/lsp/providers/browser-fs-provider.js} +22 -34
  21. package/out/lsp/providers/browser-fs-provider.js.map +1 -0
  22. package/out/lsp/providers/hybrid-fs-provider.d.ts +28 -0
  23. package/{src/lsp/providers/hybrid-fs-provider.ts → out/lsp/providers/hybrid-fs-provider.js} +22 -44
  24. package/out/lsp/providers/hybrid-fs-provider.js.map +1 -0
  25. package/out/rest/export.d.ts +16 -0
  26. package/{src/rest/export.ts → out/rest/export.js} +14 -35
  27. package/out/rest/export.js.map +1 -0
  28. package/out/rest/routes.d.ts +49 -0
  29. package/{src/rest/routes.ts → out/rest/routes.js} +5 -27
  30. package/out/rest/routes.js.map +1 -0
  31. package/out/rest/server.d.ts +15 -0
  32. package/{src/rest/server.ts → out/rest/server.js} +207 -479
  33. package/out/rest/server.js.map +1 -0
  34. package/out/rest/template.d.ts +18 -0
  35. package/{src/rest/template.ts → out/rest/template.js} +21 -80
  36. package/out/rest/template.js.map +1 -0
  37. package/out/rest/validation.d.ts +49 -0
  38. package/{src/rest/validation.ts → out/rest/validation.js} +59 -163
  39. package/out/rest/validation.js.map +1 -0
  40. package/package.json +9 -4
  41. package/src/lsp/diagram-server.ts +0 -48
  42. package/tsconfig.json +0 -22
@@ -1,5 +1,4 @@
1
1
  // Copyright (c) 2026 Modelware. All rights reserved.
2
-
3
2
  import * as http from 'node:http';
4
3
  import * as fsSync from 'node:fs';
5
4
  import * as fs from 'node:fs/promises';
@@ -10,57 +9,23 @@ import { PassThrough } from 'node:stream';
10
9
  import { URL, pathToFileURL } from 'node:url';
11
10
  import { URI } from 'langium';
12
11
  import { NodeFileSystem } from 'langium/node';
13
- import { createConnection, type Connection } from 'vscode-languageserver/node.js';
12
+ import { createConnection } from 'vscode-languageserver/node.js';
14
13
  import { DataFactory, Writer } from 'n3';
15
14
  import uFuzzy from '@leeoniya/ufuzzy';
16
- import {
17
- MarkdownHandlerRegistry,
18
- MarkdownPreviewRuntime,
19
- buildTemplateCatalog as buildNavigationTemplateCatalog,
20
- extractLeadingFrontMatter,
21
- resolveTemplateForNavigation,
22
- renderTemplate,
23
- type TemplateInvocation,
24
- MarkdownExecutor,
25
- type MdBlockKind,
26
- type MdExecutableBlock,
27
- type MdBlockExecutionResult,
28
- } from '@oml/markdown';
15
+ import { MarkdownHandlerRegistry, MarkdownPreviewRuntime, buildTemplateCatalog as buildNavigationTemplateCatalog, extractLeadingFrontMatter, resolveTemplateForNavigation, renderTemplate, MarkdownExecutor, } from '@oml/markdown';
29
16
  import { STATIC_MARKDOWN_RUNTIME_BUNDLE_FILE, STATIC_MARKDOWN_RUNTIME_CSS } from '@oml/markdown/static';
30
- import {
31
- applyOmlUpdate,
32
- collectOntologyMembers,
33
- getIriForNode,
34
- getOntologyModelIndex,
35
- iriFragment,
36
- isDescription,
37
- isOntology,
38
- isVocabulary,
39
- tokenizeForFuzzy,
40
- type OmlEditRequest,
41
- type OmlEditResponse,
42
- type OmlFuzzyIndexedEntry,
43
- } from '@oml/language';
17
+ import { applyOmlUpdate, collectOntologyMembers, getIriForNode, getOntologyModelIndex, iriFragment, isDescription, isOntology, isVocabulary, tokenizeForFuzzy, } from '@oml/language';
44
18
  import { detectSparqlKind } from '@oml/owl';
45
- import { exportAssertedWorkspace, exportWorkspace, type RestExportContext } from './export.js';
46
- import { startOmlLanguageServer, type OmlLanguageServerRuntime } from '../lsp/language-server.js';
19
+ import { exportAssertedWorkspace, exportWorkspace } from './export.js';
20
+ import { startOmlLanguageServer } from '../lsp/language-server.js';
47
21
  import { createOpenApiSpec, dispatchRestRoute } from './routes.js';
48
- import {
49
- buildTemplateCatalog,
50
- expandTemplateComposeBlocks,
51
- findFilesByExtension,
52
- frontMatterString,
53
- isTemplateMarkdownFile,
54
- normalizeContextOntologyIri,
55
- } from './template.js';
56
- import { lintWorkspace, reasonWorkspace, type RestLintResult, type RestValidationContext, validateWorkspace } from './validation.js';
57
-
22
+ import { buildTemplateCatalog, expandTemplateComposeBlocks, findFilesByExtension, frontMatterString, isTemplateMarkdownFile, normalizeContextOntologyIri, } from './template.js';
23
+ import { lintWorkspace, reasonWorkspace, validateWorkspace } from './validation.js';
58
24
  const JSON_CONTENT_TYPE = 'application/json; charset=utf-8';
59
25
  const HTML_CONTENT_TYPE = 'text/html; charset=utf-8';
60
26
  const DEFAULT_BODY_LIMIT_BYTES = 2 * 1024 * 1024;
61
- const DEFAULT_REQUEST_TIMEOUT_MS = 30_000;
62
-
63
- const SUPPORTED_MD_BLOCK_KINDS = new Set<MdBlockKind>([
27
+ const DEFAULT_REQUEST_TIMEOUT_MS = 30000;
28
+ const SUPPORTED_MD_BLOCK_KINDS = new Set([
64
29
  'table',
65
30
  'tree',
66
31
  'graph',
@@ -71,22 +36,6 @@ const SUPPORTED_MD_BLOCK_KINDS = new Set<MdBlockKind>([
71
36
  'matrix',
72
37
  'table-editor'
73
38
  ]);
74
-
75
- export interface OmlRestServerOptions {
76
- host: string;
77
- port: number;
78
- workspaceRoot?: string;
79
- watchWorkspace?: boolean;
80
- requestTimeoutMs?: number;
81
- authToken?: string;
82
- runtime?: OmlLanguageServerRuntime;
83
- }
84
-
85
- interface WorkspaceModelFileEntry {
86
- path: string;
87
- uri: string;
88
- }
89
-
90
39
  const BUILT_IN_ONTOLOGIES = new Set([
91
40
  'http://www.w3.org/2001/XMLSchema',
92
41
  'http://www.w3.org/1999/02/22-rdf-syntax-ns',
@@ -95,37 +44,31 @@ const BUILT_IN_ONTOLOGIES = new Set([
95
44
  'http://www.w3.org/2003/11/swrl',
96
45
  'http://www.w3.org/2003/11/swrlb',
97
46
  ]);
98
-
99
-
100
- function jsonResponse(res: http.ServerResponse, status: number, payload: unknown): void {
47
+ function jsonResponse(res, status, payload) {
101
48
  const body = JSON.stringify(payload);
102
49
  res.statusCode = status;
103
50
  res.setHeader('content-type', JSON_CONTENT_TYPE);
104
51
  res.setHeader('content-length', Buffer.byteLength(body, 'utf-8'));
105
52
  res.end(body);
106
53
  }
107
-
108
- function htmlResponse(res: http.ServerResponse, status: number, body: string): void {
109
- res.statusCode = status;
110
- res.setHeader('content-type', HTML_CONTENT_TYPE);
111
- res.setHeader('content-length', Buffer.byteLength(body, 'utf-8'));
112
- res.end(body);
54
+ function htmlResponse(res, status, body) {
55
+ res.statusCode = status;
56
+ res.setHeader('content-type', HTML_CONTENT_TYPE);
57
+ res.setHeader('content-length', Buffer.byteLength(body, 'utf-8'));
58
+ res.end(body);
113
59
  }
114
-
115
- function escapeHtml(value: string): string {
116
- return value
117
- .replace(/&/g, '&amp;')
118
- .replace(/</g, '&lt;')
119
- .replace(/>/g, '&gt;')
120
- .replace(/"/g, '&quot;')
121
- .replace(/'/g, '&#39;');
60
+ function escapeHtml(value) {
61
+ return value
62
+ .replace(/&/g, '&amp;')
63
+ .replace(/</g, '&lt;')
64
+ .replace(/>/g, '&gt;')
65
+ .replace(/"/g, '&quot;')
66
+ .replace(/'/g, '&#39;');
122
67
  }
123
-
124
- async function listWorkspaceModelFiles(workspaceRoot: string): Promise<WorkspaceModelFileEntry[]> {
125
- const entries: WorkspaceModelFileEntry[] = [];
68
+ async function listWorkspaceModelFiles(workspaceRoot) {
69
+ const entries = [];
126
70
  const ignoredNames = new Set(['.git', 'node_modules', 'dist', 'build', 'out']);
127
-
128
- const visit = async (currentDir: string): Promise<void> => {
71
+ const visit = async (currentDir) => {
129
72
  const children = await fs.readdir(currentDir, { withFileTypes: true });
130
73
  for (const child of children) {
131
74
  const childPath = path.join(currentDir, child.name);
@@ -146,13 +89,11 @@ async function listWorkspaceModelFiles(workspaceRoot: string): Promise<Workspace
146
89
  });
147
90
  }
148
91
  };
149
-
150
92
  await visit(workspaceRoot);
151
93
  entries.sort((left, right) => left.path.localeCompare(right.path));
152
94
  return entries;
153
95
  }
154
-
155
- function createSparqlWorkbenchPage(defaultWorkspaceRoot: string): string {
96
+ function createSparqlWorkbenchPage(defaultWorkspaceRoot) {
156
97
  const escapedWorkspaceRoot = escapeHtml(defaultWorkspaceRoot);
157
98
  return `<!DOCTYPE html>
158
99
  <html lang="en">
@@ -991,9 +932,8 @@ LIMIT 25</textarea>
991
932
  </body>
992
933
  </html>`;
993
934
  }
994
-
995
- async function readJsonBody(req: http.IncomingMessage): Promise<Record<string, unknown>> {
996
- const chunks: Buffer[] = [];
935
+ async function readJsonBody(req) {
936
+ const chunks = [];
997
937
  let total = 0;
998
938
  for await (const chunk of req) {
999
939
  const buffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
@@ -1007,36 +947,30 @@ async function readJsonBody(req: http.IncomingMessage): Promise<Record<string, u
1007
947
  return {};
1008
948
  }
1009
949
  const parsed = JSON.parse(Buffer.concat(chunks).toString('utf-8'));
1010
- return typeof parsed === 'object' && parsed !== null ? parsed as Record<string, unknown> : {};
950
+ return typeof parsed === 'object' && parsed !== null ? parsed : {};
1011
951
  }
1012
-
1013
- function withTimeout<T>(promise: Promise<T>, timeoutMs: number, method: string): Promise<T> {
1014
- return new Promise<T>((resolve, reject) => {
952
+ function withTimeout(promise, timeoutMs, method) {
953
+ return new Promise((resolve, reject) => {
1015
954
  const timer = setTimeout(() => {
1016
955
  reject(new Error(`LSP request timeout for '${method}' after ${timeoutMs}ms.`));
1017
956
  }, timeoutMs);
1018
- void promise.then(
1019
- (value) => {
1020
- clearTimeout(timer);
1021
- resolve(value);
1022
- },
1023
- (error: unknown) => {
1024
- clearTimeout(timer);
1025
- reject(error);
1026
- },
1027
- );
957
+ void promise.then((value) => {
958
+ clearTimeout(timer);
959
+ resolve(value);
960
+ }, (error) => {
961
+ clearTimeout(timer);
962
+ reject(error);
963
+ });
1028
964
  });
1029
965
  }
1030
-
1031
- function normalizeOntologyNamespace(value: string | undefined): string | undefined {
966
+ function normalizeOntologyNamespace(value) {
1032
967
  if (!value) {
1033
968
  return undefined;
1034
969
  }
1035
970
  const normalized = value.replace(/^<|>$/g, '').replace(/[\/#]+$/, '');
1036
971
  return normalized.length > 0 ? normalized : undefined;
1037
972
  }
1038
-
1039
- function resolveOutputPathFromOntologyIriString(ontologyIri: string, format: 'ttl' | 'trig' | 'nt' | 'nq' | 'n3'): string {
973
+ function resolveOutputPathFromOntologyIriString(ontologyIri, format) {
1040
974
  const iri = new URL(ontologyIri);
1041
975
  const rawPath = iri.pathname.replace(/\/+$/, '');
1042
976
  const pathSegments = rawPath.split('/').filter(Boolean);
@@ -1046,12 +980,7 @@ function resolveOutputPathFromOntologyIriString(ontologyIri: string, format: 'tt
1046
980
  : pathSegments.slice(0, -1);
1047
981
  return path.join(...directorySegments, `${fileStem}.${format}`);
1048
982
  }
1049
-
1050
- async function serializeQuads(
1051
- quads: any[],
1052
- format: 'ttl' | 'trig' | 'nt' | 'nq' | 'n3',
1053
- pretty = false,
1054
- ): Promise<string> {
983
+ async function serializeQuads(quads, format, pretty = false) {
1055
984
  const writer = new Writer({
1056
985
  format: format === 'ttl'
1057
986
  ? 'text/turtle'
@@ -1062,7 +991,7 @@ async function serializeQuads(
1062
991
  : (format === 'nq' ? 'N-Quads' : 'application/n3'))),
1063
992
  });
1064
993
  writer.addQuads(quads);
1065
- const serialized = await new Promise<string>((resolve, reject) => {
994
+ const serialized = await new Promise((resolve, reject) => {
1066
995
  writer.end((error, result) => {
1067
996
  if (error) {
1068
997
  reject(error);
@@ -1073,13 +1002,12 @@ async function serializeQuads(
1073
1002
  });
1074
1003
  return pretty ? prettyPrintRdf(serialized, format) : serialized;
1075
1004
  }
1076
-
1077
- function prettyPrintRdf(serialized: string, format: 'ttl' | 'trig' | 'nt' | 'nq' | 'n3'): string {
1005
+ function prettyPrintRdf(serialized, format) {
1078
1006
  if (format !== 'ttl' && format !== 'trig') {
1079
1007
  return serialized;
1080
1008
  }
1081
1009
  const lines = serialized.split('\n');
1082
- const out: string[] = [];
1010
+ const out = [];
1083
1011
  for (let i = 0; i < lines.length; i += 1) {
1084
1012
  const line = lines[i];
1085
1013
  out.push(line);
@@ -1092,19 +1020,8 @@ function prettyPrintRdf(serialized: string, format: 'ttl' | 'trig' | 'nt' | 'nq'
1092
1020
  }
1093
1021
  return out.join('\n');
1094
1022
  }
1095
-
1096
- function toSparqlRowDto(row: Map<string, any>): Record<string, {
1097
- termType: 'NamedNode' | 'Literal' | 'BlankNode';
1098
- value: string;
1099
- datatype?: string;
1100
- language?: string;
1101
- }> {
1102
- const result: Record<string, {
1103
- termType: 'NamedNode' | 'Literal' | 'BlankNode';
1104
- value: string;
1105
- datatype?: string;
1106
- language?: string;
1107
- }> = {};
1023
+ function toSparqlRowDto(row) {
1024
+ const result = {};
1108
1025
  for (const [key, term] of row.entries()) {
1109
1026
  if (!term) {
1110
1027
  continue;
@@ -1118,29 +1035,14 @@ function toSparqlRowDto(row: Map<string, any>): Record<string, {
1118
1035
  }
1119
1036
  return result;
1120
1037
  }
1121
-
1122
- function isRecord(value: unknown): value is Record<string, unknown> {
1038
+ function isRecord(value) {
1123
1039
  return typeof value === 'object' && value !== null && !Array.isArray(value);
1124
1040
  }
1125
-
1126
- type RenderedBlockResult = MdBlockExecutionResult & {
1127
- options?: Record<string, unknown>;
1128
- };
1129
-
1130
- function toMdBlockKind(language: string): MdBlockKind | undefined {
1131
- return SUPPORTED_MD_BLOCK_KINDS.has(language as MdBlockKind) ? (language as MdBlockKind) : undefined;
1041
+ function toMdBlockKind(language) {
1042
+ return SUPPORTED_MD_BLOCK_KINDS.has(language) ? language : undefined;
1132
1043
  }
1133
-
1134
- function toExecutableBlocks(codeBlocks: ReadonlyArray<{
1135
- id: string;
1136
- language: string;
1137
- content: string;
1138
- meta?: string;
1139
- options?: Record<string, unknown>;
1140
- lineStart: number;
1141
- lineEnd: number;
1142
- }>): MdExecutableBlock[] {
1143
- const executable: MdExecutableBlock[] = [];
1044
+ function toExecutableBlocks(codeBlocks) {
1045
+ const executable = [];
1144
1046
  for (const block of codeBlocks) {
1145
1047
  const kind = toMdBlockKind(block.language);
1146
1048
  if (!kind) {
@@ -1158,8 +1060,7 @@ function toExecutableBlocks(codeBlocks: ReadonlyArray<{
1158
1060
  }
1159
1061
  return executable;
1160
1062
  }
1161
-
1162
- function splitHref(href: string): { path: string; query: string; fragment: string } {
1063
+ function splitHref(href) {
1163
1064
  const hashIndex = href.indexOf('#');
1164
1065
  const pathAndQuery = hashIndex >= 0 ? href.slice(0, hashIndex) : href;
1165
1066
  const fragment = hashIndex >= 0 ? href.slice(hashIndex) : '';
@@ -1170,8 +1071,7 @@ function splitHref(href: string): { path: string; query: string; fragment: strin
1170
1071
  fragment
1171
1072
  };
1172
1073
  }
1173
-
1174
- function resolveWorkspacePath(workspaceRoot: string, hrefPath: string): string | undefined {
1074
+ function resolveWorkspacePath(workspaceRoot, hrefPath) {
1175
1075
  const relative = hrefPath.slice('workspace:/'.length).replace(/^\/+/, '');
1176
1076
  const resolved = path.resolve(workspaceRoot, relative);
1177
1077
  const relativeToWorkspace = path.relative(workspaceRoot, resolved);
@@ -1180,27 +1080,17 @@ function resolveWorkspacePath(workspaceRoot: string, hrefPath: string): string |
1180
1080
  }
1181
1081
  return resolved;
1182
1082
  }
1183
-
1184
- function toRelativeWebPath(fromDir: string, toFile: string): string {
1083
+ function toRelativeWebPath(fromDir, toFile) {
1185
1084
  const relative = path.relative(fromDir, toFile).split(path.sep).join('/');
1186
1085
  if (!relative || relative === '.') {
1187
1086
  return '.';
1188
1087
  }
1189
1088
  return relative.startsWith('.') ? relative : `./${relative}`;
1190
1089
  }
1191
-
1192
- function isImagePath(filePath: string): boolean {
1090
+ function isImagePath(filePath) {
1193
1091
  return /\.(png|jpe?g|gif|svg|webp|bmp|ico|avif)$/i.test(filePath);
1194
1092
  }
1195
-
1196
- function resolveAssetTargetPath(
1197
- resolvedFile: string,
1198
- context: {
1199
- workspaceRoot: string;
1200
- inputRoot: string;
1201
- outputRoot: string;
1202
- }
1203
- ): string {
1093
+ function resolveAssetTargetPath(resolvedFile, context) {
1204
1094
  const workspaceRelative = path.relative(context.workspaceRoot, resolvedFile);
1205
1095
  const markdownRelative = path.relative(context.inputRoot, resolvedFile);
1206
1096
  const isInsideMarkdownRoot = !markdownRelative.startsWith('..') && !path.isAbsolute(markdownRelative);
@@ -1211,18 +1101,7 @@ function resolveAssetTargetPath(
1211
1101
  const outputRelative = isInsideMarkdownRoot ? markdownRelative : workspaceRelative;
1212
1102
  return path.join(context.outputRoot, outputRelative);
1213
1103
  }
1214
-
1215
- function rewriteHref(
1216
- href: string,
1217
- context: {
1218
- workspaceRoot: string;
1219
- inputRoot: string;
1220
- inputFile: string;
1221
- outputRoot: string;
1222
- outputFile: string;
1223
- },
1224
- workspaceAssets: Set<string>
1225
- ): string {
1104
+ function rewriteHref(href, context, workspaceAssets) {
1226
1105
  const parts = splitHref(href);
1227
1106
  if (!parts.path) {
1228
1107
  return href;
@@ -1240,10 +1119,7 @@ function rewriteHref(
1240
1119
  workspaceAssets.add(resolved);
1241
1120
  }
1242
1121
  const targetInOutput = resolved.toLowerCase().endsWith('.md')
1243
- ? path.join(
1244
- context.outputRoot,
1245
- path.relative(context.inputRoot, resolved).replace(/\.md$/i, '.html')
1246
- )
1122
+ ? path.join(context.outputRoot, path.relative(context.inputRoot, resolved).replace(/\.md$/i, '.html'))
1247
1123
  : resolveAssetTargetPath(resolved, context);
1248
1124
  const rewrittenPath = toRelativeWebPath(path.dirname(context.outputFile), targetInOutput);
1249
1125
  return `${rewrittenPath}${parts.query}${parts.fragment}`;
@@ -1259,10 +1135,7 @@ function rewriteHref(
1259
1135
  workspaceAssets.add(resolved);
1260
1136
  }
1261
1137
  const targetInOutput = resolved.toLowerCase().endsWith('.md')
1262
- ? path.join(
1263
- context.outputRoot,
1264
- path.relative(context.inputRoot, resolved).replace(/\.md$/i, '.html')
1265
- )
1138
+ ? path.join(context.outputRoot, path.relative(context.inputRoot, resolved).replace(/\.md$/i, '.html'))
1266
1139
  : resolveAssetTargetPath(resolved, context);
1267
1140
  const rewrittenPath = toRelativeWebPath(path.dirname(context.outputFile), targetInOutput);
1268
1141
  return `${rewrittenPath}${parts.query}${parts.fragment}`;
@@ -1273,38 +1146,15 @@ function rewriteHref(
1273
1146
  : trimmedPath;
1274
1147
  return `${rewrittenPath}${parts.query}${parts.fragment}`;
1275
1148
  }
1276
-
1277
- function rewriteRenderedLinks(
1278
- content: string,
1279
- context: {
1280
- workspaceRoot: string;
1281
- inputRoot: string;
1282
- inputFile: string;
1283
- outputRoot: string;
1284
- outputFile: string;
1285
- }
1286
- ): {
1287
- html: string;
1288
- workspaceAssets: Set<string>;
1289
- } {
1290
- const workspaceAssets = new Set<string>();
1291
- const html = content.replace(/(\b(?:href|src)\s*=\s*)(["'])([^"']+)\2/gi, (_match, prefix: string, quote: string, rawHref: string) => {
1149
+ function rewriteRenderedLinks(content, context) {
1150
+ const workspaceAssets = new Set();
1151
+ const html = content.replace(/(\b(?:href|src)\s*=\s*)(["'])([^"']+)\2/gi, (_match, prefix, quote, rawHref) => {
1292
1152
  const rewritten = rewriteHref(rawHref, context, workspaceAssets);
1293
1153
  return `${prefix}${quote}${rewritten}${quote}`;
1294
1154
  });
1295
1155
  return { html, workspaceAssets };
1296
1156
  }
1297
-
1298
- function rewriteAssetReference(
1299
- rawValue: string,
1300
- context: {
1301
- workspaceRoot: string;
1302
- inputRoot: string;
1303
- sourceFile: string;
1304
- outputRoot: string;
1305
- outputFile: string;
1306
- }
1307
- ): { rewritten: string; sourceAsset?: string } {
1157
+ function rewriteAssetReference(rawValue, context) {
1308
1158
  const trimmed = rawValue.trim();
1309
1159
  if (!trimmed || trimmed.startsWith('#') || trimmed.startsWith('data:') || trimmed.startsWith('//')) {
1310
1160
  return { rewritten: rawValue };
@@ -1312,16 +1162,18 @@ function rewriteAssetReference(
1312
1162
  if (/^[a-z][a-z0-9+.-]*:/i.test(trimmed) && !trimmed.startsWith('workspace:/')) {
1313
1163
  return { rewritten: rawValue };
1314
1164
  }
1315
- let resolved: string | undefined;
1165
+ let resolved;
1316
1166
  if (trimmed.startsWith('workspace:/')) {
1317
1167
  resolved = resolveWorkspacePath(context.workspaceRoot, trimmed);
1318
- } else if (trimmed.startsWith('/')) {
1168
+ }
1169
+ else if (trimmed.startsWith('/')) {
1319
1170
  const candidate = path.resolve(context.workspaceRoot, trimmed.replace(/^\/+/, ''));
1320
1171
  const relative = path.relative(context.workspaceRoot, candidate);
1321
1172
  if (!relative.startsWith('..') && !path.isAbsolute(relative)) {
1322
1173
  resolved = candidate;
1323
1174
  }
1324
- } else {
1175
+ }
1176
+ else {
1325
1177
  const candidate = path.resolve(path.dirname(context.sourceFile), trimmed);
1326
1178
  const relative = path.relative(context.workspaceRoot, candidate);
1327
1179
  if (!relative.startsWith('..') && !path.isAbsolute(relative)) {
@@ -1341,18 +1193,7 @@ function rewriteAssetReference(
1341
1193
  sourceAsset: resolved,
1342
1194
  };
1343
1195
  }
1344
-
1345
- function rewriteBlockResultAssetPaths(
1346
- result: RenderedBlockResult,
1347
- context: {
1348
- workspaceRoot: string;
1349
- inputRoot: string;
1350
- sourceFile: string;
1351
- outputRoot: string;
1352
- outputFile: string;
1353
- },
1354
- workspaceAssets: Set<string>,
1355
- ): RenderedBlockResult {
1196
+ function rewriteBlockResultAssetPaths(result, context, workspaceAssets) {
1356
1197
  if (!result.options || result.kind !== 'diagram') {
1357
1198
  return result;
1358
1199
  }
@@ -1366,7 +1207,7 @@ function rewriteBlockResultAssetPaths(
1366
1207
  return entry;
1367
1208
  }
1368
1209
  let entryChanged = false;
1369
- const icon = { ...entry.style.icon } as Record<string, unknown>;
1210
+ const icon = { ...entry.style.icon };
1370
1211
  for (const key of ['href', 'xlinkHref', 'xlink:href']) {
1371
1212
  const value = icon[key];
1372
1213
  if (typeof value !== 'string') {
@@ -1404,26 +1245,21 @@ function rewriteBlockResultAssetPaths(
1404
1245
  },
1405
1246
  };
1406
1247
  }
1407
-
1408
- function sanitizeBlockId(value: string): string {
1248
+ function sanitizeBlockId(value) {
1409
1249
  const trimmed = value.trim();
1410
1250
  if (!trimmed) {
1411
1251
  return 'block';
1412
1252
  }
1413
1253
  return trimmed.replace(/[^a-zA-Z0-9._-]/g, '_');
1414
1254
  }
1415
-
1416
- async function writeBlockArtifacts(outputFile: string, results: ReadonlyArray<RenderedBlockResult>): Promise<{
1417
- count: number;
1418
- manifest: Array<{ blockId: string; path: string }>;
1419
- }> {
1255
+ async function writeBlockArtifacts(outputFile, results) {
1420
1256
  if (results.length === 0) {
1421
1257
  return { count: 0, manifest: [] };
1422
1258
  }
1423
1259
  const blockDirName = `${path.basename(outputFile, '.html')}.blocks`;
1424
1260
  const blockDir = path.join(path.dirname(outputFile), blockDirName);
1425
1261
  await fs.mkdir(blockDir, { recursive: true });
1426
- const manifest: Array<{ blockId: string; path: string }> = [];
1262
+ const manifest = [];
1427
1263
  for (const result of results) {
1428
1264
  const safeId = sanitizeBlockId(result.blockId);
1429
1265
  const fileName = `${safeId}.json`;
@@ -1436,33 +1272,29 @@ async function writeBlockArtifacts(outputFile: string, results: ReadonlyArray<Re
1436
1272
  }
1437
1273
  return { count: results.length, manifest };
1438
1274
  }
1439
-
1440
- async function loadStaticRuntimeBundle(): Promise<string> {
1275
+ async function loadStaticRuntimeBundle() {
1441
1276
  const require = createRequire(import.meta.url);
1442
1277
  const staticEntry = require.resolve('@oml/markdown/static');
1443
1278
  const bundlePath = path.join(path.dirname(staticEntry), STATIC_MARKDOWN_RUNTIME_BUNDLE_FILE);
1444
1279
  try {
1445
1280
  return await fs.readFile(bundlePath, 'utf-8');
1446
- } catch {
1281
+ }
1282
+ catch {
1447
1283
  throw new Error(`Unable to load markdown static runtime bundle at '${bundlePath}'.`);
1448
1284
  }
1449
1285
  }
1450
-
1451
- async function loadCodeBlockStylesheet(): Promise<string> {
1286
+ async function loadCodeBlockStylesheet() {
1452
1287
  const require = createRequire(import.meta.url);
1453
1288
  const staticEntry = require.resolve('@oml/markdown/static');
1454
1289
  const stylesheetPath = path.resolve(path.dirname(staticEntry), '..', '..', 'src', 'static', 'markdown-webview.css');
1455
1290
  try {
1456
1291
  return await fs.readFile(stylesheetPath, 'utf-8');
1457
- } catch {
1292
+ }
1293
+ catch {
1458
1294
  throw new Error(`Unable to load markdown webview stylesheet at '${stylesheetPath}'.`);
1459
1295
  }
1460
1296
  }
1461
-
1462
- async function writeStaticAssets(outputRoot: string): Promise<{
1463
- runtimeScriptFile: string;
1464
- stylesheetFile: string;
1465
- }> {
1297
+ async function writeStaticAssets(outputRoot) {
1466
1298
  const runtimeBundle = await loadStaticRuntimeBundle();
1467
1299
  const sourceStylesheet = await loadCodeBlockStylesheet();
1468
1300
  const mergedStylesheet = `${sourceStylesheet}\n\n${STATIC_MARKDOWN_RUNTIME_CSS}\n`;
@@ -1475,8 +1307,7 @@ async function writeStaticAssets(outputRoot: string): Promise<{
1475
1307
  await fs.writeFile(stylesheetFile, mergedStylesheet, 'utf-8');
1476
1308
  return { runtimeScriptFile: runtimeFile, stylesheetFile };
1477
1309
  }
1478
-
1479
- function escapeAttribute(value: string): string {
1310
+ function escapeAttribute(value) {
1480
1311
  return value
1481
1312
  .replace(/&/g, '&amp;')
1482
1313
  .replace(/</g, '&lt;')
@@ -1484,12 +1315,10 @@ function escapeAttribute(value: string): string {
1484
1315
  .replace(/"/g, '&quot;')
1485
1316
  .replace(/'/g, '&#39;');
1486
1317
  }
1487
-
1488
- function escapeJsonForScript(value: string): string {
1318
+ function escapeJsonForScript(value) {
1489
1319
  return value.replace(/</g, '\\u003c');
1490
1320
  }
1491
-
1492
- function normalizeWikiPathKey(raw: string): string {
1321
+ function normalizeWikiPathKey(raw) {
1493
1322
  const normalized = raw.replace(/\\/g, '/').replace(/^\/+/, '').replace(/\/+/g, '/');
1494
1323
  if (!normalized) {
1495
1324
  return '';
@@ -1497,9 +1326,8 @@ function normalizeWikiPathKey(raw: string): string {
1497
1326
  const withoutHtml = normalized.replace(/\.html$/i, '');
1498
1327
  return withoutHtml.replace(/^\.\//, '').toLowerCase();
1499
1328
  }
1500
-
1501
- function buildWikiPageIndex(markdownFiles: ReadonlyArray<string>, inputRoot: string, outputRoot: string): Map<string, string> {
1502
- const index = new Map<string, string>();
1329
+ function buildWikiPageIndex(markdownFiles, inputRoot, outputRoot) {
1330
+ const index = new Map();
1503
1331
  for (const markdownFile of markdownFiles) {
1504
1332
  const relativeInput = path.relative(inputRoot, markdownFile).split(path.sep).join('/');
1505
1333
  const normalizedRelative = normalizeWikiPathKey(relativeInput.replace(/\.md$/i, ''));
@@ -1511,23 +1339,17 @@ function buildWikiPageIndex(markdownFiles: ReadonlyArray<string>, inputRoot: str
1511
1339
  }
1512
1340
  return index;
1513
1341
  }
1514
-
1515
- function buildWikiLinkHrefMapForPage(
1516
- wikiPageIndex: ReadonlyMap<string, string>,
1517
- outputFile: string
1518
- ): Record<string, string> {
1519
- const map: Record<string, string> = {};
1342
+ function buildWikiLinkHrefMapForPage(wikiPageIndex, outputFile) {
1343
+ const map = {};
1520
1344
  for (const [key, targetFile] of wikiPageIndex.entries()) {
1521
1345
  map[key] = toRelativeWebPath(path.dirname(outputFile), targetFile);
1522
1346
  }
1523
1347
  return map;
1524
1348
  }
1525
-
1526
- function normalizeIri(value: string): string {
1349
+ function normalizeIri(value) {
1527
1350
  return value.trim().replace(/^<|>$/g, '');
1528
1351
  }
1529
-
1530
- function inferOntologyIriFromMemberIri(memberIri: string): string | undefined {
1352
+ function inferOntologyIriFromMemberIri(memberIri) {
1531
1353
  const normalized = normalizeIri(memberIri);
1532
1354
  if (!normalized) {
1533
1355
  return undefined;
@@ -1543,13 +1365,13 @@ function inferOntologyIriFromMemberIri(memberIri: string): string | undefined {
1543
1365
  }
1544
1366
  return normalized.replace(/[\/#]+$/, '');
1545
1367
  }
1546
-
1547
- function memberIriToOutputFile(outputRoot: string, memberIri: string): string | undefined {
1368
+ function memberIriToOutputFile(outputRoot, memberIri) {
1548
1369
  const normalized = normalizeIri(memberIri);
1549
- let parsed: URL;
1370
+ let parsed;
1550
1371
  try {
1551
1372
  parsed = new URL(normalized);
1552
- } catch {
1373
+ }
1374
+ catch {
1553
1375
  return undefined;
1554
1376
  }
1555
1377
  const host = (parsed.hostname || '').trim().toLowerCase();
@@ -1569,11 +1391,7 @@ function memberIriToOutputFile(outputRoot: string, memberIri: string): string |
1569
1391
  : pathname.split('/').slice(0, -1).join('/');
1570
1392
  return path.join(outputRoot, host, basePath, `${safeMember}.html`);
1571
1393
  }
1572
-
1573
- async function queryMemberTypes(
1574
- reasoningService: any,
1575
- modelUri: string,
1576
- ): Promise<Map<string, string[]>> {
1394
+ async function queryMemberTypes(reasoningService, modelUri) {
1577
1395
  const queryResult = await reasoningService.getSparqlService().query(modelUri, `
1578
1396
  PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
1579
1397
  SELECT DISTINCT ?member ?type
@@ -1585,44 +1403,29 @@ async function queryMemberTypes(
1585
1403
  }
1586
1404
  `);
1587
1405
  if (!queryResult?.success || !Array.isArray(queryResult.rows)) {
1588
- return new Map<string, string[]>();
1406
+ return new Map();
1589
1407
  }
1590
- const byMember = new Map<string, Set<string>>();
1591
- for (const row of queryResult.rows as Array<Map<string, { value: string } | undefined>>) {
1408
+ const byMember = new Map();
1409
+ for (const row of queryResult.rows) {
1592
1410
  const member = normalizeIri(row.get('member')?.value ?? '');
1593
1411
  const type = normalizeIri(row.get('type')?.value ?? '');
1594
1412
  if (!member || !type) {
1595
1413
  continue;
1596
1414
  }
1597
- const existing = byMember.get(member) ?? new Set<string>();
1415
+ const existing = byMember.get(member) ?? new Set();
1598
1416
  existing.add(type);
1599
1417
  byMember.set(member, existing);
1600
1418
  }
1601
- return new Map<string, string[]>(
1602
- Array.from(byMember.entries()).map(([member, types]) => [member, Array.from(types)])
1603
- );
1419
+ return new Map(Array.from(byMember.entries()).map(([member, types]) => [member, Array.from(types)]));
1604
1420
  }
1605
-
1606
- function buildIriAliasMapForPage(
1607
- aliasesByIri: ReadonlyMap<string, string>,
1608
- outputFile: string
1609
- ): Record<string, string> {
1610
- const aliases: Record<string, string> = {};
1421
+ function buildIriAliasMapForPage(aliasesByIri, outputFile) {
1422
+ const aliases = {};
1611
1423
  for (const [iri, absoluteTarget] of aliasesByIri.entries()) {
1612
1424
  aliases[iri] = toRelativeWebPath(path.dirname(outputFile), absoluteTarget);
1613
1425
  }
1614
1426
  return aliases;
1615
1427
  }
1616
-
1617
- function wrapHtml(
1618
- content: string,
1619
- runtimeScriptPath: string,
1620
- stylesheetPath: string,
1621
- blockManifest: Array<{ blockId: string; path: string }>,
1622
- blockResults: ReadonlyArray<RenderedBlockResult>,
1623
- wikiLinkHrefByKey: Record<string, string>,
1624
- iriAliasByIri: Record<string, string>,
1625
- ): string {
1428
+ function wrapHtml(content, runtimeScriptPath, stylesheetPath, blockManifest, blockResults, wikiLinkHrefByKey, iriAliasByIri) {
1626
1429
  const escapedManifest = escapeJsonForScript(JSON.stringify(blockManifest));
1627
1430
  const inlineResults = Object.fromEntries(blockResults.map((result) => [result.blockId, result]));
1628
1431
  const escapedInlineResults = escapeJsonForScript(JSON.stringify(inlineResults));
@@ -1650,33 +1453,21 @@ ${content}
1650
1453
  </html>
1651
1454
  `;
1652
1455
  }
1653
-
1654
1456
  class InMemoryJsonRpcLspClient {
1655
- private readonly workspaceRoot: string;
1656
- private readonly requestTimeoutMs: number;
1657
- private readonly clientConnection?: Connection;
1658
- private readonly serverConnection?: Connection;
1659
- private readonly clientToServer?: PassThrough;
1660
- private readonly serverToClient?: PassThrough;
1661
- private initPromise?: Promise<void>;
1662
- private readonly runtime: OmlLanguageServerRuntime;
1663
- private readonly useExternalRuntime: boolean;
1664
- private readonly watchWorkspace: boolean;
1665
- private readonly watchers: Set<fsSync.FSWatcher> = new Set();
1666
- private watcherFlushTimer: NodeJS.Timeout | undefined;
1667
- private watcherActive = false;
1668
- private refreshInFlight = false;
1669
- private refreshQueued = false;
1670
- private initialWorkspaceSyncCompleted = false;
1671
-
1672
- constructor(workspaceRoot: string, requestTimeoutMs: number, watchWorkspace: boolean, runtime?: OmlLanguageServerRuntime) {
1457
+ constructor(workspaceRoot, requestTimeoutMs, watchWorkspace, runtime) {
1458
+ this.watchers = new Set();
1459
+ this.watcherActive = false;
1460
+ this.refreshInFlight = false;
1461
+ this.refreshQueued = false;
1462
+ this.initialWorkspaceSyncCompleted = false;
1673
1463
  this.workspaceRoot = workspaceRoot;
1674
1464
  this.requestTimeoutMs = requestTimeoutMs;
1675
1465
  this.useExternalRuntime = runtime !== undefined;
1676
1466
  this.watchWorkspace = runtime ? false : watchWorkspace;
1677
1467
  if (runtime) {
1678
1468
  this.runtime = runtime;
1679
- } else {
1469
+ }
1470
+ else {
1680
1471
  this.clientToServer = new PassThrough();
1681
1472
  this.serverToClient = new PassThrough();
1682
1473
  this.serverConnection = createConnection(this.clientToServer, this.serverToClient);
@@ -1693,20 +1484,18 @@ class InMemoryJsonRpcLspClient {
1693
1484
  this.startWorkspaceWatcher();
1694
1485
  }
1695
1486
  }
1696
-
1697
- private getWorkspaceOmlDocuments(): any[] {
1487
+ getWorkspaceOmlDocuments() {
1698
1488
  const documents = this.runtime.shared.workspace.LangiumDocuments;
1699
1489
  const allDocs = documents.all ?? [];
1700
- const iterable: any[] = Array.isArray(allDocs)
1490
+ const iterable = Array.isArray(allDocs)
1701
1491
  ? allDocs
1702
- : (typeof allDocs?.toArray === 'function' ? allDocs.toArray() : Array.from(allDocs as Iterable<any>));
1492
+ : (typeof allDocs?.toArray === 'function' ? allDocs.toArray() : Array.from(allDocs));
1703
1493
  return iterable
1704
1494
  .filter((doc) => String(doc?.uri ?? '').trim().toLowerCase().endsWith('.oml'))
1705
1495
  .sort((left, right) => String(left?.uri ?? '').localeCompare(String(right?.uri ?? '')));
1706
1496
  }
1707
-
1708
- async lintWorkspace(params: Record<string, unknown> = {}): Promise<RestLintResult> {
1709
- const context: RestValidationContext = {
1497
+ async lintWorkspace(params = {}) {
1498
+ const context = {
1710
1499
  workspaceRoot: this.workspaceRoot,
1711
1500
  runtime: this.runtime,
1712
1501
  ensureInitialized: () => this.ensureInitialized(),
@@ -1716,8 +1505,7 @@ class InMemoryJsonRpcLspClient {
1716
1505
  };
1717
1506
  return await lintWorkspace(context, params);
1718
1507
  }
1719
-
1720
- async queryWorkspace(params: Record<string, unknown>): Promise<Record<string, unknown>> {
1508
+ async queryWorkspace(params) {
1721
1509
  await this.ensureInitialized();
1722
1510
  await this.ensureWorkspaceCurrent();
1723
1511
  const modelUri = typeof params.modelUri === 'string' ? params.modelUri.trim() : '';
@@ -1731,7 +1519,7 @@ class InMemoryJsonRpcLspClient {
1731
1519
  };
1732
1520
  }
1733
1521
  try {
1734
- const reasoningService = this.runtime.Oml.reasoning.ReasoningService as any;
1522
+ const reasoningService = this.runtime.Oml.reasoning.ReasoningService;
1735
1523
  const kind = detectSparqlKind(sparql);
1736
1524
  await reasoningService.ensureQueryContext(modelUri);
1737
1525
  const sparqlService = reasoningService.getSparqlService();
@@ -1741,7 +1529,7 @@ class InMemoryJsonRpcLspClient {
1741
1529
  success: result.success,
1742
1530
  kind,
1743
1531
  warnings: result.warnings ?? [],
1744
- rows: result.rows.map((row: Map<string, any>) => toSparqlRowDto(row)),
1532
+ rows: result.rows.map((row) => toSparqlRowDto(row)),
1745
1533
  error: result.error,
1746
1534
  };
1747
1535
  }
@@ -1761,7 +1549,7 @@ class InMemoryJsonRpcLspClient {
1761
1549
  success: result.success,
1762
1550
  kind,
1763
1551
  warnings: result.warnings ?? [],
1764
- quads: result.quads.map((quad: any) => ({
1552
+ quads: result.quads.map((quad) => ({
1765
1553
  subject: quad.subject.value,
1766
1554
  predicate: quad.predicate.value,
1767
1555
  object: quad.object.value,
@@ -1776,7 +1564,8 @@ class InMemoryJsonRpcLspClient {
1776
1564
  warnings: [],
1777
1565
  error: 'Unsupported or unknown SPARQL query kind.',
1778
1566
  };
1779
- } catch (error) {
1567
+ }
1568
+ catch (error) {
1780
1569
  return {
1781
1570
  success: false,
1782
1571
  kind: detectSparqlKind(sparql),
@@ -1785,18 +1574,12 @@ class InMemoryJsonRpcLspClient {
1785
1574
  };
1786
1575
  }
1787
1576
  }
1788
-
1789
- async updateWorkspace(params: Record<string, unknown>): Promise<OmlEditResponse> {
1577
+ async updateWorkspace(params) {
1790
1578
  await this.ensureInitialized();
1791
1579
  await this.ensureWorkspaceCurrent();
1792
- return await applyOmlUpdate(
1793
- this.runtime.shared,
1794
- params as OmlEditRequest,
1795
- (message) => this.logError(message),
1796
- );
1580
+ return await applyOmlUpdate(this.runtime.shared, params, (message) => this.logError(message));
1797
1581
  }
1798
-
1799
- async fuzzySearchWorkspace(params: Record<string, unknown>): Promise<Record<string, unknown>> {
1582
+ async fuzzySearchWorkspace(params) {
1800
1583
  await this.ensureInitialized();
1801
1584
  await this.ensureWorkspaceCurrent();
1802
1585
  try {
@@ -1805,14 +1588,14 @@ class InMemoryJsonRpcLspClient {
1805
1588
  return { success: true, candidates: [] };
1806
1589
  }
1807
1590
  const limit = Math.max(1, Math.min(50, typeof params.limit === 'number' ? params.limit : 12));
1808
- const ontologyIndex = getOntologyModelIndex(this.runtime.shared as any);
1809
- const langiumDocuments: any = this.runtime.shared.workspace.LangiumDocuments;
1591
+ const ontologyIndex = getOntologyModelIndex(this.runtime.shared);
1592
+ const langiumDocuments = this.runtime.shared.workspace.LangiumDocuments;
1810
1593
  const allDocs = langiumDocuments.all ?? [];
1811
- const iterable: any[] = Array.isArray(allDocs)
1594
+ const iterable = Array.isArray(allDocs)
1812
1595
  ? allDocs
1813
- : (typeof allDocs?.toArray === 'function' ? allDocs.toArray() : Array.from(allDocs as Iterable<any>));
1814
- const modelUris: string[] = [];
1815
- const candidateByIri = new Map<string, { iri: string; label?: string }>();
1596
+ : (typeof allDocs?.toArray === 'function' ? allDocs.toArray() : Array.from(allDocs));
1597
+ const modelUris = [];
1598
+ const candidateByIri = new Map();
1816
1599
  for (const doc of iterable) {
1817
1600
  const root = doc?.parseResult?.value;
1818
1601
  if (!root || !isOntology(root) || (!isVocabulary(root) && !isDescription(root))) {
@@ -1833,8 +1616,7 @@ class InMemoryJsonRpcLspClient {
1833
1616
  entry.label = label;
1834
1617
  candidateByIri.set(iri, entry);
1835
1618
  }
1836
-
1837
- const indexedEntries: OmlFuzzyIndexedEntry[] = [...candidateByIri.values()].map((entry) => ({
1619
+ const indexedEntries = [...candidateByIri.values()].map((entry) => ({
1838
1620
  iri: entry.iri,
1839
1621
  label: entry.label,
1840
1622
  fragment: iriFragment(entry.iri),
@@ -1850,11 +1632,11 @@ class InMemoryJsonRpcLspClient {
1850
1632
  const info = uf.info(filtered, haystack, text);
1851
1633
  const order = info ? uf.sort(info, haystack, text) : null;
1852
1634
  const ranked = (order ?? filtered.map((_, index) => index))
1853
- .map((index) => filtered[index]!)
1635
+ .map((index) => filtered[index])
1854
1636
  .slice(0, limit);
1855
1637
  const queryTokens = tokenizeForFuzzy(text).slice(0, 6);
1856
1638
  const candidates = ranked.map((entryIndex, index) => {
1857
- const entry = indexedEntries[entryIndex]!;
1639
+ const entry = indexedEntries[entryIndex];
1858
1640
  const fragment = entry.fragment.toLowerCase();
1859
1641
  const lowerLabel = (entry.label ?? '').toLowerCase();
1860
1642
  const lowerInput = text.toLowerCase();
@@ -1887,7 +1669,8 @@ class InMemoryJsonRpcLspClient {
1887
1669
  };
1888
1670
  });
1889
1671
  return { success: true, candidates };
1890
- } catch (error) {
1672
+ }
1673
+ catch (error) {
1891
1674
  return {
1892
1675
  success: false,
1893
1676
  candidates: [],
@@ -1895,26 +1678,21 @@ class InMemoryJsonRpcLspClient {
1895
1678
  };
1896
1679
  }
1897
1680
  }
1898
-
1899
- private async writeWorkspaceAssertedOwl(
1900
- outputDir: string,
1901
- format: 'ttl' | 'trig' | 'nt' | 'nq' | 'n3',
1902
- pretty: boolean,
1903
- ): Promise<Array<{ modelUri: string; ontologyIri: string; owlPath: string }>> {
1904
- const entries: Array<{ modelUri: string; ontologyIri: string; owlPath: string }> = [];
1681
+ async writeWorkspaceAssertedOwl(outputDir, format, pretty) {
1682
+ const entries = [];
1905
1683
  const docs = this.getWorkspaceOmlDocuments();
1906
- const reasoningService = this.runtime.Oml.reasoning.ReasoningService as any;
1684
+ const reasoningService = this.runtime.Oml.reasoning.ReasoningService;
1907
1685
  const store = reasoningService.getStore().getStore();
1908
1686
  for (const doc of docs) {
1909
1687
  const modelUri = String(doc?.uri ?? '').trim();
1910
- const root = doc?.parseResult?.value as { namespace?: string } | undefined;
1688
+ const root = doc?.parseResult?.value;
1911
1689
  const ontologyIri = normalizeOntologyNamespace(root?.namespace)?.replace(/[\/#]+$/, '');
1912
1690
  if (!ontologyIri || BUILT_IN_ONTOLOGIES.has(ontologyIri)) {
1913
1691
  continue;
1914
1692
  }
1915
1693
  await reasoningService.ensureQueryContext(modelUri);
1916
1694
  const quads = store.getQuads(null, null, null, DataFactory.namedNode(modelUri))
1917
- .map((quad: any) => DataFactory.quad(quad.subject, quad.predicate, quad.object));
1695
+ .map((quad) => DataFactory.quad(quad.subject, quad.predicate, quad.object));
1918
1696
  const owlPath = path.join(outputDir, resolveOutputPathFromOntologyIriString(ontologyIri, format));
1919
1697
  await fs.mkdir(path.dirname(owlPath), { recursive: true });
1920
1698
  await fs.writeFile(owlPath, await serializeQuads(quads, format, pretty), 'utf-8');
@@ -1923,9 +1701,8 @@ class InMemoryJsonRpcLspClient {
1923
1701
  entries.sort((left, right) => left.ontologyIri.localeCompare(right.ontologyIri));
1924
1702
  return entries;
1925
1703
  }
1926
-
1927
- async reasonWorkspace(params: Record<string, unknown>): Promise<Record<string, unknown>> {
1928
- const context: RestValidationContext = {
1704
+ async reasonWorkspace(params) {
1705
+ const context = {
1929
1706
  workspaceRoot: this.workspaceRoot,
1930
1707
  runtime: this.runtime,
1931
1708
  ensureInitialized: () => this.ensureInitialized(),
@@ -1935,9 +1712,8 @@ class InMemoryJsonRpcLspClient {
1935
1712
  };
1936
1713
  return await reasonWorkspace(context, params);
1937
1714
  }
1938
-
1939
- async validateWorkspace(params: Record<string, unknown>): Promise<Record<string, unknown>> {
1940
- const context: RestValidationContext = {
1715
+ async validateWorkspace(params) {
1716
+ const context = {
1941
1717
  workspaceRoot: this.workspaceRoot,
1942
1718
  runtime: this.runtime,
1943
1719
  ensureInitialized: () => this.ensureInitialized(),
@@ -1947,9 +1723,8 @@ class InMemoryJsonRpcLspClient {
1947
1723
  };
1948
1724
  return await validateWorkspace(context, params);
1949
1725
  }
1950
-
1951
- async exportWorkspace(params: Record<string, unknown>): Promise<Record<string, unknown>> {
1952
- const context: RestExportContext = {
1726
+ async exportWorkspace(params) {
1727
+ const context = {
1953
1728
  workspaceRoot: this.workspaceRoot,
1954
1729
  ensureInitialized: () => this.ensureInitialized(),
1955
1730
  ensureWorkspaceCurrent: () => this.ensureWorkspaceCurrent(),
@@ -1958,13 +1733,13 @@ class InMemoryJsonRpcLspClient {
1958
1733
  };
1959
1734
  return await exportWorkspace(context, params);
1960
1735
  }
1961
-
1962
- async close(): Promise<void> {
1736
+ async close() {
1963
1737
  this.stopWorkspaceWatcher();
1964
1738
  if (!this.useExternalRuntime) {
1965
1739
  try {
1966
1740
  this.clientConnection?.sendNotification('exit');
1967
- } catch {
1741
+ }
1742
+ catch {
1968
1743
  // Ignore close-time notification failures.
1969
1744
  }
1970
1745
  this.clientConnection?.dispose();
@@ -1973,24 +1748,21 @@ class InMemoryJsonRpcLspClient {
1973
1748
  this.serverToClient?.destroy();
1974
1749
  }
1975
1750
  }
1976
-
1977
- private logError(message: string): void {
1751
+ logError(message) {
1978
1752
  if (this.clientConnection?.console?.error) {
1979
1753
  this.clientConnection.console.error(message);
1980
1754
  return;
1981
1755
  }
1982
1756
  console.error(`[oml-rest] ${message}`);
1983
1757
  }
1984
-
1985
- private startWorkspaceWatcher(): void {
1758
+ startWorkspaceWatcher() {
1986
1759
  if (this.watcherActive) {
1987
1760
  return;
1988
1761
  }
1989
1762
  this.watcherActive = true;
1990
1763
  this.watchDirectory(this.workspaceRoot);
1991
1764
  }
1992
-
1993
- private stopWorkspaceWatcher(): void {
1765
+ stopWorkspaceWatcher() {
1994
1766
  this.watcherActive = false;
1995
1767
  if (this.watcherFlushTimer) {
1996
1768
  clearTimeout(this.watcherFlushTimer);
@@ -2001,8 +1773,7 @@ class InMemoryJsonRpcLspClient {
2001
1773
  }
2002
1774
  this.watchers.clear();
2003
1775
  }
2004
-
2005
- private watchDirectory(dirPath: string): void {
1776
+ watchDirectory(dirPath) {
2006
1777
  const basename = path.basename(dirPath);
2007
1778
  if (basename.startsWith('.') || basename === 'node_modules' || basename === 'out' || basename === 'build') {
2008
1779
  return;
@@ -2019,10 +1790,10 @@ class InMemoryJsonRpcLspClient {
2019
1790
  this.scheduleWorkspaceRefresh();
2020
1791
  });
2021
1792
  this.watchers.add(watcher);
2022
- } catch {
1793
+ }
1794
+ catch {
2023
1795
  return;
2024
1796
  }
2025
-
2026
1797
  try {
2027
1798
  const entries = fsSync.readdirSync(dirPath, { withFileTypes: true });
2028
1799
  for (const entry of entries) {
@@ -2030,22 +1801,21 @@ class InMemoryJsonRpcLspClient {
2030
1801
  this.watchDirectory(path.join(dirPath, entry.name));
2031
1802
  }
2032
1803
  }
2033
- } catch {
1804
+ }
1805
+ catch {
2034
1806
  // Ignore unreadable directories.
2035
1807
  }
2036
1808
  }
2037
-
2038
- private scheduleWorkspaceRefresh(): void {
1809
+ scheduleWorkspaceRefresh() {
2039
1810
  if (this.watcherFlushTimer) {
2040
1811
  return;
2041
1812
  }
2042
1813
  this.watcherFlushTimer = setTimeout(() => {
2043
1814
  this.watcherFlushTimer = undefined;
2044
- void this.refreshWorkspaceOmlDocumentsQueued().catch(() => {});
1815
+ void this.refreshWorkspaceOmlDocumentsQueued().catch(() => { });
2045
1816
  }, 100);
2046
1817
  }
2047
-
2048
- private async refreshWorkspaceOmlDocumentsQueued(): Promise<void> {
1818
+ async refreshWorkspaceOmlDocumentsQueued() {
2049
1819
  if (this.refreshInFlight) {
2050
1820
  this.refreshQueued = true;
2051
1821
  return;
@@ -2053,7 +1823,8 @@ class InMemoryJsonRpcLspClient {
2053
1823
  this.refreshInFlight = true;
2054
1824
  try {
2055
1825
  await this.refreshWorkspaceOmlDocuments();
2056
- } finally {
1826
+ }
1827
+ finally {
2057
1828
  this.refreshInFlight = false;
2058
1829
  }
2059
1830
  if (this.refreshQueued) {
@@ -2061,9 +1832,8 @@ class InMemoryJsonRpcLspClient {
2061
1832
  await this.refreshWorkspaceOmlDocumentsQueued();
2062
1833
  }
2063
1834
  }
2064
-
2065
- async exportAssertedWorkspace(params: Record<string, unknown>): Promise<Record<string, unknown>> {
2066
- const context: RestExportContext = {
1835
+ async exportAssertedWorkspace(params) {
1836
+ const context = {
2067
1837
  workspaceRoot: this.workspaceRoot,
2068
1838
  ensureInitialized: () => this.ensureInitialized(),
2069
1839
  ensureWorkspaceCurrent: () => this.ensureWorkspaceCurrent(),
@@ -2072,8 +1842,7 @@ class InMemoryJsonRpcLspClient {
2072
1842
  };
2073
1843
  return await exportAssertedWorkspace(context, params);
2074
1844
  }
2075
-
2076
- async renderWorkspace(params: Record<string, unknown>): Promise<Record<string, unknown>> {
1845
+ async renderWorkspace(params) {
2077
1846
  await this.ensureInitialized();
2078
1847
  await this.ensureWorkspaceCurrent();
2079
1848
  if (params.only !== true) {
@@ -2095,14 +1864,8 @@ class InMemoryJsonRpcLspClient {
2095
1864
  const outputFromOptions = typeof params.outputDir === 'string' && params.outputDir.trim().length > 0
2096
1865
  ? params.outputDir.trim()
2097
1866
  : (typeof params.web === 'string' && params.web.trim().length > 0 ? params.web.trim() : 'build/web');
2098
- const inputDir = path.resolve(
2099
- workspaceRoot,
2100
- inputFromOptions,
2101
- );
2102
- const outputDir = path.resolve(
2103
- workspaceRoot,
2104
- outputFromOptions,
2105
- );
1867
+ const inputDir = path.resolve(workspaceRoot, inputFromOptions);
1868
+ const outputDir = path.resolve(workspaceRoot, outputFromOptions);
2106
1869
  const contextOption = typeof params.contextOntologyIri === 'string' && params.contextOntologyIri.trim().length > 0
2107
1870
  ? params.contextOntologyIri.trim()
2108
1871
  : (typeof params.context === 'string' && params.context.trim().length > 0 ? params.context.trim() : undefined);
@@ -2111,12 +1874,10 @@ class InMemoryJsonRpcLspClient {
2111
1874
  : undefined;
2112
1875
  const runtime = new MarkdownPreviewRuntime(new MarkdownHandlerRegistry());
2113
1876
  const templateCatalog = await buildTemplateCatalog(workspaceRoot);
2114
- const navigationTemplateCatalog = buildNavigationTemplateCatalog(
2115
- Array.from(templateCatalog.values()).flatMap((entries) => entries.map((entry) => entry.definition))
2116
- );
1877
+ const navigationTemplateCatalog = buildNavigationTemplateCatalog(Array.from(templateCatalog.values()).flatMap((entries) => entries.map((entry) => entry.definition)));
2117
1878
  const staticAssets = await writeStaticAssets(outputDir);
2118
- const reasoningService = this.runtime.Oml.reasoning.ReasoningService as any;
2119
- const ontologyIndex = getOntologyModelIndex(this.runtime.shared as any);
1879
+ const reasoningService = this.runtime.Oml.reasoning.ReasoningService;
1880
+ const ontologyIndex = getOntologyModelIndex(this.runtime.shared);
2120
1881
  const executor = new MarkdownExecutor({
2121
1882
  ensureContext: (modelUri) => reasoningService.ensureQueryContext(modelUri),
2122
1883
  resolveContextIri: (modelUri) => reasoningService.getContextIri(modelUri),
@@ -2126,16 +1887,10 @@ class InMemoryJsonRpcLspClient {
2126
1887
  });
2127
1888
  const markdownFiles = await findFilesByExtension(inputDir, '.md');
2128
1889
  const wikiPageIndex = buildWikiPageIndex(markdownFiles, inputDir, outputDir);
2129
- const workspaceAssetFiles = new Set<string>();
2130
- const aliasesByIri = new Map<string, string>();
2131
- const renderJobs: Array<{
2132
- htmlPath: string;
2133
- renderedHtml: string;
2134
- blockManifest: Array<{ blockId: string; path: string }>;
2135
- blockResults: ReadonlyArray<RenderedBlockResult>;
2136
- wikiLinkHrefByKey: Record<string, string>;
2137
- }> = [];
2138
- const contextModelUris = new Set<string>();
1890
+ const workspaceAssetFiles = new Set();
1891
+ const aliasesByIri = new Map();
1892
+ const renderJobs = [];
1893
+ const contextModelUris = new Set();
2139
1894
  let filesRendered = 0;
2140
1895
  let blockArtifactFiles = 0;
2141
1896
  for (const markdownPath of markdownFiles) {
@@ -2144,11 +1899,9 @@ class InMemoryJsonRpcLspClient {
2144
1899
  continue;
2145
1900
  }
2146
1901
  const frontMatter = extractLeadingFrontMatter(markdown);
2147
- const contextOntologyIri = normalizeContextOntologyIri(
2148
- frontMatter?.contextOntologyIri
2149
- ?? frontMatterString(frontMatter?.data, 'ontologyIri')
2150
- ?? frontMatterString(frontMatter?.data, 'ontology')
2151
- );
1902
+ const contextOntologyIri = normalizeContextOntologyIri(frontMatter?.contextOntologyIri
1903
+ ?? frontMatterString(frontMatter?.data, 'ontologyIri')
1904
+ ?? frontMatterString(frontMatter?.data, 'ontology'));
2152
1905
  const contextMemberIri = frontMatterString(frontMatter?.data, 'memberIri')
2153
1906
  ?? frontMatterString(frontMatter?.data, 'contextMemberIri');
2154
1907
  const referencingUri = pathToFileURL(markdownPath).toString();
@@ -2181,7 +1934,7 @@ class InMemoryJsonRpcLspClient {
2181
1934
  workspaceAssetFiles.add(asset);
2182
1935
  }
2183
1936
  const executableBlocks = toExecutableBlocks(prepared.codeBlocks);
2184
- const optionsByBlockId = new Map(prepared.codeBlocks.map((block) => [block.id, block.options] as const));
1937
+ const optionsByBlockId = new Map(prepared.codeBlocks.map((block) => [block.id, block.options]));
2185
1938
  const blockResults = executableBlocks.length === 0 || !contextModelUri
2186
1939
  ? []
2187
1940
  : (await executor.executeBlocks({
@@ -2191,7 +1944,7 @@ class InMemoryJsonRpcLspClient {
2191
1944
  })).results.map((result) => ({
2192
1945
  ...result,
2193
1946
  options: optionsByBlockId.get(result.blockId),
2194
- } as RenderedBlockResult));
1947
+ }));
2195
1948
  const rewrittenBlockResults = blockResults.map((result) => rewriteBlockResultAssetPaths(result, {
2196
1949
  workspaceRoot,
2197
1950
  inputRoot: inputDir,
@@ -2211,7 +1964,7 @@ class InMemoryJsonRpcLspClient {
2211
1964
  });
2212
1965
  filesRendered += 1;
2213
1966
  }
2214
- const renderedNavigationPages = new Set<string>();
1967
+ const renderedNavigationPages = new Set();
2215
1968
  for (const modelUri of contextModelUris) {
2216
1969
  await reasoningService.ensureQueryContext(modelUri);
2217
1970
  const membersToTypes = await queryMemberTypes(reasoningService, modelUri);
@@ -2231,7 +1984,7 @@ class InMemoryJsonRpcLspClient {
2231
1984
  renderedNavigationPages.add(targetFile);
2232
1985
  const contextOntologyIri = inferOntologyIriFromMemberIri(memberIri);
2233
1986
  const sourceDocumentUri = resolution.template.sourceUri?.trim() || pathToFileURL(path.join(workspaceRoot, 'index.md')).toString();
2234
- const invocation: TemplateInvocation = {
1987
+ const invocation = {
2235
1988
  templateId: resolution.template.id,
2236
1989
  mode: 'navigation',
2237
1990
  context: {
@@ -2279,7 +2032,7 @@ class InMemoryJsonRpcLspClient {
2279
2032
  workspaceAssetFiles.add(asset);
2280
2033
  }
2281
2034
  const executableBlocks = toExecutableBlocks(prepared.codeBlocks);
2282
- const optionsByBlockId = new Map(prepared.codeBlocks.map((block) => [block.id, block.options] as const));
2035
+ const optionsByBlockId = new Map(prepared.codeBlocks.map((block) => [block.id, block.options]));
2283
2036
  const blockResults = executableBlocks.length === 0
2284
2037
  ? []
2285
2038
  : (await executor.executeBlocks({
@@ -2289,7 +2042,7 @@ class InMemoryJsonRpcLspClient {
2289
2042
  })).results.map((result) => ({
2290
2043
  ...result,
2291
2044
  options: optionsByBlockId.get(result.blockId),
2292
- } as RenderedBlockResult));
2045
+ }));
2293
2046
  const rewrittenBlockResults = blockResults.map((result) => rewriteBlockResultAssetPaths(result, {
2294
2047
  workspaceRoot,
2295
2048
  inputRoot: inputDir,
@@ -2312,15 +2065,7 @@ class InMemoryJsonRpcLspClient {
2312
2065
  for (const job of renderJobs) {
2313
2066
  const runtimeScriptRelative = toRelativeWebPath(path.dirname(job.htmlPath), staticAssets.runtimeScriptFile);
2314
2067
  const stylesheetRelative = toRelativeWebPath(path.dirname(job.htmlPath), staticAssets.stylesheetFile);
2315
- const html = wrapHtml(
2316
- job.renderedHtml,
2317
- runtimeScriptRelative,
2318
- stylesheetRelative,
2319
- job.blockManifest,
2320
- job.blockResults,
2321
- job.wikiLinkHrefByKey,
2322
- buildIriAliasMapForPage(aliasesByIri, job.htmlPath),
2323
- );
2068
+ const html = wrapHtml(job.renderedHtml, runtimeScriptRelative, stylesheetRelative, job.blockManifest, job.blockResults, job.wikiLinkHrefByKey, buildIriAliasMapForPage(aliasesByIri, job.htmlPath));
2324
2069
  await fs.mkdir(path.dirname(job.htmlPath), { recursive: true });
2325
2070
  await fs.writeFile(job.htmlPath, html, 'utf-8');
2326
2071
  }
@@ -2340,8 +2085,9 @@ class InMemoryJsonRpcLspClient {
2340
2085
  await fs.mkdir(path.dirname(target), { recursive: true });
2341
2086
  try {
2342
2087
  await fs.copyFile(file, target);
2343
- } catch (error) {
2344
- const code = (error as NodeJS.ErrnoException).code;
2088
+ }
2089
+ catch (error) {
2090
+ const code = error.code;
2345
2091
  if (code !== 'ENOENT') {
2346
2092
  throw error;
2347
2093
  }
@@ -2349,8 +2095,7 @@ class InMemoryJsonRpcLspClient {
2349
2095
  }
2350
2096
  return { success: true, filesRendered, outputDir, blockArtifactFiles };
2351
2097
  }
2352
-
2353
- private async ensureWorkspaceCurrent(): Promise<void> {
2098
+ async ensureWorkspaceCurrent() {
2354
2099
  if (this.useExternalRuntime) {
2355
2100
  return;
2356
2101
  }
@@ -2364,23 +2109,21 @@ class InMemoryJsonRpcLspClient {
2364
2109
  }
2365
2110
  await this.waitForWatcherRefreshIdle();
2366
2111
  }
2367
-
2368
- private async waitForWatcherRefreshIdle(): Promise<void> {
2112
+ async waitForWatcherRefreshIdle() {
2369
2113
  while (this.watcherFlushTimer !== undefined || this.refreshInFlight || this.refreshQueued) {
2370
2114
  await new Promise((resolve) => setTimeout(resolve, 10));
2371
2115
  }
2372
2116
  }
2373
-
2374
- private async refreshWorkspaceOmlDocuments(): Promise<void> {
2117
+ async refreshWorkspaceOmlDocuments() {
2375
2118
  const workspaceRoot = path.resolve(this.workspaceRoot);
2376
2119
  const omlFiles = await findFilesByExtension(workspaceRoot, '.oml');
2377
2120
  const changedUris = omlFiles.map((filePath) => URI.parse(pathToFileURL(filePath).toString()));
2378
2121
  const documents = this.runtime.shared.workspace.LangiumDocuments;
2379
2122
  const allDocs = documents.all ?? [];
2380
- const iterable: any[] = Array.isArray(allDocs)
2123
+ const iterable = Array.isArray(allDocs)
2381
2124
  ? allDocs
2382
- : (typeof allDocs?.toArray === 'function' ? allDocs.toArray() : Array.from(allDocs as Iterable<any>));
2383
- const currentOmlUris = new Set<string>();
2125
+ : (typeof allDocs?.toArray === 'function' ? allDocs.toArray() : Array.from(allDocs));
2126
+ const currentOmlUris = new Set();
2384
2127
  for (const document of iterable) {
2385
2128
  const uri = String(document?.uri ?? '').trim();
2386
2129
  if (!uri.toLowerCase().endsWith('.oml')) {
@@ -2396,23 +2139,22 @@ class InMemoryJsonRpcLspClient {
2396
2139
  const builder = this.runtime.shared.workspace.DocumentBuilder;
2397
2140
  await builder.update(changedUris, deletedUris);
2398
2141
  }
2399
-
2400
- private async ensureInitialized(): Promise<void> {
2142
+ async ensureInitialized() {
2401
2143
  if (this.initPromise) {
2402
2144
  await this.initPromise;
2403
2145
  return;
2404
2146
  }
2405
-
2406
2147
  if (this.useExternalRuntime) {
2407
2148
  this.initPromise = (async () => {
2408
2149
  const workspace = this.runtime.shared.workspace.WorkspaceManager;
2409
2150
  await workspace.ready;
2410
2151
  })();
2411
- } else {
2152
+ }
2153
+ else {
2412
2154
  const rootPath = path.resolve(this.workspaceRoot);
2413
2155
  const rootUri = pathToFileURL(rootPath).toString();
2414
2156
  this.initPromise = (async () => {
2415
- await withTimeout(this.clientConnection!.sendRequest('initialize', {
2157
+ await withTimeout(this.clientConnection.sendRequest('initialize', {
2416
2158
  processId: process.pid,
2417
2159
  rootUri,
2418
2160
  workspaceFolders: [{ uri: rootUri, name: path.basename(rootPath) }],
@@ -2420,25 +2162,18 @@ class InMemoryJsonRpcLspClient {
2420
2162
  clientInfo: { name: 'oml-rest-server', version: '1.0' },
2421
2163
  initializationOptions: {},
2422
2164
  }), this.requestTimeoutMs, 'initialize');
2423
- this.clientConnection!.sendNotification('initialized', {});
2165
+ this.clientConnection.sendNotification('initialized', {});
2424
2166
  })();
2425
2167
  }
2426
2168
  await this.initPromise;
2427
2169
  }
2428
2170
  }
2429
-
2430
- export async function startOmlRestServer(options: OmlRestServerOptions): Promise<{ server: http.Server; updateToken: (token: string) => void }> {
2171
+ export async function startOmlRestServer(options) {
2431
2172
  const workspaceRoot = options.workspaceRoot ? path.resolve(options.workspaceRoot) : process.cwd();
2432
- const client = new InMemoryJsonRpcLspClient(
2433
- workspaceRoot,
2434
- options.requestTimeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS,
2435
- options.watchWorkspace === true,
2436
- options.runtime,
2437
- );
2173
+ const client = new InMemoryJsonRpcLspClient(workspaceRoot, options.requestTimeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS, options.watchWorkspace === true, options.runtime);
2438
2174
  const openApiSpec = createOpenApiSpec(options.host, options.port);
2439
- let currentAccessToken: string | undefined = options.authToken;
2440
- const getAccessToken = (): string | undefined => currentAccessToken;
2441
-
2175
+ let currentAccessToken = options.authToken;
2176
+ const getAccessToken = () => currentAccessToken;
2442
2177
  const server = http.createServer(async (req, res) => {
2443
2178
  const requestId = randomUUID();
2444
2179
  try {
@@ -2446,7 +2181,6 @@ export async function startOmlRestServer(options: OmlRestServerOptions): Promise
2446
2181
  const rawUrl = req.url ?? '/';
2447
2182
  const parsed = new URL(rawUrl, `http://${req.headers.host ?? 'localhost'}`);
2448
2183
  const pathname = parsed.pathname;
2449
-
2450
2184
  if (method === 'GET' && pathname === '/health') {
2451
2185
  jsonResponse(res, 200, {
2452
2186
  status: 'ok',
@@ -2458,17 +2192,14 @@ export async function startOmlRestServer(options: OmlRestServerOptions): Promise
2458
2192
  });
2459
2193
  return;
2460
2194
  }
2461
-
2462
2195
  if (method === 'GET' && pathname === '/') {
2463
2196
  htmlResponse(res, 200, createSparqlWorkbenchPage(workspaceRoot));
2464
2197
  return;
2465
2198
  }
2466
-
2467
2199
  if (method === 'GET' && pathname === '/openapi.json') {
2468
2200
  jsonResponse(res, 200, openApiSpec);
2469
2201
  return;
2470
2202
  }
2471
-
2472
2203
  if (method === 'GET' && pathname === '/v0/models') {
2473
2204
  const workspaceModelFiles = await listWorkspaceModelFiles(workspaceRoot);
2474
2205
  jsonResponse(res, 200, {
@@ -2477,7 +2208,6 @@ export async function startOmlRestServer(options: OmlRestServerOptions): Promise
2477
2208
  });
2478
2209
  return;
2479
2210
  }
2480
-
2481
2211
  if (method === 'POST') {
2482
2212
  const body = await readJsonBody(req);
2483
2213
  const route = await dispatchRestRoute(method, pathname, body, client);
@@ -2491,27 +2221,25 @@ export async function startOmlRestServer(options: OmlRestServerOptions): Promise
2491
2221
  return;
2492
2222
  }
2493
2223
  }
2494
-
2495
2224
  jsonResponse(res, 404, { error: `No route for ${method} ${pathname}.`, requestId });
2496
- } catch (error) {
2225
+ }
2226
+ catch (error) {
2497
2227
  const message = error instanceof Error ? error.message : String(error);
2498
2228
  const status = error instanceof SyntaxError || message.includes('Request body exceeds') ? 400 : 500;
2499
2229
  jsonResponse(res, status, { error: message, requestId });
2500
2230
  }
2501
2231
  });
2502
-
2503
2232
  server.on('close', () => {
2504
2233
  void client.close();
2505
2234
  currentAccessToken = undefined;
2506
2235
  });
2507
-
2508
- await new Promise<void>((resolve, reject) => {
2236
+ await new Promise((resolve, reject) => {
2509
2237
  server.once('error', reject);
2510
2238
  server.listen(options.port, options.host, () => resolve());
2511
2239
  });
2512
-
2513
2240
  return {
2514
2241
  server,
2515
- updateToken: (token: string) => { currentAccessToken = token; },
2242
+ updateToken: (token) => { currentAccessToken = token; },
2516
2243
  };
2517
2244
  }
2245
+ //# sourceMappingURL=server.js.map