eslint-plugin-sanity 0.1.0 → 0.1.2

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/README.md CHANGED
@@ -17,9 +17,9 @@ npm install eslint-plugin-sanity
17
17
  import sanity from 'eslint-plugin-sanity'
18
18
 
19
19
  export default [
20
- sanity.configs.recommended,
20
+ ...sanity.configs.recommended,
21
21
  // or for stricter checking:
22
- // sanity.configs.strict,
22
+ // ...sanity.configs.strict,
23
23
  ]
24
24
  ```
25
25
 
@@ -60,7 +60,10 @@ All rules enabled as errors.
60
60
 
61
61
  ### GROQ Rules
62
62
 
63
- These rules lint GROQ queries in `groq\`...\`` tagged template literals.
63
+ These rules lint GROQ queries in:
64
+
65
+ - `groq\`...\`` tagged template literals
66
+ - `defineQuery('...')` function calls (from `next-sanity` or `@sanity/client`)
64
67
 
65
68
  | Rule | Default | Description |
66
69
  | ------------------------------------------ | ------- | ----------------------------------------------- |
@@ -109,8 +112,8 @@ For schema-aware rules (`unknown-field`, `invalid-type-filter`), you need to pro
109
112
  import sanity from 'eslint-plugin-sanity'
110
113
 
111
114
  export default [
115
+ ...sanity.configs.recommended,
112
116
  {
113
- ...sanity.configs.recommended,
114
117
  settings: {
115
118
  sanity: {
116
119
  schemaPath: './schema.json',
@@ -126,6 +129,45 @@ Generate `schema.json` with:
126
129
  npx sanity schema extract
127
130
  ```
128
131
 
132
+ ## Monorepo Setup
133
+
134
+ When using eslint-plugin-sanity in a monorepo (turborepo, pnpm workspaces, etc.), VS Code/Cursor may have trouble finding the ESLint config for nested packages.
135
+
136
+ ### VS Code / Cursor Settings
137
+
138
+ Create `.vscode/settings.json` at your **monorepo root**:
139
+
140
+ ```json
141
+ {
142
+ "eslint.workingDirectories": [
143
+ { "directory": "apps/web", "changeProcessCWD": true },
144
+ { "directory": "apps/studio", "changeProcessCWD": true }
145
+ ]
146
+ }
147
+ ```
148
+
149
+ Replace the paths with your actual package directories that have ESLint configs.
150
+
151
+ ### Alternative: Auto-detect
152
+
153
+ You can also let ESLint auto-detect working directories:
154
+
155
+ ```json
156
+ {
157
+ "eslint.workingDirectories": [{ "mode": "auto" }]
158
+ }
159
+ ```
160
+
161
+ ### Troubleshooting
162
+
163
+ If rules still don't appear in the editor:
164
+
165
+ 1. **Restart ESLint Server**: `Cmd+Shift+P` → "ESLint: Restart ESLint Server"
166
+ 2. **Check ESLint Output**: View → Output → select "ESLint" to see errors
167
+ 3. **Verify flat config**: Ensure `eslint.config.mjs` exists in your package directory
168
+
169
+ > **Note**: The CLI (`npx eslint .`) works regardless of these settings. This is purely for editor integration.
170
+
129
171
  ## License
130
172
 
131
173
  MIT
package/dist/index.cjs CHANGED
@@ -500,7 +500,7 @@ function createAllSchemaRules(rules2) {
500
500
  }
501
501
 
502
502
  // src/index.ts
503
- var version = true ? "0.1.0" : "0.0.0";
503
+ var version = true ? "0.1.2" : "0.0.0";
504
504
  var groqEslintRules = createAllRules(import_groq_lint2.rules);
505
505
  var schemaEslintRules = createAllSchemaRules(import_schema_lint2.rules);
506
506
  var rules = {
@@ -514,54 +514,58 @@ var plugin = {
514
514
  },
515
515
  rules
516
516
  };
517
- var recommended = {
518
- plugins: {
519
- sanity: plugin
520
- },
521
- rules: {
522
- // === GROQ Rules ===
523
- // Errors - these are serious performance or correctness issues
524
- "sanity/groq-join-in-filter": "error",
525
- // Warnings - performance issues that should be addressed
526
- "sanity/groq-deep-pagination": "warn",
527
- "sanity/groq-large-pages": "warn",
528
- "sanity/groq-many-joins": "warn",
529
- "sanity/groq-computed-value-in-filter": "warn",
530
- "sanity/groq-non-literal-comparison": "warn",
531
- "sanity/groq-order-on-expr": "warn",
532
- "sanity/groq-very-large-query": "warn",
533
- "sanity/groq-extremely-large-query": "error",
534
- // Info - suggestions for improvement (off by default, enable as warnings)
535
- "sanity/groq-join-to-get-id": "warn",
536
- "sanity/groq-repeated-dereference": "warn",
537
- "sanity/groq-match-on-id": "warn",
538
- "sanity/groq-count-in-correlated-subquery": "warn",
539
- "sanity/groq-deep-pagination-param": "warn",
540
- // === Schema Rules ===
541
- // Errors - correctness issues
542
- "sanity/schema-missing-define-type": "error",
543
- "sanity/schema-missing-define-field": "error",
544
- "sanity/schema-reserved-field-name": "error",
545
- // Warnings - best practice violations
546
- "sanity/schema-missing-icon": "warn",
547
- "sanity/schema-missing-title": "warn",
548
- "sanity/schema-presentation-field-name": "warn",
549
- "sanity/schema-missing-slug-source": "warn",
550
- "sanity/schema-missing-required-validation": "warn",
551
- "sanity/schema-heading-level-in-schema": "warn",
552
- // Info - suggestions (off by default)
553
- "sanity/schema-missing-description": "off",
554
- "sanity/schema-boolean-instead-of-list": "off",
555
- "sanity/schema-array-missing-constraints": "off",
556
- "sanity/schema-unnecessary-reference": "off"
517
+ var recommended = [
518
+ {
519
+ plugins: {
520
+ sanity: plugin
521
+ },
522
+ rules: {
523
+ // === GROQ Rules ===
524
+ // Errors - these are serious performance or correctness issues
525
+ "sanity/groq-join-in-filter": "error",
526
+ // Warnings - performance issues that should be addressed
527
+ "sanity/groq-deep-pagination": "warn",
528
+ "sanity/groq-large-pages": "warn",
529
+ "sanity/groq-many-joins": "warn",
530
+ "sanity/groq-computed-value-in-filter": "warn",
531
+ "sanity/groq-non-literal-comparison": "warn",
532
+ "sanity/groq-order-on-expr": "warn",
533
+ "sanity/groq-very-large-query": "warn",
534
+ "sanity/groq-extremely-large-query": "error",
535
+ // Info - suggestions for improvement (off by default, enable as warnings)
536
+ "sanity/groq-join-to-get-id": "warn",
537
+ "sanity/groq-repeated-dereference": "warn",
538
+ "sanity/groq-match-on-id": "warn",
539
+ "sanity/groq-count-in-correlated-subquery": "warn",
540
+ "sanity/groq-deep-pagination-param": "warn",
541
+ // === Schema Rules ===
542
+ // Errors - correctness issues
543
+ "sanity/schema-missing-define-type": "error",
544
+ "sanity/schema-missing-define-field": "error",
545
+ "sanity/schema-reserved-field-name": "error",
546
+ // Warnings - best practice violations
547
+ "sanity/schema-missing-icon": "warn",
548
+ "sanity/schema-missing-title": "warn",
549
+ "sanity/schema-presentation-field-name": "warn",
550
+ "sanity/schema-missing-slug-source": "warn",
551
+ "sanity/schema-missing-required-validation": "warn",
552
+ "sanity/schema-heading-level-in-schema": "warn",
553
+ // Info - suggestions (off by default)
554
+ "sanity/schema-missing-description": "off",
555
+ "sanity/schema-boolean-instead-of-list": "off",
556
+ "sanity/schema-array-missing-constraints": "off",
557
+ "sanity/schema-unnecessary-reference": "off"
558
+ }
557
559
  }
558
- };
559
- var strict = {
560
- plugins: {
561
- sanity: plugin
562
- },
563
- rules: Object.fromEntries(Object.keys(rules).map((ruleId) => [`sanity/${ruleId}`, "error"]))
564
- };
560
+ ];
561
+ var strict = [
562
+ {
563
+ plugins: {
564
+ sanity: plugin
565
+ },
566
+ rules: Object.fromEntries(Object.keys(rules).map((ruleId) => [`sanity/${ruleId}`, "error"]))
567
+ }
568
+ ];
565
569
  var configs = {
566
570
  recommended,
567
571
  strict
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/utils/rule-factory.ts","../src/utils/groq-extractor.ts","../src/utils/schema-rule-factory.ts","../src/utils/schema-extractor.ts"],"sourcesContent":["/**\n * ESLint plugin for Sanity\n *\n * This plugin provides rules for linting GROQ queries and schema definitions\n * in JavaScript/TypeScript files.\n *\n * @example\n * ```js\n * // eslint.config.js\n * import sanity from 'eslint-plugin-sanity'\n *\n * export default [\n * {\n * plugins: { sanity },\n * rules: {\n * 'sanity/groq-join-in-filter': 'error',\n * 'sanity/schema-missing-icon': 'warn',\n * },\n * },\n * ]\n * ```\n *\n * Or use the recommended config:\n * ```js\n * import sanity from 'eslint-plugin-sanity'\n *\n * export default [\n * sanity.configs.recommended,\n * ]\n * ```\n */\n\nimport type { ESLint, Linter } from 'eslint'\nimport { rules as groqRules } from '@sanity/groq-lint'\nimport { rules as schemaRules } from '@sanity/schema-lint'\nimport { createAllRules } from './utils/rule-factory'\nimport { createAllSchemaRules } from './utils/schema-rule-factory'\n\n// Version is injected at build time by tsup\ndeclare const PACKAGE_VERSION: string\nconst version = typeof PACKAGE_VERSION !== 'undefined' ? PACKAGE_VERSION : '0.0.0'\n\n// Create ESLint rules from all GROQ lint rules\nconst groqEslintRules = createAllRules(groqRules)\n\n// Create ESLint rules from all schema lint rules\nconst schemaEslintRules = createAllSchemaRules(schemaRules)\n\n// Combine all rules\nconst rules = {\n ...groqEslintRules,\n ...schemaEslintRules,\n}\n\n// Build the plugin object\nconst plugin: ESLint.Plugin = {\n meta: {\n name: 'eslint-plugin-sanity',\n version,\n },\n rules,\n}\n\n// Create recommended config\nconst recommended: Linter.Config = {\n plugins: {\n sanity: plugin,\n },\n rules: {\n // === GROQ Rules ===\n\n // Errors - these are serious performance or correctness issues\n 'sanity/groq-join-in-filter': 'error',\n\n // Warnings - performance issues that should be addressed\n 'sanity/groq-deep-pagination': 'warn',\n 'sanity/groq-large-pages': 'warn',\n 'sanity/groq-many-joins': 'warn',\n 'sanity/groq-computed-value-in-filter': 'warn',\n 'sanity/groq-non-literal-comparison': 'warn',\n 'sanity/groq-order-on-expr': 'warn',\n 'sanity/groq-very-large-query': 'warn',\n 'sanity/groq-extremely-large-query': 'error',\n\n // Info - suggestions for improvement (off by default, enable as warnings)\n 'sanity/groq-join-to-get-id': 'warn',\n 'sanity/groq-repeated-dereference': 'warn',\n 'sanity/groq-match-on-id': 'warn',\n 'sanity/groq-count-in-correlated-subquery': 'warn',\n 'sanity/groq-deep-pagination-param': 'warn',\n\n // === Schema Rules ===\n\n // Errors - correctness issues\n 'sanity/schema-missing-define-type': 'error',\n 'sanity/schema-missing-define-field': 'error',\n 'sanity/schema-reserved-field-name': 'error',\n\n // Warnings - best practice violations\n 'sanity/schema-missing-icon': 'warn',\n 'sanity/schema-missing-title': 'warn',\n 'sanity/schema-presentation-field-name': 'warn',\n 'sanity/schema-missing-slug-source': 'warn',\n 'sanity/schema-missing-required-validation': 'warn',\n 'sanity/schema-heading-level-in-schema': 'warn',\n\n // Info - suggestions (off by default)\n 'sanity/schema-missing-description': 'off',\n 'sanity/schema-boolean-instead-of-list': 'off',\n 'sanity/schema-array-missing-constraints': 'off',\n 'sanity/schema-unnecessary-reference': 'off',\n },\n}\n\n// Create strict config (all rules as errors)\nconst strict: Linter.Config = {\n plugins: {\n sanity: plugin,\n },\n rules: Object.fromEntries(Object.keys(rules).map((ruleId) => [`sanity/${ruleId}`, 'error'])),\n}\n\n// Configs with explicit type annotation\nconst configs: { recommended: Linter.Config; strict: Linter.Config } = {\n recommended,\n strict,\n}\n\n// Plugin type\ninterface SanityPlugin {\n meta: ESLint.Plugin['meta']\n rules: typeof rules\n configs: typeof configs\n}\n\n// Default export for ESLint flat config\nconst sanityPlugin: SanityPlugin = {\n meta: plugin.meta,\n rules,\n configs,\n}\n\nexport default sanityPlugin\n\n// Named exports for flexibility\nexport { rules, configs }\n","import type { Rule as ESLintRule } from 'eslint'\nimport type { TSESTree } from '@typescript-eslint/types'\nimport type { Rule as GroqRule } from '@sanity/groq-lint'\nimport { lint, rules as allGroqRules } from '@sanity/groq-lint'\nimport {\n isGroqTaggedTemplate,\n extractGroqString,\n isGroqFunctionCall,\n extractGroqStringFromCall,\n} from './groq-extractor'\n\n/**\n * Build a config that enables only the specified rule\n */\nfunction buildSingleRuleConfig(ruleId: string): Record<string, boolean> {\n const config: Record<string, boolean> = {}\n for (const rule of allGroqRules) {\n config[rule.id] = rule.id === ruleId\n }\n return config\n}\n\n/**\n * Create an ESLint rule from a GROQ lint rule.\n */\nexport function createESLintRule(groqRule: GroqRule): ESLintRule.RuleModule {\n return {\n meta: {\n type: groqRule.category === 'correctness' ? 'problem' : 'suggestion',\n docs: {\n description: groqRule.description,\n recommended: groqRule.severity === 'error',\n },\n messages: {\n [groqRule.id]: '{{ message }}',\n },\n schema: [], // No options for now\n },\n\n create(context) {\n /**\n * Lint a GROQ query and report findings\n */\n function lintQuery(query: string, eslintNode: ESLintRule.Node): void {\n try {\n const result = lint(query, { config: { rules: buildSingleRuleConfig(groqRule.id) } })\n\n for (const finding of result.findings) {\n if (finding.ruleId === groqRule.id) {\n context.report({\n node: eslintNode,\n messageId: groqRule.id,\n data: {\n message: finding.help ? `${finding.message} ${finding.help}` : finding.message,\n },\n })\n }\n }\n } catch {\n // Parse error - don't report, let the user see it in runtime\n }\n }\n\n return {\n // Handle groq`...` tagged template literals\n TaggedTemplateExpression(eslintNode: ESLintRule.Node) {\n const node = eslintNode as unknown as TSESTree.TaggedTemplateExpression\n if (!isGroqTaggedTemplate(node)) {\n return\n }\n\n const query = extractGroqString(node)\n lintQuery(query, eslintNode)\n },\n\n // Handle defineQuery(`...`) and defineQuery(\"...\") function calls\n CallExpression(eslintNode: ESLintRule.Node) {\n const node = eslintNode as unknown as TSESTree.CallExpression\n if (!isGroqFunctionCall(node)) {\n return\n }\n\n const query = extractGroqStringFromCall(node)\n if (query !== null) {\n lintQuery(query, eslintNode)\n }\n },\n }\n },\n }\n}\n\n/**\n * Create all ESLint rules from GROQ lint rules.\n */\nexport function createAllRules(groqRules: GroqRule[]): Record<string, ESLintRule.RuleModule> {\n const eslintRules: Record<string, ESLintRule.RuleModule> = {}\n\n for (const rule of groqRules) {\n // Convert rule ID from snake_case to kebab-case for ESLint convention\n const eslintRuleId = `groq-${rule.id}`\n eslintRules[eslintRuleId] = createESLintRule(rule)\n }\n\n return eslintRules\n}\n","import type { TSESTree } from '@typescript-eslint/types'\n\n/**\n * Known function names that take GROQ queries as their first argument.\n * Used by next-sanity and other Sanity packages.\n */\nconst GROQ_FUNCTION_NAMES = ['defineQuery', 'groq']\n\n/**\n * Check if a node is a tagged template literal with a GROQ tag.\n * Matches: groq`...`, groq.something`...`\n */\nexport function isGroqTaggedTemplate(node: TSESTree.TaggedTemplateExpression): boolean {\n const tag = node.tag\n\n // groq`...`\n if (tag.type === 'Identifier' && tag.name === 'groq') {\n return true\n }\n\n // groq.something`...` (for groq.experimental etc)\n if (\n tag.type === 'MemberExpression' &&\n tag.object.type === 'Identifier' &&\n tag.object.name === 'groq'\n ) {\n return true\n }\n\n return false\n}\n\n/**\n * Check if a node is a function call that takes a GROQ query as its first argument.\n * Matches: defineQuery(`...`), defineQuery(\"...\")\n */\nexport function isGroqFunctionCall(node: TSESTree.CallExpression): boolean {\n const callee = node.callee\n\n // defineQuery(...) or groq(...)\n if (callee.type === 'Identifier' && GROQ_FUNCTION_NAMES.includes(callee.name)) {\n return true\n }\n\n return false\n}\n\n/**\n * Extract the GROQ query string from a function call.\n * Handles both template literals and string literals as the first argument.\n */\nexport function extractGroqStringFromCall(node: TSESTree.CallExpression): string | null {\n const firstArg = node.arguments[0]\n if (!firstArg) return null\n\n // defineQuery(`...`) - template literal\n if (firstArg.type === 'TemplateLiteral') {\n return extractStringFromTemplateLiteral(firstArg)\n }\n\n // defineQuery(\"...\") - string literal\n if (firstArg.type === 'Literal' && typeof firstArg.value === 'string') {\n return firstArg.value\n }\n\n return null\n}\n\n/**\n * Extract string from a template literal, handling expressions.\n */\nfunction extractStringFromTemplateLiteral(node: TSESTree.TemplateLiteral): string {\n const { quasis, expressions } = node\n\n // Simple case: no expressions\n if (expressions.length === 0) {\n return quasis[0]?.value.cooked ?? quasis[0]?.value.raw ?? ''\n }\n\n // Build the string with placeholders for expressions\n let result = ''\n for (let i = 0; i < quasis.length; i++) {\n result += quasis[i]?.value.cooked ?? quasis[i]?.value.raw ?? ''\n if (i < expressions.length) {\n // Replace expression with a parameter placeholder\n result += `$__expr${i}__`\n }\n }\n\n return result\n}\n\n/**\n * Get the source location for a function call's first argument.\n */\nexport function getCallArgumentLocation(\n node: TSESTree.CallExpression\n): TSESTree.SourceLocation | null {\n const firstArg = node.arguments[0]\n if (!firstArg) return null\n return firstArg.loc\n}\n\n/**\n * Extract the GROQ query string from a tagged template literal.\n * Handles template literals with expressions by replacing them with placeholders.\n */\nexport function extractGroqString(node: TSESTree.TaggedTemplateExpression): string {\n const { quasis, expressions } = node.quasi\n\n // Simple case: no expressions\n if (expressions.length === 0) {\n return quasis[0]?.value.cooked ?? quasis[0]?.value.raw ?? ''\n }\n\n // Build the string with placeholders for expressions\n let result = ''\n for (let i = 0; i < quasis.length; i++) {\n result += quasis[i]?.value.cooked ?? quasis[i]?.value.raw ?? ''\n if (i < expressions.length) {\n // Replace expression with a parameter placeholder\n // This allows the query to still parse while marking where expressions are\n result += `$__expr${i}__`\n }\n }\n\n return result\n}\n\n/**\n * Get the source location for reporting errors.\n * Returns the location of the template literal content, not the tag.\n */\nexport function getTemplateLocation(\n node: TSESTree.TaggedTemplateExpression\n): TSESTree.SourceLocation {\n return node.quasi.loc\n}\n","import type { Rule as ESLintRule } from 'eslint'\nimport type { TSESTree } from '@typescript-eslint/types'\nimport type { SchemaRule } from '@sanity/schema-lint'\nimport { lint, rules as schemaRules } from '@sanity/schema-lint'\nimport {\n isDefineTypeCall,\n extractSchemaFromDefineType,\n extractSchemaFromObject,\n} from './schema-extractor'\n\n/**\n * Create an ESLint rule from a schema lint rule.\n */\nexport function createSchemaESLintRule(schemaRule: SchemaRule): ESLintRule.RuleModule {\n return {\n meta: {\n type: schemaRule.category === 'correctness' ? 'problem' : 'suggestion',\n docs: {\n description: schemaRule.description,\n recommended: schemaRule.severity === 'error',\n },\n messages: {\n [schemaRule.id]: '{{ message }}',\n },\n schema: [], // No options for now\n },\n\n create(context) {\n return {\n // Handle defineType() calls\n CallExpression(eslintNode: ESLintRule.Node) {\n // Cast to our TSESTree type for type-safe property access\n const node = eslintNode as unknown as TSESTree.CallExpression\n if (!isDefineTypeCall(node)) {\n return\n }\n\n try {\n const schema = extractSchemaFromDefineType(node)\n if (!schema) {\n return\n }\n\n const result = lint(schema, schemaRules, {\n rules: [schemaRule],\n filePath: context.filename,\n })\n\n for (const finding of result.findings) {\n if (finding.ruleId === schemaRule.id) {\n context.report({\n node: eslintNode,\n messageId: schemaRule.id,\n data: {\n message: finding.help ? `${finding.message} ${finding.help}` : finding.message,\n },\n })\n }\n }\n } catch {\n // Parse error - don't report\n }\n },\n\n // Handle export statements with object literals (not using defineType)\n ExportNamedDeclaration(eslintNode: ESLintRule.Node) {\n // Cast to our TSESTree type for type-safe property access\n const node = eslintNode as unknown as TSESTree.ExportNamedDeclaration\n\n // Only check the missing-define-type rule for non-defineType exports\n if (schemaRule.id !== 'missing-define-type') {\n return\n }\n\n if (!node.declaration) {\n return\n }\n\n // export const foo = { name: '...', type: '...' }\n if (node.declaration.type === 'VariableDeclaration') {\n for (const declarator of node.declaration.declarations) {\n if (\n declarator.init?.type === 'ObjectExpression' &&\n !isWrappedInDefineType(declarator.init)\n ) {\n const schema = extractSchemaFromObject(declarator.init)\n if (schema && (schema.type === 'document' || schema.type === 'object')) {\n try {\n const result = lint(schema, schemaRules, {\n rules: [schemaRule],\n filePath: context.filename,\n })\n\n for (const finding of result.findings) {\n if (finding.ruleId === schemaRule.id) {\n context.report({\n node: eslintNode,\n messageId: schemaRule.id,\n data: {\n message: finding.help\n ? `${finding.message} ${finding.help}`\n : finding.message,\n },\n })\n }\n }\n } catch {\n // Parse error - don't report\n }\n }\n }\n }\n }\n },\n\n // Handle default exports with object literals\n ExportDefaultDeclaration(eslintNode: ESLintRule.Node) {\n // Cast to our TSESTree type for type-safe property access\n const node = eslintNode as unknown as TSESTree.ExportDefaultDeclaration\n\n // Only check the missing-define-type rule for non-defineType exports\n if (schemaRule.id !== 'missing-define-type') {\n return\n }\n\n if (node.declaration.type === 'ObjectExpression') {\n const schema = extractSchemaFromObject(node.declaration)\n if (schema && (schema.type === 'document' || schema.type === 'object')) {\n try {\n const result = lint(schema, schemaRules, {\n rules: [schemaRule],\n filePath: context.filename,\n })\n\n for (const finding of result.findings) {\n if (finding.ruleId === schemaRule.id) {\n context.report({\n node: eslintNode,\n messageId: schemaRule.id,\n data: {\n message: finding.help\n ? `${finding.message} ${finding.help}`\n : finding.message,\n },\n })\n }\n }\n } catch {\n // Parse error - don't report\n }\n }\n }\n },\n }\n },\n }\n}\n\n/**\n * Check if an object expression's parent is a defineType() call\n */\nfunction isWrappedInDefineType(_node: TSESTree.ObjectExpression): boolean {\n // This is a simplified check - in practice we check by seeing if\n // the parent is a CallExpression with defineType callee\n // For now we rely on the CallExpression handler\n return false\n}\n\n/**\n * Create all ESLint rules from schema lint rules.\n */\nexport function createAllSchemaRules(rules: SchemaRule[]): Record<string, ESLintRule.RuleModule> {\n const eslintRules: Record<string, ESLintRule.RuleModule> = {}\n\n for (const rule of rules) {\n // Use schema- prefix to distinguish from groq- rules\n const eslintRuleId = `schema-${rule.id}`\n eslintRules[eslintRuleId] = createSchemaESLintRule(rule)\n }\n\n return eslintRules\n}\n","import type { TSESTree } from '@typescript-eslint/types'\nimport type { SchemaType, SchemaField } from '@sanity/schema-lint'\nimport type { SourceSpan } from '@sanity/lint-core'\n\n/**\n * Check if a node is a defineType() call\n */\nexport function isDefineTypeCall(node: TSESTree.CallExpression): boolean {\n const callee = node.callee\n\n // defineType({ ... })\n if (callee.type === 'Identifier' && callee.name === 'defineType') {\n return true\n }\n\n return false\n}\n\n/**\n * Check if a node is a defineField() call\n */\nexport function isDefineFieldCall(node: TSESTree.CallExpression): boolean {\n const callee = node.callee\n\n // defineField({ ... })\n if (callee.type === 'Identifier' && callee.name === 'defineField') {\n return true\n }\n\n return false\n}\n\n/**\n * Convert ESLint location to our SourceSpan format\n */\nfunction toSourceSpan(loc: TSESTree.SourceLocation): SourceSpan {\n return {\n start: {\n line: loc.start.line,\n column: loc.start.column + 1, // 1-based\n offset: 0, // We don't have offset info easily\n },\n end: {\n line: loc.end.line,\n column: loc.end.column + 1, // 1-based\n offset: 0,\n },\n }\n}\n\n/**\n * Extract a string value from an AST node\n */\nfunction extractStringValue(node: TSESTree.Node | undefined): string | undefined {\n if (!node) return undefined\n\n if (node.type === 'Literal' && typeof node.value === 'string') {\n return node.value\n }\n\n // Handle template literals without expressions\n if (node.type === 'TemplateLiteral' && node.expressions.length === 0) {\n return node.quasis[0]?.value.cooked ?? node.quasis[0]?.value.raw\n }\n\n return undefined\n}\n\n/**\n * Extract a boolean value from an AST node\n */\nfunction extractBooleanValue(node: TSESTree.Node | undefined): boolean | undefined {\n if (!node) return undefined\n\n if (node.type === 'Literal' && typeof node.value === 'boolean') {\n return node.value\n }\n\n return undefined\n}\n\n/**\n * Check if a property exists in an object expression\n */\nfunction hasProperty(node: TSESTree.ObjectExpression, name: string): boolean {\n return node.properties.some((prop) => {\n if (prop.type === 'Property' && prop.key.type === 'Identifier') {\n return prop.key.name === name\n }\n return false\n })\n}\n\n/**\n * Get a property value from an object expression\n */\nfunction getProperty(node: TSESTree.ObjectExpression, name: string): TSESTree.Node | undefined {\n for (const prop of node.properties) {\n if (prop.type === 'Property' && prop.key.type === 'Identifier' && prop.key.name === name) {\n return prop.value\n }\n }\n return undefined\n}\n\n/**\n * Extract field options from an object expression\n */\nfunction extractFieldOptions(\n optionsNode: TSESTree.Node | undefined\n): SchemaField['options'] | undefined {\n if (!optionsNode || optionsNode.type !== 'ObjectExpression') {\n return undefined\n }\n\n const options: NonNullable<SchemaField['options']> = {}\n\n for (const prop of optionsNode.properties) {\n if (prop.type === 'Property' && prop.key.type === 'Identifier') {\n const name = prop.key.name\n\n if (name === 'source') {\n const source = extractStringValue(prop.value)\n if (source !== undefined) options.source = source\n } else if (name === 'hotspot') {\n const hotspot = extractBooleanValue(prop.value)\n if (hotspot !== undefined) options.hotspot = hotspot\n } else if (name === 'layout') {\n const layout = extractStringValue(prop.value)\n if (layout !== undefined) options.layout = layout\n } else if (name === 'list' && prop.value.type === 'ArrayExpression') {\n options.list = prop.value.elements.map((el) => {\n if (!el) return null\n if (el.type === 'Literal') return el.value\n if (el.type === 'ObjectExpression') {\n const value = extractStringValue(getProperty(el, 'value'))\n return { value }\n }\n return null\n })\n }\n }\n }\n\n return Object.keys(options).length > 0 ? options : undefined\n}\n\n/**\n * Extract a field from an object expression (either raw or wrapped in defineField)\n */\nfunction extractField(\n node: TSESTree.Node,\n usesDefineField: { value: boolean }\n): SchemaField | undefined {\n let fieldObj: TSESTree.ObjectExpression | undefined\n\n // Check if it's wrapped in defineField()\n if (node.type === 'CallExpression' && isDefineFieldCall(node)) {\n const arg = node.arguments[0]\n if (arg?.type === 'ObjectExpression') {\n fieldObj = arg\n }\n } else if (node.type === 'ObjectExpression') {\n fieldObj = node\n usesDefineField.value = false // At least one field doesn't use defineField\n }\n\n if (!fieldObj) return undefined\n\n const name = extractStringValue(getProperty(fieldObj, 'name'))\n const type = extractStringValue(getProperty(fieldObj, 'type'))\n\n if (!name || !type) return undefined\n\n const title = extractStringValue(getProperty(fieldObj, 'title'))\n const description = extractStringValue(getProperty(fieldObj, 'description'))\n const options = extractFieldOptions(getProperty(fieldObj, 'options'))\n\n const field: SchemaField = {\n name,\n type,\n hasValidation: hasProperty(fieldObj, 'validation'),\n hidden: hasProperty(fieldObj, 'hidden'),\n readOnly: hasProperty(fieldObj, 'readOnly'),\n span: toSourceSpan(fieldObj.loc),\n ...(title !== undefined && { title }),\n ...(description !== undefined && { description }),\n ...(options !== undefined && { options }),\n }\n\n // Check for deprecated\n if (hasProperty(fieldObj, 'deprecated')) {\n const deprecatedNode = getProperty(fieldObj, 'deprecated')\n const deprecatedValue = extractStringValue(deprecatedNode)\n field.deprecated = deprecatedValue ?? true\n }\n\n return field\n}\n\n/**\n * Extract fields from an array expression\n */\nfunction extractFields(node: TSESTree.Node | undefined): {\n fields: SchemaField[]\n usesDefineField: boolean\n} {\n const result = { fields: [] as SchemaField[], usesDefineField: true }\n\n if (!node || node.type !== 'ArrayExpression') {\n return result\n }\n\n const usesDefineFieldTracker = { value: true }\n\n for (const element of node.elements) {\n if (element) {\n const field = extractField(element, usesDefineFieldTracker)\n if (field) {\n result.fields.push(field)\n }\n }\n }\n\n result.usesDefineField = usesDefineFieldTracker.value\n\n return result\n}\n\n/**\n * Extract schema type from a defineType() call\n */\nexport function extractSchemaFromDefineType(node: TSESTree.CallExpression): SchemaType | undefined {\n const arg = node.arguments[0]\n\n if (!arg || arg.type !== 'ObjectExpression') {\n return undefined\n }\n\n const name = extractStringValue(getProperty(arg, 'name'))\n const type = extractStringValue(getProperty(arg, 'type'))\n\n if (!name || !type) {\n return undefined\n }\n\n const title = extractStringValue(getProperty(arg, 'title'))\n const description = extractStringValue(getProperty(arg, 'description'))\n const fieldsResult = extractFields(getProperty(arg, 'fields'))\n const hasFields = fieldsResult.fields.length > 0\n\n const schema: SchemaType = {\n name,\n type,\n hasIcon: hasProperty(arg, 'icon'),\n hasPreview: hasProperty(arg, 'preview'),\n usesDefineType: true,\n span: toSourceSpan(arg.loc),\n ...(title !== undefined && { title }),\n ...(description !== undefined && { description }),\n ...(hasFields && { fields: fieldsResult.fields }),\n ...(hasFields && { usesDefineField: fieldsResult.usesDefineField }),\n }\n\n return schema\n}\n\n/**\n * Extract schema type from a plain object literal (not wrapped in defineType)\n */\nexport function extractSchemaFromObject(node: TSESTree.ObjectExpression): SchemaType | undefined {\n const name = extractStringValue(getProperty(node, 'name'))\n const type = extractStringValue(getProperty(node, 'type'))\n\n if (!name || !type) {\n return undefined\n }\n\n // Only process if it looks like a Sanity schema (has name and type)\n const title = extractStringValue(getProperty(node, 'title'))\n const description = extractStringValue(getProperty(node, 'description'))\n const fieldsResult = extractFields(getProperty(node, 'fields'))\n const hasFields = fieldsResult.fields.length > 0\n\n const schema: SchemaType = {\n name,\n type,\n hasIcon: hasProperty(node, 'icon'),\n hasPreview: hasProperty(node, 'preview'),\n usesDefineType: false,\n span: toSourceSpan(node.loc),\n ...(title !== undefined && { title }),\n ...(description !== undefined && { description }),\n ...(hasFields && { fields: fieldsResult.fields }),\n ...(hasFields && { usesDefineField: fieldsResult.usesDefineField }),\n }\n\n return schema\n}\n"],"mappings":"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","names":["import_groq_lint","import_schema_lint","allGroqRules","groqRules","schemaRules","rules","groqRules","schemaRules"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/utils/rule-factory.ts","../src/utils/groq-extractor.ts","../src/utils/schema-rule-factory.ts","../src/utils/schema-extractor.ts"],"sourcesContent":["/**\n * ESLint plugin for Sanity\n *\n * This plugin provides rules for linting GROQ queries and schema definitions\n * in JavaScript/TypeScript files.\n *\n * @example\n * ```js\n * // eslint.config.js\n * import sanity from 'eslint-plugin-sanity'\n *\n * export default [\n * {\n * plugins: { sanity },\n * rules: {\n * 'sanity/groq-join-in-filter': 'error',\n * 'sanity/schema-missing-icon': 'warn',\n * },\n * },\n * ]\n * ```\n *\n * Or use the recommended config:\n * ```js\n * import sanity from 'eslint-plugin-sanity'\n *\n * export default [\n * ...sanity.configs.recommended,\n * ]\n * ```\n */\n\nimport type { ESLint, Linter } from 'eslint'\nimport { rules as groqRules } from '@sanity/groq-lint'\nimport { rules as schemaRules } from '@sanity/schema-lint'\nimport { createAllRules } from './utils/rule-factory'\nimport { createAllSchemaRules } from './utils/schema-rule-factory'\n\n// Version is injected at build time by tsup\ndeclare const PACKAGE_VERSION: string\nconst version = typeof PACKAGE_VERSION !== 'undefined' ? PACKAGE_VERSION : '0.0.0'\n\n// Create ESLint rules from all GROQ lint rules\nconst groqEslintRules = createAllRules(groqRules)\n\n// Create ESLint rules from all schema lint rules\nconst schemaEslintRules = createAllSchemaRules(schemaRules)\n\n// Combine all rules\nconst rules = {\n ...groqEslintRules,\n ...schemaEslintRules,\n}\n\n// Build the plugin object\nconst plugin: ESLint.Plugin = {\n meta: {\n name: 'eslint-plugin-sanity',\n version,\n },\n rules,\n}\n\n// Create recommended config as an array for easy spreading\n// Users can use either: ...sanity.configs.recommended or sanity.configs.recommended\nconst recommended: Linter.Config[] = [\n {\n plugins: {\n sanity: plugin,\n },\n rules: {\n // === GROQ Rules ===\n\n // Errors - these are serious performance or correctness issues\n 'sanity/groq-join-in-filter': 'error',\n\n // Warnings - performance issues that should be addressed\n 'sanity/groq-deep-pagination': 'warn',\n 'sanity/groq-large-pages': 'warn',\n 'sanity/groq-many-joins': 'warn',\n 'sanity/groq-computed-value-in-filter': 'warn',\n 'sanity/groq-non-literal-comparison': 'warn',\n 'sanity/groq-order-on-expr': 'warn',\n 'sanity/groq-very-large-query': 'warn',\n 'sanity/groq-extremely-large-query': 'error',\n\n // Info - suggestions for improvement (off by default, enable as warnings)\n 'sanity/groq-join-to-get-id': 'warn',\n 'sanity/groq-repeated-dereference': 'warn',\n 'sanity/groq-match-on-id': 'warn',\n 'sanity/groq-count-in-correlated-subquery': 'warn',\n 'sanity/groq-deep-pagination-param': 'warn',\n\n // === Schema Rules ===\n\n // Errors - correctness issues\n 'sanity/schema-missing-define-type': 'error',\n 'sanity/schema-missing-define-field': 'error',\n 'sanity/schema-reserved-field-name': 'error',\n\n // Warnings - best practice violations\n 'sanity/schema-missing-icon': 'warn',\n 'sanity/schema-missing-title': 'warn',\n 'sanity/schema-presentation-field-name': 'warn',\n 'sanity/schema-missing-slug-source': 'warn',\n 'sanity/schema-missing-required-validation': 'warn',\n 'sanity/schema-heading-level-in-schema': 'warn',\n\n // Info - suggestions (off by default)\n 'sanity/schema-missing-description': 'off',\n 'sanity/schema-boolean-instead-of-list': 'off',\n 'sanity/schema-array-missing-constraints': 'off',\n 'sanity/schema-unnecessary-reference': 'off',\n },\n },\n]\n\n// Create strict config (all rules as errors)\nconst strict: Linter.Config[] = [\n {\n plugins: {\n sanity: plugin,\n },\n rules: Object.fromEntries(Object.keys(rules).map((ruleId) => [`sanity/${ruleId}`, 'error'])),\n },\n]\n\n// Configs with explicit type annotation\nconst configs: { recommended: Linter.Config[]; strict: Linter.Config[] } = {\n recommended,\n strict,\n}\n\n// Plugin type\ninterface SanityPlugin {\n meta: ESLint.Plugin['meta']\n rules: typeof rules\n configs: typeof configs\n}\n\n// Default export for ESLint flat config\nconst sanityPlugin: SanityPlugin = {\n meta: plugin.meta,\n rules,\n configs,\n}\n\nexport default sanityPlugin\n\n// Named exports for flexibility\nexport { rules, configs }\n","import type { Rule as ESLintRule } from 'eslint'\nimport type { TSESTree } from '@typescript-eslint/types'\nimport type { Rule as GroqRule } from '@sanity/groq-lint'\nimport { lint, rules as allGroqRules } from '@sanity/groq-lint'\nimport {\n isGroqTaggedTemplate,\n extractGroqString,\n isGroqFunctionCall,\n extractGroqStringFromCall,\n} from './groq-extractor'\n\n/**\n * Build a config that enables only the specified rule\n */\nfunction buildSingleRuleConfig(ruleId: string): Record<string, boolean> {\n const config: Record<string, boolean> = {}\n for (const rule of allGroqRules) {\n config[rule.id] = rule.id === ruleId\n }\n return config\n}\n\n/**\n * Create an ESLint rule from a GROQ lint rule.\n */\nexport function createESLintRule(groqRule: GroqRule): ESLintRule.RuleModule {\n return {\n meta: {\n type: groqRule.category === 'correctness' ? 'problem' : 'suggestion',\n docs: {\n description: groqRule.description,\n recommended: groqRule.severity === 'error',\n },\n messages: {\n [groqRule.id]: '{{ message }}',\n },\n schema: [], // No options for now\n },\n\n create(context) {\n /**\n * Lint a GROQ query and report findings\n */\n function lintQuery(query: string, eslintNode: ESLintRule.Node): void {\n try {\n const result = lint(query, { config: { rules: buildSingleRuleConfig(groqRule.id) } })\n\n for (const finding of result.findings) {\n if (finding.ruleId === groqRule.id) {\n context.report({\n node: eslintNode,\n messageId: groqRule.id,\n data: {\n message: finding.help ? `${finding.message} ${finding.help}` : finding.message,\n },\n })\n }\n }\n } catch {\n // Parse error - don't report, let the user see it in runtime\n }\n }\n\n return {\n // Handle groq`...` tagged template literals\n TaggedTemplateExpression(eslintNode: ESLintRule.Node) {\n const node = eslintNode as unknown as TSESTree.TaggedTemplateExpression\n if (!isGroqTaggedTemplate(node)) {\n return\n }\n\n const query = extractGroqString(node)\n lintQuery(query, eslintNode)\n },\n\n // Handle defineQuery(`...`) and defineQuery(\"...\") function calls\n CallExpression(eslintNode: ESLintRule.Node) {\n const node = eslintNode as unknown as TSESTree.CallExpression\n if (!isGroqFunctionCall(node)) {\n return\n }\n\n const query = extractGroqStringFromCall(node)\n if (query !== null) {\n lintQuery(query, eslintNode)\n }\n },\n }\n },\n }\n}\n\n/**\n * Create all ESLint rules from GROQ lint rules.\n */\nexport function createAllRules(groqRules: GroqRule[]): Record<string, ESLintRule.RuleModule> {\n const eslintRules: Record<string, ESLintRule.RuleModule> = {}\n\n for (const rule of groqRules) {\n // Convert rule ID from snake_case to kebab-case for ESLint convention\n const eslintRuleId = `groq-${rule.id}`\n eslintRules[eslintRuleId] = createESLintRule(rule)\n }\n\n return eslintRules\n}\n","import type { TSESTree } from '@typescript-eslint/types'\n\n/**\n * Known function names that take GROQ queries as their first argument.\n * Used by next-sanity and other Sanity packages.\n */\nconst GROQ_FUNCTION_NAMES = ['defineQuery', 'groq']\n\n/**\n * Check if a node is a tagged template literal with a GROQ tag.\n * Matches: groq`...`, groq.something`...`\n */\nexport function isGroqTaggedTemplate(node: TSESTree.TaggedTemplateExpression): boolean {\n const tag = node.tag\n\n // groq`...`\n if (tag.type === 'Identifier' && tag.name === 'groq') {\n return true\n }\n\n // groq.something`...` (for groq.experimental etc)\n if (\n tag.type === 'MemberExpression' &&\n tag.object.type === 'Identifier' &&\n tag.object.name === 'groq'\n ) {\n return true\n }\n\n return false\n}\n\n/**\n * Check if a node is a function call that takes a GROQ query as its first argument.\n * Matches: defineQuery(`...`), defineQuery(\"...\")\n */\nexport function isGroqFunctionCall(node: TSESTree.CallExpression): boolean {\n const callee = node.callee\n\n // defineQuery(...) or groq(...)\n if (callee.type === 'Identifier' && GROQ_FUNCTION_NAMES.includes(callee.name)) {\n return true\n }\n\n return false\n}\n\n/**\n * Extract the GROQ query string from a function call.\n * Handles both template literals and string literals as the first argument.\n */\nexport function extractGroqStringFromCall(node: TSESTree.CallExpression): string | null {\n const firstArg = node.arguments[0]\n if (!firstArg) return null\n\n // defineQuery(`...`) - template literal\n if (firstArg.type === 'TemplateLiteral') {\n return extractStringFromTemplateLiteral(firstArg)\n }\n\n // defineQuery(\"...\") - string literal\n if (firstArg.type === 'Literal' && typeof firstArg.value === 'string') {\n return firstArg.value\n }\n\n return null\n}\n\n/**\n * Extract string from a template literal, handling expressions.\n */\nfunction extractStringFromTemplateLiteral(node: TSESTree.TemplateLiteral): string {\n const { quasis, expressions } = node\n\n // Simple case: no expressions\n if (expressions.length === 0) {\n return quasis[0]?.value.cooked ?? quasis[0]?.value.raw ?? ''\n }\n\n // Build the string with placeholders for expressions\n let result = ''\n for (let i = 0; i < quasis.length; i++) {\n result += quasis[i]?.value.cooked ?? quasis[i]?.value.raw ?? ''\n if (i < expressions.length) {\n // Replace expression with a parameter placeholder\n result += `$__expr${i}__`\n }\n }\n\n return result\n}\n\n/**\n * Get the source location for a function call's first argument.\n */\nexport function getCallArgumentLocation(\n node: TSESTree.CallExpression\n): TSESTree.SourceLocation | null {\n const firstArg = node.arguments[0]\n if (!firstArg) return null\n return firstArg.loc\n}\n\n/**\n * Extract the GROQ query string from a tagged template literal.\n * Handles template literals with expressions by replacing them with placeholders.\n */\nexport function extractGroqString(node: TSESTree.TaggedTemplateExpression): string {\n const { quasis, expressions } = node.quasi\n\n // Simple case: no expressions\n if (expressions.length === 0) {\n return quasis[0]?.value.cooked ?? quasis[0]?.value.raw ?? ''\n }\n\n // Build the string with placeholders for expressions\n let result = ''\n for (let i = 0; i < quasis.length; i++) {\n result += quasis[i]?.value.cooked ?? quasis[i]?.value.raw ?? ''\n if (i < expressions.length) {\n // Replace expression with a parameter placeholder\n // This allows the query to still parse while marking where expressions are\n result += `$__expr${i}__`\n }\n }\n\n return result\n}\n\n/**\n * Get the source location for reporting errors.\n * Returns the location of the template literal content, not the tag.\n */\nexport function getTemplateLocation(\n node: TSESTree.TaggedTemplateExpression\n): TSESTree.SourceLocation {\n return node.quasi.loc\n}\n","import type { Rule as ESLintRule } from 'eslint'\nimport type { TSESTree } from '@typescript-eslint/types'\nimport type { SchemaRule } from '@sanity/schema-lint'\nimport { lint, rules as schemaRules } from '@sanity/schema-lint'\nimport {\n isDefineTypeCall,\n extractSchemaFromDefineType,\n extractSchemaFromObject,\n} from './schema-extractor'\n\n/**\n * Create an ESLint rule from a schema lint rule.\n */\nexport function createSchemaESLintRule(schemaRule: SchemaRule): ESLintRule.RuleModule {\n return {\n meta: {\n type: schemaRule.category === 'correctness' ? 'problem' : 'suggestion',\n docs: {\n description: schemaRule.description,\n recommended: schemaRule.severity === 'error',\n },\n messages: {\n [schemaRule.id]: '{{ message }}',\n },\n schema: [], // No options for now\n },\n\n create(context) {\n return {\n // Handle defineType() calls\n CallExpression(eslintNode: ESLintRule.Node) {\n // Cast to our TSESTree type for type-safe property access\n const node = eslintNode as unknown as TSESTree.CallExpression\n if (!isDefineTypeCall(node)) {\n return\n }\n\n try {\n const schema = extractSchemaFromDefineType(node)\n if (!schema) {\n return\n }\n\n const result = lint(schema, schemaRules, {\n rules: [schemaRule],\n filePath: context.filename,\n })\n\n for (const finding of result.findings) {\n if (finding.ruleId === schemaRule.id) {\n context.report({\n node: eslintNode,\n messageId: schemaRule.id,\n data: {\n message: finding.help ? `${finding.message} ${finding.help}` : finding.message,\n },\n })\n }\n }\n } catch {\n // Parse error - don't report\n }\n },\n\n // Handle export statements with object literals (not using defineType)\n ExportNamedDeclaration(eslintNode: ESLintRule.Node) {\n // Cast to our TSESTree type for type-safe property access\n const node = eslintNode as unknown as TSESTree.ExportNamedDeclaration\n\n // Only check the missing-define-type rule for non-defineType exports\n if (schemaRule.id !== 'missing-define-type') {\n return\n }\n\n if (!node.declaration) {\n return\n }\n\n // export const foo = { name: '...', type: '...' }\n if (node.declaration.type === 'VariableDeclaration') {\n for (const declarator of node.declaration.declarations) {\n if (\n declarator.init?.type === 'ObjectExpression' &&\n !isWrappedInDefineType(declarator.init)\n ) {\n const schema = extractSchemaFromObject(declarator.init)\n if (schema && (schema.type === 'document' || schema.type === 'object')) {\n try {\n const result = lint(schema, schemaRules, {\n rules: [schemaRule],\n filePath: context.filename,\n })\n\n for (const finding of result.findings) {\n if (finding.ruleId === schemaRule.id) {\n context.report({\n node: eslintNode,\n messageId: schemaRule.id,\n data: {\n message: finding.help\n ? `${finding.message} ${finding.help}`\n : finding.message,\n },\n })\n }\n }\n } catch {\n // Parse error - don't report\n }\n }\n }\n }\n }\n },\n\n // Handle default exports with object literals\n ExportDefaultDeclaration(eslintNode: ESLintRule.Node) {\n // Cast to our TSESTree type for type-safe property access\n const node = eslintNode as unknown as TSESTree.ExportDefaultDeclaration\n\n // Only check the missing-define-type rule for non-defineType exports\n if (schemaRule.id !== 'missing-define-type') {\n return\n }\n\n if (node.declaration.type === 'ObjectExpression') {\n const schema = extractSchemaFromObject(node.declaration)\n if (schema && (schema.type === 'document' || schema.type === 'object')) {\n try {\n const result = lint(schema, schemaRules, {\n rules: [schemaRule],\n filePath: context.filename,\n })\n\n for (const finding of result.findings) {\n if (finding.ruleId === schemaRule.id) {\n context.report({\n node: eslintNode,\n messageId: schemaRule.id,\n data: {\n message: finding.help\n ? `${finding.message} ${finding.help}`\n : finding.message,\n },\n })\n }\n }\n } catch {\n // Parse error - don't report\n }\n }\n }\n },\n }\n },\n }\n}\n\n/**\n * Check if an object expression's parent is a defineType() call\n */\nfunction isWrappedInDefineType(_node: TSESTree.ObjectExpression): boolean {\n // This is a simplified check - in practice we check by seeing if\n // the parent is a CallExpression with defineType callee\n // For now we rely on the CallExpression handler\n return false\n}\n\n/**\n * Create all ESLint rules from schema lint rules.\n */\nexport function createAllSchemaRules(rules: SchemaRule[]): Record<string, ESLintRule.RuleModule> {\n const eslintRules: Record<string, ESLintRule.RuleModule> = {}\n\n for (const rule of rules) {\n // Use schema- prefix to distinguish from groq- rules\n const eslintRuleId = `schema-${rule.id}`\n eslintRules[eslintRuleId] = createSchemaESLintRule(rule)\n }\n\n return eslintRules\n}\n","import type { TSESTree } from '@typescript-eslint/types'\nimport type { SchemaType, SchemaField } from '@sanity/schema-lint'\nimport type { SourceSpan } from '@sanity/lint-core'\n\n/**\n * Check if a node is a defineType() call\n */\nexport function isDefineTypeCall(node: TSESTree.CallExpression): boolean {\n const callee = node.callee\n\n // defineType({ ... })\n if (callee.type === 'Identifier' && callee.name === 'defineType') {\n return true\n }\n\n return false\n}\n\n/**\n * Check if a node is a defineField() call\n */\nexport function isDefineFieldCall(node: TSESTree.CallExpression): boolean {\n const callee = node.callee\n\n // defineField({ ... })\n if (callee.type === 'Identifier' && callee.name === 'defineField') {\n return true\n }\n\n return false\n}\n\n/**\n * Convert ESLint location to our SourceSpan format\n */\nfunction toSourceSpan(loc: TSESTree.SourceLocation): SourceSpan {\n return {\n start: {\n line: loc.start.line,\n column: loc.start.column + 1, // 1-based\n offset: 0, // We don't have offset info easily\n },\n end: {\n line: loc.end.line,\n column: loc.end.column + 1, // 1-based\n offset: 0,\n },\n }\n}\n\n/**\n * Extract a string value from an AST node\n */\nfunction extractStringValue(node: TSESTree.Node | undefined): string | undefined {\n if (!node) return undefined\n\n if (node.type === 'Literal' && typeof node.value === 'string') {\n return node.value\n }\n\n // Handle template literals without expressions\n if (node.type === 'TemplateLiteral' && node.expressions.length === 0) {\n return node.quasis[0]?.value.cooked ?? node.quasis[0]?.value.raw\n }\n\n return undefined\n}\n\n/**\n * Extract a boolean value from an AST node\n */\nfunction extractBooleanValue(node: TSESTree.Node | undefined): boolean | undefined {\n if (!node) return undefined\n\n if (node.type === 'Literal' && typeof node.value === 'boolean') {\n return node.value\n }\n\n return undefined\n}\n\n/**\n * Check if a property exists in an object expression\n */\nfunction hasProperty(node: TSESTree.ObjectExpression, name: string): boolean {\n return node.properties.some((prop) => {\n if (prop.type === 'Property' && prop.key.type === 'Identifier') {\n return prop.key.name === name\n }\n return false\n })\n}\n\n/**\n * Get a property value from an object expression\n */\nfunction getProperty(node: TSESTree.ObjectExpression, name: string): TSESTree.Node | undefined {\n for (const prop of node.properties) {\n if (prop.type === 'Property' && prop.key.type === 'Identifier' && prop.key.name === name) {\n return prop.value\n }\n }\n return undefined\n}\n\n/**\n * Extract field options from an object expression\n */\nfunction extractFieldOptions(\n optionsNode: TSESTree.Node | undefined\n): SchemaField['options'] | undefined {\n if (!optionsNode || optionsNode.type !== 'ObjectExpression') {\n return undefined\n }\n\n const options: NonNullable<SchemaField['options']> = {}\n\n for (const prop of optionsNode.properties) {\n if (prop.type === 'Property' && prop.key.type === 'Identifier') {\n const name = prop.key.name\n\n if (name === 'source') {\n const source = extractStringValue(prop.value)\n if (source !== undefined) options.source = source\n } else if (name === 'hotspot') {\n const hotspot = extractBooleanValue(prop.value)\n if (hotspot !== undefined) options.hotspot = hotspot\n } else if (name === 'layout') {\n const layout = extractStringValue(prop.value)\n if (layout !== undefined) options.layout = layout\n } else if (name === 'list' && prop.value.type === 'ArrayExpression') {\n options.list = prop.value.elements.map((el) => {\n if (!el) return null\n if (el.type === 'Literal') return el.value\n if (el.type === 'ObjectExpression') {\n const value = extractStringValue(getProperty(el, 'value'))\n return { value }\n }\n return null\n })\n }\n }\n }\n\n return Object.keys(options).length > 0 ? options : undefined\n}\n\n/**\n * Extract a field from an object expression (either raw or wrapped in defineField)\n */\nfunction extractField(\n node: TSESTree.Node,\n usesDefineField: { value: boolean }\n): SchemaField | undefined {\n let fieldObj: TSESTree.ObjectExpression | undefined\n\n // Check if it's wrapped in defineField()\n if (node.type === 'CallExpression' && isDefineFieldCall(node)) {\n const arg = node.arguments[0]\n if (arg?.type === 'ObjectExpression') {\n fieldObj = arg\n }\n } else if (node.type === 'ObjectExpression') {\n fieldObj = node\n usesDefineField.value = false // At least one field doesn't use defineField\n }\n\n if (!fieldObj) return undefined\n\n const name = extractStringValue(getProperty(fieldObj, 'name'))\n const type = extractStringValue(getProperty(fieldObj, 'type'))\n\n if (!name || !type) return undefined\n\n const title = extractStringValue(getProperty(fieldObj, 'title'))\n const description = extractStringValue(getProperty(fieldObj, 'description'))\n const options = extractFieldOptions(getProperty(fieldObj, 'options'))\n\n const field: SchemaField = {\n name,\n type,\n hasValidation: hasProperty(fieldObj, 'validation'),\n hidden: hasProperty(fieldObj, 'hidden'),\n readOnly: hasProperty(fieldObj, 'readOnly'),\n span: toSourceSpan(fieldObj.loc),\n ...(title !== undefined && { title }),\n ...(description !== undefined && { description }),\n ...(options !== undefined && { options }),\n }\n\n // Check for deprecated\n if (hasProperty(fieldObj, 'deprecated')) {\n const deprecatedNode = getProperty(fieldObj, 'deprecated')\n const deprecatedValue = extractStringValue(deprecatedNode)\n field.deprecated = deprecatedValue ?? true\n }\n\n return field\n}\n\n/**\n * Extract fields from an array expression\n */\nfunction extractFields(node: TSESTree.Node | undefined): {\n fields: SchemaField[]\n usesDefineField: boolean\n} {\n const result = { fields: [] as SchemaField[], usesDefineField: true }\n\n if (!node || node.type !== 'ArrayExpression') {\n return result\n }\n\n const usesDefineFieldTracker = { value: true }\n\n for (const element of node.elements) {\n if (element) {\n const field = extractField(element, usesDefineFieldTracker)\n if (field) {\n result.fields.push(field)\n }\n }\n }\n\n result.usesDefineField = usesDefineFieldTracker.value\n\n return result\n}\n\n/**\n * Extract schema type from a defineType() call\n */\nexport function extractSchemaFromDefineType(node: TSESTree.CallExpression): SchemaType | undefined {\n const arg = node.arguments[0]\n\n if (!arg || arg.type !== 'ObjectExpression') {\n return undefined\n }\n\n const name = extractStringValue(getProperty(arg, 'name'))\n const type = extractStringValue(getProperty(arg, 'type'))\n\n if (!name || !type) {\n return undefined\n }\n\n const title = extractStringValue(getProperty(arg, 'title'))\n const description = extractStringValue(getProperty(arg, 'description'))\n const fieldsResult = extractFields(getProperty(arg, 'fields'))\n const hasFields = fieldsResult.fields.length > 0\n\n const schema: SchemaType = {\n name,\n type,\n hasIcon: hasProperty(arg, 'icon'),\n hasPreview: hasProperty(arg, 'preview'),\n usesDefineType: true,\n span: toSourceSpan(arg.loc),\n ...(title !== undefined && { title }),\n ...(description !== undefined && { description }),\n ...(hasFields && { fields: fieldsResult.fields }),\n ...(hasFields && { usesDefineField: fieldsResult.usesDefineField }),\n }\n\n return schema\n}\n\n/**\n * Extract schema type from a plain object literal (not wrapped in defineType)\n */\nexport function extractSchemaFromObject(node: TSESTree.ObjectExpression): SchemaType | undefined {\n const name = extractStringValue(getProperty(node, 'name'))\n const type = extractStringValue(getProperty(node, 'type'))\n\n if (!name || !type) {\n return undefined\n }\n\n // Only process if it looks like a Sanity schema (has name and type)\n const title = extractStringValue(getProperty(node, 'title'))\n const description = extractStringValue(getProperty(node, 'description'))\n const fieldsResult = extractFields(getProperty(node, 'fields'))\n const hasFields = fieldsResult.fields.length > 0\n\n const schema: SchemaType = {\n name,\n type,\n hasIcon: hasProperty(node, 'icon'),\n hasPreview: hasProperty(node, 'preview'),\n usesDefineType: false,\n span: toSourceSpan(node.loc),\n ...(title !== undefined && { title }),\n ...(description !== undefined && { description }),\n ...(hasFields && { fields: fieldsResult.fields }),\n ...(hasFields && { usesDefineField: fieldsResult.usesDefineField }),\n }\n\n return schema\n}\n"],"mappings":"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","names":["import_groq_lint","import_schema_lint","allGroqRules","groqRules","schemaRules","rules","groqRules","schemaRules"]}
package/dist/index.d.cts CHANGED
@@ -5,8 +5,8 @@ declare const rules: {
5
5
  [x: string]: eslint.Rule.RuleModule;
6
6
  };
7
7
  declare const configs: {
8
- recommended: Linter.Config;
9
- strict: Linter.Config;
8
+ recommended: Linter.Config[];
9
+ strict: Linter.Config[];
10
10
  };
11
11
  interface SanityPlugin {
12
12
  meta: ESLint.Plugin['meta'];
package/dist/index.d.ts CHANGED
@@ -5,8 +5,8 @@ declare const rules: {
5
5
  [x: string]: eslint.Rule.RuleModule;
6
6
  };
7
7
  declare const configs: {
8
- recommended: Linter.Config;
9
- strict: Linter.Config;
8
+ recommended: Linter.Config[];
9
+ strict: Linter.Config[];
10
10
  };
11
11
  interface SanityPlugin {
12
12
  meta: ESLint.Plugin['meta'];
package/dist/index.js CHANGED
@@ -474,7 +474,7 @@ function createAllSchemaRules(rules2) {
474
474
  }
475
475
 
476
476
  // src/index.ts
477
- var version = true ? "0.1.0" : "0.0.0";
477
+ var version = true ? "0.1.2" : "0.0.0";
478
478
  var groqEslintRules = createAllRules(groqRules);
479
479
  var schemaEslintRules = createAllSchemaRules(schemaRules2);
480
480
  var rules = {
@@ -488,54 +488,58 @@ var plugin = {
488
488
  },
489
489
  rules
490
490
  };
491
- var recommended = {
492
- plugins: {
493
- sanity: plugin
494
- },
495
- rules: {
496
- // === GROQ Rules ===
497
- // Errors - these are serious performance or correctness issues
498
- "sanity/groq-join-in-filter": "error",
499
- // Warnings - performance issues that should be addressed
500
- "sanity/groq-deep-pagination": "warn",
501
- "sanity/groq-large-pages": "warn",
502
- "sanity/groq-many-joins": "warn",
503
- "sanity/groq-computed-value-in-filter": "warn",
504
- "sanity/groq-non-literal-comparison": "warn",
505
- "sanity/groq-order-on-expr": "warn",
506
- "sanity/groq-very-large-query": "warn",
507
- "sanity/groq-extremely-large-query": "error",
508
- // Info - suggestions for improvement (off by default, enable as warnings)
509
- "sanity/groq-join-to-get-id": "warn",
510
- "sanity/groq-repeated-dereference": "warn",
511
- "sanity/groq-match-on-id": "warn",
512
- "sanity/groq-count-in-correlated-subquery": "warn",
513
- "sanity/groq-deep-pagination-param": "warn",
514
- // === Schema Rules ===
515
- // Errors - correctness issues
516
- "sanity/schema-missing-define-type": "error",
517
- "sanity/schema-missing-define-field": "error",
518
- "sanity/schema-reserved-field-name": "error",
519
- // Warnings - best practice violations
520
- "sanity/schema-missing-icon": "warn",
521
- "sanity/schema-missing-title": "warn",
522
- "sanity/schema-presentation-field-name": "warn",
523
- "sanity/schema-missing-slug-source": "warn",
524
- "sanity/schema-missing-required-validation": "warn",
525
- "sanity/schema-heading-level-in-schema": "warn",
526
- // Info - suggestions (off by default)
527
- "sanity/schema-missing-description": "off",
528
- "sanity/schema-boolean-instead-of-list": "off",
529
- "sanity/schema-array-missing-constraints": "off",
530
- "sanity/schema-unnecessary-reference": "off"
491
+ var recommended = [
492
+ {
493
+ plugins: {
494
+ sanity: plugin
495
+ },
496
+ rules: {
497
+ // === GROQ Rules ===
498
+ // Errors - these are serious performance or correctness issues
499
+ "sanity/groq-join-in-filter": "error",
500
+ // Warnings - performance issues that should be addressed
501
+ "sanity/groq-deep-pagination": "warn",
502
+ "sanity/groq-large-pages": "warn",
503
+ "sanity/groq-many-joins": "warn",
504
+ "sanity/groq-computed-value-in-filter": "warn",
505
+ "sanity/groq-non-literal-comparison": "warn",
506
+ "sanity/groq-order-on-expr": "warn",
507
+ "sanity/groq-very-large-query": "warn",
508
+ "sanity/groq-extremely-large-query": "error",
509
+ // Info - suggestions for improvement (off by default, enable as warnings)
510
+ "sanity/groq-join-to-get-id": "warn",
511
+ "sanity/groq-repeated-dereference": "warn",
512
+ "sanity/groq-match-on-id": "warn",
513
+ "sanity/groq-count-in-correlated-subquery": "warn",
514
+ "sanity/groq-deep-pagination-param": "warn",
515
+ // === Schema Rules ===
516
+ // Errors - correctness issues
517
+ "sanity/schema-missing-define-type": "error",
518
+ "sanity/schema-missing-define-field": "error",
519
+ "sanity/schema-reserved-field-name": "error",
520
+ // Warnings - best practice violations
521
+ "sanity/schema-missing-icon": "warn",
522
+ "sanity/schema-missing-title": "warn",
523
+ "sanity/schema-presentation-field-name": "warn",
524
+ "sanity/schema-missing-slug-source": "warn",
525
+ "sanity/schema-missing-required-validation": "warn",
526
+ "sanity/schema-heading-level-in-schema": "warn",
527
+ // Info - suggestions (off by default)
528
+ "sanity/schema-missing-description": "off",
529
+ "sanity/schema-boolean-instead-of-list": "off",
530
+ "sanity/schema-array-missing-constraints": "off",
531
+ "sanity/schema-unnecessary-reference": "off"
532
+ }
531
533
  }
532
- };
533
- var strict = {
534
- plugins: {
535
- sanity: plugin
536
- },
537
- rules: Object.fromEntries(Object.keys(rules).map((ruleId) => [`sanity/${ruleId}`, "error"]))
538
- };
534
+ ];
535
+ var strict = [
536
+ {
537
+ plugins: {
538
+ sanity: plugin
539
+ },
540
+ rules: Object.fromEntries(Object.keys(rules).map((ruleId) => [`sanity/${ruleId}`, "error"]))
541
+ }
542
+ ];
539
543
  var configs = {
540
544
  recommended,
541
545
  strict
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/utils/rule-factory.ts","../src/utils/groq-extractor.ts","../src/utils/schema-rule-factory.ts","../src/utils/schema-extractor.ts"],"sourcesContent":["/**\n * ESLint plugin for Sanity\n *\n * This plugin provides rules for linting GROQ queries and schema definitions\n * in JavaScript/TypeScript files.\n *\n * @example\n * ```js\n * // eslint.config.js\n * import sanity from 'eslint-plugin-sanity'\n *\n * export default [\n * {\n * plugins: { sanity },\n * rules: {\n * 'sanity/groq-join-in-filter': 'error',\n * 'sanity/schema-missing-icon': 'warn',\n * },\n * },\n * ]\n * ```\n *\n * Or use the recommended config:\n * ```js\n * import sanity from 'eslint-plugin-sanity'\n *\n * export default [\n * sanity.configs.recommended,\n * ]\n * ```\n */\n\nimport type { ESLint, Linter } from 'eslint'\nimport { rules as groqRules } from '@sanity/groq-lint'\nimport { rules as schemaRules } from '@sanity/schema-lint'\nimport { createAllRules } from './utils/rule-factory'\nimport { createAllSchemaRules } from './utils/schema-rule-factory'\n\n// Version is injected at build time by tsup\ndeclare const PACKAGE_VERSION: string\nconst version = typeof PACKAGE_VERSION !== 'undefined' ? PACKAGE_VERSION : '0.0.0'\n\n// Create ESLint rules from all GROQ lint rules\nconst groqEslintRules = createAllRules(groqRules)\n\n// Create ESLint rules from all schema lint rules\nconst schemaEslintRules = createAllSchemaRules(schemaRules)\n\n// Combine all rules\nconst rules = {\n ...groqEslintRules,\n ...schemaEslintRules,\n}\n\n// Build the plugin object\nconst plugin: ESLint.Plugin = {\n meta: {\n name: 'eslint-plugin-sanity',\n version,\n },\n rules,\n}\n\n// Create recommended config\nconst recommended: Linter.Config = {\n plugins: {\n sanity: plugin,\n },\n rules: {\n // === GROQ Rules ===\n\n // Errors - these are serious performance or correctness issues\n 'sanity/groq-join-in-filter': 'error',\n\n // Warnings - performance issues that should be addressed\n 'sanity/groq-deep-pagination': 'warn',\n 'sanity/groq-large-pages': 'warn',\n 'sanity/groq-many-joins': 'warn',\n 'sanity/groq-computed-value-in-filter': 'warn',\n 'sanity/groq-non-literal-comparison': 'warn',\n 'sanity/groq-order-on-expr': 'warn',\n 'sanity/groq-very-large-query': 'warn',\n 'sanity/groq-extremely-large-query': 'error',\n\n // Info - suggestions for improvement (off by default, enable as warnings)\n 'sanity/groq-join-to-get-id': 'warn',\n 'sanity/groq-repeated-dereference': 'warn',\n 'sanity/groq-match-on-id': 'warn',\n 'sanity/groq-count-in-correlated-subquery': 'warn',\n 'sanity/groq-deep-pagination-param': 'warn',\n\n // === Schema Rules ===\n\n // Errors - correctness issues\n 'sanity/schema-missing-define-type': 'error',\n 'sanity/schema-missing-define-field': 'error',\n 'sanity/schema-reserved-field-name': 'error',\n\n // Warnings - best practice violations\n 'sanity/schema-missing-icon': 'warn',\n 'sanity/schema-missing-title': 'warn',\n 'sanity/schema-presentation-field-name': 'warn',\n 'sanity/schema-missing-slug-source': 'warn',\n 'sanity/schema-missing-required-validation': 'warn',\n 'sanity/schema-heading-level-in-schema': 'warn',\n\n // Info - suggestions (off by default)\n 'sanity/schema-missing-description': 'off',\n 'sanity/schema-boolean-instead-of-list': 'off',\n 'sanity/schema-array-missing-constraints': 'off',\n 'sanity/schema-unnecessary-reference': 'off',\n },\n}\n\n// Create strict config (all rules as errors)\nconst strict: Linter.Config = {\n plugins: {\n sanity: plugin,\n },\n rules: Object.fromEntries(Object.keys(rules).map((ruleId) => [`sanity/${ruleId}`, 'error'])),\n}\n\n// Configs with explicit type annotation\nconst configs: { recommended: Linter.Config; strict: Linter.Config } = {\n recommended,\n strict,\n}\n\n// Plugin type\ninterface SanityPlugin {\n meta: ESLint.Plugin['meta']\n rules: typeof rules\n configs: typeof configs\n}\n\n// Default export for ESLint flat config\nconst sanityPlugin: SanityPlugin = {\n meta: plugin.meta,\n rules,\n configs,\n}\n\nexport default sanityPlugin\n\n// Named exports for flexibility\nexport { rules, configs }\n","import type { Rule as ESLintRule } from 'eslint'\nimport type { TSESTree } from '@typescript-eslint/types'\nimport type { Rule as GroqRule } from '@sanity/groq-lint'\nimport { lint, rules as allGroqRules } from '@sanity/groq-lint'\nimport {\n isGroqTaggedTemplate,\n extractGroqString,\n isGroqFunctionCall,\n extractGroqStringFromCall,\n} from './groq-extractor'\n\n/**\n * Build a config that enables only the specified rule\n */\nfunction buildSingleRuleConfig(ruleId: string): Record<string, boolean> {\n const config: Record<string, boolean> = {}\n for (const rule of allGroqRules) {\n config[rule.id] = rule.id === ruleId\n }\n return config\n}\n\n/**\n * Create an ESLint rule from a GROQ lint rule.\n */\nexport function createESLintRule(groqRule: GroqRule): ESLintRule.RuleModule {\n return {\n meta: {\n type: groqRule.category === 'correctness' ? 'problem' : 'suggestion',\n docs: {\n description: groqRule.description,\n recommended: groqRule.severity === 'error',\n },\n messages: {\n [groqRule.id]: '{{ message }}',\n },\n schema: [], // No options for now\n },\n\n create(context) {\n /**\n * Lint a GROQ query and report findings\n */\n function lintQuery(query: string, eslintNode: ESLintRule.Node): void {\n try {\n const result = lint(query, { config: { rules: buildSingleRuleConfig(groqRule.id) } })\n\n for (const finding of result.findings) {\n if (finding.ruleId === groqRule.id) {\n context.report({\n node: eslintNode,\n messageId: groqRule.id,\n data: {\n message: finding.help ? `${finding.message} ${finding.help}` : finding.message,\n },\n })\n }\n }\n } catch {\n // Parse error - don't report, let the user see it in runtime\n }\n }\n\n return {\n // Handle groq`...` tagged template literals\n TaggedTemplateExpression(eslintNode: ESLintRule.Node) {\n const node = eslintNode as unknown as TSESTree.TaggedTemplateExpression\n if (!isGroqTaggedTemplate(node)) {\n return\n }\n\n const query = extractGroqString(node)\n lintQuery(query, eslintNode)\n },\n\n // Handle defineQuery(`...`) and defineQuery(\"...\") function calls\n CallExpression(eslintNode: ESLintRule.Node) {\n const node = eslintNode as unknown as TSESTree.CallExpression\n if (!isGroqFunctionCall(node)) {\n return\n }\n\n const query = extractGroqStringFromCall(node)\n if (query !== null) {\n lintQuery(query, eslintNode)\n }\n },\n }\n },\n }\n}\n\n/**\n * Create all ESLint rules from GROQ lint rules.\n */\nexport function createAllRules(groqRules: GroqRule[]): Record<string, ESLintRule.RuleModule> {\n const eslintRules: Record<string, ESLintRule.RuleModule> = {}\n\n for (const rule of groqRules) {\n // Convert rule ID from snake_case to kebab-case for ESLint convention\n const eslintRuleId = `groq-${rule.id}`\n eslintRules[eslintRuleId] = createESLintRule(rule)\n }\n\n return eslintRules\n}\n","import type { TSESTree } from '@typescript-eslint/types'\n\n/**\n * Known function names that take GROQ queries as their first argument.\n * Used by next-sanity and other Sanity packages.\n */\nconst GROQ_FUNCTION_NAMES = ['defineQuery', 'groq']\n\n/**\n * Check if a node is a tagged template literal with a GROQ tag.\n * Matches: groq`...`, groq.something`...`\n */\nexport function isGroqTaggedTemplate(node: TSESTree.TaggedTemplateExpression): boolean {\n const tag = node.tag\n\n // groq`...`\n if (tag.type === 'Identifier' && tag.name === 'groq') {\n return true\n }\n\n // groq.something`...` (for groq.experimental etc)\n if (\n tag.type === 'MemberExpression' &&\n tag.object.type === 'Identifier' &&\n tag.object.name === 'groq'\n ) {\n return true\n }\n\n return false\n}\n\n/**\n * Check if a node is a function call that takes a GROQ query as its first argument.\n * Matches: defineQuery(`...`), defineQuery(\"...\")\n */\nexport function isGroqFunctionCall(node: TSESTree.CallExpression): boolean {\n const callee = node.callee\n\n // defineQuery(...) or groq(...)\n if (callee.type === 'Identifier' && GROQ_FUNCTION_NAMES.includes(callee.name)) {\n return true\n }\n\n return false\n}\n\n/**\n * Extract the GROQ query string from a function call.\n * Handles both template literals and string literals as the first argument.\n */\nexport function extractGroqStringFromCall(node: TSESTree.CallExpression): string | null {\n const firstArg = node.arguments[0]\n if (!firstArg) return null\n\n // defineQuery(`...`) - template literal\n if (firstArg.type === 'TemplateLiteral') {\n return extractStringFromTemplateLiteral(firstArg)\n }\n\n // defineQuery(\"...\") - string literal\n if (firstArg.type === 'Literal' && typeof firstArg.value === 'string') {\n return firstArg.value\n }\n\n return null\n}\n\n/**\n * Extract string from a template literal, handling expressions.\n */\nfunction extractStringFromTemplateLiteral(node: TSESTree.TemplateLiteral): string {\n const { quasis, expressions } = node\n\n // Simple case: no expressions\n if (expressions.length === 0) {\n return quasis[0]?.value.cooked ?? quasis[0]?.value.raw ?? ''\n }\n\n // Build the string with placeholders for expressions\n let result = ''\n for (let i = 0; i < quasis.length; i++) {\n result += quasis[i]?.value.cooked ?? quasis[i]?.value.raw ?? ''\n if (i < expressions.length) {\n // Replace expression with a parameter placeholder\n result += `$__expr${i}__`\n }\n }\n\n return result\n}\n\n/**\n * Get the source location for a function call's first argument.\n */\nexport function getCallArgumentLocation(\n node: TSESTree.CallExpression\n): TSESTree.SourceLocation | null {\n const firstArg = node.arguments[0]\n if (!firstArg) return null\n return firstArg.loc\n}\n\n/**\n * Extract the GROQ query string from a tagged template literal.\n * Handles template literals with expressions by replacing them with placeholders.\n */\nexport function extractGroqString(node: TSESTree.TaggedTemplateExpression): string {\n const { quasis, expressions } = node.quasi\n\n // Simple case: no expressions\n if (expressions.length === 0) {\n return quasis[0]?.value.cooked ?? quasis[0]?.value.raw ?? ''\n }\n\n // Build the string with placeholders for expressions\n let result = ''\n for (let i = 0; i < quasis.length; i++) {\n result += quasis[i]?.value.cooked ?? quasis[i]?.value.raw ?? ''\n if (i < expressions.length) {\n // Replace expression with a parameter placeholder\n // This allows the query to still parse while marking where expressions are\n result += `$__expr${i}__`\n }\n }\n\n return result\n}\n\n/**\n * Get the source location for reporting errors.\n * Returns the location of the template literal content, not the tag.\n */\nexport function getTemplateLocation(\n node: TSESTree.TaggedTemplateExpression\n): TSESTree.SourceLocation {\n return node.quasi.loc\n}\n","import type { Rule as ESLintRule } from 'eslint'\nimport type { TSESTree } from '@typescript-eslint/types'\nimport type { SchemaRule } from '@sanity/schema-lint'\nimport { lint, rules as schemaRules } from '@sanity/schema-lint'\nimport {\n isDefineTypeCall,\n extractSchemaFromDefineType,\n extractSchemaFromObject,\n} from './schema-extractor'\n\n/**\n * Create an ESLint rule from a schema lint rule.\n */\nexport function createSchemaESLintRule(schemaRule: SchemaRule): ESLintRule.RuleModule {\n return {\n meta: {\n type: schemaRule.category === 'correctness' ? 'problem' : 'suggestion',\n docs: {\n description: schemaRule.description,\n recommended: schemaRule.severity === 'error',\n },\n messages: {\n [schemaRule.id]: '{{ message }}',\n },\n schema: [], // No options for now\n },\n\n create(context) {\n return {\n // Handle defineType() calls\n CallExpression(eslintNode: ESLintRule.Node) {\n // Cast to our TSESTree type for type-safe property access\n const node = eslintNode as unknown as TSESTree.CallExpression\n if (!isDefineTypeCall(node)) {\n return\n }\n\n try {\n const schema = extractSchemaFromDefineType(node)\n if (!schema) {\n return\n }\n\n const result = lint(schema, schemaRules, {\n rules: [schemaRule],\n filePath: context.filename,\n })\n\n for (const finding of result.findings) {\n if (finding.ruleId === schemaRule.id) {\n context.report({\n node: eslintNode,\n messageId: schemaRule.id,\n data: {\n message: finding.help ? `${finding.message} ${finding.help}` : finding.message,\n },\n })\n }\n }\n } catch {\n // Parse error - don't report\n }\n },\n\n // Handle export statements with object literals (not using defineType)\n ExportNamedDeclaration(eslintNode: ESLintRule.Node) {\n // Cast to our TSESTree type for type-safe property access\n const node = eslintNode as unknown as TSESTree.ExportNamedDeclaration\n\n // Only check the missing-define-type rule for non-defineType exports\n if (schemaRule.id !== 'missing-define-type') {\n return\n }\n\n if (!node.declaration) {\n return\n }\n\n // export const foo = { name: '...', type: '...' }\n if (node.declaration.type === 'VariableDeclaration') {\n for (const declarator of node.declaration.declarations) {\n if (\n declarator.init?.type === 'ObjectExpression' &&\n !isWrappedInDefineType(declarator.init)\n ) {\n const schema = extractSchemaFromObject(declarator.init)\n if (schema && (schema.type === 'document' || schema.type === 'object')) {\n try {\n const result = lint(schema, schemaRules, {\n rules: [schemaRule],\n filePath: context.filename,\n })\n\n for (const finding of result.findings) {\n if (finding.ruleId === schemaRule.id) {\n context.report({\n node: eslintNode,\n messageId: schemaRule.id,\n data: {\n message: finding.help\n ? `${finding.message} ${finding.help}`\n : finding.message,\n },\n })\n }\n }\n } catch {\n // Parse error - don't report\n }\n }\n }\n }\n }\n },\n\n // Handle default exports with object literals\n ExportDefaultDeclaration(eslintNode: ESLintRule.Node) {\n // Cast to our TSESTree type for type-safe property access\n const node = eslintNode as unknown as TSESTree.ExportDefaultDeclaration\n\n // Only check the missing-define-type rule for non-defineType exports\n if (schemaRule.id !== 'missing-define-type') {\n return\n }\n\n if (node.declaration.type === 'ObjectExpression') {\n const schema = extractSchemaFromObject(node.declaration)\n if (schema && (schema.type === 'document' || schema.type === 'object')) {\n try {\n const result = lint(schema, schemaRules, {\n rules: [schemaRule],\n filePath: context.filename,\n })\n\n for (const finding of result.findings) {\n if (finding.ruleId === schemaRule.id) {\n context.report({\n node: eslintNode,\n messageId: schemaRule.id,\n data: {\n message: finding.help\n ? `${finding.message} ${finding.help}`\n : finding.message,\n },\n })\n }\n }\n } catch {\n // Parse error - don't report\n }\n }\n }\n },\n }\n },\n }\n}\n\n/**\n * Check if an object expression's parent is a defineType() call\n */\nfunction isWrappedInDefineType(_node: TSESTree.ObjectExpression): boolean {\n // This is a simplified check - in practice we check by seeing if\n // the parent is a CallExpression with defineType callee\n // For now we rely on the CallExpression handler\n return false\n}\n\n/**\n * Create all ESLint rules from schema lint rules.\n */\nexport function createAllSchemaRules(rules: SchemaRule[]): Record<string, ESLintRule.RuleModule> {\n const eslintRules: Record<string, ESLintRule.RuleModule> = {}\n\n for (const rule of rules) {\n // Use schema- prefix to distinguish from groq- rules\n const eslintRuleId = `schema-${rule.id}`\n eslintRules[eslintRuleId] = createSchemaESLintRule(rule)\n }\n\n return eslintRules\n}\n","import type { TSESTree } from '@typescript-eslint/types'\nimport type { SchemaType, SchemaField } from '@sanity/schema-lint'\nimport type { SourceSpan } from '@sanity/lint-core'\n\n/**\n * Check if a node is a defineType() call\n */\nexport function isDefineTypeCall(node: TSESTree.CallExpression): boolean {\n const callee = node.callee\n\n // defineType({ ... })\n if (callee.type === 'Identifier' && callee.name === 'defineType') {\n return true\n }\n\n return false\n}\n\n/**\n * Check if a node is a defineField() call\n */\nexport function isDefineFieldCall(node: TSESTree.CallExpression): boolean {\n const callee = node.callee\n\n // defineField({ ... })\n if (callee.type === 'Identifier' && callee.name === 'defineField') {\n return true\n }\n\n return false\n}\n\n/**\n * Convert ESLint location to our SourceSpan format\n */\nfunction toSourceSpan(loc: TSESTree.SourceLocation): SourceSpan {\n return {\n start: {\n line: loc.start.line,\n column: loc.start.column + 1, // 1-based\n offset: 0, // We don't have offset info easily\n },\n end: {\n line: loc.end.line,\n column: loc.end.column + 1, // 1-based\n offset: 0,\n },\n }\n}\n\n/**\n * Extract a string value from an AST node\n */\nfunction extractStringValue(node: TSESTree.Node | undefined): string | undefined {\n if (!node) return undefined\n\n if (node.type === 'Literal' && typeof node.value === 'string') {\n return node.value\n }\n\n // Handle template literals without expressions\n if (node.type === 'TemplateLiteral' && node.expressions.length === 0) {\n return node.quasis[0]?.value.cooked ?? node.quasis[0]?.value.raw\n }\n\n return undefined\n}\n\n/**\n * Extract a boolean value from an AST node\n */\nfunction extractBooleanValue(node: TSESTree.Node | undefined): boolean | undefined {\n if (!node) return undefined\n\n if (node.type === 'Literal' && typeof node.value === 'boolean') {\n return node.value\n }\n\n return undefined\n}\n\n/**\n * Check if a property exists in an object expression\n */\nfunction hasProperty(node: TSESTree.ObjectExpression, name: string): boolean {\n return node.properties.some((prop) => {\n if (prop.type === 'Property' && prop.key.type === 'Identifier') {\n return prop.key.name === name\n }\n return false\n })\n}\n\n/**\n * Get a property value from an object expression\n */\nfunction getProperty(node: TSESTree.ObjectExpression, name: string): TSESTree.Node | undefined {\n for (const prop of node.properties) {\n if (prop.type === 'Property' && prop.key.type === 'Identifier' && prop.key.name === name) {\n return prop.value\n }\n }\n return undefined\n}\n\n/**\n * Extract field options from an object expression\n */\nfunction extractFieldOptions(\n optionsNode: TSESTree.Node | undefined\n): SchemaField['options'] | undefined {\n if (!optionsNode || optionsNode.type !== 'ObjectExpression') {\n return undefined\n }\n\n const options: NonNullable<SchemaField['options']> = {}\n\n for (const prop of optionsNode.properties) {\n if (prop.type === 'Property' && prop.key.type === 'Identifier') {\n const name = prop.key.name\n\n if (name === 'source') {\n const source = extractStringValue(prop.value)\n if (source !== undefined) options.source = source\n } else if (name === 'hotspot') {\n const hotspot = extractBooleanValue(prop.value)\n if (hotspot !== undefined) options.hotspot = hotspot\n } else if (name === 'layout') {\n const layout = extractStringValue(prop.value)\n if (layout !== undefined) options.layout = layout\n } else if (name === 'list' && prop.value.type === 'ArrayExpression') {\n options.list = prop.value.elements.map((el) => {\n if (!el) return null\n if (el.type === 'Literal') return el.value\n if (el.type === 'ObjectExpression') {\n const value = extractStringValue(getProperty(el, 'value'))\n return { value }\n }\n return null\n })\n }\n }\n }\n\n return Object.keys(options).length > 0 ? options : undefined\n}\n\n/**\n * Extract a field from an object expression (either raw or wrapped in defineField)\n */\nfunction extractField(\n node: TSESTree.Node,\n usesDefineField: { value: boolean }\n): SchemaField | undefined {\n let fieldObj: TSESTree.ObjectExpression | undefined\n\n // Check if it's wrapped in defineField()\n if (node.type === 'CallExpression' && isDefineFieldCall(node)) {\n const arg = node.arguments[0]\n if (arg?.type === 'ObjectExpression') {\n fieldObj = arg\n }\n } else if (node.type === 'ObjectExpression') {\n fieldObj = node\n usesDefineField.value = false // At least one field doesn't use defineField\n }\n\n if (!fieldObj) return undefined\n\n const name = extractStringValue(getProperty(fieldObj, 'name'))\n const type = extractStringValue(getProperty(fieldObj, 'type'))\n\n if (!name || !type) return undefined\n\n const title = extractStringValue(getProperty(fieldObj, 'title'))\n const description = extractStringValue(getProperty(fieldObj, 'description'))\n const options = extractFieldOptions(getProperty(fieldObj, 'options'))\n\n const field: SchemaField = {\n name,\n type,\n hasValidation: hasProperty(fieldObj, 'validation'),\n hidden: hasProperty(fieldObj, 'hidden'),\n readOnly: hasProperty(fieldObj, 'readOnly'),\n span: toSourceSpan(fieldObj.loc),\n ...(title !== undefined && { title }),\n ...(description !== undefined && { description }),\n ...(options !== undefined && { options }),\n }\n\n // Check for deprecated\n if (hasProperty(fieldObj, 'deprecated')) {\n const deprecatedNode = getProperty(fieldObj, 'deprecated')\n const deprecatedValue = extractStringValue(deprecatedNode)\n field.deprecated = deprecatedValue ?? true\n }\n\n return field\n}\n\n/**\n * Extract fields from an array expression\n */\nfunction extractFields(node: TSESTree.Node | undefined): {\n fields: SchemaField[]\n usesDefineField: boolean\n} {\n const result = { fields: [] as SchemaField[], usesDefineField: true }\n\n if (!node || node.type !== 'ArrayExpression') {\n return result\n }\n\n const usesDefineFieldTracker = { value: true }\n\n for (const element of node.elements) {\n if (element) {\n const field = extractField(element, usesDefineFieldTracker)\n if (field) {\n result.fields.push(field)\n }\n }\n }\n\n result.usesDefineField = usesDefineFieldTracker.value\n\n return result\n}\n\n/**\n * Extract schema type from a defineType() call\n */\nexport function extractSchemaFromDefineType(node: TSESTree.CallExpression): SchemaType | undefined {\n const arg = node.arguments[0]\n\n if (!arg || arg.type !== 'ObjectExpression') {\n return undefined\n }\n\n const name = extractStringValue(getProperty(arg, 'name'))\n const type = extractStringValue(getProperty(arg, 'type'))\n\n if (!name || !type) {\n return undefined\n }\n\n const title = extractStringValue(getProperty(arg, 'title'))\n const description = extractStringValue(getProperty(arg, 'description'))\n const fieldsResult = extractFields(getProperty(arg, 'fields'))\n const hasFields = fieldsResult.fields.length > 0\n\n const schema: SchemaType = {\n name,\n type,\n hasIcon: hasProperty(arg, 'icon'),\n hasPreview: hasProperty(arg, 'preview'),\n usesDefineType: true,\n span: toSourceSpan(arg.loc),\n ...(title !== undefined && { title }),\n ...(description !== undefined && { description }),\n ...(hasFields && { fields: fieldsResult.fields }),\n ...(hasFields && { usesDefineField: fieldsResult.usesDefineField }),\n }\n\n return schema\n}\n\n/**\n * Extract schema type from a plain object literal (not wrapped in defineType)\n */\nexport function extractSchemaFromObject(node: TSESTree.ObjectExpression): SchemaType | undefined {\n const name = extractStringValue(getProperty(node, 'name'))\n const type = extractStringValue(getProperty(node, 'type'))\n\n if (!name || !type) {\n return undefined\n }\n\n // Only process if it looks like a Sanity schema (has name and type)\n const title = extractStringValue(getProperty(node, 'title'))\n const description = extractStringValue(getProperty(node, 'description'))\n const fieldsResult = extractFields(getProperty(node, 'fields'))\n const hasFields = fieldsResult.fields.length > 0\n\n const schema: SchemaType = {\n name,\n type,\n hasIcon: hasProperty(node, 'icon'),\n hasPreview: hasProperty(node, 'preview'),\n usesDefineType: false,\n span: toSourceSpan(node.loc),\n ...(title !== undefined && { title }),\n ...(description !== undefined && { description }),\n ...(hasFields && { fields: fieldsResult.fields }),\n ...(hasFields && { usesDefineField: fieldsResult.usesDefineField }),\n }\n\n return schema\n}\n"],"mappings":"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","names":["schemaRules","groqRules","lint","lint","rules","schemaRules"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/utils/rule-factory.ts","../src/utils/groq-extractor.ts","../src/utils/schema-rule-factory.ts","../src/utils/schema-extractor.ts"],"sourcesContent":["/**\n * ESLint plugin for Sanity\n *\n * This plugin provides rules for linting GROQ queries and schema definitions\n * in JavaScript/TypeScript files.\n *\n * @example\n * ```js\n * // eslint.config.js\n * import sanity from 'eslint-plugin-sanity'\n *\n * export default [\n * {\n * plugins: { sanity },\n * rules: {\n * 'sanity/groq-join-in-filter': 'error',\n * 'sanity/schema-missing-icon': 'warn',\n * },\n * },\n * ]\n * ```\n *\n * Or use the recommended config:\n * ```js\n * import sanity from 'eslint-plugin-sanity'\n *\n * export default [\n * ...sanity.configs.recommended,\n * ]\n * ```\n */\n\nimport type { ESLint, Linter } from 'eslint'\nimport { rules as groqRules } from '@sanity/groq-lint'\nimport { rules as schemaRules } from '@sanity/schema-lint'\nimport { createAllRules } from './utils/rule-factory'\nimport { createAllSchemaRules } from './utils/schema-rule-factory'\n\n// Version is injected at build time by tsup\ndeclare const PACKAGE_VERSION: string\nconst version = typeof PACKAGE_VERSION !== 'undefined' ? PACKAGE_VERSION : '0.0.0'\n\n// Create ESLint rules from all GROQ lint rules\nconst groqEslintRules = createAllRules(groqRules)\n\n// Create ESLint rules from all schema lint rules\nconst schemaEslintRules = createAllSchemaRules(schemaRules)\n\n// Combine all rules\nconst rules = {\n ...groqEslintRules,\n ...schemaEslintRules,\n}\n\n// Build the plugin object\nconst plugin: ESLint.Plugin = {\n meta: {\n name: 'eslint-plugin-sanity',\n version,\n },\n rules,\n}\n\n// Create recommended config as an array for easy spreading\n// Users can use either: ...sanity.configs.recommended or sanity.configs.recommended\nconst recommended: Linter.Config[] = [\n {\n plugins: {\n sanity: plugin,\n },\n rules: {\n // === GROQ Rules ===\n\n // Errors - these are serious performance or correctness issues\n 'sanity/groq-join-in-filter': 'error',\n\n // Warnings - performance issues that should be addressed\n 'sanity/groq-deep-pagination': 'warn',\n 'sanity/groq-large-pages': 'warn',\n 'sanity/groq-many-joins': 'warn',\n 'sanity/groq-computed-value-in-filter': 'warn',\n 'sanity/groq-non-literal-comparison': 'warn',\n 'sanity/groq-order-on-expr': 'warn',\n 'sanity/groq-very-large-query': 'warn',\n 'sanity/groq-extremely-large-query': 'error',\n\n // Info - suggestions for improvement (off by default, enable as warnings)\n 'sanity/groq-join-to-get-id': 'warn',\n 'sanity/groq-repeated-dereference': 'warn',\n 'sanity/groq-match-on-id': 'warn',\n 'sanity/groq-count-in-correlated-subquery': 'warn',\n 'sanity/groq-deep-pagination-param': 'warn',\n\n // === Schema Rules ===\n\n // Errors - correctness issues\n 'sanity/schema-missing-define-type': 'error',\n 'sanity/schema-missing-define-field': 'error',\n 'sanity/schema-reserved-field-name': 'error',\n\n // Warnings - best practice violations\n 'sanity/schema-missing-icon': 'warn',\n 'sanity/schema-missing-title': 'warn',\n 'sanity/schema-presentation-field-name': 'warn',\n 'sanity/schema-missing-slug-source': 'warn',\n 'sanity/schema-missing-required-validation': 'warn',\n 'sanity/schema-heading-level-in-schema': 'warn',\n\n // Info - suggestions (off by default)\n 'sanity/schema-missing-description': 'off',\n 'sanity/schema-boolean-instead-of-list': 'off',\n 'sanity/schema-array-missing-constraints': 'off',\n 'sanity/schema-unnecessary-reference': 'off',\n },\n },\n]\n\n// Create strict config (all rules as errors)\nconst strict: Linter.Config[] = [\n {\n plugins: {\n sanity: plugin,\n },\n rules: Object.fromEntries(Object.keys(rules).map((ruleId) => [`sanity/${ruleId}`, 'error'])),\n },\n]\n\n// Configs with explicit type annotation\nconst configs: { recommended: Linter.Config[]; strict: Linter.Config[] } = {\n recommended,\n strict,\n}\n\n// Plugin type\ninterface SanityPlugin {\n meta: ESLint.Plugin['meta']\n rules: typeof rules\n configs: typeof configs\n}\n\n// Default export for ESLint flat config\nconst sanityPlugin: SanityPlugin = {\n meta: plugin.meta,\n rules,\n configs,\n}\n\nexport default sanityPlugin\n\n// Named exports for flexibility\nexport { rules, configs }\n","import type { Rule as ESLintRule } from 'eslint'\nimport type { TSESTree } from '@typescript-eslint/types'\nimport type { Rule as GroqRule } from '@sanity/groq-lint'\nimport { lint, rules as allGroqRules } from '@sanity/groq-lint'\nimport {\n isGroqTaggedTemplate,\n extractGroqString,\n isGroqFunctionCall,\n extractGroqStringFromCall,\n} from './groq-extractor'\n\n/**\n * Build a config that enables only the specified rule\n */\nfunction buildSingleRuleConfig(ruleId: string): Record<string, boolean> {\n const config: Record<string, boolean> = {}\n for (const rule of allGroqRules) {\n config[rule.id] = rule.id === ruleId\n }\n return config\n}\n\n/**\n * Create an ESLint rule from a GROQ lint rule.\n */\nexport function createESLintRule(groqRule: GroqRule): ESLintRule.RuleModule {\n return {\n meta: {\n type: groqRule.category === 'correctness' ? 'problem' : 'suggestion',\n docs: {\n description: groqRule.description,\n recommended: groqRule.severity === 'error',\n },\n messages: {\n [groqRule.id]: '{{ message }}',\n },\n schema: [], // No options for now\n },\n\n create(context) {\n /**\n * Lint a GROQ query and report findings\n */\n function lintQuery(query: string, eslintNode: ESLintRule.Node): void {\n try {\n const result = lint(query, { config: { rules: buildSingleRuleConfig(groqRule.id) } })\n\n for (const finding of result.findings) {\n if (finding.ruleId === groqRule.id) {\n context.report({\n node: eslintNode,\n messageId: groqRule.id,\n data: {\n message: finding.help ? `${finding.message} ${finding.help}` : finding.message,\n },\n })\n }\n }\n } catch {\n // Parse error - don't report, let the user see it in runtime\n }\n }\n\n return {\n // Handle groq`...` tagged template literals\n TaggedTemplateExpression(eslintNode: ESLintRule.Node) {\n const node = eslintNode as unknown as TSESTree.TaggedTemplateExpression\n if (!isGroqTaggedTemplate(node)) {\n return\n }\n\n const query = extractGroqString(node)\n lintQuery(query, eslintNode)\n },\n\n // Handle defineQuery(`...`) and defineQuery(\"...\") function calls\n CallExpression(eslintNode: ESLintRule.Node) {\n const node = eslintNode as unknown as TSESTree.CallExpression\n if (!isGroqFunctionCall(node)) {\n return\n }\n\n const query = extractGroqStringFromCall(node)\n if (query !== null) {\n lintQuery(query, eslintNode)\n }\n },\n }\n },\n }\n}\n\n/**\n * Create all ESLint rules from GROQ lint rules.\n */\nexport function createAllRules(groqRules: GroqRule[]): Record<string, ESLintRule.RuleModule> {\n const eslintRules: Record<string, ESLintRule.RuleModule> = {}\n\n for (const rule of groqRules) {\n // Convert rule ID from snake_case to kebab-case for ESLint convention\n const eslintRuleId = `groq-${rule.id}`\n eslintRules[eslintRuleId] = createESLintRule(rule)\n }\n\n return eslintRules\n}\n","import type { TSESTree } from '@typescript-eslint/types'\n\n/**\n * Known function names that take GROQ queries as their first argument.\n * Used by next-sanity and other Sanity packages.\n */\nconst GROQ_FUNCTION_NAMES = ['defineQuery', 'groq']\n\n/**\n * Check if a node is a tagged template literal with a GROQ tag.\n * Matches: groq`...`, groq.something`...`\n */\nexport function isGroqTaggedTemplate(node: TSESTree.TaggedTemplateExpression): boolean {\n const tag = node.tag\n\n // groq`...`\n if (tag.type === 'Identifier' && tag.name === 'groq') {\n return true\n }\n\n // groq.something`...` (for groq.experimental etc)\n if (\n tag.type === 'MemberExpression' &&\n tag.object.type === 'Identifier' &&\n tag.object.name === 'groq'\n ) {\n return true\n }\n\n return false\n}\n\n/**\n * Check if a node is a function call that takes a GROQ query as its first argument.\n * Matches: defineQuery(`...`), defineQuery(\"...\")\n */\nexport function isGroqFunctionCall(node: TSESTree.CallExpression): boolean {\n const callee = node.callee\n\n // defineQuery(...) or groq(...)\n if (callee.type === 'Identifier' && GROQ_FUNCTION_NAMES.includes(callee.name)) {\n return true\n }\n\n return false\n}\n\n/**\n * Extract the GROQ query string from a function call.\n * Handles both template literals and string literals as the first argument.\n */\nexport function extractGroqStringFromCall(node: TSESTree.CallExpression): string | null {\n const firstArg = node.arguments[0]\n if (!firstArg) return null\n\n // defineQuery(`...`) - template literal\n if (firstArg.type === 'TemplateLiteral') {\n return extractStringFromTemplateLiteral(firstArg)\n }\n\n // defineQuery(\"...\") - string literal\n if (firstArg.type === 'Literal' && typeof firstArg.value === 'string') {\n return firstArg.value\n }\n\n return null\n}\n\n/**\n * Extract string from a template literal, handling expressions.\n */\nfunction extractStringFromTemplateLiteral(node: TSESTree.TemplateLiteral): string {\n const { quasis, expressions } = node\n\n // Simple case: no expressions\n if (expressions.length === 0) {\n return quasis[0]?.value.cooked ?? quasis[0]?.value.raw ?? ''\n }\n\n // Build the string with placeholders for expressions\n let result = ''\n for (let i = 0; i < quasis.length; i++) {\n result += quasis[i]?.value.cooked ?? quasis[i]?.value.raw ?? ''\n if (i < expressions.length) {\n // Replace expression with a parameter placeholder\n result += `$__expr${i}__`\n }\n }\n\n return result\n}\n\n/**\n * Get the source location for a function call's first argument.\n */\nexport function getCallArgumentLocation(\n node: TSESTree.CallExpression\n): TSESTree.SourceLocation | null {\n const firstArg = node.arguments[0]\n if (!firstArg) return null\n return firstArg.loc\n}\n\n/**\n * Extract the GROQ query string from a tagged template literal.\n * Handles template literals with expressions by replacing them with placeholders.\n */\nexport function extractGroqString(node: TSESTree.TaggedTemplateExpression): string {\n const { quasis, expressions } = node.quasi\n\n // Simple case: no expressions\n if (expressions.length === 0) {\n return quasis[0]?.value.cooked ?? quasis[0]?.value.raw ?? ''\n }\n\n // Build the string with placeholders for expressions\n let result = ''\n for (let i = 0; i < quasis.length; i++) {\n result += quasis[i]?.value.cooked ?? quasis[i]?.value.raw ?? ''\n if (i < expressions.length) {\n // Replace expression with a parameter placeholder\n // This allows the query to still parse while marking where expressions are\n result += `$__expr${i}__`\n }\n }\n\n return result\n}\n\n/**\n * Get the source location for reporting errors.\n * Returns the location of the template literal content, not the tag.\n */\nexport function getTemplateLocation(\n node: TSESTree.TaggedTemplateExpression\n): TSESTree.SourceLocation {\n return node.quasi.loc\n}\n","import type { Rule as ESLintRule } from 'eslint'\nimport type { TSESTree } from '@typescript-eslint/types'\nimport type { SchemaRule } from '@sanity/schema-lint'\nimport { lint, rules as schemaRules } from '@sanity/schema-lint'\nimport {\n isDefineTypeCall,\n extractSchemaFromDefineType,\n extractSchemaFromObject,\n} from './schema-extractor'\n\n/**\n * Create an ESLint rule from a schema lint rule.\n */\nexport function createSchemaESLintRule(schemaRule: SchemaRule): ESLintRule.RuleModule {\n return {\n meta: {\n type: schemaRule.category === 'correctness' ? 'problem' : 'suggestion',\n docs: {\n description: schemaRule.description,\n recommended: schemaRule.severity === 'error',\n },\n messages: {\n [schemaRule.id]: '{{ message }}',\n },\n schema: [], // No options for now\n },\n\n create(context) {\n return {\n // Handle defineType() calls\n CallExpression(eslintNode: ESLintRule.Node) {\n // Cast to our TSESTree type for type-safe property access\n const node = eslintNode as unknown as TSESTree.CallExpression\n if (!isDefineTypeCall(node)) {\n return\n }\n\n try {\n const schema = extractSchemaFromDefineType(node)\n if (!schema) {\n return\n }\n\n const result = lint(schema, schemaRules, {\n rules: [schemaRule],\n filePath: context.filename,\n })\n\n for (const finding of result.findings) {\n if (finding.ruleId === schemaRule.id) {\n context.report({\n node: eslintNode,\n messageId: schemaRule.id,\n data: {\n message: finding.help ? `${finding.message} ${finding.help}` : finding.message,\n },\n })\n }\n }\n } catch {\n // Parse error - don't report\n }\n },\n\n // Handle export statements with object literals (not using defineType)\n ExportNamedDeclaration(eslintNode: ESLintRule.Node) {\n // Cast to our TSESTree type for type-safe property access\n const node = eslintNode as unknown as TSESTree.ExportNamedDeclaration\n\n // Only check the missing-define-type rule for non-defineType exports\n if (schemaRule.id !== 'missing-define-type') {\n return\n }\n\n if (!node.declaration) {\n return\n }\n\n // export const foo = { name: '...', type: '...' }\n if (node.declaration.type === 'VariableDeclaration') {\n for (const declarator of node.declaration.declarations) {\n if (\n declarator.init?.type === 'ObjectExpression' &&\n !isWrappedInDefineType(declarator.init)\n ) {\n const schema = extractSchemaFromObject(declarator.init)\n if (schema && (schema.type === 'document' || schema.type === 'object')) {\n try {\n const result = lint(schema, schemaRules, {\n rules: [schemaRule],\n filePath: context.filename,\n })\n\n for (const finding of result.findings) {\n if (finding.ruleId === schemaRule.id) {\n context.report({\n node: eslintNode,\n messageId: schemaRule.id,\n data: {\n message: finding.help\n ? `${finding.message} ${finding.help}`\n : finding.message,\n },\n })\n }\n }\n } catch {\n // Parse error - don't report\n }\n }\n }\n }\n }\n },\n\n // Handle default exports with object literals\n ExportDefaultDeclaration(eslintNode: ESLintRule.Node) {\n // Cast to our TSESTree type for type-safe property access\n const node = eslintNode as unknown as TSESTree.ExportDefaultDeclaration\n\n // Only check the missing-define-type rule for non-defineType exports\n if (schemaRule.id !== 'missing-define-type') {\n return\n }\n\n if (node.declaration.type === 'ObjectExpression') {\n const schema = extractSchemaFromObject(node.declaration)\n if (schema && (schema.type === 'document' || schema.type === 'object')) {\n try {\n const result = lint(schema, schemaRules, {\n rules: [schemaRule],\n filePath: context.filename,\n })\n\n for (const finding of result.findings) {\n if (finding.ruleId === schemaRule.id) {\n context.report({\n node: eslintNode,\n messageId: schemaRule.id,\n data: {\n message: finding.help\n ? `${finding.message} ${finding.help}`\n : finding.message,\n },\n })\n }\n }\n } catch {\n // Parse error - don't report\n }\n }\n }\n },\n }\n },\n }\n}\n\n/**\n * Check if an object expression's parent is a defineType() call\n */\nfunction isWrappedInDefineType(_node: TSESTree.ObjectExpression): boolean {\n // This is a simplified check - in practice we check by seeing if\n // the parent is a CallExpression with defineType callee\n // For now we rely on the CallExpression handler\n return false\n}\n\n/**\n * Create all ESLint rules from schema lint rules.\n */\nexport function createAllSchemaRules(rules: SchemaRule[]): Record<string, ESLintRule.RuleModule> {\n const eslintRules: Record<string, ESLintRule.RuleModule> = {}\n\n for (const rule of rules) {\n // Use schema- prefix to distinguish from groq- rules\n const eslintRuleId = `schema-${rule.id}`\n eslintRules[eslintRuleId] = createSchemaESLintRule(rule)\n }\n\n return eslintRules\n}\n","import type { TSESTree } from '@typescript-eslint/types'\nimport type { SchemaType, SchemaField } from '@sanity/schema-lint'\nimport type { SourceSpan } from '@sanity/lint-core'\n\n/**\n * Check if a node is a defineType() call\n */\nexport function isDefineTypeCall(node: TSESTree.CallExpression): boolean {\n const callee = node.callee\n\n // defineType({ ... })\n if (callee.type === 'Identifier' && callee.name === 'defineType') {\n return true\n }\n\n return false\n}\n\n/**\n * Check if a node is a defineField() call\n */\nexport function isDefineFieldCall(node: TSESTree.CallExpression): boolean {\n const callee = node.callee\n\n // defineField({ ... })\n if (callee.type === 'Identifier' && callee.name === 'defineField') {\n return true\n }\n\n return false\n}\n\n/**\n * Convert ESLint location to our SourceSpan format\n */\nfunction toSourceSpan(loc: TSESTree.SourceLocation): SourceSpan {\n return {\n start: {\n line: loc.start.line,\n column: loc.start.column + 1, // 1-based\n offset: 0, // We don't have offset info easily\n },\n end: {\n line: loc.end.line,\n column: loc.end.column + 1, // 1-based\n offset: 0,\n },\n }\n}\n\n/**\n * Extract a string value from an AST node\n */\nfunction extractStringValue(node: TSESTree.Node | undefined): string | undefined {\n if (!node) return undefined\n\n if (node.type === 'Literal' && typeof node.value === 'string') {\n return node.value\n }\n\n // Handle template literals without expressions\n if (node.type === 'TemplateLiteral' && node.expressions.length === 0) {\n return node.quasis[0]?.value.cooked ?? node.quasis[0]?.value.raw\n }\n\n return undefined\n}\n\n/**\n * Extract a boolean value from an AST node\n */\nfunction extractBooleanValue(node: TSESTree.Node | undefined): boolean | undefined {\n if (!node) return undefined\n\n if (node.type === 'Literal' && typeof node.value === 'boolean') {\n return node.value\n }\n\n return undefined\n}\n\n/**\n * Check if a property exists in an object expression\n */\nfunction hasProperty(node: TSESTree.ObjectExpression, name: string): boolean {\n return node.properties.some((prop) => {\n if (prop.type === 'Property' && prop.key.type === 'Identifier') {\n return prop.key.name === name\n }\n return false\n })\n}\n\n/**\n * Get a property value from an object expression\n */\nfunction getProperty(node: TSESTree.ObjectExpression, name: string): TSESTree.Node | undefined {\n for (const prop of node.properties) {\n if (prop.type === 'Property' && prop.key.type === 'Identifier' && prop.key.name === name) {\n return prop.value\n }\n }\n return undefined\n}\n\n/**\n * Extract field options from an object expression\n */\nfunction extractFieldOptions(\n optionsNode: TSESTree.Node | undefined\n): SchemaField['options'] | undefined {\n if (!optionsNode || optionsNode.type !== 'ObjectExpression') {\n return undefined\n }\n\n const options: NonNullable<SchemaField['options']> = {}\n\n for (const prop of optionsNode.properties) {\n if (prop.type === 'Property' && prop.key.type === 'Identifier') {\n const name = prop.key.name\n\n if (name === 'source') {\n const source = extractStringValue(prop.value)\n if (source !== undefined) options.source = source\n } else if (name === 'hotspot') {\n const hotspot = extractBooleanValue(prop.value)\n if (hotspot !== undefined) options.hotspot = hotspot\n } else if (name === 'layout') {\n const layout = extractStringValue(prop.value)\n if (layout !== undefined) options.layout = layout\n } else if (name === 'list' && prop.value.type === 'ArrayExpression') {\n options.list = prop.value.elements.map((el) => {\n if (!el) return null\n if (el.type === 'Literal') return el.value\n if (el.type === 'ObjectExpression') {\n const value = extractStringValue(getProperty(el, 'value'))\n return { value }\n }\n return null\n })\n }\n }\n }\n\n return Object.keys(options).length > 0 ? options : undefined\n}\n\n/**\n * Extract a field from an object expression (either raw or wrapped in defineField)\n */\nfunction extractField(\n node: TSESTree.Node,\n usesDefineField: { value: boolean }\n): SchemaField | undefined {\n let fieldObj: TSESTree.ObjectExpression | undefined\n\n // Check if it's wrapped in defineField()\n if (node.type === 'CallExpression' && isDefineFieldCall(node)) {\n const arg = node.arguments[0]\n if (arg?.type === 'ObjectExpression') {\n fieldObj = arg\n }\n } else if (node.type === 'ObjectExpression') {\n fieldObj = node\n usesDefineField.value = false // At least one field doesn't use defineField\n }\n\n if (!fieldObj) return undefined\n\n const name = extractStringValue(getProperty(fieldObj, 'name'))\n const type = extractStringValue(getProperty(fieldObj, 'type'))\n\n if (!name || !type) return undefined\n\n const title = extractStringValue(getProperty(fieldObj, 'title'))\n const description = extractStringValue(getProperty(fieldObj, 'description'))\n const options = extractFieldOptions(getProperty(fieldObj, 'options'))\n\n const field: SchemaField = {\n name,\n type,\n hasValidation: hasProperty(fieldObj, 'validation'),\n hidden: hasProperty(fieldObj, 'hidden'),\n readOnly: hasProperty(fieldObj, 'readOnly'),\n span: toSourceSpan(fieldObj.loc),\n ...(title !== undefined && { title }),\n ...(description !== undefined && { description }),\n ...(options !== undefined && { options }),\n }\n\n // Check for deprecated\n if (hasProperty(fieldObj, 'deprecated')) {\n const deprecatedNode = getProperty(fieldObj, 'deprecated')\n const deprecatedValue = extractStringValue(deprecatedNode)\n field.deprecated = deprecatedValue ?? true\n }\n\n return field\n}\n\n/**\n * Extract fields from an array expression\n */\nfunction extractFields(node: TSESTree.Node | undefined): {\n fields: SchemaField[]\n usesDefineField: boolean\n} {\n const result = { fields: [] as SchemaField[], usesDefineField: true }\n\n if (!node || node.type !== 'ArrayExpression') {\n return result\n }\n\n const usesDefineFieldTracker = { value: true }\n\n for (const element of node.elements) {\n if (element) {\n const field = extractField(element, usesDefineFieldTracker)\n if (field) {\n result.fields.push(field)\n }\n }\n }\n\n result.usesDefineField = usesDefineFieldTracker.value\n\n return result\n}\n\n/**\n * Extract schema type from a defineType() call\n */\nexport function extractSchemaFromDefineType(node: TSESTree.CallExpression): SchemaType | undefined {\n const arg = node.arguments[0]\n\n if (!arg || arg.type !== 'ObjectExpression') {\n return undefined\n }\n\n const name = extractStringValue(getProperty(arg, 'name'))\n const type = extractStringValue(getProperty(arg, 'type'))\n\n if (!name || !type) {\n return undefined\n }\n\n const title = extractStringValue(getProperty(arg, 'title'))\n const description = extractStringValue(getProperty(arg, 'description'))\n const fieldsResult = extractFields(getProperty(arg, 'fields'))\n const hasFields = fieldsResult.fields.length > 0\n\n const schema: SchemaType = {\n name,\n type,\n hasIcon: hasProperty(arg, 'icon'),\n hasPreview: hasProperty(arg, 'preview'),\n usesDefineType: true,\n span: toSourceSpan(arg.loc),\n ...(title !== undefined && { title }),\n ...(description !== undefined && { description }),\n ...(hasFields && { fields: fieldsResult.fields }),\n ...(hasFields && { usesDefineField: fieldsResult.usesDefineField }),\n }\n\n return schema\n}\n\n/**\n * Extract schema type from a plain object literal (not wrapped in defineType)\n */\nexport function extractSchemaFromObject(node: TSESTree.ObjectExpression): SchemaType | undefined {\n const name = extractStringValue(getProperty(node, 'name'))\n const type = extractStringValue(getProperty(node, 'type'))\n\n if (!name || !type) {\n return undefined\n }\n\n // Only process if it looks like a Sanity schema (has name and type)\n const title = extractStringValue(getProperty(node, 'title'))\n const description = extractStringValue(getProperty(node, 'description'))\n const fieldsResult = extractFields(getProperty(node, 'fields'))\n const hasFields = fieldsResult.fields.length > 0\n\n const schema: SchemaType = {\n name,\n type,\n hasIcon: hasProperty(node, 'icon'),\n hasPreview: hasProperty(node, 'preview'),\n usesDefineType: false,\n span: toSourceSpan(node.loc),\n ...(title !== undefined && { title }),\n ...(description !== undefined && { description }),\n ...(hasFields && { fields: fieldsResult.fields }),\n ...(hasFields && { usesDefineField: fieldsResult.usesDefineField }),\n }\n\n return schema\n}\n"],"mappings":"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","names":["schemaRules","groqRules","lint","lint","rules","schemaRules"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint-plugin-sanity",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "ESLint plugin for Sanity Lint - lint GROQ queries and schema definitions",
5
5
  "author": "Sanity.io <hello@sanity.io>",
6
6
  "license": "MIT",
@@ -27,9 +27,9 @@
27
27
  "dist"
28
28
  ],
29
29
  "dependencies": {
30
- "@sanity/groq-lint": "0.0.2",
31
- "@sanity/lint-core": "0.0.2",
32
- "@sanity/schema-lint": "0.0.2"
30
+ "@sanity/groq-lint": "0.0.3",
31
+ "@sanity/schema-lint": "0.0.3",
32
+ "@sanity/lint-core": "0.0.3"
33
33
  },
34
34
  "peerDependencies": {
35
35
  "eslint": ">=8.0.0"