@unified-product-graph/core 0.10.0 → 0.10.2
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/dist/index.cjs +57 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +27 -2
- package/dist/index.d.ts +27 -2
- package/dist/index.js +57 -3
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1353,6 +1353,10 @@ var UPG_EDGE_CATALOG = {
|
|
|
1353
1353
|
// would be a separate catalog-mechanic change).
|
|
1354
1354
|
competitive_analysis_dimensioned_by_classification_axis: { forward_verb: "dimensioned_by", reverse_verb: "dimensions", classification: "hierarchy", source_type: "competitive_analysis", target_type: "classification_axis" },
|
|
1355
1355
|
classification_axis_includes_classification_value: { forward_verb: "includes", reverse_verb: "value_of", classification: "hierarchy", source_type: "classification_axis", target_type: "classification_value" },
|
|
1356
|
+
// 0.10.2: also dual-registered as a cross-edge (UPG_CROSS_EDGE_TYPES) so a
|
|
1357
|
+
// competitor can be classified directly against a `registry/{classification_value}`
|
|
1358
|
+
// canonical, eliminating the per-graph taxonomy node. Within-graph (the catalogue
|
|
1359
|
+
// case) here; cross-product against the registry canonical via create_cross_product_edge.
|
|
1356
1360
|
competitor_classified_as_classification_value: { forward_verb: "classified_as", reverse_verb: "classification_of", classification: "semantic", source_type: "competitor", target_type: "classification_value" },
|
|
1357
1361
|
persona_anti_fit_for_classification_value: { forward_verb: "is_anti_fit_for", reverse_verb: "should_not_be_picked_by", classification: "semantic", source_type: "persona", target_type: "classification_value" },
|
|
1358
1362
|
persona_anti_fit_for_product: { forward_verb: "is_anti_fit_for", reverse_verb: "should_not_be_picked_by", classification: "semantic", source_type: "persona", target_type: "product" },
|
|
@@ -3248,7 +3252,8 @@ var UPG_CROSS_EDGE_TYPES = [
|
|
|
3248
3252
|
"primitive_stored_as_data_type",
|
|
3249
3253
|
"feature_rivals_competitor_feature",
|
|
3250
3254
|
"competitor_signal_maps_to_feature",
|
|
3251
|
-
"competitor_signal_surfaces_opportunity"
|
|
3255
|
+
"competitor_signal_surfaces_opportunity",
|
|
3256
|
+
"competitor_classified_as_classification_value"
|
|
3252
3257
|
];
|
|
3253
3258
|
var REGISTRY_PRODUCT_ID = "registry";
|
|
3254
3259
|
|
|
@@ -7458,6 +7463,34 @@ function getDeprecatedTypes() {
|
|
|
7458
7463
|
return deprecated;
|
|
7459
7464
|
}
|
|
7460
7465
|
var UPG_PROPERTY_MIGRATIONS = {
|
|
7466
|
+
// ── v0.10.2: market_intelligence number -> assessment reshape ──────────────
|
|
7467
|
+
//
|
|
7468
|
+
// The v0.10.0 property-registry generator fix (#43) corrected several property
|
|
7469
|
+
// types that interfaces already declared as `UPGAssessment` but the generator
|
|
7470
|
+
// had emitted loosely. A pre-0.10.0 graph that stored a bare number for
|
|
7471
|
+
// `market_trend.impact` / `relevance` is now invalid (the schema wants
|
|
7472
|
+
// `{value,label}`). These rules wrap the bare number on its canonical scale so
|
|
7473
|
+
// the migration is one command, not a hand-reshape. The enum tightenings the
|
|
7474
|
+
// same #43 fix surfaced (data_flow.direction, integration_pattern.pattern_type,
|
|
7475
|
+
// api_contract.protocol, service.service_type) already have rules under 0.9.12;
|
|
7476
|
+
// 0.10.2 also makes ALL of them visible to validate_graph (they were applied by
|
|
7477
|
+
// migrate_properties but never surfaced as a fixable drift).
|
|
7478
|
+
"0.10.2": [
|
|
7479
|
+
{
|
|
7480
|
+
kind: "reshape_value_to_assessment",
|
|
7481
|
+
type: "market_trend",
|
|
7482
|
+
property: "impact",
|
|
7483
|
+
scale_id: "impact_5",
|
|
7484
|
+
reason: "market_trend.impact is a UPGAssessment (impact_5); the 0.10.0 generator fix (#43) tightened it from a bare number. A legacy numeric value wraps to {value,label} on impact_5."
|
|
7485
|
+
},
|
|
7486
|
+
{
|
|
7487
|
+
kind: "reshape_value_to_assessment",
|
|
7488
|
+
type: "market_trend",
|
|
7489
|
+
property: "relevance",
|
|
7490
|
+
scale_id: "importance_5",
|
|
7491
|
+
reason: "market_trend.relevance is a UPGAssessment (importance_5); the 0.10.0 generator fix (#43) tightened it from a bare number. A legacy numeric value wraps to {value,label} on importance_5."
|
|
7492
|
+
}
|
|
7493
|
+
],
|
|
7461
7494
|
// ── v0.9.14: drop the key_result kr_status / status twin (A2) ──────────────
|
|
7462
7495
|
//
|
|
7463
7496
|
// key_result carried BOTH a lifecycle `status` and a `kr_status` property with
|
|
@@ -8030,6 +8063,26 @@ function migrateNodeProperties(node, fromVersion, toVersion) {
|
|
|
8030
8063
|
mutated = true;
|
|
8031
8064
|
break;
|
|
8032
8065
|
}
|
|
8066
|
+
case "reshape_value_to_assessment": {
|
|
8067
|
+
const props = workingNode.properties;
|
|
8068
|
+
if (!props || !(m.property in props)) break;
|
|
8069
|
+
const oldValue = props[m.property];
|
|
8070
|
+
let num = null;
|
|
8071
|
+
if (typeof oldValue === "number" && Number.isFinite(oldValue)) num = oldValue;
|
|
8072
|
+
else if (typeof oldValue === "string" && oldValue.trim() !== "" && Number.isFinite(Number(oldValue))) {
|
|
8073
|
+
num = Number(oldValue);
|
|
8074
|
+
}
|
|
8075
|
+
if (num === null) break;
|
|
8076
|
+
const label = getScale(m.scale_id)?.points.find((p) => p.value === num)?.label ?? String(num);
|
|
8077
|
+
const nextProps = {
|
|
8078
|
+
...props,
|
|
8079
|
+
[m.property]: { value: num, label, scale_id: m.scale_id }
|
|
8080
|
+
};
|
|
8081
|
+
workingNode.properties = nextProps;
|
|
8082
|
+
mutated = true;
|
|
8083
|
+
changes.push({ kind: "reshaped_to_assessment", property: m.property, scale_id: m.scale_id, value: num, label });
|
|
8084
|
+
break;
|
|
8085
|
+
}
|
|
8033
8086
|
}
|
|
8034
8087
|
}
|
|
8035
8088
|
}
|
|
@@ -18250,6 +18303,7 @@ for (const fw of UPG_FRAMEWORKS) {
|
|
|
18250
18303
|
|
|
18251
18304
|
// src/grammar/validate.ts
|
|
18252
18305
|
var crossProductEdgeTypeSet = new Set(UPG_CROSS_EDGE_TYPES);
|
|
18306
|
+
var withinProductEdgeTypeSet = new Set(Object.keys(UPG_EDGE_CATALOG));
|
|
18253
18307
|
var CONTENT_DEPTH_WARNING_RULES = /* @__PURE__ */ new Set([
|
|
18254
18308
|
"property-type",
|
|
18255
18309
|
"property-enum",
|
|
@@ -18352,7 +18406,7 @@ function validateUPGDocument(doc) {
|
|
|
18352
18406
|
if (!e.id || typeof e.id !== "string") {
|
|
18353
18407
|
errors.push({ path: `${path}.id`, message: "Edge id is required and must be a string" });
|
|
18354
18408
|
}
|
|
18355
|
-
if (typeof e.type === "string" && crossProductEdgeTypeSet.has(e.type)) {
|
|
18409
|
+
if (typeof e.type === "string" && crossProductEdgeTypeSet.has(e.type) && !withinProductEdgeTypeSet.has(e.type)) {
|
|
18356
18410
|
errors.push({
|
|
18357
18411
|
path: `${path}.type`,
|
|
18358
18412
|
message: `Cross-product edge type "${e.type}" must live in portfolio.cross_edges[], not product edges[].`
|
|
@@ -28583,7 +28637,7 @@ function isCanonical(text) {
|
|
|
28583
28637
|
}
|
|
28584
28638
|
|
|
28585
28639
|
// src/index.ts
|
|
28586
|
-
var UPG_VERSION = "0.10.
|
|
28640
|
+
var UPG_VERSION = "0.10.2";
|
|
28587
28641
|
var UPG_FORMAT_VERSION = "0.4.0";
|
|
28588
28642
|
var MARKDOWN_FORMAT_VERSION = "0.1";
|
|
28589
28643
|
var UPG_TYPES = getTypes();
|