fix(sdk): harden import boundary scanner
This commit is contained in:
@@ -42,6 +42,22 @@ test('scanner rejects game imports of framework net internals', async () => {
|
||||
assert.match(scan(root)[0].message, /game.*framework\/net/);
|
||||
});
|
||||
|
||||
test('scanner rejects multiline game imports of framework net internals', async () => {
|
||||
const root = await createFixtureRoot();
|
||||
await writeFixture(root, 'games/a/assets/game/bad.ts', "import {\n NetClient,\n} from '../../../../framework/net/net-client.ts'\n");
|
||||
const violations = scan(root);
|
||||
assert.equal(violations.length, 1);
|
||||
assert.match(violations[0].message, /game.*framework\/net/);
|
||||
});
|
||||
|
||||
test('scanner rejects multiline sdk contract imports outside their sibling directory', async () => {
|
||||
const root = await createFixtureRoot();
|
||||
await writeFixture(root, 'framework/sdk/contracts/bad.ts', "import {\n PlatformSession,\n} from '../../platform/session.ts'\n");
|
||||
const violations = scan(root);
|
||||
assert.equal(violations.length, 1);
|
||||
assert.match(violations[0].message, /sdk\/contracts.*sibling contracts/);
|
||||
});
|
||||
|
||||
test('scanner permits a game import of the public sdk barrel', async () => {
|
||||
const root = await createFixtureRoot();
|
||||
await writeFixture(root, 'games/a/assets/game/allowed.ts', "import '../../../../framework/sdk/index.ts'\n");
|
||||
@@ -60,6 +76,38 @@ test('scanner rejects cc imports in sdk contracts', async () => {
|
||||
assert.match(scan(root)[0].message, /sdk\/contracts.*cc/);
|
||||
});
|
||||
|
||||
test('scanner rejects non-relative imports in sdk contracts', async () => {
|
||||
const root = await createFixtureRoot();
|
||||
await writeFixture(root, 'framework/sdk/contracts/bad.ts', "import 'node:fs'\n");
|
||||
const violations = scan(root);
|
||||
assert.equal(violations.length, 1);
|
||||
assert.match(violations[0].message, /sdk\/contracts.*non-relative/);
|
||||
});
|
||||
|
||||
test('scanner rejects import-type leaks from sdk contracts', async () => {
|
||||
const root = await createFixtureRoot();
|
||||
await writeFixture(root, 'framework/sdk/contracts/bad.ts', "type ReadonlyRoom = import('../../platform/readonly.ts').ReadonlyRoomStore\n");
|
||||
const violations = scan(root);
|
||||
assert.equal(violations.length, 1);
|
||||
assert.match(violations[0].message, /sdk\/contracts.*sibling contracts/);
|
||||
});
|
||||
|
||||
test('scanner rejects export-star leaks from sdk contracts', async () => {
|
||||
const root = await createFixtureRoot();
|
||||
await writeFixture(root, 'framework/sdk/contracts/index.ts', "export * from '../../platform/readonly.ts'\n");
|
||||
const violations = scan(root);
|
||||
assert.equal(violations.length, 1);
|
||||
assert.match(violations[0].message, /sdk\/contracts.*sibling contracts/);
|
||||
});
|
||||
|
||||
test('scanner rejects named re-export leaks from sdk contracts', async () => {
|
||||
const root = await createFixtureRoot();
|
||||
await writeFixture(root, 'framework/sdk/contracts/index.ts', "export { ReadonlyRoomStore } from '../../platform/readonly.ts'\n");
|
||||
const violations = scan(root);
|
||||
assert.equal(violations.length, 1);
|
||||
assert.match(violations[0].message, /sdk\/contracts.*sibling contracts/);
|
||||
});
|
||||
|
||||
test('scanner permits cc imports in game code', async () => {
|
||||
const root = await createFixtureRoot();
|
||||
await writeFixture(root, 'games/a/assets/game/allowed.ts', "import { Node } from 'cc'\n");
|
||||
@@ -72,6 +120,22 @@ test('scanner rejects framework imports resolving under games', async () => {
|
||||
assert.match(scan(root)[0].message, /framework.*games/);
|
||||
});
|
||||
|
||||
test('scanner rejects framework production imports of migration-only sdk declarations', async () => {
|
||||
const root = await createFixtureRoot();
|
||||
await writeFixture(root, 'framework/application/bad.ts', "import type { GameContext } from '../sdk/index.ts'\n");
|
||||
const violations = scan(root);
|
||||
assert.equal(violations.length, 1);
|
||||
assert.match(violations[0].message, /GameContext.*migration-only/);
|
||||
});
|
||||
|
||||
test('scanner rejects alias imports of migration-only sdk declarations', async () => {
|
||||
const root = await createFixtureRoot();
|
||||
await writeFixture(root, 'framework/application/bad.ts', "import type { IGameModule } from '@internal/sdk'\n");
|
||||
const violations = scan(root);
|
||||
assert.equal(violations.length, 1);
|
||||
assert.match(violations[0].message, /IGameModule.*migration-only/);
|
||||
});
|
||||
|
||||
test('scanner rejects new production imports of a quarantined legacy runtime', async () => {
|
||||
const root = await createFixtureRoot();
|
||||
await writeFixture(root, 'framework/application/bad.ts', "import '../net/net-client.ts'\n");
|
||||
|
||||
Reference in New Issue
Block a user