@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.
Files changed (63) hide show
  1. package/README.md +75 -0
  2. package/bin/cli.js +6 -0
  3. package/out/auth.d.ts +25 -0
  4. package/out/auth.js +253 -0
  5. package/out/auth.js.map +1 -0
  6. package/out/backend/backend-types.d.ts +19 -0
  7. package/out/backend/backend-types.js +3 -0
  8. package/out/backend/backend-types.js.map +1 -0
  9. package/out/backend/create-backend.d.ts +2 -0
  10. package/out/backend/create-backend.js +6 -0
  11. package/out/backend/create-backend.js.map +1 -0
  12. package/out/backend/direct-backend.d.ts +17 -0
  13. package/out/backend/direct-backend.js +97 -0
  14. package/out/backend/direct-backend.js.map +1 -0
  15. package/out/backend/reasoned-output.d.ts +38 -0
  16. package/out/backend/reasoned-output.js +568 -0
  17. package/out/backend/reasoned-output.js.map +1 -0
  18. package/out/cli.d.ts +1 -0
  19. package/out/cli.js +132 -0
  20. package/out/cli.js.map +1 -0
  21. package/out/commands/closure.d.ts +33 -0
  22. package/out/commands/closure.js +537 -0
  23. package/out/commands/closure.js.map +1 -0
  24. package/out/commands/compile.d.ts +11 -0
  25. package/out/commands/compile.js +63 -0
  26. package/out/commands/compile.js.map +1 -0
  27. package/out/commands/lint.d.ts +5 -0
  28. package/out/commands/lint.js +31 -0
  29. package/out/commands/lint.js.map +1 -0
  30. package/out/commands/reason.d.ts +13 -0
  31. package/out/commands/reason.js +62 -0
  32. package/out/commands/reason.js.map +1 -0
  33. package/out/commands/render.d.ts +15 -0
  34. package/out/commands/render.js +753 -0
  35. package/out/commands/render.js.map +1 -0
  36. package/out/commands/validate.d.ts +5 -0
  37. package/out/commands/validate.js +186 -0
  38. package/out/commands/validate.js.map +1 -0
  39. package/out/main.d.ts +1 -0
  40. package/out/main.js +4 -0
  41. package/out/main.js.map +1 -0
  42. package/out/update.d.ts +1 -0
  43. package/out/update.js +79 -0
  44. package/out/update.js.map +1 -0
  45. package/out/util.d.ts +10 -0
  46. package/out/util.js +63 -0
  47. package/out/util.js.map +1 -0
  48. package/package.json +36 -0
  49. package/src/auth.ts +315 -0
  50. package/src/backend/backend-types.ts +25 -0
  51. package/src/backend/create-backend.ts +8 -0
  52. package/src/backend/direct-backend.ts +114 -0
  53. package/src/backend/reasoned-output.ts +697 -0
  54. package/src/cli.ts +147 -0
  55. package/src/commands/closure.ts +624 -0
  56. package/src/commands/compile.ts +88 -0
  57. package/src/commands/lint.ts +35 -0
  58. package/src/commands/reason.ts +79 -0
  59. package/src/commands/render.ts +1021 -0
  60. package/src/commands/validate.ts +226 -0
  61. package/src/main.ts +5 -0
  62. package/src/update.ts +103 -0
  63. 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
+ };