diff --git a/apps/oxlint/src-js/js_config.ts b/apps/oxlint/src-js/js_config.ts index 6408d0dca0709..6ddcc43073b63 100644 --- a/apps/oxlint/src-js/js_config.ts +++ b/apps/oxlint/src-js/js_config.ts @@ -1,4 +1,5 @@ import { getErrorMessage } from "./utils/utils.ts"; +import { isDefineConfig } from "./package/config.ts"; import { JSONStringify } from "./utils/globals.ts"; interface JsConfigResult { @@ -36,6 +37,12 @@ export async function loadJsConfigs(paths: string[]): Promise { throw new Error(`Configuration file must have a default export that is an object.`); } + if (!isDefineConfig(config)) { + throw new Error( + `Configuration file must wrap its default export with defineConfig() from "oxlint".`, + ); + } + return { path, config }; }), ); diff --git a/apps/oxlint/src-js/package/config.ts b/apps/oxlint/src-js/package/config.ts index 75f2858c63232..ce706226e5b61 100644 --- a/apps/oxlint/src-js/package/config.ts +++ b/apps/oxlint/src-js/package/config.ts @@ -34,6 +34,8 @@ export type OxlintConfig = Oxlintrc; export type { OxlintOverride }; +const DEFINE_CONFIG_REGISTRY = new WeakSet(); + /** * Define an Oxlint configuration with type inference. * @@ -41,5 +43,12 @@ export type { OxlintOverride }; * @returns Config unchanged */ export function defineConfig(config: T): T { + DEFINE_CONFIG_REGISTRY.add(config as object); return config; } + +export function isDefineConfig(config: unknown): boolean { + return ( + typeof config === "object" && config !== null && DEFINE_CONFIG_REGISTRY.has(config as object) + ); +} diff --git a/apps/oxlint/test/fixtures/js_config_basic/oxlint.config.ts b/apps/oxlint/test/fixtures/js_config_basic/oxlint.config.ts index eb3b55a5f1e73..79e377b8b3e66 100644 --- a/apps/oxlint/test/fixtures/js_config_basic/oxlint.config.ts +++ b/apps/oxlint/test/fixtures/js_config_basic/oxlint.config.ts @@ -1,7 +1,9 @@ // Basic test for oxlint.config.ts support -export default { +import { defineConfig } from "#oxlint"; + +export default defineConfig({ rules: { "no-debugger": "error", eqeqeq: "warn", }, -}; +}); diff --git a/apps/oxlint/test/fixtures/js_config_missing_define_config/files/oxlint.config.ts b/apps/oxlint/test/fixtures/js_config_missing_define_config/files/oxlint.config.ts new file mode 100644 index 0000000000000..4f00b08c16ffa --- /dev/null +++ b/apps/oxlint/test/fixtures/js_config_missing_define_config/files/oxlint.config.ts @@ -0,0 +1,3 @@ +export default { + rules: {}, +}; diff --git a/apps/oxlint/test/fixtures/js_config_missing_define_config/files/test.js b/apps/oxlint/test/fixtures/js_config_missing_define_config/files/test.js new file mode 100644 index 0000000000000..4f252c003683a --- /dev/null +++ b/apps/oxlint/test/fixtures/js_config_missing_define_config/files/test.js @@ -0,0 +1 @@ +console.log("ok"); diff --git a/apps/oxlint/test/fixtures/js_config_missing_define_config/output.snap.md b/apps/oxlint/test/fixtures/js_config_missing_define_config/output.snap.md new file mode 100644 index 0000000000000..dc461dcfb657a --- /dev/null +++ b/apps/oxlint/test/fixtures/js_config_missing_define_config/output.snap.md @@ -0,0 +1,15 @@ +# Exit code +1 + +# stdout +``` +Failed to parse oxlint configuration file. + + x Failed to load config: /files/oxlint.config.ts + | + | Error: Configuration file must wrap its default export with defineConfig() from "oxlint". +``` + +# stderr +``` +``` diff --git a/apps/oxlint/test/fixtures/js_config_nested_conflict/files/nested/oxlint.config.ts b/apps/oxlint/test/fixtures/js_config_nested_conflict/files/nested/oxlint.config.ts index 08717a09a7300..aeaeb12258072 100644 --- a/apps/oxlint/test/fixtures/js_config_nested_conflict/files/nested/oxlint.config.ts +++ b/apps/oxlint/test/fixtures/js_config_nested_conflict/files/nested/oxlint.config.ts @@ -1 +1,3 @@ -export default { rules: {} }; +import { defineConfig } from "#oxlint"; + +export default defineConfig({ rules: {} }); diff --git a/apps/oxlint/test/fixtures/js_config_overrides/oxlint.config.ts b/apps/oxlint/test/fixtures/js_config_overrides/oxlint.config.ts index 6bac6874e56e0..298e7158b1bd2 100644 --- a/apps/oxlint/test/fixtures/js_config_overrides/oxlint.config.ts +++ b/apps/oxlint/test/fixtures/js_config_overrides/oxlint.config.ts @@ -1,5 +1,7 @@ // Test that overrides work in oxlint.config.ts -export default { +import { defineConfig } from "#oxlint"; + +export default defineConfig({ rules: { "no-debugger": "off", }, @@ -11,4 +13,4 @@ export default { }, }, ], -}; +}); diff --git a/apps/oxlint/test/fixtures/js_config_throws_err/output.snap.md b/apps/oxlint/test/fixtures/js_config_throws_err/output.snap.md index 815872f706b75..7c29c1dd7a86a 100644 --- a/apps/oxlint/test/fixtures/js_config_throws_err/output.snap.md +++ b/apps/oxlint/test/fixtures/js_config_throws_err/output.snap.md @@ -8,7 +8,7 @@ Failed to parse oxlint configuration file. x Failed to load config: /oxlint.config.ts | | Error: This is a test error - | at /oxlint.config.ts:1:7 + | at /oxlint.config.ts:3:7 ``` # stderr diff --git a/apps/oxlint/test/fixtures/js_config_throws_err/oxlint.config.ts b/apps/oxlint/test/fixtures/js_config_throws_err/oxlint.config.ts index ddd4800bd9c4a..032ce2c00b4e4 100644 --- a/apps/oxlint/test/fixtures/js_config_throws_err/oxlint.config.ts +++ b/apps/oxlint/test/fixtures/js_config_throws_err/oxlint.config.ts @@ -1,3 +1,5 @@ +import { defineConfig } from "#oxlint"; + throw new Error("This is a test error"); -export default {}; +export default defineConfig({});