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 +46 -4
- package/dist/index.cjs +52 -48
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +52 -48
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
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
|
|
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.
|
|
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
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
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
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
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
|
package/dist/index.cjs.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":["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.
|
|
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
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
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
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
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":";AAiCA,SAAS,SAAS,iBAAiB;AACnC,SAAS,SAASA,oBAAmB;;;AC/BrC,SAAS,MAAM,SAAS,oBAAoB;;;ACG5C,IAAM,sBAAsB,CAAC,eAAe,MAAM;AAM3C,SAAS,qBAAqB,MAAkD;AACrF,QAAM,MAAM,KAAK;AAGjB,MAAI,IAAI,SAAS,gBAAgB,IAAI,SAAS,QAAQ;AACpD,WAAO;AAAA,EACT;AAGA,MACE,IAAI,SAAS,sBACb,IAAI,OAAO,SAAS,gBACpB,IAAI,OAAO,SAAS,QACpB;AACA,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAMO,SAAS,mBAAmB,MAAwC;AACzE,QAAM,SAAS,KAAK;AAGpB,MAAI,OAAO,SAAS,gBAAgB,oBAAoB,SAAS,OAAO,IAAI,GAAG;AAC7E,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAMO,SAAS,0BAA0B,MAA8C;AACtF,QAAM,WAAW,KAAK,UAAU,CAAC;AACjC,MAAI,CAAC,SAAU,QAAO;AAGtB,MAAI,SAAS,SAAS,mBAAmB;AACvC,WAAO,iCAAiC,QAAQ;AAAA,EAClD;AAGA,MAAI,SAAS,SAAS,aAAa,OAAO,SAAS,UAAU,UAAU;AACrE,WAAO,SAAS;AAAA,EAClB;AAEA,SAAO;AACT;AAKA,SAAS,iCAAiC,MAAwC;AAChF,QAAM,EAAE,QAAQ,YAAY,IAAI;AAGhC,MAAI,YAAY,WAAW,GAAG;AAC5B,WAAO,OAAO,CAAC,GAAG,MAAM,UAAU,OAAO,CAAC,GAAG,MAAM,OAAO;AAAA,EAC5D;AAGA,MAAI,SAAS;AACb,WAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;AACtC,cAAU,OAAO,CAAC,GAAG,MAAM,UAAU,OAAO,CAAC,GAAG,MAAM,OAAO;AAC7D,QAAI,IAAI,YAAY,QAAQ;AAE1B,gBAAU,UAAU,CAAC;AAAA,IACvB;AAAA,EACF;AAEA,SAAO;AACT;AAiBO,SAAS,kBAAkB,MAAiD;AACjF,QAAM,EAAE,QAAQ,YAAY,IAAI,KAAK;AAGrC,MAAI,YAAY,WAAW,GAAG;AAC5B,WAAO,OAAO,CAAC,GAAG,MAAM,UAAU,OAAO,CAAC,GAAG,MAAM,OAAO;AAAA,EAC5D;AAGA,MAAI,SAAS;AACb,WAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;AACtC,cAAU,OAAO,CAAC,GAAG,MAAM,UAAU,OAAO,CAAC,GAAG,MAAM,OAAO;AAC7D,QAAI,IAAI,YAAY,QAAQ;AAG1B,gBAAU,UAAU,CAAC;AAAA,IACvB;AAAA,EACF;AAEA,SAAO;AACT;;;ADjHA,SAAS,sBAAsB,QAAyC;AACtE,QAAM,SAAkC,CAAC;AACzC,aAAW,QAAQ,cAAc;AAC/B,WAAO,KAAK,EAAE,IAAI,KAAK,OAAO;AAAA,EAChC;AACA,SAAO;AACT;AAKO,SAAS,iBAAiB,UAA2C;AAC1E,SAAO;AAAA,IACL,MAAM;AAAA,MACJ,MAAM,SAAS,aAAa,gBAAgB,YAAY;AAAA,MACxD,MAAM;AAAA,QACJ,aAAa,SAAS;AAAA,QACtB,aAAa,SAAS,aAAa;AAAA,MACrC;AAAA,MACA,UAAU;AAAA,QACR,CAAC,SAAS,EAAE,GAAG;AAAA,MACjB;AAAA,MACA,QAAQ,CAAC;AAAA;AAAA,IACX;AAAA,IAEA,OAAO,SAAS;AAId,eAAS,UAAU,OAAe,YAAmC;AACnE,YAAI;AACF,gBAAM,SAAS,KAAK,OAAO,EAAE,QAAQ,EAAE,OAAO,sBAAsB,SAAS,EAAE,EAAE,EAAE,CAAC;AAEpF,qBAAW,WAAW,OAAO,UAAU;AACrC,gBAAI,QAAQ,WAAW,SAAS,IAAI;AAClC,sBAAQ,OAAO;AAAA,gBACb,MAAM;AAAA,gBACN,WAAW,SAAS;AAAA,gBACpB,MAAM;AAAA,kBACJ,SAAS,QAAQ,OAAO,GAAG,QAAQ,OAAO,IAAI,QAAQ,IAAI,KAAK,QAAQ;AAAA,gBACzE;AAAA,cACF,CAAC;AAAA,YACH;AAAA,UACF;AAAA,QACF,QAAQ;AAAA,QAER;AAAA,MACF;AAEA,aAAO;AAAA;AAAA,QAEL,yBAAyB,YAA6B;AACpD,gBAAM,OAAO;AACb,cAAI,CAAC,qBAAqB,IAAI,GAAG;AAC/B;AAAA,UACF;AAEA,gBAAM,QAAQ,kBAAkB,IAAI;AACpC,oBAAU,OAAO,UAAU;AAAA,QAC7B;AAAA;AAAA,QAGA,eAAe,YAA6B;AAC1C,gBAAM,OAAO;AACb,cAAI,CAAC,mBAAmB,IAAI,GAAG;AAC7B;AAAA,UACF;AAEA,gBAAM,QAAQ,0BAA0B,IAAI;AAC5C,cAAI,UAAU,MAAM;AAClB,sBAAU,OAAO,UAAU;AAAA,UAC7B;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAKO,SAAS,eAAeC,YAA8D;AAC3F,QAAM,cAAqD,CAAC;AAE5D,aAAW,QAAQA,YAAW;AAE5B,UAAM,eAAe,QAAQ,KAAK,EAAE;AACpC,gBAAY,YAAY,IAAI,iBAAiB,IAAI;AAAA,EACnD;AAEA,SAAO;AACT;;;AEtGA,SAAS,QAAAC,OAAM,SAAS,mBAAmB;;;ACIpC,SAAS,iBAAiB,MAAwC;AACvE,QAAM,SAAS,KAAK;AAGpB,MAAI,OAAO,SAAS,gBAAgB,OAAO,SAAS,cAAc;AAChE,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAKO,SAAS,kBAAkB,MAAwC;AACxE,QAAM,SAAS,KAAK;AAGpB,MAAI,OAAO,SAAS,gBAAgB,OAAO,SAAS,eAAe;AACjE,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAKA,SAAS,aAAa,KAA0C;AAC9D,SAAO;AAAA,IACL,OAAO;AAAA,MACL,MAAM,IAAI,MAAM;AAAA,MAChB,QAAQ,IAAI,MAAM,SAAS;AAAA;AAAA,MAC3B,QAAQ;AAAA;AAAA,IACV;AAAA,IACA,KAAK;AAAA,MACH,MAAM,IAAI,IAAI;AAAA,MACd,QAAQ,IAAI,IAAI,SAAS;AAAA;AAAA,MACzB,QAAQ;AAAA,IACV;AAAA,EACF;AACF;AAKA,SAAS,mBAAmB,MAAqD;AAC/E,MAAI,CAAC,KAAM,QAAO;AAElB,MAAI,KAAK,SAAS,aAAa,OAAO,KAAK,UAAU,UAAU;AAC7D,WAAO,KAAK;AAAA,EACd;AAGA,MAAI,KAAK,SAAS,qBAAqB,KAAK,YAAY,WAAW,GAAG;AACpE,WAAO,KAAK,OAAO,CAAC,GAAG,MAAM,UAAU,KAAK,OAAO,CAAC,GAAG,MAAM;AAAA,EAC/D;AAEA,SAAO;AACT;AAKA,SAAS,oBAAoB,MAAsD;AACjF,MAAI,CAAC,KAAM,QAAO;AAElB,MAAI,KAAK,SAAS,aAAa,OAAO,KAAK,UAAU,WAAW;AAC9D,WAAO,KAAK;AAAA,EACd;AAEA,SAAO;AACT;AAKA,SAAS,YAAY,MAAiC,MAAuB;AAC3E,SAAO,KAAK,WAAW,KAAK,CAAC,SAAS;AACpC,QAAI,KAAK,SAAS,cAAc,KAAK,IAAI,SAAS,cAAc;AAC9D,aAAO,KAAK,IAAI,SAAS;AAAA,IAC3B;AACA,WAAO;AAAA,EACT,CAAC;AACH;AAKA,SAAS,YAAY,MAAiC,MAAyC;AAC7F,aAAW,QAAQ,KAAK,YAAY;AAClC,QAAI,KAAK,SAAS,cAAc,KAAK,IAAI,SAAS,gBAAgB,KAAK,IAAI,SAAS,MAAM;AACxF,aAAO,KAAK;AAAA,IACd;AAAA,EACF;AACA,SAAO;AACT;AAKA,SAAS,oBACP,aACoC;AACpC,MAAI,CAAC,eAAe,YAAY,SAAS,oBAAoB;AAC3D,WAAO;AAAA,EACT;AAEA,QAAM,UAA+C,CAAC;AAEtD,aAAW,QAAQ,YAAY,YAAY;AACzC,QAAI,KAAK,SAAS,cAAc,KAAK,IAAI,SAAS,cAAc;AAC9D,YAAM,OAAO,KAAK,IAAI;AAEtB,UAAI,SAAS,UAAU;AACrB,cAAM,SAAS,mBAAmB,KAAK,KAAK;AAC5C,YAAI,WAAW,OAAW,SAAQ,SAAS;AAAA,MAC7C,WAAW,SAAS,WAAW;AAC7B,cAAM,UAAU,oBAAoB,KAAK,KAAK;AAC9C,YAAI,YAAY,OAAW,SAAQ,UAAU;AAAA,MAC/C,WAAW,SAAS,UAAU;AAC5B,cAAM,SAAS,mBAAmB,KAAK,KAAK;AAC5C,YAAI,WAAW,OAAW,SAAQ,SAAS;AAAA,MAC7C,WAAW,SAAS,UAAU,KAAK,MAAM,SAAS,mBAAmB;AACnE,gBAAQ,OAAO,KAAK,MAAM,SAAS,IAAI,CAAC,OAAO;AAC7C,cAAI,CAAC,GAAI,QAAO;AAChB,cAAI,GAAG,SAAS,UAAW,QAAO,GAAG;AACrC,cAAI,GAAG,SAAS,oBAAoB;AAClC,kBAAM,QAAQ,mBAAmB,YAAY,IAAI,OAAO,CAAC;AACzD,mBAAO,EAAE,MAAM;AAAA,UACjB;AACA,iBAAO;AAAA,QACT,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAEA,SAAO,OAAO,KAAK,OAAO,EAAE,SAAS,IAAI,UAAU;AACrD;AAKA,SAAS,aACP,MACA,iBACyB;AACzB,MAAI;AAGJ,MAAI,KAAK,SAAS,oBAAoB,kBAAkB,IAAI,GAAG;AAC7D,UAAM,MAAM,KAAK,UAAU,CAAC;AAC5B,QAAI,KAAK,SAAS,oBAAoB;AACpC,iBAAW;AAAA,IACb;AAAA,EACF,WAAW,KAAK,SAAS,oBAAoB;AAC3C,eAAW;AACX,oBAAgB,QAAQ;AAAA,EAC1B;AAEA,MAAI,CAAC,SAAU,QAAO;AAEtB,QAAM,OAAO,mBAAmB,YAAY,UAAU,MAAM,CAAC;AAC7D,QAAM,OAAO,mBAAmB,YAAY,UAAU,MAAM,CAAC;AAE7D,MAAI,CAAC,QAAQ,CAAC,KAAM,QAAO;AAE3B,QAAM,QAAQ,mBAAmB,YAAY,UAAU,OAAO,CAAC;AAC/D,QAAM,cAAc,mBAAmB,YAAY,UAAU,aAAa,CAAC;AAC3E,QAAM,UAAU,oBAAoB,YAAY,UAAU,SAAS,CAAC;AAEpE,QAAM,QAAqB;AAAA,IACzB;AAAA,IACA;AAAA,IACA,eAAe,YAAY,UAAU,YAAY;AAAA,IACjD,QAAQ,YAAY,UAAU,QAAQ;AAAA,IACtC,UAAU,YAAY,UAAU,UAAU;AAAA,IAC1C,MAAM,aAAa,SAAS,GAAG;AAAA,IAC/B,GAAI,UAAU,UAAa,EAAE,MAAM;AAAA,IACnC,GAAI,gBAAgB,UAAa,EAAE,YAAY;AAAA,IAC/C,GAAI,YAAY,UAAa,EAAE,QAAQ;AAAA,EACzC;AAGA,MAAI,YAAY,UAAU,YAAY,GAAG;AACvC,UAAM,iBAAiB,YAAY,UAAU,YAAY;AACzD,UAAM,kBAAkB,mBAAmB,cAAc;AACzD,UAAM,aAAa,mBAAmB;AAAA,EACxC;AAEA,SAAO;AACT;AAKA,SAAS,cAAc,MAGrB;AACA,QAAM,SAAS,EAAE,QAAQ,CAAC,GAAoB,iBAAiB,KAAK;AAEpE,MAAI,CAAC,QAAQ,KAAK,SAAS,mBAAmB;AAC5C,WAAO;AAAA,EACT;AAEA,QAAM,yBAAyB,EAAE,OAAO,KAAK;AAE7C,aAAW,WAAW,KAAK,UAAU;AACnC,QAAI,SAAS;AACX,YAAM,QAAQ,aAAa,SAAS,sBAAsB;AAC1D,UAAI,OAAO;AACT,eAAO,OAAO,KAAK,KAAK;AAAA,MAC1B;AAAA,IACF;AAAA,EACF;AAEA,SAAO,kBAAkB,uBAAuB;AAEhD,SAAO;AACT;AAKO,SAAS,4BAA4B,MAAuD;AACjG,QAAM,MAAM,KAAK,UAAU,CAAC;AAE5B,MAAI,CAAC,OAAO,IAAI,SAAS,oBAAoB;AAC3C,WAAO;AAAA,EACT;AAEA,QAAM,OAAO,mBAAmB,YAAY,KAAK,MAAM,CAAC;AACxD,QAAM,OAAO,mBAAmB,YAAY,KAAK,MAAM,CAAC;AAExD,MAAI,CAAC,QAAQ,CAAC,MAAM;AAClB,WAAO;AAAA,EACT;AAEA,QAAM,QAAQ,mBAAmB,YAAY,KAAK,OAAO,CAAC;AAC1D,QAAM,cAAc,mBAAmB,YAAY,KAAK,aAAa,CAAC;AACtE,QAAM,eAAe,cAAc,YAAY,KAAK,QAAQ,CAAC;AAC7D,QAAM,YAAY,aAAa,OAAO,SAAS;AAE/C,QAAM,SAAqB;AAAA,IACzB;AAAA,IACA;AAAA,IACA,SAAS,YAAY,KAAK,MAAM;AAAA,IAChC,YAAY,YAAY,KAAK,SAAS;AAAA,IACtC,gBAAgB;AAAA,IAChB,MAAM,aAAa,IAAI,GAAG;AAAA,IAC1B,GAAI,UAAU,UAAa,EAAE,MAAM;AAAA,IACnC,GAAI,gBAAgB,UAAa,EAAE,YAAY;AAAA,IAC/C,GAAI,aAAa,EAAE,QAAQ,aAAa,OAAO;AAAA,IAC/C,GAAI,aAAa,EAAE,iBAAiB,aAAa,gBAAgB;AAAA,EACnE;AAEA,SAAO;AACT;AAKO,SAAS,wBAAwB,MAAyD;AAC/F,QAAM,OAAO,mBAAmB,YAAY,MAAM,MAAM,CAAC;AACzD,QAAM,OAAO,mBAAmB,YAAY,MAAM,MAAM,CAAC;AAEzD,MAAI,CAAC,QAAQ,CAAC,MAAM;AAClB,WAAO;AAAA,EACT;AAGA,QAAM,QAAQ,mBAAmB,YAAY,MAAM,OAAO,CAAC;AAC3D,QAAM,cAAc,mBAAmB,YAAY,MAAM,aAAa,CAAC;AACvE,QAAM,eAAe,cAAc,YAAY,MAAM,QAAQ,CAAC;AAC9D,QAAM,YAAY,aAAa,OAAO,SAAS;AAE/C,QAAM,SAAqB;AAAA,IACzB;AAAA,IACA;AAAA,IACA,SAAS,YAAY,MAAM,MAAM;AAAA,IACjC,YAAY,YAAY,MAAM,SAAS;AAAA,IACvC,gBAAgB;AAAA,IAChB,MAAM,aAAa,KAAK,GAAG;AAAA,IAC3B,GAAI,UAAU,UAAa,EAAE,MAAM;AAAA,IACnC,GAAI,gBAAgB,UAAa,EAAE,YAAY;AAAA,IAC/C,GAAI,aAAa,EAAE,QAAQ,aAAa,OAAO;AAAA,IAC/C,GAAI,aAAa,EAAE,iBAAiB,aAAa,gBAAgB;AAAA,EACnE;AAEA,SAAO;AACT;;;AD7RO,SAAS,uBAAuB,YAA+C;AACpF,SAAO;AAAA,IACL,MAAM;AAAA,MACJ,MAAM,WAAW,aAAa,gBAAgB,YAAY;AAAA,MAC1D,MAAM;AAAA,QACJ,aAAa,WAAW;AAAA,QACxB,aAAa,WAAW,aAAa;AAAA,MACvC;AAAA,MACA,UAAU;AAAA,QACR,CAAC,WAAW,EAAE,GAAG;AAAA,MACnB;AAAA,MACA,QAAQ,CAAC;AAAA;AAAA,IACX;AAAA,IAEA,OAAO,SAAS;AACd,aAAO;AAAA;AAAA,QAEL,eAAe,YAA6B;AAE1C,gBAAM,OAAO;AACb,cAAI,CAAC,iBAAiB,IAAI,GAAG;AAC3B;AAAA,UACF;AAEA,cAAI;AACF,kBAAM,SAAS,4BAA4B,IAAI;AAC/C,gBAAI,CAAC,QAAQ;AACX;AAAA,YACF;AAEA,kBAAM,SAASC,MAAK,QAAQ,aAAa;AAAA,cACvC,OAAO,CAAC,UAAU;AAAA,cAClB,UAAU,QAAQ;AAAA,YACpB,CAAC;AAED,uBAAW,WAAW,OAAO,UAAU;AACrC,kBAAI,QAAQ,WAAW,WAAW,IAAI;AACpC,wBAAQ,OAAO;AAAA,kBACb,MAAM;AAAA,kBACN,WAAW,WAAW;AAAA,kBACtB,MAAM;AAAA,oBACJ,SAAS,QAAQ,OAAO,GAAG,QAAQ,OAAO,IAAI,QAAQ,IAAI,KAAK,QAAQ;AAAA,kBACzE;AAAA,gBACF,CAAC;AAAA,cACH;AAAA,YACF;AAAA,UACF,QAAQ;AAAA,UAER;AAAA,QACF;AAAA;AAAA,QAGA,uBAAuB,YAA6B;AAElD,gBAAM,OAAO;AAGb,cAAI,WAAW,OAAO,uBAAuB;AAC3C;AAAA,UACF;AAEA,cAAI,CAAC,KAAK,aAAa;AACrB;AAAA,UACF;AAGA,cAAI,KAAK,YAAY,SAAS,uBAAuB;AACnD,uBAAW,cAAc,KAAK,YAAY,cAAc;AACtD,kBACE,WAAW,MAAM,SAAS,sBAC1B,CAAC,sBAAsB,WAAW,IAAI,GACtC;AACA,sBAAM,SAAS,wBAAwB,WAAW,IAAI;AACtD,oBAAI,WAAW,OAAO,SAAS,cAAc,OAAO,SAAS,WAAW;AACtE,sBAAI;AACF,0BAAM,SAASA,MAAK,QAAQ,aAAa;AAAA,sBACvC,OAAO,CAAC,UAAU;AAAA,sBAClB,UAAU,QAAQ;AAAA,oBACpB,CAAC;AAED,+BAAW,WAAW,OAAO,UAAU;AACrC,0BAAI,QAAQ,WAAW,WAAW,IAAI;AACpC,gCAAQ,OAAO;AAAA,0BACb,MAAM;AAAA,0BACN,WAAW,WAAW;AAAA,0BACtB,MAAM;AAAA,4BACJ,SAAS,QAAQ,OACb,GAAG,QAAQ,OAAO,IAAI,QAAQ,IAAI,KAClC,QAAQ;AAAA,0BACd;AAAA,wBACF,CAAC;AAAA,sBACH;AAAA,oBACF;AAAA,kBACF,QAAQ;AAAA,kBAER;AAAA,gBACF;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA;AAAA,QAGA,yBAAyB,YAA6B;AAEpD,gBAAM,OAAO;AAGb,cAAI,WAAW,OAAO,uBAAuB;AAC3C;AAAA,UACF;AAEA,cAAI,KAAK,YAAY,SAAS,oBAAoB;AAChD,kBAAM,SAAS,wBAAwB,KAAK,WAAW;AACvD,gBAAI,WAAW,OAAO,SAAS,cAAc,OAAO,SAAS,WAAW;AACtE,kBAAI;AACF,sBAAM,SAASA,MAAK,QAAQ,aAAa;AAAA,kBACvC,OAAO,CAAC,UAAU;AAAA,kBAClB,UAAU,QAAQ;AAAA,gBACpB,CAAC;AAED,2BAAW,WAAW,OAAO,UAAU;AACrC,sBAAI,QAAQ,WAAW,WAAW,IAAI;AACpC,4BAAQ,OAAO;AAAA,sBACb,MAAM;AAAA,sBACN,WAAW,WAAW;AAAA,sBACtB,MAAM;AAAA,wBACJ,SAAS,QAAQ,OACb,GAAG,QAAQ,OAAO,IAAI,QAAQ,IAAI,KAClC,QAAQ;AAAA,sBACd;AAAA,oBACF,CAAC;AAAA,kBACH;AAAA,gBACF;AAAA,cACF,QAAQ;AAAA,cAER;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAKA,SAAS,sBAAsB,OAA2C;AAIxE,SAAO;AACT;AAKO,SAAS,qBAAqBC,QAA4D;AAC/F,QAAM,cAAqD,CAAC;AAE5D,aAAW,QAAQA,QAAO;AAExB,UAAM,eAAe,UAAU,KAAK,EAAE;AACtC,gBAAY,YAAY,IAAI,uBAAuB,IAAI;AAAA,EACzD;AAEA,SAAO;AACT;;;AH7IA,IAAM,UAAU,OAAyC,UAAkB;AAG3E,IAAM,kBAAkB,eAAe,SAAS;AAGhD,IAAM,oBAAoB,qBAAqBC,YAAW;AAG1D,IAAM,QAAQ;AAAA,EACZ,GAAG;AAAA,EACH,GAAG;AACL;AAGA,IAAM,SAAwB;AAAA,EAC5B,MAAM;AAAA,IACJ,MAAM;AAAA,IACN;AAAA,EACF;AAAA,EACA;AACF;AAGA,IAAM,cAA6B;AAAA,EACjC,SAAS;AAAA,IACP,QAAQ;AAAA,EACV;AAAA,EACA,OAAO;AAAA;AAAA;AAAA,IAIL,8BAA8B;AAAA;AAAA,IAG9B,+BAA+B;AAAA,IAC/B,2BAA2B;AAAA,IAC3B,0BAA0B;AAAA,IAC1B,wCAAwC;AAAA,IACxC,sCAAsC;AAAA,IACtC,6BAA6B;AAAA,IAC7B,gCAAgC;AAAA,IAChC,qCAAqC;AAAA;AAAA,IAGrC,8BAA8B;AAAA,IAC9B,oCAAoC;AAAA,IACpC,2BAA2B;AAAA,IAC3B,4CAA4C;AAAA,IAC5C,qCAAqC;AAAA;AAAA;AAAA,IAKrC,qCAAqC;AAAA,IACrC,sCAAsC;AAAA,IACtC,qCAAqC;AAAA;AAAA,IAGrC,8BAA8B;AAAA,IAC9B,+BAA+B;AAAA,IAC/B,yCAAyC;AAAA,IACzC,qCAAqC;AAAA,IACrC,6CAA6C;AAAA,IAC7C,yCAAyC;AAAA;AAAA,IAGzC,qCAAqC;AAAA,IACrC,yCAAyC;AAAA,IACzC,2CAA2C;AAAA,IAC3C,uCAAuC;AAAA,EACzC;AACF;AAGA,IAAM,SAAwB;AAAA,EAC5B,SAAS;AAAA,IACP,QAAQ;AAAA,EACV;AAAA,EACA,OAAO,OAAO,YAAY,OAAO,KAAK,KAAK,EAAE,IAAI,CAAC,WAAW,CAAC,UAAU,MAAM,IAAI,OAAO,CAAC,CAAC;AAC7F;AAGA,IAAM,UAAiE;AAAA,EACrE;AAAA,EACA;AACF;AAUA,IAAM,eAA6B;AAAA,EACjC,MAAM,OAAO;AAAA,EACb;AAAA,EACA;AACF;AAEA,IAAO,gBAAQ;","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.
|
|
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.
|
|
31
|
-
"@sanity/lint
|
|
32
|
-
"@sanity/
|
|
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"
|