fix(sdk): close boundary alias bypasses
This commit is contained in:
@@ -28,10 +28,11 @@ async function writeFixture(root, relativePath, source) {
|
||||
await writeFile(file, source, 'utf8');
|
||||
}
|
||||
|
||||
function scan(root) {
|
||||
function scan(root, tsconfigPath) {
|
||||
return scanImportBoundaries({
|
||||
frameworkDir: join(root, 'framework'),
|
||||
gamesDir: join(root, 'games'),
|
||||
tsconfigPath: tsconfigPath ? join(root, tsconfigPath) : undefined,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -217,6 +218,84 @@ test('scanner rejects every sdk runtime dependency on framework implementation l
|
||||
}
|
||||
});
|
||||
|
||||
test('scanner resolves and rejects an sdk runtime path alias into framework implementation', async () => {
|
||||
const root = await createFixtureRoot();
|
||||
await writeFixture(root, 'framework/core/internal.ts', 'export const value = true\n');
|
||||
await writeFixture(
|
||||
root,
|
||||
'framework/sdk/runtime/bad.ts',
|
||||
"import { value } from '@framework/core/internal'; void value\n",
|
||||
);
|
||||
await writeFixture(root, 'tsconfig.json', JSON.stringify({
|
||||
compilerOptions: {
|
||||
baseUrl: '.',
|
||||
paths: { '@framework/*': ['framework/*'] },
|
||||
module: 'ESNext',
|
||||
moduleResolution: 'Bundler',
|
||||
allowImportingTsExtensions: true,
|
||||
},
|
||||
}));
|
||||
|
||||
const violations = scan(root, 'tsconfig.json');
|
||||
assert.equal(violations.length, 1);
|
||||
assert.equal(violations[0].specifier, '@framework/core/internal');
|
||||
assert.match(violations[0].message, /sdk.*framework implementation.*framework\/core/);
|
||||
});
|
||||
|
||||
test('scanner rejects Cocos imports throughout sdk runtime', async () => {
|
||||
for (const specifier of ['cc', 'cc/env']) {
|
||||
const root = await createFixtureRoot();
|
||||
await writeFixture(
|
||||
root,
|
||||
'framework/sdk/runtime/bad.ts',
|
||||
`import { Node } from '${specifier}'; void Node\n`,
|
||||
);
|
||||
|
||||
const violations = scan(root);
|
||||
assert.equal(violations.length, 1, specifier);
|
||||
assert.equal(violations[0].specifier, specifier);
|
||||
assert.match(violations[0].message, /sdk.*Cocos/);
|
||||
}
|
||||
});
|
||||
|
||||
test('sdk migration barrel exception permits only its four retained legacy dependencies', async () => {
|
||||
const root = await createFixtureRoot();
|
||||
for (const file of [
|
||||
'framework/core/events.ts',
|
||||
'framework/core/reactive.ts',
|
||||
'framework/platform/readonly.ts',
|
||||
'framework/platform/stores/types.ts',
|
||||
'framework/core/constants.ts',
|
||||
]) {
|
||||
await writeFixture(root, file, 'export interface Value {}\n');
|
||||
}
|
||||
await writeFixture(root, 'framework/sdk/index.ts', [
|
||||
"import type { Value as Events } from '../core/events.ts'; void (0 as unknown as Events);",
|
||||
"import type { Value as Reactive } from '../core/reactive.ts'; void (0 as unknown as Reactive);",
|
||||
"import type { Value as ReadonlyStore } from '../platform/readonly.ts'; void (0 as unknown as ReadonlyStore);",
|
||||
"import type { Value as StoreTypes } from '../platform/stores/types.ts'; void (0 as unknown as StoreTypes);",
|
||||
"import type { Value as Constants } from '../core/constants.ts'; void (0 as unknown as Constants);",
|
||||
].join('\n'));
|
||||
|
||||
const violations = scan(root);
|
||||
assert.equal(violations.length, 1);
|
||||
assert.equal(violations[0].specifier, '../core/constants.ts');
|
||||
assert.match(violations[0].message, /sdk.*framework implementation/);
|
||||
});
|
||||
|
||||
test('scanner permits sdk-internal relatives and ordinary external pure dependencies', async () => {
|
||||
const root = await createFixtureRoot();
|
||||
await writeFixture(root, 'framework/sdk/contracts/index.ts', 'export interface Contract {}\n');
|
||||
await writeFixture(root, 'framework/sdk/runtime/helper.ts', 'export const helper = true\n');
|
||||
await writeFixture(root, 'framework/sdk/runtime/allowed.ts', [
|
||||
"import type { Contract } from '../contracts/index.ts'; void (0 as unknown as Contract);",
|
||||
"import { helper } from './helper.ts'; void helper;",
|
||||
"import type { PureValue } from 'pure-external'; void (0 as unknown as PureValue);",
|
||||
].join('\n'));
|
||||
|
||||
assert.deepEqual(scan(root), []);
|
||||
});
|
||||
|
||||
test('scanner rejects game imports of framework net internals', async () => {
|
||||
const root = await createFixtureRoot();
|
||||
await writeFixture(root, 'games/a/assets/game/bad.ts', "import '../../../framework/net/net-client.ts'\n");
|
||||
|
||||
Reference in New Issue
Block a user