From b15d496f8f840fdc8bc890b1f88117fb1b0dccb0 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Thu, 23 Jul 2026 11:17:49 +0000 Subject: [PATCH] =?UTF-8?q?fix(ci):=20=E6=B8=85=E7=90=86=20land/economy=20?= =?UTF-8?q?lock=20=E6=AE=8B=E7=95=99=EF=BC=8Ceslint-plugin=20dist=20?= =?UTF-8?q?=E5=AF=B9=E9=BD=90=20SDK=20=E6=9E=84=E5=BB=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - package-lock 删除已移除的 packages/land 与旁路 economy 条目(DRY) - gitignore @sfmc-eslint-plugin/dist,与 @sfmc-sdk 一致,避免再提交残缺产物 - RuleTester 样板抽到 createRuleTester(DRY) - lint 脚本先 build eslint-plugin,保证 flat config 可解析 Co-authored-by: Shiroha --- .gitignore | 2 + .../dist/configs/recommended.d.ts | 28 ----------- .../dist/configs/recommended.js | 39 --------------- .../sdk/@sfmc-eslint-plugin/dist/index.d.ts | 9 ---- modules/sdk/@sfmc-eslint-plugin/dist/index.js | 18 ------- .../dist/rules/no-player-send-message.d.ts | 6 --- .../dist/rules/no-player-send-message.js | 30 ------------ .../rules/no-player-send-message.test.d.ts | 1 - .../dist/rules/no-player-send-message.test.js | 31 ------------ .../dist/rules/no-sdk-deep-import.d.ts | 6 --- .../dist/rules/no-sdk-deep-import.js | 38 --------------- .../dist/rules/no-sdk-deep-import.test.d.ts | 1 - .../dist/rules/no-sdk-deep-import.test.js | 31 ------------ .../dist/rules/no-sfmc-sdk-alias.d.ts | 6 --- .../dist/rules/no-sfmc-sdk-alias.js | 33 ------------- .../dist/rules/no-sfmc-sdk-alias.test.d.ts | 1 - .../dist/rules/no-sfmc-sdk-alias.test.js | 31 ------------ .../dist/rules/require-module-registry.d.ts | 6 --- .../dist/rules/require-module-registry.js | 47 ------------------- .../rules/require-module-registry.test.d.ts | 1 - .../rules/require-module-registry.test.js | 38 --------------- .../dist/utils/create-rule.d.ts | 4 -- .../dist/utils/create-rule.js | 2 - .../src/rules/no-player-send-message.test.ts | 19 +------- .../src/rules/no-sdk-deep-import.test.ts | 19 +------- .../src/rules/no-sfmc-sdk-alias.test.ts | 19 +------- .../src/rules/require-module-registry.test.ts | 19 +------- .../src/utils/rule-tester.ts | 19 ++++++++ package-lock.json | 17 ------- package.json | 2 +- 30 files changed, 30 insertions(+), 493 deletions(-) delete mode 100644 modules/sdk/@sfmc-eslint-plugin/dist/configs/recommended.d.ts delete mode 100644 modules/sdk/@sfmc-eslint-plugin/dist/configs/recommended.js delete mode 100644 modules/sdk/@sfmc-eslint-plugin/dist/index.d.ts delete mode 100644 modules/sdk/@sfmc-eslint-plugin/dist/index.js delete mode 100644 modules/sdk/@sfmc-eslint-plugin/dist/rules/no-player-send-message.d.ts delete mode 100644 modules/sdk/@sfmc-eslint-plugin/dist/rules/no-player-send-message.js delete mode 100644 modules/sdk/@sfmc-eslint-plugin/dist/rules/no-player-send-message.test.d.ts delete mode 100644 modules/sdk/@sfmc-eslint-plugin/dist/rules/no-player-send-message.test.js delete mode 100644 modules/sdk/@sfmc-eslint-plugin/dist/rules/no-sdk-deep-import.d.ts delete mode 100644 modules/sdk/@sfmc-eslint-plugin/dist/rules/no-sdk-deep-import.js delete mode 100644 modules/sdk/@sfmc-eslint-plugin/dist/rules/no-sdk-deep-import.test.d.ts delete mode 100644 modules/sdk/@sfmc-eslint-plugin/dist/rules/no-sdk-deep-import.test.js delete mode 100644 modules/sdk/@sfmc-eslint-plugin/dist/rules/no-sfmc-sdk-alias.d.ts delete mode 100644 modules/sdk/@sfmc-eslint-plugin/dist/rules/no-sfmc-sdk-alias.js delete mode 100644 modules/sdk/@sfmc-eslint-plugin/dist/rules/no-sfmc-sdk-alias.test.d.ts delete mode 100644 modules/sdk/@sfmc-eslint-plugin/dist/rules/no-sfmc-sdk-alias.test.js delete mode 100644 modules/sdk/@sfmc-eslint-plugin/dist/rules/require-module-registry.d.ts delete mode 100644 modules/sdk/@sfmc-eslint-plugin/dist/rules/require-module-registry.js delete mode 100644 modules/sdk/@sfmc-eslint-plugin/dist/rules/require-module-registry.test.d.ts delete mode 100644 modules/sdk/@sfmc-eslint-plugin/dist/rules/require-module-registry.test.js delete mode 100644 modules/sdk/@sfmc-eslint-plugin/dist/utils/create-rule.d.ts delete mode 100644 modules/sdk/@sfmc-eslint-plugin/dist/utils/create-rule.js create mode 100644 modules/sdk/@sfmc-eslint-plugin/src/utils/rule-tester.ts diff --git a/.gitignore b/.gitignore index 7bc1b1af..7569b962 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,8 @@ qq-bridge/dist/ sfmc/dist/ modules/sdk/@sfmc-sdk/dist/ modules/sdk/@sfmc-sdk/node_modules/ +modules/sdk/@sfmc-eslint-plugin/dist/ +modules/sdk/@sfmc-eslint-plugin/node_modules/ shared/**/dist/ shared/**/node_modules/ diff --git a/modules/sdk/@sfmc-eslint-plugin/dist/configs/recommended.d.ts b/modules/sdk/@sfmc-eslint-plugin/dist/configs/recommended.d.ts deleted file mode 100644 index a7b1e557..00000000 --- a/modules/sdk/@sfmc-eslint-plugin/dist/configs/recommended.d.ts +++ /dev/null @@ -1,28 +0,0 @@ -import type { ESLint, Linter } from "eslint"; -/** - * 规则实现注册表(权威来源)。 - * 新增规则只需:实现 rule → 挂到此处 → 写入 recommended/all 严重级别。 - */ -export declare const rules: { - "no-player-send-message": import("@typescript-eslint/utils/ts-eslint").RuleModule<"useMsg", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & { - name: string; - }; - "no-sfmc-sdk-alias": import("@typescript-eslint/utils/ts-eslint").RuleModule<"useOfficial", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & { - name: string; - }; - "no-sdk-deep-import": import("@typescript-eslint/utils/ts-eslint").RuleModule<"usePublic", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & { - name: string; - }; - "require-module-registry": import("@typescript-eslint/utils/ts-eslint").RuleModule<"missing", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & { - name: string; - }; -}; -/** recommended:日常模块/SDK 约定 */ -export declare const recommendedRules: Linter.RulesRecord; -/** all:在 recommended 上将 no-player-send-message 升为 error */ -export declare const allRules: Linter.RulesRecord; -/** - * 生成 flat config 片段。 - * 由调用方注入 plugin 实例,避免 configs ↔ index 循环依赖。 - */ -export declare function createFlatConfig(plugin: ESLint.Plugin, ruleSeverities: Linter.RulesRecord, name?: string): Linter.Config; diff --git a/modules/sdk/@sfmc-eslint-plugin/dist/configs/recommended.js b/modules/sdk/@sfmc-eslint-plugin/dist/configs/recommended.js deleted file mode 100644 index 453686cb..00000000 --- a/modules/sdk/@sfmc-eslint-plugin/dist/configs/recommended.js +++ /dev/null @@ -1,39 +0,0 @@ -import { noPlayerSendMessage } from "../rules/no-player-send-message.js"; -import { noSdkDeepImport } from "../rules/no-sdk-deep-import.js"; -import { noSfmcSdkAlias } from "../rules/no-sfmc-sdk-alias.js"; -import { requireModuleRegistry } from "../rules/require-module-registry.js"; -/** - * 规则实现注册表(权威来源)。 - * 新增规则只需:实现 rule → 挂到此处 → 写入 recommended/all 严重级别。 - */ -export const rules = { - "no-player-send-message": noPlayerSendMessage, - "no-sfmc-sdk-alias": noSfmcSdkAlias, - "no-sdk-deep-import": noSdkDeepImport, - "require-module-registry": requireModuleRegistry, -}; -/** recommended:日常模块/SDK 约定 */ -export const recommendedRules = { - "@sfmc-bds/no-player-send-message": "warn", - "@sfmc-bds/no-sfmc-sdk-alias": "error", - "@sfmc-bds/no-sdk-deep-import": "error", - "@sfmc-bds/require-module-registry": "warn", -}; -/** all:在 recommended 上将 no-player-send-message 升为 error */ -export const allRules = { - ...recommendedRules, - "@sfmc-bds/no-player-send-message": "error", -}; -/** - * 生成 flat config 片段。 - * 由调用方注入 plugin 实例,避免 configs ↔ index 循环依赖。 - */ -export function createFlatConfig(plugin, ruleSeverities, name = "@sfmc-bds/eslint-plugin/recommended") { - return { - name, - plugins: { - "@sfmc-bds": plugin, - }, - rules: ruleSeverities, - }; -} diff --git a/modules/sdk/@sfmc-eslint-plugin/dist/index.d.ts b/modules/sdk/@sfmc-eslint-plugin/dist/index.d.ts deleted file mode 100644 index 0b7b92e0..00000000 --- a/modules/sdk/@sfmc-eslint-plugin/dist/index.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -import type { ESLint } from "eslint"; -import { allRules, recommendedRules, rules } from "./configs/recommended.js"; -/** - * ESLint.Plugin.rules 期望核心 RuleDefinition,而 @typescript-eslint 的 RuleModule - * 在 create/context 形状上更窄;运行时兼容,此处用断言对齐发布面契约(LSP 边界)。 - */ -declare const plugin: ESLint.Plugin; -export default plugin; -export { allRules, recommendedRules, rules }; diff --git a/modules/sdk/@sfmc-eslint-plugin/dist/index.js b/modules/sdk/@sfmc-eslint-plugin/dist/index.js deleted file mode 100644 index e732ac10..00000000 --- a/modules/sdk/@sfmc-eslint-plugin/dist/index.js +++ /dev/null @@ -1,18 +0,0 @@ -import { allRules, createFlatConfig, recommendedRules, rules, } from "./configs/recommended.js"; -/** - * ESLint.Plugin.rules 期望核心 RuleDefinition,而 @typescript-eslint 的 RuleModule - * 在 create/context 形状上更窄;运行时兼容,此处用断言对齐发布面契约(LSP 边界)。 - */ -const plugin = { - meta: { - name: "@sfmc-bds/eslint-plugin", - version: "0.1.0", - }, - rules, -}; -plugin.configs = { - recommended: createFlatConfig(plugin, recommendedRules), - all: createFlatConfig(plugin, allRules, "@sfmc-bds/eslint-plugin/all"), -}; -export default plugin; -export { allRules, recommendedRules, rules }; diff --git a/modules/sdk/@sfmc-eslint-plugin/dist/rules/no-player-send-message.d.ts b/modules/sdk/@sfmc-eslint-plugin/dist/rules/no-player-send-message.d.ts deleted file mode 100644 index 6ab89272..00000000 --- a/modules/sdk/@sfmc-eslint-plugin/dist/rules/no-player-send-message.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -/** - * 禁止 player/world.sendMessage — 业务侧应使用 Msg.* - */ -export declare const noPlayerSendMessage: import("@typescript-eslint/utils/ts-eslint").RuleModule<"useMsg", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & { - name: string; -}; diff --git a/modules/sdk/@sfmc-eslint-plugin/dist/rules/no-player-send-message.js b/modules/sdk/@sfmc-eslint-plugin/dist/rules/no-player-send-message.js deleted file mode 100644 index a3f8c601..00000000 --- a/modules/sdk/@sfmc-eslint-plugin/dist/rules/no-player-send-message.js +++ /dev/null @@ -1,30 +0,0 @@ -import { createRule } from "../utils/create-rule.js"; -/** - * 禁止 player/world.sendMessage — 业务侧应使用 Msg.* - */ -export const noPlayerSendMessage = createRule({ - name: "no-player-send-message", - meta: { - type: "suggestion", - docs: { - description: "禁止直接调用 sendMessage;请使用 Msg.info/success/error/warning/tips", - }, - messages: { - useMsg: "勿直接调用 sendMessage()。请使用 Msg.info / Msg.success / Msg.error / Msg.warning / Msg.tips(@sfmc-bds/sdk/sapi/runtime)。", - }, - schema: [], - }, - defaultOptions: [], - create(context) { - return { - CallExpression(node) { - if (node.callee.type !== "MemberExpression" || node.callee.computed) - return; - const prop = node.callee.property; - if (prop.type !== "Identifier" || prop.name !== "sendMessage") - return; - context.report({ node, messageId: "useMsg" }); - }, - }; - }, -}); diff --git a/modules/sdk/@sfmc-eslint-plugin/dist/rules/no-player-send-message.test.d.ts b/modules/sdk/@sfmc-eslint-plugin/dist/rules/no-player-send-message.test.d.ts deleted file mode 100644 index cb0ff5c3..00000000 --- a/modules/sdk/@sfmc-eslint-plugin/dist/rules/no-player-send-message.test.d.ts +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/modules/sdk/@sfmc-eslint-plugin/dist/rules/no-player-send-message.test.js b/modules/sdk/@sfmc-eslint-plugin/dist/rules/no-player-send-message.test.js deleted file mode 100644 index 03ca567d..00000000 --- a/modules/sdk/@sfmc-eslint-plugin/dist/rules/no-player-send-message.test.js +++ /dev/null @@ -1,31 +0,0 @@ -import { RuleTester } from "@typescript-eslint/rule-tester"; -import test from "node:test"; -import { noPlayerSendMessage } from "./no-player-send-message.js"; -RuleTester.afterAll = () => { }; -RuleTester.describe = test; -RuleTester.it = test; -RuleTester.itOnly = test.only; -const ruleTester = new RuleTester({ - languageOptions: { - parserOptions: { - ecmaVersion: 2022, - sourceType: "module", - }, - }, -}); -ruleTester.run("no-player-send-message", noPlayerSendMessage, { - valid: [ - `import { Msg } from "@sfmc-bds/sdk/sapi/runtime"; Msg.info("hi", player);`, - `foo.bar();`, - ], - invalid: [ - { - code: `player.sendMessage("hi");`, - errors: [{ messageId: "useMsg" }], - }, - { - code: `world.sendMessage({ rawtext: [] });`, - errors: [{ messageId: "useMsg" }], - }, - ], -}); diff --git a/modules/sdk/@sfmc-eslint-plugin/dist/rules/no-sdk-deep-import.d.ts b/modules/sdk/@sfmc-eslint-plugin/dist/rules/no-sdk-deep-import.d.ts deleted file mode 100644 index ee6619b9..00000000 --- a/modules/sdk/@sfmc-eslint-plugin/dist/rules/no-sdk-deep-import.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -/** - * 禁止相对路径深挖 SDK 源码 - */ -export declare const noSdkDeepImport: import("@typescript-eslint/utils/ts-eslint").RuleModule<"usePublic", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & { - name: string; -}; diff --git a/modules/sdk/@sfmc-eslint-plugin/dist/rules/no-sdk-deep-import.js b/modules/sdk/@sfmc-eslint-plugin/dist/rules/no-sdk-deep-import.js deleted file mode 100644 index 77865384..00000000 --- a/modules/sdk/@sfmc-eslint-plugin/dist/rules/no-sdk-deep-import.js +++ /dev/null @@ -1,38 +0,0 @@ -import { createRule } from "../utils/create-rule.js"; -/** - * 禁止相对路径深挖 SDK 源码 - */ -export const noSdkDeepImport = createRule({ - name: "no-sdk-deep-import", - meta: { - type: "problem", - docs: { - description: "禁止相对路径引用 SDK 源码;只允许 @sfmc-bds/sdk/", - }, - messages: { - usePublic: "请使用 @sfmc-bds/sdk/ 公开入口,勿相对路径引用 SDK 源码(@sfmc-sdk/src 或 modules/sdk)。", - }, - schema: [], - }, - defaultOptions: [], - create(context) { - function checkSource(node) { - const src = node.source; - if (!src || src.type !== "Literal" || typeof src.value !== "string") - return; - const v = src.value.replace(/\\/g, "/"); - if (v.includes("@sfmc-sdk/src") || - v.includes("modules/sdk/") || - /(?:^|\/)@sfmc-sdk(?:\/|$)/.test(v)) { - if (v.startsWith("@sfmc-bds/sdk")) - return; - context.report({ node: src, messageId: "usePublic" }); - } - } - return { - ImportDeclaration: checkSource, - ExportNamedDeclaration: checkSource, - ExportAllDeclaration: checkSource, - }; - }, -}); diff --git a/modules/sdk/@sfmc-eslint-plugin/dist/rules/no-sdk-deep-import.test.d.ts b/modules/sdk/@sfmc-eslint-plugin/dist/rules/no-sdk-deep-import.test.d.ts deleted file mode 100644 index cb0ff5c3..00000000 --- a/modules/sdk/@sfmc-eslint-plugin/dist/rules/no-sdk-deep-import.test.d.ts +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/modules/sdk/@sfmc-eslint-plugin/dist/rules/no-sdk-deep-import.test.js b/modules/sdk/@sfmc-eslint-plugin/dist/rules/no-sdk-deep-import.test.js deleted file mode 100644 index fa2c33fa..00000000 --- a/modules/sdk/@sfmc-eslint-plugin/dist/rules/no-sdk-deep-import.test.js +++ /dev/null @@ -1,31 +0,0 @@ -import { RuleTester } from "@typescript-eslint/rule-tester"; -import test from "node:test"; -import { noSdkDeepImport } from "./no-sdk-deep-import.js"; -RuleTester.afterAll = () => { }; -RuleTester.describe = test; -RuleTester.it = test; -RuleTester.itOnly = test.only; -const ruleTester = new RuleTester({ - languageOptions: { - parserOptions: { - ecmaVersion: 2022, - sourceType: "module", - }, - }, -}); -ruleTester.run("no-sdk-deep-import", noSdkDeepImport, { - valid: [ - `import { Msg } from "@sfmc-bds/sdk/sapi/runtime";`, - `import { foo } from "../utils";`, - ], - invalid: [ - { - code: `import { Msg } from "../../../../modules/sdk/@sfmc-sdk/src/sapi/runtime/msg";`, - errors: [{ messageId: "usePublic" }], - }, - { - code: `import x from "../../../@sfmc-sdk/src/index";`, - errors: [{ messageId: "usePublic" }], - }, - ], -}); diff --git a/modules/sdk/@sfmc-eslint-plugin/dist/rules/no-sfmc-sdk-alias.d.ts b/modules/sdk/@sfmc-eslint-plugin/dist/rules/no-sfmc-sdk-alias.d.ts deleted file mode 100644 index 27ba1972..00000000 --- a/modules/sdk/@sfmc-eslint-plugin/dist/rules/no-sfmc-sdk-alias.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -/** - * 禁止 @sfmc/sdk 别名,统一 @sfmc-bds/sdk - */ -export declare const noSfmcSdkAlias: import("@typescript-eslint/utils/ts-eslint").RuleModule<"useOfficial", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & { - name: string; -}; diff --git a/modules/sdk/@sfmc-eslint-plugin/dist/rules/no-sfmc-sdk-alias.js b/modules/sdk/@sfmc-eslint-plugin/dist/rules/no-sfmc-sdk-alias.js deleted file mode 100644 index e70e497f..00000000 --- a/modules/sdk/@sfmc-eslint-plugin/dist/rules/no-sfmc-sdk-alias.js +++ /dev/null @@ -1,33 +0,0 @@ -import { createRule } from "../utils/create-rule.js"; -/** - * 禁止 @sfmc/sdk 别名,统一 @sfmc-bds/sdk - */ -export const noSfmcSdkAlias = createRule({ - name: "no-sfmc-sdk-alias", - meta: { - type: "problem", - docs: { - description: "禁止 import @sfmc/sdk;请使用 @sfmc-bds/sdk 公开入口", - }, - messages: { - useOfficial: "请改用 @sfmc-bds/sdk(@sfmc/sdk 仅为本地 alias,发布面以 @sfmc-bds 为准)。", - }, - schema: [], - }, - defaultOptions: [], - create(context) { - function checkSource(node) { - const src = node.source; - if (!src || src.type !== "Literal" || typeof src.value !== "string") - return; - if (src.value === "@sfmc/sdk" || src.value.startsWith("@sfmc/sdk/")) { - context.report({ node: src, messageId: "useOfficial" }); - } - } - return { - ImportDeclaration: checkSource, - ExportNamedDeclaration: checkSource, - ExportAllDeclaration: checkSource, - }; - }, -}); diff --git a/modules/sdk/@sfmc-eslint-plugin/dist/rules/no-sfmc-sdk-alias.test.d.ts b/modules/sdk/@sfmc-eslint-plugin/dist/rules/no-sfmc-sdk-alias.test.d.ts deleted file mode 100644 index cb0ff5c3..00000000 --- a/modules/sdk/@sfmc-eslint-plugin/dist/rules/no-sfmc-sdk-alias.test.d.ts +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/modules/sdk/@sfmc-eslint-plugin/dist/rules/no-sfmc-sdk-alias.test.js b/modules/sdk/@sfmc-eslint-plugin/dist/rules/no-sfmc-sdk-alias.test.js deleted file mode 100644 index 591ca700..00000000 --- a/modules/sdk/@sfmc-eslint-plugin/dist/rules/no-sfmc-sdk-alias.test.js +++ /dev/null @@ -1,31 +0,0 @@ -import { RuleTester } from "@typescript-eslint/rule-tester"; -import test from "node:test"; -import { noSfmcSdkAlias } from "./no-sfmc-sdk-alias.js"; -RuleTester.afterAll = () => { }; -RuleTester.describe = test; -RuleTester.it = test; -RuleTester.itOnly = test.only; -const ruleTester = new RuleTester({ - languageOptions: { - parserOptions: { - ecmaVersion: 2022, - sourceType: "module", - }, - }, -}); -ruleTester.run("no-sfmc-sdk-alias", noSfmcSdkAlias, { - valid: [ - `import { Msg } from "@sfmc-bds/sdk/sapi/runtime";`, - `import { ModuleRegistry } from "@sfmc-bds/sdk/module-loader";`, - ], - invalid: [ - { - code: `import { Msg } from "@sfmc/sdk/sapi/runtime";`, - errors: [{ messageId: "useOfficial" }], - }, - { - code: `import x from "@sfmc/sdk";`, - errors: [{ messageId: "useOfficial" }], - }, - ], -}); diff --git a/modules/sdk/@sfmc-eslint-plugin/dist/rules/require-module-registry.d.ts b/modules/sdk/@sfmc-eslint-plugin/dist/rules/require-module-registry.d.ts deleted file mode 100644 index 5808fa34..00000000 --- a/modules/sdk/@sfmc-eslint-plugin/dist/rules/require-module-registry.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -/** - * 模块入口 index.ts 应调用 ModuleRegistry.register - */ -export declare const requireModuleRegistry: import("@typescript-eslint/utils/ts-eslint").RuleModule<"missing", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & { - name: string; -}; diff --git a/modules/sdk/@sfmc-eslint-plugin/dist/rules/require-module-registry.js b/modules/sdk/@sfmc-eslint-plugin/dist/rules/require-module-registry.js deleted file mode 100644 index 6bb6f98b..00000000 --- a/modules/sdk/@sfmc-eslint-plugin/dist/rules/require-module-registry.js +++ /dev/null @@ -1,47 +0,0 @@ -import { createRule } from "../utils/create-rule.js"; -/** - * 模块入口 index.ts 应调用 ModuleRegistry.register - */ -export const requireModuleRegistry = createRule({ - name: "require-module-registry", - meta: { - type: "suggestion", - docs: { - description: "sapi/src/index.ts 入口须调用 ModuleRegistry.register", - }, - messages: { - missing: "模块入口应调用 ModuleRegistry.register({ id, lifecycle, ... })(@sfmc-bds/sdk/module-loader)。", - }, - schema: [], - }, - defaultOptions: [], - create(context) { - const filename = context.filename.replace(/\\/g, "/"); - // 仅约束 .../sapi/src/index.ts - if (!/\/sapi\/src\/index\.ts$/.test(filename)) { - return {}; - } - let found = false; - function isRegisterCall(node) { - const callee = node.callee; - if (callee.type !== "MemberExpression" || callee.computed) - return false; - if (callee.property.type !== "Identifier" || callee.property.name !== "register") { - return false; - } - const obj = callee.object; - return obj.type === "Identifier" && obj.name === "ModuleRegistry"; - } - return { - CallExpression(node) { - if (isRegisterCall(node)) - found = true; - }, - "Program:exit"() { - if (!found) { - context.report({ loc: { line: 1, column: 0 }, messageId: "missing" }); - } - }, - }; - }, -}); diff --git a/modules/sdk/@sfmc-eslint-plugin/dist/rules/require-module-registry.test.d.ts b/modules/sdk/@sfmc-eslint-plugin/dist/rules/require-module-registry.test.d.ts deleted file mode 100644 index cb0ff5c3..00000000 --- a/modules/sdk/@sfmc-eslint-plugin/dist/rules/require-module-registry.test.d.ts +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/modules/sdk/@sfmc-eslint-plugin/dist/rules/require-module-registry.test.js b/modules/sdk/@sfmc-eslint-plugin/dist/rules/require-module-registry.test.js deleted file mode 100644 index b917a249..00000000 --- a/modules/sdk/@sfmc-eslint-plugin/dist/rules/require-module-registry.test.js +++ /dev/null @@ -1,38 +0,0 @@ -import { RuleTester } from "@typescript-eslint/rule-tester"; -import test from "node:test"; -import { requireModuleRegistry } from "./require-module-registry.js"; -RuleTester.afterAll = () => { }; -RuleTester.describe = test; -RuleTester.it = test; -RuleTester.itOnly = test.only; -const ruleTester = new RuleTester({ - languageOptions: { - parserOptions: { - ecmaVersion: 2022, - sourceType: "module", - }, - }, -}); -ruleTester.run("require-module-registry", requireModuleRegistry, { - valid: [ - { - filename: "/repo/packages/afk/sapi/src/index.ts", - code: ` - import { ModuleRegistry } from "@sfmc-bds/sdk/module-loader"; - ModuleRegistry.register({ id: "feature-afk", lifecycle: {} }); - `, - }, - { - // 非入口文件不检查 - filename: "/repo/packages/afk/sapi/src/helper.ts", - code: `export const x = 1;`, - }, - ], - invalid: [ - { - filename: "/repo/packages/afk/sapi/src/index.ts", - code: `export const x = 1;`, - errors: [{ messageId: "missing" }], - }, - ], -}); diff --git a/modules/sdk/@sfmc-eslint-plugin/dist/utils/create-rule.d.ts b/modules/sdk/@sfmc-eslint-plugin/dist/utils/create-rule.d.ts deleted file mode 100644 index 7b868c90..00000000 --- a/modules/sdk/@sfmc-eslint-plugin/dist/utils/create-rule.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { ESLintUtils } from "@typescript-eslint/utils"; -export declare const createRule: ({ meta, name, ...rule }: Readonly>) => ESLintUtils.RuleModule & { - name: string; -}; diff --git a/modules/sdk/@sfmc-eslint-plugin/dist/utils/create-rule.js b/modules/sdk/@sfmc-eslint-plugin/dist/utils/create-rule.js deleted file mode 100644 index 5ead9951..00000000 --- a/modules/sdk/@sfmc-eslint-plugin/dist/utils/create-rule.js +++ /dev/null @@ -1,2 +0,0 @@ -import { ESLintUtils } from "@typescript-eslint/utils"; -export const createRule = ESLintUtils.RuleCreator((name) => `https://github.com/DogeLakeDev/ScriptsForMinecraftServer/blob/main/modules/sdk/@sfmc-eslint-plugin/README.md#${name}`); diff --git a/modules/sdk/@sfmc-eslint-plugin/src/rules/no-player-send-message.test.ts b/modules/sdk/@sfmc-eslint-plugin/src/rules/no-player-send-message.test.ts index 3d45a25e..776bfa3a 100644 --- a/modules/sdk/@sfmc-eslint-plugin/src/rules/no-player-send-message.test.ts +++ b/modules/sdk/@sfmc-eslint-plugin/src/rules/no-player-send-message.test.ts @@ -1,22 +1,7 @@ -import { RuleTester } from "@typescript-eslint/rule-tester"; -import test from "node:test"; import { noPlayerSendMessage } from "./no-player-send-message.js"; +import { createRuleTester } from "../utils/rule-tester.js"; -RuleTester.afterAll = () => {}; -RuleTester.describe = test; -RuleTester.it = test; -RuleTester.itOnly = test.only; - -const ruleTester = new RuleTester({ - languageOptions: { - parserOptions: { - ecmaVersion: 2022, - sourceType: "module", - }, - }, -}); - -ruleTester.run("no-player-send-message", noPlayerSendMessage, { +createRuleTester().run("no-player-send-message", noPlayerSendMessage, { valid: [ `import { Msg } from "@sfmc-bds/sdk/sapi/runtime"; Msg.info("hi", player);`, `foo.bar();`, diff --git a/modules/sdk/@sfmc-eslint-plugin/src/rules/no-sdk-deep-import.test.ts b/modules/sdk/@sfmc-eslint-plugin/src/rules/no-sdk-deep-import.test.ts index 0098ce52..052fc6aa 100644 --- a/modules/sdk/@sfmc-eslint-plugin/src/rules/no-sdk-deep-import.test.ts +++ b/modules/sdk/@sfmc-eslint-plugin/src/rules/no-sdk-deep-import.test.ts @@ -1,22 +1,7 @@ -import { RuleTester } from "@typescript-eslint/rule-tester"; -import test from "node:test"; import { noSdkDeepImport } from "./no-sdk-deep-import.js"; +import { createRuleTester } from "../utils/rule-tester.js"; -RuleTester.afterAll = () => {}; -RuleTester.describe = test; -RuleTester.it = test; -RuleTester.itOnly = test.only; - -const ruleTester = new RuleTester({ - languageOptions: { - parserOptions: { - ecmaVersion: 2022, - sourceType: "module", - }, - }, -}); - -ruleTester.run("no-sdk-deep-import", noSdkDeepImport, { +createRuleTester().run("no-sdk-deep-import", noSdkDeepImport, { valid: [ `import { Msg } from "@sfmc-bds/sdk/sapi/runtime";`, `import { foo } from "../utils";`, diff --git a/modules/sdk/@sfmc-eslint-plugin/src/rules/no-sfmc-sdk-alias.test.ts b/modules/sdk/@sfmc-eslint-plugin/src/rules/no-sfmc-sdk-alias.test.ts index c1ae4feb..85a715f8 100644 --- a/modules/sdk/@sfmc-eslint-plugin/src/rules/no-sfmc-sdk-alias.test.ts +++ b/modules/sdk/@sfmc-eslint-plugin/src/rules/no-sfmc-sdk-alias.test.ts @@ -1,22 +1,7 @@ -import { RuleTester } from "@typescript-eslint/rule-tester"; -import test from "node:test"; import { noSfmcSdkAlias } from "./no-sfmc-sdk-alias.js"; +import { createRuleTester } from "../utils/rule-tester.js"; -RuleTester.afterAll = () => {}; -RuleTester.describe = test; -RuleTester.it = test; -RuleTester.itOnly = test.only; - -const ruleTester = new RuleTester({ - languageOptions: { - parserOptions: { - ecmaVersion: 2022, - sourceType: "module", - }, - }, -}); - -ruleTester.run("no-sfmc-sdk-alias", noSfmcSdkAlias, { +createRuleTester().run("no-sfmc-sdk-alias", noSfmcSdkAlias, { valid: [ `import { Msg } from "@sfmc-bds/sdk/sapi/runtime";`, `import { ModuleRegistry } from "@sfmc-bds/sdk/module-loader";`, diff --git a/modules/sdk/@sfmc-eslint-plugin/src/rules/require-module-registry.test.ts b/modules/sdk/@sfmc-eslint-plugin/src/rules/require-module-registry.test.ts index 7d0a1c32..ad01942f 100644 --- a/modules/sdk/@sfmc-eslint-plugin/src/rules/require-module-registry.test.ts +++ b/modules/sdk/@sfmc-eslint-plugin/src/rules/require-module-registry.test.ts @@ -1,22 +1,7 @@ -import { RuleTester } from "@typescript-eslint/rule-tester"; -import test from "node:test"; import { requireModuleRegistry } from "./require-module-registry.js"; +import { createRuleTester } from "../utils/rule-tester.js"; -RuleTester.afterAll = () => {}; -RuleTester.describe = test; -RuleTester.it = test; -RuleTester.itOnly = test.only; - -const ruleTester = new RuleTester({ - languageOptions: { - parserOptions: { - ecmaVersion: 2022, - sourceType: "module", - }, - }, -}); - -ruleTester.run("require-module-registry", requireModuleRegistry, { +createRuleTester().run("require-module-registry", requireModuleRegistry, { valid: [ { filename: "/repo/packages/afk/sapi/src/index.ts", diff --git a/modules/sdk/@sfmc-eslint-plugin/src/utils/rule-tester.ts b/modules/sdk/@sfmc-eslint-plugin/src/utils/rule-tester.ts new file mode 100644 index 00000000..65006ca9 --- /dev/null +++ b/modules/sdk/@sfmc-eslint-plugin/src/utils/rule-tester.ts @@ -0,0 +1,19 @@ +import { RuleTester } from "@typescript-eslint/rule-tester"; +import test from "node:test"; + +/** 统一 RuleTester 与 node:test 桥接,避免各规则测试重复样板(DRY) */ +RuleTester.afterAll = () => {}; +RuleTester.describe = test; +RuleTester.it = test; +RuleTester.itOnly = test.only; + +export function createRuleTester(): RuleTester { + return new RuleTester({ + languageOptions: { + parserOptions: { + ecmaVersion: 2022, + sourceType: "module", + }, + }, + }); +} diff --git a/package-lock.json b/package-lock.json index 7f18f1ed..571c3990 100644 --- a/package-lock.json +++ b/package-lock.json @@ -52,14 +52,6 @@ "node": ">=22.13.0" } }, - "../sfmc-modules/packages/economy": { - "name": "@sfmc-bds/module-economy", - "version": "0.1.0", - "extraneous": true, - "dependencies": { - "@sfmc-bds/sdk": "*" - } - }, "bds-tools": { "name": "@sfmc-bds/bds-tools", "version": "0.1.0", @@ -94,15 +86,6 @@ "@sfmc-bds/sdk": "*" } }, - "modules/packages/land": { - "name": "@sfmc-bds/module-land", - "version": "0.1.0", - "extraneous": true, - "dependencies": { - "@sfmc-bds/module-economy": "file:../../../../sfmc-modules/packages/economy", - "@sfmc-bds/sdk": "*" - } - }, "modules/sdk/@sfmc-eslint-plugin": { "name": "@sfmc-bds/eslint-plugin", "version": "0.1.0", diff --git a/package.json b/package.json index b312c2b8..b7753615 100644 --- a/package.json +++ b/package.json @@ -50,7 +50,7 @@ "check-ootb": "node tools/check-ootb.mjs", "check-minecraft-versions": "node tools/check-minecraft-versions.mjs", "smoke-modules": "node tools/smoke-modules.mjs", - "lint": "eslint .", + "lint": "npm run eslint-plugin:build && eslint .", "bundle": "node build-sea.mjs", "sea": "node --build-sea sea-config.json" },