@oml/markdown 0.14.17 → 0.16.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/md/md-frontmatter.d.ts +1 -1
- package/out/md/md-frontmatter.js +6 -11
- package/out/md/md-frontmatter.js.map +1 -1
- package/out/md/md-runtime.js +26 -7
- package/out/md/md-runtime.js.map +1 -1
- package/out/md/md-types.d.ts +2 -2
- package/out/renderers/table-renderer.js +12 -4
- package/out/renderers/table-renderer.js.map +1 -1
- package/out/static/browser-runtime.bundle.js +718 -14
- package/out/static/browser-runtime.bundle.js.map +3 -3
- package/out/static/browser-runtime.js +748 -1
- package/out/static/browser-runtime.js.map +1 -1
- package/out/static/runtime-assets.d.ts +1 -1
- package/out/static/runtime-assets.js +3 -0
- package/out/static/runtime-assets.js.map +1 -1
- package/out/template/binder.js +156 -32
- package/out/template/binder.js.map +1 -1
- package/out/template/compose.d.ts +1 -2
- package/out/template/compose.js +7 -41
- package/out/template/compose.js.map +1 -1
- package/out/template/definition.js +0 -11
- package/out/template/definition.js.map +1 -1
- package/out/template/engine.js +1 -1
- package/out/template/engine.js.map +1 -1
- package/out/template/types.d.ts +0 -2
- package/package.json +2 -2
- package/src/md/md-frontmatter.ts +6 -11
- package/src/md/md-runtime.ts +29 -7
- package/src/md/md-types.ts +2 -2
- package/src/renderers/table-renderer.ts +13 -4
- package/src/static/browser-runtime.ts +803 -1
- package/src/static/markdown-webview.css +88 -1
- package/src/static/runtime-assets.ts +3 -0
- package/src/template/binder.ts +165 -35
- package/src/template/compose.ts +8 -45
- package/src/template/definition.ts +0 -12
- package/src/template/engine.ts +1 -1
- package/src/template/types.ts +0 -9
|
@@ -43,10 +43,80 @@ pre > code.language-diagram,
|
|
|
43
43
|
pre > code.language-list,
|
|
44
44
|
pre > code.language-text,
|
|
45
45
|
pre > code.language-matrix,
|
|
46
|
-
pre > code.language-table-editor
|
|
46
|
+
pre > code.language-table-editor,
|
|
47
|
+
pre > code.language-js,
|
|
48
|
+
pre > code.language-javascript,
|
|
49
|
+
pre > code.language-python,
|
|
50
|
+
pre > code.language-r {
|
|
47
51
|
display: none;
|
|
48
52
|
}
|
|
49
53
|
|
|
54
|
+
.oml-md-js-result {
|
|
55
|
+
margin: 1rem 0;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
.oml-md-js-result:empty {
|
|
59
|
+
display: none;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
pre.oml-md-js-text-output {
|
|
63
|
+
font-family: var(--vscode-editor-font-family, monospace);
|
|
64
|
+
font-size: 0.9em;
|
|
65
|
+
background: var(--vscode-textBlockQuote-background, var(--oml-static-background, #f6f8fa));
|
|
66
|
+
border: 1px solid var(--vscode-editorWidget-border, var(--oml-static-border, #d0d7de));
|
|
67
|
+
border-radius: 6px !important;
|
|
68
|
+
padding: 0.5rem 0.75rem !important;
|
|
69
|
+
margin: 0.25rem 0;
|
|
70
|
+
white-space: pre-wrap;
|
|
71
|
+
overflow: visible !important;
|
|
72
|
+
color: var(--vscode-editor-foreground, var(--oml-static-foreground, #24292f));
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
.oml-md-js-html-output {
|
|
76
|
+
margin: 0.25rem 0;
|
|
77
|
+
color: var(--vscode-editor-foreground, var(--oml-static-foreground, #24292f));
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
.oml-md-js-html-output ul,
|
|
81
|
+
.oml-md-js-html-output ol {
|
|
82
|
+
padding-left: 2em;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
.oml-md-js-html-output li {
|
|
86
|
+
color: var(--vscode-editor-foreground, var(--oml-static-foreground, #24292f));
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
.oml-md-js-error {
|
|
90
|
+
border: 1px solid var(--vscode-inputValidation-errorBorder, #f14c4c);
|
|
91
|
+
background: var(--vscode-inputValidation-errorBackground, rgba(241, 76, 76, 0.1));
|
|
92
|
+
color: var(--vscode-errorForeground, #f14c4c);
|
|
93
|
+
border-radius: 6px;
|
|
94
|
+
padding: 0.5rem 0.75rem;
|
|
95
|
+
margin: 0.25rem 0;
|
|
96
|
+
font-family: var(--vscode-editor-font-family, monospace);
|
|
97
|
+
font-size: 0.9em;
|
|
98
|
+
white-space: pre-wrap;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
.oml-md-js-empty {
|
|
102
|
+
color: var(--vscode-descriptionForeground, #666);
|
|
103
|
+
font-style: italic;
|
|
104
|
+
margin: 0.25rem 0;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
pre.oml-md-js-stderr {
|
|
108
|
+
font-family: var(--vscode-editor-font-family, monospace);
|
|
109
|
+
font-size: 0.85em;
|
|
110
|
+
color: var(--vscode-descriptionForeground, #888);
|
|
111
|
+
background: transparent;
|
|
112
|
+
border: none;
|
|
113
|
+
border-radius: 0 !important;
|
|
114
|
+
padding: 0 !important;
|
|
115
|
+
margin: 0;
|
|
116
|
+
white-space: pre-wrap;
|
|
117
|
+
overflow: visible !important;
|
|
118
|
+
}
|
|
119
|
+
|
|
50
120
|
h1,
|
|
51
121
|
h2,
|
|
52
122
|
h3,
|
|
@@ -349,6 +419,7 @@ pre {
|
|
|
349
419
|
text-align: left;
|
|
350
420
|
font-weight: 600;
|
|
351
421
|
border-bottom: 1px solid var(--vscode-editorWidget-border);
|
|
422
|
+
border-right: 1px solid var(--vscode-editorWidget-border);
|
|
352
423
|
padding: 8px 10px;
|
|
353
424
|
background: var(--vscode-editor-background);
|
|
354
425
|
cursor: pointer;
|
|
@@ -358,12 +429,21 @@ pre {
|
|
|
358
429
|
user-select: none;
|
|
359
430
|
}
|
|
360
431
|
|
|
432
|
+
.oml-md-table thead th:last-child {
|
|
433
|
+
border-right: none;
|
|
434
|
+
}
|
|
435
|
+
|
|
361
436
|
.oml-md-table tbody td {
|
|
362
437
|
border-bottom: 1px solid var(--vscode-editorWidget-border);
|
|
438
|
+
border-right: 1px solid var(--vscode-editorWidget-border);
|
|
363
439
|
padding: 6px 10px;
|
|
364
440
|
vertical-align: top;
|
|
365
441
|
}
|
|
366
442
|
|
|
443
|
+
.oml-md-table tbody td:last-child {
|
|
444
|
+
border-right: none;
|
|
445
|
+
}
|
|
446
|
+
|
|
367
447
|
.vscode-dark th {
|
|
368
448
|
border-color: rgb(255 255 255 / 69%);
|
|
369
449
|
}
|
|
@@ -726,6 +806,8 @@ pre {
|
|
|
726
806
|
align-items: center;
|
|
727
807
|
gap: 0.5rem;
|
|
728
808
|
margin-left: auto;
|
|
809
|
+
font-family: var(--vscode-font-family, var(--markdown-font-family, -apple-system, BlinkMacSystemFont, "Segoe WPC", "Segoe UI", system-ui, "Ubuntu", "Droid Sans", sans-serif));
|
|
810
|
+
font-size: 0.85rem;
|
|
729
811
|
}
|
|
730
812
|
|
|
731
813
|
.oml-md-result .table-pagination {
|
|
@@ -745,6 +827,7 @@ pre {
|
|
|
745
827
|
background: transparent;
|
|
746
828
|
color: var(--vscode-foreground);
|
|
747
829
|
cursor: pointer;
|
|
830
|
+
font-family: inherit;
|
|
748
831
|
font-size: 1rem;
|
|
749
832
|
font-weight: 600;
|
|
750
833
|
line-height: 1;
|
|
@@ -764,6 +847,10 @@ pre {
|
|
|
764
847
|
.oml-md-result .table-page-label {
|
|
765
848
|
min-width: 36px;
|
|
766
849
|
text-align: center;
|
|
850
|
+
font-family: inherit;
|
|
851
|
+
font-size: inherit;
|
|
852
|
+
font-weight: 400;
|
|
853
|
+
line-height: 1.2;
|
|
767
854
|
}
|
|
768
855
|
|
|
769
856
|
.oml-md-result .graph-canvas-root {
|
|
@@ -3,6 +3,9 @@
|
|
|
3
3
|
export const STATIC_MARKDOWN_RUNTIME_BUNDLE_FILE = 'browser-runtime.bundle.js';
|
|
4
4
|
|
|
5
5
|
export const STATIC_MARKDOWN_RUNTIME_CSS = `
|
|
6
|
+
/* Prevent first-paint flicker before static runtime hydration restores content. */
|
|
7
|
+
body { visibility: hidden; }
|
|
8
|
+
|
|
6
9
|
.oml-md-result { margin: 1rem 0; }
|
|
7
10
|
.oml-md-result-message {
|
|
8
11
|
border: 1px solid #e5b567;
|
package/src/template/binder.ts
CHANGED
|
@@ -13,58 +13,188 @@ export function bindTemplateParameters(
|
|
|
13
13
|
for (const parameter of parameters) {
|
|
14
14
|
const explicit = explicitArgs[parameter.id];
|
|
15
15
|
if (explicit !== undefined) {
|
|
16
|
-
values[parameter.id] = explicit;
|
|
16
|
+
values[parameter.id] = coerceParameterValue(parameter, explicit);
|
|
17
17
|
continue;
|
|
18
18
|
}
|
|
19
|
-
const
|
|
20
|
-
if (
|
|
21
|
-
values[parameter.id] =
|
|
22
|
-
continue;
|
|
23
|
-
}
|
|
24
|
-
if (parameter.defaultValue !== undefined) {
|
|
25
|
-
values[parameter.id] = parameter.defaultValue;
|
|
19
|
+
const defaultValue = resolveTemplateDefaultValue(parameter.defaultValue, context);
|
|
20
|
+
if (defaultValue !== undefined) {
|
|
21
|
+
values[parameter.id] = coerceParameterValue(parameter, defaultValue);
|
|
26
22
|
continue;
|
|
27
23
|
}
|
|
28
24
|
if (parameter.required) {
|
|
29
25
|
missingRequired.push(parameter.id);
|
|
26
|
+
continue;
|
|
30
27
|
}
|
|
28
|
+
values[parameter.id] = naturalDefaultValue(parameter.type);
|
|
31
29
|
}
|
|
32
30
|
return { values, missingRequired };
|
|
33
31
|
}
|
|
34
32
|
|
|
35
|
-
function
|
|
36
|
-
|
|
33
|
+
function resolveTemplateDefaultValue(
|
|
34
|
+
value: TemplateValue | undefined,
|
|
37
35
|
context: TemplateInvocationContext
|
|
38
36
|
): TemplateValue | undefined {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
case 'context.modelUri':
|
|
45
|
-
return context.model?.modelUri;
|
|
46
|
-
case 'context.selection[*]':
|
|
47
|
-
return context.selection?.iris ?? [];
|
|
48
|
-
default:
|
|
49
|
-
return resolveSelectionIndexedBinding(parameter.from, context);
|
|
37
|
+
if (value === undefined) {
|
|
38
|
+
return undefined;
|
|
39
|
+
}
|
|
40
|
+
if (typeof value !== 'string') {
|
|
41
|
+
return value;
|
|
50
42
|
}
|
|
43
|
+
return interpolateContextExpression(value, context);
|
|
51
44
|
}
|
|
52
45
|
|
|
53
|
-
function
|
|
54
|
-
|
|
55
|
-
context:
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
46
|
+
function interpolateContextExpression(source: string, context: TemplateInvocationContext): string | undefined {
|
|
47
|
+
let unresolved = false;
|
|
48
|
+
const output = source.replace(/\$\{context\.([^}]+)\}/g, (_match, token: string) => {
|
|
49
|
+
const resolved = resolveContextToken(token.trim(), context);
|
|
50
|
+
if (resolved === undefined) {
|
|
51
|
+
unresolved = true;
|
|
52
|
+
return '';
|
|
53
|
+
}
|
|
54
|
+
return resolved;
|
|
55
|
+
});
|
|
56
|
+
return unresolved ? undefined : output;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function resolveContextToken(token: string, context: TemplateInvocationContext): string | undefined {
|
|
60
|
+
const indexedSelection = /^selection\[(\d+)]$/.exec(token);
|
|
61
|
+
if (indexedSelection) {
|
|
62
|
+
const index = Number.parseInt(indexedSelection[1] ?? '', 10);
|
|
63
|
+
if (!Number.isFinite(index) || index < 0) {
|
|
64
|
+
return undefined;
|
|
65
|
+
}
|
|
66
|
+
const selection = context.selection?.iris ?? [];
|
|
67
|
+
const value = selection[index];
|
|
68
|
+
return typeof value === 'string' && value.trim().length > 0 ? value.trim() : undefined;
|
|
59
69
|
}
|
|
60
|
-
const
|
|
61
|
-
|
|
62
|
-
|
|
70
|
+
const key = token;
|
|
71
|
+
const vars = context.vars ?? {};
|
|
72
|
+
const direct = vars[key];
|
|
73
|
+
if (typeof direct === 'string') {
|
|
74
|
+
return direct;
|
|
63
75
|
}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
76
|
+
if (typeof direct === 'number' || typeof direct === 'boolean') {
|
|
77
|
+
return String(direct);
|
|
78
|
+
}
|
|
79
|
+
if (key === 'ontology') {
|
|
80
|
+
return context.model?.ontologyIri?.trim() || undefined;
|
|
81
|
+
}
|
|
82
|
+
if (key === 'member') {
|
|
83
|
+
return context.focus?.memberIri?.trim() || undefined;
|
|
84
|
+
}
|
|
85
|
+
if (key === 'selection') {
|
|
86
|
+
const selection = context.selection?.iris ?? [];
|
|
87
|
+
return selection.join(', ');
|
|
88
|
+
}
|
|
89
|
+
return undefined;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function coerceParameterValue(parameter: TemplateParameterDefinition, value: TemplateValue): TemplateValue {
|
|
93
|
+
switch (parameter.type) {
|
|
94
|
+
case 'string':
|
|
95
|
+
case 'iri':
|
|
96
|
+
return coerceString(parameter, value);
|
|
97
|
+
case 'number':
|
|
98
|
+
return coerceNumber(parameter, value);
|
|
99
|
+
case 'boolean':
|
|
100
|
+
return coerceBoolean(parameter, value);
|
|
101
|
+
case 'iri[]':
|
|
102
|
+
return coerceIriArray(parameter, value);
|
|
103
|
+
case 'json':
|
|
104
|
+
return coerceJson(parameter, value);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function coerceString(parameter: TemplateParameterDefinition, value: TemplateValue): string {
|
|
109
|
+
if (typeof value === 'string') {
|
|
110
|
+
return value;
|
|
111
|
+
}
|
|
112
|
+
if (typeof value === 'number' || typeof value === 'boolean') {
|
|
113
|
+
return String(value);
|
|
114
|
+
}
|
|
115
|
+
throw new Error(`Template parameter '${parameter.id}' must be a string.`);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
function coerceNumber(parameter: TemplateParameterDefinition, value: TemplateValue): number {
|
|
119
|
+
if (typeof value === 'number' && Number.isFinite(value)) {
|
|
120
|
+
return value;
|
|
121
|
+
}
|
|
122
|
+
if (typeof value === 'string') {
|
|
123
|
+
const parsed = Number(value.trim());
|
|
124
|
+
if (Number.isFinite(parsed)) {
|
|
125
|
+
return parsed;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
throw new Error(`Template parameter '${parameter.id}' must be a number.`);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function coerceBoolean(parameter: TemplateParameterDefinition, value: TemplateValue): boolean {
|
|
132
|
+
if (typeof value === 'boolean') {
|
|
133
|
+
return value;
|
|
134
|
+
}
|
|
135
|
+
if (typeof value === 'string') {
|
|
136
|
+
const normalized = value.trim().toLowerCase();
|
|
137
|
+
if (normalized === 'true') {
|
|
138
|
+
return true;
|
|
139
|
+
}
|
|
140
|
+
if (normalized === 'false') {
|
|
141
|
+
return false;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
throw new Error(`Template parameter '${parameter.id}' must be a boolean.`);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
function coerceIriArray(parameter: TemplateParameterDefinition, value: TemplateValue): string[] {
|
|
148
|
+
if (Array.isArray(value) && value.every((entry) => typeof entry === 'string')) {
|
|
149
|
+
return value;
|
|
150
|
+
}
|
|
151
|
+
if (typeof value === 'string') {
|
|
152
|
+
const normalized = value.trim();
|
|
153
|
+
if (!normalized) {
|
|
154
|
+
return [];
|
|
155
|
+
}
|
|
156
|
+
return normalized.split(',').map((entry) => entry.trim()).filter((entry) => entry.length > 0);
|
|
157
|
+
}
|
|
158
|
+
throw new Error(`Template parameter '${parameter.id}' must be an array of strings.`);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
function coerceJson(parameter: TemplateParameterDefinition, value: TemplateValue): TemplateValue {
|
|
162
|
+
if (value === null || typeof value === 'object') {
|
|
163
|
+
return value;
|
|
164
|
+
}
|
|
165
|
+
if (typeof value === 'string') {
|
|
166
|
+
try {
|
|
167
|
+
const parsed = JSON.parse(value) as unknown;
|
|
168
|
+
if (
|
|
169
|
+
parsed === null
|
|
170
|
+
|| typeof parsed === 'string'
|
|
171
|
+
|| typeof parsed === 'number'
|
|
172
|
+
|| typeof parsed === 'boolean'
|
|
173
|
+
|| (Array.isArray(parsed) && parsed.every((entry) => typeof entry === 'string'))
|
|
174
|
+
|| (typeof parsed === 'object' && parsed !== null)
|
|
175
|
+
) {
|
|
176
|
+
return parsed as TemplateValue;
|
|
177
|
+
}
|
|
178
|
+
throw new Error('unsupported-json');
|
|
179
|
+
} catch {
|
|
180
|
+
throw new Error(`Template parameter '${parameter.id}' must be valid JSON.`);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
throw new Error(`Template parameter '${parameter.id}' must be JSON.`);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
function naturalDefaultValue(type: TemplateParameterDefinition['type']): TemplateValue {
|
|
187
|
+
switch (type) {
|
|
188
|
+
case 'number':
|
|
189
|
+
return 0;
|
|
190
|
+
case 'boolean':
|
|
191
|
+
return false;
|
|
192
|
+
case 'iri[]':
|
|
193
|
+
return [];
|
|
194
|
+
case 'json':
|
|
195
|
+
return {};
|
|
196
|
+
case 'string':
|
|
197
|
+
case 'iri':
|
|
198
|
+
return '';
|
|
67
199
|
}
|
|
68
|
-
const iris = context.selection?.iris ?? [];
|
|
69
|
-
return iris[index];
|
|
70
200
|
}
|
package/src/template/compose.ts
CHANGED
|
@@ -1,48 +1,36 @@
|
|
|
1
1
|
// Copyright (c) 2026 Modelware. All rights reserved.
|
|
2
2
|
|
|
3
3
|
import { parse } from 'yaml';
|
|
4
|
-
import type {
|
|
4
|
+
import type { TemplateValue } from './types.js';
|
|
5
5
|
|
|
6
6
|
export interface TemplateComposeDirective {
|
|
7
7
|
id: string;
|
|
8
8
|
args: Record<string, TemplateValue>;
|
|
9
|
-
bind: Record<string, TemplateBindingSource>;
|
|
10
9
|
}
|
|
11
10
|
|
|
12
11
|
export function parseTemplateComposeDirective(source: string): TemplateComposeDirective | undefined {
|
|
13
12
|
const normalized = source.replace(/^\uFEFF/, '');
|
|
14
|
-
const
|
|
15
|
-
if (!frontMatterMatch) {
|
|
16
|
-
return undefined;
|
|
17
|
-
}
|
|
18
|
-
const trailing = frontMatterMatch[2] ?? '';
|
|
19
|
-
if (trailing.trim().length > 0) {
|
|
20
|
-
return undefined;
|
|
21
|
-
}
|
|
22
|
-
const yamlBody = frontMatterMatch[1]
|
|
23
|
-
.replace(/^---[ \t]*\r?\n/, '')
|
|
24
|
-
.replace(/\r?\n---[ \t]*$/, '');
|
|
25
|
-
const parsed = parse(yamlBody);
|
|
13
|
+
const parsed = parse(normalized);
|
|
26
14
|
if (!isRecord(parsed)) {
|
|
27
15
|
return undefined;
|
|
28
16
|
}
|
|
29
|
-
const id = normalizeString(parsed.
|
|
17
|
+
const id = normalizeString(parsed.template);
|
|
30
18
|
if (!id) {
|
|
31
19
|
return undefined;
|
|
32
20
|
}
|
|
33
|
-
const args = parseArgs(parsed
|
|
34
|
-
|
|
35
|
-
return { id, args, bind };
|
|
21
|
+
const args = parseArgs(parsed, ['template']);
|
|
22
|
+
return { id, args };
|
|
36
23
|
}
|
|
37
24
|
|
|
38
|
-
function parseArgs(value: unknown): Record<string, TemplateValue> {
|
|
25
|
+
function parseArgs(value: unknown, excludedKeys: string[] = []): Record<string, TemplateValue> {
|
|
39
26
|
if (!isRecord(value)) {
|
|
40
27
|
return {};
|
|
41
28
|
}
|
|
29
|
+
const excluded = new Set(excludedKeys);
|
|
42
30
|
const args: Record<string, TemplateValue> = {};
|
|
43
31
|
for (const [key, raw] of Object.entries(value)) {
|
|
44
32
|
const normalizedKey = normalizeString(key);
|
|
45
|
-
if (!normalizedKey) {
|
|
33
|
+
if (!normalizedKey || excluded.has(normalizedKey)) {
|
|
46
34
|
continue;
|
|
47
35
|
}
|
|
48
36
|
const converted = toTemplateValue(raw);
|
|
@@ -53,22 +41,6 @@ function parseArgs(value: unknown): Record<string, TemplateValue> {
|
|
|
53
41
|
return args;
|
|
54
42
|
}
|
|
55
43
|
|
|
56
|
-
function parseBind(value: unknown): Record<string, TemplateBindingSource> {
|
|
57
|
-
if (!isRecord(value)) {
|
|
58
|
-
return {};
|
|
59
|
-
}
|
|
60
|
-
const bind: Record<string, TemplateBindingSource> = {};
|
|
61
|
-
for (const [key, raw] of Object.entries(value)) {
|
|
62
|
-
const normalizedKey = normalizeString(key);
|
|
63
|
-
const source = normalizeString(raw);
|
|
64
|
-
if (!normalizedKey || !source || !isTemplateBindingSource(source)) {
|
|
65
|
-
continue;
|
|
66
|
-
}
|
|
67
|
-
bind[normalizedKey] = source;
|
|
68
|
-
}
|
|
69
|
-
return bind;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
44
|
function toTemplateValue(value: unknown): TemplateValue | undefined {
|
|
73
45
|
if (value === null) {
|
|
74
46
|
return null;
|
|
@@ -85,15 +57,6 @@ function toTemplateValue(value: unknown): TemplateValue | undefined {
|
|
|
85
57
|
return undefined;
|
|
86
58
|
}
|
|
87
59
|
|
|
88
|
-
function isTemplateBindingSource(value: string): value is TemplateBindingSource {
|
|
89
|
-
return value === 'context.member'
|
|
90
|
-
|| value === 'context.ontology'
|
|
91
|
-
|| value === 'context.modelUri'
|
|
92
|
-
|| value === 'context.selection[*]'
|
|
93
|
-
|| value === 'user'
|
|
94
|
-
|| /^context\.selection\[\d+]$/.test(value);
|
|
95
|
-
}
|
|
96
|
-
|
|
97
60
|
function normalizeString(value: unknown): string | undefined {
|
|
98
61
|
if (typeof value !== 'string') {
|
|
99
62
|
return undefined;
|
|
@@ -117,8 +117,6 @@ function parseTemplateParameters(raw: unknown): TemplateParameterDefinition[] {
|
|
|
117
117
|
continue;
|
|
118
118
|
}
|
|
119
119
|
const required = typeof entry.required === 'boolean' ? entry.required : undefined;
|
|
120
|
-
const fromValue = typeof entry.from === 'string' ? entry.from.trim() : '';
|
|
121
|
-
const from = isSupportedBindingSource(fromValue) ? fromValue : undefined;
|
|
122
120
|
const description = typeof entry.description === 'string' && entry.description.trim().length > 0
|
|
123
121
|
? entry.description.trim()
|
|
124
122
|
: undefined;
|
|
@@ -126,7 +124,6 @@ function parseTemplateParameters(raw: unknown): TemplateParameterDefinition[] {
|
|
|
126
124
|
id,
|
|
127
125
|
type,
|
|
128
126
|
required,
|
|
129
|
-
from,
|
|
130
127
|
defaultValue: toTemplateValue(entry.defaultValue),
|
|
131
128
|
description,
|
|
132
129
|
});
|
|
@@ -143,15 +140,6 @@ function isSupportedParameterType(value: string): value is TemplateParameterDefi
|
|
|
143
140
|
|| value === 'json';
|
|
144
141
|
}
|
|
145
142
|
|
|
146
|
-
function isSupportedBindingSource(value: string): value is NonNullable<TemplateParameterDefinition['from']> {
|
|
147
|
-
return value === 'context.member'
|
|
148
|
-
|| value === 'context.ontology'
|
|
149
|
-
|| value === 'context.modelUri'
|
|
150
|
-
|| value === 'context.selection[*]'
|
|
151
|
-
|| /^context\.selection\[\d+]$/.test(value)
|
|
152
|
-
|| value === 'user';
|
|
153
|
-
}
|
|
154
|
-
|
|
155
143
|
function toTemplateValue(value: unknown): TemplateValue | undefined {
|
|
156
144
|
if (value === null) {
|
|
157
145
|
return null;
|
package/src/template/engine.ts
CHANGED
|
@@ -28,7 +28,7 @@ export function interpolateTemplateBody(
|
|
|
28
28
|
): string {
|
|
29
29
|
return source.replace(/\$\{([A-Za-z_][A-Za-z0-9_]*)\}/g, (_match: string, key: string): string => {
|
|
30
30
|
if (!(key in values)) {
|
|
31
|
-
return
|
|
31
|
+
return _match;
|
|
32
32
|
}
|
|
33
33
|
const value = values[key];
|
|
34
34
|
if (Array.isArray(value)) {
|
package/src/template/types.ts
CHANGED
|
@@ -10,19 +10,10 @@ export type TemplateParameterType =
|
|
|
10
10
|
| 'iri[]'
|
|
11
11
|
| 'json';
|
|
12
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
13
|
export interface TemplateParameterDefinition {
|
|
22
14
|
id: string;
|
|
23
15
|
type: TemplateParameterType;
|
|
24
16
|
required?: boolean;
|
|
25
|
-
from?: TemplateBindingSource;
|
|
26
17
|
defaultValue?: TemplateValue;
|
|
27
18
|
description?: string;
|
|
28
19
|
}
|