oxlint-plugin-react-doctor 0.9.1-dev.8534d86 → 0.9.1-dev.b1b62db

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +70 -22
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -34013,6 +34013,27 @@ const jsxNoTargetBlank = defineRule({
34013
34013
  }
34014
34014
  });
34015
34015
  //#endregion
34016
+ //#region src/plugin/utils/get-project-relative-filename.ts
34017
+ const getProjectRelativeFilename = (filename, rootDirectory) => {
34018
+ const normalizedFilename = normalizeFilename(filename);
34019
+ if (!rootDirectory) return normalizedFilename;
34020
+ const rootDirectoryPrefix = `${normalizeFilename(rootDirectory).replace(/\/+$/, "")}/`;
34021
+ if (!normalizedFilename.startsWith(rootDirectoryPrefix)) return normalizedFilename;
34022
+ return normalizedFilename.slice(rootDirectoryPrefix.length);
34023
+ };
34024
+ //#endregion
34025
+ //#region src/plugin/utils/get-project-relative-filename-from-roots.ts
34026
+ const getProjectRelativeFilenameFromRoots = (filename, rootDirectories) => {
34027
+ const normalizedFilename = normalizeFilename(filename);
34028
+ if (normalizedFilename.length === 0) return null;
34029
+ if (!path.isAbsolute(filename)) return normalizedFilename;
34030
+ for (const rootDirectory of rootDirectories) {
34031
+ const relativeFilename = getProjectRelativeFilename(normalizedFilename, rootDirectory);
34032
+ if (relativeFilename !== normalizedFilename) return relativeFilename;
34033
+ }
34034
+ return null;
34035
+ };
34036
+ //#endregion
34016
34037
  //#region src/plugin/rules/react-builtins/jsx-no-undef.ts
34017
34038
  const buildMessage$18 = (name) => `\`${name}\` crashes at runtime because it isn't defined here.`;
34018
34039
  const KNOWN_GLOBALS = new Set([
@@ -34063,24 +34084,60 @@ const getRootIdentifier$1 = (elementName) => {
34063
34084
  }
34064
34085
  return null;
34065
34086
  };
34087
+ const resolveUnpluginAutoImportGlobalScopes = (settings) => {
34088
+ const reactDoctorSettings = settings?.["react-doctor"];
34089
+ if (typeof reactDoctorSettings !== "object" || reactDoctorSettings === null || Array.isArray(reactDoctorSettings)) return [];
34090
+ const rawScopes = Object.getOwnPropertyDescriptor(reactDoctorSettings, "unpluginAutoImportGlobalScopes")?.value;
34091
+ if (!Array.isArray(rawScopes)) return [];
34092
+ const scopes = [];
34093
+ for (const rawScope of rawScopes) {
34094
+ if (typeof rawScope !== "object" || rawScope === null || Array.isArray(rawScope)) continue;
34095
+ const directory = Object.getOwnPropertyDescriptor(rawScope, "directory")?.value;
34096
+ const names = Object.getOwnPropertyDescriptor(rawScope, "names")?.value;
34097
+ if (typeof directory !== "string" || !Array.isArray(names)) continue;
34098
+ const validNames = names.filter((name) => typeof name === "string" && name.length > 0);
34099
+ scopes.push({
34100
+ directory,
34101
+ names: new Set(validNames)
34102
+ });
34103
+ }
34104
+ return scopes;
34105
+ };
34106
+ const isInjectedRuntimeGlobal = (name, relativeFilename, configuredRuntimeGlobals, scopes) => {
34107
+ if (configuredRuntimeGlobals.has(name)) return true;
34108
+ if (relativeFilename === null) return false;
34109
+ let nearestScope = null;
34110
+ for (const scope of scopes) if ((scope.directory.length === 0 || relativeFilename.startsWith(`${scope.directory}/`)) && (!nearestScope || scope.directory.length > nearestScope.directory.length)) nearestScope = scope;
34111
+ return nearestScope?.names.has(name) ?? false;
34112
+ };
34066
34113
  const jsxNoUndef = defineRule({
34067
34114
  id: "jsx-no-undef",
34068
34115
  title: "Undefined JSX component",
34069
34116
  severity: "error",
34070
34117
  recommendation: "Import the component or fix the typo so React can resolve the JSX identifier at runtime.",
34071
- create: (context) => ({ JSXOpeningElement(node) {
34072
- const rootIdentifier = getRootIdentifier$1(node.name);
34073
- if (!rootIdentifier) return;
34074
- if (KNOWN_GLOBALS.has(rootIdentifier)) return;
34075
- const programRoot = findProgramRoot(node);
34076
- if (!programRoot) return;
34077
- if (isReactLiveStyleScript(programRoot)) return;
34078
- if (findVariableInitializer(node, rootIdentifier)) return;
34079
- context.report({
34080
- node: node.name,
34081
- message: buildMessage$18(rootIdentifier)
34082
- });
34083
- } })
34118
+ create: (context) => {
34119
+ const autoImportGlobalScopes = resolveUnpluginAutoImportGlobalScopes(context.settings);
34120
+ const configuredRuntimeGlobals = new Set(getReactDoctorStringArraySetting(context.settings, "runtimeGlobals"));
34121
+ const configuredAutoImportRootDirectories = getReactDoctorStringArraySetting(context.settings, "unpluginAutoImportRootDirectories");
34122
+ const rootDirectory = getReactDoctorStringSetting(context.settings, "rootDirectory");
34123
+ const fallbackAutoImportRootDirectories = rootDirectory ? [rootDirectory] : [];
34124
+ const autoImportRootDirectories = configuredAutoImportRootDirectories.length > 0 ? configuredAutoImportRootDirectories : fallbackAutoImportRootDirectories;
34125
+ const relativeFilename = getProjectRelativeFilenameFromRoots(context.filename ?? "", autoImportRootDirectories);
34126
+ return { JSXOpeningElement(node) {
34127
+ const rootIdentifier = getRootIdentifier$1(node.name);
34128
+ if (!rootIdentifier) return;
34129
+ if (KNOWN_GLOBALS.has(rootIdentifier)) return;
34130
+ if (isInjectedRuntimeGlobal(rootIdentifier, relativeFilename, configuredRuntimeGlobals, autoImportGlobalScopes)) return;
34131
+ const programRoot = findProgramRoot(node);
34132
+ if (!programRoot) return;
34133
+ if (isReactLiveStyleScript(programRoot)) return;
34134
+ if (findVariableInitializer(node, rootIdentifier)) return;
34135
+ context.report({
34136
+ node: node.name,
34137
+ message: buildMessage$18(rootIdentifier)
34138
+ });
34139
+ } };
34140
+ }
34084
34141
  });
34085
34142
  //#endregion
34086
34143
  //#region src/plugin/rules/react-builtins/jsx-no-useless-fragment.ts
@@ -37556,15 +37613,6 @@ const getSingleReturnExpression = (functionNode) => {
37556
37613
  return isNodeOfType(statement, "ReturnStatement") && statement.argument ? statement.argument : null;
37557
37614
  };
37558
37615
  //#endregion
37559
- //#region src/plugin/utils/get-project-relative-filename.ts
37560
- const getProjectRelativeFilename = (filename, rootDirectory) => {
37561
- const normalizedFilename = normalizeFilename(filename);
37562
- if (!rootDirectory) return normalizedFilename;
37563
- const rootDirectoryPrefix = `${normalizeFilename(rootDirectory).replace(/\/+$/, "")}/`;
37564
- if (!normalizedFilename.startsWith(rootDirectoryPrefix)) return normalizedFilename;
37565
- return normalizedFilename.slice(rootDirectoryPrefix.length);
37566
- };
37567
- //#endregion
37568
37616
  //#region src/plugin/utils/get-react-router-framework-module-kind.ts
37569
37617
  const REACT_ROUTER_ROUTE_DIRECTORY_PATTERN = /(?:^|\/)app\/routes\//;
37570
37618
  const REACT_ROUTER_ROOT_FILE_PATTERN = /(?:^|\/)app\/root\.(?:jsx?|tsx?)$/;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "oxlint-plugin-react-doctor",
3
- "version": "0.9.1-dev.8534d86",
3
+ "version": "0.9.1-dev.b1b62db",
4
4
  "description": "React Doctor rules for oxlint.",
5
5
  "keywords": [
6
6
  "accessibility",