@oml/markdown 0.13.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.
- package/out/index.d.ts +1 -0
- package/out/index.js +1 -0
- package/out/index.js.map +1 -1
- package/out/md/md-execution.d.ts +3 -3
- package/out/md/md-execution.js +1 -1
- package/out/md/md-execution.js.map +1 -1
- package/out/md/md-executor.js +6 -8
- package/out/md/md-executor.js.map +1 -1
- package/out/md/md-frontmatter.d.ts +1 -1
- package/out/md/md-frontmatter.js +15 -10
- package/out/md/md-frontmatter.js.map +1 -1
- package/out/md/md-runtime.js +1 -1
- package/out/md/md-runtime.js.map +1 -1
- package/out/md/md-types.d.ts +2 -2
- package/out/renderers/diagram-renderer.js +231 -12
- package/out/renderers/diagram-renderer.js.map +1 -1
- package/out/renderers/graph-renderer.js +2 -2
- package/out/renderers/graph-renderer.js.map +1 -1
- package/out/renderers/table-renderer.js +25 -10
- package/out/renderers/table-renderer.js.map +1 -1
- package/out/static/browser-runtime.bundle.js +489 -25
- package/out/static/browser-runtime.bundle.js.map +3 -3
- package/out/static/browser-runtime.js +258 -0
- package/out/static/browser-runtime.js.map +1 -1
- package/out/static/runtime-assets.d.ts +1 -1
- package/out/static/runtime-assets.js +1 -0
- package/out/static/runtime-assets.js.map +1 -1
- package/out/template/binder.d.ts +2 -0
- package/out/template/binder.js +56 -0
- package/out/template/binder.js.map +1 -0
- package/out/template/catalog.d.ts +8 -0
- package/out/template/catalog.js +26 -0
- package/out/template/catalog.js.map +1 -0
- package/out/template/compose.d.ts +7 -0
- package/out/template/compose.js +93 -0
- package/out/template/compose.js.map +1 -0
- package/out/template/definition.d.ts +3 -0
- package/out/template/definition.js +204 -0
- package/out/template/definition.js.map +1 -0
- package/out/template/engine.d.ts +8 -0
- package/out/template/engine.js +30 -0
- package/out/template/engine.js.map +1 -0
- package/out/template/index.d.ts +7 -0
- package/out/template/index.js +9 -0
- package/out/template/index.js.map +1 -0
- package/out/template/resolver.d.ts +4 -0
- package/out/template/resolver.js +58 -0
- package/out/template/resolver.js.map +1 -0
- package/out/template/types.d.ts +82 -0
- package/out/template/types.js +3 -0
- package/out/template/types.js.map +1 -0
- package/package.json +2 -2
- package/src/index.ts +1 -0
- package/src/md/md-execution.ts +3 -3
- package/src/md/md-executor.ts +6 -9
- package/src/md/md-frontmatter.ts +15 -10
- package/src/md/md-runtime.ts +1 -1
- package/src/md/md-types.ts +2 -2
- package/src/renderers/diagram-renderer.ts +229 -12
- package/src/renderers/graph-renderer.ts +2 -2
- package/src/renderers/table-renderer.ts +26 -10
- package/src/static/browser-runtime.ts +305 -0
- package/src/static/markdown-webview.css +13 -0
- package/src/static/runtime-assets.ts +1 -0
- package/src/template/binder.ts +70 -0
- package/src/template/catalog.ts +35 -0
- package/src/template/compose.ts +107 -0
- package/src/template/definition.ts +222 -0
- package/src/template/engine.ts +45 -0
- package/src/template/index.ts +9 -0
- package/src/template/resolver.ts +75 -0
- package/src/template/types.ts +111 -0
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
// Copyright (c) 2026 Modelware. All rights reserved.
|
|
2
|
+
|
|
3
|
+
import { extractLeadingFrontMatter } from '../md/md-frontmatter.js';
|
|
4
|
+
import type {
|
|
5
|
+
TemplateDefinition,
|
|
6
|
+
TemplateExposure,
|
|
7
|
+
TemplateParameterDefinition,
|
|
8
|
+
TemplateValue,
|
|
9
|
+
} from './types.js';
|
|
10
|
+
|
|
11
|
+
export function parseTemplateDefinition(content: string, sourceUri?: string): TemplateDefinition | undefined {
|
|
12
|
+
const frontMatter = extractLeadingFrontMatter(content);
|
|
13
|
+
const data = frontMatter?.data;
|
|
14
|
+
if (!data) {
|
|
15
|
+
return undefined;
|
|
16
|
+
}
|
|
17
|
+
const rawTemplate = data.template;
|
|
18
|
+
if (!isRecord(rawTemplate)) {
|
|
19
|
+
return undefined;
|
|
20
|
+
}
|
|
21
|
+
const id = normalizeTemplateType(typeof rawTemplate.id === 'string' ? rawTemplate.id : '');
|
|
22
|
+
if (!id) {
|
|
23
|
+
return undefined;
|
|
24
|
+
}
|
|
25
|
+
const name = typeof rawTemplate.name === 'string' && rawTemplate.name.trim().length > 0
|
|
26
|
+
? rawTemplate.name.trim()
|
|
27
|
+
: undefined;
|
|
28
|
+
const rank = parseRank(rawTemplate.rank);
|
|
29
|
+
const exposures = parseTemplateExposures(rawTemplate.expose);
|
|
30
|
+
const parameters = parseTemplateParameters(rawTemplate.params);
|
|
31
|
+
return {
|
|
32
|
+
id,
|
|
33
|
+
name,
|
|
34
|
+
rank,
|
|
35
|
+
exposures,
|
|
36
|
+
parameters,
|
|
37
|
+
body: content,
|
|
38
|
+
sourceUri,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function deriveContextLabelFromIri(iri: string): string {
|
|
43
|
+
const normalized = iri.trim().replace(/^<|>$/g, '');
|
|
44
|
+
if (!normalized) {
|
|
45
|
+
return 'IRI';
|
|
46
|
+
}
|
|
47
|
+
const hashIndex = normalized.lastIndexOf('#');
|
|
48
|
+
if (hashIndex >= 0 && hashIndex < normalized.length - 1) {
|
|
49
|
+
return decodeIriSegment(normalized.slice(hashIndex + 1));
|
|
50
|
+
}
|
|
51
|
+
const withoutTrailingSlash = normalized.replace(/\/+$/, '');
|
|
52
|
+
const slashIndex = withoutTrailingSlash.lastIndexOf('/');
|
|
53
|
+
if (slashIndex >= 0 && slashIndex < withoutTrailingSlash.length - 1) {
|
|
54
|
+
return decodeIriSegment(withoutTrailingSlash.slice(slashIndex + 1));
|
|
55
|
+
}
|
|
56
|
+
return decodeIriSegment(withoutTrailingSlash);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function normalizeTemplateType(value: string): string {
|
|
60
|
+
let normalized = value.trim();
|
|
61
|
+
const wikilinkMatch = /^\[\[([^\]]+)\]\]$/.exec(normalized);
|
|
62
|
+
if (wikilinkMatch) {
|
|
63
|
+
normalized = (wikilinkMatch[1] ?? '').trim();
|
|
64
|
+
}
|
|
65
|
+
return normalized.replace(/^<|>$/g, '');
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function parseTemplateExposures(raw: unknown): TemplateExposure[] {
|
|
69
|
+
const entries = Array.isArray(raw) ? raw : raw ? [raw] : [];
|
|
70
|
+
const exposures: TemplateExposure[] = [];
|
|
71
|
+
for (const entry of entries) {
|
|
72
|
+
if (!isRecord(entry) || typeof entry.kind !== 'string') {
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
const kind = entry.kind.trim();
|
|
76
|
+
if (kind === 'navigation') {
|
|
77
|
+
const match = isRecord(entry.match) ? entry.match : undefined;
|
|
78
|
+
const anyTypeOf = asNormalizedStringArray(match?.anyTypeOf);
|
|
79
|
+
const allTypesOf = asNormalizedStringArray(match?.allTypesOf);
|
|
80
|
+
exposures.push({
|
|
81
|
+
kind: 'navigation',
|
|
82
|
+
match: (anyTypeOf.length > 0 || allTypesOf.length > 0)
|
|
83
|
+
? { anyTypeOf, allTypesOf }
|
|
84
|
+
: undefined
|
|
85
|
+
});
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
if (kind === 'compose') {
|
|
89
|
+
const placementRaw = typeof entry.placement === 'string' ? entry.placement.trim() : '';
|
|
90
|
+
const placement = placementRaw === 'prepend' || placementRaw === 'append' ? placementRaw : undefined;
|
|
91
|
+
exposures.push({ kind: 'compose', placement });
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
if (kind === 'call') {
|
|
95
|
+
const selection = isRecord(entry.selection) ? entry.selection : undefined;
|
|
96
|
+
const min = toNonNegativeInteger(selection?.min);
|
|
97
|
+
const max = toNonNegativeInteger(selection?.max);
|
|
98
|
+
exposures.push({
|
|
99
|
+
kind: 'call',
|
|
100
|
+
selection: min !== undefined || max !== undefined ? { min, max } : undefined
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return exposures;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function parseTemplateParameters(raw: unknown): TemplateParameterDefinition[] {
|
|
108
|
+
if (!Array.isArray(raw)) {
|
|
109
|
+
return [];
|
|
110
|
+
}
|
|
111
|
+
const params: TemplateParameterDefinition[] = [];
|
|
112
|
+
for (const entry of raw) {
|
|
113
|
+
if (!isRecord(entry)) {
|
|
114
|
+
continue;
|
|
115
|
+
}
|
|
116
|
+
const id = typeof entry.id === 'string' ? entry.id.trim() : '';
|
|
117
|
+
const type = typeof entry.type === 'string' ? entry.type.trim() : '';
|
|
118
|
+
if (!id || !isSupportedParameterType(type)) {
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
const required = typeof entry.required === 'boolean' ? entry.required : undefined;
|
|
122
|
+
const fromValue = typeof entry.from === 'string' ? entry.from.trim() : '';
|
|
123
|
+
const from = isSupportedBindingSource(fromValue) ? fromValue : undefined;
|
|
124
|
+
const description = typeof entry.description === 'string' && entry.description.trim().length > 0
|
|
125
|
+
? entry.description.trim()
|
|
126
|
+
: undefined;
|
|
127
|
+
params.push({
|
|
128
|
+
id,
|
|
129
|
+
type,
|
|
130
|
+
required,
|
|
131
|
+
from,
|
|
132
|
+
defaultValue: toTemplateValue(entry.defaultValue),
|
|
133
|
+
description,
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
return params;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
function isSupportedParameterType(value: string): value is TemplateParameterDefinition['type'] {
|
|
140
|
+
return value === 'iri'
|
|
141
|
+
|| value === 'string'
|
|
142
|
+
|| value === 'number'
|
|
143
|
+
|| value === 'boolean'
|
|
144
|
+
|| value === 'iri[]'
|
|
145
|
+
|| value === 'json';
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
function isSupportedBindingSource(value: string): value is NonNullable<TemplateParameterDefinition['from']> {
|
|
149
|
+
return value === 'context.member'
|
|
150
|
+
|| value === 'context.ontology'
|
|
151
|
+
|| value === 'context.modelUri'
|
|
152
|
+
|| value === 'context.selection[*]'
|
|
153
|
+
|| /^context\.selection\[\d+]$/.test(value)
|
|
154
|
+
|| value === 'user';
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
function toTemplateValue(value: unknown): TemplateValue | undefined {
|
|
158
|
+
if (value === null) {
|
|
159
|
+
return null;
|
|
160
|
+
}
|
|
161
|
+
if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {
|
|
162
|
+
return value;
|
|
163
|
+
}
|
|
164
|
+
if (Array.isArray(value)) {
|
|
165
|
+
return value.every((entry) => typeof entry === 'string') ? value : undefined;
|
|
166
|
+
}
|
|
167
|
+
if (isRecord(value)) {
|
|
168
|
+
return value;
|
|
169
|
+
}
|
|
170
|
+
return undefined;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
function parseRank(value: unknown): number {
|
|
174
|
+
if (typeof value === 'number' && Number.isFinite(value)) {
|
|
175
|
+
return value;
|
|
176
|
+
}
|
|
177
|
+
if (typeof value === 'string') {
|
|
178
|
+
const parsed = Number(value.trim());
|
|
179
|
+
if (Number.isFinite(parsed)) {
|
|
180
|
+
return parsed;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
return 0;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
function asNormalizedStringArray(value: unknown): string[] {
|
|
187
|
+
if (!Array.isArray(value)) {
|
|
188
|
+
return [];
|
|
189
|
+
}
|
|
190
|
+
return value
|
|
191
|
+
.filter((entry): entry is string => typeof entry === 'string')
|
|
192
|
+
.map((entry) => normalizeTemplateType(entry))
|
|
193
|
+
.filter((entry): entry is string => entry.length > 0);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
function toNonNegativeInteger(value: unknown): number | undefined {
|
|
197
|
+
if (typeof value === 'number' && Number.isInteger(value) && value >= 0) {
|
|
198
|
+
return value;
|
|
199
|
+
}
|
|
200
|
+
if (typeof value === 'string') {
|
|
201
|
+
const parsed = Number.parseInt(value.trim(), 10);
|
|
202
|
+
if (Number.isInteger(parsed) && parsed >= 0) {
|
|
203
|
+
return parsed;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
return undefined;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
210
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
function decodeIriSegment(value: string): string {
|
|
214
|
+
if (!value) {
|
|
215
|
+
return 'IRI';
|
|
216
|
+
}
|
|
217
|
+
try {
|
|
218
|
+
return decodeURIComponent(value);
|
|
219
|
+
} catch {
|
|
220
|
+
return value;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
// Copyright (c) 2026 Modelware. All rights reserved.
|
|
2
|
+
|
|
3
|
+
import { bindTemplateParameters } from './binder.js';
|
|
4
|
+
import type { TemplateDefinition, TemplateInvocation, TemplateValue } from './types.js';
|
|
5
|
+
|
|
6
|
+
export interface TemplateRenderResult {
|
|
7
|
+
output: string;
|
|
8
|
+
values: Record<string, TemplateValue>;
|
|
9
|
+
missingRequired: string[];
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function renderTemplate(
|
|
13
|
+
template: TemplateDefinition,
|
|
14
|
+
invocation: TemplateInvocation
|
|
15
|
+
): TemplateRenderResult {
|
|
16
|
+
const bound = bindTemplateParameters(template, invocation.context, invocation.args);
|
|
17
|
+
const output = interpolateTemplateBody(template.body, bound.values);
|
|
18
|
+
return {
|
|
19
|
+
output,
|
|
20
|
+
values: bound.values,
|
|
21
|
+
missingRequired: bound.missingRequired
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function interpolateTemplateBody(
|
|
26
|
+
source: string,
|
|
27
|
+
values: Readonly<Record<string, TemplateValue>>
|
|
28
|
+
): string {
|
|
29
|
+
return source.replace(/\$\{([A-Za-z_][A-Za-z0-9_]*)\}/g, (_match: string, key: string): string => {
|
|
30
|
+
if (!(key in values)) {
|
|
31
|
+
return '';
|
|
32
|
+
}
|
|
33
|
+
const value = values[key];
|
|
34
|
+
if (Array.isArray(value)) {
|
|
35
|
+
return value.map((entry) => String(entry)).join(', ');
|
|
36
|
+
}
|
|
37
|
+
if (value === null || value === undefined) {
|
|
38
|
+
return '';
|
|
39
|
+
}
|
|
40
|
+
if (typeof value === 'object') {
|
|
41
|
+
return JSON.stringify(value);
|
|
42
|
+
}
|
|
43
|
+
return String(value);
|
|
44
|
+
});
|
|
45
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
// Copyright (c) 2026 Modelware. All rights reserved.
|
|
2
|
+
|
|
3
|
+
export * from './types.js';
|
|
4
|
+
export * from './catalog.js';
|
|
5
|
+
export * from './resolver.js';
|
|
6
|
+
export * from './binder.js';
|
|
7
|
+
export * from './engine.js';
|
|
8
|
+
export * from './compose.js';
|
|
9
|
+
export * from './definition.js';
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
// Copyright (c) 2026 Modelware. All rights reserved.
|
|
2
|
+
|
|
3
|
+
import { getTemplateById, type TemplateCatalog } from './catalog.js';
|
|
4
|
+
import type { TemplateDefinition, TemplateNavigationExposure, TemplateResolutionCandidate, TemplateResolutionResult } from './types.js';
|
|
5
|
+
|
|
6
|
+
export function resolveTemplateById(catalog: TemplateCatalog, templateId: string): TemplateDefinition | undefined {
|
|
7
|
+
return getTemplateById(catalog, templateId);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function resolveTemplateForNavigation(
|
|
11
|
+
catalog: TemplateCatalog,
|
|
12
|
+
rdfTypes: ReadonlyArray<string>
|
|
13
|
+
): TemplateResolutionResult {
|
|
14
|
+
const candidates = collectNavigationCandidates(catalog, rdfTypes);
|
|
15
|
+
const template = selectBestTemplate(candidates);
|
|
16
|
+
return { template, candidates };
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function collectNavigationCandidates(
|
|
20
|
+
catalog: TemplateCatalog,
|
|
21
|
+
rdfTypes: ReadonlyArray<string>
|
|
22
|
+
): TemplateResolutionCandidate[] {
|
|
23
|
+
const normalizedTypes = [...new Set(rdfTypes.map(normalizeIri).filter((value): value is string => value.length > 0))];
|
|
24
|
+
const normalizedTypeSet = new Set(normalizedTypes);
|
|
25
|
+
const results: TemplateResolutionCandidate[] = [];
|
|
26
|
+
for (const template of catalog.all) {
|
|
27
|
+
const exposures = template.exposures?.filter((exposure): exposure is TemplateNavigationExposure => exposure.kind === 'navigation') ?? [];
|
|
28
|
+
if (exposures.length === 0) {
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
let bestScoreForTemplate: number | undefined;
|
|
32
|
+
for (const exposure of exposures) {
|
|
33
|
+
const score = scoreNavigationExposure(exposure, normalizedTypeSet);
|
|
34
|
+
if (score === undefined) {
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
if (bestScoreForTemplate === undefined || score > bestScoreForTemplate) {
|
|
38
|
+
bestScoreForTemplate = score;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
if (bestScoreForTemplate === undefined) {
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
const rank = Number.isFinite(template.rank) ? Number(template.rank) : 0;
|
|
45
|
+
results.push({ template, score: bestScoreForTemplate + rank });
|
|
46
|
+
}
|
|
47
|
+
return results.sort((left, right) => right.score - left.score || left.template.id.localeCompare(right.template.id));
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function scoreNavigationExposure(
|
|
51
|
+
exposure: TemplateNavigationExposure,
|
|
52
|
+
rdfTypeSet: ReadonlySet<string>
|
|
53
|
+
): number | undefined {
|
|
54
|
+
const anyTypeOf = (exposure.match?.anyTypeOf ?? []).map(normalizeIri).filter((value): value is string => value.length > 0);
|
|
55
|
+
const allTypesOf = (exposure.match?.allTypesOf ?? []).map(normalizeIri).filter((value): value is string => value.length > 0);
|
|
56
|
+
|
|
57
|
+
if (allTypesOf.length > 0 && allTypesOf.some((iri) => !rdfTypeSet.has(iri))) {
|
|
58
|
+
return undefined;
|
|
59
|
+
}
|
|
60
|
+
if (anyTypeOf.length > 0 && !anyTypeOf.some((iri) => rdfTypeSet.has(iri))) {
|
|
61
|
+
return undefined;
|
|
62
|
+
}
|
|
63
|
+
if (allTypesOf.length === 0 && anyTypeOf.length === 0) {
|
|
64
|
+
return 0;
|
|
65
|
+
}
|
|
66
|
+
return (allTypesOf.length * 10) + anyTypeOf.length;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function selectBestTemplate(candidates: ReadonlyArray<TemplateResolutionCandidate>): TemplateDefinition | undefined {
|
|
70
|
+
return candidates.length > 0 ? candidates[0].template : undefined;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function normalizeIri(value: string): string {
|
|
74
|
+
return value.trim().replace(/^<|>$/g, '');
|
|
75
|
+
}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
// Copyright (c) 2026 Modelware. All rights reserved.
|
|
2
|
+
|
|
3
|
+
export type TemplateValue = string | number | boolean | null | string[] | Record<string, unknown>;
|
|
4
|
+
|
|
5
|
+
export type TemplateParameterType =
|
|
6
|
+
| 'iri'
|
|
7
|
+
| 'string'
|
|
8
|
+
| 'number'
|
|
9
|
+
| 'boolean'
|
|
10
|
+
| 'iri[]'
|
|
11
|
+
| 'json';
|
|
12
|
+
|
|
13
|
+
export type TemplateBindingSource =
|
|
14
|
+
| 'context.member'
|
|
15
|
+
| 'context.ontology'
|
|
16
|
+
| 'context.modelUri'
|
|
17
|
+
| `context.selection[${number}]`
|
|
18
|
+
| 'context.selection[*]'
|
|
19
|
+
| 'user';
|
|
20
|
+
|
|
21
|
+
export interface TemplateParameterDefinition {
|
|
22
|
+
id: string;
|
|
23
|
+
type: TemplateParameterType;
|
|
24
|
+
required?: boolean;
|
|
25
|
+
from?: TemplateBindingSource;
|
|
26
|
+
defaultValue?: TemplateValue;
|
|
27
|
+
description?: string;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface TemplateNavigationMatch {
|
|
31
|
+
anyTypeOf?: string[];
|
|
32
|
+
allTypesOf?: string[];
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export interface TemplateNavigationExposure {
|
|
36
|
+
kind: 'navigation';
|
|
37
|
+
match?: TemplateNavigationMatch;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export interface TemplateComposeExposure {
|
|
41
|
+
kind: 'compose';
|
|
42
|
+
placement?: 'prepend' | 'append';
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export interface TemplateCallExposure {
|
|
46
|
+
kind: 'call';
|
|
47
|
+
selection?: {
|
|
48
|
+
min?: number;
|
|
49
|
+
max?: number;
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export type TemplateExposure =
|
|
54
|
+
| TemplateNavigationExposure
|
|
55
|
+
| TemplateComposeExposure
|
|
56
|
+
| TemplateCallExposure;
|
|
57
|
+
|
|
58
|
+
export interface TemplateDefinition {
|
|
59
|
+
id: string;
|
|
60
|
+
name?: string;
|
|
61
|
+
rank?: number;
|
|
62
|
+
exposures?: TemplateExposure[];
|
|
63
|
+
parameters?: TemplateParameterDefinition[];
|
|
64
|
+
body: string;
|
|
65
|
+
sourceUri?: string;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export type TemplateInvocationMode = 'navigation' | 'compose' | 'call' | 'preview' | 'inline' | 'newDocument';
|
|
69
|
+
|
|
70
|
+
export interface TemplateInvocationContext {
|
|
71
|
+
invocation: {
|
|
72
|
+
mode: TemplateInvocationMode;
|
|
73
|
+
sourceDocumentUri?: string;
|
|
74
|
+
referenceDocumentUri?: string;
|
|
75
|
+
};
|
|
76
|
+
model?: {
|
|
77
|
+
ontologyIri?: string;
|
|
78
|
+
modelUri?: string;
|
|
79
|
+
};
|
|
80
|
+
focus?: {
|
|
81
|
+
memberIri?: string;
|
|
82
|
+
rdfTypes?: string[];
|
|
83
|
+
};
|
|
84
|
+
selection?: {
|
|
85
|
+
iris?: string[];
|
|
86
|
+
rows?: Array<{ iri: string; cells: Record<string, string> }>;
|
|
87
|
+
};
|
|
88
|
+
vars?: Record<string, TemplateValue>;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export interface TemplateInvocation {
|
|
92
|
+
templateId: string;
|
|
93
|
+
mode: TemplateInvocationMode;
|
|
94
|
+
context: TemplateInvocationContext;
|
|
95
|
+
args?: Record<string, TemplateValue>;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export interface TemplateResolutionCandidate {
|
|
99
|
+
template: TemplateDefinition;
|
|
100
|
+
score: number;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export interface TemplateResolutionResult {
|
|
104
|
+
template?: TemplateDefinition;
|
|
105
|
+
candidates: TemplateResolutionCandidate[];
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export interface TemplateBindResult {
|
|
109
|
+
values: Record<string, TemplateValue>;
|
|
110
|
+
missingRequired: string[];
|
|
111
|
+
}
|