modscape 1.0.6 → 1.0.8
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/create.js +45 -0
- package/src/index.js +10 -1
- package/src/templates/default-model.yaml +61 -0
- package/visualizer/package.json +1 -1
- package/visualizer-dist/assets/{index-DU3LZqQA.js → index-_wTHYing.js} +9 -9
- package/visualizer-dist/index.html +1 -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/create.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { confirm } from '@inquirer/prompts';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import fs from 'fs';
|
|
4
|
+
import { fileURLToPath } from 'url';
|
|
5
|
+
|
|
6
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
7
|
+
|
|
8
|
+
export async function createModel(filePath) {
|
|
9
|
+
// 1. Extension Handling
|
|
10
|
+
if (!filePath.endsWith('.yaml') && !filePath.endsWith('.yml')) {
|
|
11
|
+
filePath += '.yaml';
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const absolutePath = path.resolve(process.cwd(), filePath);
|
|
15
|
+
const dir = path.dirname(absolutePath);
|
|
16
|
+
|
|
17
|
+
// 2. Recursive Directory Creation
|
|
18
|
+
if (!fs.existsSync(dir)) {
|
|
19
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
20
|
+
console.log(` Created directory: ${path.relative(process.cwd(), dir)}`);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// 3. Overwrite Protection
|
|
24
|
+
if (fs.existsSync(absolutePath)) {
|
|
25
|
+
const overwrite = await confirm({
|
|
26
|
+
message: `File ${filePath} already exists. Overwrite with template?`,
|
|
27
|
+
default: false,
|
|
28
|
+
});
|
|
29
|
+
if (!overwrite) {
|
|
30
|
+
console.log(` Operation cancelled. File ${filePath} preserved.`);
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// 4. Template Writing
|
|
36
|
+
try {
|
|
37
|
+
const templatePath = path.join(__dirname, 'templates/default-model.yaml');
|
|
38
|
+
const template = fs.readFileSync(templatePath, 'utf8');
|
|
39
|
+
fs.writeFileSync(absolutePath, template, 'utf8');
|
|
40
|
+
console.log(` ✅ Successfully created new model: ${filePath}`);
|
|
41
|
+
console.log(` 🚀 Run 'modscape dev ${filePath}' to start modeling.`);
|
|
42
|
+
} catch (error) {
|
|
43
|
+
console.error(` ❌ Failed to create model: ${error.message}`);
|
|
44
|
+
}
|
|
45
|
+
}
|
package/src/index.js
CHANGED
|
@@ -7,6 +7,7 @@ import { startDevServer } from './dev.js';
|
|
|
7
7
|
import { build } from './build.js';
|
|
8
8
|
import { initProject } from './init.js';
|
|
9
9
|
import { exportModel } from './export.js';
|
|
10
|
+
import { createModel } from './create.js';
|
|
10
11
|
|
|
11
12
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
12
13
|
const VISUALIZER_PATH = path.resolve(__dirname, '../visualizer');
|
|
@@ -15,7 +16,7 @@ const program = new Command();
|
|
|
15
16
|
program
|
|
16
17
|
.name('modscape')
|
|
17
18
|
.description('Modscape: A YAML-driven data modeling visualizer CLI')
|
|
18
|
-
.version('1.0.
|
|
19
|
+
.version('1.0.8');
|
|
19
20
|
|
|
20
21
|
program
|
|
21
22
|
.command('init')
|
|
@@ -28,6 +29,14 @@ program
|
|
|
28
29
|
initProject(options);
|
|
29
30
|
});
|
|
30
31
|
|
|
32
|
+
program
|
|
33
|
+
.command('new')
|
|
34
|
+
.description('Create a new YAML model file from template')
|
|
35
|
+
.argument('<path>', 'path to the new YAML file')
|
|
36
|
+
.action((path) => {
|
|
37
|
+
createModel(path);
|
|
38
|
+
});
|
|
39
|
+
|
|
31
40
|
program
|
|
32
41
|
.command('dev')
|
|
33
42
|
.description('Start the development visualizer with local YAML files or directories')
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# Modscape Data Model
|
|
2
|
+
# Use 'modscape dev <filename>' to visualize and edit this model.
|
|
3
|
+
|
|
4
|
+
domains:
|
|
5
|
+
- id: sample_domain
|
|
6
|
+
name: Sample Domain
|
|
7
|
+
color: "rgba(59, 130, 246, 0.1)"
|
|
8
|
+
description: "A logical grouping of related business entities."
|
|
9
|
+
tables: [source_table, derived_table]
|
|
10
|
+
|
|
11
|
+
tables:
|
|
12
|
+
- id: source_table
|
|
13
|
+
name: Source Table
|
|
14
|
+
logical_name: "Original Business Record"
|
|
15
|
+
physical_name: "raw_source_table"
|
|
16
|
+
appearance:
|
|
17
|
+
type: table
|
|
18
|
+
icon: "📋"
|
|
19
|
+
columns:
|
|
20
|
+
- id: id
|
|
21
|
+
logical: { name: ID, type: Int, isPrimaryKey: true }
|
|
22
|
+
physical: { name: id, type: BIGINT }
|
|
23
|
+
- id: name
|
|
24
|
+
logical: { name: Name, type: String }
|
|
25
|
+
physical: { name: name, type: VARCHAR(255) }
|
|
26
|
+
sampleData:
|
|
27
|
+
- [id, name]
|
|
28
|
+
- [1, "Example Record A"]
|
|
29
|
+
- [2, "Example Record B"]
|
|
30
|
+
|
|
31
|
+
- id: derived_table
|
|
32
|
+
name: Derived Mart
|
|
33
|
+
logical_name: "Processed Analytics Summary"
|
|
34
|
+
physical_name: "mart_derived_summary"
|
|
35
|
+
appearance:
|
|
36
|
+
type: mart
|
|
37
|
+
icon: "📈"
|
|
38
|
+
lineage:
|
|
39
|
+
upstream: [source_table] # Lineage: Defines the flow of data (dashed arrows)
|
|
40
|
+
columns:
|
|
41
|
+
- id: id
|
|
42
|
+
logical: { name: ID, type: Int, isPrimaryKey: true }
|
|
43
|
+
physical: { name: id, type: BIGINT }
|
|
44
|
+
- id: source_id
|
|
45
|
+
logical: { name: Source ID, type: Int, isForeignKey: true }
|
|
46
|
+
physical: { name: source_id, type: BIGINT }
|
|
47
|
+
- id: summary_value
|
|
48
|
+
logical: { name: Value, type: Decimal, additivity: fully }
|
|
49
|
+
physical: { name: total_val, type: NUMBER(18,2) }
|
|
50
|
+
sampleData:
|
|
51
|
+
- [id, source_id, summary_value]
|
|
52
|
+
- [101, 1, 150.50]
|
|
53
|
+
- [102, 2, 300.75]
|
|
54
|
+
|
|
55
|
+
relationships:
|
|
56
|
+
# Relationships: Defines Entity-Relationship connections (solid lines with 1:M badges)
|
|
57
|
+
- from: { table: source_table, column: id }
|
|
58
|
+
to: { table: derived_table, column: source_id }
|
|
59
|
+
type: one-to-many
|
|
60
|
+
|
|
61
|
+
lineage: [] # Note: Table-level lineage is also supported here, or inside tables[].lineage
|