@trackunit/eslint-plugin-trackunit 0.6.90 → 0.6.91-alpha-06136b80b13.0
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.
- package/CHANGELOG.md +0 -6
- package/migrations/entry.js.map +1 -0
- package/package.json +1 -1
- package/src/index.js.map +1 -0
- package/src/lib/config/fragments/ignores.js.map +1 -0
- package/src/lib/config/fragments/import-rules.js.map +1 -0
- package/src/lib/config/fragments/jest-overrides.js.map +1 -0
- package/src/lib/config/fragments/jsdoc-rules.js.map +1 -0
- package/src/lib/config/fragments/module-boundaries.js.map +1 -0
- package/src/lib/config/fragments/no-direct-storage-access.js.map +1 -0
- package/src/lib/config/fragments/react-rules.js.map +1 -0
- package/src/lib/config/fragments/restricted-imports.js.map +1 -0
- package/src/lib/config/fragments/testing-library.js.map +1 -0
- package/src/lib/config/fragments/typescript-rules.js.map +1 -0
- package/src/lib/config/index.js.map +1 -0
- package/src/lib/config/plugins.js.map +1 -0
- package/src/lib/config/presets/base.js.map +1 -0
- package/src/lib/config/presets/e2e.js.map +1 -0
- package/src/lib/config/presets/react.js.map +1 -0
- package/src/lib/config/presets/server.js.map +1 -0
- package/src/lib/config/utils.js.map +1 -0
- package/src/lib/config-helpers/create-skip-when.js.map +1 -0
- package/src/lib/rules/component-name-matches-filename/component-name-matches-filename.js.map +1 -0
- package/src/lib/rules/cva-merge-base-classes-as-array/cva-merge-base-classes-as-array.js.map +1 -0
- package/src/lib/rules/design-guideline-button-icon-size-match/design-guideline-button-icon-size-match.js.map +1 -0
- package/src/lib/rules/no-deprecated-graphql-fields/no-deprecated-graphql-fields.js.map +1 -0
- package/src/lib/rules/no-deprecated-graphql-fields/schema-cache.js.map +1 -0
- package/src/lib/rules/no-internal-barrel-files/no-internal-barrel-files.js.map +1 -0
- package/src/lib/rules/no-internal-graphql-when-tagged-with-gql-public/no-internal-graphql-when-tagged-with-gql-public.js.map +1 -0
- package/src/lib/rules/no-jest-mock-trackunit-react-core-hooks/no-jest-mock-trackunit-react-core-hooks.js.map +1 -0
- package/src/lib/rules/no-template-strings-in-classname-prop/no-template-strings-in-classname-prop.js.map +1 -0
- package/src/lib/rules/no-typescript-assertion/no-typescript-assertion.js.map +1 -0
- package/src/lib/rules/one-component-per-file/one-component-per-file.js.map +1 -0
- package/src/lib/rules/prefer-destructured-imports/prefer-destructured-imports.js.map +1 -0
- package/src/lib/rules/prefer-event-specific-callback-naming/name-suggestion-strategies.js.map +1 -0
- package/src/lib/rules/prefer-event-specific-callback-naming/prefer-event-specific-callback-naming.js.map +1 -0
- package/src/lib/rules/prefer-event-specific-callback-naming/strategies/string-based.js.map +1 -0
- package/src/lib/rules/prefer-event-specific-callback-naming/strategies/type-based.js.map +1 -0
- package/src/lib/rules/prefer-event-specific-callback-naming/utils.js.map +1 -0
- package/src/lib/rules/prefer-field-components/prefer-field-components.js.map +1 -0
- package/src/lib/rules/prefer-mouse-event-handler-in-react-props/prefer-mouse-event-handler-in-react-props.js.map +1 -0
- package/src/lib/rules/require-classname-alternatives/require-classname-alternatives.js.map +1 -0
- package/src/lib/rules/require-component-prop-contracts/require-component-prop-contracts.js.map +1 -0
- package/src/lib/rules/require-list-item-virtualization-props/require-list-item-virtualization-props.js.map +1 -0
- package/src/lib/rules/require-optional-prop-initialization/require-optional-prop-initialization.js.map +1 -0
- package/src/lib/rules/require-optional-prop-initialization/suggestion-utils.js.map +1 -0
- package/src/lib/rules/require-storybook-folder-landing-page/require-storybook-folder-landing-page.js.map +1 -0
- package/src/lib/rules-map.js.map +1 -0
- package/src/lib/utils/ast-utils.js.map +1 -0
- package/src/lib/utils/classname-utils.js.map +1 -0
- package/src/lib/utils/component-utils.js.map +1 -0
- package/src/lib/utils/file-utils.js.map +1 -0
- package/src/lib/utils/import-utils.js.map +1 -0
- package/src/lib/utils/nx-utils.js.map +1 -0
- package/src/lib/utils/package-utils.js.map +1 -0
- package/src/lib/utils/typescript-utils.js.map +1 -0
package/CHANGELOG.md
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"entry.js","sourceRoot":"","sources":["../../../../../libs/eslint/plugin-trackunit/migrations/entry.ts"],"names":[],"mappings":"","sourcesContent":["export {};\n"]}
|
package/package.json
CHANGED
package/src/index.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../libs/eslint/plugin-trackunit/src/index.ts"],"names":[],"mappings":";;;AAAA,+CAA2C;AAE3C,kBAAe,oBAAQ,CAAC;AAExB,uCAAuC;AAA9B,iGAAA,OAAO,OAAA;AAChB,0EAAuE;AAA9D,kHAAA,cAAc,OAAA;AACvB,4CAAsD;AAA7C,yGAAA,gBAAgB,OAAA;AAGzB,kEAAsE;AAA7D,+GAAA,gBAAgB,OAAA;AACzB,gFAAkF;AAAzE,2HAAA,qBAAqB,OAAA;AAC9B,gDAAkG;AAAzF,kGAAA,OAAO,OAAA;AAAE,gGAAA,KAAK,OAAA;AAAE,2GAAA,gBAAgB,OAAA;AAAE,6FAAA,EAAE,OAAA;AAAE,qGAAA,UAAU,OAAA;AAAE,mGAAA,QAAQ,OAAA","sourcesContent":["import { rulesMap } from \"./lib/rules-map\";\n\nexport default rulesMap;\n\nexport { configs } from \"./lib/config\";\nexport { createSkipWhen } from \"./lib/config-helpers/create-skip-when\";\nexport { findMonorepoRoot } from \"./lib/config/utils\";\nexport type { MatchCriteria, ProjectMetadata } from \"./lib/utils/nx-utils\";\n\nexport { strictJsdocRules } from \"./lib/config/fragments/jsdoc-rules\";\nexport { restrictedImportRules } from \"./lib/config/fragments/restricted-imports\";\nexport { globals, jsdoc, localRulesPlugin, nx, reactHooks, tsParser } from \"./lib/config/plugins\";\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ignores.js","sourceRoot":"","sources":["../../../../../../../../libs/eslint/plugin-trackunit/src/lib/config/fragments/ignores.ts"],"names":[],"mappings":";;;AAEa,QAAA,aAAa,GAAkB;IAC1C,OAAO,EAAE;QACP,oBAAoB;QACpB,qBAAqB;QACrB,kBAAkB;QAClB,sBAAsB;QACtB,kBAAkB;QAClB,iBAAiB;QACjB,mBAAmB;QACnB,kBAAkB;QAClB,4BAA4B;QAC5B,uBAAuB;QACvB,cAAc;QACd,eAAe;KAChB;CACF,CAAC","sourcesContent":["import type { Linter } from \"eslint\";\n\nexport const globalIgnores: Linter.Config = {\n ignores: [\n \"**/src/gql-api.tsx\",\n \"**/src/typings/**/*\",\n \"**/testUtils.tsx\",\n \"**/webpack.config.js\",\n \"**/jest.config.*\",\n \"**/jest.setup.*\",\n \"**/vite*.config.*\",\n \"**/vite*.setup.*\",\n \"**/src/**/generated/**/*.*\",\n \"**/src/**/generated.*\",\n \"**/dist/**/*\",\n \"**/*.docs.mdx\",\n ],\n};\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"import-rules.js","sourceRoot":"","sources":["../../../../../../../../libs/eslint/plugin-trackunit/src/lib/config/fragments/import-rules.ts"],"names":[],"mappings":";;;AACA,4EAAuE;AACvE,wCAA0C;AAE7B,QAAA,WAAW,GAAuB;IAC7C,mBAAmB,EAAE;QACnB,OAAO;QACP;YACE,cAAc,EAAE,IAAI;SACrB;KACF;IACD,gBAAgB,EAAE,KAAK;CACxB,CAAC;AAEK,MAAM,wCAAwC,GAAG,CAAC,OAAe,EAAiB,EAAE,CACzF,IAAA,iCAAc,EAAC;IACb,IAAI,EAAE,EAAE,IAAI,EAAE,CAAC,YAAY,CAAC,EAAE;IAC9B,OAAO,EAAE;QACP,UAAU,EAAE,sBAAY;KACzB;IACD,KAAK,EAAE;QACL,qCAAqC,EAAE;YACrC,OAAO;YACP;gBACE,UAAU,EAAE,OAAO;gBACnB,eAAe,EAAE;oBACf,oBAAoB;oBACpB,oBAAoB;oBACpB,iBAAiB;oBACjB,iBAAiB;oBACjB,mBAAmB;oBACnB,YAAY;oBACZ,aAAa;oBACb,eAAe;oBACf,kBAAkB;oBAClB,kBAAkB;oBAClB,iBAAiB;oBACjB,iBAAiB;oBACjB,mBAAmB;oBACnB,0BAA0B;oBAC1B,uBAAuB;oBACvB,4BAA4B;oBAC5B,kBAAkB;oBAClB,eAAe;oBACf,aAAa;oBACb,6BAA6B;oBAC7B,oBAAoB;oBACpB,6CAA6C;oBAC7C,4BAA4B;iBAC7B;gBACD,oBAAoB,EAAE,KAAK;gBAC3B,gBAAgB,EAAE,IAAI;gBACtB,mBAAmB,EAAE,IAAI;aAC1B;SACF;KACF;CACF,CAAC,CAAC;AA1CQ,QAAA,wCAAwC,4CA0ChD","sourcesContent":["import type { Linter } from \"eslint\";\nimport { createSkipWhen } from \"../../config-helpers/create-skip-when\";\nimport { importPlugin } from \"../plugins\";\n\nexport const importRules: Linter.RulesRecord = {\n \"import-x/no-cycle\": [\n \"error\",\n {\n ignoreExternal: true,\n },\n ],\n \"import-x/first\": \"off\",\n};\n\nexport const createImportExtraneousDependenciesConfig = (rootDir: string): Linter.Config =>\n createSkipWhen({\n when: { tags: [\"scope:tool\"] },\n plugins: {\n \"import-x\": importPlugin,\n },\n rules: {\n \"import-x/no-extraneous-dependencies\": [\n \"error\",\n {\n packageDir: rootDir,\n devDependencies: [\n \"**/*.spec.{ts,tsx}\",\n \"**/*.test.{ts,tsx}\",\n \"**/jest.setup.*\",\n \"**/vite.setup.*\",\n \"**/vite.config.ts\",\n \"**/test/**\",\n \"**/tests/**\",\n \"**/testing/**\",\n \"**/test-setup/**\",\n \"**/test-utils/**\",\n \"**/__tests__/**\",\n \"**/__mocks__/**\",\n \"**/mocks.{ts,tsx}\",\n \"**/core-contexts-test/**\",\n \"**/*.stories.{ts,tsx}\",\n \"**/storybookUtils.{ts,tsx}\",\n \"**/.storybook/**\",\n \"**/scripts/**\",\n \"**/tools/**\",\n \"**/*.config.{ts,js,cjs,mjs}\",\n \"**/css/tailwind/**\",\n \"**/css/tailwind-custom-properties-plugin/**\",\n \"**/css/component-tokens/**\",\n ],\n optionalDependencies: false,\n peerDependencies: true,\n bundledDependencies: true,\n },\n ],\n },\n });\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jest-overrides.js","sourceRoot":"","sources":["../../../../../../../../libs/eslint/plugin-trackunit/src/lib/config/fragments/jest-overrides.ts"],"names":[],"mappings":";;;AACA,wCAAkD;AAErC,QAAA,iBAAiB,GAAkB;IAC9C,KAAK,EAAE,CAAC,cAAc,EAAE,eAAe,CAAC;IACxC,eAAe,EAAE;QACf,WAAW,EAAE,CAAC;QACd,UAAU,EAAE,QAAQ;QACpB,aAAa,EAAE;YACb,OAAO,EAAE,CAAC,oBAAoB,CAAC;SAChC;KACF;IAED,OAAO,EAAE;QACP,IAAI,EAAJ,cAAI;QACJ,iBAAiB,EAAE,wBAAc;KAClC;IAED,KAAK,EAAE;QACL,GAAG,cAAI,CAAC,OAAO,CAAC,WAAW,CAAC,KAAK;QACjC,GAAG,cAAI,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK;QAC3B,oCAAoC,EAAE,KAAK;QAC3C,sCAAsC,EAAE,KAAK;QAC7C,0CAA0C,EAAE,KAAK;QACjD,oCAAoC,EAAE,KAAK;QAC3C,oDAAoD,EAAE,OAAO;QAC7D,YAAY,EAAE,KAAK;QACnB,uBAAuB,EAAE,KAAK;QAC9B,0BAA0B,EAAE,KAAK;QACjC,+CAA+C,EAAE,KAAK;KACvD;CACF,CAAC","sourcesContent":["import type { Linter } from \"eslint\";\nimport { jest, testingLibrary } from \"../plugins\";\n\nexport const baseJestOverrides: Linter.Config = {\n files: [\"**/*.spec.ts\", \"**/*.spec.tsx\"],\n languageOptions: {\n ecmaVersion: 5,\n sourceType: \"script\",\n parserOptions: {\n project: [\"./tsconfig.*?.json\"],\n },\n },\n\n plugins: {\n jest,\n \"testing-library\": testingLibrary,\n },\n\n rules: {\n ...jest.configs.recommended.rules,\n ...jest.configs.style.rules,\n \"@typescript-eslint/no-explicit-any\": \"off\",\n \"@typescript-eslint/no-empty-function\": \"off\",\n \"@typescript-eslint/no-non-null-assertion\": \"off\",\n \"@trackunit/no-typescript-assertion\": \"off\",\n \"@trackunit/no-jest-mock-trackunit-react-core-hooks\": \"error\",\n \"no-console\": \"off\",\n \"no-restricted-globals\": \"off\",\n \"no-restricted-properties\": \"off\",\n \"@typescript-eslint/strict-boolean-expressions\": \"off\",\n },\n};\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jsdoc-rules.js","sourceRoot":"","sources":["../../../../../../../../libs/eslint/plugin-trackunit/src/lib/config/fragments/jsdoc-rules.ts"],"names":[],"mappings":";;;AAEa,QAAA,eAAe,GAAuB;IACjD,iBAAiB,EAAE;QACjB,OAAO;QACP,OAAO;QACP;YACE,UAAU,EAAE,CAAC;SACd;KACF;IACD,uBAAuB,EAAE,OAAO;IAChC,wBAAwB,EAAE,KAAK;IAC/B,yBAAyB,EAAE,KAAK;IAChC,4BAA4B,EAAE;QAC5B,OAAO;QACP;YACE,QAAQ,EAAE;gBACR;oBACE,OAAO,EAAE,sCAAsC;oBAC/C,OAAO,EAAE,KAAK;oBACd,OAAO,EAAE,qDAAqD;iBAC/D;aACF;SACF;KACF;CACF,CAAC;AAEW,QAAA,gBAAgB,GAAuB;IAClD,qBAAqB,EAAE;QACrB,OAAO;QACP;YACE,UAAU,EAAE,IAAI;YAEhB,OAAO,EAAE;gBACP,uBAAuB,EAAE,IAAI;gBAC7B,gBAAgB,EAAE,IAAI;gBACtB,mBAAmB,EAAE,IAAI;gBACzB,kBAAkB,EAAE,IAAI;gBACxB,gBAAgB,EAAE,IAAI;aACvB;SACF;KACF;IAED,0BAA0B,EAAE;QAC1B,OAAO;QACP;YACE,YAAY,EAAE,CAAC,KAAK,CAAC;SACtB;KACF;IAED,yBAAyB,EAAE,OAAO;IAClC,4BAA4B,EAAE,OAAO;IACrC,mBAAmB,EAAE,OAAO;IAC5B,iCAAiC,EAAE,OAAO;IAC1C,oBAAoB,EAAE,OAAO;IAC7B,4BAA4B,EAAE,OAAO;IACrC,uBAAuB,EAAE,OAAO;IAChC,mBAAmB,EAAE,OAAO;IAC5B,oBAAoB,EAAE,OAAO;IAC7B,uBAAuB,EAAE,OAAO;IAChC,kBAAkB,EAAE,OAAO;IAC3B,6BAA6B,EAAE,OAAO;IACtC,wBAAwB,EAAE,OAAO;IACjC,0BAA0B,EAAE,OAAO;IACnC,wBAAwB,EAAE,OAAO;IACjC,oCAAoC,EAAE,OAAO;IAC7C,6BAA6B,EAAE,OAAO;IACtC,6BAA6B,EAAE,OAAO;IACtC,6BAA6B,EAAE,OAAO;IACtC,mCAAmC,EAAE,OAAO;IAC5C,sBAAsB,EAAE,OAAO;IAC/B,4BAA4B,EAAE,OAAO;CACtC,CAAC","sourcesContent":["import type { Linter } from \"eslint\";\n\nexport const basicJsdocRules: Linter.RulesRecord = {\n \"jsdoc/tag-lines\": [\n \"error\",\n \"never\",\n {\n startLines: 1,\n },\n ],\n \"jsdoc/check-alignment\": \"error\",\n \"prefer-arrow-functions\": \"off\",\n \"jsdoc/check-indentation\": \"off\",\n \"jsdoc/no-restricted-syntax\": [\n \"error\",\n {\n contexts: [\n {\n comment: \"JsdocBlock:has(JsdocTag[tag=/type/])\",\n context: \"any\",\n message: \"Projects should not use @type annotation in JSDocs.\",\n },\n ],\n },\n ],\n};\n\nexport const strictJsdocRules: Linter.RulesRecord = {\n \"jsdoc/require-jsdoc\": [\n \"error\",\n {\n publicOnly: true,\n\n require: {\n ArrowFunctionExpression: true,\n ClassDeclaration: true,\n FunctionDeclaration: true,\n FunctionExpression: true,\n MethodDefinition: true,\n },\n },\n ],\n\n \"jsdoc/no-undefined-types\": [\n \"error\",\n {\n definedTypes: [\"JSX\"],\n },\n ],\n\n \"jsdoc/check-param-names\": \"error\",\n \"jsdoc/require-returns-type\": \"error\",\n \"jsdoc/valid-types\": \"error\",\n \"jsdoc/require-param-description\": \"error\",\n \"jsdoc/check-access\": \"error\",\n \"jsdoc/check-property-names\": \"error\",\n \"jsdoc/check-tag-names\": \"error\",\n \"jsdoc/check-types\": \"error\",\n \"jsdoc/check-values\": \"error\",\n \"jsdoc/check-alignment\": \"error\",\n \"jsdoc/empty-tags\": \"error\",\n \"jsdoc/implements-on-classes\": \"error\",\n \"jsdoc/multiline-blocks\": \"error\",\n \"jsdoc/no-multi-asterisks\": \"error\",\n \"jsdoc/require-property\": \"error\",\n \"jsdoc/require-property-description\": \"error\",\n \"jsdoc/require-property-name\": \"error\",\n \"jsdoc/require-property-type\": \"error\",\n \"jsdoc/require-returns-check\": \"error\",\n \"jsdoc/require-returns-description\": \"error\",\n \"jsdoc/require-yields\": \"error\",\n \"jsdoc/require-yields-check\": \"error\",\n};\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"module-boundaries.js","sourceRoot":"","sources":["../../../../../../../../libs/eslint/plugin-trackunit/src/lib/config/fragments/module-boundaries.ts"],"names":[],"mappings":";;;AAEa,QAAA,mBAAmB,GAAuB;IACrD,+BAA+B,EAAE;QAC/B,OAAO;QACP;YACE,KAAK,EAAE,EAAE;YAET,cAAc,EAAE;gBACd;oBACE,SAAS,EAAE,UAAU;oBACrB,wBAAwB,EAAE,CAAC,gBAAgB,EAAE,YAAY,EAAE,cAAc,CAAC;oBAC1E,qBAAqB,EAAE,CAAC,SAAS,EAAE,eAAe,CAAC;iBACpD;gBACD;oBACE,SAAS,EAAE,gBAAgB;oBAC3B,wBAAwB,EAAE,CAAC,YAAY,EAAE,cAAc,CAAC;oBACxD,qBAAqB,EAAE,CAAC,SAAS,EAAE,eAAe,CAAC;iBACpD;gBACD;oBACE,SAAS,EAAE,YAAY;oBACvB,wBAAwB,EAAE,CAAC,YAAY,EAAE,cAAc,CAAC;oBACxD,qBAAqB,EAAE,CAAC,SAAS,EAAE,eAAe,CAAC;iBACpD;gBACD;oBACE,SAAS,EAAE,cAAc;oBACzB,wBAAwB,EAAE,CAAC,cAAc,CAAC;oBAC1C,qBAAqB,EAAE,CAAC,SAAS,EAAE,QAAQ,CAAC;iBAC7C;gBACD;oBACE,SAAS,EAAE,WAAW;oBACtB,wBAAwB,EAAE,CAAC,cAAc,EAAE,cAAc,CAAC;iBAC3D;gBACD;oBACE,SAAS,EAAE,cAAc;oBACzB,wBAAwB,EAAE,CAAC,cAAc,CAAC;iBAC3C;gBACD;oBACE,SAAS,EAAE,YAAY;oBACvB,wBAAwB,EAAE,CAAC,YAAY,CAAC;iBACzC;gBACD;oBACE,SAAS,EAAE,cAAc;oBACzB,wBAAwB,EAAE,CAAC,cAAc,CAAC;iBAC3C;gBACD;oBACE,SAAS,EAAE,iBAAiB;oBAC5B,wBAAwB,EAAE,CAAC,iBAAiB,EAAE,mBAAmB,CAAC;iBACnE;gBACD;oBACE,SAAS,EAAE,qBAAqB;oBAChC,wBAAwB,EAAE,CAAC,qBAAqB,EAAE,mBAAmB,CAAC;iBACvE;gBACD;oBACE,SAAS,EAAE,mBAAmB;oBAC9B,wBAAwB,EAAE,CAAC,mBAAmB,CAAC;iBAChD;gBACD;oBACE,SAAS,EAAE,4BAA4B;oBACvC,uBAAuB,EAAE,CAAC,YAAY,CAAC;iBACxC;gBACD;oBACE,SAAS,EAAE,cAAc;iBAC1B;gBACD;oBACE,SAAS,EAAE,YAAY;iBACxB;gBACD;oBACE,SAAS,EAAE,OAAO;iBACnB;gBACD;oBACE,SAAS,EAAE,OAAO;iBACnB;gBACD;oBACE,SAAS,EAAE,OAAO;iBACnB;gBACD;oBACE,SAAS,EAAE,OAAO;iBACnB;gBACD;oBACE,SAAS,EAAE,aAAa;oBACxB,wBAAwB,EAAE,CAAC,aAAa,CAAC;oBACzC,qBAAqB,EAAE,CAAC,WAAW,CAAC;oBACpC,uBAAuB,EAAE,CAAC,YAAY,CAAC;iBACxC;aACF;YAED,6BAA6B,EAAE,IAAI;YACnC,yBAAyB,EAAE,IAAI;SAChC;KACF;CACF,CAAC","sourcesContent":["import type { Linter } from \"eslint\";\n\nexport const moduleBoundaryRules: Linter.RulesRecord = {\n \"@nx/enforce-module-boundaries\": [\n \"error\",\n {\n allow: [],\n\n depConstraints: [\n {\n sourceTag: \"type:app\",\n onlyDependOnLibsWithTags: [\"type:extension\", \"type:react\", \"type:vanilla\"],\n bannedExternalImports: [\"i18next\", \"react-i18next\"],\n },\n {\n sourceTag: \"type:extension\",\n onlyDependOnLibsWithTags: [\"type:react\", \"type:vanilla\"],\n bannedExternalImports: [\"i18next\", \"react-i18next\"],\n },\n {\n sourceTag: \"type:react\",\n onlyDependOnLibsWithTags: [\"type:react\", \"type:vanilla\"],\n bannedExternalImports: [\"i18next\", \"react-i18next\"],\n },\n {\n sourceTag: \"type:vanilla\",\n onlyDependOnLibsWithTags: [\"type:vanilla\"],\n bannedExternalImports: [\"i18next\", \"react*\"],\n },\n {\n sourceTag: \"scope:app\",\n onlyDependOnLibsWithTags: [\"scope:client\", \"scope:server\"],\n },\n {\n sourceTag: \"scope:client\",\n onlyDependOnLibsWithTags: [\"scope:client\"],\n },\n {\n sourceTag: \"scope:tool\",\n onlyDependOnLibsWithTags: [\"scope:tool\"],\n },\n {\n sourceTag: \"scope:server\",\n onlyDependOnLibsWithTags: [\"scope:server\"],\n },\n {\n sourceTag: \"visibility:host\",\n onlyDependOnLibsWithTags: [\"visibility:host\", \"visibility:shared\"],\n },\n {\n sourceTag: \"visibility:iris-app\",\n onlyDependOnLibsWithTags: [\"visibility:iris-app\", \"visibility:shared\"],\n },\n {\n sourceTag: \"visibility:shared\",\n onlyDependOnLibsWithTags: [\"visibility:shared\"],\n },\n {\n sourceTag: \"dependencies:no-deprecated\",\n notDependOnLibsWithTags: [\"deprecated\"],\n },\n {\n sourceTag: \"gql:internal\",\n },\n {\n sourceTag: \"gql:public\",\n },\n {\n sourceTag: \"tier1\",\n },\n {\n sourceTag: \"tier2\",\n },\n {\n sourceTag: \"tier3\",\n },\n {\n sourceTag: \"tier4\",\n },\n {\n sourceTag: \"publish:npm\",\n onlyDependOnLibsWithTags: [\"publish:npm\"],\n bannedExternalImports: [\"@sentry/*\"],\n notDependOnLibsWithTags: [\"deprecated\"],\n },\n ],\n\n enforceBuildableLibDependency: true,\n banTransitiveDependencies: true,\n },\n ],\n};\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-direct-storage-access.js","sourceRoot":"","sources":["../../../../../../../../libs/eslint/plugin-trackunit/src/lib/config/fragments/no-direct-storage-access.ts"],"names":[],"mappings":";;;AACA,oCAA4C;AAE5C,MAAM,mBAAmB,GACvB,uHAAuH,CAAC;AAC1H,MAAM,qBAAqB,GACzB,6HAA6H,CAAC;AAEnH,QAAA,0BAA0B,GAAqB;IAC1D,OAAO;IACP;QACE,IAAI,EAAE,cAAc;QACpB,OAAO,EAAE,mBAAmB;KAC7B;IACD;QACE,IAAI,EAAE,gBAAgB;QACtB,OAAO,EAAE,qBAAqB;KAC/B;CACF,CAAC;AAEW,QAAA,6BAA6B,GAAqB;IAC7D,OAAO;IACP;QACE,MAAM,EAAE,QAAQ;QAChB,QAAQ,EAAE,cAAc;QACxB,OAAO,EAAE,mBAAmB;KAC7B;IACD;QACE,MAAM,EAAE,QAAQ;QAChB,QAAQ,EAAE,gBAAgB;QAC1B,OAAO,EAAE,qBAAqB;KAC/B;IACD;QACE,MAAM,EAAE,YAAY;QACpB,QAAQ,EAAE,cAAc;QACxB,OAAO,EAAE,mBAAmB;KAC7B;IACD;QACE,MAAM,EAAE,YAAY;QACpB,QAAQ,EAAE,gBAAgB;QAC1B,OAAO,EAAE,qBAAqB;KAC/B;CACF,CAAC;AAEF,MAAM,8BAA8B,GAAG;IACrC,iEAAiE;IACjE,wEAAwE;IACxE,mEAAmE;IACnE,0EAA0E;CAC3E,CAAC;AAEW,QAAA,yCAAyC,GAAkB;IACtE,QAAQ,EAAE,IAAA,wBAAgB,GAAE;IAC5B,KAAK,EAAE,8BAA8B;IACrC,KAAK,EAAE;QACL,0BAA0B,EAAE,KAAK;KAClC;CACF,CAAC","sourcesContent":["import type { Linter } from \"eslint\";\nimport { findMonorepoRoot } from \"../utils\";\n\nconst localStorageMessage =\n \"Use useLocalStorage or useLocalStorageReducer from @trackunit/react-components instead of direct localStorage access.\";\nconst sessionStorageMessage =\n \"Use useSessionStorage or useSessionStorageReducer from @trackunit/react-components instead of direct sessionStorage access.\";\n\nexport const noDirectStorageGlobalsRule: Linter.RuleEntry = [\n \"error\",\n {\n name: \"localStorage\",\n message: localStorageMessage,\n },\n {\n name: \"sessionStorage\",\n message: sessionStorageMessage,\n },\n];\n\nexport const noDirectStoragePropertiesRule: Linter.RuleEntry = [\n \"error\",\n {\n object: \"window\",\n property: \"localStorage\",\n message: localStorageMessage,\n },\n {\n object: \"window\",\n property: \"sessionStorage\",\n message: sessionStorageMessage,\n },\n {\n object: \"globalThis\",\n property: \"localStorage\",\n message: localStorageMessage,\n },\n {\n object: \"globalThis\",\n property: \"sessionStorage\",\n message: sessionStorageMessage,\n },\n];\n\nconst storageHookImplementationFiles = [\n \"libs/react/components/src/hooks/localStorage/useLocalStorage.ts\",\n \"libs/react/components/src/hooks/localStorage/useLocalStorageReducer.ts\",\n \"libs/react/components/src/hooks/localStorage/useSessionStorage.ts\",\n \"libs/react/components/src/hooks/localStorage/useSessionStorageReducer.ts\",\n];\n\nexport const noDirectStoragePropertyExceptionOverrides: Linter.Config = {\n basePath: findMonorepoRoot(),\n files: storageHookImplementationFiles,\n rules: {\n \"no-restricted-properties\": \"off\",\n },\n};\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"react-rules.js","sourceRoot":"","sources":["../../../../../../../../libs/eslint/plugin-trackunit/src/lib/config/fragments/react-rules.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Linter } from \"eslint\";\n\nexport const reactRules: Linter.RulesRecord = {\n \"react-hooks/rules-of-hooks\": \"error\",\n \"react-hooks/exhaustive-deps\": \"error\",\n\n \"react-hooks/config\": \"error\",\n \"react-hooks/error-boundaries\": \"error\",\n \"react-hooks/component-hook-factories\": \"error\",\n \"react-hooks/gating\": \"error\",\n \"react-hooks/globals\": \"error\",\n \"react-hooks/set-state-in-render\": \"error\",\n \"react-hooks/use-memo\": \"error\",\n \"react/self-closing-comp\": \"error\",\n \"react-hooks/unsupported-syntax\": \"error\",\n \"react-hooks/static-components\": \"error\",\n \"react-hooks/purity\": \"error\",\n\n \"react-hooks/immutability\": \"warn\",\n \"react/no-unstable-nested-components\": \"warn\",\n \"react-hooks/refs\": \"warn\",\n \"react-hooks/set-state-in-effect\": \"warn\",\n \"react-hooks/preserve-manual-memoization\": \"warn\",\n \"react-hooks/incompatible-library\": \"warn\",\n\n \"react/jsx-curly-brace-presence\": [\n \"error\",\n {\n children: \"never\",\n propElementValues: \"always\",\n props: \"never\",\n },\n ],\n\n \"react/jsx-key\": \"error\",\n \"react/jsx-no-leaked-render\": \"error\",\n \"react/jsx-uses-react\": \"error\",\n \"react/jsx-uses-vars\": \"error\",\n \"react/no-danger\": \"error\",\n \"react/no-unused-prop-types\": \"error\",\n \"react/jsx-sort-props\": \"error\",\n\n \"react/no-children-prop\": [\n \"error\",\n {\n allowFunctions: false,\n },\n ],\n};\n\nexport const reactCustomRules: Linter.RulesRecord = {\n \"@trackunit/no-template-strings-in-classname-prop\": \"error\",\n \"@trackunit/require-classname-alternatives\": [\n \"error\",\n {\n alternatives: {\n slate: [\"neutral\"],\n gray: [\"neutral\"],\n zinc: [\"neutral\"],\n stone: [\"neutral\"],\n teal: [\"cyan\"],\n purple: [\"violet\"],\n fuchsia: [\"pink\"],\n red: [\"danger\"],\n yellow: [\"warning\"],\n green: [\"success\"],\n emerald: [\"success\"],\n amber: [\"warning\", \"low\", \"idle\"],\n sky: [\"primary\", \"info\"],\n blue: [\"primary\", \"info\", \"working\", \"utilized\"],\n indigo: [\"primary\", \"violet\"],\n rose: [\"danger\", \"pink\"],\n },\n prefixes: [\n \"bg\",\n \"text\",\n \"border\",\n \"border-t\",\n \"border-r\",\n \"border-b\",\n \"border-l\",\n \"border-x\",\n \"border-y\",\n \"ring\",\n \"ring-offset\",\n \"outline\",\n \"divide\",\n \"shadow\",\n \"accent\",\n \"caret\",\n \"fill\",\n \"stroke\",\n \"decoration\",\n \"placeholder\",\n \"from\",\n \"via\",\n \"to\",\n ],\n },\n ],\n \"@trackunit/require-list-item-virtualization-props\": \"error\",\n \"@trackunit/cva-merge-base-classes-as-array\": \"error\",\n \"@trackunit/design-guideline-button-icon-size-match\": \"error\",\n \"@trackunit/prefer-destructured-imports\": [\n \"error\",\n {\n packages: {\n react: \"React\",\n },\n },\n ],\n \"@trackunit/require-optional-prop-initialization\": \"error\",\n \"@trackunit/prefer-event-specific-callback-naming\": [\n \"error\",\n {\n events: [\"onClick\", \"onSubmit\", \"onDoubleClick\"],\n },\n ],\n \"@trackunit/prefer-mouse-event-handler-in-react-props\": [\n \"error\",\n {\n allowedNames: [\"onClickClose\"],\n },\n ],\n \"@trackunit/prefer-field-components\": \"error\",\n \"@trackunit/one-component-per-file\": \"error\",\n \"@trackunit/component-name-matches-filename\": [\n \"warn\",\n {\n allowedMismatches: [\n // i18next convention: every library's translation.tsx exports a `Trans` wrapper\n // named after the library component, not the file.\n { file: \"translation\", component: \"Trans\" },\n // React context pattern: *Context files always contain both the context object and\n // the provider component. The provider can't be renamed to match the file because\n // the context object already uses that name.\n { file: \"*Context\", component: \"*Provider\" },\n ],\n },\n ],\n};\n\nexport const reactTestingLibraryOverrides: Linter.Config = {\n files: [\"**/*.spec.ts\", \"**/*.spec.tsx\"],\n rules: {\n \"jest/no-commented-out-tests\": \"error\",\n \"jest/expect-expect\": \"error\",\n },\n};\n\nexport const reactStoryOverrides: Linter.Config = {\n files: [\"**/*.stories.ts\", \"**/*.stories.tsx\"],\n rules: {\n \"jsdoc/require-jsdoc\": \"off\",\n \"no-console\": \"off\",\n \"@typescript-eslint/no-empty-function\": \"off\",\n },\n};\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"restricted-imports.js","sourceRoot":"","sources":["../../../../../../../../libs/eslint/plugin-trackunit/src/lib/config/fragments/restricted-imports.ts"],"names":[],"mappings":";;;AAEa,QAAA,qBAAqB,GAAuB;IACvD,uBAAuB,EAAE;QACvB,OAAO;QACP;YACE,KAAK,EAAE;gBACL;oBACE,IAAI,EAAE,sBAAsB;oBAC5B,OAAO,EAAE,2DAA2D;iBACrE;gBACD;oBACE,IAAI,EAAE,eAAe;oBACrB,WAAW,EAAE,CAAC,gBAAgB,CAAC;oBAC/B,OAAO,EAAE,gFAAgF;iBAC1F;gBACD;oBACE,IAAI,EAAE,eAAe;oBACrB,WAAW,EAAE,CAAC,OAAO,CAAC;oBACtB,OAAO,EAAE,uEAAuE;iBACjF;gBACD;oBACE,IAAI,EAAE,gBAAgB;oBACtB,WAAW,EAAE,CAAC,UAAU,EAAE,cAAc,CAAC;oBACzC,OAAO,EACL,mHAAmH;iBACtH;gBACD;oBACE,IAAI,EAAE,oBAAoB;oBAC1B,OAAO,EAAE,+EAA+E;iBACzF;gBACD;oBACE,IAAI,EAAE,2BAA2B;oBACjC,OAAO,EAAE,8DAA8D;iBACxE;gBACD;oBACE,IAAI,EAAE,6BAA6B;oBACnC,OAAO,EAAE,8DAA8D;iBACxE;gBACD;oBACE,IAAI,EAAE,0BAA0B;oBAChC,OAAO,EACL,0HAA0H;iBAC7H;aACF;YAED,QAAQ,EAAE;gBACR;oBACE,KAAK,EAAE,CAAC,WAAW,CAAC;oBACpB,OAAO,EAAE,sFAAsF;iBAChG;gBACD;oBACE,KAAK,EAAE,CAAC,cAAc,CAAC;oBACvB,OAAO,EAAE,sFAAsF;iBAChG;aACF;SACF;KACF;CACF,CAAC","sourcesContent":["import type { Linter } from \"eslint\";\n\nexport const restrictedImportRules: Linter.RulesRecord = {\n \"no-restricted-imports\": [\n \"error\",\n {\n paths: [\n {\n name: \"react-dom/test-utils\",\n message: \"Please use 'act' from the @testing-library/react instead.\",\n },\n {\n name: \"react-i18next\",\n importNames: [\"useTranslation\"],\n message: \"Please import useTranslation from @trackunit/i18n-manager-translation instead.\",\n },\n {\n name: \"react-i18next\",\n importNames: [\"Trans\"],\n message: \"Please import Trans from @trackunit/i18n-manager-translation instead.\",\n },\n {\n name: \"@apollo/client\",\n importNames: [\"useQuery\", \"useLazyQuery\"],\n message:\n \"Please import the same from @trackunit/react-graphql-hooks instead, to ensure loading state is handled correctly.\",\n },\n {\n name: \"@nx/plugin/testing\",\n message: \"Please import it from @trackunit/nx-utils instead or expose it from that lib.\",\n },\n {\n name: \"@heroicons/react/20/solid\",\n message: \"Please use the Icon component from react-components instead.\",\n },\n {\n name: \"@heroicons/react/24/outline\",\n message: \"Please use the Icon component from react-components instead.\",\n },\n {\n name: \"class-variance-authority\",\n message:\n \"Import our wrappers from, @trackunit/css-class-variance-utilities or twMerge instead. [cva -> cvaMerge], [cx -> twMerge]\",\n },\n ],\n\n patterns: [\n {\n group: [\"date-fns*\"],\n message: \"Please use @trackunit/date-and-time-utils or @trackunit/date-and-time-hooks instead.\",\n },\n {\n group: [\"date-fns-tz*\"],\n message: \"Please use @trackunit/date-and-time-utils or @trackunit/date-and-time-hooks instead.\",\n },\n ],\n },\n ],\n};\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"testing-library.js","sourceRoot":"","sources":["../../../../../../../../libs/eslint/plugin-trackunit/src/lib/config/fragments/testing-library.ts"],"names":[],"mappings":";;;AACA,wCAA4C;AAE5C,MAAM,WAAW,GAAG,wBAAc,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC;AAEhD,QAAA,wBAAwB,GAAuB,MAAM,CAAC,WAAW,CAC5E,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,EAAuC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,SAAS,CAAC,CAC3G,CAAC","sourcesContent":["import type { Linter } from \"eslint\";\nimport { testingLibrary } from \"../plugins\";\n\nconst configRules = testingLibrary.configs.react.rules ?? {};\n\nexport const reactTestingLibraryRules: Linter.RulesRecord = Object.fromEntries(\n Object.entries(configRules).filter((entry): entry is [string, Linter.RuleEntry] => entry[1] !== undefined)\n);\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"typescript-rules.js","sourceRoot":"","sources":["../../../../../../../../libs/eslint/plugin-trackunit/src/lib/config/fragments/typescript-rules.ts"],"names":[],"mappings":";;;AAEa,QAAA,eAAe,GAAuB;IACjD,oCAAoC,EAAE,OAAO;IAC7C,wCAAwC,EAAE,OAAO;IACjD,uCAAuC,EAAE,OAAO;IAChD,6CAA6C,EAAE,OAAO;IACtD,gBAAgB,EAAE,KAAK;IACvB,mCAAmC,EAAE;QACnC,OAAO;QACP;YACE,IAAI,EAAE,KAAK;YACX,iBAAiB,EAAE,IAAI;YACvB,YAAY,EAAE,KAAK;YACnB,yBAAyB,EAAE,IAAI;YAC/B,8BAA8B,EAAE,IAAI;YACpC,iBAAiB,EAAE,IAAI;YACvB,kBAAkB,EAAE,IAAI;SACzB;KACF;IACD,+BAA+B,EAAE;QAC/B,OAAO;QACP;YACE,OAAO,EAAE,SAAS;SACnB;KACF;IACD,iCAAiC,EAAE,CAAC,OAAO,EAAE,EAAE,cAAc,EAAE,KAAK,EAAE,CAAC;IACvE,8BAA8B,EAAE;QAC9B,OAAO;QACP;YACE,KAAK,EAAE,KAAK;SACb;KACF;IACD,+CAA+C,EAAE;QAC/C,MAAM;QACN;YACE,oBAAoB,EAAE,IAAI;YAC1B,mBAAmB,EAAE,IAAI;SAC1B;KACF;IACD,sCAAsC,EAAE;QACtC,OAAO;QACP;YACE,QAAQ,EAAE,WAAW;YACrB,MAAM,EAAE,CAAC,YAAY,CAAC;YAEtB,MAAM,EAAE;gBACN,KAAK,EAAE,SAAS;gBAChB,KAAK,EAAE,KAAK;aACb;SACF;QACD;YACE,QAAQ,EAAE,eAAe;YACzB,MAAM,EAAE,CAAC,YAAY,CAAC;YAEtB,MAAM,EAAE;gBACN,KAAK,EAAE,2BAA2B;gBAClC,KAAK,EAAE,IAAI;aACZ;SACF;KACF;IACD,0CAA0C,EAAE,MAAM;IAClD,sCAAsC,EAAE,OAAO;IAC/C,0CAA0C,EAAE,OAAO;IACnD,iCAAiC,EAAE,OAAO;IAC1C,mCAAmC,EAAE,MAAM;IAC3C,mCAAmC,EAAE,MAAM;IAC3C,oCAAoC,EAAE,OAAO;IAC7C,yCAAyC,EAAE,OAAO;IAClD,yCAAyC,EAAE,OAAO;IAClD,kDAAkD,EAAE;QAClD,OAAO;QACP;YACE,aAAa,EAAE,UAAU;YACzB,SAAS,EAAE;gBACT,SAAS,EAAE,UAAU;gBACrB,YAAY,EAAE,UAAU;gBACxB,mBAAmB,EAAE,UAAU;aAChC;SACF;KACF;IACD,kDAAkD,EAAE,OAAO;IAC3D,uCAAuC,EAAE,MAAM;IAC/C,wCAAwC,EAAE;QACxC,OAAO;QACP;YACE,KAAK,EAAE;gBACL,UAAU,EAAE;oBACV,OAAO,EAAE,6CAA6C;iBACvD;gBAED,EAAE,EAAE;oBACF,OAAO,EAAE,6CAA6C;iBACvD;aACF;SACF;KACF;CACF,CAAC","sourcesContent":["import type { Linter } from \"eslint\";\n\nexport const typescriptRules: Linter.RulesRecord = {\n \"@typescript-eslint/no-explicit-any\": \"error\",\n \"@typescript-eslint/no-inferrable-types\": \"error\",\n \"@typescript-eslint/unified-signatures\": \"error\",\n \"@typescript-eslint/no-unnecessary-condition\": \"error\",\n \"no-unused-vars\": \"off\",\n \"@typescript-eslint/no-unused-vars\": [\n \"error\",\n {\n args: \"all\",\n argsIgnorePattern: \"^_\",\n caughtErrors: \"all\",\n caughtErrorsIgnorePattern: \"^_\",\n destructuredArrayIgnorePattern: \"^_\",\n varsIgnorePattern: \"^_\",\n ignoreRestSiblings: true,\n },\n ],\n \"@typescript-eslint/array-type\": [\n \"error\",\n {\n default: \"generic\",\n },\n ],\n \"@typescript-eslint/no-redeclare\": [\"error\", { builtinGlobals: false }],\n \"@typescript-eslint/no-shadow\": [\n \"error\",\n {\n hoist: \"all\",\n },\n ],\n \"@typescript-eslint/strict-boolean-expressions\": [\n \"warn\",\n {\n allowNullableBoolean: true,\n allowNullableString: true,\n },\n ],\n \"@typescript-eslint/naming-convention\": [\n \"error\",\n {\n selector: \"interface\",\n format: [\"PascalCase\"],\n\n custom: {\n regex: \"^I[A-Z]\",\n match: false,\n },\n },\n {\n selector: \"typeParameter\",\n format: [\"PascalCase\"],\n\n custom: {\n regex: \"^(T|Keys?)[A-Z][a-zA-Z]+$\",\n match: true,\n },\n },\n ],\n \"@typescript-eslint/no-non-null-assertion\": \"warn\",\n \"@typescript-eslint/no-empty-function\": \"error\",\n \"@typescript-eslint/no-unused-expressions\": \"error\",\n \"@typescript-eslint/dot-notation\": \"error\",\n \"@typescript-eslint/await-thenable\": \"warn\",\n \"@typescript-eslint/ban-ts-comment\": \"warn\",\n \"@typescript-eslint/member-ordering\": \"error\",\n \"@typescript-eslint/no-empty-object-type\": \"error\",\n \"@typescript-eslint/no-floating-promises\": \"error\",\n \"@typescript-eslint/explicit-member-accessibility\": [\n \"error\",\n {\n accessibility: \"explicit\",\n overrides: {\n accessors: \"explicit\",\n constructors: \"explicit\",\n parameterProperties: \"explicit\",\n },\n },\n ],\n \"@typescript-eslint/no-unnecessary-type-assertion\": \"error\",\n \"@typescript-eslint/no-require-imports\": \"warn\",\n \"@typescript-eslint/no-restricted-types\": [\n \"error\",\n {\n types: {\n \"React.FC\": {\n message: \"Please use props interface or type instead.\",\n },\n\n FC: {\n message: \"Please use props interface or type instead.\",\n },\n },\n },\n ],\n};\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../../libs/eslint/plugin-trackunit/src/lib/config/index.ts"],"names":[],"mappings":";;;AAAA,yCAAsC;AACtC,2CAA8C;AAEjC,QAAA,OAAO,GAAG;IACrB,IAAI,EAAJ,WAAI;IACJ,KAAK,EAAE,mBAAW;CACnB,CAAC","sourcesContent":["import { base } from \"./presets/base\";\nimport { reactPreset } from \"./presets/react\";\n\nexport const configs = {\n base,\n react: reactPreset,\n};\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugins.js","sourceRoot":"","sources":["../../../../../../../libs/eslint/plugin-trackunit/src/lib/config/plugins.ts"],"names":[],"mappings":";;;;AAAA;;;;;;;;GAQG;AACH,8DAAwC;AAwBtC,gBAAE;AAvBJ,2FAAqE;AA4BnE,4CAAgB;AA3BlB,4EAAsD;AA0BpD,4BAAQ;AAzBV,+EAA+D;AAc7D,+BAdK,cAAoB,CAcL;AAbtB,2EAAqD;AAenD,oCAAY;AAdd,iEAA2C;AAezC,oBAAI;AAdN,mEAA6C;AAe3C,sBAAK;AAdP,sEAAgD;AAgB9C,wBAAM;AAfR,mEAA6C;AAiB3C,sBAAK;AAhBP,8EAAwD;AAiBtD,gCAAU;AAhBZ,sFAAgE;AAiB9D,wCAAc;AAhBhB,yDAAmC;AAOjC,0BAAO;AANT,yEAAmD;AAUjD,kCAAW;AATb,4CAAwC;AAE3B,QAAA,gBAAgB,GAAG,EAAE,KAAK,EAAE,oBAAQ,EAAE,CAAC","sourcesContent":["/**\n * Shared plugin instances for ESLint flat config.\n *\n * ESLint flat config requires that the same plugin name always maps to the same\n * object reference. With TypeScript's __importStar() helper (from esModuleInterop),\n * each file that does `import * as foo from \"pkg\"` gets its own wrapper object.\n * By importing all plugins once here and re-exporting, all presets share the same\n * object references.\n */\nimport * as nx from \"@nx/eslint-plugin\";\nimport * as typescriptEslint from \"@typescript-eslint/eslint-plugin\";\nimport * as tsParser from \"@typescript-eslint/parser\";\nimport eslintConfigPrettier from \"eslint-config-prettier/flat\";\nimport * as importPlugin from \"eslint-plugin-import\";\nimport * as jest from \"eslint-plugin-jest\";\nimport * as jsdoc from \"eslint-plugin-jsdoc\";\nimport * as noNull from \"eslint-plugin-no-null\";\nimport * as react from \"eslint-plugin-react\";\nimport * as reactHooks from \"eslint-plugin-react-hooks\";\nimport * as testingLibrary from \"eslint-plugin-testing-library\";\nimport * as globals from \"globals\";\nimport * as jsoncParser from \"jsonc-eslint-parser\";\nimport { rulesMap } from \"../rules-map\";\n\nexport const localRulesPlugin = { rules: rulesMap };\nexport {\n eslintConfigPrettier,\n globals,\n importPlugin,\n jest,\n jsdoc,\n jsoncParser,\n noNull,\n nx,\n react,\n reactHooks,\n testingLibrary,\n tsParser,\n typescriptEslint,\n};\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base.js","sourceRoot":"","sources":["../../../../../../../../libs/eslint/plugin-trackunit/src/lib/config/presets/base.ts"],"names":[],"mappings":"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","sourcesContent":["import { createSkipWhen } from \"../../config-helpers/create-skip-when\";\n\nimport { globalIgnores } from \"../fragments/ignores\";\nimport { importRules } from \"../fragments/import-rules\";\nimport { baseJestOverrides } from \"../fragments/jest-overrides\";\nimport { basicJsdocRules } from \"../fragments/jsdoc-rules\";\nimport { moduleBoundaryRules } from \"../fragments/module-boundaries\";\nimport { noDirectStorageGlobalsRule } from \"../fragments/no-direct-storage-access\";\nimport { restrictedImportRules } from \"../fragments/restricted-imports\";\nimport { typescriptRules } from \"../fragments/typescript-rules\";\nimport {\n eslintConfigPrettier,\n importPlugin,\n jsdoc,\n jsoncParser,\n localRulesPlugin,\n noNull,\n nx,\n tsParser,\n typescriptEslint,\n} from \"../plugins\";\nimport { findMonorepoRoot } from \"../utils\";\n\nexport const base = [\n globalIgnores,\n {\n plugins: {\n \"@nx\": nx,\n \"@trackunit\": localRulesPlugin,\n \"@typescript-eslint\": typescriptEslint,\n \"no-null\": noNull,\n \"import-x\": importPlugin,\n jsdoc,\n },\n\n rules: {\n ...moduleBoundaryRules,\n ...restrictedImportRules,\n },\n },\n createSkipWhen({\n when: { tags: [\"scope:tool\"] },\n plugins: {\n \"import-x\": importPlugin,\n },\n rules: {\n \"import-x/no-extraneous-dependencies\": [\n \"error\",\n {\n packageDir: findMonorepoRoot(),\n devDependencies: [\n \"**/*.spec.{ts,tsx}\",\n \"**/*.test.{ts,tsx}\",\n \"**/jest.setup.*\",\n \"**/test/**\",\n \"**/tests/**\",\n \"**/testing/**\",\n \"**/test-setup/**\",\n \"**/test-utils/**\",\n \"**/vite.setup.*\",\n \"**/vite.config.ts\",\n \"**/__tests__/**\",\n \"**/__mocks__/**\",\n \"**/mocks.{ts,tsx}\",\n \"**/core-contexts-test/**\",\n \"**/*.stories.{ts,tsx}\",\n \"**/storybookUtils.{ts,tsx}\",\n \"**/.storybook/**\",\n \"**/scripts/**\",\n \"**/tools/**\",\n \"**/*.config.{ts,js,cjs,mjs}\",\n \"**/css/tailwind/**\",\n \"**/css/tailwind-custom-properties-plugin/**\",\n \"**/css/component-tokens/**\",\n ],\n optionalDependencies: false,\n peerDependencies: true,\n bundledDependencies: true,\n },\n ],\n },\n }),\n {\n files: [\"**/*.ts\", \"**/*.tsx\", \"**/*.js\", \"**/*.jsx\"],\n\n languageOptions: {\n ecmaVersion: 5,\n sourceType: \"script\",\n parser: tsParser,\n parserOptions: {\n project: [\"./tsconfig.*?.json\"],\n },\n },\n rules: {\n \"constructor-super\": \"error\",\n curly: \"error\",\n \"default-case\": \"error\",\n \"id-match\": \"error\",\n \"no-caller\": \"error\",\n \"no-debugger\": \"error\",\n \"no-duplicate-imports\": \"error\",\n \"no-empty\": \"error\",\n \"no-eval\": \"error\",\n \"no-console\": \"error\",\n \"no-var\": \"error\",\n \"prefer-const\": \"error\",\n \"no-template-curly-in-string\": \"error\",\n eqeqeq: [\"error\", \"always\"],\n \"no-undef-init\": \"error\",\n \"no-invalid-this\": \"off\",\n \"no-null/no-null\": \"off\",\n \"no-underscore-dangle\": \"off\",\n \"no-redeclare\": \"off\",\n \"no-empty-function\": \"off\",\n \"no-unused-expressions\": \"off\",\n \"no-shadow\": \"off\",\n\n ...basicJsdocRules,\n\n \"no-restricted-globals\": noDirectStorageGlobalsRule,\n\n \"@trackunit/no-internal-barrel-files\": \"error\",\n \"@trackunit/no-typescript-assertion\": \"warn\",\n\n ...importRules,\n\n ...typescriptRules,\n },\n },\n {\n files: [\"**/project.json\"],\n languageOptions: {\n parser: jsoncParser,\n },\n plugins: {\n \"@trackunit\": localRulesPlugin,\n },\n rules: {\n \"@trackunit/no-internal-graphql-when-tagged-with-gql-public\": \"error\",\n \"@trackunit/no-deprecated-graphql-fields\": \"warn\",\n },\n },\n baseJestOverrides,\n {\n files: [\n \"**/eslint.config.cjs\",\n \"**/iris-app-manifest.ts\",\n \"**/rspack.config.ts\",\n \"**/rspack.config.js\",\n \"**/webpack.config.ts\",\n ],\n rules: {\n \"@typescript-eslint/no-require-imports\": \"off\",\n },\n },\n {\n files: [\"**/eslint.config.cjs\"],\n rules: {\n \"@nx/enforce-module-boundaries\": \"off\",\n },\n },\n eslintConfigPrettier,\n {\n files: [\"**/*.stories.{ts,tsx,js,jsx}\", \"**/*.demo.{ts,tsx,js,jsx}\"],\n rules: {\n \"@nx/enforce-module-boundaries\": \"off\",\n },\n },\n];\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"e2e.js","sourceRoot":"","sources":["../../../../../../../../libs/eslint/plugin-trackunit/src/lib/config/presets/e2e.ts"],"names":[],"mappings":";;;AAAa,QAAA,GAAG,GAAG;IACjB;QACE,KAAK,EAAE,CAAC,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,CAAC;QAErD,eAAe,EAAE;YACf,WAAW,EAAE,CAAC;YACd,UAAU,EAAE,QAAQ;YAEpB,aAAa,EAAE;gBACb,OAAO,EAAE,CAAC,oBAAoB,EAAE,iBAAiB,EAAE,4BAA4B,CAAC;aACjF;SACF;KACF;IACD;QACE,KAAK,EAAE,CAAC,oBAAoB,EAAE,qBAAqB,CAAC;QACpD,KAAK,EAAE;YACL,uCAAuC,EAAE,KAAK;YAC9C,gCAAgC,EAAE,KAAK;YACvC,8BAA8B,EAAE,KAAK;YACrC,iDAAiD,EAAE,KAAK;YACxD,wCAAwC,EAAE,KAAK;SAChD;KACF;CACF,CAAC","sourcesContent":["export const e2e = [\n {\n files: [\"**/*.ts\", \"**/*.tsx\", \"**/*.js\", \"**/*.jsx\"],\n\n languageOptions: {\n ecmaVersion: 5,\n sourceType: \"script\",\n\n parserOptions: {\n project: [\"./tsconfig.*?.json\", \"./tsconfig.json\", \"./playwright/tsconfig.json\"],\n },\n },\n },\n {\n files: [\"playwright/**/*.ts\", \"playwright/**/*.tsx\"],\n rules: {\n \"testing-library/prefer-screen-queries\": \"off\",\n \"testing-library/no-node-access\": \"off\",\n \"testing-library/no-container\": \"off\",\n \"testing-library/render-result-naming-convention\": \"off\",\n \"testing-library/no-render-in-lifecycle\": \"off\",\n },\n },\n];\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"react.js","sourceRoot":"","sources":["../../../../../../../../libs/eslint/plugin-trackunit/src/lib/config/presets/react.ts"],"names":[],"mappings":";;;AAAA,oFAG+C;AAC/C,0DAAwE;AACxE,kEAAwE;AACxE,wCAWoB;AAEP,QAAA,WAAW,GAAG;IACzB;QACE,OAAO,EAAE;YACP,YAAY,EAAE,0BAAgB;YAC9B,oBAAoB,EAAE,0BAAgB;YACtC,KAAK,EAAL,eAAK;YACL,KAAK,EAAL,eAAK;YACL,aAAa,EAAE,oBAAU;YACzB,iBAAiB,EAAE,wBAAc;YACjC,KAAK,EAAE,YAAE;SACV;QAED,QAAQ,EAAE;YACR,KAAK,EAAE;gBACL,OAAO,EAAE,QAAQ;aAClB;SACF;QACD,eAAe,EAAE;YACf,OAAO,EAAE;gBACP,GAAG,iBAAO,CAAC,OAAO;gBAClB,GAAG,cAAI,CAAC,YAAY,CAAC,OAAO,CAAC,OAAO;gBACpC,GAAG,iBAAO,CAAC,IAAI;gBACf,IAAI,EAAE,UAAU;gBAChB,MAAM,EAAE,UAAU;aACnB;YACD,MAAM,EAAE,kBAAQ;YAChB,WAAW,EAAE,IAAI;YACjB,UAAU,EAAE,UAAU;YACtB,aAAa,EAAE;gBACb,YAAY,EAAE;oBACZ,GAAG,EAAE,IAAI;iBACV;aACF;SACF;KACF;IACD;QACE,KAAK,EAAE,CAAC,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,CAAC;QACrD,KAAK,EAAE;YACL,GAAG,8BAAgB;YAEnB,yBAAyB,EAAE;gBACzB,OAAO;gBACP;oBACE,GAAG,EAAE,CAAC;iBACP;aACF;YAED,gBAAgB,EAAE,OAAO;YACzB,eAAe,EAAE,OAAO;YAExB,GAAG,wBAAU;YAEb,sBAAsB,EAAE;gBACtB,MAAM;gBACN;oBACE,QAAQ,EAAE,mBAAmB;oBAC7B,OAAO,EAAE,8DAA8D;iBACxE;aACF;YAED,0BAA0B,EAAE,wDAA6B;SAC1D;KACF;IACD,oEAAyC;IACzC;QACE,KAAK,EAAE,CAAC,iBAAiB,EAAE,kBAAkB,CAAC;QAC9C,KAAK,EAAE;YACL,qBAAqB,EAAE,KAAK;YAC5B,YAAY,EAAE,KAAK;YACnB,sCAAsC,EAAE,KAAK;YAC7C,mCAAmC,EAAE,KAAK;YAC1C,4CAA4C,EAAE,KAAK;YAEnD,2EAA2E;YAC3E,kFAAkF;YAClF,kDAAkD,EAAE,OAAO;SAC5D;KACF;IACD;QACE,KAAK,EAAE,CAAC,cAAc,EAAE,eAAe,EAAE,cAAc,EAAE,eAAe,CAAC;QACzE,KAAK,EAAE;YACL,mCAAmC,EAAE,KAAK;YAC1C,4CAA4C,EAAE,KAAK;YACnD,0BAA0B,EAAE,KAAK;SAClC;KACF;IACD;QACE,KAAK,EAAE,CAAC,cAAc,EAAE,eAAe,CAAC;QAExC,OAAO,EAAE;YACP,IAAI,EAAJ,cAAI;YACJ,iBAAiB,EAAE,wBAAc;SAClC;QACD,eAAe,EAAE;YACf,OAAO,EAAE;gBACP,GAAG,iBAAO,CAAC,OAAO;gBAClB,GAAG,cAAI,CAAC,YAAY,CAAC,OAAO,CAAC,OAAO;gBACpC,GAAG,iBAAO,CAAC,IAAI;gBACf,IAAI,EAAE,UAAU;gBAChB,MAAM,EAAE,UAAU;aACnB;YAED,MAAM,EAAE,kBAAQ;SACjB;QAED,KAAK,EAAE;YACL,GAAG,cAAI,CAAC,OAAO,CAAC,WAAW,CAAC,KAAK;YACjC,GAAG,cAAI,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK;YAC3B,GAAG,0CAAwB;YAC3B,6BAA6B,EAAE,OAAO;YACtC,oBAAoB,EAAE,OAAO;SAC9B;KACF;CACF,CAAC","sourcesContent":["import {\n noDirectStoragePropertiesRule,\n noDirectStoragePropertyExceptionOverrides,\n} from \"../fragments/no-direct-storage-access\";\nimport { reactCustomRules, reactRules } from \"../fragments/react-rules\";\nimport { reactTestingLibraryRules } from \"../fragments/testing-library\";\nimport {\n globals,\n jest,\n jsdoc,\n localRulesPlugin,\n nx,\n react,\n reactHooks,\n testingLibrary,\n tsParser,\n typescriptEslint,\n} from \"../plugins\";\n\nexport const reactPreset = [\n {\n plugins: {\n \"@trackunit\": localRulesPlugin,\n \"@typescript-eslint\": typescriptEslint,\n jsdoc,\n react,\n \"react-hooks\": reactHooks,\n \"testing-library\": testingLibrary,\n \"@nx\": nx,\n },\n\n settings: {\n react: {\n version: \"detect\",\n },\n },\n languageOptions: {\n globals: {\n ...globals.browser,\n ...jest.environments.globals.globals,\n ...globals.node,\n Text: \"writable\",\n screen: \"writable\",\n },\n parser: tsParser,\n ecmaVersion: 2022,\n sourceType: \"commonjs\",\n parserOptions: {\n ecmaFeatures: {\n jsx: true,\n },\n },\n },\n },\n {\n files: [\"**/*.ts\", \"**/*.tsx\", \"**/*.js\", \"**/*.jsx\"],\n rules: {\n ...reactCustomRules,\n\n \"no-multiple-empty-lines\": [\n \"error\",\n {\n max: 1,\n },\n ],\n\n \"no-unreachable\": \"error\",\n \"prefer-spread\": \"error\",\n\n ...reactRules,\n\n \"no-restricted-syntax\": [\n \"warn\",\n {\n selector: \"TSEnumDeclaration\",\n message: \"Please use string literal union or objects instead of enums.\",\n },\n ],\n\n \"no-restricted-properties\": noDirectStoragePropertiesRule,\n },\n },\n noDirectStoragePropertyExceptionOverrides,\n {\n files: [\"**/*.stories.ts\", \"**/*.stories.tsx\"],\n rules: {\n \"jsdoc/require-jsdoc\": \"off\",\n \"no-console\": \"off\",\n \"@typescript-eslint/no-empty-function\": \"off\",\n \"@trackunit/one-component-per-file\": \"off\",\n \"@trackunit/component-name-matches-filename\": \"off\",\n\n // Every Storybook folder implied by a story title must have a landing page\n // (*.docs.mdx with a matching <Meta title>). See docs/STORYBOOK-LANDING-PAGES.md.\n \"@trackunit/require-storybook-folder-landing-page\": \"error\",\n },\n },\n {\n files: [\"**/*.spec.ts\", \"**/*.spec.tsx\", \"**/*.test.ts\", \"**/*.test.tsx\"],\n rules: {\n \"@trackunit/one-component-per-file\": \"off\",\n \"@trackunit/component-name-matches-filename\": \"off\",\n \"no-restricted-properties\": \"off\",\n },\n },\n {\n files: [\"**/*.spec.ts\", \"**/*.spec.tsx\"],\n\n plugins: {\n jest,\n \"testing-library\": testingLibrary,\n },\n languageOptions: {\n globals: {\n ...globals.browser,\n ...jest.environments.globals.globals,\n ...globals.node,\n Text: \"writable\",\n screen: \"writable\",\n },\n\n parser: tsParser,\n },\n\n rules: {\n ...jest.configs.recommended.rules,\n ...jest.configs.style.rules,\n ...reactTestingLibraryRules,\n \"jest/no-commented-out-tests\": \"error\",\n \"jest/expect-expect\": \"error\",\n },\n },\n];\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../../../../../../../libs/eslint/plugin-trackunit/src/lib/config/presets/server.ts"],"names":[],"mappings":";;;;AAAA,2CAAkD;AAClD,gFAA0D;AAE1D,wCAAsD;AAEzC,QAAA,MAAM,GAAG;IACpB;QACE,eAAe,EAAE;YACf,OAAO,EAAE;gBACP,GAAG,iBAAO,CAAC,OAAO;aACnB;YAED,MAAM,EAAE,kBAAQ;SACjB;KACF;IACD;QACE,KAAK,EAAE,CAAC,SAAS,EAAE,SAAS,CAAC;QAC7B,OAAO,EAAE;YACP,KAAK,EAAL,eAAK;YACL,cAAc,EAAE,IAAA,yBAAgB,EAAC,WAAW,CAAC;SAC9C;QACD,eAAe,EAAE;YACf,aAAa,EAAE;gBACb,OAAO,EAAE,CAAC,oBAAoB,CAAC;aAChC;SACF;QAED,KAAK,EAAE;YACL,GAAG,WAAW,CAAC,OAAO,CAAC,WAAW,CAAC,KAAK;YACxC,qCAAqC,EAAE,CAAC,OAAO,EAAE,KAAK,CAAC;YACvD,2CAA2C,EAAE,KAAK;YAClD,wCAAwC,EAAE,OAAO;YACjD,0CAA0C,EAAE,KAAK;SAClD;KACF;CACF,CAAC","sourcesContent":["import { fixupPluginRules } from \"@eslint/compat\";\nimport * as typeGraphql from \"eslint-plugin-type-graphql\";\n\nimport { globals, jsdoc, tsParser } from \"../plugins\";\n\nexport const server = [\n {\n languageOptions: {\n globals: {\n ...globals.browser,\n },\n\n parser: tsParser,\n },\n },\n {\n files: [\"**/*.ts\", \"**/*.js\"],\n plugins: {\n jsdoc,\n \"type-graphql\": fixupPluginRules(typeGraphql),\n },\n languageOptions: {\n parserOptions: {\n project: [\"./tsconfig.*?.json\"],\n },\n },\n\n rules: {\n ...typeGraphql.configs.recommended.rules,\n \"type-graphql/missing-decorator-type\": [\"error\", \"all\"],\n \"type-graphql/invalid-nullable-output-type\": \"off\",\n \"type-graphql/wrong-decorator-signature\": \"error\",\n \"type-graphql/invalid-nullable-input-type\": \"off\",\n },\n },\n];\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../../../../../libs/eslint/plugin-trackunit/src/lib/config/utils.ts"],"names":[],"mappings":";;AAUA,4CAcC;;AAxBD,+CAAyB;AACzB,mDAA6B;AAE7B,IAAI,UAA8B,CAAC;AAEnC;;;;GAIG;AACH,SAAgB,gBAAgB;IAC9B,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;QAC7B,OAAO,UAAU,CAAC;IACpB,CAAC;IACD,IAAI,GAAG,GAAG,SAAS,CAAC;IACpB,OAAO,GAAG,KAAK,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QACjC,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC,EAAE,CAAC;YAC7C,UAAU,GAAG,GAAG,CAAC;YACjB,OAAO,GAAG,CAAC;QACb,CAAC;QACD,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAC1B,CAAC;IACD,UAAU,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAC3B,OAAO,UAAU,CAAC;AACpB,CAAC","sourcesContent":["import * as fs from \"fs\";\nimport * as path from \"path\";\n\nlet cachedRoot: string | undefined;\n\n/**\n * Finds the monorepo root by walking up from the config package directory\n * until a directory containing nx.json is found.\n * Falls back to process.cwd() if no nx.json is found.\n */\nexport function findMonorepoRoot(): string {\n if (cachedRoot !== undefined) {\n return cachedRoot;\n }\n let dir = __dirname;\n while (dir !== path.dirname(dir)) {\n if (fs.existsSync(path.join(dir, \"nx.json\"))) {\n cachedRoot = dir;\n return dir;\n }\n dir = path.dirname(dir);\n }\n cachedRoot = process.cwd();\n return cachedRoot;\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-skip-when.js","sourceRoot":"","sources":["../../../../../../../libs/eslint/plugin-trackunit/src/lib/config-helpers/create-skip-when.ts"],"names":[],"mappings":";;;AAqBA,gDAAmG;AAUnG,IAAI,eAAe,GAAG,CAAC,CAAC;AAExB;;GAEG;AACI,MAAM,cAAc,GAAG,CAAC,OAA8B,EAAqB,EAAE;IAClF,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC;IAEzC,8CAA8C;IAC9C,MAAM,UAAU,GAAG,aAAa,eAAe,EAAE,EAAE,CAAC;IAEpD,4CAA4C;IAC5C,MAAM,YAAY,GAAoC,EAAE,CAAC;IAEzD,KAAK,MAAM,CAAC,kBAAkB,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QACnE,KAAK,MAAM,CAAC,QAAQ,EAAE,YAAY,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;YACpE,MAAM,YAAY,GAAG,GAAG,kBAAkB,IAAI,QAAQ,EAAE,CAAC;YAEzD,sCAAsC;YACtC,YAAY,CAAC,YAAY,CAAC,GAAG;gBAC3B,IAAI,EAAE,YAAY,CAAC,IAAI;gBACvB,MAAM,CAAC,OAAyB;oBAC9B,gEAAgE;oBAChE,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;oBAC3D,MAAM,QAAQ,GAAG,IAAA,6BAAkB,EAAC,QAAQ,CAAC,CAAC;oBAE9C,6CAA6C;oBAC7C,IAAI,QAAQ,IAAI,IAAA,iCAAsB,EAAC,QAAQ,EAAE,IAAI,CAAC,EAAE,CAAC;wBACvD,0CAA0C;wBAC1C,OAAO,EAAE,CAAC;oBACZ,CAAC;oBAED,2CAA2C;oBAC3C,OAAO,YAAY,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;gBACtC,CAAC;aACF,CAAC;QACJ,CAAC;IACH,CAAC;IAED,yBAAyB;IACzB,MAAM,WAAW,GAAuB,EAAE,CAAC;IAE3C,KAAK,MAAM,CAAC,QAAQ,EAAE,UAAU,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAC3D,4BAA4B;QAC5B,WAAW,CAAC,QAAQ,CAAC,GAAG,KAAK,CAAC;QAE9B,6BAA6B;QAC7B,WAAW,CAAC,GAAG,UAAU,IAAI,QAAQ,EAAE,CAAC,GAAG,UAAU,CAAC;IACxD,CAAC;IAED,OAAO;QACL,OAAO,EAAE;YACP,CAAC,UAAU,CAAC,EAAE;gBACZ,KAAK,EAAE,YAAY;aACpB;SACF;QACD,KAAK,EAAE,WAAW;KACnB,CAAC;AACJ,CAAC,CAAC;AArDW,QAAA,cAAc,kBAqDzB","sourcesContent":["/**\n * Helper to create ESLint config that wraps rules with skip-when-lib-has-tag-tool logic.\n *\n * This provides a cleaner API than manually using the skip-when-lib-has-tag-tool/ prefix.\n *\n * @example\n * createSkipWhen({\n * when: { tags: ['scope:tool'] },\n * plugins: {\n * 'import-x': importXPlugin,\n * },\n * rules: {\n * 'import-x/no-extraneous-dependencies': [\"error\", { ... }],\n * }\n * })\n *\n * Returns a config object with:\n * - A unique plugin containing the wrapped rules for this specific config\n * - Rules configured to use the wrapped versions\n */\nimport type { Linter, Rule } from \"eslint\";\nimport { getProjectMetadata, projectMatchesCriteria, type MatchCriteria } from \"../utils/nx-utils\";\n\ntype PluginMap = Record<string, { rules: Record<string, Rule.RuleModule> }>;\n\ntype CreateSkipWhenOptions = {\n when: MatchCriteria;\n plugins: PluginMap;\n rules: Linter.RulesRecord;\n};\n\nlet skipWhenCounter = 0;\n\n/**\n * Creates an ESLint config that wraps rules to skip enforcement based on NX project criteria.\n */\nexport const createSkipWhen = (options: CreateSkipWhenOptions): Linter.FlatConfig => {\n const { when, plugins, rules } = options;\n\n // Create a unique plugin name for this config\n const pluginName = `skip-when-${skipWhenCounter++}`;\n\n // Build wrapped rules from provided plugins\n const wrappedRules: Record<string, Rule.RuleModule> = {};\n\n for (const [originalPluginName, plugin] of Object.entries(plugins)) {\n for (const [ruleName, originalRule] of Object.entries(plugin.rules)) {\n const fullRuleName = `${originalPluginName}/${ruleName}`;\n\n // Create wrapped version of this rule\n wrappedRules[fullRuleName] = {\n meta: originalRule.meta,\n create(context: Rule.RuleContext) {\n // Check if this file belongs to a project matching the criteria\n const filename = context.filename || context.getFilename();\n const metadata = getProjectMetadata(filename);\n\n // Check if project matches the skip criteria\n if (metadata && projectMatchesCriteria(metadata, when)) {\n // Skip enforcement - return empty visitor\n return {};\n }\n\n // Otherwise, delegate to the original rule\n return originalRule.create(context);\n },\n };\n }\n }\n\n // Build the rules config\n const rulesConfig: Linter.RulesRecord = {};\n\n for (const [ruleName, ruleConfig] of Object.entries(rules)) {\n // Disable the original rule\n rulesConfig[ruleName] = \"off\";\n\n // Enable our wrapped version\n rulesConfig[`${pluginName}/${ruleName}`] = ruleConfig;\n }\n\n return {\n plugins: {\n [pluginName]: {\n rules: wrappedRules,\n },\n },\n rules: rulesConfig,\n };\n};\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"component-name-matches-filename.js","sourceRoot":"","sources":["../../../../../../../../libs/eslint/plugin-trackunit/src/lib/rules/component-name-matches-filename/component-name-matches-filename.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * ESLint rule: component-name-matches-filename\n *\n * Enforces that every exported React component is named after the file it lives in.\n * For a file named `Foo.tsx`, the exported component must be named `Foo`.\n *\n * Anonymous default exports are skipped (no name to compare).\n * `index.*` files are skipped (they are entry-point re-export files, not component files).\n *\n * When combined with `one-component-per-file`, these two rules together fully enforce\n * the \"one named component per file\" convention.\n *\n * @example\n * // File: Foo.tsx\n * // Bad — exported name doesn't match filename\n * export function Bar() { return <div />; }\n *\n * // Good\n * export function Foo() { return <div />; }\n */\n\nimport { ESLintUtils } from \"@typescript-eslint/utils\";\nimport { minimatch } from \"minimatch\";\nimport path from \"path\";\nimport { createComponentFileTracker } from \"../../utils/component-utils\";\n\nconst createRule = ESLintUtils.RuleCreator(\n name => `https://github.com/trackunit/manager/blob/main/libs/eslint/plugin-trackunit/src/lib/rules/${name}/${name}.ts`\n);\n\ntype MessageIds = \"componentNameMismatch\";\n\ntype AllowedMismatch = {\n /** Basename of the file (without extension) where the mismatch is permitted. Supports glob patterns (`*`, `?`). */\n file: string;\n /** Exported component name that is permitted despite not matching the filename. Supports glob patterns (`*`, `?`). */\n component: string;\n};\n\ntype Options = [{ allowedMismatches?: ReadonlyArray<AllowedMismatch> }];\n\nexport const componentNameMatchesFilename = createRule<Options, MessageIds>({\n name: \"component-name-matches-filename\",\n meta: {\n type: \"suggestion\",\n docs: {\n description:\n \"Enforce that exported React component names match the filename they live in. \" +\n \"index.* files and anonymous default exports are exempt.\",\n },\n messages: {\n componentNameMismatch:\n \"Component '{{name}}' should match the filename. \" + \"Rename it to '{{expected}}' or move it to its own file.\",\n },\n schema: [\n {\n type: \"object\",\n properties: {\n allowedMismatches: {\n type: \"array\",\n description:\n \"Pairs that are exempt from the name-matching rule. Both `file` and `component` support glob patterns \" +\n \"(`*`, `?`), so one entry can cover a whole family of files (e.g. { file: '*Context', component: '*Provider' }).\",\n items: {\n type: \"object\",\n properties: {\n file: {\n type: \"string\",\n description:\n \"Basename of the file without extension. Supports glob patterns (`*`, `?`). \" +\n \"e.g. 'translation' or '*Context'.\",\n },\n component: {\n type: \"string\",\n description:\n \"Exported component name. Supports glob patterns (`*`, `?`). \" + \"e.g. 'Trans' or '*Provider'.\",\n },\n },\n required: [\"file\", \"component\"],\n additionalProperties: false,\n },\n },\n },\n additionalProperties: false,\n },\n ],\n },\n defaultOptions: [{}],\n create(context, [{ allowedMismatches = [] }]) {\n const filename = context.filename;\n const basename = path.basename(filename, path.extname(filename));\n\n if (basename === \"index\" || basename === \"<input>\") return {};\n\n // Normalize kebab-case and snake_case filenames to PascalCase.\n // e.g. `current-weather-status` → `CurrentWeatherStatus`, `app` → `App`.\n const expectedName = basename\n .split(/[-_]/)\n .map(segment => segment.charAt(0).toUpperCase() + segment.slice(1))\n .join(\"\");\n\n const tracker = createComponentFileTracker();\n\n return {\n FunctionDeclaration: tracker.onFunctionDeclaration,\n VariableDeclarator: tracker.onVariableDeclarator,\n ExportNamedDeclaration: tracker.onExportNamedDeclaration,\n ExportDefaultDeclaration: tracker.onExportDefaultDeclaration,\n\n \"Program:exit\"() {\n for (const { name, node } of tracker.getExportedComponents()) {\n if (name === null) continue; // anonymous default exports are exempt\n if (name === expectedName) continue;\n\n const isAllowed = allowedMismatches.some(\n entry => minimatch(basename, entry.file) && minimatch(name, entry.component)\n );\n if (isAllowed) continue;\n\n context.report({\n node,\n messageId: \"componentNameMismatch\",\n data: { name, expected: expectedName },\n });\n }\n },\n };\n },\n});\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cva-merge-base-classes-as-array.js","sourceRoot":"","sources":["../../../../../../../../libs/eslint/plugin-trackunit/src/lib/rules/cva-merge-base-classes-as-array/cva-merge-base-classes-as-array.ts"],"names":[],"mappings":"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","sourcesContent":["import { AST_NODE_TYPES, ESLintUtils, TSESTree } from \"@typescript-eslint/utils\";\nimport {\n type ClassnameContext,\n type ClassnameLocation,\n findClassnameStringsInCall,\n formatAsArray,\n splitClasses,\n} from \"../../utils/classname-utils\";\n\nconst createRule = ESLintUtils.RuleCreator(\n name => `https://github.com/trackunit/manager/blob/main/libs/eslint/plugin-trackunit/src/lib/rules/${name}.ts`\n);\n\ntype MessageIds = \"stringNeedsArray\" | \"arrayNeedsSplit\";\ntype Options = [];\n\nconst isCvaMergeBaseContext = (context: ClassnameContext): boolean => {\n if (context.type === \"function-call\") {\n return context.functionName === \"cvaMerge\" && context.argumentIndex === 0;\n }\n\n if (context.type === \"array-element\" && context.parentContext.type === \"function-call\") {\n return context.parentContext.functionName === \"cvaMerge\" && context.parentContext.argumentIndex === 0;\n }\n\n return false;\n};\n\nconst isLiteralLocation = (\n location: ClassnameLocation\n): location is ClassnameLocation & { fixNode: TSESTree.Literal } => {\n return location.fixNode.type === AST_NODE_TYPES.Literal && typeof location.fixNode.value === \"string\";\n};\n\n/**\n * ESLint rule that converts cvaMerge base styles to arrays if more than one class is used.\n *\n * @example\n * Invalid:\n * const cvaMyComponent = cvaMerge(\"text-danger-600 mb-4 font-semibold\");\n * const cvaMyComponent = cvaMerge([\"text-danger-600 mb-4\",\"font-semibold\"]);\n * Valid:\n * const cvaMyComponent = cvaMerge([\"text-danger-600\", \"mb-4\", \"font-semibold\"]);\n */\nexport const cvaMergeBaseClassesAsArray = createRule<Options, MessageIds>({\n name: \"cva-merge-base-classes-as-array\",\n meta: {\n type: \"layout\",\n docs: {\n description: \"Convert cvaMerge base styles to arrays if more than one class is used.\",\n },\n fixable: \"code\",\n messages: {\n stringNeedsArray: \"[cvaMerge] The first argument of cvaMerge should be an array if multiple classes are used.\",\n arrayNeedsSplit: \"[cvaMerge] Only one class per array item is allowed.\",\n },\n schema: [],\n },\n defaultOptions: [],\n create(context) {\n return {\n CallExpression(node: TSESTree.CallExpression) {\n const firstArg = node.arguments[0];\n if (!firstArg) {\n return;\n }\n\n const baseClassLocations = findClassnameStringsInCall(node)\n .filter(location => isCvaMergeBaseContext(location.context))\n .filter(isLiteralLocation);\n\n // Handle string literal: cvaMerge(\"class1 class2\")\n if (firstArg.type === AST_NODE_TYPES.Literal) {\n const baseClassLocation = baseClassLocations[0];\n if (!baseClassLocation) {\n return;\n }\n\n const value = baseClassLocation.value;\n if (value.includes(\" \")) {\n context.report({\n node,\n messageId: \"stringNeedsArray\",\n fix(fixer) {\n return fixer.replaceText(baseClassLocation.fixNode, formatAsArray(splitClasses(value)));\n },\n });\n }\n return;\n }\n\n // Handle array: cvaMerge([\"class1 class2\", \"class3\"])\n if (firstArg.type === AST_NODE_TYPES.ArrayExpression) {\n const hasMultiClassElement = baseClassLocations.some(location => location.value.includes(\" \"));\n\n if (hasMultiClassElement) {\n context.report({\n node,\n messageId: \"arrayNeedsSplit\",\n fix(fixer) {\n const allClasses = baseClassLocations.flatMap(location => splitClasses(location.value));\n return fixer.replaceText(firstArg, formatAsArray(allClasses));\n },\n });\n }\n }\n },\n };\n },\n});\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"design-guideline-button-icon-size-match.js","sourceRoot":"","sources":["../../../../../../../../libs/eslint/plugin-trackunit/src/lib/rules/design-guideline-button-icon-size-match/design-guideline-button-icon-size-match.ts"],"names":[],"mappings":"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","sourcesContent":["import { ESLintUtils, type TSESLint, type TSESTree } from \"@typescript-eslint/utils\";\nimport * as ts from \"typescript\";\n\nconst createRule = ESLintUtils.RuleCreator(\n name => `https://github.com/trackunit/manager/blob/main/libs/eslint/plugin-trackunit/docs/rules/${name}.md`\n);\n\n// Helper to get possible string literal values from a variable's type\nfunction getPossibleStringLiterals(\n context: TSESLint.RuleContext<string, ReadonlyArray<unknown>>,\n identifier: TSESTree.Identifier\n): Array<string> | null {\n try {\n const services = ESLintUtils.getParserServices(context);\n const checker = services.program.getTypeChecker();\n const tsNode = services.esTreeNodeToTSNodeMap.get(identifier);\n const type = checker.getTypeAtLocation(tsNode);\n\n const literalValues: Array<string> = [];\n\n // Type guard for string literal types\n const isStringLiteralType = (t: ts.Type): t is ts.Type & { value: string } => {\n if ((t.flags & ts.TypeFlags.StringLiteral) === 0) {\n return false;\n }\n // Check if the type has a value property and it's a string\n // eslint-disable-next-line @trackunit/no-typescript-assertion\n const typeWithValue = t as { value?: unknown };\n return \"value\" in typeWithValue && typeof typeWithValue.value === \"string\";\n };\n\n if (type.isUnion()) {\n for (const unionType of type.types) {\n if (isStringLiteralType(unionType)) {\n literalValues.push(unionType.value);\n }\n }\n } else if (isStringLiteralType(type)) {\n literalValues.push(type.value);\n }\n\n return literalValues.length > 0 ? literalValues : null;\n } catch {\n return null;\n }\n}\n\n// Helper to check if a conditional expression matches the expected button-icon size pattern\nfunction isCorrectConditionalExpression(expression: TSESTree.Expression, buttonVariableName: string): boolean {\n if (expression.type !== \"ConditionalExpression\") {\n return false;\n }\n\n const { test, consequent, alternate } = expression;\n\n // Check if test is: variable === \"large\"\n if (\n test.type === \"BinaryExpression\" &&\n test.operator === \"===\" &&\n test.left.type === \"Identifier\" &&\n test.left.name === buttonVariableName &&\n test.right.type === \"Literal\" &&\n test.right.value === \"large\"\n ) {\n // Check if consequent is \"medium\" and alternate is \"small\"\n return (\n consequent.type === \"Literal\" &&\n consequent.value === \"medium\" &&\n alternate.type === \"Literal\" &&\n alternate.value === \"small\"\n );\n }\n\n return false;\n}\n\nexport const designGuidelineButtonIconSizeMatch = createRule({\n name: \"design-guideline-button-icon-size-match\",\n meta: {\n type: \"suggestion\",\n docs: {\n description: \"Ensure Icon components within Button have the correct size prop based on the Button's size.\",\n },\n fixable: \"code\",\n schema: [],\n messages: {\n incorrectIconSize:\n \"Expected Icon size to be '{{expectedSize}}' for Button size '{{buttonSize}}', found '{{iconSize}}'.\",\n },\n },\n defaultOptions: [],\n create(context) {\n return {\n JSXOpeningElement(node: TSESTree.JSXOpeningElement) {\n if (node.name.type === \"JSXIdentifier\" && node.name.name === \"Button\") {\n const sizeAttr = node.attributes.find(\n (attr): attr is TSESTree.JSXAttribute =>\n attr.type === \"JSXAttribute\" && attr.name.type === \"JSXIdentifier\" && attr.name.name === \"size\"\n );\n\n const buttonSizeInfo = (() => {\n if (!sizeAttr?.value) return { type: \"implicit\", value: null };\n\n if (sizeAttr.value.type === \"Literal\" && typeof sizeAttr.value.value === \"string\") {\n return { type: \"literal\", value: sizeAttr.value.value };\n }\n\n if (sizeAttr.value.type === \"JSXExpressionContainer\") {\n const expr = sizeAttr.value.expression;\n if (expr.type === \"Identifier\") {\n return { type: \"variable\", value: expr.name, expression: expr };\n }\n return { type: \"expression\", value: null, expression: expr };\n }\n\n return { type: \"implicit\", value: null };\n })();\n\n node.attributes.forEach(attr => {\n if (\n attr.type === \"JSXAttribute\" &&\n attr.name.type === \"JSXIdentifier\" &&\n (attr.name.name === \"prefix\" || attr.name.name === \"suffix\") &&\n attr.value?.type === \"JSXExpressionContainer\"\n ) {\n // Find Icon element - could be direct or inside conditional\n const findIconElement = (expression: TSESTree.Expression): TSESTree.JSXOpeningElement | null => {\n if (\n expression.type === \"JSXElement\" &&\n expression.openingElement.name.type === \"JSXIdentifier\" &&\n expression.openingElement.name.name === \"Icon\"\n ) {\n return expression.openingElement;\n }\n\n if (expression.type === \"ConditionalExpression\") {\n // Check both consequent and alternate\n const consequent = findIconElement(expression.consequent);\n if (consequent) return consequent;\n\n const alternate = findIconElement(expression.alternate);\n if (alternate) return alternate;\n }\n\n return null;\n };\n\n // Skip empty JSX expressions like {}\n if (attr.value.expression.type === \"JSXEmptyExpression\") return;\n\n const iconElement = findIconElement(attr.value.expression);\n if (!iconElement) return;\n const iconSizeAttr = iconElement.attributes.find(\n (iconAttr): iconAttr is TSESTree.JSXAttribute =>\n iconAttr.type === \"JSXAttribute\" &&\n iconAttr.name.type === \"JSXIdentifier\" &&\n iconAttr.name.name === \"size\"\n );\n\n const iconSizeInfo = (() => {\n if (!iconSizeAttr?.value) return { type: \"implicit\", value: null };\n\n if (iconSizeAttr.value.type === \"Literal\" && typeof iconSizeAttr.value.value === \"string\") {\n return { type: \"literal\", value: iconSizeAttr.value.value };\n }\n\n if (iconSizeAttr.value.type === \"JSXExpressionContainer\") {\n const expr = iconSizeAttr.value.expression;\n if (expr.type === \"Identifier\") {\n return { type: \"variable\", value: expr.name, expression: expr };\n }\n return { type: \"expression\", value: null, expression: expr };\n }\n\n return { type: \"implicit\", value: null };\n })();\n\n // Rule: large buttons → medium icons, small/medium buttons → small icons\n const getExpectedIconSize = (buttonSize: string): string => {\n if (buttonSize === \"large\") return \"medium\";\n return \"small\"; // both \"small\" and \"medium\" buttons get \"small\" icons\n };\n\n const shouldReport = (() => {\n // For complex expressions, always warn but don't autofix\n if (buttonSizeInfo.type === \"expression\") {\n return true;\n }\n\n // For variables, check if icon already has the correct size\n if (buttonSizeInfo.type === \"variable\" && buttonSizeInfo.expression?.type === \"Identifier\") {\n const possibleSizes = getPossibleStringLiterals(context, buttonSizeInfo.expression);\n\n if (possibleSizes) {\n // Check if all possible button sizes map to the same icon size\n const iconSizes = possibleSizes.map(getExpectedIconSize);\n const uniqueIconSizes = [...new Set(iconSizes)];\n\n if (uniqueIconSizes.length === 1) {\n // All map to same icon size - check if icon already has correct literal\n const variableExpectedIconSize = uniqueIconSizes[0];\n const variableIconEffectiveSize = iconSizeInfo.value || \"medium\";\n\n if (variableIconEffectiveSize === variableExpectedIconSize) {\n return false; // Icon already has correct literal size\n }\n } else {\n // Mixed mapping - check if icon has correct conditional expression\n if (\n iconSizeInfo.type === \"expression\" &&\n iconSizeInfo.expression &&\n iconSizeInfo.expression.type !== \"JSXEmptyExpression\" &&\n buttonSizeInfo.value &&\n isCorrectConditionalExpression(iconSizeInfo.expression, buttonSizeInfo.value)\n ) {\n return false; // Icon already has correct conditional\n }\n }\n }\n\n // Mixed mapping or can't determine - always warn\n return true;\n }\n\n // For literals and implicit, check the mapping\n const buttonEffectiveSize = buttonSizeInfo.value || \"medium\";\n const iconEffectiveSize = iconSizeInfo.value || \"medium\";\n const expectedIconSize = getExpectedIconSize(buttonEffectiveSize);\n\n return iconEffectiveSize !== expectedIconSize;\n })();\n\n if (shouldReport) {\n context.report({\n node: iconElement,\n messageId: \"incorrectIconSize\",\n data: {\n expectedSize: (() => {\n if (buttonSizeInfo.type === \"variable\" && buttonSizeInfo.expression?.type === \"Identifier\") {\n // Analyze the variable's type to determine expected message\n const possibleSizes = getPossibleStringLiterals(context, buttonSizeInfo.expression);\n\n if (possibleSizes) {\n const iconSizes = possibleSizes.map(getExpectedIconSize);\n const uniqueIconSizes = [...new Set(iconSizes)];\n\n if (uniqueIconSizes.length === 1) {\n return uniqueIconSizes[0];\n }\n }\n\n return `{${buttonSizeInfo.value} === \"large\" ? \"medium\" : \"small\"}`;\n }\n if (buttonSizeInfo.type === \"expression\") {\n return \"small (for small/medium buttons) or medium (for large buttons)\";\n }\n const buttonEffectiveSize = buttonSizeInfo.value || \"medium\";\n return getExpectedIconSize(buttonEffectiveSize);\n })(),\n buttonSize:\n buttonSizeInfo.type === \"implicit\"\n ? \"medium (default)\"\n : buttonSizeInfo.type === \"literal\"\n ? buttonSizeInfo.value\n : buttonSizeInfo.type === \"variable\"\n ? (() => {\n if (buttonSizeInfo.expression?.type === \"Identifier\") {\n const possibleSizes = getPossibleStringLiterals(context, buttonSizeInfo.expression);\n if (possibleSizes && possibleSizes.length > 0) {\n const sizeList = possibleSizes.map(s => `\"${s}\"`).join(\" | \");\n return `{${buttonSizeInfo.value}} (of type ${sizeList})`;\n }\n }\n return `{${buttonSizeInfo.value}}`;\n })()\n : \"expression\",\n iconSize:\n iconSizeInfo.type === \"implicit\"\n ? \"medium (default)\"\n : iconSizeInfo.type === \"literal\"\n ? iconSizeInfo.value\n : iconSizeInfo.type === \"variable\"\n ? `{${iconSizeInfo.value}}`\n : \"expression\",\n },\n fix(fixer) {\n // Don't autofix complex expressions, only variables and literals\n if (buttonSizeInfo.type === \"expression\") {\n return null;\n }\n\n let targetSizeValue: string;\n\n if (buttonSizeInfo.type === \"variable\" && buttonSizeInfo.expression?.type === \"Identifier\") {\n // Analyze the variable's type to determine optimal autofix\n const possibleSizes = getPossibleStringLiterals(context, buttonSizeInfo.expression);\n\n if (possibleSizes) {\n // Check if all possible button sizes map to the same icon size\n const iconSizes = possibleSizes.map(getExpectedIconSize);\n const uniqueIconSizes = [...new Set(iconSizes)];\n\n if (uniqueIconSizes.length === 1) {\n // All possible button sizes map to the same icon size\n targetSizeValue = `\"${uniqueIconSizes[0]}\"`;\n } else {\n // Mixed mapping, use conditional\n targetSizeValue = `{${buttonSizeInfo.value} === \"large\" ? \"medium\" : \"small\"}`;\n }\n } else {\n // Can't determine type, use conditional\n targetSizeValue = `{${buttonSizeInfo.value} === \"large\" ? \"medium\" : \"small\"}`;\n }\n } else {\n // Calculate target icon size based on button size (literal or implicit)\n const buttonEffectiveSize = buttonSizeInfo.value || \"medium\";\n const targetIconSize = getExpectedIconSize(buttonEffectiveSize);\n targetSizeValue = `\"${targetIconSize}\"`;\n }\n\n if (iconSizeAttr) {\n // Replace existing size attribute\n if (!iconSizeAttr.value) return null;\n return fixer.replaceText(iconSizeAttr.value, targetSizeValue);\n } else {\n // Add size attribute\n const lastAttr = iconElement.attributes[iconElement.attributes.length - 1];\n if (lastAttr) {\n return fixer.insertTextAfter(lastAttr, ` size=${targetSizeValue}`);\n } else {\n return fixer.insertTextAfter(iconElement.name, ` size=${targetSizeValue}`);\n }\n }\n },\n });\n }\n }\n });\n }\n },\n };\n },\n});\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-deprecated-graphql-fields.js","sourceRoot":"","sources":["../../../../../../../../libs/eslint/plugin-trackunit/src/lib/rules/no-deprecated-graphql-fields/no-deprecated-graphql-fields.ts"],"names":[],"mappings":";;;;AAAA,oDAAuD;AACvD,+CAAyB;AACzB,qCAAkE;AAClE,mDAA6B;AAC7B,uDAAyD;AACzD,iDAA2C;AAE3C,MAAM,UAAU,GAAG,mBAAW,CAAC,WAAW,CACxC,IAAI,CAAC,EAAE,CAAC,6FAA6F,IAAI,IAAI,IAAI,KAAK,CACvH,CAAC;AAKF,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC,CAAC,cAAc,EAAE,WAAW,EAAE,MAAM,CAAC,CAAC,CAAC;AAErE,MAAM,mBAAmB,GAAG,CAAC,GAAW,EAAE,QAAuB,EAAE,EAAiB,EAAE;IACpF,IAAI,OAAyB,CAAC;IAC9B,IAAI,CAAC;QACH,OAAO,GAAG,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IACzD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;IACD,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QAC5C,IAAI,IAAc,CAAC;QACnB,IAAI,CAAC;YACH,IAAI,GAAG,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QAC/B,CAAC;QAAC,MAAM,CAAC;YACP,SAAS;QACX,CAAC;QACD,IAAI,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;YACvB,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;gBACnC,mBAAmB,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;YACvC,CAAC;QACH,CAAC;aAAM,IAAI,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;YAC3C,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACvB,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC,CAAC;AAEW,QAAA,yBAAyB,GAAG,UAAU,CAAsB;IACvE,IAAI,EAAE,8BAA8B;IACpC,IAAI,EAAE;QACJ,IAAI,EAAE,SAAS;QACf,IAAI,EAAE;YACJ,WAAW,EAAE,0EAA0E;SACxF;QACD,QAAQ,EAAE;YACR,mBAAmB,EAAE,wDAAwD;SAC9E;QACD,MAAM,EAAE,EAAE;KACX;IACD,cAAc,EAAE,EAAE;IAClB,MAAM,CAAC,OAAO;QACZ,OAAO;YACL,OAAO,EAAE,KAAK,CAAC,EAAE;gBACf,MAAM,cAAc,GAAG,OAAO,CAAC,QAAQ,CAAC;gBACxC,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,eAAe,CAAC,EAAE,CAAC;oBAC9C,OAAO;gBACT,CAAC;gBAED,MAAM,UAAU,GAAG,IAAA,4BAAe,EAAC,cAAc,EAAE,SAAS,CAAC,CAAC;gBAC9D,IAAI,CAAC,UAAU,EAAE,CAAC;oBAChB,OAAO;gBACT,CAAC;gBACD,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;gBAE9C,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAC1B,YAAY,EACZ,MAAM,EACN,KAAK,EACL,qBAAqB,EACrB,WAAW,EACX,qBAAqB,CACtB,CAAC;gBAEF,MAAM,MAAM,GAAG,IAAA,wBAAS,EAAC,UAAU,CAAC,CAAC;gBACrC,IAAI,CAAC,MAAM,EAAE,CAAC;oBACZ,OAAO;gBACT,CAAC;gBAED,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;gBAChD,MAAM,YAAY,GAAG,mBAAmB,CAAC,UAAU,CAAC,CAAC;gBAErD,KAAK,MAAM,OAAO,IAAI,YAAY,EAAE,CAAC;oBACnC,IAAI,OAAe,CAAC;oBACpB,IAAI,CAAC;wBACH,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;oBAC7C,CAAC;oBAAC,MAAM,CAAC;wBACP,SAAS;oBACX,CAAC;oBAED,IAAI,QAAQ,CAAC;oBACb,IAAI,CAAC;wBACH,QAAQ,GAAG,IAAA,eAAK,EAAC,OAAO,CAAC,CAAC;oBAC5B,CAAC;oBAAC,MAAM,CAAC;wBACP,SAAS;oBACX,CAAC;oBAED,MAAM,MAAM,GAAG,IAAA,kBAAQ,EAAC,MAAM,EAAE,QAAQ,EAAE,CAAC,gCAAsB,CAAC,CAAC,CAAC;oBACpE,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;wBAC3B,OAAO,CAAC,MAAM,CAAC;4BACb,SAAS,EAAE,qBAAqB;4BAChC,IAAI,EAAE;gCACJ,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC;gCAC1C,OAAO,EAAE,KAAK,CAAC,OAAO;6BACvB;4BACD,GAAG,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE;yBAC5B,CAAC,CAAC;oBACL,CAAC;gBACH,CAAC;YACH,CAAC;SACF,CAAC;IACJ,CAAC;CACF,CAAC,CAAC","sourcesContent":["import { ESLintUtils } from \"@typescript-eslint/utils\";\nimport * as fs from \"fs\";\nimport { NoDeprecatedCustomRule, parse, validate } from \"graphql\";\nimport * as path from \"path\";\nimport { findNearestFile } from \"../../utils/file-utils\";\nimport { getSchema } from \"./schema-cache\";\n\nconst createRule = ESLintUtils.RuleCreator(\n name => `https://github.com/trackunit/manager/blob/main/libs/eslint/plugin-trackunit/src/lib/rules/${name}/${name}.ts`\n);\n\ntype MessageIds = \"deprecatedFieldUsed\";\ntype Options = [];\n\nconst EXCLUDED_DIRS = new Set([\"node_modules\", \"generated\", \"dist\"]);\n\nconst collectGraphqlFiles = (dir: string, files: Array<string> = []): Array<string> => {\n let entries: Array<fs.Dirent>;\n try {\n entries = fs.readdirSync(dir, { withFileTypes: true });\n } catch {\n return files;\n }\n for (const entry of entries) {\n const fullPath = path.join(dir, entry.name);\n let stat: fs.Stats;\n try {\n stat = fs.statSync(fullPath);\n } catch {\n continue;\n }\n if (stat.isDirectory()) {\n if (!EXCLUDED_DIRS.has(entry.name)) {\n collectGraphqlFiles(fullPath, files);\n }\n } else if (entry.name.endsWith(\".graphql\")) {\n files.push(fullPath);\n }\n }\n return files;\n};\n\nexport const noDeprecatedGraphqlFields = createRule<Options, MessageIds>({\n name: \"no-deprecated-graphql-fields\",\n meta: {\n type: \"problem\",\n docs: {\n description: \"Disallow usage of @deprecated GraphQL fields in .graphql operation files\",\n },\n messages: {\n deprecatedFieldUsed: \"Deprecated GraphQL field used in {{file}}: {{message}}\",\n },\n schema: [],\n },\n defaultOptions: [],\n create(context) {\n return {\n Program: _node => {\n const sourceFilePath = context.filename;\n if (!sourceFilePath.endsWith(\"/project.json\")) {\n return;\n }\n\n const nxJsonPath = findNearestFile(sourceFilePath, \"nx.json\");\n if (!nxJsonPath) {\n return;\n }\n const monorepoRoot = path.dirname(nxJsonPath);\n\n const schemaPath = path.join(\n monorepoRoot,\n \"libs\",\n \"api\",\n \"internal-gql-schema\",\n \"generated\",\n \"internal-schema.gql\"\n );\n\n const schema = getSchema(schemaPath);\n if (!schema) {\n return;\n }\n\n const projectDir = path.dirname(sourceFilePath);\n const graphqlFiles = collectGraphqlFiles(projectDir);\n\n for (const gqlFile of graphqlFiles) {\n let content: string;\n try {\n content = fs.readFileSync(gqlFile, \"utf8\");\n } catch {\n continue;\n }\n\n let document;\n try {\n document = parse(content);\n } catch {\n continue;\n }\n\n const errors = validate(schema, document, [NoDeprecatedCustomRule]);\n for (const error of errors) {\n context.report({\n messageId: \"deprecatedFieldUsed\",\n data: {\n file: path.relative(monorepoRoot, gqlFile),\n message: error.message,\n },\n loc: { line: 1, column: 0 },\n });\n }\n }\n },\n };\n },\n});\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema-cache.js","sourceRoot":"","sources":["../../../../../../../../libs/eslint/plugin-trackunit/src/lib/rules/no-deprecated-graphql-fields/schema-cache.ts"],"names":[],"mappings":";;;;AAAA,+CAAyB;AACzB,qCAA0D;AAE1D;;;GAGG;AACH,MAAM,WAAW,GAAG,IAAI,GAAG,EAAyB,CAAC;AAE9C,MAAM,SAAS,GAAG,CAAC,UAAkB,EAAwB,EAAE;IACpE,IAAI,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC;QAChC,OAAO,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,IAAI,CAAC;IAC7C,CAAC;IACD,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;QACpD,MAAM,MAAM,GAAG,IAAA,qBAAW,EAAC,OAAO,CAAC,CAAC;QACpC,WAAW,CAAC,GAAG,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;QACpC,OAAO,MAAM,CAAC;IAChB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC,CAAC;AAZW,QAAA,SAAS,aAYpB;AAEK,MAAM,gBAAgB,GAAG,GAAS,EAAE;IACzC,WAAW,CAAC,KAAK,EAAE,CAAC;AACtB,CAAC,CAAC;AAFW,QAAA,gBAAgB,oBAE3B","sourcesContent":["import * as fs from \"fs\";\nimport { type GraphQLSchema, buildSchema } from \"graphql\";\n\n/**\n * Caches parsed schemas by path to avoid re-parsing on every project.json lint.\n * Isolated in its own module so tests can reset it independently of the rule's production exports.\n */\nconst schemaCache = new Map<string, GraphQLSchema>();\n\nexport const getSchema = (schemaPath: string): GraphQLSchema | null => {\n if (schemaCache.has(schemaPath)) {\n return schemaCache.get(schemaPath) ?? null;\n }\n try {\n const content = fs.readFileSync(schemaPath, \"utf8\");\n const schema = buildSchema(content);\n schemaCache.set(schemaPath, schema);\n return schema;\n } catch {\n return null;\n }\n};\n\nexport const clearSchemaCache = (): void => {\n schemaCache.clear();\n};\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-internal-barrel-files.js","sourceRoot":"","sources":["../../../../../../../../libs/eslint/plugin-trackunit/src/lib/rules/no-internal-barrel-files/no-internal-barrel-files.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * ESLint rule to disallow internal barrel files.\n *\n * Internal barrel files (any index.ts or index.tsx that is not at the library root) cause:\n * - Multiple import paths to the same module\n * - Slower builds (bundlers must traverse more barrel files)\n * - Confusion about canonical import paths\n * - Potential bundle size issues\n * - Module identity problems\n *\n * EXCEPTION: Secondary entry points configured in tsconfig.base.json are allowed.\n * These are intentional barrel files that provide separate package imports\n * (e.g., @trackunit/react-core-contexts-host-test pointing to src/test/index.ts).\n *\n * @example\n * // Valid - Root barrel file\n * // libs/my-lib/src/index.ts ✅\n *\n * // Valid - Secondary entry point configured in tsconfig.base.json\n * // libs/my-lib/src/test/index.ts ✅ (if configured as @trackunit/my-lib-test)\n *\n * // Invalid - Internal barrel file\n * // libs/my-lib/src/components/index.ts ❌\n * // libs/my-lib/src/utils/helpers/index.ts ❌\n */\nimport { ESLintUtils } from \"@typescript-eslint/utils\";\nimport * as fs from \"fs\";\nimport * as path from \"path\";\nimport { z } from \"zod\";\nimport { findNearestFile } from \"../../utils/file-utils\";\n\nconst projectJsonSchema = z.object({\n sourceRoot: z.string().optional(),\n});\n\nconst tsconfigSchema = z.object({\n compilerOptions: z\n .object({\n paths: z.record(z.array(z.string())).optional(),\n })\n .optional(),\n});\n\n/**\n * Cache for tsconfig.base.json secondary entry points.\n * Key: workspace root path\n * Value: Set of absolute paths to allowed secondary entry points\n */\nconst secondaryEntryPointsCache = new Map<string, Set<string>>();\n\n/**\n * Find the workspace root by looking for nx.json\n */\nconst findWorkspaceRoot = (startPath: string): string | null => {\n const nxJsonPath = findNearestFile(startPath, \"nx.json\");\n return nxJsonPath ? path.dirname(nxJsonPath) : null;\n};\n\n/**\n * Get secondary entry points from tsconfig.base.json.\n * These are path mappings that point to index.ts files inside src/ subdirectories.\n * Results are cached per workspace root.\n */\nconst getSecondaryEntryPoints = (workspaceRoot: string): Set<string> => {\n const cached = secondaryEntryPointsCache.get(workspaceRoot);\n if (cached) {\n return cached;\n }\n\n const entryPoints = new Set<string>();\n const tsconfigPath = path.join(workspaceRoot, \"tsconfig.base.json\");\n\n try {\n const tsconfigContent = fs.readFileSync(tsconfigPath, \"utf-8\");\n const parsed = tsconfigSchema.safeParse(JSON.parse(tsconfigContent));\n\n if (parsed.success && parsed.data.compilerOptions?.paths) {\n const paths = parsed.data.compilerOptions.paths;\n\n for (const pathMappings of Object.values(paths)) {\n for (const mapping of pathMappings) {\n // Only consider mappings that point to index.ts files\n if (mapping.endsWith(\"/index.ts\") || mapping.endsWith(\"/index.tsx\")) {\n const absolutePath = path.normalize(path.join(workspaceRoot, mapping));\n entryPoints.add(absolutePath);\n }\n }\n }\n }\n } catch {\n // If we can't read tsconfig.base.json, return empty set\n }\n\n secondaryEntryPointsCache.set(workspaceRoot, entryPoints);\n return entryPoints;\n};\n\nconst createRule = ESLintUtils.RuleCreator(\n name => `https://github.com/trackunit/manager/blob/main/libs/eslint/plugin-trackunit/src/lib/rules/${name}.ts`\n);\n\ntype MessageIds = \"noInternalBarrel\";\ntype Options = [];\n\n/**\n * Check if a file is a barrel file (index.ts or index.tsx).\n */\nconst isBarrelFile = (filePath: string): boolean => {\n const basename = path.basename(filePath);\n return basename === \"index.ts\" || basename === \"index.tsx\";\n};\n\n/**\n * Normalize file path for comparison (handles potential trailing slashes, etc.)\n */\nconst normalizePath = (filePath: string): string => {\n return path.normalize(filePath);\n};\n\nexport const noInternalBarrelFiles = createRule<Options, MessageIds>({\n name: \"no-internal-barrel-files\",\n meta: {\n type: \"suggestion\",\n docs: {\n description:\n \"Disallow internal barrel files (index.ts) that are not at the library root or configured as secondary entry points\",\n },\n schema: [],\n messages: {\n noInternalBarrel:\n \"Internal barrel files are not allowed. Move exports to the root barrel file (src/index.ts) instead. Use the flatten-barrel-exports tool: yarn ts-node devtools/flatten-barrel-exports/flatten-barrel-exports.ts\",\n },\n },\n defaultOptions: [],\n create(context) {\n return {\n Program(node) {\n const currentFile = context.filename;\n\n // Only analyze barrel files (index.ts/tsx)\n if (!isBarrelFile(currentFile)) {\n return;\n }\n\n // Find the project root by looking for project.json\n const projectJsonPath = findNearestFile(currentFile, \"project.json\");\n if (projectJsonPath === null) {\n // Not in an NX project, skip\n return;\n }\n\n const projectRoot = path.dirname(projectJsonPath);\n const workspaceRoot = findWorkspaceRoot(currentFile);\n\n // Read sourceRoot from project.json, defaulting to \"src\" if not specified\n // sourceRoot in project.json is relative to workspace root (e.g., \"libs/my-lib/src\")\n let sourceRootAbsolute = path.join(projectRoot, \"src\");\n try {\n const projectJsonContent = fs.readFileSync(projectJsonPath, \"utf-8\");\n const parsed = projectJsonSchema.safeParse(JSON.parse(projectJsonContent));\n if (parsed.success && parsed.data.sourceRoot && workspaceRoot) {\n // sourceRoot is relative to workspace root, so resolve it\n sourceRootAbsolute = path.join(workspaceRoot, parsed.data.sourceRoot);\n }\n } catch {\n // If we can't read project.json, fall back to projectRoot/src\n }\n\n // The root barrel is at {sourceRoot}/index.ts or {sourceRoot}/index.tsx\n const rootBarrelTs = normalizePath(path.join(sourceRootAbsolute, \"index.ts\"));\n const rootBarrelTsx = normalizePath(path.join(sourceRootAbsolute, \"index.tsx\"));\n const normalizedCurrentFile = normalizePath(currentFile);\n\n // If this IS the root barrel, it's allowed\n if (normalizedCurrentFile === rootBarrelTs || normalizedCurrentFile === rootBarrelTsx) {\n return;\n }\n\n // Check if this is a secondary entry point configured in tsconfig.base.json\n if (workspaceRoot) {\n const secondaryEntryPoints = getSecondaryEntryPoints(workspaceRoot);\n if (secondaryEntryPoints.has(normalizedCurrentFile)) {\n // This is a configured secondary entry point, allow it\n return;\n }\n }\n\n // This is an internal barrel file - flag it\n // Note: No autofix or suggestion is provided because:\n // 1. The exports need to be moved to the root barrel\n // 2. Imports throughout the codebase may need updating\n // 3. The flatten-barrel-exports tool handles this properly\n context.report({\n node,\n messageId: \"noInternalBarrel\",\n });\n },\n };\n },\n});\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-internal-graphql-when-tagged-with-gql-public.js","sourceRoot":"","sources":["../../../../../../../../libs/eslint/plugin-trackunit/src/lib/rules/no-internal-graphql-when-tagged-with-gql-public/no-internal-graphql-when-tagged-with-gql-public.ts"],"names":[],"mappings":"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","sourcesContent":["import { ESLintUtils } from \"@typescript-eslint/utils\";\nimport * as fs from \"fs\";\nimport * as path from \"path\";\n\nconst createRule = ESLintUtils.RuleCreator(\n name => `https://github.com/trackunit/manager/blob/main/libs/eslint/plugin-trackunit/src/lib/rules/${name}/${name}.ts`\n);\n\ntype MessageIds = \"internalGraphqlFileFound\";\ntype Options = [];\n\nexport const noInternalGraphqlWhenTaggedWithGqlPublic = createRule<Options, MessageIds>({\n name: \"no-internal-graphql-when-tagged-with-gql-public\",\n meta: {\n type: \"problem\",\n docs: {\n description: \"Disallow '-internal.graphql' files in projects tagged with 'gql:public'\",\n },\n messages: {\n internalGraphqlFileFound: \"'*-internal.graphql' file found in a 'gql:public' tagged project. - {{path}}\",\n },\n schema: [],\n },\n defaultOptions: [],\n create(context) {\n const getLineAndColumnFromPosition = (content: string, position: number) => {\n const lines = content.substring(0, position).split(\"\\n\");\n const line = lines.length;\n const column = lines[lines.length - 1]?.length ?? 0;\n return { line, column };\n };\n\n const checkDirectoryForInternalGraphQLFiles = (directory: string, projectJson: string) => {\n const entries = fs.readdirSync(directory, { withFileTypes: true });\n for (const entry of entries) {\n const fullPath = path.join(directory, entry.name);\n\n // Handle broken symlinks or inaccessible paths gracefully\n let stat: fs.Stats;\n try {\n stat = fs.statSync(fullPath);\n } catch {\n // Skip paths that can't be accessed (broken symlinks, permission issues, etc.)\n continue;\n }\n\n if (stat.isDirectory()) {\n checkDirectoryForInternalGraphQLFiles(fullPath, projectJson);\n } else if (entry.name.endsWith(\"-internal.graphql\")) {\n context.report({\n messageId: \"internalGraphqlFileFound\",\n data: { path: fullPath },\n loc: getLineAndColumnFromPosition(projectJson, projectJson.indexOf(\"gql:public\")),\n });\n return;\n }\n }\n };\n return {\n Program: _node => {\n const sourceFilePath = context.filename;\n if (sourceFilePath.endsWith(\"/project.json\")) {\n const projectJsonString = fs.readFileSync(sourceFilePath, \"utf8\");\n const projectJson: { tags?: Array<string> } = JSON.parse(projectJsonString);\n if (Array.isArray(projectJson.tags) && projectJson.tags.includes(\"gql:public\")) {\n const projectDir = path.dirname(sourceFilePath);\n checkDirectoryForInternalGraphQLFiles(projectDir, projectJsonString);\n }\n }\n },\n };\n },\n});\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-jest-mock-trackunit-react-core-hooks.js","sourceRoot":"","sources":["../../../../../../../../libs/eslint/plugin-trackunit/src/lib/rules/no-jest-mock-trackunit-react-core-hooks/no-jest-mock-trackunit-react-core-hooks.ts"],"names":[],"mappings":";;;AAAA,oDAAuD;AAEvD,MAAM,UAAU,GAAG,mBAAW,CAAC,WAAW,CACxC,IAAI,CAAC,EAAE,CACL,6FAA6F,IAAI,IAAI,IAAI,KAAK,CACjH,CAAC;AAKW,QAAA,iCAAiC,GAAG,UAAU,CAAsB;IAC/E,IAAI,EAAE,yCAAyC;IAC/C,IAAI,EAAE;QACJ,IAAI,EAAE,SAAS;QACf,IAAI,EAAE;YACJ,WAAW,EAAE,4DAA4D;SAC1E;QACD,QAAQ,EAAE;YACR,YAAY,EACV,oKAAoK;SACvK;QACD,MAAM,EAAE,EAAE;KACX;IACD,cAAc,EAAE,EAAE;IAClB,MAAM,CAAC,OAAO;QACZ,OAAO;YACL,cAAc,CAAC,IAAI;gBACjB,IACE,IAAI,CAAC,MAAM,CAAC,IAAI,KAAK,kBAAkB;oBACvC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,KAAK,YAAY;oBACxC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,KAAK,MAAM;oBAClC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,KAAK,YAAY;oBAC1C,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,KAAK,MAAM;oBACpC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,KAAK,SAAS;oBACrC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,KAAK,KAAK,6BAA6B,EACzD,CAAC;oBACD,OAAO,CAAC,MAAM,CAAC;wBACb,IAAI;wBACJ,SAAS,EAAE,cAAc;qBAC1B,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;SACF,CAAC;IACJ,CAAC;CACF,CAAC,CAAC","sourcesContent":["import { ESLintUtils } from \"@typescript-eslint/utils\";\n\nconst createRule = ESLintUtils.RuleCreator(\n name =>\n `https://github.com/trackunit/manager/blob/main/libs/eslint/plugin-trackunit/src/lib/rules/${name}/${name}.ts`\n);\n\ntype MessageIds = \"noDirectMock\";\ntype Options = [];\n\nexport const noJestMockTrackunitReactCoreHooks = createRule<Options, MessageIds>({\n name: \"no-jest-mock-trackunit-react-core-hooks\",\n meta: {\n type: \"problem\",\n docs: {\n description: \"Disallow direct jest.mock() of @trackunit/react-core-hooks\",\n },\n messages: {\n noDirectMock:\n 'Don\\'t use jest.mock(\"@trackunit/react-core-hooks\"). Use mock builder from trackunitProviders(), trackunitProvidersInternal() or trackunitProvidersHost() instead.',\n },\n schema: [],\n },\n defaultOptions: [],\n create(context) {\n return {\n CallExpression(node) {\n if (\n node.callee.type === \"MemberExpression\" &&\n node.callee.object.type === \"Identifier\" &&\n node.callee.object.name === \"jest\" &&\n node.callee.property.type === \"Identifier\" &&\n node.callee.property.name === \"mock\" &&\n node.arguments[0]?.type === \"Literal\" &&\n node.arguments[0].value === \"@trackunit/react-core-hooks\"\n ) {\n context.report({\n node,\n messageId: \"noDirectMock\",\n });\n }\n },\n };\n },\n});\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-template-strings-in-classname-prop.js","sourceRoot":"","sources":["../../../../../../../../libs/eslint/plugin-trackunit/src/lib/rules/no-template-strings-in-classname-prop/no-template-strings-in-classname-prop.ts"],"names":[],"mappings":";;;AAAA,oDAAiF;AACjF,iEAAmG;AAEnG,MAAM,UAAU,GAAG,mBAAW,CAAC,WAAW,CACxC,IAAI,CAAC,EAAE,CAAC,6FAA6F,IAAI,KAAK,CAC/G,CAAC;AAKF;;;;;;;;;;;GAWG;AACU,QAAA,4BAA4B,GAAG,UAAU,CAAsB;IAC1E,IAAI,EAAE,uCAAuC;IAC7C,IAAI,EAAE;QACJ,IAAI,EAAE,YAAY;QAClB,IAAI,EAAE;YACJ,WAAW,EAAE,8FAA8F;SAC5G;QACD,QAAQ,EAAE;YACR,yBAAyB,EACvB,+LAA+L;SAClM;QACD,MAAM,EAAE,EAAE;KACX;IACD,cAAc,EAAE,EAAE;IAClB,MAAM,CAAC,OAAO;QACZ,OAAO;YACL;;;;;;eAMG;YACH,YAAY,CAAC,IAA2B;gBACtC,8DAA8D;gBAC9D,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,sBAAc,CAAC,aAAa,IAAI,CAAC,IAAA,sCAAoB,EAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;oBAC7F,OAAO;gBACT,CAAC;gBAED,yEAAyE;gBACzE,IACE,IAAI,CAAC,KAAK,EAAE,IAAI,KAAK,sBAAc,CAAC,sBAAsB;oBAC1D,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,KAAK,sBAAc,CAAC,eAAe,EAC7D,CAAC;oBACD,OAAO,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,2BAA2B,EAAE,CAAC,CAAC;gBACnE,CAAC;YACH,CAAC;YAED,kBAAkB,CAAC,IAAiC;gBAClD,MAAM,SAAS,GAAG,IAAA,gDAA8B,EAAC,IAAI,CAAC,CAAC;gBACvD,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;oBACjC,IAAI,QAAQ,CAAC,OAAO,CAAC,IAAI,KAAK,sBAAc,CAAC,eAAe,EAAE,CAAC;wBAC7D,OAAO,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,QAAQ,CAAC,UAAU,EAAE,SAAS,EAAE,2BAA2B,EAAE,CAAC,CAAC;oBACxF,CAAC;gBACH,CAAC;YACH,CAAC;SACF,CAAC;IACJ,CAAC;CACF,CAAC,CAAC","sourcesContent":["import { AST_NODE_TYPES, ESLintUtils, TSESTree } from \"@typescript-eslint/utils\";\nimport { findClassnameStringsInVariable, isClassnameAttribute } from \"../../utils/classname-utils\";\n\nconst createRule = ESLintUtils.RuleCreator(\n name => `https://github.com/trackunit/manager/blob/main/libs/eslint/plugin-trackunit/src/lib/rules/${name}.ts`\n);\n\ntype MessageIds = \"templateStringInClassName\";\ntype Options = [];\n\n/**\n * ESLint rule to disallow template strings in className prop.\n *\n * @example\n * // Bad\n * <div className={`${dynamicClass} staticClass`}>Content</div>\n *\n * // Good\n * <div className={twMerge(dynamicClassName, \"staticClassName\")}>Content</div>\n * // or\n * <div className={yourCvaMergeFunction({ yourVariantProp, className: \"extraClassName\" })}>Content</div>\n */\nexport const noTemplateStringsInClassName = createRule<Options, MessageIds>({\n name: \"no-template-strings-in-classname-prop\",\n meta: {\n type: \"suggestion\",\n docs: {\n description: \"Disallow the use of template strings in className prop to encourage better class management.\",\n },\n messages: {\n templateStringInClassName:\n \"Do not use template strings in className prop. If you wish to merge classes from different sources, use twMerge() for simple inline merging or make a cvaMerge() function if it has variants.\",\n },\n schema: [],\n },\n defaultOptions: [],\n create(context) {\n return {\n /**\n * Handle JSXAttribute with className prop that uses template strings.\n *\n * @example\n * // Bad\n * <div className={`${dynamicClass} staticClass`}>Content</div>\n */\n JSXAttribute(node: TSESTree.JSXAttribute) {\n // Check if this is a classname attribute (className or class)\n if (node.name.type !== AST_NODE_TYPES.JSXIdentifier || !isClassnameAttribute(node.name.name)) {\n return;\n }\n\n // Check if the value is a template literal in a JSX expression container\n if (\n node.value?.type === AST_NODE_TYPES.JSXExpressionContainer &&\n node.value.expression.type === AST_NODE_TYPES.TemplateLiteral\n ) {\n context.report({ node, messageId: \"templateStringInClassName\" });\n }\n },\n\n VariableDeclarator(node: TSESTree.VariableDeclarator) {\n const locations = findClassnameStringsInVariable(node);\n for (const location of locations) {\n if (location.fixNode.type === AST_NODE_TYPES.TemplateLiteral) {\n context.report({ node: location.reportNode, messageId: \"templateStringInClassName\" });\n }\n }\n },\n };\n },\n});\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-typescript-assertion.js","sourceRoot":"","sources":["../../../../../../../../libs/eslint/plugin-trackunit/src/lib/rules/no-typescript-assertion/no-typescript-assertion.ts"],"names":[],"mappings":";;;AAAA;;;;;;;;;;;;;;GAcG;AACH,oDAAiF;AAEjF,MAAM,UAAU,GAAG,mBAAW,CAAC,WAAW,CACxC,IAAI,CAAC,EAAE,CAAC,6FAA6F,IAAI,IAAI,IAAI,KAAK,CACvH,CAAC;AAKF,SAAS,sBAAsB,CAAC,cAAiC;IAC/D,IAAI,cAAc,CAAC,IAAI,KAAK,sBAAc,CAAC,gBAAgB,EAAE,CAAC;QAC5D,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,cAAc,CAAC,IAAI,KAAK,sBAAc,CAAC,eAAe,EAAE,CAAC;QAC3D,MAAM,EAAE,QAAQ,EAAE,GAAG,cAAc,CAAC;QACpC,IAAI,QAAQ,CAAC,IAAI,KAAK,sBAAc,CAAC,UAAU,IAAI,QAAQ,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;YAC7E,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAEY,QAAA,qBAAqB,GAAG,UAAU,CAAsB;IACnE,IAAI,EAAE,yBAAyB;IAC/B,IAAI,EAAE;QACJ,IAAI,EAAE,YAAY;QAClB,IAAI,EAAE;YACJ,WAAW,EAAE,qEAAqE;SACnF;QACD,QAAQ,EAAE;YACR,qBAAqB,EAAE,wEAAwE;YAC/F,WAAW,EAAE,2EAA2E;YACxF,gBAAgB,EAAE,iFAAiF;SACpG;QACD,MAAM,EAAE,EAAE;KACX;IACD,cAAc,EAAE,EAAE;IAClB,MAAM,CAAC,OAAO;QACZ,OAAO;YACL,eAAe,CAAC,IAA8B;gBAC5C,IAAI,sBAAsB,CAAC,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC;oBAChD,OAAO;gBACT,CAAC;gBACD,OAAO,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,uBAAuB,EAAE,CAAC,CAAC;YAC/D,CAAC;YACD,cAAc,CAAC,IAA6B;gBAC1C,IAAI,sBAAsB,CAAC,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC;oBAChD,OAAO;gBACT,CAAC;gBACD,OAAO,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,aAAa,EAAE,CAAC,CAAC;YACrD,CAAC;YACD,mBAAmB,CAAC,IAAkC;gBACpD,OAAO,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,kBAAkB,EAAE,CAAC,CAAC;YAC1D,CAAC;SACF,CAAC;IACJ,CAAC;CACF,CAAC,CAAC","sourcesContent":["/**\n * ESLint rule to disallow type assertions in TypeScript.\n * Initial implementation based on eslint-plugin-no-type-assertion\n * https://github.com/Dremora/eslint-plugin-no-type-assertion/blob/master/lib/rules/no-type-assertion.js\n *\n * @example\n * // Bad - type assertions bypass type checking\n * const foo = <string> bar;\n * const baz = bar as string;\n * const qux = bar!;\n *\n * // Good - proper typing or const assertions\n * const foo = bar;\n * const options = [\"a\", \"b\"] as const;\n */\nimport { AST_NODE_TYPES, ESLintUtils, TSESTree } from \"@typescript-eslint/utils\";\n\nconst createRule = ESLintUtils.RuleCreator(\n name => `https://github.com/trackunit/manager/blob/main/libs/eslint/plugin-trackunit/src/lib/rules/${name}/${name}.ts`\n);\n\ntype MessageIds = \"angleBracketAssertion\" | \"asAssertion\" | \"nonNullAssertion\";\ntype Options = [];\n\nfunction isAllowedTypeAssertion(typeAnnotation: TSESTree.TypeNode): boolean {\n if (typeAnnotation.type === AST_NODE_TYPES.TSUnknownKeyword) {\n return true;\n }\n if (typeAnnotation.type === AST_NODE_TYPES.TSTypeReference) {\n const { typeName } = typeAnnotation;\n if (typeName.type === AST_NODE_TYPES.Identifier && typeName.name === \"const\") {\n return true;\n }\n }\n return false;\n}\n\nexport const noTypescriptAssertion = createRule<Options, MessageIds>({\n name: \"no-typescript-assertion\",\n meta: {\n type: \"suggestion\",\n docs: {\n description: \"Prevent the use of type assertions to encourage better type safety.\",\n },\n messages: {\n angleBracketAssertion: \"Avoid using angle bracket for type casting. It bypasses type checking.\",\n asAssertion: \"Avoid using the `as` keyword for type casting. It bypasses type checking.\",\n nonNullAssertion: \"Avoid using the non-null assertion operator (!). It can lead to runtime errors.\",\n },\n schema: [],\n },\n defaultOptions: [],\n create(context) {\n return {\n TSTypeAssertion(node: TSESTree.TSTypeAssertion) {\n if (isAllowedTypeAssertion(node.typeAnnotation)) {\n return;\n }\n context.report({ node, messageId: \"angleBracketAssertion\" });\n },\n TSAsExpression(node: TSESTree.TSAsExpression) {\n if (isAllowedTypeAssertion(node.typeAnnotation)) {\n return;\n }\n context.report({ node, messageId: \"asAssertion\" });\n },\n TSNonNullExpression(node: TSESTree.TSNonNullExpression) {\n context.report({ node, messageId: \"nonNullAssertion\" });\n },\n };\n },\n});\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"one-component-per-file.js","sourceRoot":"","sources":["../../../../../../../../libs/eslint/plugin-trackunit/src/lib/rules/one-component-per-file/one-component-per-file.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;GAmBG;;;AAEH,oDAAuD;AACvD,iEAAyE;AAEzE,MAAM,UAAU,GAAG,mBAAW,CAAC,WAAW,CACxC,IAAI,CAAC,EAAE,CAAC,6FAA6F,IAAI,IAAI,IAAI,KAAK,CACvH,CAAC;AAMW,QAAA,mBAAmB,GAAG,UAAU,CAAsB;IACjE,IAAI,EAAE,wBAAwB;IAC9B,IAAI,EAAE;QACJ,IAAI,EAAE,YAAY;QAClB,IAAI,EAAE;YACJ,WAAW,EACT,+DAA+D;gBAC/D,4EAA4E;SAC/E;QACD,QAAQ,EAAE;YACR,eAAe,EAAE,sFAAsF;YACvG,iBAAiB,EAAE,8EAA8E;SAClG;QACD,MAAM,EAAE;YACN;gBACE,IAAI,EAAE,QAAQ;gBACd,UAAU,EAAE;oBACV,YAAY,EAAE;wBACZ,IAAI,EAAE,SAAS;wBACf,WAAW,EACT,6DAA6D;4BAC7D,gEAAgE;qBACnE;iBACF;gBACD,oBAAoB,EAAE,KAAK;aAC5B;SACF;KACF;IACD,cAAc,EAAE,CAAC,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC;IACxC,MAAM,CAAC,OAAO,EAAE,CAAC,EAAE,YAAY,GAAG,IAAI,EAAE,CAAC;QACvC,MAAM,OAAO,GAAG,IAAA,4CAA0B,GAAE,CAAC;QAE7C,OAAO;YACL,mBAAmB,EAAE,OAAO,CAAC,qBAAqB;YAClD,kBAAkB,EAAE,OAAO,CAAC,oBAAoB;YAChD,sBAAsB,EAAE,OAAO,CAAC,wBAAwB;YACxD,wBAAwB,EAAE,OAAO,CAAC,0BAA0B;YAE5D,cAAc;gBACZ,MAAM,UAAU,GAAG,YAAY,CAAC,CAAC,CAAC,OAAO,CAAC,qBAAqB,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,gBAAgB,EAAE,CAAC;gBAE/F,IAAI,UAAU,CAAC,MAAM,IAAI,CAAC;oBAAE,OAAO;gBAEnC,MAAM,SAAS,GAAe,YAAY,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,mBAAmB,CAAC;gBAErF,KAAK,MAAM,EAAE,IAAI,EAAE,IAAI,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;oBAC3C,OAAO,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC;gBACtC,CAAC;YACH,CAAC;SACF,CAAC;IACJ,CAAC;CACF,CAAC,CAAC","sourcesContent":["/**\n * ESLint rule: one-component-per-file\n *\n * Enforces that each file contains at most one React component.\n *\n * Default mode (`exportedOnly: true`): only one exported component is allowed.\n * Internal/private components are fine.\n *\n * Strict mode (`exportedOnly: false`): only one component total, regardless of\n * whether it is exported.\n *\n * @example\n * // Bad (default) — two exported components\n * export function Foo() { return <div />; }\n * export function Bar() { return <span />; }\n *\n * // Good (default) — one exported, one internal\n * function InternalHelper() { return <span />; }\n * export function Foo() { return <div><InternalHelper /></div>; }\n */\n\nimport { ESLintUtils } from \"@typescript-eslint/utils\";\nimport { createComponentFileTracker } from \"../../utils/component-utils\";\n\nconst createRule = ESLintUtils.RuleCreator(\n name => `https://github.com/trackunit/manager/blob/main/libs/eslint/plugin-trackunit/src/lib/rules/${name}/${name}.ts`\n);\n\ntype MessageIds = \"tooManyExported\" | \"tooManyComponents\";\n\ntype Options = [{ exportedOnly?: boolean }];\n\nexport const oneComponentPerFile = createRule<Options, MessageIds>({\n name: \"one-component-per-file\",\n meta: {\n type: \"suggestion\",\n docs: {\n description:\n \"Enforce that each file contains at most one React component. \" +\n \"Use exportedOnly: false to also disallow multiple non-exported components.\",\n },\n messages: {\n tooManyExported: \"Only one component should be exported per file. Move this component to its own file.\",\n tooManyComponents: \"Only one component is allowed per file. Move this component to its own file.\",\n },\n schema: [\n {\n type: \"object\",\n properties: {\n exportedOnly: {\n type: \"boolean\",\n description:\n \"When true (default), only exported components are counted. \" +\n \"When false, all components in the file count toward the limit.\",\n },\n },\n additionalProperties: false,\n },\n ],\n },\n defaultOptions: [{ exportedOnly: true }],\n create(context, [{ exportedOnly = true }]) {\n const tracker = createComponentFileTracker();\n\n return {\n FunctionDeclaration: tracker.onFunctionDeclaration,\n VariableDeclarator: tracker.onVariableDeclarator,\n ExportNamedDeclaration: tracker.onExportNamedDeclaration,\n ExportDefaultDeclaration: tracker.onExportDefaultDeclaration,\n\n \"Program:exit\"() {\n const components = exportedOnly ? tracker.getExportedComponents() : tracker.getAllComponents();\n\n if (components.length <= 1) return;\n\n const messageId: MessageIds = exportedOnly ? \"tooManyExported\" : \"tooManyComponents\";\n\n for (const { node } of components.slice(1)) {\n context.report({ node, messageId });\n }\n },\n };\n },\n});\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prefer-destructured-imports.js","sourceRoot":"","sources":["../../../../../../../../libs/eslint/plugin-trackunit/src/lib/rules/prefer-destructured-imports/prefer-destructured-imports.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @fileoverview Enforce destructured imports instead of namespace imports for configured packages.\n * This rule helps maintain consistent import styles by converting namespace imports and detecting global UMD usage.\n * @example\n * // ❌ Bad (namespace import)\n * import React from \"react\";\n * const Component = () => {\n * React.useEffect(() => {}, []);\n * return <div />;\n * };\n *\n * // ✅ Good (destructured import)\n * import { useEffect } from \"react\";\n * const Component = () => {\n * useEffect(() => {}, []);\n * return <div />;\n * };\n * @example\n * // ❌ Bad (global UMD usage without import)\n * interface Props {\n * children: React.ReactNode;\n * }\n *\n * // ✅ Good (explicit import)\n * import { ReactNode } from \"react\";\n * interface Props {\n * children: ReactNode;\n * }\n */\n\nimport { AST_NODE_TYPES, ESLintUtils, TSESTree } from \"@typescript-eslint/utils\";\nimport { addImportSpecifiers, replaceNamespaceWithDestructured } from \"../../utils/import-utils\";\n\nconst createRule = ESLintUtils.RuleCreator(\n name => `https://github.com/trackunit/manager/blob/main/libs/eslint/plugin-trackunit/src/lib/rules/${name}.ts`\n);\n\ntype MessageIds = \"preferDestructured\" | \"preferDestructuredGlobal\";\n\ntype PackageConfig = {\n /** Mapping of package names to their global UMD variable names (e.g., { \"react\": \"React\", \"lodash\": \"_\" }) */\n packages: Record<string, string>;\n};\n\ntype Options = [PackageConfig?];\n\n/**\n * ESLint rule: prefer-destructured-imports\n *\n * ## Configuration\n *\n * This rule requires explicit configuration to specify which packages to enforce.\n * Without configuration, the rule does nothing.\n *\n * @example\n * // .eslintrc.js - Enforce for React\n * {\n * \"rules\": {\n * \"@trackunit/prefer-destructured-imports\": [\"error\", {\n * \"packages\": {\n * \"react\": \"React\"\n * }\n * }]\n * }\n * }\n * @example\n * // .eslintrc.js - Multiple packages\n * {\n * \"rules\": {\n * \"@trackunit/prefer-destructured-imports\": [\"error\", {\n * \"packages\": {\n * \"react\": \"React\",\n * \"lodash\": \"_\",\n * \"jquery\": \"$\"\n * }\n * }]\n * }\n * }\n */\nexport const preferDestructuredImports = createRule<Options, MessageIds>({\n name: \"prefer-destructured-imports\",\n meta: {\n type: \"suggestion\",\n docs: {\n description: \"Prefer destructured imports instead of namespace imports for certain packages\",\n },\n fixable: \"code\",\n schema: [\n {\n type: \"object\",\n properties: {\n packages: {\n type: \"object\",\n description: \"Mapping of package names to their global UMD variable names (e.g., { 'react': 'React' })\",\n additionalProperties: {\n type: \"string\",\n },\n },\n },\n additionalProperties: false,\n },\n ],\n messages: {\n preferDestructured: \"Prefer destructured imports instead of namespace imports\",\n preferDestructuredGlobal:\n \"Import '{{members}}' from '{{packageName}}' instead of using the global {{globalName}} variable\",\n },\n },\n defaultOptions: [],\n create(context) {\n const sourceCode = context.sourceCode;\n const options = context.options[0];\n\n // Return early if no packages are configured\n if (options === undefined || Object.keys(options.packages).length === 0) {\n return {};\n }\n\n const packageToGlobalName = options.packages;\n const targetPackages = Object.keys(packageToGlobalName);\n\n // Helper to check if a string is a valid/configured package name\n const isValidPackageName = (value: string): boolean => {\n return targetPackages.includes(value);\n };\n\n // Track which global identifiers are actually imported (to avoid false positives)\n const importedGlobalIdentifiers = new Set<string>();\n\n const namespaceImports = new Map<string, { node: TSESTree.ImportDeclaration; existingSpecifiers: Set<string> }>();\n const usagesByImport = new Map<string, Map<number, { name: string; start: number; end: number }>>();\n\n // Track usages of global identifiers that aren't imported (e.g., React.ReactElement without importing React)\n const globalUsages = new Map<string, { packageName: string; members: Set<string>; nodes: Array<TSESTree.Node> }>();\n\n return {\n ImportDeclaration(node: TSESTree.ImportDeclaration) {\n const sourceValue = node.source.value;\n if (typeof sourceValue === \"string\" && isValidPackageName(sourceValue)) {\n const globalName = packageToGlobalName[sourceValue];\n\n // Get any existing destructured imports\n const existingSpecifiers = new Set(\n node.specifiers\n .filter((s): s is TSESTree.ImportSpecifier => s.type === AST_NODE_TYPES.ImportSpecifier)\n .map(s => s.local.name)\n );\n\n // Find the namespace or default import if it exists\n const namespaceOrDefaultSpecifier = node.specifiers.find(\n (s): s is TSESTree.ImportDefaultSpecifier | TSESTree.ImportNamespaceSpecifier =>\n s.type === AST_NODE_TYPES.ImportDefaultSpecifier || s.type === AST_NODE_TYPES.ImportNamespaceSpecifier\n );\n\n if (namespaceOrDefaultSpecifier) {\n const importName = namespaceOrDefaultSpecifier.local.name;\n // Only mark this global as imported if the import name matches the global name\n // This prevents false positives when someone imports React as a different name\n if (importName === globalName) {\n importedGlobalIdentifiers.add(globalName);\n }\n\n // If this import also has destructured specifiers, store it as both\n if (existingSpecifiers.size > 0) {\n namespaceImports.set(\"destructured\", { node, existingSpecifiers });\n }\n namespaceImports.set(importName, { node, existingSpecifiers });\n usagesByImport.set(importName, new Map());\n } else if (existingSpecifiers.size > 0) {\n // Store pure destructured imports\n namespaceImports.set(\"destructured\", { node, existingSpecifiers });\n // Do NOT mark the global as imported - we want to catch global usage even with destructured imports\n }\n }\n },\n\n // Handle React.something in regular code\n MemberExpression(node: TSESTree.MemberExpression) {\n const objectNode = node.object;\n\n if (objectNode.type === AST_NODE_TYPES.Identifier && node.property.type === AST_NODE_TYPES.Identifier) {\n // Check if this is a tracked namespace import\n if (namespaceImports.has(objectNode.name)) {\n const usages = usagesByImport.get(objectNode.name);\n if (usages) {\n usages.set(node.range[0], {\n name: node.property.name,\n start: node.range[0],\n end: node.range[1],\n });\n }\n }\n // Check if this is a global identifier usage (e.g., React.ReactElement without import)\n else if (!importedGlobalIdentifiers.has(objectNode.name)) {\n // Find if this identifier matches any of our configured global names\n for (const packageName of targetPackages) {\n const globalName = packageToGlobalName[packageName];\n if (objectNode.name === globalName) {\n if (!globalUsages.has(globalName)) {\n globalUsages.set(globalName, {\n packageName: packageName,\n members: new Set(),\n nodes: [],\n });\n }\n const usage = globalUsages.get(globalName);\n if (usage) {\n usage.members.add(node.property.name);\n usage.nodes.push(node);\n }\n break;\n }\n }\n }\n }\n },\n\n // Handle React.ReactNode in type annotations\n TSQualifiedName(node: TSESTree.TSQualifiedName) {\n if (node.left.type === AST_NODE_TYPES.Identifier) {\n // Check if this is a tracked namespace import\n if (namespaceImports.has(node.left.name)) {\n const usages = usagesByImport.get(node.left.name);\n if (usages) {\n usages.set(node.range[0], {\n name: node.right.name,\n start: node.range[0],\n end: node.range[1],\n });\n }\n }\n // Check if this is a global identifier usage\n else if (!importedGlobalIdentifiers.has(node.left.name)) {\n for (const packageName of targetPackages) {\n const globalName = packageToGlobalName[packageName];\n if (node.left.name === globalName) {\n if (!globalUsages.has(globalName)) {\n globalUsages.set(globalName, {\n packageName: packageName,\n members: new Set(),\n nodes: [],\n });\n }\n const usage = globalUsages.get(globalName);\n if (usage) {\n usage.members.add(node.right.name);\n usage.nodes.push(node);\n }\n break;\n }\n }\n }\n }\n },\n\n // Note: TSQualifiedName already handles React.ReactElement, React.RefObject, etc.\n // This visitor is kept for potential future expansion but currently does nothing\n // to avoid duplicate tracking with TSQualifiedName\n TSTypeReference(_node: TSESTree.TSTypeReference) {\n // TSQualifiedName visitor handles all qualified type names (React.Something)\n // No action needed here\n },\n\n \"Program:exit\"() {\n // Report errors for namespace imports\n for (const [importName, { node: importNode }] of namespaceImports) {\n const usages = usagesByImport.get(importName);\n if (!usages || usages.size === 0) {\n continue;\n }\n\n const sourceValue = importNode.source.value;\n\n if (typeof sourceValue !== \"string\" || !isValidPackageName(sourceValue)) {\n continue;\n }\n\n context.report({\n node: importNode,\n messageId: \"preferDestructured\",\n fix(fixer) {\n const fixes = [];\n\n // Collect all specifiers needed from usages (e.g., [\"useState\", \"useEffect\"] from React.useState, React.useEffect)\n const specifiersFromUsages = Array.from(usages.values()).map(usage => usage.name);\n\n // Check if there's a separate destructured import to merge with\n const existingDestructured = namespaceImports.get(\"destructured\");\n const otherDestructuredImport =\n existingDestructured && existingDestructured.node !== importNode\n ? existingDestructured.node\n : undefined;\n\n // Replace the namespace import with destructured imports (merges if other import exists)\n fixes.push(\n ...replaceNamespaceWithDestructured({\n sourceCode,\n fixer,\n packageName: sourceValue,\n namespaceImportToReplace: importNode,\n specifiersToAdd: specifiersFromUsages,\n mergeIntoImport: otherDestructuredImport,\n })\n );\n\n // Remove namespace/default prefix from all usages\n for (const { start, end } of usages.values()) {\n const text = sourceCode.getText().slice(start, end);\n const newText = text.replace(new RegExp(`^${importName}\\\\.`), \"\");\n fixes.push(fixer.replaceTextRange([start, end], newText));\n }\n\n return fixes;\n },\n });\n }\n\n // Report errors for global UMD variable usages (e.g., React.ReactElement without import)\n for (const [globalName, { packageName, members, nodes }] of globalUsages) {\n if (members.size === 0 || nodes.length === 0) {\n continue;\n }\n\n // Report on the first usage node\n const firstNode = nodes[0];\n if (!firstNode) {\n continue;\n }\n\n const membersList = Array.from(members);\n const existingDestructured = namespaceImports.get(\"destructured\");\n\n // Filter out members that are already imported (no need to add them again)\n const membersToAdd = existingDestructured\n ? membersList.filter(member => !existingDestructured.existingSpecifiers.has(member))\n : membersList;\n\n context.report({\n node: firstNode,\n messageId: \"preferDestructuredGlobal\",\n data: {\n globalName,\n packageName,\n members: membersList.sort().join(\", \"), // Sort only for display in error message\n },\n fix(fixer) {\n const fixes = [];\n\n // Only update imports if there are new members to add\n if (membersToAdd.length > 0) {\n fixes.push(\n ...addImportSpecifiers({\n sourceCode,\n fixer,\n packageName,\n specifiers: membersToAdd,\n existingImport: existingDestructured?.node,\n })\n );\n }\n\n // Replace all global usages (React.X → X)\n // Deduplicate nodes by range and sort by position (reverse order to maintain positions)\n const uniqueNodesByRange = new Map<string, TSESTree.Node>();\n for (const node of nodes) {\n const rangeKey = `${node.range[0]}-${node.range[1]}`;\n if (!uniqueNodesByRange.has(rangeKey)) {\n uniqueNodesByRange.set(rangeKey, node);\n }\n }\n\n const sortedNodes = Array.from(uniqueNodesByRange.values()).sort((a, b) => b.range[0] - a.range[0]);\n\n for (const node of sortedNodes) {\n const nodeText = sourceCode.getText(node);\n const newText = nodeText.replace(new RegExp(`^${globalName}\\\\.`), \"\");\n fixes.push(fixer.replaceText(node, newText));\n }\n\n return fixes;\n },\n });\n }\n },\n };\n },\n});\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"name-suggestion-strategies.js","sourceRoot":"","sources":["../../../../../../../../libs/eslint/plugin-trackunit/src/lib/rules/prefer-event-specific-callback-naming/name-suggestion-strategies.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Strategy-based name suggestion system for the prefer-event-specific-callback-naming rule.\n *\n * This module provides a structured, extensible approach to generating suggested names\n * for callback functions based on different naming patterns. Each strategy handles a\n * specific type of problematic name and knows how to transform it correctly.\n *\n * Strategies are evaluated in order - the first matching strategy wins.\n */\n\n/**\n * Context passed to name suggestion strategies.\n */\nexport type NameSuggestionContext = {\n /** The current callback name (e.g., \"onPrimary\", \"onClose\", \"handleClick\") */\n callbackName: string;\n /** The event handler prop name (e.g., \"onClick\", \"primaryAction\", \"onSubmit\") */\n eventName: string;\n};\n\n/**\n * A strategy for suggesting renamed callback names.\n * Each strategy handles a specific pattern of problematic naming.\n */\nexport type NameSuggestionStrategy = {\n /** Human-readable name for debugging and logging */\n name: string;\n /** Returns true if this strategy should handle the given context */\n matches: (ctx: NameSuggestionContext) => boolean;\n /** Returns the suggested name for the callback */\n suggest: (ctx: NameSuggestionContext) => string;\n};\n\n// =============================================================================\n// Helper Functions\n// =============================================================================\n\n/**\n * Capitalizes the first letter of a string.\n *\n * @example capitalize(\"primary\") // \"Primary\"\n */\nconst capitalize = (str: string): string => {\n if (str.length === 0) return str;\n return str.charAt(0).toUpperCase() + str.slice(1);\n};\n\n// =============================================================================\n// Strategy Implementations\n// =============================================================================\n\n/**\n * Strategy: Handle `*Action` suffix event names.\n *\n * When the event prop ends with \"Action\" (e.g., \"primaryAction\", \"secondaryAction\"),\n * the prop itself is poorly named for a click handler. We extract the prefix and\n * construct a proper onClick* name.\n *\n * @example\n * - eventName: \"primaryAction\", callbackName: \"onPrimary\" → \"onClickPrimary\"\n * - eventName: \"secondaryAction\", callbackName: \"action\" → \"onClickSecondary\"\n * - eventName: \"primaryAction\", callbackName: \"foo\" → \"onClickPrimary\"\n */\nconst actionSuffixEventStrategy: NameSuggestionStrategy = {\n name: \"actionSuffixEventStrategy\",\n\n matches: (ctx: NameSuggestionContext): boolean => {\n // Matches when the event name ends with \"Action\" (case-sensitive)\n return ctx.eventName.endsWith(\"Action\");\n },\n\n suggest: (ctx: NameSuggestionContext): string => {\n // Extract the prefix before \"Action\" (e.g., \"primary\" from \"primaryAction\")\n const prefix = ctx.eventName.slice(0, -\"Action\".length);\n\n // If the callback starts with \"on\", extract its semantic part\n // e.g., \"onPrimary\" → \"Primary\", \"onConfirm\" → \"Confirm\"\n if (ctx.callbackName.startsWith(\"on\") && ctx.callbackName.length > 2) {\n const callbackSuffix = ctx.callbackName.slice(2);\n\n // If the callback suffix matches the event prefix (case-insensitive),\n // use the callback's casing for consistency\n // e.g., eventName: \"primaryAction\", callbackName: \"onPrimary\" → \"onClickPrimary\"\n if (callbackSuffix.toLowerCase() === prefix.toLowerCase()) {\n return `onClick${callbackSuffix}`;\n }\n\n // Otherwise, combine both for clarity\n // e.g., eventName: \"primaryAction\", callbackName: \"onConfirm\" → \"onClickPrimaryConfirm\"\n return `onClick${capitalize(prefix)}${callbackSuffix}`;\n }\n\n // For non-\"on\" prefixed callbacks, just use the event prefix\n // e.g., eventName: \"primaryAction\", callbackName: \"foo\" → \"onClickPrimary\"\n return `onClick${capitalize(prefix)}`;\n },\n};\n\n/**\n * Strategy: Handle `*Handler` suffix event names.\n *\n * When the event prop ends with \"Handler\" (e.g., \"clickHandler\", \"submitHandler\"),\n * the prop itself is poorly named. We extract the prefix and construct a proper onClick* name.\n *\n * @example\n * - eventName: \"clickHandler\", callbackName: \"onClose\" → \"onClickClose\"\n * - eventName: \"submitHandler\", callbackName: \"foo\" → \"onClickSubmit\"\n */\nconst handlerSuffixEventStrategy: NameSuggestionStrategy = {\n name: \"handlerSuffixEventStrategy\",\n\n matches: (ctx: NameSuggestionContext): boolean => {\n // Matches when the event name ends with \"Handler\" (case-sensitive)\n return ctx.eventName.endsWith(\"Handler\");\n },\n\n suggest: (ctx: NameSuggestionContext): string => {\n // Extract the prefix before \"Handler\" (e.g., \"click\" from \"clickHandler\")\n const prefix = ctx.eventName.slice(0, -\"Handler\".length);\n\n // If the callback starts with \"on\", extract its semantic part\n if (ctx.callbackName.startsWith(\"on\") && ctx.callbackName.length > 2) {\n const callbackSuffix = ctx.callbackName.slice(2);\n return `onClick${capitalize(prefix)}${callbackSuffix}`;\n }\n\n // For non-\"on\" prefixed callbacks\n return `onClick${capitalize(prefix)}`;\n },\n};\n\n/**\n * Strategy: Handle `on*` callback → `onClick` event.\n *\n * When a callback starts with \"on\" (but not \"onClick\") and is passed to an onClick handler,\n * we replace the \"on\" prefix with \"onClick\".\n *\n * @example\n * - eventName: \"onClick\", callbackName: \"onClose\" → \"onClickClose\"\n * - eventName: \"onClick\", callbackName: \"onCancel\" → \"onClickCancel\"\n */\nconst onPrefixCallbackToClickEventStrategy: NameSuggestionStrategy = {\n name: \"onPrefixCallbackToClickEventStrategy\",\n\n matches: (ctx: NameSuggestionContext): boolean => {\n return ctx.eventName === \"onClick\" && ctx.callbackName.startsWith(\"on\") && !ctx.callbackName.startsWith(\"onClick\");\n },\n\n suggest: (ctx: NameSuggestionContext): string => {\n // Replace \"on\" with \"onClick\"\n // e.g., \"onClose\" → \"onClickClose\"\n const suffix = ctx.callbackName.slice(2);\n return `onClick${suffix}`;\n },\n};\n\n/**\n * Strategy: Handle `on*` callback → generic `on*` event (not onClick).\n *\n * When a callback starts with \"on\" and is passed to a different on* event handler\n * (like onMouseDown, onSubmit, etc.), we replace the \"on\" prefix with the event name.\n *\n * @example\n * - eventName: \"onMouseDown\", callbackName: \"onClose\" → \"onMouseDownClose\"\n * - eventName: \"onSubmit\", callbackName: \"onConfirm\" → \"onSubmitConfirm\"\n */\nconst onPrefixCallbackToGenericEventStrategy: NameSuggestionStrategy = {\n name: \"onPrefixCallbackToGenericEventStrategy\",\n\n matches: (ctx: NameSuggestionContext): boolean => {\n return (\n ctx.eventName.startsWith(\"on\") &&\n ctx.eventName !== \"onClick\" &&\n ctx.callbackName.startsWith(\"on\") &&\n !ctx.callbackName.startsWith(ctx.eventName)\n );\n },\n\n suggest: (ctx: NameSuggestionContext): string => {\n const callbackSuffix = ctx.callbackName.slice(2);\n\n // Avoid duplication: if event name already ends with the suffix, just use the event name\n // e.g., eventName: \"onClickClose\", callbackName: \"onClose\" → \"onClickClose\"\n if (ctx.eventName.toLowerCase().endsWith(callbackSuffix.toLowerCase())) {\n return ctx.eventName;\n }\n\n return `${ctx.eventName}${callbackSuffix}`;\n },\n};\n\n/**\n * Strategy: Default fallback.\n *\n * For any callback that doesn't match other patterns, capitalize and prepend\n * the event name.\n *\n * @example\n * - eventName: \"onClick\", callbackName: \"myCallback\" → \"onClickMyCallback\"\n * - eventName: \"onClick\", callbackName: \"close\" → \"onClickClose\"\n */\nconst defaultCapitalizeStrategy: NameSuggestionStrategy = {\n name: \"defaultCapitalizeStrategy\",\n\n matches: (): boolean => {\n // Always matches as a fallback\n return true;\n },\n\n suggest: (ctx: NameSuggestionContext): string => {\n const capitalizedName = capitalize(ctx.callbackName);\n return `${ctx.eventName}${capitalizedName}`;\n },\n};\n\n// =============================================================================\n// Strategy Registry\n// =============================================================================\n\n/**\n * Ordered list of strategies. First matching strategy wins.\n *\n * Order matters:\n * 1. Specific patterns (Action suffix, Handler suffix) first\n * 2. General patterns (on* prefix) next\n * 3. Default fallback last\n */\nconst strategies: ReadonlyArray<NameSuggestionStrategy> = [\n actionSuffixEventStrategy,\n handlerSuffixEventStrategy,\n onPrefixCallbackToClickEventStrategy,\n onPrefixCallbackToGenericEventStrategy,\n defaultCapitalizeStrategy,\n];\n\n// =============================================================================\n// Public API\n// =============================================================================\n\n/**\n * Generates a suggested name for a callback based on the event it's passed to.\n *\n * Uses a strategy pattern to handle different naming conventions appropriately.\n * The first matching strategy determines the suggested name.\n *\n * @param ctx - The naming context with callback and event names\n * @returns The suggested name for the callback\n * @example\n * getSuggestedName({ callbackName: \"onClose\", eventName: \"onClick\" })\n * // Returns: \"onClickClose\"\n *\n * getSuggestedName({ callbackName: \"onPrimary\", eventName: \"primaryAction\" })\n * // Returns: \"onClickPrimary\"\n */\nexport const getSuggestedName = (ctx: NameSuggestionContext): string => {\n for (const strategy of strategies) {\n if (strategy.matches(ctx)) {\n return strategy.suggest(ctx);\n }\n }\n\n // Should never reach here since defaultCapitalizeStrategy always matches,\n // but TypeScript doesn't know that\n return defaultCapitalizeStrategy.suggest(ctx);\n};\n\n/**\n * Exported for testing purposes - allows testing individual strategies.\n */\nexport const testableStrategies = {\n actionSuffixEventStrategy,\n handlerSuffixEventStrategy,\n onPrefixCallbackToClickEventStrategy,\n onPrefixCallbackToGenericEventStrategy,\n defaultCapitalizeStrategy,\n};\n"]}
|