@vertesia/fusion-ux 1.0.0-dev.20260128.144200
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/LICENSE +13 -0
- package/README.md +160 -0
- package/lib/esm/fusion-fragment/ChartRenderer.js +70 -0
- package/lib/esm/fusion-fragment/ChartRenderer.js.map +1 -0
- package/lib/esm/fusion-fragment/FieldRenderer.js +153 -0
- package/lib/esm/fusion-fragment/FieldRenderer.js.map +1 -0
- package/lib/esm/fusion-fragment/FusionFragmentContext.js +53 -0
- package/lib/esm/fusion-fragment/FusionFragmentContext.js.map +1 -0
- package/lib/esm/fusion-fragment/FusionFragmentHandler.js +233 -0
- package/lib/esm/fusion-fragment/FusionFragmentHandler.js.map +1 -0
- package/lib/esm/fusion-fragment/FusionFragmentRenderer.js +108 -0
- package/lib/esm/fusion-fragment/FusionFragmentRenderer.js.map +1 -0
- package/lib/esm/fusion-fragment/SectionRenderer.js +134 -0
- package/lib/esm/fusion-fragment/SectionRenderer.js.map +1 -0
- package/lib/esm/fusion-fragment/TableRenderer.js +137 -0
- package/lib/esm/fusion-fragment/TableRenderer.js.map +1 -0
- package/lib/esm/fusion-fragment/index.js +11 -0
- package/lib/esm/fusion-fragment/index.js.map +1 -0
- package/lib/esm/index.js +44 -0
- package/lib/esm/index.js.map +1 -0
- package/lib/esm/render/index.js +12 -0
- package/lib/esm/render/index.js.map +1 -0
- package/lib/esm/render/textPreview.js +194 -0
- package/lib/esm/render/textPreview.js.map +1 -0
- package/lib/esm/types.js +8 -0
- package/lib/esm/types.js.map +1 -0
- package/lib/esm/validation/formatErrors.js +105 -0
- package/lib/esm/validation/formatErrors.js.map +1 -0
- package/lib/esm/validation/fuzzyMatch.js +87 -0
- package/lib/esm/validation/fuzzyMatch.js.map +1 -0
- package/lib/esm/validation/index.js +8 -0
- package/lib/esm/validation/index.js.map +1 -0
- package/lib/esm/validation/schemas.js +166 -0
- package/lib/esm/validation/schemas.js.map +1 -0
- package/lib/esm/validation/validateTemplate.js +247 -0
- package/lib/esm/validation/validateTemplate.js.map +1 -0
- package/lib/tsconfig.tsbuildinfo +1 -0
- package/lib/types/fusion-fragment/ChartRenderer.d.ts +23 -0
- package/lib/types/fusion-fragment/ChartRenderer.d.ts.map +1 -0
- package/lib/types/fusion-fragment/FieldRenderer.d.ts +12 -0
- package/lib/types/fusion-fragment/FieldRenderer.d.ts.map +1 -0
- package/lib/types/fusion-fragment/FusionFragmentContext.d.ts +48 -0
- package/lib/types/fusion-fragment/FusionFragmentContext.d.ts.map +1 -0
- package/lib/types/fusion-fragment/FusionFragmentHandler.d.ts +38 -0
- package/lib/types/fusion-fragment/FusionFragmentHandler.d.ts.map +1 -0
- package/lib/types/fusion-fragment/FusionFragmentRenderer.d.ts +32 -0
- package/lib/types/fusion-fragment/FusionFragmentRenderer.d.ts.map +1 -0
- package/lib/types/fusion-fragment/SectionRenderer.d.ts +12 -0
- package/lib/types/fusion-fragment/SectionRenderer.d.ts.map +1 -0
- package/lib/types/fusion-fragment/TableRenderer.d.ts +15 -0
- package/lib/types/fusion-fragment/TableRenderer.d.ts.map +1 -0
- package/lib/types/fusion-fragment/index.d.ts +11 -0
- package/lib/types/fusion-fragment/index.d.ts.map +1 -0
- package/lib/types/index.d.ts +42 -0
- package/lib/types/index.d.ts.map +1 -0
- package/lib/types/render/index.d.ts +12 -0
- package/lib/types/render/index.d.ts.map +1 -0
- package/lib/types/render/textPreview.d.ts +20 -0
- package/lib/types/render/textPreview.d.ts.map +1 -0
- package/lib/types/types.d.ts +262 -0
- package/lib/types/types.d.ts.map +1 -0
- package/lib/types/validation/formatErrors.d.ts +35 -0
- package/lib/types/validation/formatErrors.d.ts.map +1 -0
- package/lib/types/validation/fuzzyMatch.d.ts +25 -0
- package/lib/types/validation/fuzzyMatch.d.ts.map +1 -0
- package/lib/types/validation/index.d.ts +8 -0
- package/lib/types/validation/index.d.ts.map +1 -0
- package/lib/types/validation/schemas.d.ts +67 -0
- package/lib/types/validation/schemas.d.ts.map +1 -0
- package/lib/types/validation/validateTemplate.d.ts +22 -0
- package/lib/types/validation/validateTemplate.d.ts.map +1 -0
- package/lib/vertesia-fusion-ux.js +2 -0
- package/lib/vertesia-fusion-ux.js.map +1 -0
- package/package.json +68 -0
- package/src/fusion-fragment/ChartRenderer.tsx +136 -0
- package/src/fusion-fragment/FieldRenderer.tsx +199 -0
- package/src/fusion-fragment/FusionFragmentContext.tsx +92 -0
- package/src/fusion-fragment/FusionFragmentHandler.tsx +313 -0
- package/src/fusion-fragment/FusionFragmentRenderer.tsx +156 -0
- package/src/fusion-fragment/SectionRenderer.tsx +196 -0
- package/src/fusion-fragment/TableRenderer.tsx +204 -0
- package/src/fusion-fragment/index.ts +20 -0
- package/src/index.ts +89 -0
- package/src/render/index.ts +16 -0
- package/src/render/textPreview.ts +231 -0
- package/src/types.ts +278 -0
- package/src/validation/formatErrors.ts +128 -0
- package/src/validation/fuzzyMatch.ts +109 -0
- package/src/validation/index.ts +8 -0
- package/src/validation/schemas.ts +175 -0
- package/src/validation/validateTemplate.ts +282 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/fusion-fragment/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,aAAa,EAA2B,MAAM,oBAAoB,CAAC;AAC5E,OAAO,EAAE,aAAa,EAA2B,MAAM,oBAAoB,CAAC;AAC5E,OAAO,EACL,sBAAsB,EACtB,wBAAwB,EACxB,4BAA4B,GAE7B,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,qBAAqB,EACrB,qCAAqC,GAEtC,MAAM,4BAA4B,CAAC"}
|
package/lib/esm/index.js
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @vertesia/fusion-ux
|
|
3
|
+
*
|
|
4
|
+
* Dynamic model-generated UI components for Vertesia.
|
|
5
|
+
*
|
|
6
|
+
* This package provides components that render model-generated templates
|
|
7
|
+
* with actual data. The model generates structure (template), the system
|
|
8
|
+
* provides values (data).
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```tsx
|
|
12
|
+
* import {
|
|
13
|
+
* FusionFragmentRenderer,
|
|
14
|
+
* FusionFragmentProvider,
|
|
15
|
+
* FusionFragmentHandler,
|
|
16
|
+
* } from '@vertesia/fusion-ux';
|
|
17
|
+
*
|
|
18
|
+
* // Option 1: Direct rendering with template and data
|
|
19
|
+
* <FusionFragmentRenderer
|
|
20
|
+
* template={templateFromModel}
|
|
21
|
+
* data={actualData}
|
|
22
|
+
* onUpdate={handleUpdate}
|
|
23
|
+
* />
|
|
24
|
+
*
|
|
25
|
+
* // Option 2: Context-based rendering (for markdown code blocks)
|
|
26
|
+
* <FusionFragmentProvider data={fund.parameters} onUpdate={handleUpdate}>
|
|
27
|
+
* <MarkdownRenderer content={agentResponse} />
|
|
28
|
+
* </FusionFragmentProvider>
|
|
29
|
+
*
|
|
30
|
+
* // Option 3: Code block handler for markdown renderers
|
|
31
|
+
* const codeBlockRenderers = {
|
|
32
|
+
* 'fusion-fragment': ({ code }) => <FusionFragmentHandler code={code} />
|
|
33
|
+
* };
|
|
34
|
+
* ```
|
|
35
|
+
*
|
|
36
|
+
* @packageDocumentation
|
|
37
|
+
*/
|
|
38
|
+
// Components
|
|
39
|
+
export { FusionFragmentRenderer, SectionRenderer, FieldRenderer, FusionFragmentProvider, FusionFragmentHandler, useFusionFragmentContext, useFusionFragmentContextSafe, createFusionFragmentCodeBlockRenderer, } from './fusion-fragment/index.js';
|
|
40
|
+
// Validation utilities
|
|
41
|
+
export { validateTemplate, parseAndValidateTemplate, FragmentTemplateSchema, SectionTemplateSchema, FieldTemplateSchema, findClosestKey, findSimilarKeys, formatValidationErrors, formatValidationSuccess, formatAvailableKeys, } from './validation/index.js';
|
|
42
|
+
// Render utilities (text preview only - image rendering is in apps/tools)
|
|
43
|
+
export { generateTextPreview, generateSampleData, generateCompactPreview, } from './render/index.js';
|
|
44
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAmBH,aAAa;AACb,OAAO,EACL,sBAAsB,EACtB,eAAe,EACf,aAAa,EACb,sBAAsB,EACtB,qBAAqB,EACrB,wBAAwB,EACxB,4BAA4B,EAC5B,qCAAqC,GAGtC,MAAM,4BAA4B,CAAC;AAEpC,uBAAuB;AACvB,OAAO,EACL,gBAAgB,EAChB,wBAAwB,EACxB,sBAAsB,EACtB,qBAAqB,EACrB,mBAAmB,EACnB,cAAc,EACd,eAAe,EACf,sBAAsB,EACtB,uBAAuB,EACvB,mBAAmB,GACpB,MAAM,uBAAuB,CAAC;AAE/B,0EAA0E;AAC1E,OAAO,EACL,mBAAmB,EACnB,kBAAkB,EAClB,sBAAsB,GACvB,MAAM,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Render module exports
|
|
3
|
+
*
|
|
4
|
+
* NOTE: All image rendering (renderToBuffer, renderToBase64, renderToDataUrl, renderToImage)
|
|
5
|
+
* has been moved to apps/tools/src/tools/fusion-ux/_shared/renderFragment.ts
|
|
6
|
+
* because it requires Node.js-only modules (@napi-rs/canvas) or DOM APIs that
|
|
7
|
+
* cannot be bundled for browser use.
|
|
8
|
+
*
|
|
9
|
+
* This module only exports text-based preview utilities that work in any environment.
|
|
10
|
+
*/
|
|
11
|
+
export { generateTextPreview, generateSampleData, generateCompactPreview, } from './textPreview.js';
|
|
12
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/render/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EACL,mBAAmB,EACnB,kBAAkB,EAClB,sBAAsB,GACvB,MAAM,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Text preview generation for non-vision models
|
|
3
|
+
* Generates a text description of what the fragment will look like
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Generate sample data for preview rendering
|
|
7
|
+
* Creates placeholder values based on field definitions
|
|
8
|
+
*/
|
|
9
|
+
export function generateSampleData(template, dataKeys) {
|
|
10
|
+
const data = {};
|
|
11
|
+
// Add provided data keys with placeholder values
|
|
12
|
+
for (const key of dataKeys) {
|
|
13
|
+
data[key] = `<${key}>`;
|
|
14
|
+
}
|
|
15
|
+
// Override with more specific placeholders based on field format
|
|
16
|
+
for (const section of template.sections) {
|
|
17
|
+
if (section.fields) {
|
|
18
|
+
for (const field of section.fields) {
|
|
19
|
+
if (field.key in data) {
|
|
20
|
+
data[field.key] = getSampleValue(field);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
return data;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Get a sample value for a field based on its format
|
|
29
|
+
*/
|
|
30
|
+
function getSampleValue(field) {
|
|
31
|
+
switch (field.format) {
|
|
32
|
+
case 'number':
|
|
33
|
+
return 1234;
|
|
34
|
+
case 'currency':
|
|
35
|
+
return 1000000;
|
|
36
|
+
case 'percent':
|
|
37
|
+
return 25;
|
|
38
|
+
case 'date':
|
|
39
|
+
return new Date().toISOString().split('T')[0];
|
|
40
|
+
case 'boolean':
|
|
41
|
+
return true;
|
|
42
|
+
case 'text':
|
|
43
|
+
default:
|
|
44
|
+
return `Sample ${field.label}`;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Generate a text description of the template for preview
|
|
49
|
+
* Used for non-vision models
|
|
50
|
+
*/
|
|
51
|
+
export function generateTextPreview(template, dataKeys) {
|
|
52
|
+
const lines = [];
|
|
53
|
+
lines.push('Template structure preview:');
|
|
54
|
+
lines.push('');
|
|
55
|
+
if (template.title) {
|
|
56
|
+
lines.push(`## ${template.title}`);
|
|
57
|
+
lines.push('');
|
|
58
|
+
}
|
|
59
|
+
for (const section of template.sections) {
|
|
60
|
+
const layout = section.layout || 'grid-3';
|
|
61
|
+
lines.push(`### ${section.title}`);
|
|
62
|
+
if (layout === 'table') {
|
|
63
|
+
lines.push(`Layout: table`);
|
|
64
|
+
if (section.dataKey) {
|
|
65
|
+
lines.push(`Data key: \`${section.dataKey}\``);
|
|
66
|
+
}
|
|
67
|
+
lines.push('');
|
|
68
|
+
if (section.columns) {
|
|
69
|
+
lines.push('Columns:');
|
|
70
|
+
for (const col of section.columns) {
|
|
71
|
+
let colLine = `- **${col.header}** \u2192 \`${col.key}\``;
|
|
72
|
+
if (col.format && col.format !== 'text') {
|
|
73
|
+
colLine += ` (${col.format})`;
|
|
74
|
+
}
|
|
75
|
+
lines.push(colLine);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
else if (layout === 'chart') {
|
|
80
|
+
lines.push(`Layout: chart`);
|
|
81
|
+
if (section.chart) {
|
|
82
|
+
const chart = section.chart;
|
|
83
|
+
if (chart.title) {
|
|
84
|
+
lines.push(`Chart title: ${chart.title}`);
|
|
85
|
+
}
|
|
86
|
+
if (chart.description) {
|
|
87
|
+
lines.push(`Description: ${chart.description}`);
|
|
88
|
+
}
|
|
89
|
+
const markType = chart.spec.mark
|
|
90
|
+
? (typeof chart.spec.mark === 'string' ? chart.spec.mark : chart.spec.mark.type || 'unknown')
|
|
91
|
+
: 'composite';
|
|
92
|
+
lines.push(`Chart type: ${markType}`);
|
|
93
|
+
if (chart.dataKey) {
|
|
94
|
+
lines.push(`Data key: \`${chart.dataKey}\``);
|
|
95
|
+
if (!dataKeys.includes(chart.dataKey)) {
|
|
96
|
+
lines.push('\u26a0\ufe0f **dataKey not found in data**');
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
else if (chart.spec.data?.values) {
|
|
100
|
+
lines.push(`Inline data: ${chart.spec.data.values.length} points`);
|
|
101
|
+
}
|
|
102
|
+
if (chart.height) {
|
|
103
|
+
lines.push(`Height: ${chart.height}px`);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
lines.push('');
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
const layoutDesc = layout === 'list' ? 'vertical list' : `${layout.split('-')[1]}-column grid`;
|
|
110
|
+
lines.push(`Layout: ${layoutDesc}${section.collapsed ? ' (collapsed by default)' : ''}`);
|
|
111
|
+
lines.push('');
|
|
112
|
+
if (section.fields) {
|
|
113
|
+
for (const field of section.fields) {
|
|
114
|
+
let fieldLine = `- **${field.label}** \u2192 \`${field.key}\``;
|
|
115
|
+
const attributes = [];
|
|
116
|
+
if (field.format && field.format !== 'text') {
|
|
117
|
+
attributes.push(field.format);
|
|
118
|
+
}
|
|
119
|
+
if (field.unit) {
|
|
120
|
+
attributes.push(`unit: "${field.unit}"`);
|
|
121
|
+
}
|
|
122
|
+
if (field.editable) {
|
|
123
|
+
attributes.push('editable');
|
|
124
|
+
}
|
|
125
|
+
if (field.highlight) {
|
|
126
|
+
attributes.push(`highlight: ${field.highlight}`);
|
|
127
|
+
}
|
|
128
|
+
if (attributes.length > 0) {
|
|
129
|
+
fieldLine += ` (${attributes.join(', ')})`;
|
|
130
|
+
}
|
|
131
|
+
// Check if key exists in data
|
|
132
|
+
if (!dataKeys.includes(field.key)) {
|
|
133
|
+
fieldLine += ' \u26a0\ufe0f **key not found in data**';
|
|
134
|
+
}
|
|
135
|
+
lines.push(fieldLine);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
lines.push('');
|
|
140
|
+
}
|
|
141
|
+
if (template.footer) {
|
|
142
|
+
lines.push('---');
|
|
143
|
+
lines.push(`Footer: ${template.footer}`);
|
|
144
|
+
lines.push('');
|
|
145
|
+
}
|
|
146
|
+
// Summary
|
|
147
|
+
const totalFields = template.sections.reduce((sum, s) => sum + (s.fields?.length || 0) + (s.columns?.length || 0), 0);
|
|
148
|
+
const missingKeys = template.sections
|
|
149
|
+
.flatMap(s => s.fields || [])
|
|
150
|
+
.filter(f => !dataKeys.includes(f.key))
|
|
151
|
+
.map(f => f.key);
|
|
152
|
+
lines.push('---');
|
|
153
|
+
lines.push(`Summary: ${template.sections.length} section(s), ${totalFields} field(s)/column(s)`);
|
|
154
|
+
if (missingKeys.length > 0) {
|
|
155
|
+
lines.push(`\u26a0\ufe0f Missing keys: ${missingKeys.join(', ')}`);
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
lines.push('\u2705 All field keys found in data');
|
|
159
|
+
}
|
|
160
|
+
return lines.join('\n');
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Generate a compact description for tool responses
|
|
164
|
+
*/
|
|
165
|
+
export function generateCompactPreview(template) {
|
|
166
|
+
const sections = template.sections.map(s => {
|
|
167
|
+
if (s.layout === 'table' && s.columns) {
|
|
168
|
+
const colList = s.columns
|
|
169
|
+
.slice(0, 3)
|
|
170
|
+
.map(c => c.header)
|
|
171
|
+
.join(', ');
|
|
172
|
+
const more = s.columns.length > 3 ? `, +${s.columns.length - 3} more` : '';
|
|
173
|
+
return `${s.title} (table): ${colList}${more}`;
|
|
174
|
+
}
|
|
175
|
+
if (s.layout === 'chart' && s.chart) {
|
|
176
|
+
const markType = s.chart.spec.mark
|
|
177
|
+
? (typeof s.chart.spec.mark === 'string' ? s.chart.spec.mark : s.chart.spec.mark.type || 'chart')
|
|
178
|
+
: 'chart';
|
|
179
|
+
return `${s.title} (${markType} chart)`;
|
|
180
|
+
}
|
|
181
|
+
if (s.fields) {
|
|
182
|
+
const fieldList = s.fields
|
|
183
|
+
.slice(0, 3)
|
|
184
|
+
.map(f => f.label)
|
|
185
|
+
.join(', ');
|
|
186
|
+
const more = s.fields.length > 3 ? `, +${s.fields.length - 3} more` : '';
|
|
187
|
+
return `${s.title}: ${fieldList}${more}`;
|
|
188
|
+
}
|
|
189
|
+
return s.title;
|
|
190
|
+
});
|
|
191
|
+
const title = template.title ? `"${template.title}" - ` : '';
|
|
192
|
+
return `${title}${sections.join(' | ')}`;
|
|
193
|
+
}
|
|
194
|
+
//# sourceMappingURL=textPreview.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"textPreview.js","sourceRoot":"","sources":["../../../src/render/textPreview.ts"],"names":[],"mappings":"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"}
|
package/lib/esm/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error formatting utilities for model-friendly output
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Format validation errors as a model-friendly string
|
|
6
|
+
* @param errors - Array of validation errors
|
|
7
|
+
* @returns Formatted error message
|
|
8
|
+
*/
|
|
9
|
+
export function formatValidationErrors(errors) {
|
|
10
|
+
if (errors.length === 0) {
|
|
11
|
+
return 'Template is valid.';
|
|
12
|
+
}
|
|
13
|
+
const header = `Template validation failed with ${errors.length} error${errors.length > 1 ? 's' : ''}:\n`;
|
|
14
|
+
const formattedErrors = errors.map((error, index) => {
|
|
15
|
+
let message = `${index + 1}. ${error.message}`;
|
|
16
|
+
message += `\n Path: ${error.path}`;
|
|
17
|
+
if (error.suggestion) {
|
|
18
|
+
message += `\n \u2192 ${error.suggestion}`;
|
|
19
|
+
}
|
|
20
|
+
return message;
|
|
21
|
+
});
|
|
22
|
+
return header + '\n' + formattedErrors.join('\n\n');
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Format a successful validation with preview info
|
|
26
|
+
* @param template - The validated template
|
|
27
|
+
* @param dataKeys - Available data keys
|
|
28
|
+
* @returns Success message with preview
|
|
29
|
+
*/
|
|
30
|
+
export function formatValidationSuccess(template, dataKeys) {
|
|
31
|
+
const lines = ['Template valid. Preview:'];
|
|
32
|
+
lines.push('');
|
|
33
|
+
if (template.title) {
|
|
34
|
+
lines.push(`**${template.title}**`);
|
|
35
|
+
lines.push('');
|
|
36
|
+
}
|
|
37
|
+
for (const section of template.sections) {
|
|
38
|
+
const fieldCount = section.fields.length;
|
|
39
|
+
lines.push(`[${section.title}] ${fieldCount} field${fieldCount > 1 ? 's' : ''}:`);
|
|
40
|
+
for (const field of section.fields) {
|
|
41
|
+
let fieldDesc = `- ${field.label} (${field.key}`;
|
|
42
|
+
if (field.format && field.format !== 'text') {
|
|
43
|
+
fieldDesc += `, ${field.format}`;
|
|
44
|
+
}
|
|
45
|
+
fieldDesc += ')';
|
|
46
|
+
// Check if key exists in data
|
|
47
|
+
if (!dataKeys.includes(field.key)) {
|
|
48
|
+
fieldDesc += ' \u26a0\ufe0f key not in data';
|
|
49
|
+
}
|
|
50
|
+
lines.push(fieldDesc);
|
|
51
|
+
}
|
|
52
|
+
lines.push('');
|
|
53
|
+
}
|
|
54
|
+
return lines.join('\n');
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Format a list of available keys for model reference
|
|
58
|
+
* @param dataKeys - Available data keys
|
|
59
|
+
* @param groupByPrefix - Whether to group keys by common prefix
|
|
60
|
+
* @returns Formatted key list
|
|
61
|
+
*/
|
|
62
|
+
export function formatAvailableKeys(dataKeys, groupByPrefix = true) {
|
|
63
|
+
if (dataKeys.length === 0) {
|
|
64
|
+
return 'No data keys available.';
|
|
65
|
+
}
|
|
66
|
+
if (!groupByPrefix || dataKeys.length <= 10) {
|
|
67
|
+
return `Available keys: ${dataKeys.join(', ')}`;
|
|
68
|
+
}
|
|
69
|
+
// Group by prefix (e.g., fund.name, fund.type -> fund.*)
|
|
70
|
+
const groups = new Map();
|
|
71
|
+
for (const key of dataKeys) {
|
|
72
|
+
const dotIndex = key.indexOf('.');
|
|
73
|
+
if (dotIndex > 0) {
|
|
74
|
+
const prefix = key.substring(0, dotIndex);
|
|
75
|
+
const rest = key.substring(dotIndex + 1);
|
|
76
|
+
const group = groups.get(prefix) || [];
|
|
77
|
+
group.push(rest);
|
|
78
|
+
groups.set(prefix, group);
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
const group = groups.get('') || [];
|
|
82
|
+
group.push(key);
|
|
83
|
+
groups.set('', group);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
const lines = ['Available keys:'];
|
|
87
|
+
// Top-level keys first
|
|
88
|
+
const topLevel = groups.get('');
|
|
89
|
+
if (topLevel && topLevel.length > 0) {
|
|
90
|
+
lines.push(` ${topLevel.join(', ')}`);
|
|
91
|
+
}
|
|
92
|
+
// Grouped keys
|
|
93
|
+
for (const [prefix, keys] of groups) {
|
|
94
|
+
if (prefix === '')
|
|
95
|
+
continue;
|
|
96
|
+
if (keys.length <= 3) {
|
|
97
|
+
lines.push(` ${prefix}: ${keys.join(', ')}`);
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
lines.push(` ${prefix}: ${keys.slice(0, 3).join(', ')}, ... (${keys.length} total)`);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return lines.join('\n');
|
|
104
|
+
}
|
|
105
|
+
//# sourceMappingURL=formatErrors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"formatErrors.js","sourceRoot":"","sources":["../../../src/validation/formatErrors.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH;;;;GAIG;AACH,MAAM,UAAU,sBAAsB,CAAC,MAAyB;IAC9D,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,OAAO,oBAAoB,CAAC;IAC9B,CAAC;IAED,MAAM,MAAM,GAAG,mCAAmC,MAAM,CAAC,MAAM,SAAS,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC;IAE1G,MAAM,eAAe,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;QAClD,IAAI,OAAO,GAAG,GAAG,KAAK,GAAG,CAAC,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC;QAC/C,OAAO,IAAI,cAAc,KAAK,CAAC,IAAI,EAAE,CAAC;QACtC,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC;YACrB,OAAO,IAAI,eAAe,KAAK,CAAC,UAAU,EAAE,CAAC;QAC/C,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC,CAAC,CAAC;IAEH,OAAO,MAAM,GAAG,IAAI,GAAG,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AACtD,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,uBAAuB,CACrC,QAAgI,EAChI,QAAkB;IAElB,MAAM,KAAK,GAAa,CAAC,0BAA0B,CAAC,CAAC;IACrD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEf,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC;QACnB,KAAK,CAAC,IAAI,CAAC,KAAK,QAAQ,CAAC,KAAK,IAAI,CAAC,CAAC;QACpC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjB,CAAC;IAED,KAAK,MAAM,OAAO,IAAI,QAAQ,CAAC,QAAQ,EAAE,CAAC;QACxC,MAAM,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC;QACzC,KAAK,CAAC,IAAI,CAAC,IAAI,OAAO,CAAC,KAAK,KAAK,UAAU,SAAS,UAAU,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;QAElF,KAAK,MAAM,KAAK,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;YACnC,IAAI,SAAS,GAAG,KAAK,KAAK,CAAC,KAAK,KAAK,KAAK,CAAC,GAAG,EAAE,CAAC;YACjD,IAAI,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;gBAC5C,SAAS,IAAI,KAAK,KAAK,CAAC,MAAM,EAAE,CAAC;YACnC,CAAC;YACD,SAAS,IAAI,GAAG,CAAC;YAEjB,8BAA8B;YAC9B,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;gBAClC,SAAS,IAAI,+BAA+B,CAAC;YAC/C,CAAC;YAED,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACxB,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjB,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB,CACjC,QAAkB,EAClB,gBAAyB,IAAI;IAE7B,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,yBAAyB,CAAC;IACnC,CAAC;IAED,IAAI,CAAC,aAAa,IAAI,QAAQ,CAAC,MAAM,IAAI,EAAE,EAAE,CAAC;QAC5C,OAAO,mBAAmB,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;IAClD,CAAC;IAED,yDAAyD;IACzD,MAAM,MAAM,GAAG,IAAI,GAAG,EAAoB,CAAC;IAE3C,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;QAC3B,MAAM,QAAQ,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAClC,IAAI,QAAQ,GAAG,CAAC,EAAE,CAAC;YACjB,MAAM,MAAM,GAAG,GAAG,CAAC,SAAS,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;YAC1C,MAAM,IAAI,GAAG,GAAG,CAAC,SAAS,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC;YACzC,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;YACvC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACjB,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QAC5B,CAAC;aAAM,CAAC;YACN,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC;YACnC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAChB,MAAM,CAAC,GAAG,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;QACxB,CAAC;IACH,CAAC;IAED,MAAM,KAAK,GAAa,CAAC,iBAAiB,CAAC,CAAC;IAE5C,uBAAuB;IACvB,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChC,IAAI,QAAQ,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACpC,KAAK,CAAC,IAAI,CAAC,KAAK,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACzC,CAAC;IAED,eAAe;IACf,KAAK,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,MAAM,EAAE,CAAC;QACpC,IAAI,MAAM,KAAK,EAAE;YAAE,SAAS;QAC5B,IAAI,IAAI,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;YACrB,KAAK,CAAC,IAAI,CAAC,KAAK,MAAM,KAAK,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAChD,CAAC;aAAM,CAAC;YACN,KAAK,CAAC,IAAI,CAAC,KAAK,MAAM,KAAK,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,IAAI,CAAC,MAAM,SAAS,CAAC,CAAC;QACxF,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fuzzy matching utilities for key suggestions
|
|
3
|
+
* Uses Levenshtein distance for finding similar keys
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Calculate Levenshtein distance between two strings
|
|
7
|
+
*/
|
|
8
|
+
export function levenshteinDistance(a, b) {
|
|
9
|
+
const matrix = [];
|
|
10
|
+
// Initialize first column
|
|
11
|
+
for (let i = 0; i <= a.length; i++) {
|
|
12
|
+
matrix[i] = [i];
|
|
13
|
+
}
|
|
14
|
+
// Initialize first row
|
|
15
|
+
for (let j = 0; j <= b.length; j++) {
|
|
16
|
+
matrix[0][j] = j;
|
|
17
|
+
}
|
|
18
|
+
// Fill in the rest of the matrix
|
|
19
|
+
for (let i = 1; i <= a.length; i++) {
|
|
20
|
+
for (let j = 1; j <= b.length; j++) {
|
|
21
|
+
const cost = a[i - 1] === b[j - 1] ? 0 : 1;
|
|
22
|
+
matrix[i][j] = Math.min(matrix[i - 1][j] + 1, // deletion
|
|
23
|
+
matrix[i][j - 1] + 1, // insertion
|
|
24
|
+
matrix[i - 1][j - 1] + cost // substitution
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return matrix[a.length][b.length];
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Find the closest matching key from a list of valid keys
|
|
32
|
+
* @param input - The key that wasn't found
|
|
33
|
+
* @param validKeys - List of valid keys to search
|
|
34
|
+
* @param maxDistance - Maximum edit distance to consider (default: 3)
|
|
35
|
+
* @returns The closest key, or undefined if none are close enough
|
|
36
|
+
*/
|
|
37
|
+
export function findClosestKey(input, validKeys, maxDistance = 3) {
|
|
38
|
+
if (validKeys.length === 0)
|
|
39
|
+
return undefined;
|
|
40
|
+
const inputLower = input.toLowerCase();
|
|
41
|
+
let bestMatch;
|
|
42
|
+
let bestDistance = Infinity;
|
|
43
|
+
for (const key of validKeys) {
|
|
44
|
+
const keyLower = key.toLowerCase();
|
|
45
|
+
// Exact case-insensitive match
|
|
46
|
+
if (inputLower === keyLower) {
|
|
47
|
+
return key;
|
|
48
|
+
}
|
|
49
|
+
// Check if input is a substring or key is a substring
|
|
50
|
+
if (inputLower.includes(keyLower) || keyLower.includes(inputLower)) {
|
|
51
|
+
const distance = Math.abs(inputLower.length - keyLower.length);
|
|
52
|
+
if (distance < bestDistance) {
|
|
53
|
+
bestDistance = distance;
|
|
54
|
+
bestMatch = key;
|
|
55
|
+
}
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
// Levenshtein distance
|
|
59
|
+
const distance = levenshteinDistance(inputLower, keyLower);
|
|
60
|
+
if (distance < bestDistance && distance <= maxDistance) {
|
|
61
|
+
bestDistance = distance;
|
|
62
|
+
bestMatch = key;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return bestMatch;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Find multiple similar keys, sorted by relevance
|
|
69
|
+
* @param input - The key that wasn't found
|
|
70
|
+
* @param validKeys - List of valid keys to search
|
|
71
|
+
* @param maxResults - Maximum number of suggestions (default: 3)
|
|
72
|
+
* @returns Array of similar keys
|
|
73
|
+
*/
|
|
74
|
+
export function findSimilarKeys(input, validKeys, maxResults = 3) {
|
|
75
|
+
if (validKeys.length === 0)
|
|
76
|
+
return [];
|
|
77
|
+
const inputLower = input.toLowerCase();
|
|
78
|
+
const scored = validKeys
|
|
79
|
+
.map(key => ({
|
|
80
|
+
key,
|
|
81
|
+
distance: levenshteinDistance(inputLower, key.toLowerCase())
|
|
82
|
+
}))
|
|
83
|
+
.filter(({ distance }) => distance <= 4) // Filter out very different keys
|
|
84
|
+
.sort((a, b) => a.distance - b.distance);
|
|
85
|
+
return scored.slice(0, maxResults).map(({ key }) => key);
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=fuzzyMatch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fuzzyMatch.js","sourceRoot":"","sources":["../../../src/validation/fuzzyMatch.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Validation module exports
|
|
3
|
+
*/
|
|
4
|
+
export { validateTemplate, parseAndValidateTemplate } from './validateTemplate.js';
|
|
5
|
+
export { FragmentTemplateSchema, SectionTemplateSchema, FieldTemplateSchema } from './schemas.js';
|
|
6
|
+
export { findClosestKey, findSimilarKeys, levenshteinDistance } from './fuzzyMatch.js';
|
|
7
|
+
export { formatValidationErrors, formatValidationSuccess, formatAvailableKeys } from './formatErrors.js';
|
|
8
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/validation/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,gBAAgB,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AACnF,OAAO,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAClG,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACvF,OAAO,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC"}
|