modscape 1.0.5 → 1.0.7
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/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-xtv3bmxO.js → index-CzpKPd1L.js} +2 -2
- package/visualizer-dist/assets/index-D-n9UqHA.css +1 -0
- package/visualizer-dist/index.html +2 -2
- package/visualizer-dist/assets/index-CoPelnvo.css +0 -1
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.7');
|
|
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
|