modscape 1.0.7 → 1.1.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/README.ja.md +7 -0
- package/README.md +7 -0
- package/package.json +1 -1
- package/src/export.js +84 -11
- package/src/index.js +1 -1
- package/visualizer/package.json +2 -1
- package/visualizer-dist/assets/index-B4th5tqq.js +63 -0
- package/visualizer-dist/assets/index-DLjsShXS.css +1 -0
- package/visualizer-dist/index.html +2 -2
- package/visualizer-dist/assets/index-CzpKPd1L.js +0 -56
- package/visualizer-dist/assets/index-D-n9UqHA.css +0 -1
package/README.ja.md
CHANGED
|
@@ -113,6 +113,13 @@ modscape dev ./models
|
|
|
113
113
|
```
|
|
114
114
|
- **永続化**: レイアウトやメタデータの変更は、直接ファイルに書き戻されます(オートセーブ対応)。
|
|
115
115
|
|
|
116
|
+
### 新規モデルの作成
|
|
117
|
+
```bash
|
|
118
|
+
modscape new models/sales/customer.yaml
|
|
119
|
+
```
|
|
120
|
+
- **再帰的作成**: 指定したパスの親ディレクトリが存在しない場合、自動的に作成します。
|
|
121
|
+
- **ボイラープレート**: ドメイン、3階層ネーミング、リレーション、リネージの例が含まれた有効なYAMLファイルを生成します。
|
|
122
|
+
|
|
116
123
|
### ビルドモード (静的サイト)
|
|
117
124
|
```bash
|
|
118
125
|
modscape build ./models -o docs-site
|
package/README.md
CHANGED
|
@@ -129,6 +129,13 @@ modscape dev ./models
|
|
|
129
129
|
```
|
|
130
130
|
- **Persistence**: Layout and metadata changes are saved directly to your files (supports Auto-save).
|
|
131
131
|
|
|
132
|
+
### Create New Model
|
|
133
|
+
```bash
|
|
134
|
+
modscape new models/sales/customer.yaml
|
|
135
|
+
```
|
|
136
|
+
- **Recursive Scaffolding**: Automatically creates parent directories if they don't exist.
|
|
137
|
+
- **Boilerplate**: Generates a valid YAML model with examples of domains, tri-layer naming, relationships, and lineage.
|
|
138
|
+
|
|
132
139
|
### Build Mode (Static Site)
|
|
133
140
|
```bash
|
|
134
141
|
modscape build ./models -o docs-site
|
package/package.json
CHANGED
package/src/export.js
CHANGED
|
@@ -15,6 +15,7 @@ function normalizeSchema(data) {
|
|
|
15
15
|
tables: Array.isArray(data.tables) ? data.tables : [],
|
|
16
16
|
relationships: Array.isArray(data.relationships) ? data.relationships : [],
|
|
17
17
|
domains: Array.isArray(data.domains) ? data.domains : [],
|
|
18
|
+
annotations: Array.isArray(data.annotations) ? data.annotations : [],
|
|
18
19
|
layout: data.layout || {}
|
|
19
20
|
};
|
|
20
21
|
|
|
@@ -30,11 +31,18 @@ function normalizeSchema(data) {
|
|
|
30
31
|
}
|
|
31
32
|
}
|
|
32
33
|
|
|
34
|
+
const columns = (Array.isArray(table.columns) ? table.columns : []).map(col => ({
|
|
35
|
+
...col,
|
|
36
|
+
id: col.id || 'unknown',
|
|
37
|
+
logical: col.logical || { name: col.id || 'unknown', type: 'string' },
|
|
38
|
+
physical: col.physical || { name: '', type: '' }
|
|
39
|
+
}));
|
|
40
|
+
|
|
33
41
|
return {
|
|
34
42
|
...table,
|
|
35
43
|
id: table.id || 'unknown',
|
|
36
44
|
name: table.name || table.id || 'Unnamed Table',
|
|
37
|
-
columns
|
|
45
|
+
columns,
|
|
38
46
|
sampleData: Array.isArray(sampleData) ? sampleData : []
|
|
39
47
|
};
|
|
40
48
|
});
|
|
@@ -47,7 +55,31 @@ function normalizeSchema(data) {
|
|
|
47
55
|
* Spaces and hyphens are replaced with underscores.
|
|
48
56
|
*/
|
|
49
57
|
function sanitize(str) {
|
|
50
|
-
|
|
58
|
+
if (!str) return 'unknown';
|
|
59
|
+
// Mermaid ER/Flowchart labels can be wrapped in quotes for better compatibility
|
|
60
|
+
return str.replace(/[^a-zA-Z0-9_\u3000-\u303f\u3040-\u309f\u30a0-\u30ff\uff00-\uff9f\u4e00-\u9faf]/g, '_');
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Generates Mermaid Data Lineage syntax.
|
|
65
|
+
*/
|
|
66
|
+
function generateMermaidLineage(schema) {
|
|
67
|
+
let mermaid = 'graph TD\n';
|
|
68
|
+
let hasLineage = false;
|
|
69
|
+
|
|
70
|
+
schema.tables.forEach(table => {
|
|
71
|
+
if (table.lineage?.upstream && table.lineage.upstream.length > 0) {
|
|
72
|
+
hasLineage = true;
|
|
73
|
+
const targetName = sanitize(table.name);
|
|
74
|
+
table.lineage.upstream.forEach(upId => {
|
|
75
|
+
const sourceTable = schema.tables.find(t => t.id === upId);
|
|
76
|
+
const sourceName = sanitize(sourceTable?.name || upId);
|
|
77
|
+
mermaid += ` ${sourceName} --> ${targetName}\n`;
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
return hasLineage ? mermaid : null;
|
|
51
83
|
}
|
|
52
84
|
|
|
53
85
|
/**
|
|
@@ -88,6 +120,24 @@ function generateMermaidER(schema) {
|
|
|
88
120
|
return mermaid;
|
|
89
121
|
}
|
|
90
122
|
|
|
123
|
+
/**
|
|
124
|
+
* Generates the Sticky Notes section.
|
|
125
|
+
*/
|
|
126
|
+
function generateNotesSection(schema) {
|
|
127
|
+
if (!schema.annotations || schema.annotations.length === 0) return null;
|
|
128
|
+
|
|
129
|
+
let md = '## Sticky Notes\n\n';
|
|
130
|
+
schema.annotations.forEach(note => {
|
|
131
|
+
md += `> **[Note]** ${note.text}\n`;
|
|
132
|
+
if (note.targetId) {
|
|
133
|
+
md += `> *Attached to: ${note.targetId} (${note.targetType})*\n`;
|
|
134
|
+
}
|
|
135
|
+
md += '\n';
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
return md;
|
|
139
|
+
}
|
|
140
|
+
|
|
91
141
|
/**
|
|
92
142
|
* Generates the full Markdown document.
|
|
93
143
|
*/
|
|
@@ -95,10 +145,21 @@ export function generateMarkdown(schema, modelName) {
|
|
|
95
145
|
let md = `# ${modelName} Data Model Definition\n\n`;
|
|
96
146
|
|
|
97
147
|
// Mermaid ER Diagram
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
148
|
+
if (schema.relationships && schema.relationships.length > 0) {
|
|
149
|
+
md += '## ER Diagram\n\n';
|
|
150
|
+
md += '```mermaid\n';
|
|
151
|
+
md += generateMermaidER(schema);
|
|
152
|
+
md += '```\n\n';
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// Mermaid Data Lineage
|
|
156
|
+
const lineageMermaid = generateMermaidLineage(schema);
|
|
157
|
+
if (lineageMermaid) {
|
|
158
|
+
md += '## Data Lineage\n\n';
|
|
159
|
+
md += '```mermaid\n';
|
|
160
|
+
md += lineageMermaid;
|
|
161
|
+
md += '```\n\n';
|
|
162
|
+
}
|
|
102
163
|
|
|
103
164
|
// Domains
|
|
104
165
|
if (schema.domains && schema.domains.length > 0) {
|
|
@@ -123,20 +184,26 @@ export function generateMarkdown(schema, modelName) {
|
|
|
123
184
|
md += `**Description**: ${table.conceptual.description}\n\n`;
|
|
124
185
|
}
|
|
125
186
|
if (table.appearance?.type) {
|
|
126
|
-
md += `**Type**: ${table.appearance.type}\n\n`;
|
|
187
|
+
md += `**Type**: ${table.appearance.type.toUpperCase()}\n\n`;
|
|
127
188
|
}
|
|
128
189
|
|
|
129
|
-
// Columns Table
|
|
190
|
+
// Columns Table (Enhanced with Physical info)
|
|
130
191
|
if (table.columns && table.columns.length > 0) {
|
|
131
192
|
md += '#### Column Definitions\n\n';
|
|
132
|
-
md += '|
|
|
133
|
-
md += '| --- | --- | --- | --- | --- |\n';
|
|
193
|
+
md += '| Logical Name | Physical Name | Logical Type | Physical Type | Key | Description |\n';
|
|
194
|
+
md += '| --- | --- | --- | --- | --- | --- |\n';
|
|
134
195
|
table.columns.forEach(col => {
|
|
135
196
|
const key = [
|
|
136
197
|
col.logical?.isPrimaryKey ? 'PK' : '',
|
|
137
198
|
col.logical?.isForeignKey ? 'FK' : ''
|
|
138
199
|
].filter(Boolean).join(', ');
|
|
139
|
-
|
|
200
|
+
const logicalName = col.logical?.name || col.id;
|
|
201
|
+
const physicalName = col.physical?.name || '-';
|
|
202
|
+
const logicalType = col.logical?.type || '-';
|
|
203
|
+
const physicalType = col.physical?.type || '-';
|
|
204
|
+
const description = col.logical?.description || '-';
|
|
205
|
+
|
|
206
|
+
md += `| ${logicalName} | ${physicalName} | ${logicalType} | ${physicalType} | ${key || '-'} | ${description} |\n`;
|
|
140
207
|
});
|
|
141
208
|
md += '\n';
|
|
142
209
|
}
|
|
@@ -157,6 +224,12 @@ export function generateMarkdown(schema, modelName) {
|
|
|
157
224
|
}
|
|
158
225
|
});
|
|
159
226
|
|
|
227
|
+
// Sticky Notes Section
|
|
228
|
+
const notesSection = generateNotesSection(schema);
|
|
229
|
+
if (notesSection) {
|
|
230
|
+
md += notesSection;
|
|
231
|
+
}
|
|
232
|
+
|
|
160
233
|
return md;
|
|
161
234
|
}
|
|
162
235
|
|
package/src/index.js
CHANGED
package/visualizer/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "visualizer",
|
|
3
3
|
"private": true,
|
|
4
|
-
"version": "1.0
|
|
4
|
+
"version": "1.1.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"dev": "vite",
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
"clsx": "^2.1.1",
|
|
21
21
|
"codemirror": "^6.0.2",
|
|
22
22
|
"dagre": "^0.8.5",
|
|
23
|
+
"html-to-image": "^1.11.13",
|
|
23
24
|
"js-yaml": "^4.1.1",
|
|
24
25
|
"lucide-react": "^0.575.0",
|
|
25
26
|
"react": "^19.2.0",
|