@intentius/chant 0.12.0 → 0.12.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/dist/graph-ir.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/graph-ir.test.ts +24 -0
- package/src/graph-ir.ts +7 -2
package/dist/graph-ir.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"graph-ir.d.ts","sourceRoot":"","sources":["../src/graph-ir.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"graph-ir.d.ts","sourceRoot":"","sources":["../src/graph-ir.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,UAAU,EAAgB,MAAM,cAAc,CAAC;AAK7D;;;;;;;;GAQG;AAEH,iFAAiF;AACjF,MAAM,WAAW,SAAS;IACxB,8EAA8E;IAC9E,IAAI,EAAE,MAAM,CAAC;IACb;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,wEAAwE;AACxE,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;CACd;AAED,iCAAiC;AACjC,MAAM,WAAW,MAAM;IACrB,kEAAkE;IAClE,EAAE,EAAE,MAAM,CAAC;IACX,wCAAwC;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,mDAAmD;IACnD,OAAO,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;OAGG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,yEAAyE;IACzE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,mCAAmC;IACnC,SAAS,CAAC,EAAE,SAAS,CAAC;CACvB;AAED,qEAAqE;AACrE,MAAM,WAAW,MAAM;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,yCAAyC;IACzC,IAAI,EAAE,KAAK,CAAC;IACZ,8EAA8E;IAC9E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,8EAA8E;IAC9E,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,qFAAqF;AACrF,MAAM,WAAW,QAAQ;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACrC,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACvC,0CAA0C;IAC1C,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;CACpC;AAED,gFAAgF;AAChF,MAAM,WAAW,OAAO;IACtB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,MAAM,EAAE,QAAQ,CAAC;CAClB;AA6ID;;;;GAIG;AACH,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,EACjC,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAmDT"}
|
package/package.json
CHANGED
package/src/graph-ir.test.ts
CHANGED
|
@@ -42,6 +42,30 @@ describe("buildGraphIr", () => {
|
|
|
42
42
|
});
|
|
43
43
|
});
|
|
44
44
|
|
|
45
|
+
test("treats a foreign AttrRef (different @intentius/chant copy) as a ref, not an opaque intrinsic (#511)", () => {
|
|
46
|
+
// A lexicon built against a *separate* copy of chant produces AttrRefs that
|
|
47
|
+
// fail `instanceof AttrRef` here but carry the global-symbol brand + shape.
|
|
48
|
+
// (This is the pinhole install scenario; before #511 it flattened to
|
|
49
|
+
// `{$intrinsic}` with no edge.)
|
|
50
|
+
const vpc = decl({ lexicon: "aws", entityType: "Vpc" });
|
|
51
|
+
const foreignRef = {
|
|
52
|
+
[Symbol.for("chant.intrinsic")]: true,
|
|
53
|
+
parent: new WeakRef(vpc),
|
|
54
|
+
attribute: "VpcId",
|
|
55
|
+
_setLogicalName() {}, // shape utils.isAttrRefLike duck-types on
|
|
56
|
+
getLogicalName: () => undefined, // resolves via object identity in the reverse map
|
|
57
|
+
};
|
|
58
|
+
const sg = decl({ lexicon: "aws", entityType: "SecurityGroup", props: { VpcId: foreignRef } });
|
|
59
|
+
const entities = new Map<string, Declarable>([
|
|
60
|
+
["vpc", vpc],
|
|
61
|
+
["sg", sg],
|
|
62
|
+
]);
|
|
63
|
+
|
|
64
|
+
const ir = buildGraphIr(entities);
|
|
65
|
+
expect(ir.edges).toEqual([{ from: "sg", to: "vpc", kind: "ref", viaAttr: "VpcId" }]);
|
|
66
|
+
expect(ir.nodes.find((n) => n.id === "sg")!.attrs).toEqual({ VpcId: { $ref: "vpc.VpcId" } });
|
|
67
|
+
});
|
|
68
|
+
|
|
45
69
|
test("excludes property-kind declarables and keeps resources", () => {
|
|
46
70
|
const resource = decl({ lexicon: "k8s", entityType: "Deployment" });
|
|
47
71
|
const prop = decl({ lexicon: "k8s", entityType: "Probe", kind: "property" as const });
|
package/src/graph-ir.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { relative, isAbsolute } from "node:path";
|
|
2
2
|
import { AttrRef } from "./attrref";
|
|
3
|
+
import { isAttrRefLike } from "./utils";
|
|
3
4
|
import { type Declarable, isDeclarable } from "./declarable";
|
|
4
5
|
import { isLexiconOutput } from "./lexicon-output";
|
|
5
6
|
import { getProvenance } from "./provenance";
|
|
@@ -113,7 +114,11 @@ function project(value: unknown, seen: Set<unknown>, reverse: Map<object, string
|
|
|
113
114
|
if (t === "string" || t === "number" || t === "boolean") return value;
|
|
114
115
|
if (t !== "object") return undefined; // functions, symbols, undefined
|
|
115
116
|
|
|
116
|
-
|
|
117
|
+
// Duck-type, not `instanceof`: a lexicon built against a different copy of
|
|
118
|
+
// `@intentius/chant` produces AttrRefs that fail `instanceof AttrRef` but carry
|
|
119
|
+
// the same shape. Without this, a real cross-resource reference falls through to
|
|
120
|
+
// the intrinsic branch below and is silently flattened to `{$intrinsic}` (#511).
|
|
121
|
+
if (isAttrRefLike(value)) {
|
|
117
122
|
const to = refTarget(value, reverse);
|
|
118
123
|
return { $ref: to ? `${to}.${value.attribute}` : value.attribute } satisfies AttrRefEnvelope;
|
|
119
124
|
}
|
|
@@ -192,7 +197,7 @@ function collectEdges(
|
|
|
192
197
|
const seen = new Set<unknown>();
|
|
193
198
|
const visit = (value: unknown, viaAttr: string): void => {
|
|
194
199
|
if (value === null || typeof value !== "object") return;
|
|
195
|
-
if (value
|
|
200
|
+
if (isAttrRefLike(value)) {
|
|
196
201
|
const to = refTarget(value, reverse);
|
|
197
202
|
if (to && to !== from && nodeIds.has(to)) {
|
|
198
203
|
edges.push({ from, to, kind: "ref", viaAttr });
|