@oml/markdown 0.12.0 → 0.14.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 (72) hide show
  1. package/out/index.d.ts +1 -0
  2. package/out/index.js +1 -0
  3. package/out/index.js.map +1 -1
  4. package/out/md/md-execution.d.ts +3 -3
  5. package/out/md/md-execution.js +1 -1
  6. package/out/md/md-execution.js.map +1 -1
  7. package/out/md/md-executor.js +6 -8
  8. package/out/md/md-executor.js.map +1 -1
  9. package/out/md/md-frontmatter.d.ts +1 -1
  10. package/out/md/md-frontmatter.js +15 -10
  11. package/out/md/md-frontmatter.js.map +1 -1
  12. package/out/md/md-runtime.js +1 -1
  13. package/out/md/md-runtime.js.map +1 -1
  14. package/out/md/md-types.d.ts +2 -2
  15. package/out/renderers/diagram-renderer.js +231 -12
  16. package/out/renderers/diagram-renderer.js.map +1 -1
  17. package/out/renderers/graph-renderer.js +2 -2
  18. package/out/renderers/graph-renderer.js.map +1 -1
  19. package/out/renderers/table-renderer.js +25 -10
  20. package/out/renderers/table-renderer.js.map +1 -1
  21. package/out/static/browser-runtime.bundle.js +489 -25
  22. package/out/static/browser-runtime.bundle.js.map +3 -3
  23. package/out/static/browser-runtime.js +258 -0
  24. package/out/static/browser-runtime.js.map +1 -1
  25. package/out/static/runtime-assets.d.ts +1 -1
  26. package/out/static/runtime-assets.js +1 -0
  27. package/out/static/runtime-assets.js.map +1 -1
  28. package/out/template/binder.d.ts +2 -0
  29. package/out/template/binder.js +56 -0
  30. package/out/template/binder.js.map +1 -0
  31. package/out/template/catalog.d.ts +8 -0
  32. package/out/template/catalog.js +26 -0
  33. package/out/template/catalog.js.map +1 -0
  34. package/out/template/compose.d.ts +7 -0
  35. package/out/template/compose.js +93 -0
  36. package/out/template/compose.js.map +1 -0
  37. package/out/template/definition.d.ts +3 -0
  38. package/out/template/definition.js +204 -0
  39. package/out/template/definition.js.map +1 -0
  40. package/out/template/engine.d.ts +8 -0
  41. package/out/template/engine.js +30 -0
  42. package/out/template/engine.js.map +1 -0
  43. package/out/template/index.d.ts +7 -0
  44. package/out/template/index.js +9 -0
  45. package/out/template/index.js.map +1 -0
  46. package/out/template/resolver.d.ts +4 -0
  47. package/out/template/resolver.js +58 -0
  48. package/out/template/resolver.js.map +1 -0
  49. package/out/template/types.d.ts +82 -0
  50. package/out/template/types.js +3 -0
  51. package/out/template/types.js.map +1 -0
  52. package/package.json +2 -2
  53. package/src/index.ts +1 -0
  54. package/src/md/md-execution.ts +3 -3
  55. package/src/md/md-executor.ts +6 -9
  56. package/src/md/md-frontmatter.ts +15 -10
  57. package/src/md/md-runtime.ts +1 -1
  58. package/src/md/md-types.ts +2 -2
  59. package/src/renderers/diagram-renderer.ts +229 -12
  60. package/src/renderers/graph-renderer.ts +2 -2
  61. package/src/renderers/table-renderer.ts +26 -10
  62. package/src/static/browser-runtime.ts +305 -0
  63. package/src/static/markdown-webview.css +13 -0
  64. package/src/static/runtime-assets.ts +1 -0
  65. package/src/template/binder.ts +70 -0
  66. package/src/template/catalog.ts +35 -0
  67. package/src/template/compose.ts +107 -0
  68. package/src/template/definition.ts +222 -0
  69. package/src/template/engine.ts +45 -0
  70. package/src/template/index.ts +9 -0
  71. package/src/template/resolver.ts +75 -0
  72. package/src/template/types.ts +111 -0
@@ -0,0 +1,204 @@
1
+ // Copyright (c) 2026 Modelware. All rights reserved.
2
+ import { extractLeadingFrontMatter } from '../md/md-frontmatter.js';
3
+ export function parseTemplateDefinition(content, sourceUri) {
4
+ const frontMatter = extractLeadingFrontMatter(content);
5
+ const data = frontMatter?.data;
6
+ if (!data) {
7
+ return undefined;
8
+ }
9
+ const rawTemplate = data.template;
10
+ if (!isRecord(rawTemplate)) {
11
+ return undefined;
12
+ }
13
+ const id = normalizeTemplateType(typeof rawTemplate.id === 'string' ? rawTemplate.id : '');
14
+ if (!id) {
15
+ return undefined;
16
+ }
17
+ const name = typeof rawTemplate.name === 'string' && rawTemplate.name.trim().length > 0
18
+ ? rawTemplate.name.trim()
19
+ : undefined;
20
+ const rank = parseRank(rawTemplate.rank);
21
+ const exposures = parseTemplateExposures(rawTemplate.expose);
22
+ const parameters = parseTemplateParameters(rawTemplate.params);
23
+ return {
24
+ id,
25
+ name,
26
+ rank,
27
+ exposures,
28
+ parameters,
29
+ body: content,
30
+ sourceUri,
31
+ };
32
+ }
33
+ export function deriveContextLabelFromIri(iri) {
34
+ const normalized = iri.trim().replace(/^<|>$/g, '');
35
+ if (!normalized) {
36
+ return 'IRI';
37
+ }
38
+ const hashIndex = normalized.lastIndexOf('#');
39
+ if (hashIndex >= 0 && hashIndex < normalized.length - 1) {
40
+ return decodeIriSegment(normalized.slice(hashIndex + 1));
41
+ }
42
+ const withoutTrailingSlash = normalized.replace(/\/+$/, '');
43
+ const slashIndex = withoutTrailingSlash.lastIndexOf('/');
44
+ if (slashIndex >= 0 && slashIndex < withoutTrailingSlash.length - 1) {
45
+ return decodeIriSegment(withoutTrailingSlash.slice(slashIndex + 1));
46
+ }
47
+ return decodeIriSegment(withoutTrailingSlash);
48
+ }
49
+ function normalizeTemplateType(value) {
50
+ let normalized = value.trim();
51
+ const wikilinkMatch = /^\[\[([^\]]+)\]\]$/.exec(normalized);
52
+ if (wikilinkMatch) {
53
+ normalized = (wikilinkMatch[1] ?? '').trim();
54
+ }
55
+ return normalized.replace(/^<|>$/g, '');
56
+ }
57
+ function parseTemplateExposures(raw) {
58
+ const entries = Array.isArray(raw) ? raw : raw ? [raw] : [];
59
+ const exposures = [];
60
+ for (const entry of entries) {
61
+ if (!isRecord(entry) || typeof entry.kind !== 'string') {
62
+ continue;
63
+ }
64
+ const kind = entry.kind.trim();
65
+ if (kind === 'navigation') {
66
+ const match = isRecord(entry.match) ? entry.match : undefined;
67
+ const anyTypeOf = asNormalizedStringArray(match?.anyTypeOf);
68
+ const allTypesOf = asNormalizedStringArray(match?.allTypesOf);
69
+ exposures.push({
70
+ kind: 'navigation',
71
+ match: (anyTypeOf.length > 0 || allTypesOf.length > 0)
72
+ ? { anyTypeOf, allTypesOf }
73
+ : undefined
74
+ });
75
+ continue;
76
+ }
77
+ if (kind === 'compose') {
78
+ const placementRaw = typeof entry.placement === 'string' ? entry.placement.trim() : '';
79
+ const placement = placementRaw === 'prepend' || placementRaw === 'append' ? placementRaw : undefined;
80
+ exposures.push({ kind: 'compose', placement });
81
+ continue;
82
+ }
83
+ if (kind === 'call') {
84
+ const selection = isRecord(entry.selection) ? entry.selection : undefined;
85
+ const min = toNonNegativeInteger(selection?.min);
86
+ const max = toNonNegativeInteger(selection?.max);
87
+ exposures.push({
88
+ kind: 'call',
89
+ selection: min !== undefined || max !== undefined ? { min, max } : undefined
90
+ });
91
+ }
92
+ }
93
+ return exposures;
94
+ }
95
+ function parseTemplateParameters(raw) {
96
+ if (!Array.isArray(raw)) {
97
+ return [];
98
+ }
99
+ const params = [];
100
+ for (const entry of raw) {
101
+ if (!isRecord(entry)) {
102
+ continue;
103
+ }
104
+ const id = typeof entry.id === 'string' ? entry.id.trim() : '';
105
+ const type = typeof entry.type === 'string' ? entry.type.trim() : '';
106
+ if (!id || !isSupportedParameterType(type)) {
107
+ continue;
108
+ }
109
+ const required = typeof entry.required === 'boolean' ? entry.required : undefined;
110
+ const fromValue = typeof entry.from === 'string' ? entry.from.trim() : '';
111
+ const from = isSupportedBindingSource(fromValue) ? fromValue : undefined;
112
+ const description = typeof entry.description === 'string' && entry.description.trim().length > 0
113
+ ? entry.description.trim()
114
+ : undefined;
115
+ params.push({
116
+ id,
117
+ type,
118
+ required,
119
+ from,
120
+ defaultValue: toTemplateValue(entry.defaultValue),
121
+ description,
122
+ });
123
+ }
124
+ return params;
125
+ }
126
+ function isSupportedParameterType(value) {
127
+ return value === 'iri'
128
+ || value === 'string'
129
+ || value === 'number'
130
+ || value === 'boolean'
131
+ || value === 'iri[]'
132
+ || value === 'json';
133
+ }
134
+ function isSupportedBindingSource(value) {
135
+ return value === 'context.member'
136
+ || value === 'context.ontology'
137
+ || value === 'context.modelUri'
138
+ || value === 'context.selection[*]'
139
+ || /^context\.selection\[\d+]$/.test(value)
140
+ || value === 'user';
141
+ }
142
+ function toTemplateValue(value) {
143
+ if (value === null) {
144
+ return null;
145
+ }
146
+ if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {
147
+ return value;
148
+ }
149
+ if (Array.isArray(value)) {
150
+ return value.every((entry) => typeof entry === 'string') ? value : undefined;
151
+ }
152
+ if (isRecord(value)) {
153
+ return value;
154
+ }
155
+ return undefined;
156
+ }
157
+ function parseRank(value) {
158
+ if (typeof value === 'number' && Number.isFinite(value)) {
159
+ return value;
160
+ }
161
+ if (typeof value === 'string') {
162
+ const parsed = Number(value.trim());
163
+ if (Number.isFinite(parsed)) {
164
+ return parsed;
165
+ }
166
+ }
167
+ return 0;
168
+ }
169
+ function asNormalizedStringArray(value) {
170
+ if (!Array.isArray(value)) {
171
+ return [];
172
+ }
173
+ return value
174
+ .filter((entry) => typeof entry === 'string')
175
+ .map((entry) => normalizeTemplateType(entry))
176
+ .filter((entry) => entry.length > 0);
177
+ }
178
+ function toNonNegativeInteger(value) {
179
+ if (typeof value === 'number' && Number.isInteger(value) && value >= 0) {
180
+ return value;
181
+ }
182
+ if (typeof value === 'string') {
183
+ const parsed = Number.parseInt(value.trim(), 10);
184
+ if (Number.isInteger(parsed) && parsed >= 0) {
185
+ return parsed;
186
+ }
187
+ }
188
+ return undefined;
189
+ }
190
+ function isRecord(value) {
191
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
192
+ }
193
+ function decodeIriSegment(value) {
194
+ if (!value) {
195
+ return 'IRI';
196
+ }
197
+ try {
198
+ return decodeURIComponent(value);
199
+ }
200
+ catch {
201
+ return value;
202
+ }
203
+ }
204
+ //# sourceMappingURL=definition.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"definition.js","sourceRoot":"","sources":["../../src/template/definition.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import type { TemplateDefinition, TemplateInvocation, TemplateValue } from './types.js';
2
+ export interface TemplateRenderResult {
3
+ output: string;
4
+ values: Record<string, TemplateValue>;
5
+ missingRequired: string[];
6
+ }
7
+ export declare function renderTemplate(template: TemplateDefinition, invocation: TemplateInvocation): TemplateRenderResult;
8
+ export declare function interpolateTemplateBody(source: string, values: Readonly<Record<string, TemplateValue>>): string;
@@ -0,0 +1,30 @@
1
+ // Copyright (c) 2026 Modelware. All rights reserved.
2
+ import { bindTemplateParameters } from './binder.js';
3
+ export function renderTemplate(template, invocation) {
4
+ const bound = bindTemplateParameters(template, invocation.context, invocation.args);
5
+ const output = interpolateTemplateBody(template.body, bound.values);
6
+ return {
7
+ output,
8
+ values: bound.values,
9
+ missingRequired: bound.missingRequired
10
+ };
11
+ }
12
+ export function interpolateTemplateBody(source, values) {
13
+ return source.replace(/\$\{([A-Za-z_][A-Za-z0-9_]*)\}/g, (_match, key) => {
14
+ if (!(key in values)) {
15
+ return '';
16
+ }
17
+ const value = values[key];
18
+ if (Array.isArray(value)) {
19
+ return value.map((entry) => String(entry)).join(', ');
20
+ }
21
+ if (value === null || value === undefined) {
22
+ return '';
23
+ }
24
+ if (typeof value === 'object') {
25
+ return JSON.stringify(value);
26
+ }
27
+ return String(value);
28
+ });
29
+ }
30
+ //# sourceMappingURL=engine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engine.js","sourceRoot":"","sources":["../../src/template/engine.ts"],"names":[],"mappings":"AAAA,qDAAqD;AAErD,OAAO,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AASrD,MAAM,UAAU,cAAc,CAC1B,QAA4B,EAC5B,UAA8B;IAE9B,MAAM,KAAK,GAAG,sBAAsB,CAAC,QAAQ,EAAE,UAAU,CAAC,OAAO,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC;IACpF,MAAM,MAAM,GAAG,uBAAuB,CAAC,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IACpE,OAAO;QACH,MAAM;QACN,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,eAAe,EAAE,KAAK,CAAC,eAAe;KACzC,CAAC;AACN,CAAC;AAED,MAAM,UAAU,uBAAuB,CACnC,MAAc,EACd,MAA+C;IAE/C,OAAO,MAAM,CAAC,OAAO,CAAC,iCAAiC,EAAE,CAAC,MAAc,EAAE,GAAW,EAAU,EAAE;QAC7F,IAAI,CAAC,CAAC,GAAG,IAAI,MAAM,CAAC,EAAE,CAAC;YACnB,OAAO,EAAE,CAAC;QACd,CAAC;QACD,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;QAC1B,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YACvB,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC1D,CAAC;QACD,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxC,OAAO,EAAE,CAAC;QACd,CAAC;QACD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC5B,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QACjC,CAAC;QACD,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;IACzB,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -0,0 +1,7 @@
1
+ export * from './types.js';
2
+ export * from './catalog.js';
3
+ export * from './resolver.js';
4
+ export * from './binder.js';
5
+ export * from './engine.js';
6
+ export * from './compose.js';
7
+ export * from './definition.js';
@@ -0,0 +1,9 @@
1
+ // Copyright (c) 2026 Modelware. All rights reserved.
2
+ export * from './types.js';
3
+ export * from './catalog.js';
4
+ export * from './resolver.js';
5
+ export * from './binder.js';
6
+ export * from './engine.js';
7
+ export * from './compose.js';
8
+ export * from './definition.js';
9
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/template/index.ts"],"names":[],"mappings":"AAAA,qDAAqD;AAErD,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC"}
@@ -0,0 +1,4 @@
1
+ import { type TemplateCatalog } from './catalog.js';
2
+ import type { TemplateDefinition, TemplateResolutionResult } from './types.js';
3
+ export declare function resolveTemplateById(catalog: TemplateCatalog, templateId: string): TemplateDefinition | undefined;
4
+ export declare function resolveTemplateForNavigation(catalog: TemplateCatalog, rdfTypes: ReadonlyArray<string>): TemplateResolutionResult;
@@ -0,0 +1,58 @@
1
+ // Copyright (c) 2026 Modelware. All rights reserved.
2
+ import { getTemplateById } from './catalog.js';
3
+ export function resolveTemplateById(catalog, templateId) {
4
+ return getTemplateById(catalog, templateId);
5
+ }
6
+ export function resolveTemplateForNavigation(catalog, rdfTypes) {
7
+ const candidates = collectNavigationCandidates(catalog, rdfTypes);
8
+ const template = selectBestTemplate(candidates);
9
+ return { template, candidates };
10
+ }
11
+ function collectNavigationCandidates(catalog, rdfTypes) {
12
+ const normalizedTypes = [...new Set(rdfTypes.map(normalizeIri).filter((value) => value.length > 0))];
13
+ const normalizedTypeSet = new Set(normalizedTypes);
14
+ const results = [];
15
+ for (const template of catalog.all) {
16
+ const exposures = template.exposures?.filter((exposure) => exposure.kind === 'navigation') ?? [];
17
+ if (exposures.length === 0) {
18
+ continue;
19
+ }
20
+ let bestScoreForTemplate;
21
+ for (const exposure of exposures) {
22
+ const score = scoreNavigationExposure(exposure, normalizedTypeSet);
23
+ if (score === undefined) {
24
+ continue;
25
+ }
26
+ if (bestScoreForTemplate === undefined || score > bestScoreForTemplate) {
27
+ bestScoreForTemplate = score;
28
+ }
29
+ }
30
+ if (bestScoreForTemplate === undefined) {
31
+ continue;
32
+ }
33
+ const rank = Number.isFinite(template.rank) ? Number(template.rank) : 0;
34
+ results.push({ template, score: bestScoreForTemplate + rank });
35
+ }
36
+ return results.sort((left, right) => right.score - left.score || left.template.id.localeCompare(right.template.id));
37
+ }
38
+ function scoreNavigationExposure(exposure, rdfTypeSet) {
39
+ const anyTypeOf = (exposure.match?.anyTypeOf ?? []).map(normalizeIri).filter((value) => value.length > 0);
40
+ const allTypesOf = (exposure.match?.allTypesOf ?? []).map(normalizeIri).filter((value) => value.length > 0);
41
+ if (allTypesOf.length > 0 && allTypesOf.some((iri) => !rdfTypeSet.has(iri))) {
42
+ return undefined;
43
+ }
44
+ if (anyTypeOf.length > 0 && !anyTypeOf.some((iri) => rdfTypeSet.has(iri))) {
45
+ return undefined;
46
+ }
47
+ if (allTypesOf.length === 0 && anyTypeOf.length === 0) {
48
+ return 0;
49
+ }
50
+ return (allTypesOf.length * 10) + anyTypeOf.length;
51
+ }
52
+ function selectBestTemplate(candidates) {
53
+ return candidates.length > 0 ? candidates[0].template : undefined;
54
+ }
55
+ function normalizeIri(value) {
56
+ return value.trim().replace(/^<|>$/g, '');
57
+ }
58
+ //# sourceMappingURL=resolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolver.js","sourceRoot":"","sources":["../../src/template/resolver.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,82 @@
1
+ export type TemplateValue = string | number | boolean | null | string[] | Record<string, unknown>;
2
+ export type TemplateParameterType = 'iri' | 'string' | 'number' | 'boolean' | 'iri[]' | 'json';
3
+ export type TemplateBindingSource = 'context.member' | 'context.ontology' | 'context.modelUri' | `context.selection[${number}]` | 'context.selection[*]' | 'user';
4
+ export interface TemplateParameterDefinition {
5
+ id: string;
6
+ type: TemplateParameterType;
7
+ required?: boolean;
8
+ from?: TemplateBindingSource;
9
+ defaultValue?: TemplateValue;
10
+ description?: string;
11
+ }
12
+ export interface TemplateNavigationMatch {
13
+ anyTypeOf?: string[];
14
+ allTypesOf?: string[];
15
+ }
16
+ export interface TemplateNavigationExposure {
17
+ kind: 'navigation';
18
+ match?: TemplateNavigationMatch;
19
+ }
20
+ export interface TemplateComposeExposure {
21
+ kind: 'compose';
22
+ placement?: 'prepend' | 'append';
23
+ }
24
+ export interface TemplateCallExposure {
25
+ kind: 'call';
26
+ selection?: {
27
+ min?: number;
28
+ max?: number;
29
+ };
30
+ }
31
+ export type TemplateExposure = TemplateNavigationExposure | TemplateComposeExposure | TemplateCallExposure;
32
+ export interface TemplateDefinition {
33
+ id: string;
34
+ name?: string;
35
+ rank?: number;
36
+ exposures?: TemplateExposure[];
37
+ parameters?: TemplateParameterDefinition[];
38
+ body: string;
39
+ sourceUri?: string;
40
+ }
41
+ export type TemplateInvocationMode = 'navigation' | 'compose' | 'call' | 'preview' | 'inline' | 'newDocument';
42
+ export interface TemplateInvocationContext {
43
+ invocation: {
44
+ mode: TemplateInvocationMode;
45
+ sourceDocumentUri?: string;
46
+ referenceDocumentUri?: string;
47
+ };
48
+ model?: {
49
+ ontologyIri?: string;
50
+ modelUri?: string;
51
+ };
52
+ focus?: {
53
+ memberIri?: string;
54
+ rdfTypes?: string[];
55
+ };
56
+ selection?: {
57
+ iris?: string[];
58
+ rows?: Array<{
59
+ iri: string;
60
+ cells: Record<string, string>;
61
+ }>;
62
+ };
63
+ vars?: Record<string, TemplateValue>;
64
+ }
65
+ export interface TemplateInvocation {
66
+ templateId: string;
67
+ mode: TemplateInvocationMode;
68
+ context: TemplateInvocationContext;
69
+ args?: Record<string, TemplateValue>;
70
+ }
71
+ export interface TemplateResolutionCandidate {
72
+ template: TemplateDefinition;
73
+ score: number;
74
+ }
75
+ export interface TemplateResolutionResult {
76
+ template?: TemplateDefinition;
77
+ candidates: TemplateResolutionCandidate[];
78
+ }
79
+ export interface TemplateBindResult {
80
+ values: Record<string, TemplateValue>;
81
+ missingRequired: string[];
82
+ }
@@ -0,0 +1,3 @@
1
+ // Copyright (c) 2026 Modelware. All rights reserved.
2
+ export {};
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/template/types.ts"],"names":[],"mappings":"AAAA,qDAAqD"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@oml/markdown",
3
3
  "description": "Markdown runtime and execution contracts for OML",
4
- "version": "0.12.0",
4
+ "version": "0.14.0",
5
5
  "type": "module",
6
6
  "engines": {
7
7
  "node": ">=20.10.0",
@@ -56,7 +56,7 @@
56
56
  "dependencies": {
57
57
  "@antv/x6": "^3.1.6",
58
58
  "@dagrejs/dagre": "^2.0.4",
59
- "@oml/owl": "0.12.0",
59
+ "@oml/owl": "0.14.0",
60
60
  "chart.js": "^4.4.0",
61
61
  "markdown-it": "^14.1.1",
62
62
  "reflect-metadata": "^0.2.2",
package/src/index.ts CHANGED
@@ -2,3 +2,4 @@
2
2
 
3
3
  export * from './md/index.js';
4
4
  export * from './static/index.js';
5
+ export * from './template/index.js';
@@ -1,6 +1,6 @@
1
1
  // Copyright (c) 2026 Modelware. All rights reserved.
2
2
 
3
- export const MarkdownExecutionRequest = 'oml/markdown/execute';
3
+ export const MarkdownExecutionRequest = 'oml/markdown';
4
4
 
5
5
  export type MdBlockKind =
6
6
  | 'table'
@@ -24,8 +24,8 @@ export interface MdExecutableBlock {
24
24
  }
25
25
 
26
26
  export interface MdExecuteBlocksParams {
27
- documentUri: string;
28
- modelUri?: string;
27
+ markdownUri: string;
28
+ modelUri: string;
29
29
  blocks: MdExecutableBlock[];
30
30
  }
31
31
 
@@ -24,14 +24,11 @@ export class MarkdownExecutor {
24
24
  constructor(private readonly backend: MarkdownExecutionBackend) {}
25
25
 
26
26
  async executeBlocks(params: MdExecuteBlocksParams): Promise<MdExecuteBlocksResult> {
27
- const resolvedModelUri = params.modelUri?.trim() || undefined;
28
- const contextQuadCount = resolvedModelUri && this.backend.countContextQuads
27
+ const resolvedModelUri = params.modelUri.trim();
28
+ const contextQuadCount = this.backend.countContextQuads
29
29
  ? await this.backend.countContextQuads(resolvedModelUri)
30
30
  : undefined;
31
-
32
- if (resolvedModelUri) {
33
- await this.backend.ensureContext(resolvedModelUri);
34
- }
31
+ await this.backend.ensureContext(resolvedModelUri);
35
32
 
36
33
  const results: MdBlockExecutionResult[] = [];
37
34
  for (const block of params.blocks) {
@@ -405,14 +402,14 @@ export class MarkdownExecutor {
405
402
  }
406
403
 
407
404
  function preprocessQuerySource(backend: MarkdownExecutionBackend, modelUri: string, source: string): string {
408
- if (!source.includes('${contextIri}')) {
405
+ if (!source.includes('${ontologyIri}')) {
409
406
  return source;
410
407
  }
411
- return source.split('${contextIri}').join(backend.resolveContextIri(modelUri));
408
+ return source.split('${ontologyIri}').join(backend.resolveContextIri(modelUri));
412
409
  }
413
410
 
414
411
  function missingContext(blockId: string, kind: MdBlockExecutionResult['kind']): MdBlockExecutionResult {
415
- return queryFailed(blockId, kind, 'No contextUri model is available for this markdown document.');
412
+ return queryFailed(blockId, kind, 'No ontologyIri model is available for this markdown document.');
416
413
  }
417
414
 
418
415
  function queryFailed(blockId: string, kind: MdBlockExecutionResult['kind'], message: string): MdBlockExecutionResult {
@@ -14,40 +14,45 @@ export function stripLeadingFrontMatter(markdown: string): string {
14
14
 
15
15
  export function extractLeadingFrontMatter(markdown: string): MarkdownFrontMatter | undefined {
16
16
  const normalized = markdown.replace(/^\uFEFF/, '');
17
- const yamlMatch = /^(---\s*\r?\n[\s\S]*?\r?\n---(?:\s*\r?\n|$))/.exec(normalized);
17
+ const yamlMatch = /^(---[ \t]*\r?\n[\s\S]*?\r?\n---[ \t]*(?:\r?\n|$))/.exec(normalized);
18
18
  if (yamlMatch) {
19
19
  const yamlBody = yamlMatch[1]
20
- .replace(/^---\s*\r?\n/, '')
21
- .replace(/\r?\n---(?:\s*\r?\n|$)$/, '');
20
+ .replace(/^---[ \t]*\r?\n/, '')
21
+ .replace(/\r?\n---[ \t]*(?:\r?\n|$)$/, '');
22
22
  const yamlData = parseYamlMap(yamlBody);
23
23
  return {
24
24
  raw: yamlMatch[1],
25
- contextUri: extractContextUriFromData(yamlData) ?? extractContextUri(yamlMatch[1]),
25
+ contextOntologyIri: extractContextIriFromData(yamlData) ?? extractContextIri(yamlMatch[1]),
26
26
  data: yamlData,
27
27
  };
28
28
  }
29
- const tomlMatch = /^(\+\+\+\s*\r?\n[\s\S]*?\r?\n\+\+\+(?:\s*\r?\n|$))/.exec(normalized);
29
+ const tomlMatch = /^(\+\+\+[ \t]*\r?\n[\s\S]*?\r?\n\+\+\+[ \t]*(?:\r?\n|$))/.exec(normalized);
30
30
  if (tomlMatch) {
31
31
  return {
32
32
  raw: tomlMatch[1],
33
- contextUri: extractContextUri(tomlMatch[1])
33
+ contextOntologyIri: extractContextIri(tomlMatch[1])
34
34
  };
35
35
  }
36
36
  return undefined;
37
37
  }
38
38
 
39
- export function extractContextUri(frontMatterRaw: string): string | undefined {
40
- const match = /^contextUri\s*:\s*(.+)$/m.exec(frontMatterRaw);
39
+ export function extractContextIri(frontMatterRaw: string): string | undefined {
40
+ const match = /^ontologyIri\s*:\s*(.+)$/m.exec(frontMatterRaw)
41
+ ?? /^ontology\s*:\s*(.+)$/m.exec(frontMatterRaw);
41
42
  if (!match) {
42
43
  return undefined;
43
44
  }
44
45
  return match[1].trim().replace(/^['"]|['"]$/g, '');
45
46
  }
46
47
 
47
- function extractContextUriFromData(data: Record<string, unknown> | undefined): string | undefined {
48
+ function extractContextIriFromData(data: Record<string, unknown> | undefined): string | undefined {
48
49
  if (!data) {
49
50
  return undefined;
50
51
  }
51
- const value = data.contextUri;
52
+ const value = typeof data.ontologyIri === 'string'
53
+ ? data.ontologyIri
54
+ : typeof data.ontology === 'string'
55
+ ? data.ontology
56
+ : undefined;
52
57
  return typeof value === 'string' ? value : undefined;
53
58
  }
@@ -31,7 +31,7 @@ export class MarkdownPreviewRuntime {
31
31
  markdown: stripped,
32
32
  renderedHtml,
33
33
  frontMatter,
34
- contextUri: frontMatter?.contextUri,
34
+ contextOntologyIri: frontMatter?.contextOntologyIri,
35
35
  codeBlocks,
36
36
  executableBlocks
37
37
  };
@@ -12,7 +12,7 @@ export interface ParsedCodeBlock {
12
12
 
13
13
  export interface MarkdownFrontMatter {
14
14
  raw: string;
15
- contextUri?: string;
15
+ contextOntologyIri?: string;
16
16
  data?: Record<string, unknown>;
17
17
  }
18
18
 
@@ -25,7 +25,7 @@ export interface PreparedMarkdownDocument {
25
25
  markdown: string;
26
26
  renderedHtml: string;
27
27
  frontMatter?: MarkdownFrontMatter;
28
- contextUri?: string;
28
+ contextOntologyIri?: string;
29
29
  codeBlocks: ParsedCodeBlock[];
30
30
  executableBlocks: PreparedCodeBlock[];
31
31
  }