feat(core-eslint): rule no-direct-socket-io
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -4,6 +4,7 @@ import tseslint from "typescript-eslint";
|
||||
import turboPlugin from "eslint-plugin-turbo";
|
||||
import boundaries from "eslint-plugin-boundaries";
|
||||
import globals from "globals";
|
||||
import noDirectSocketIO from "./rules/no-direct-socket-io.js";
|
||||
|
||||
export default [
|
||||
{ ignores: ["dist/**", "node_modules/**", ".next/**", ".turbo/**", "storybook-static/**"] },
|
||||
@@ -169,4 +170,13 @@ export default [
|
||||
],
|
||||
},
|
||||
},
|
||||
// R2 — `socket.io` and `socket.io-client` must not be imported outside
|
||||
// core-realtime/src/ and apps/*/server.ts. Use @repo/core-realtime helpers.
|
||||
{
|
||||
files: ["**/*.{ts,tsx,mjs,cjs,js}"],
|
||||
plugins: { "repo-rules": { rules: { "no-direct-socket-io": noDirectSocketIO } } },
|
||||
rules: {
|
||||
"repo-rules/no-direct-socket-io": "error",
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
33
packages/core-eslint/rules/no-direct-socket-io.js
Normal file
33
packages/core-eslint/rules/no-direct-socket-io.js
Normal file
@@ -0,0 +1,33 @@
|
||||
// packages/core-eslint/rules/no-direct-socket-io.js
|
||||
const ALLOWED = [
|
||||
/\/packages\/core-realtime\/src\//,
|
||||
/\/apps\/[^/]+\/server\.ts$/,
|
||||
];
|
||||
|
||||
export default {
|
||||
meta: {
|
||||
type: "problem",
|
||||
docs: { description: "Block direct socket.io imports outside core-realtime + app servers" },
|
||||
messages: {
|
||||
noDirectSocketIO: 'Import from "@repo/core-realtime" instead of "socket.io". Direct imports allowed only in packages/core-realtime/src/ and apps/*/server.ts.',
|
||||
noDirectSocketIOClient: 'Use the realtime helpers from "@repo/core-realtime" / "@repo/core-testing/instrumentation" instead of "socket.io-client".',
|
||||
},
|
||||
schema: [],
|
||||
},
|
||||
create(context) {
|
||||
const filename = context.filename ?? context.getFilename();
|
||||
const allowed = ALLOWED.some((re) => re.test(filename));
|
||||
if (allowed) return {};
|
||||
|
||||
return {
|
||||
ImportDeclaration(node) {
|
||||
const source = node.source.value;
|
||||
if (source === "socket.io") {
|
||||
context.report({ node, messageId: "noDirectSocketIO" });
|
||||
} else if (source === "socket.io-client") {
|
||||
context.report({ node, messageId: "noDirectSocketIOClient" });
|
||||
}
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
30
packages/core-eslint/rules/no-direct-socket-io.test.js
Normal file
30
packages/core-eslint/rules/no-direct-socket-io.test.js
Normal file
@@ -0,0 +1,30 @@
|
||||
// packages/core-eslint/rules/no-direct-socket-io.test.js
|
||||
import { RuleTester } from "eslint";
|
||||
import rule from "./no-direct-socket-io.js";
|
||||
|
||||
const tester = new RuleTester({
|
||||
languageOptions: { ecmaVersion: 2022, sourceType: "module" },
|
||||
});
|
||||
|
||||
tester.run("no-direct-socket-io", rule, {
|
||||
valid: [
|
||||
// Allowed inside core-realtime
|
||||
{ code: 'import { Server } from "socket.io";', filename: "/repo/packages/core-realtime/src/socket-io-realtime-server.ts" },
|
||||
// Allowed in app servers
|
||||
{ code: 'import { Server } from "socket.io";', filename: "/repo/apps/web-next/server.ts" },
|
||||
// Allowed elsewhere when not importing socket.io
|
||||
{ code: 'import { foo } from "bar";', filename: "/repo/packages/blog/src/foo.ts" },
|
||||
],
|
||||
invalid: [
|
||||
{
|
||||
code: 'import { Server } from "socket.io";',
|
||||
filename: "/repo/packages/blog/src/foo.ts",
|
||||
errors: [{ messageId: "noDirectSocketIO" }],
|
||||
},
|
||||
{
|
||||
code: 'import { io } from "socket.io-client";',
|
||||
filename: "/repo/packages/blog/src/ui/Component.tsx",
|
||||
errors: [{ messageId: "noDirectSocketIOClient" }],
|
||||
},
|
||||
],
|
||||
});
|
||||
@@ -4,6 +4,6 @@ export default defineConfig({
|
||||
test: {
|
||||
globals: true,
|
||||
environment: "node",
|
||||
include: ["*.test.js"],
|
||||
include: ["*.test.js", "rules/*.test.js"],
|
||||
},
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user