Skip to content

Commit 42e59df

Browse files
committed
test(ci): cover cyclic script declaration barrels
1 parent bb5181b commit 42e59df

2 files changed

Lines changed: 23 additions & 0 deletions

File tree

scripts/check-script-declarations.mjs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,8 @@ function collectValueExports(filePath, fsImpl, state) {
352352
return cached;
353353
}
354354
if (state.visiting.has(normalizedFilePath)) {
355+
// Full cyclic star resolution requires a fixed point. Fail closed instead of
356+
// caching a partial map; script barrels can break the cycle with explicit exports.
355357
return {
356358
ambiguous: new Set(),
357359
exports: new Map(),

test/scripts/check-script-declarations.test.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,27 @@ describe("script declaration contracts", () => {
172172
).toEqual({ checked: 1, issues: [] });
173173
});
174174

175+
it("fails closed on cyclic star graphs", () => {
176+
const root = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-script-declarations-"));
177+
tempDirs.push(root);
178+
fs.mkdirSync(path.join(root, "scripts"), { recursive: true });
179+
fs.writeFileSync(path.join(root, "scripts", "a.mjs"), 'export * from "./b.mjs";\n');
180+
fs.writeFileSync(
181+
path.join(root, "scripts", "b.mjs"),
182+
'export const value = 1;\nexport * from "./a.mjs";\n',
183+
);
184+
fs.writeFileSync(path.join(root, "scripts", "a.d.mts"), "export const value: 1;\n");
185+
fs.writeFileSync(path.join(root, "scripts", "b.d.mts"), "export const value: 1;\n");
186+
187+
const result = verifyScriptDeclarationContracts({
188+
root,
189+
files: ["scripts/a.d.mts", "scripts/a.mjs", "scripts/b.d.mts", "scripts/b.mjs"],
190+
});
191+
expect(result.checked).toBe(2);
192+
expect(result.issues).toHaveLength(2);
193+
expect(result.issues.every((issue) => issue.includes("cyclic star re-export"))).toBe(true);
194+
});
195+
175196
it("fails closed on explicit re-exports of ambiguous bindings", () => {
176197
const root = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-script-declarations-"));
177198
tempDirs.push(root);

0 commit comments

Comments
 (0)