@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
package/src/cli.ts ADDED
@@ -0,0 +1,147 @@
1
+ // Copyright (c) 2026 Modelware. All rights reserved.
2
+
3
+ import { OmlLanguageMetaData } from '@oml/language';
4
+ import chalk from 'chalk';
5
+ import { Command } from 'commander';
6
+ import * as fs from 'node:fs/promises';
7
+ import * as path from 'node:path';
8
+ import * as url from 'node:url';
9
+ import { OmlCliAuthService } from './auth.js';
10
+ import { compileAction } from './commands/compile.js';
11
+ import { lintAction } from './commands/lint.js';
12
+ import { renderAction } from './commands/render.js';
13
+ import { notifyIfCliUpdateAvailable } from './update.js';
14
+ import { validateAction } from './commands/validate.js';
15
+
16
+ const __dirname = url.fileURLToPath(new URL('.', import.meta.url));
17
+
18
+ export async function runCli(argv: string[] = process.argv): Promise<void> {
19
+ const packagePath = path.resolve(__dirname, '..', 'package.json');
20
+ const packageContent = await fs.readFile(packagePath, 'utf-8');
21
+ const packageJson = JSON.parse(packageContent) as { version: string };
22
+ const updateCheck = notifyIfCliUpdateAvailable(packageJson.version);
23
+
24
+ const program = new Command();
25
+ program.version(packageJson.version);
26
+ const authService = new OmlCliAuthService();
27
+
28
+ program
29
+ .command('login')
30
+ .description('run GitHub device-flow sign-in for CLI authorization checks')
31
+ .action(async () => {
32
+ await authService.login({});
33
+ });
34
+
35
+ program
36
+ .command('logout')
37
+ .description('remove the local beta sign-in session')
38
+ .action(async () => {
39
+ await authService.logout();
40
+ });
41
+
42
+ program
43
+ .command('whoami')
44
+ .description('print the current beta sign-in session and authorization state')
45
+ .action(async () => {
46
+ await authService.whoami();
47
+ });
48
+
49
+ const fileExtensions = OmlLanguageMetaData.fileExtensions.join(', ');
50
+ program
51
+ .command('lint')
52
+ .argument('[file]', `source file (possible file extensions: ${fileExtensions})`)
53
+ .option('-w, --workspace <dir>', 'workspace root used to resolve cross-file references', '.')
54
+ .description('lints OML files and prints any syntax or validation errors')
55
+ .action(lintAction);
56
+
57
+ program
58
+ .command('render')
59
+ .option('-w, --workspace <workspace-folder>', 'workspace root used to resolve workspace:/ links (default: current directory)')
60
+ .requiredOption('-md, --md <input-folder>', 'folder containing markdown files to render')
61
+ .requiredOption('-web, --web <output-folder>', 'folder where rendered static site files are written')
62
+ .option('-owl, --owl <dir>', 'folder where compiled RDF and entailment files are written')
63
+ .option('-f, --format <ext>', 'RDF format extension for compile/reason output: ttl, trig, nt, nq, or n3', 'ttl')
64
+ .option('-c, --context <model-uri>', 'default model URI/path used for markdown files without contextUri; also enables wikilink template page generation')
65
+ .option('--clean', 'remove output folders before rebuilding')
66
+ .option('--only', 'skip reason/compile/lint and render from the existing owl output folder')
67
+ .option('--pretty', 'pretty-print Turtle/TriG output with blank lines between top-level blocks')
68
+ .option('-u, --unique-names-assumption [value]', 'enable or disable the unique names assumption', parseBooleanOption, true)
69
+ .option('-e, --explanations [value]', 'enable or disable inconsistency explanations', parseBooleanOption, true)
70
+ .option('-p, --profile [value]', 'include phase timings in the reasoner result', parseBooleanOption, false)
71
+ .description('reason the workspace, then render markdown files under the selected markdown folder to static html and copy referenced non-markdown assets')
72
+ .action(renderAction);
73
+
74
+ program
75
+ .command('compile')
76
+ .option('-w, --workspace <dir>', 'workspace root used to resolve and compile OML files', '.')
77
+ .option('-owl, --owl <dir>', 'folder where compiled RDF files are written')
78
+ .option('-f, --format <ext>', 'RDF format extension: ttl, trig, nt, nq, or n3', 'ttl')
79
+ .option('--clean', 'remove output folder before compiling')
80
+ .option('--only', 'skip lint and compile from the current workspace state')
81
+ .option('--pretty', 'pretty-print Turtle/TriG output with blank lines between top-level blocks')
82
+ .description('compile OML files to RDF and write them to an output folder')
83
+ .action(compileAction);
84
+
85
+ program
86
+ .command('reason')
87
+ .option('-w, --workspace <dir>', 'workspace root used to resolve and compile OML files', '.')
88
+ .option('-owl, --owl <dir>', 'folder where compiled RDF and entailment files are written')
89
+ .option('-f, --format <ext>', 'RDF format extension for compile output: ttl, trig, nt, nq, or n3', 'ttl')
90
+ .option('--clean', 'remove output folder before compiling')
91
+ .option('--only', 'skip compile/lint and reason from the existing owl output folder')
92
+ .option('--pretty', 'pretty-print Turtle/TriG output with blank lines between top-level blocks')
93
+ .option('-c, --check-only', 'only check consistency; skip entailment materialization and file output')
94
+ .option('-u, --unique-names-assumption [value]', 'enable or disable the unique names assumption', parseBooleanOption, true)
95
+ .option('-e, --explanations [value]', 'enable or disable inconsistency explanations', parseBooleanOption, true)
96
+ .option('-p, --profile [value]', 'include phase timings in the reasoner result', parseBooleanOption, false)
97
+ .description('compile OML files, then run consistency checking for every ontology in dependency order')
98
+ .action(async (opts) => {
99
+ const { reasonAction } = await import('./commands/reason.js');
100
+ await reasonAction(opts);
101
+ });
102
+
103
+ program
104
+ .command('validate')
105
+ .requiredOption('-md, --md <input-folder>', 'folder containing markdown files to validate recursively')
106
+ .option('-w, --workspace <dir>', 'workspace root used to resolve and compile OML files', '.')
107
+ .option('-owl, --owl <dir>', 'folder where compiled RDF and entailment files are written')
108
+ .option('-f, --format <ext>', 'RDF format extension for compile output: ttl, trig, nt, nq, or n3', 'ttl')
109
+ .option('--clean', 'remove output folder before compiling')
110
+ .option('--only', 'skip compile/lint and reason from the existing owl output folder')
111
+ .option('--pretty', 'pretty-print Turtle/TriG output with blank lines between top-level blocks')
112
+ .option('-u, --unique-names-assumption [value]', 'enable or disable the unique names assumption', parseBooleanOption, true)
113
+ .option('-e, --explanations [value]', 'enable or disable inconsistency explanations', parseBooleanOption, true)
114
+ .option('-p, --profile [value]', 'include phase timings in the reasoner result', parseBooleanOption, false)
115
+ .description('compile and reason the workspace, then validate nested markdown table-editor SHACL blocks against their context models')
116
+ .action(validateAction);
117
+
118
+ program.hook('preAction', async (_thisCommand, actionCommand) => {
119
+ if (actionCommand.name() === 'login' || actionCommand.name() === 'logout' || actionCommand.name() === 'whoami') {
120
+ return;
121
+ }
122
+ await authService.ensureAuthenticated('OML CLI');
123
+ });
124
+
125
+ await program.parseAsync(argv);
126
+ await updateCheck;
127
+ }
128
+
129
+ function parseBooleanOption(value: string | boolean): boolean {
130
+ if (typeof value === 'boolean') {
131
+ return value;
132
+ }
133
+ const normalized = value.trim().toLowerCase();
134
+ if (normalized === 'true') {
135
+ return true;
136
+ }
137
+ if (normalized === 'false') {
138
+ return false;
139
+ }
140
+ throw new Error(`Expected a boolean value, received '${value}'.`);
141
+ }
142
+
143
+ process.on('unhandledRejection', (error) => {
144
+ const message = error instanceof Error ? error.message : String(error);
145
+ console.error(chalk.red(message));
146
+ process.exit(1);
147
+ });