@oml/server 0.14.13 → 0.14.15
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/out/auth/feature-policy.js +1 -0
- package/out/auth/feature-policy.js.map +1 -1
- package/out/rest/export.js +4 -85
- package/out/rest/export.js.map +1 -1
- package/out/rest/routes.d.ts +5 -5
- package/out/rest/routes.js +212 -78
- package/out/rest/routes.js.map +1 -1
- package/out/rest/server.d.ts +9 -0
- package/out/rest/server.js +126 -79
- package/out/rest/server.js.map +1 -1
- package/out/rest/validation.d.ts +1 -20
- package/out/rest/validation.js +3 -240
- package/out/rest/validation.js.map +1 -1
- package/package.json +4 -4
package/out/rest/server.d.ts
CHANGED
|
@@ -11,6 +11,15 @@ export interface OmlRestServerOptions {
|
|
|
11
11
|
runtime?: OmlLanguageServerRuntime;
|
|
12
12
|
featureGate?: OmlFeatureGateLike;
|
|
13
13
|
}
|
|
14
|
+
export type OmlWorkspaceLocalOperation = 'lint' | 'validate' | 'assertions' | 'export' | 'render';
|
|
15
|
+
export declare function runOmlWorkspaceLocalOperation<T = Record<string, unknown>>(options: {
|
|
16
|
+
workspaceRoot?: string;
|
|
17
|
+
operation: OmlWorkspaceLocalOperation;
|
|
18
|
+
params?: Record<string, unknown>;
|
|
19
|
+
requestTimeoutMs?: number;
|
|
20
|
+
watchWorkspace?: boolean;
|
|
21
|
+
runtime?: OmlLanguageServerRuntime;
|
|
22
|
+
}): Promise<T>;
|
|
14
23
|
export declare function startOmlRestServer(options: OmlRestServerOptions): Promise<{
|
|
15
24
|
server: http.Server;
|
|
16
25
|
updateToken: (token: string) => Promise<void>;
|
package/out/rest/server.js
CHANGED
|
@@ -12,9 +12,6 @@ import { NodeFileSystem } from 'langium/node';
|
|
|
12
12
|
import { createConnection } from 'vscode-languageserver/node.js';
|
|
13
13
|
import { DataFactory, Writer } from 'n3';
|
|
14
14
|
import uFuzzy from '@leeoniya/ufuzzy';
|
|
15
|
-
// swagger-ui-dist does not ship TypeScript declarations.
|
|
16
|
-
// @ts-expect-error Untyped CommonJS module import.
|
|
17
|
-
import swaggerUiDist from 'swagger-ui-dist';
|
|
18
15
|
import { MarkdownHandlerRegistry, MarkdownPreviewRuntime, buildTemplateCatalog as buildNavigationTemplateCatalog, extractLeadingFrontMatter, resolveTemplateForNavigation, renderTemplate, MarkdownExecutor, } from '@oml/markdown';
|
|
19
16
|
import { STATIC_MARKDOWN_RUNTIME_BUNDLE_FILE, STATIC_MARKDOWN_RUNTIME_CSS } from '@oml/markdown/static';
|
|
20
17
|
import { applyOmlUpdate, collectOntologyMembers, getIriForNode, getOntologyModelIndex, iriFragment, isDescription, isOntology, isVocabulary, tokenizeForFuzzy, } from '@oml/language';
|
|
@@ -23,7 +20,7 @@ import { exportAssertedWorkspace, exportWorkspace } from './export.js';
|
|
|
23
20
|
import { startOmlLanguageServer } from '../lsp/language-server.js';
|
|
24
21
|
import { createOpenApiSpec, dispatchRestOperation, resolveRestOperationId } from './routes.js';
|
|
25
22
|
import { buildTemplateCatalog, expandTemplateComposeBlocks, findFilesByExtension, frontMatterString, isTemplateMarkdownFile, normalizeContextOntologyIri, } from './template.js';
|
|
26
|
-
import { lintWorkspace,
|
|
23
|
+
import { lintWorkspace, validateWorkspace } from './validation.js';
|
|
27
24
|
import { OmlAccessError, requiredFeatureForRestOperation, } from '../auth/feature-policy.js';
|
|
28
25
|
const JSON_CONTENT_TYPE = 'application/json; charset=utf-8';
|
|
29
26
|
const HTML_CONTENT_TYPE = 'text/html; charset=utf-8';
|
|
@@ -43,9 +40,9 @@ const SWAGGER_CONTENT_TYPES = {
|
|
|
43
40
|
'.js': 'application/javascript; charset=utf-8',
|
|
44
41
|
'.png': 'image/png',
|
|
45
42
|
};
|
|
46
|
-
let swaggerDistDirCache;
|
|
47
43
|
let swaggerAssetValidationError;
|
|
48
44
|
let markdownStaticEntryFileCache;
|
|
45
|
+
const swaggerAssetPathCache = new Map();
|
|
49
46
|
function createModuleRequire() {
|
|
50
47
|
if (typeof __filename === 'string' && path.isAbsolute(__filename)) {
|
|
51
48
|
return createRequire(__filename);
|
|
@@ -105,22 +102,6 @@ function textResponse(res, status, contentType, body) {
|
|
|
105
102
|
res.setHeader('content-length', Buffer.byteLength(body, 'utf-8'));
|
|
106
103
|
res.end(body);
|
|
107
104
|
}
|
|
108
|
-
function resolveSwaggerDistDir() {
|
|
109
|
-
if (!swaggerDistDirCache) {
|
|
110
|
-
if (typeof swaggerUiDist?.getAbsoluteFSPath !== 'function') {
|
|
111
|
-
throw new Error("Swagger UI package is unavailable: missing 'swagger-ui-dist.getAbsoluteFSPath()'.");
|
|
112
|
-
}
|
|
113
|
-
const resolved = swaggerUiDist.getAbsoluteFSPath();
|
|
114
|
-
if (!resolved || resolved.trim().length === 0) {
|
|
115
|
-
throw new Error("Swagger UI package returned an invalid asset directory.");
|
|
116
|
-
}
|
|
117
|
-
swaggerDistDirCache = resolved;
|
|
118
|
-
}
|
|
119
|
-
if (!swaggerDistDirCache) {
|
|
120
|
-
throw new Error('Swagger UI package returned an invalid asset directory.');
|
|
121
|
-
}
|
|
122
|
-
return swaggerDistDirCache;
|
|
123
|
-
}
|
|
124
105
|
function resolveMarkdownStaticEntryFile() {
|
|
125
106
|
if (!markdownStaticEntryFileCache) {
|
|
126
107
|
const entryFile = require.resolve('@oml/markdown/static');
|
|
@@ -132,13 +113,8 @@ function resolveMarkdownStaticEntryFile() {
|
|
|
132
113
|
return markdownStaticEntryFileCache;
|
|
133
114
|
}
|
|
134
115
|
function validateSwaggerAssetsOrThrow() {
|
|
135
|
-
const
|
|
136
|
-
|
|
137
|
-
const filePath = path.join(distDir, fileName);
|
|
138
|
-
const stat = fsSync.statSync(filePath, { throwIfNoEntry: false });
|
|
139
|
-
if (!stat || !stat.isFile()) {
|
|
140
|
-
throw new Error(`Swagger UI asset missing: ${fileName}`);
|
|
141
|
-
}
|
|
116
|
+
for (const asset of ['swagger-ui-bundle.js', 'swagger-ui-standalone-preset.js']) {
|
|
117
|
+
resolveSwaggerAssetPath(asset);
|
|
142
118
|
}
|
|
143
119
|
}
|
|
144
120
|
function getSwaggerValidationError() {
|
|
@@ -159,7 +135,7 @@ async function serveSwaggerAsset(res, fileName) {
|
|
|
159
135
|
jsonResponse(res, 404, { error: 'Swagger asset not found.' });
|
|
160
136
|
return;
|
|
161
137
|
}
|
|
162
|
-
const filePath =
|
|
138
|
+
const filePath = resolveSwaggerAssetPath(fileName);
|
|
163
139
|
const extension = path.extname(fileName).toLowerCase();
|
|
164
140
|
const contentType = SWAGGER_CONTENT_TYPES[extension] ?? 'application/octet-stream';
|
|
165
141
|
const content = await fs.readFile(filePath);
|
|
@@ -169,6 +145,22 @@ async function serveSwaggerAsset(res, fileName) {
|
|
|
169
145
|
res.setHeader('content-length', content.length);
|
|
170
146
|
res.end(content);
|
|
171
147
|
}
|
|
148
|
+
function resolveSwaggerAssetPath(fileName) {
|
|
149
|
+
if (!SWAGGER_ASSET_FILES.has(fileName)) {
|
|
150
|
+
throw new Error(`Swagger UI asset not allowed: ${fileName}`);
|
|
151
|
+
}
|
|
152
|
+
const cached = swaggerAssetPathCache.get(fileName);
|
|
153
|
+
if (cached) {
|
|
154
|
+
return cached;
|
|
155
|
+
}
|
|
156
|
+
const resolvedPath = require.resolve(`swagger-ui-dist/${fileName}`);
|
|
157
|
+
const resolvedStat = fsSync.statSync(resolvedPath, { throwIfNoEntry: false });
|
|
158
|
+
if (resolvedStat?.isFile()) {
|
|
159
|
+
swaggerAssetPathCache.set(fileName, resolvedPath);
|
|
160
|
+
return resolvedPath;
|
|
161
|
+
}
|
|
162
|
+
throw new Error(`Swagger UI asset missing: ${fileName}`);
|
|
163
|
+
}
|
|
172
164
|
function createSwaggerUiPage() {
|
|
173
165
|
return `<!doctype html>
|
|
174
166
|
<html lang="en">
|
|
@@ -789,7 +781,7 @@ function createSparqlWorkbenchPage(defaultWorkspaceRoot) {
|
|
|
789
781
|
<section class="hero">
|
|
790
782
|
<div class="hero-header">
|
|
791
783
|
<h1 class="page-title">OML Server</h1>
|
|
792
|
-
<a id="swaggerLink" class="swagger-link" href="
|
|
784
|
+
<a id="swaggerLink" class="swagger-link" href="docs" target="_blank" rel="noopener noreferrer" title="Open Swagger Docs">
|
|
793
785
|
<svg viewBox="0 0 24 24" aria-hidden="true">
|
|
794
786
|
<path d="M13.8 2.6a2.1 2.1 0 0 0-3.6 1.5c0 .2 0 .4.1.6a6 6 0 0 0-2.2 1.3l-.4-.2a2.1 2.1 0 1 0-1.8 3.8l.4.2a6.3 6.3 0 0 0 0 2.6l-.4.2a2.1 2.1 0 1 0 1.8 3.8l.4-.2a6 6 0 0 0 2.2 1.3 2.1 2.1 0 1 0 3.5 0 6 6 0 0 0 2.2-1.3l.4.2a2.1 2.1 0 1 0 1.8-3.8l-.4-.2a6.3 6.3 0 0 0 0-2.6l.4-.2a2.1 2.1 0 1 0-1.8-3.8l-.4.2a6 6 0 0 0-2.2-1.3c.1-.2.1-.4.1-.6 0-.6-.2-1.1-.6-1.5Zm-2.6 6.3a3.3 3.3 0 1 1 0 6.6 3.3 3.3 0 0 1 0-6.6Zm4.8 9.6a1 1 0 1 1 0 2 1 1 0 0 1 0-2Zm-9.6 0a1 1 0 1 1 0 2 1 1 0 0 1 0-2Zm11-8.7a1 1 0 1 1 0-2 1 1 0 0 1 0 2Zm-12.4 0a1 1 0 1 1 0-2 1 1 0 0 1 0 2Zm7.2-7.1a1 1 0 1 1 0 2 1 1 0 0 1 0-2Z"/>
|
|
795
787
|
</svg>
|
|
@@ -897,7 +889,6 @@ LIMIT 25</textarea>
|
|
|
897
889
|
const browseStatus = document.getElementById('browseStatus');
|
|
898
890
|
const browseList = document.getElementById('browseList');
|
|
899
891
|
const browseFilter = document.getElementById('browseFilter');
|
|
900
|
-
const swaggerLink = document.getElementById('swaggerLink');
|
|
901
892
|
|
|
902
893
|
let browseEntries = [];
|
|
903
894
|
let selectedModelId = '';
|
|
@@ -916,10 +907,6 @@ LIMIT 25</textarea>
|
|
|
916
907
|
return baseRoutePath() + normalized;
|
|
917
908
|
}
|
|
918
909
|
|
|
919
|
-
if (swaggerLink) {
|
|
920
|
-
swaggerLink.setAttribute('href', routeUrl('docs'));
|
|
921
|
-
}
|
|
922
|
-
|
|
923
910
|
function escapeClientHtml(value) {
|
|
924
911
|
return String(value)
|
|
925
912
|
.replace(/&/g, '&')
|
|
@@ -2044,7 +2031,7 @@ class InMemoryJsonRpcLspClient {
|
|
|
2044
2031
|
listener.dispose();
|
|
2045
2032
|
}
|
|
2046
2033
|
}
|
|
2047
|
-
async lintWorkspace(
|
|
2034
|
+
async lintWorkspace(_params = {}) {
|
|
2048
2035
|
const preDocs = this.getWorkspaceOmlDocuments();
|
|
2049
2036
|
const preSummary = this.summarizeDiagnostics(preDocs);
|
|
2050
2037
|
const preStates = this.summarizeDocumentStates(preDocs);
|
|
@@ -2070,18 +2057,15 @@ class InMemoryJsonRpcLspClient {
|
|
|
2070
2057
|
ensureInitialized: () => this.ensureInitialized(),
|
|
2071
2058
|
ensureWorkspaceCurrent: () => this.ensureWorkspaceCurrent(),
|
|
2072
2059
|
getWorkspaceOmlDocuments: () => this.getWorkspaceOmlDocuments(),
|
|
2073
|
-
writeWorkspaceAssertedOwl: (outputDir, format, pretty) => this.writeWorkspaceAssertedOwl(outputDir, format, pretty),
|
|
2074
2060
|
};
|
|
2075
|
-
const result = await lintWorkspace(context
|
|
2061
|
+
const result = await lintWorkspace(context);
|
|
2076
2062
|
const postDocs = this.getWorkspaceOmlDocuments();
|
|
2077
2063
|
const postStates = this.summarizeDocumentStates(postDocs);
|
|
2078
2064
|
debugRest('lint.end', {
|
|
2079
2065
|
filesChecked: result.filesChecked,
|
|
2080
2066
|
errors: result.errors,
|
|
2081
2067
|
warnings: result.warnings,
|
|
2082
|
-
|
|
2083
|
-
returnedProblems: result.returnedProblems,
|
|
2084
|
-
truncated: result.truncated,
|
|
2068
|
+
problems: result.problems.length,
|
|
2085
2069
|
elapsedMs: result.elapsedMs,
|
|
2086
2070
|
stateValidated: postStates.validated,
|
|
2087
2071
|
stateLinked: postStates.linked,
|
|
@@ -2177,6 +2161,12 @@ class InMemoryJsonRpcLspClient {
|
|
|
2177
2161
|
async updateWorkspace(params) {
|
|
2178
2162
|
await this.ensureInitialized();
|
|
2179
2163
|
await this.ensureWorkspaceCurrent();
|
|
2164
|
+
const lint = await this.lintWorkspace({});
|
|
2165
|
+
if (lint.errors > 0 || lint.warnings > 0) {
|
|
2166
|
+
return {
|
|
2167
|
+
error: `lint failed with ${lint.errors} error(s) and ${lint.warnings} warning(s).`,
|
|
2168
|
+
};
|
|
2169
|
+
}
|
|
2180
2170
|
return await applyOmlUpdate(this.runtime.shared, params, (message) => this.logError(message));
|
|
2181
2171
|
}
|
|
2182
2172
|
async fuzzySearchWorkspace(params) {
|
|
@@ -2278,6 +2268,52 @@ class InMemoryJsonRpcLspClient {
|
|
|
2278
2268
|
};
|
|
2279
2269
|
}
|
|
2280
2270
|
}
|
|
2271
|
+
async assertionsWorkspace(params) {
|
|
2272
|
+
await this.ensureInitialized();
|
|
2273
|
+
await this.ensureWorkspaceCurrent();
|
|
2274
|
+
const lint = await this.lintWorkspace({});
|
|
2275
|
+
if (lint.errors > 0 || lint.warnings > 0) {
|
|
2276
|
+
return {
|
|
2277
|
+
success: false,
|
|
2278
|
+
files: [],
|
|
2279
|
+
error: `lint failed with ${lint.errors} error(s) and ${lint.warnings} warning(s).`,
|
|
2280
|
+
};
|
|
2281
|
+
}
|
|
2282
|
+
const modelUriFilter = typeof params.modelUri === 'string' ? params.modelUri.trim() : '';
|
|
2283
|
+
const docs = this.getWorkspaceOmlDocuments();
|
|
2284
|
+
const reasoningService = this.runtime.Oml.reasoning.ReasoningService;
|
|
2285
|
+
const store = reasoningService.getStore().getStore();
|
|
2286
|
+
const files = [];
|
|
2287
|
+
for (const doc of docs) {
|
|
2288
|
+
const modelUri = String(doc?.uri ?? '').trim();
|
|
2289
|
+
if (modelUriFilter.length > 0 && modelUri !== modelUriFilter) {
|
|
2290
|
+
continue;
|
|
2291
|
+
}
|
|
2292
|
+
const root = doc?.parseResult?.value;
|
|
2293
|
+
const ontologyIri = normalizeOntologyNamespace(root?.namespace)?.replace(/[\/#]+$/, '');
|
|
2294
|
+
if (!ontologyIri || BUILT_IN_ONTOLOGIES.has(ontologyIri)) {
|
|
2295
|
+
continue;
|
|
2296
|
+
}
|
|
2297
|
+
await reasoningService.ensureQueryContext(modelUri);
|
|
2298
|
+
const quads = store.getQuads(null, null, null, DataFactory.namedNode(modelUri))
|
|
2299
|
+
.map((quad) => ({
|
|
2300
|
+
subject: quad.subject,
|
|
2301
|
+
predicate: quad.predicate,
|
|
2302
|
+
object: quad.object,
|
|
2303
|
+
}));
|
|
2304
|
+
files.push({
|
|
2305
|
+
modelUri,
|
|
2306
|
+
ontologyIri,
|
|
2307
|
+
path: resolveOutputPathFromOntologyIriString(ontologyIri, 'nt').split(path.sep).join('/'),
|
|
2308
|
+
content: await serializeQuads(quads, 'nt', false),
|
|
2309
|
+
});
|
|
2310
|
+
}
|
|
2311
|
+
files.sort((left, right) => left.ontologyIri.localeCompare(right.ontologyIri));
|
|
2312
|
+
return {
|
|
2313
|
+
success: true,
|
|
2314
|
+
files,
|
|
2315
|
+
};
|
|
2316
|
+
}
|
|
2281
2317
|
async writeWorkspaceAssertedOwl(outputDir, format, pretty) {
|
|
2282
2318
|
const entries = [];
|
|
2283
2319
|
const docs = this.getWorkspaceOmlDocuments();
|
|
@@ -2301,17 +2337,6 @@ class InMemoryJsonRpcLspClient {
|
|
|
2301
2337
|
entries.sort((left, right) => left.ontologyIri.localeCompare(right.ontologyIri));
|
|
2302
2338
|
return entries;
|
|
2303
2339
|
}
|
|
2304
|
-
async reasonWorkspace(params) {
|
|
2305
|
-
const context = {
|
|
2306
|
-
workspaceRoot: this.workspaceRoot,
|
|
2307
|
-
runtime: this.runtime,
|
|
2308
|
-
ensureInitialized: () => this.ensureInitialized(),
|
|
2309
|
-
ensureWorkspaceCurrent: () => this.ensureWorkspaceCurrent(),
|
|
2310
|
-
getWorkspaceOmlDocuments: () => this.getWorkspaceOmlDocuments(),
|
|
2311
|
-
writeWorkspaceAssertedOwl: (outputDir, format, pretty) => this.writeWorkspaceAssertedOwl(outputDir, format, pretty),
|
|
2312
|
-
};
|
|
2313
|
-
return await reasonWorkspace(context, params);
|
|
2314
|
-
}
|
|
2315
2340
|
async validateWorkspace(params) {
|
|
2316
2341
|
const context = {
|
|
2317
2342
|
workspaceRoot: this.workspaceRoot,
|
|
@@ -2319,19 +2344,15 @@ class InMemoryJsonRpcLspClient {
|
|
|
2319
2344
|
ensureInitialized: () => this.ensureInitialized(),
|
|
2320
2345
|
ensureWorkspaceCurrent: () => this.ensureWorkspaceCurrent(),
|
|
2321
2346
|
getWorkspaceOmlDocuments: () => this.getWorkspaceOmlDocuments(),
|
|
2322
|
-
writeWorkspaceAssertedOwl: (outputDir, format, pretty) => this.writeWorkspaceAssertedOwl(outputDir, format, pretty),
|
|
2323
2347
|
};
|
|
2324
2348
|
return await validateWorkspace(context, params);
|
|
2325
2349
|
}
|
|
2326
2350
|
async exportWorkspace(params) {
|
|
2327
|
-
const lint = await this.lintWorkspace({
|
|
2328
|
-
limit: typeof params.lintLimit === 'number' ? params.lintLimit : undefined,
|
|
2329
|
-
});
|
|
2351
|
+
const lint = await this.lintWorkspace({});
|
|
2330
2352
|
if (lint.errors > 0 || lint.warnings > 0) {
|
|
2331
2353
|
return {
|
|
2332
2354
|
success: false,
|
|
2333
2355
|
error: `lint failed with ${lint.errors} error(s) and ${lint.warnings} warning(s).`,
|
|
2334
|
-
lint,
|
|
2335
2356
|
};
|
|
2336
2357
|
}
|
|
2337
2358
|
const context = {
|
|
@@ -2342,10 +2363,7 @@ class InMemoryJsonRpcLspClient {
|
|
|
2342
2363
|
exportAssertedWorkspace: (options) => exportAssertedWorkspace(context, options),
|
|
2343
2364
|
};
|
|
2344
2365
|
const result = await exportWorkspace(context, params);
|
|
2345
|
-
return
|
|
2346
|
-
...result,
|
|
2347
|
-
lint,
|
|
2348
|
-
};
|
|
2366
|
+
return result;
|
|
2349
2367
|
}
|
|
2350
2368
|
async close() {
|
|
2351
2369
|
this.stopWorkspaceWatcher();
|
|
@@ -2459,39 +2477,45 @@ class InMemoryJsonRpcLspClient {
|
|
|
2459
2477
|
async renderWorkspace(params) {
|
|
2460
2478
|
await this.ensureInitialized();
|
|
2461
2479
|
await this.ensureWorkspaceCurrent();
|
|
2462
|
-
const lint = await this.lintWorkspace({
|
|
2463
|
-
limit: typeof params.lintLimit === 'number' ? params.lintLimit : undefined,
|
|
2464
|
-
});
|
|
2480
|
+
const lint = await this.lintWorkspace({});
|
|
2465
2481
|
if (lint.errors > 0 || lint.warnings > 0) {
|
|
2466
2482
|
return {
|
|
2467
2483
|
success: false,
|
|
2468
2484
|
filesRendered: 0,
|
|
2469
|
-
outputDir: '',
|
|
2470
2485
|
error: `lint failed with ${lint.errors} error(s) and ${lint.warnings} warning(s).`,
|
|
2471
|
-
lint,
|
|
2472
2486
|
};
|
|
2473
2487
|
}
|
|
2474
2488
|
const workspaceRoot = path.resolve(this.workspaceRoot);
|
|
2475
|
-
const inputFromOptions = typeof params.
|
|
2476
|
-
|
|
2477
|
-
: (typeof params.md === 'string' && params.md.trim().length > 0 ? params.md.trim() : 'src/md');
|
|
2478
|
-
const outputFromOptions = typeof params.outputDir === 'string' && params.outputDir.trim().length > 0
|
|
2479
|
-
? params.outputDir.trim()
|
|
2480
|
-
: (typeof params.web === 'string' && params.web.trim().length > 0 ? params.web.trim() : 'build/web');
|
|
2489
|
+
const inputFromOptions = typeof params.md === 'string' && params.md.trim().length > 0 ? params.md.trim() : 'src/md';
|
|
2490
|
+
const outputFromOptions = typeof params.web === 'string' && params.web.trim().length > 0 ? params.web.trim() : 'build/web';
|
|
2481
2491
|
const inputDir = path.resolve(workspaceRoot, inputFromOptions);
|
|
2482
2492
|
const outputDir = path.resolve(workspaceRoot, outputFromOptions);
|
|
2483
|
-
|
|
2484
|
-
|
|
2485
|
-
|
|
2486
|
-
const defaultContextOntologyIri = contextOption
|
|
2487
|
-
? normalizeContextOntologyIri(contextOption)
|
|
2488
|
-
: undefined;
|
|
2493
|
+
if (params.clean === true) {
|
|
2494
|
+
await fs.rm(outputDir, { recursive: true, force: true });
|
|
2495
|
+
}
|
|
2489
2496
|
const runtime = new MarkdownPreviewRuntime(new MarkdownHandlerRegistry());
|
|
2490
2497
|
const templateCatalog = await buildTemplateCatalog(workspaceRoot);
|
|
2491
2498
|
const navigationTemplateCatalog = buildNavigationTemplateCatalog(Array.from(templateCatalog.values()).flatMap((entries) => entries.map((entry) => entry.definition)));
|
|
2492
2499
|
const staticAssets = await writeStaticAssets(outputDir);
|
|
2493
2500
|
const reasoningService = this.runtime.Oml.reasoning.ReasoningService;
|
|
2494
2501
|
const ontologyIndex = getOntologyModelIndex(this.runtime.shared);
|
|
2502
|
+
const contextOption = typeof params.context === 'string' && params.context.trim().length > 0
|
|
2503
|
+
? params.context.trim()
|
|
2504
|
+
: undefined;
|
|
2505
|
+
const defaultContextOntologyIri = contextOption
|
|
2506
|
+
? (() => {
|
|
2507
|
+
const contextModelPath = path.resolve(workspaceRoot, contextOption);
|
|
2508
|
+
const contextModelUri = pathToFileURL(contextModelPath).toString();
|
|
2509
|
+
return ontologyIndex.resolveOntologyIri(contextModelUri);
|
|
2510
|
+
})()
|
|
2511
|
+
: undefined;
|
|
2512
|
+
if (contextOption && !defaultContextOntologyIri) {
|
|
2513
|
+
return {
|
|
2514
|
+
success: false,
|
|
2515
|
+
filesRendered: 0,
|
|
2516
|
+
error: `Unable to resolve ontology IRI for context model path '${contextOption}'.`,
|
|
2517
|
+
};
|
|
2518
|
+
}
|
|
2495
2519
|
const executor = new MarkdownExecutor({
|
|
2496
2520
|
ensureContext: (modelUri) => reasoningService.ensureQueryContext(modelUri),
|
|
2497
2521
|
resolveContextIri: (modelUri) => reasoningService.getContextIri(modelUri),
|
|
@@ -2707,7 +2731,7 @@ class InMemoryJsonRpcLspClient {
|
|
|
2707
2731
|
}
|
|
2708
2732
|
}
|
|
2709
2733
|
}
|
|
2710
|
-
return { success: true, filesRendered, outputDir, blockArtifactFiles
|
|
2734
|
+
return { success: true, filesRendered, outputDir, blockArtifactFiles };
|
|
2711
2735
|
}
|
|
2712
2736
|
async ensureWorkspaceCurrent() {
|
|
2713
2737
|
debugRest('workspace.current.begin', {
|
|
@@ -2835,6 +2859,29 @@ class InMemoryJsonRpcLspClient {
|
|
|
2835
2859
|
await this.initPromise;
|
|
2836
2860
|
}
|
|
2837
2861
|
}
|
|
2862
|
+
export async function runOmlWorkspaceLocalOperation(options) {
|
|
2863
|
+
const client = new InMemoryJsonRpcLspClient(options.workspaceRoot ? path.resolve(options.workspaceRoot) : process.cwd(), options.requestTimeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS, options.watchWorkspace === true, options.runtime);
|
|
2864
|
+
try {
|
|
2865
|
+
const params = options.params ?? {};
|
|
2866
|
+
switch (options.operation) {
|
|
2867
|
+
case 'lint':
|
|
2868
|
+
return await client.lintWorkspace(params);
|
|
2869
|
+
case 'validate':
|
|
2870
|
+
return await client.validateWorkspace(params);
|
|
2871
|
+
case 'assertions':
|
|
2872
|
+
return await client.assertionsWorkspace(params);
|
|
2873
|
+
case 'export':
|
|
2874
|
+
return await client.exportWorkspace(params);
|
|
2875
|
+
case 'render':
|
|
2876
|
+
return await client.renderWorkspace(params);
|
|
2877
|
+
default:
|
|
2878
|
+
throw new Error(`Unsupported local operation: ${String(options.operation)}`);
|
|
2879
|
+
}
|
|
2880
|
+
}
|
|
2881
|
+
finally {
|
|
2882
|
+
await client.close();
|
|
2883
|
+
}
|
|
2884
|
+
}
|
|
2838
2885
|
export async function startOmlRestServer(options) {
|
|
2839
2886
|
const workspaceRoot = options.workspaceRoot ? path.resolve(options.workspaceRoot) : process.cwd();
|
|
2840
2887
|
debugRest('rest.start.options', {
|