@oml/cli 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +75 -0
- package/bin/cli.js +6 -0
- package/out/auth.d.ts +25 -0
- package/out/auth.js +253 -0
- package/out/auth.js.map +1 -0
- package/out/backend/backend-types.d.ts +19 -0
- package/out/backend/backend-types.js +3 -0
- package/out/backend/backend-types.js.map +1 -0
- package/out/backend/create-backend.d.ts +2 -0
- package/out/backend/create-backend.js +6 -0
- package/out/backend/create-backend.js.map +1 -0
- package/out/backend/direct-backend.d.ts +17 -0
- package/out/backend/direct-backend.js +97 -0
- package/out/backend/direct-backend.js.map +1 -0
- package/out/backend/reasoned-output.d.ts +38 -0
- package/out/backend/reasoned-output.js +568 -0
- package/out/backend/reasoned-output.js.map +1 -0
- package/out/cli.d.ts +1 -0
- package/out/cli.js +132 -0
- package/out/cli.js.map +1 -0
- package/out/commands/closure.d.ts +33 -0
- package/out/commands/closure.js +537 -0
- package/out/commands/closure.js.map +1 -0
- package/out/commands/compile.d.ts +11 -0
- package/out/commands/compile.js +63 -0
- package/out/commands/compile.js.map +1 -0
- package/out/commands/lint.d.ts +5 -0
- package/out/commands/lint.js +31 -0
- package/out/commands/lint.js.map +1 -0
- package/out/commands/reason.d.ts +13 -0
- package/out/commands/reason.js +62 -0
- package/out/commands/reason.js.map +1 -0
- package/out/commands/render.d.ts +15 -0
- package/out/commands/render.js +753 -0
- package/out/commands/render.js.map +1 -0
- package/out/commands/validate.d.ts +5 -0
- package/out/commands/validate.js +186 -0
- package/out/commands/validate.js.map +1 -0
- package/out/main.d.ts +1 -0
- package/out/main.js +4 -0
- package/out/main.js.map +1 -0
- package/out/update.d.ts +1 -0
- package/out/update.js +79 -0
- package/out/update.js.map +1 -0
- package/out/util.d.ts +10 -0
- package/out/util.js +63 -0
- package/out/util.js.map +1 -0
- package/package.json +36 -0
- package/src/auth.ts +315 -0
- package/src/backend/backend-types.ts +25 -0
- package/src/backend/create-backend.ts +8 -0
- package/src/backend/direct-backend.ts +114 -0
- package/src/backend/reasoned-output.ts +697 -0
- package/src/cli.ts +147 -0
- package/src/commands/closure.ts +624 -0
- package/src/commands/compile.ts +88 -0
- package/src/commands/lint.ts +35 -0
- package/src/commands/reason.ts +79 -0
- package/src/commands/render.ts +1021 -0
- package/src/commands/validate.ts +226 -0
- package/src/main.ts +5 -0
- package/src/update.ts +103 -0
- package/src/util.ts +83 -0
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
// Copyright (c) 2026 Modelware. All rights reserved.
|
|
2
|
+
|
|
3
|
+
import { createOmlServices } from '@oml/language';
|
|
4
|
+
import chalk from 'chalk';
|
|
5
|
+
import { NodeFileSystem } from 'langium/node';
|
|
6
|
+
import { URI } from 'langium';
|
|
7
|
+
import * as fs from 'node:fs/promises';
|
|
8
|
+
import * as path from 'node:path';
|
|
9
|
+
import { normalizeFormatExtension, writeCompiledWorkspace } from '../backend/reasoned-output.js';
|
|
10
|
+
import { formatDuration } from '../util.js';
|
|
11
|
+
import { lintAction } from './lint.js';
|
|
12
|
+
|
|
13
|
+
export type CompileOptions = {
|
|
14
|
+
workspace?: string,
|
|
15
|
+
owl?: string,
|
|
16
|
+
format?: string,
|
|
17
|
+
clean?: boolean,
|
|
18
|
+
pretty?: boolean,
|
|
19
|
+
only?: boolean
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export const compileAction = async (opts: CompileOptions): Promise<void> => {
|
|
23
|
+
const workspaceRoot = resolveCompileWorkspaceRoot(opts.workspace);
|
|
24
|
+
const outputRoot = resolveCompileOutputRoot(workspaceRoot, opts.owl);
|
|
25
|
+
const format = normalizeFormatExtension(opts.format);
|
|
26
|
+
|
|
27
|
+
if (!opts.only) {
|
|
28
|
+
await lintAction(undefined, { workspace: workspaceRoot });
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const workspaceStat = await fs.stat(workspaceRoot).catch(() => undefined);
|
|
32
|
+
if (!workspaceStat || !workspaceStat.isDirectory()) {
|
|
33
|
+
console.error(chalk.red(`Workspace folder does not exist: ${workspaceRoot}`));
|
|
34
|
+
process.exit(1);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const sourceFiles = await findOmlFiles(workspaceRoot);
|
|
38
|
+
if (sourceFiles.length === 0) {
|
|
39
|
+
console.log(chalk.yellow(`No .oml files found under ${workspaceRoot}.`));
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (opts.clean) {
|
|
44
|
+
await fs.rm(outputRoot, { recursive: true, force: true });
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const startedAt = Date.now();
|
|
48
|
+
const servicesBundle = createOmlServices(NodeFileSystem);
|
|
49
|
+
await servicesBundle.Oml.shared.workspace.WorkspaceManager.initializeWorkspace([
|
|
50
|
+
{ uri: URI.file(workspaceRoot).toString(), name: path.basename(workspaceRoot) }
|
|
51
|
+
]);
|
|
52
|
+
const entries = await writeCompiledWorkspace(servicesBundle.Oml, workspaceRoot, outputRoot, format, opts.pretty === true);
|
|
53
|
+
|
|
54
|
+
console.log(
|
|
55
|
+
chalk.green(
|
|
56
|
+
`compile: ${entries.length} OML file(s) converted to .${format} in ${path.relative(process.cwd(), outputRoot) || outputRoot} [${formatDuration(Date.now() - startedAt)}]`
|
|
57
|
+
)
|
|
58
|
+
);
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
export function resolveCompileWorkspaceRoot(workspace: string | undefined): string {
|
|
62
|
+
return path.resolve(workspace ?? '.');
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export function resolveCompileOutputRoot(workspaceRoot: string, owl: string | undefined): string {
|
|
66
|
+
return path.resolve(owl ?? path.join(workspaceRoot, 'build', 'owl'));
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
async function findOmlFiles(root: string): Promise<string[]> {
|
|
70
|
+
const entries = await fs.readdir(root, { withFileTypes: true });
|
|
71
|
+
const results: string[] = [];
|
|
72
|
+
|
|
73
|
+
for (const entry of entries) {
|
|
74
|
+
const fullPath = path.join(root, entry.name);
|
|
75
|
+
if (entry.isDirectory()) {
|
|
76
|
+
if (entry.name === 'node_modules' || entry.name.startsWith('.')) {
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
results.push(...await findOmlFiles(fullPath));
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
if (entry.isFile() && entry.name.toLowerCase().endsWith('.oml')) {
|
|
83
|
+
results.push(fullPath);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return results;
|
|
88
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
// Copyright (c) 2026 Modelware. All rights reserved.
|
|
2
|
+
|
|
3
|
+
import chalk from 'chalk';
|
|
4
|
+
import { createBackend } from '../backend/create-backend.js';
|
|
5
|
+
import { formatDuration } from '../util.js';
|
|
6
|
+
|
|
7
|
+
export type LintOptions = {
|
|
8
|
+
workspace?: string,
|
|
9
|
+
workspaceRoot?: string
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export const lintAction = async (fileName: string | undefined, opts: LintOptions): Promise<void> => {
|
|
13
|
+
const startedAt = Date.now();
|
|
14
|
+
const workspaceRoot = opts.workspace ?? opts.workspaceRoot ?? '.';
|
|
15
|
+
const backend = createBackend();
|
|
16
|
+
try {
|
|
17
|
+
const result = await backend.validate(fileName, workspaceRoot);
|
|
18
|
+
if (result.filesChecked === 0) {
|
|
19
|
+
console.log(chalk.yellow(`No .oml files found under ${workspaceRoot}.`));
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
if (fileName && result.warnings === 0) {
|
|
23
|
+
console.log(chalk.green('lint: no syntax or validation errors found.'));
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
if (result.warnings > 0) {
|
|
27
|
+
console.log(chalk.yellow(`lint: ${result.filesChecked} OML file(s) checked with ${result.warnings} warning(s). [${formatDuration(Date.now() - startedAt)}]`));
|
|
28
|
+
process.exit(1);
|
|
29
|
+
} else {
|
|
30
|
+
console.log(chalk.green(`lint: ${result.filesChecked} OML file(s) checked. [${formatDuration(Date.now() - startedAt)}]`));
|
|
31
|
+
}
|
|
32
|
+
} finally {
|
|
33
|
+
await backend.dispose();
|
|
34
|
+
}
|
|
35
|
+
};
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
// Copyright (c) 2026 Modelware. All rights reserved.
|
|
2
|
+
|
|
3
|
+
import { createOmlServices } from '@oml/language';
|
|
4
|
+
import chalk from 'chalk';
|
|
5
|
+
import { NodeFileSystem } from 'langium/node';
|
|
6
|
+
import { URI } from 'langium';
|
|
7
|
+
import * as fs from 'node:fs/promises';
|
|
8
|
+
import * as path from 'node:path';
|
|
9
|
+
import { buildWorkspaceDocuments, collectWorkspaceOntologyEntries, normalizeFormatExtension, OntologyInconsistencyError, reasonWorkspaceOntologies } from '../backend/reasoned-output.js';
|
|
10
|
+
import { formatDuration } from '../util.js';
|
|
11
|
+
import { compileAction, resolveCompileOutputRoot, resolveCompileWorkspaceRoot } from './compile.js';
|
|
12
|
+
|
|
13
|
+
export type ReasonOptions = {
|
|
14
|
+
workspace?: string,
|
|
15
|
+
owl?: string,
|
|
16
|
+
format?: string,
|
|
17
|
+
clean?: boolean,
|
|
18
|
+
pretty?: boolean,
|
|
19
|
+
only?: boolean,
|
|
20
|
+
checkOnly?: boolean,
|
|
21
|
+
uniqueNamesAssumption?: boolean,
|
|
22
|
+
explanations?: boolean,
|
|
23
|
+
profile?: boolean
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export const reasonAction = async (opts: ReasonOptions): Promise<void> => {
|
|
27
|
+
const workspaceRoot = resolveCompileWorkspaceRoot(opts.workspace);
|
|
28
|
+
const outputRoot = resolveCompileOutputRoot(workspaceRoot, opts.owl);
|
|
29
|
+
const format = normalizeFormatExtension(opts.format);
|
|
30
|
+
if (opts.only && opts.clean) {
|
|
31
|
+
console.error(chalk.red('Cannot combine --only with --clean for reason.'));
|
|
32
|
+
process.exit(1);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if (!opts.only) {
|
|
36
|
+
await compileAction({
|
|
37
|
+
workspace: workspaceRoot,
|
|
38
|
+
owl: outputRoot,
|
|
39
|
+
format,
|
|
40
|
+
clean: opts.clean,
|
|
41
|
+
pretty: opts.pretty
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const outputStat = await fs.stat(outputRoot).catch(() => undefined);
|
|
46
|
+
if (!outputStat || !outputStat.isDirectory()) {
|
|
47
|
+
console.error(chalk.red(`OWL output folder does not exist: ${outputRoot}`));
|
|
48
|
+
process.exit(1);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const startedAt = Date.now();
|
|
52
|
+
const servicesBundle = createOmlServices(NodeFileSystem);
|
|
53
|
+
await servicesBundle.Oml.shared.workspace.WorkspaceManager.initializeWorkspace([
|
|
54
|
+
{ uri: URI.file(workspaceRoot).toString(), name: path.basename(workspaceRoot) }
|
|
55
|
+
]);
|
|
56
|
+
const documents = await buildWorkspaceDocuments(servicesBundle.Oml, workspaceRoot, true);
|
|
57
|
+
const entries = collectWorkspaceOntologyEntries(documents, outputRoot, format);
|
|
58
|
+
let result;
|
|
59
|
+
try {
|
|
60
|
+
result = await reasonWorkspaceOntologies(entries, {
|
|
61
|
+
outputRoot,
|
|
62
|
+
format,
|
|
63
|
+
pretty: opts.pretty ?? false,
|
|
64
|
+
explanations: opts.explanations ?? true,
|
|
65
|
+
uniqueNamesAssumption: opts.uniqueNamesAssumption ?? true,
|
|
66
|
+
checkOnly: opts.checkOnly ?? false,
|
|
67
|
+
profile: opts.profile ?? false,
|
|
68
|
+
});
|
|
69
|
+
} catch (error) {
|
|
70
|
+
if (error instanceof OntologyInconsistencyError) {
|
|
71
|
+
console.error(chalk.red(error.message));
|
|
72
|
+
process.exit(1);
|
|
73
|
+
}
|
|
74
|
+
throw error;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const action = opts.checkOnly ? 'checked in' : 'generated in';
|
|
78
|
+
console.log(chalk.green(`reason: ${result.ontologiesReasoned} ontology file(s) ${action} ${path.relative(process.cwd(), outputRoot) || outputRoot} [${formatDuration(Date.now() - startedAt)}]`));
|
|
79
|
+
};
|