entitymodeler 0.1.0 → 0.1.1
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/bin/em.mjs +14 -3
- package/package.json +1 -1
package/bin/em.mjs
CHANGED
|
@@ -12729,6 +12729,10 @@ function relationalPlan(m) {
|
|
|
12729
12729
|
if (!child || !parent || !pk) continue;
|
|
12730
12730
|
let fk = resolveForeignKey(m, r, byName);
|
|
12731
12731
|
if (!fk) fk = addColumn(child, ends.child === ends.parent ? `parent_${pk.name}` : keyColumnName(parent, pk), pk, `${parent.display_name} (${r.forward_label})`, `relationship ${r.name}`);
|
|
12732
|
+
if (r.required) {
|
|
12733
|
+
const column = child.columns.find((c) => c.name === fk);
|
|
12734
|
+
if (column) column.notNull = true;
|
|
12735
|
+
}
|
|
12732
12736
|
if (r.cardinality === "1:1" && !child.pk.includes(fk)) child.unique.push(fk);
|
|
12733
12737
|
for (const ra of r.attributes || []) addRelationshipColumn(child, ra, r, false);
|
|
12734
12738
|
foreignKeys.push({ name: fkName(`fk_${r.name}`), table: child.name, column: fk, refTable: parent.name, refColumn: pk.name, kind: "relationship", relationship: r.name });
|
|
@@ -13224,6 +13228,7 @@ function deriveLogical(src, o) {
|
|
|
13224
13228
|
}
|
|
13225
13229
|
delete r.foreign_key;
|
|
13226
13230
|
if (!child || !a) continue;
|
|
13231
|
+
if (a.required) r.required = true;
|
|
13227
13232
|
child.attributes = child.attributes.filter((x) => x !== a);
|
|
13228
13233
|
rep.droppedColumns.push(`${child.name}.${a.name} (foreign key \u2192 ${r.name})`);
|
|
13229
13234
|
}
|
|
@@ -13388,14 +13393,18 @@ function derivePhysical(src, o) {
|
|
|
13388
13393
|
child.attributes.push({ ...rest, name: uniqueName(ra.name, child.attributes.map((a) => a.name)), is_primary_key: false, is_label: false, description: ra.description || `${r.forward_label || r.name}: ${ra.label || ra.name}` });
|
|
13389
13394
|
}
|
|
13390
13395
|
if (r.attributes?.length) r.attributes = [];
|
|
13396
|
+
const required = r.required;
|
|
13397
|
+
delete r.required;
|
|
13391
13398
|
const existing = r.foreign_key && child.attributes.some((a) => a.name === r.foreign_key) ? r.foreign_key : inferForeignKey(m, r);
|
|
13392
13399
|
if (existing) {
|
|
13393
13400
|
r.foreign_key = existing;
|
|
13401
|
+
const column = child.attributes.find((a) => a.name === existing);
|
|
13402
|
+
if (required && column) column.required = true;
|
|
13394
13403
|
continue;
|
|
13395
13404
|
}
|
|
13396
13405
|
const name = uniqueName(ends.child === ends.parent ? `parent_${pk.name}` : keyColumnName(parent, pk), child.attributes.map((a) => a.name));
|
|
13397
13406
|
const at = child.attributes.findIndex((a) => !a.is_primary_key);
|
|
13398
|
-
const col = { name, label: toLabel(name), type: pk.type, description: `${parent.display_name} (${r.forward_label || r.name})` };
|
|
13407
|
+
const col = { name, label: toLabel(name), type: pk.type, ...required ? { required } : {}, description: `${parent.display_name} (${r.forward_label || r.name})` };
|
|
13399
13408
|
child.attributes.splice(at === -1 ? child.attributes.length : at, 0, col);
|
|
13400
13409
|
r.foreign_key = name;
|
|
13401
13410
|
fkAdded++;
|
|
@@ -14928,6 +14937,7 @@ function validateModel(m) {
|
|
|
14928
14937
|
for (const end of ["source", "target"])
|
|
14929
14938
|
if (!entityByName.has(r[end])) push("error", "rel.endpoint", `Relationship "${r.name}" ${end} entity "${r[end]}" does not exist.`, t);
|
|
14930
14939
|
if (!r.forward_label) push("warning", "rel.fwd", `Relationship "${r.name}" has no forward label.`, t);
|
|
14940
|
+
if (r.required && !relationshipEnds(r)) push("warning", "rel.reqnn", `Relationship "${r.name}" is N:N, so "required" is ignored (a junction table is used).`, t);
|
|
14931
14941
|
if (r.foreign_key) {
|
|
14932
14942
|
const ends = relationshipEnds(r);
|
|
14933
14943
|
if (!ends) push("warning", "rel.fknn", `Relationship "${r.name}" is N:N, so its foreign key "${r.foreign_key}" is ignored (a junction table is used).`, t);
|
|
@@ -16522,6 +16532,7 @@ function diffViews(A, B, dir, a = { id: "a", name: "Before" }, b = { id: "b", na
|
|
|
16522
16532
|
if (relKey(ra, "a") !== relKey(rb, "b")) d.push(`ends ${ra.source} \u2192 ${ra.target} became ${rb.source} \u2192 ${rb.target}`);
|
|
16523
16533
|
if (ra.cardinality !== rb.cardinality) d.push(`cardinality ${ra.cardinality} \u2192 ${rb.cardinality}`);
|
|
16524
16534
|
if ((ra.foreign_key || "") !== (rb.foreign_key || "")) d.push(`foreign key ${ra.foreign_key || "(none)"} \u2192 ${rb.foreign_key || "(none)"}`);
|
|
16535
|
+
if (!!ra.required !== !!rb.required) d.push(rb.required ? "optional \u2192 required" : "required \u2192 optional");
|
|
16525
16536
|
if (ra.forward_label !== rb.forward_label) d.push(`label "${ra.forward_label}" \u2192 "${rb.forward_label}"`);
|
|
16526
16537
|
const raAttrs = new Map((ra.attributes || []).map((x) => [x.name, x]));
|
|
16527
16538
|
const rbAttrs = new Map((rb.attributes || []).map((x) => [x.name, x]));
|
|
@@ -17076,8 +17087,8 @@ update_entity {entity, set:{display_name?, description?, entity_type?, color_cod
|
|
|
17076
17087
|
rename_entity {entity, to} delete_entity {entity}
|
|
17077
17088
|
add_attribute {entity, attribute:{name, type?, label?, description?, is_primary_key?, is_label?, required?, pii?, example?, is_array?, reference?:{entity, output_attribute}, struct_type?}, after?}
|
|
17078
17089
|
update_attribute {entity, attribute, set:{\u2026}} rename_attribute {entity, attribute, to} delete_attribute {entity, attribute} move_attribute {entity, attribute, after: name|null}
|
|
17079
|
-
add_relationship {relationship:{source, target, name?, cardinality?: "1:1"|"1:N"|"N:1"|"N:N", forward_label?, reverse_label?, bidirectional?, foreign_key?, description?, attributes?: Attribute[]}}
|
|
17080
|
-
update_relationship {relationship, set:{\u2026}} \u2014 set.attributes replaces the relationship's own attributes (facts about the link, e.g. an enrollment's grade; simple types only): junction-table columns for N:N, child-table columns otherwise rename_relationship {relationship, to} delete_relationship {relationship}
|
|
17090
|
+
add_relationship {relationship:{source, target, name?, cardinality?: "1:1"|"1:N"|"N:1"|"N:N", forward_label?, reverse_label?, bidirectional?, foreign_key?, required?, description?, attributes?: Attribute[]}}
|
|
17091
|
+
update_relationship {relationship, set:{\u2026}} \u2014 set.required: true means the child can't exist without the parent (NOT NULL foreign key); set.attributes replaces the relationship's own attributes (facts about the link, e.g. an enrollment's grade; simple types only): junction-table columns for N:N, child-table columns otherwise rename_relationship {relationship, to} delete_relationship {relationship}
|
|
17081
17092
|
set_reference_values {entity, values:[{attr: "value"}\u2026], source?}
|
|
17082
17093
|
add_note {text} set_hidden {entities:[\u2026], hidden} update_model {set:{title?, description?, organization?, version?, author?, status?}}
|
|
17083
17094
|
update_tab {tab, set:{name?, kind?, dialect?, description?}} make_primary {tab} delete_tab {tab}
|