@sanity-labs/groq-content-mapper 0.1.3 → 0.1.4
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.
|
@@ -41,11 +41,23 @@ function getMessage(error) {
|
|
|
41
41
|
* Parses a GROQ query for type evaluation. groq-js only accepts constant slice bounds, so a
|
|
42
42
|
* `$param` used as one is bound to `0` first: the value does not matter for its type. Not for
|
|
43
43
|
* queries that are executed.
|
|
44
|
+
*
|
|
45
|
+
* groq-js 2.0 only ends a `//` comment at a newline, so a file whose last line is a comment
|
|
46
|
+
* would not parse; such a query is parsed again with one appended. Any other error is the
|
|
47
|
+
* query's own, at its own position.
|
|
44
48
|
*/
|
|
45
49
|
function safeParseQuery(query) {
|
|
46
50
|
let params = {};
|
|
47
51
|
for (let param of extractSliceParams(query)) params[param] = 0;
|
|
48
|
-
|
|
52
|
+
try {
|
|
53
|
+
return parse(query, { params });
|
|
54
|
+
} catch (error) {
|
|
55
|
+
try {
|
|
56
|
+
return parse(`${query}\n`, { params });
|
|
57
|
+
} catch {
|
|
58
|
+
throw error;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
49
61
|
}
|
|
50
62
|
/** The names of the `$params` used as slice bounds, as in `[$start...$end]` or `[10..$end]`. */
|
|
51
63
|
function* extractSliceParams(query) {
|
|
@@ -893,4 +905,4 @@ function parse$1(schema, params, method) {
|
|
|
893
905
|
}
|
|
894
906
|
export { serveJsonRpc as a, JsonRpcErrorCode as i, DIAGNOSTIC_SOURCE as n, GroqFileDiagnosticCode as o, JsonRpcError as r, generateGroqModule as s, ContentMapper as t };
|
|
895
907
|
|
|
896
|
-
//# sourceMappingURL=contentMapper-
|
|
908
|
+
//# sourceMappingURL=contentMapper-BRyFa5Y0.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contentMapper-BRyFa5Y0.js","names":["resolve","exhaustive","parse"],"sources":["../src/helpers.ts","../src/safeParseQuery.ts","../src/inferParams.ts","../src/schemaTypes.ts","../src/groqModule.ts","../src/jsonRpc.ts","../src/schemas.ts","../src/contentMapper.ts"],"sourcesContent":["import path from 'node:path'\n\nimport {CodeGenerator} from '@babel/generator'\nimport * as t from '@babel/types'\n\n/**\n * Names `@sanity/codegen` gives the helpers a schema type can refer to. A module that refers to\n * one declares it locally, as `sanity.types.ts` does.\n */\nexport const ARRAY_OF = 'ArrayOf'\nexport const INTERNAL_REFERENCE_SYMBOL = 'internalGroqTypeReferenceTo'\n\nconst RESERVED_IDENTIFIERS = new Set([\n 'AllSanitySchemaTypes',\n ARRAY_OF,\n INTERNAL_REFERENCE_SYMBOL,\n 'SanityQueries',\n])\n\n/** `filename` relative to `root`, with forward slashes on every platform. */\nexport function normalizePrintablePath(root: string, filename: string): string {\n return path.relative(root, path.resolve(root, filename)).replaceAll('\\\\', '/')\n}\n\n/** Whether a string is a valid ECMAScript IdentifierName. */\nexport function isIdentifierName(input: string): boolean {\n return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(input)\n}\n\n/** A PascalCase identifier for `name` that is not in `taken`, suffixed `_2`, `_3`… as needed. */\nexport function getUniqueIdentifierForName(name: string, taken: Set<string>): t.Identifier {\n const sanitized = name\n .replace(/^\\d/, '_')\n .replaceAll(/[^$\\w]+(.)/g, (_, char: string) => char.toUpperCase())\n const desired = `${sanitized.charAt(0).toUpperCase()}${sanitized.slice(1)}`\n let resulting = desired\n for (let index = 2; taken.has(resulting) || RESERVED_IDENTIFIERS.has(resulting); index++) {\n resulting = `${desired}_${index}`\n }\n return t.identifier(resulting)\n}\n\nexport function generateCode(node: t.Node): string {\n return `${new CodeGenerator(node).generate().code.trim()}\\n\\n`\n}\n\nexport function getMessage(error: unknown): string {\n return typeof error === 'object' &&\n !!error &&\n 'message' in error &&\n typeof error.message === 'string'\n ? error.message\n : 'Unknown error'\n}\n","import {type ExprNode, parse} from 'groq-js'\n\n/**\n * Parses a GROQ query for type evaluation. groq-js only accepts constant slice bounds, so a\n * `$param` used as one is bound to `0` first: the value does not matter for its type. Not for\n * queries that are executed.\n *\n * groq-js 2.0 only ends a `//` comment at a newline, so a file whose last line is a comment\n * would not parse; such a query is parsed again with one appended. Any other error is the\n * query's own, at its own position.\n */\nexport function safeParseQuery(query: string): ExprNode {\n const params: Record<string, unknown> = {}\n for (const param of extractSliceParams(query)) {\n params[param] = 0\n }\n try {\n return parse(query, {params})\n } catch (error) {\n try {\n return parse(`${query}\\n`, {params})\n } catch {\n throw error\n }\n }\n}\n\n/** The names of the `$params` used as slice bounds, as in `[$start...$end]` or `[10..$end]`. */\nexport function* extractSliceParams(query: string): Generator<string> {\n const sliceRegex = /\\[\\s*(\\$(\\w+)|\\d+)\\s*\\.\\.\\.?\\s*(\\$(\\w+)|\\d+)\\s*\\]/g\n for (const match of query.matchAll(sliceRegex)) {\n if (match[1] === `$${match[2]}`) yield match[2]!\n if (match[3] === `$${match[4]}`) yield match[4]!\n }\n}\n","import {type SchemaType, typeEvaluate, type TypeNode} from 'groq-js'\n\nimport {\n type ExprNode,\n type InRangeNode,\n type ObjectNode,\n type OpCall,\n type OpCallNode,\n type ParameterNode,\n} from './groqAst.js'\nimport {extractSliceParams} from './safeParseQuery.js'\n\n/** The attribute a probe projection writes the counterpart's type to. */\nconst PROBE = '__sanityGroqParam'\nconst UNKNOWN: TypeNode = {type: 'unknown'}\nconst PARAMETER = /\\$([A-Za-z_]\\w*)/g\n\n/**\n * Where an expression is evaluated. `wrap` turns an expression meant for this scope into a\n * root-level query whose result holds the expression's type `depth` probe objects deep: each\n * scope-creating ancestor keeps its base and swaps its body for a projection of the probe, so\n * groq-js resolves the scope exactly as it does for the query itself.\n */\ninterface Scope {\n depth: number\n wrap: (expr: ExprNode) => ExprNode\n}\n\nconst ROOT: Scope = {depth: 0, wrap: (expr) => expr}\n\n/** A placeholder on one side of an operator, with the expression on the other side. */\ninterface Comparison {\n counterpart: ExprNode\n name: string\n op: 'range' | OpCall\n paramOnLeft: boolean\n scope: Scope\n}\n\ninterface Collected {\n comparisons: Comparison[]\n names: Set<string>\n}\n\n/**\n * The type of every `$param` in a query, in order of first appearance.\n *\n * A placeholder compared with a field takes the field's type: `slug.current == $slug` is\n * `string`, `role == $role` keeps a string enum, `tags == $tags` is `Array<string>`,\n * `$tag in tags` is `string`, `_id in $ids` is `Array<string>`, and `title match $term` is\n * `string`. Slice bounds are `number`. Field types come from groq-js's own type evaluation, so\n * dereferences, `_type` narrowing in a filter, nested scopes and inline types resolve as they do\n * for the result type. A placeholder compared with a literal widens to the literal's primitive.\n * One that is only passed to a function or projected is `unknown`, and still required.\n *\n * @param ast - The query as `safeParseQuery` parsed it, so slice bounds are already constants\n */\nexport function inferParams({\n ast,\n query,\n schema,\n}: {\n ast: ExprNode\n query: string\n schema: SchemaType\n}): Map<string, TypeNode> {\n const found: Collected = {comparisons: [], names: new Set()}\n walk(ast, ROOT, found)\n\n // Slice bounds are substituted before parsing, so the AST no longer names them.\n const code = withoutLiterals(query)\n const types = new Map<string, TypeNode[]>()\n for (const name of extractSliceParams(code)) types.set(name, [{type: 'number'}])\n for (const name of found.names) types.set(name, types.get(name) ?? [])\n for (const comparison of found.comparisons) {\n const type = resolve(comparison, schema)\n if (type) types.get(comparison.name)?.push(type)\n }\n\n const params = new Map<string, TypeNode>()\n const inOrder = [...code.matchAll(PARAMETER)].map((match) => match[1]!)\n for (const name of [...inOrder, ...types.keys()]) {\n const candidates = types.get(name)\n if (candidates && !params.has(name)) params.set(name, combine(candidates))\n }\n return params\n}\n\nfunction walk(node: ExprNode, scope: Scope, found: Collected): void {\n switch (node.type) {\n case 'Filter': {\n walk(node.base, scope, found)\n // The probe projects the filtered set, so `_type` checks in the filter narrow it.\n walk(\n node.expr,\n nested(scope, (probe) => mapElements(node, probe)),\n found,\n )\n return\n }\n case 'FlatMap':\n case 'Map': {\n walk(node.base, scope, found)\n // `base[]{...}` parses as a map of `@{...}`, the scope `^` resolves from.\n const projects = node.expr.type === 'Projection' && node.expr.base.type === 'This'\n walk(\n node.expr,\n nested(scope, (probe) => ({...node, expr: projects ? ownScope(probe) : probe})),\n found,\n )\n return\n }\n case 'InRange': {\n noteRange(node, scope, found)\n break\n }\n case 'OpCall': {\n noteComparison(node, scope, found)\n break\n }\n case 'Parameter': {\n found.names.add(node.name)\n return\n }\n case 'PipeFuncCall': {\n // `order()` and `score()` evaluate their arguments once per element of the base.\n walk(node.base, scope, found)\n const inner = nested(scope, (probe) => mapElements(node.base, probe))\n for (const arg of node.args) walk(arg, inner, found)\n return\n }\n case 'Projection': {\n walk(node.base, scope, found)\n // `base{...}` over a set parses as a map of `@{...}`, which keeps the element as `@`.\n const inner =\n node.base.type === 'This' ? scope : nested(scope, (probe) => ({...node, expr: probe}))\n walk(node.expr, inner, found)\n return\n }\n case 'AccessAttribute':\n case 'AccessElement':\n case 'And':\n case 'Array':\n case 'ArrayCoerce':\n case 'Asc':\n case 'Context':\n case 'Deref':\n case 'Desc':\n case 'Everything':\n case 'FuncCall':\n case 'Group':\n case 'Neg':\n case 'Not':\n case 'Object':\n case 'Or':\n case 'Parent':\n case 'Pos':\n case 'Select':\n case 'SelectorFuncCall':\n case 'SelectorNested':\n case 'Slice':\n case 'This':\n case 'Tuple':\n case 'Value': {\n break\n }\n default: {\n node satisfies never\n }\n }\n for (const child of children(node)) walk(child, scope, found)\n}\n\nfunction nested(scope: Scope, build: (probe: ObjectNode) => ExprNode): Scope {\n return {\n depth: scope.depth + 1,\n wrap: (expr) =>\n scope.wrap(\n build({\n attributes: [{name: PROBE, type: 'ObjectAttributeValue', value: expr}],\n type: 'Object',\n }),\n ),\n }\n}\n\n/** The probe evaluated once per element of `base`, whether the elements are objects or not. */\nfunction mapElements(base: ExprNode, probe: ObjectNode): ExprNode {\n return {base, expr: ownScope(probe), type: 'Map'}\n}\n\n/**\n * groq-js hides a map's scope from `^`, so a probe that uses `^` projects `@` to get a scope of\n * its own, as a filter or `@{...}` has. That types only object elements, so other probes do not.\n */\nfunction ownScope(probe: ObjectNode): ExprNode {\n if (!some(probe, (node) => node.type === 'Parent')) return probe\n return {base: {type: 'This'}, expr: probe, type: 'Projection'}\n}\n\nfunction noteComparison(node: OpCallNode, scope: Scope, found: Collected): void {\n const left = asParameter(node.left)\n const right = asParameter(node.right)\n // Two placeholders say nothing about each other, and two fields involve no placeholder.\n if (Boolean(left) === Boolean(right)) return\n found.comparisons.push({\n counterpart: left ? node.right : node.left,\n name: (left ?? right)!.name,\n op: node.op,\n paramOnLeft: Boolean(left),\n scope,\n })\n}\n\nfunction noteRange(node: InRangeNode, scope: Scope, found: Collected): void {\n for (const bound of [node.left, node.right]) {\n const param = asParameter(bound)\n if (!param) continue\n found.comparisons.push({\n counterpart: node.base,\n name: param.name,\n op: 'range',\n paramOnLeft: true,\n scope,\n })\n }\n}\n\nfunction asParameter(node: ExprNode): ParameterNode | undefined {\n if (node.type === 'Group') return asParameter(node.base)\n return node.type === 'Parameter' ? node : undefined\n}\n\nfunction resolve(\n {counterpart, op, paramOnLeft, scope}: Comparison,\n schema: SchemaType,\n): TypeNode | undefined {\n if (op === 'match') return {type: 'string'}\n const expr = unwrapGroups(counterpart)\n const probed = probe(scope, expr, schema)\n if (!probed) return undefined\n // A comparison with a literal, as in `$role == \"admin\"`, is about a value of that primitive.\n const type = expr.type === 'Value' ? widen(probed) : withoutNull(probed)\n // An attribute the schema does not have evaluates to null, which says nothing about the value.\n if (type.type === 'null' && expr.type !== 'Value') return undefined\n if (op !== 'in') return type\n return paramOnLeft ? withoutNull(elementOf(type)) : {of: type, type: 'array'}\n}\n\n/** Evaluates `expr` in `scope`, or `undefined` when the probe cannot be typed. */\nfunction probe(scope: Scope, expr: ExprNode, schema: SchemaType): TypeNode | undefined {\n let evaluated: TypeNode\n try {\n evaluated = typeEvaluate(scope.wrap(expr), schema)\n } catch {\n return undefined\n }\n const types = dig(evaluated, scope.depth)\n return types.length > 0 ? union(types) : undefined\n}\n\n/** Reads the probe attribute `depth` levels down, through the arrays and unions on the way. */\nfunction dig(type: TypeNode, depth: number): TypeNode[] {\n if (depth === 0) return [type]\n switch (type.type) {\n case 'array': {\n return dig(type.of, depth)\n }\n case 'boolean':\n case 'inline':\n case 'null':\n case 'number':\n case 'string': {\n return []\n }\n case 'object': {\n const attribute = type.attributes[PROBE]\n return attribute ? dig(attribute.value, depth - 1) : []\n }\n case 'union': {\n return type.of.flatMap((member) => dig(member, depth))\n }\n case 'unknown': {\n return [type]\n }\n default: {\n const exhaustive: never = type\n throw new Error(`Unexpected type node ${JSON.stringify(exhaustive)}`)\n }\n }\n}\n\n/** One type per parameter: the union of what its comparisons say, or `unknown` if nothing does. */\nfunction combine(types: TypeNode[]): TypeNode {\n const known = types.flatMap((type) => members(type)).filter((type) => type.type !== 'unknown')\n return known.length > 0 ? union(known) : UNKNOWN\n}\n\nfunction members(type: TypeNode): TypeNode[] {\n return type.type === 'union' ? type.of.flatMap((member) => members(member)) : [type]\n}\n\nfunction union(types: TypeNode[]): TypeNode {\n const unique = new Map<string, TypeNode>()\n for (const type of types.flatMap((member) => members(member))) {\n unique.set(JSON.stringify(type), type)\n }\n const of = [...unique.values()]\n return of.length === 1 ? of[0]! : {of, type: 'union'}\n}\n\nfunction withoutNull(type: TypeNode): TypeNode {\n const of = members(type).filter((member) => member.type !== 'null')\n return of.length > 0 ? union(of) : type\n}\n\nfunction elementOf(type: TypeNode): TypeNode {\n return union(members(type).map((member) => (member.type === 'array' ? member.of : member)))\n}\n\nfunction widen(type: TypeNode): TypeNode {\n return union(\n members(type).map((member) =>\n member.type === 'string' || member.type === 'number' || member.type === 'boolean'\n ? {type: member.type}\n : member,\n ),\n )\n}\n\nfunction unwrapGroups(node: ExprNode): ExprNode {\n return node.type === 'Group' ? unwrapGroups(node.base) : node\n}\n\nfunction some(node: ExprNode, predicate: (node: ExprNode) => boolean): boolean {\n return predicate(node) || children(node).some((child) => some(child, predicate))\n}\n\nfunction children(node: ExprNode): ExprNode[] {\n switch (node.type) {\n case 'AccessAttribute': {\n return node.base ? [node.base] : []\n }\n case 'AccessElement':\n case 'ArrayCoerce':\n case 'Asc':\n case 'Deref':\n case 'Desc':\n case 'Group':\n case 'Neg':\n case 'Not':\n case 'Pos':\n case 'Slice': {\n return [node.base]\n }\n case 'And':\n case 'OpCall':\n case 'Or': {\n return [node.left, node.right]\n }\n case 'Array': {\n return node.elements.map((element) => element.value)\n }\n case 'Context':\n case 'Everything':\n case 'Parameter':\n case 'Parent':\n case 'This':\n case 'Value': {\n return []\n }\n case 'Filter':\n case 'FlatMap':\n case 'Map':\n case 'Projection': {\n return [node.base, node.expr]\n }\n case 'FuncCall': {\n return node.args\n }\n case 'InRange': {\n return [node.base, node.left, node.right]\n }\n case 'Object': {\n return node.attributes.flatMap((attribute) =>\n attribute.type === 'ObjectConditionalSplat'\n ? [attribute.condition, attribute.value]\n : [attribute.value],\n )\n }\n case 'PipeFuncCall': {\n return [node.base, ...node.args]\n }\n case 'Select': {\n return [\n ...node.alternatives.flatMap((alternative) => [alternative.condition, alternative.value]),\n ...(node.fallback ? [node.fallback] : []),\n ]\n }\n case 'SelectorFuncCall': {\n return [node.arg]\n }\n case 'SelectorNested': {\n return [node.base, node.nested]\n }\n case 'Tuple': {\n return node.members\n }\n default: {\n const exhaustive: never = node\n throw new Error(`Unexpected GROQ node ${JSON.stringify(exhaustive)}`)\n }\n }\n}\n\n/**\n * The query with the contents of string literals and comments blanked out, at the same\n * positions, so a `$name` or a slice inside them is neither read nor hides a real one.\n */\nfunction withoutLiterals(query: string): string {\n let code = ''\n let quote: string | undefined\n for (let index = 0; index < query.length; index++) {\n const char = query[index]!\n if (quote) {\n if (char === '\\\\') {\n code += ' '\n index++\n } else if (char === quote) {\n quote = undefined\n code += char\n } else {\n code += ' '\n }\n } else if (char === '\"' || char === \"'\") {\n quote = char\n code += char\n } else if (char === '/' && query[index + 1] === '/') {\n const end = query.indexOf('\\n', index)\n const length = (end === -1 ? query.length : end) - index\n code += ' '.repeat(length)\n index += length - 1\n } else {\n code += char\n }\n }\n return code\n}\n","import {SchemaTypeGenerator} from '@sanity/codegen'\nimport {type SchemaType} from 'groq-js'\n\nexport type SchemaTypes = SchemaTypeGenerator\n\nconst cache = new WeakMap<SchemaType, SchemaTypes>()\n\n/** The schema's types, computed once per schema object. */\nexport function schemaTypesFor(schema: SchemaType): SchemaTypes {\n let schemaTypes = cache.get(schema)\n if (!schemaTypes) cache.set(schema, (schemaTypes = new SchemaTypeGenerator(schema)))\n return schemaTypes\n}\n","import * as t from '@babel/types'\nimport {GroqSyntaxError, type SchemaType, typeEvaluate} from 'groq-js'\n\nimport {type ExprNode} from './groqAst.js'\nimport {\n ARRAY_OF,\n generateCode,\n getMessage,\n getUniqueIdentifierForName,\n INTERNAL_REFERENCE_SYMBOL,\n isIdentifierName,\n normalizePrintablePath,\n} from './helpers.js'\nimport {inferParams} from './inferParams.js'\nimport {safeParseQuery} from './safeParseQuery.js'\nimport {type SchemaTypes, schemaTypesFor} from './schemaTypes.js'\n\n/** The type exports of every typed `.groq` module. */\nconst QUERY_RESPONSE = 'QueryResponse'\nconst QUERY_PARAMS = 'QueryParams'\n\n/** The phantom properties the default export carries its types in. `@sanity/client` reads them. */\nconst GROQ_RESULT_BRAND = '__groqResult'\nconst GROQ_PARAMS_BRAND = '__groqParams'\n\n/** Names a module declares itself, which a schema type alias cannot take. */\nconst MODULE_NAMES = new Set(['query', QUERY_PARAMS, QUERY_RESPONSE])\n\n/**\n * Why a `.groq` file could not be typed, or not entirely. Reported by the content mapper with\n * `groq` as the diagnostic source, so an editor shows `groq2` for a syntax error.\n * @beta\n */\nexport const GroqFileDiagnosticCode = {\n /** The file holds no query. */\n EmptyFile: 1,\n /** groq-js could not evaluate the query against the schema. */\n EvaluationFailed: 4,\n /** No schema to type the query against. */\n SchemaUnavailable: 3,\n /** The query does not parse. `start` points at the error. */\n SyntaxError: 2,\n} as const\n\n/** @beta */\nexport type GroqFileDiagnosticCode =\n (typeof GroqFileDiagnosticCode)[keyof typeof GroqFileDiagnosticCode]\n\n/**\n * A problem with a `.groq` file. Positions are UTF-16 offsets into the file's content.\n * @beta\n */\nexport interface GroqFileDiagnostic {\n code: GroqFileDiagnosticCode\n length: number\n messageText: string\n start: number\n}\n\n/**\n * A `.groq` file typed as a TypeScript module. The default export is the query string, typed as\n * its own literal with the result and params types attached as optional phantom properties, and\n * `QueryResponse` and `QueryParams` are exported as types. Nothing is declared globally.\n * @beta\n */\nexport interface GroqModule {\n ast: t.Program\n code: string\n /**\n * Problems with the file. The module is still complete: an untyped query exports `unknown`\n * as its response and accepts any params, so the import keeps resolving.\n */\n diagnostics: GroqFileDiagnostic[]\n /** The query the default export evaluates to: the file's exact content, as a text import delivers it. */\n query: string\n}\n\nexport interface RenderGroqModuleOptions {\n /** The `.groq` file, for the `// Source:` comment. */\n filename: string\n /** Notes written as comments at the top of the module. */\n notes: string[]\n query: string\n\n /** The params object type. Absent when the query could not be parsed. */\n params?: t.TSType\n /** The result type, with the schema types it refers to. Absent when the query could not be typed. */\n result?: {schemaTypes: SchemaTypes; tsType: t.TSType}\n root?: string\n /** The schema file, for the `// Schema:` comment. */\n schemaPath?: string\n}\n\n/**\n * Options for typing one `.groq` file.\n * @beta\n */\nexport interface GenerateGroqModuleOptions {\n /** The file's content, which is also the query: a text import delivers the file as it is. */\n content: string\n /** The `.groq` file, named in a comment at the top of the module. */\n filename: string\n schema: SchemaType\n\n /** The directory file names in comments are relative to. Defaults to the working directory. */\n root?: string\n /** The schema file, named in a comment at the top of the module. */\n schemaPath?: string\n}\n\n/**\n * Types one `.groq` file as a TypeScript module, so a text import of the file,\n * `import query from './file.groq' with {type: 'text'}`, gives a query string that carries\n * its own types:\n *\n * ```ts\n * export type QueryResponse = Array<{title: string | null}>\n * export type QueryParams = {slug: string}\n * declare const query: '*[_type == \"post\" && slug.current == $slug]{title}\\n' & {\n * readonly __groqResult?: QueryResponse\n * readonly __groqParams?: QueryParams\n * }\n * export default query\n * ```\n *\n * The literal is the file's exact content, whitespace and all, because that is what a text\n * import evaluates to at run time; GROQ does not mind the whitespace. The result type is\n * evaluated as `@sanity/codegen` evaluates a `defineQuery` call, so `[0]` becomes `T | null`.\n * Params are inferred from the `$` placeholders: a placeholder compared with a field takes the\n * field's type, slice bounds are numbers, and anything else is `unknown`.\n *\n * A file that cannot be typed still yields a complete module, with `unknown` for what could\n * not be inferred, plus a diagnostic saying why. The schema's type aliases are computed once\n * per schema object.\n * @beta\n */\nexport function generateGroqModule(options: GenerateGroqModuleOptions): GroqModule {\n const {content, filename, root, schema, schemaPath} = options\n const query = content\n const diagnostics: GroqFileDiagnostic[] = []\n const notes: string[] = []\n const report = (\n code: GroqFileDiagnosticCode,\n messageText: string,\n start: number,\n length: number,\n ) => {\n const from = Math.min(start, content.length)\n diagnostics.push({\n code,\n length: Math.min(length, content.length - from),\n messageText,\n start: from,\n })\n }\n const render = (parts: Pick<RenderGroqModuleOptions, 'params' | 'result'>): GroqModule => ({\n ...renderGroqModule({filename, notes, query, root, schemaPath, ...parts}),\n diagnostics,\n query,\n })\n\n if (query.trim().length === 0) {\n report(GroqFileDiagnosticCode.EmptyFile, 'This .groq file has no query.', 0, content.length)\n return render({})\n }\n\n let ast: ReturnType<typeof safeParseQuery>\n try {\n ast = safeParseQuery(query)\n } catch (error) {\n const position = error instanceof GroqSyntaxError ? error.position : 0\n report(GroqFileDiagnosticCode.SyntaxError, getMessage(error), position, 1)\n return render({})\n }\n\n try {\n const schemaTypes = schemaTypesFor(schema)\n const params = new Map<string, t.TSType>()\n for (const [name, type] of inferParams({ast: ast as ExprNode, query, schema})) {\n params.set(name, schemaTypes.generateTsType(type))\n }\n const tsType = schemaTypes.generateTsType(typeEvaluate(ast, schema))\n return render({params: paramsType(params), result: {schemaTypes, tsType}})\n } catch (error) {\n const message = `Could not type this query against the schema: ${getMessage(error)}`\n report(GroqFileDiagnosticCode.EvaluationFailed, message, 0, query.length)\n notes.push(message)\n return render({})\n }\n}\n\n/**\n * The TypeScript module for a `.groq` file.\n *\n * The module is self-contained. Only the schema type aliases the result and params refer to are\n * declared, as module-local types, so a projection carries no schema at all and two files with\n * the same query text are interchangeable.\n */\nexport function renderGroqModule(\n options: RenderGroqModuleOptions,\n): Pick<GroqModule, 'ast' | 'code'> {\n const {filename, notes, query, result, root = process.cwd(), schemaPath} = options\n let response = result?.tsType ?? t.tsUnknownKeyword()\n let params = options.params ?? recordOf(t.tsUnknownKeyword())\n const referenced = new Set<string>()\n collectReferences(response, referenced)\n collectReferences(params, referenced)\n\n const body: t.Statement[] = []\n if (result) {\n let aliases: {id: t.Identifier; tsType: t.TSType}[] = referencedSchemaTypes(\n result.schemaTypes,\n referenced,\n )\n // A schema type named like one of the exports is renamed within this module.\n const renames = renamesFor(aliases.map(({id}) => id.name))\n if (renames.size > 0) {\n response = renamed(response, renames)\n params = renamed(params, renames)\n aliases = aliases.map(({id, tsType}) => ({\n id: t.identifier(renames.get(id.name) ?? id.name),\n tsType: renamed(tsType, renames),\n }))\n }\n if (referenced.has(INTERNAL_REFERENCE_SYMBOL)) body.push(internalReferenceSymbol())\n if (referenced.has(ARRAY_OF)) body.push(arrayOf())\n for (const {id, tsType} of aliases) body.push(t.tsTypeAliasDeclaration(id, null, tsType))\n }\n\n body.push(\n documented(\n t.exportNamedDeclaration(\n t.tsTypeAliasDeclaration(t.identifier(QUERY_RESPONSE), null, response),\n ),\n ' The result of this query, as `client.fetch` resolves it. ',\n ),\n documented(\n t.exportNamedDeclaration(t.tsTypeAliasDeclaration(t.identifier(QUERY_PARAMS), null, params)),\n ' The values for the `$` placeholders in this query. ',\n ),\n queryDeclaration(query),\n t.exportDefaultDeclaration(t.identifier('query')),\n )\n\n const comments = [\n ` Source: ${normalizePrintablePath(root, filename)}`,\n ...(schemaPath ? [` Schema: ${normalizePrintablePath(root, schemaPath)}`] : []),\n ...notes.flatMap((note) => note.split('\\n').map((line) => ` ${line}`)),\n ]\n t.addComments(\n body[0]!,\n 'leading',\n comments.map((value) => ({type: 'CommentLine', value})),\n )\n\n const ast = t.program(body)\n return {ast, code: body.map((statement) => generateCode(statement)).join('')}\n}\n\n/** `{name: type}` for the inferred params, or `Record<string, never>` for a query without any. */\nfunction paramsType(params: Map<string, t.TSType>): t.TSType {\n if (params.size === 0) return recordOf(t.tsNeverKeyword())\n return t.tsTypeLiteral(\n [...params].map(([name, type]) =>\n t.tsPropertySignature(\n isIdentifierName(name) ? t.identifier(name) : t.stringLiteral(name),\n t.tsTypeAnnotation(type),\n ),\n ),\n )\n}\n\n/**\n * The default export's declaration: the query's literal type intersected with an object of two\n * optional, readonly phantom properties, `__groqResult` and `__groqParams`. The properties never\n * exist at runtime, and because they are optional the value is still assignable to `string` and\n * to its own literal.\n */\nfunction queryDeclaration(query: string): t.VariableDeclaration {\n const brand = t.tsTypeLiteral([\n phantomProperty(GROQ_RESULT_BRAND, QUERY_RESPONSE),\n phantomProperty(GROQ_PARAMS_BRAND, QUERY_PARAMS),\n ])\n const id = t.identifier('query')\n id.typeAnnotation = t.tsTypeAnnotation(\n t.tsIntersectionType([t.tsLiteralType(t.stringLiteral(query)), brand]),\n )\n const declaration = t.variableDeclaration('const', [t.variableDeclarator(id)])\n declaration.declare = true\n return declaration\n}\n\nfunction phantomProperty(name: string, type: string): t.TSPropertySignature {\n const property = t.tsPropertySignature(\n t.identifier(name),\n t.tsTypeAnnotation(t.tsTypeReference(t.identifier(type))),\n )\n property.optional = true\n property.readonly = true\n return property\n}\n\nfunction recordOf(value: t.TSType): t.TSType {\n return t.tsTypeReference(\n t.identifier('Record'),\n t.tsTypeParameterInstantiation([t.tsStringKeyword(), value]),\n )\n}\n\nfunction documented<T extends t.Node>(node: T, comment: string): T {\n return t.addComment(node, 'leading', `*${comment}`, false)\n}\n\n/** `declare const internalGroqTypeReferenceTo: unique symbol`, as `sanity.types.ts` declares it. */\nfunction internalReferenceSymbol(): t.Statement {\n const id = t.identifier(INTERNAL_REFERENCE_SYMBOL)\n id.typeAnnotation = t.tsTypeAnnotation(t.tsTypeOperator(t.tsSymbolKeyword(), 'unique'))\n const declaration = t.variableDeclaration('const', [t.variableDeclarator(id)])\n declaration.declare = true\n return declaration\n}\n\n/** `type ArrayOf<T> = Array<T & {_key: string}>`, as `sanity.types.ts` declares it. */\nfunction arrayOf(): t.Statement {\n return t.tsTypeAliasDeclaration(\n t.identifier(ARRAY_OF),\n t.tsTypeParameterDeclaration([t.tsTypeParameter(null, null, 'T')]),\n t.tsTypeReference(\n t.identifier('Array'),\n t.tsTypeParameterInstantiation([\n t.tsIntersectionType([\n t.tsTypeReference(t.identifier('T')),\n t.tsTypeLiteral([\n t.tsPropertySignature(t.identifier('_key'), t.tsTypeAnnotation(t.tsStringKeyword())),\n ]),\n ]),\n ]),\n ),\n )\n}\n\n/**\n * The schema aliases `referenced` names, and the ones they name in turn, in schema order. Every\n * name found on the way is added to `referenced`.\n */\nfunction referencedSchemaTypes(schemaTypes: SchemaTypes, referenced: Set<string>) {\n const byName = new Map([...schemaTypes].map((schemaType) => [schemaType.id.name, schemaType]))\n const included = new Set<string>()\n const queue = [...referenced]\n for (let name = queue.shift(); name !== undefined; name = queue.shift()) {\n const schemaType = byName.get(name)\n if (!schemaType || included.has(name)) continue\n included.add(name)\n const inner = new Set<string>()\n collectReferences(schemaType.tsType, inner)\n for (const innerName of inner) {\n referenced.add(innerName)\n queue.push(innerName)\n }\n }\n return [...byName.values()].filter(({id}) => included.has(id.name))\n}\n\n/** New names for the aliases that collide with the module's own exports. */\nfunction renamesFor(aliasNames: string[]): Map<string, string> {\n const renames = new Map<string, string>()\n const taken = new Set([...MODULE_NAMES, ...aliasNames])\n for (const name of aliasNames) {\n if (!MODULE_NAMES.has(name)) continue\n const id = getUniqueIdentifierForName(name, taken)\n taken.add(id.name)\n renames.set(name, id.name)\n }\n return renames\n}\n\n/** A copy of `node` with the identifiers in `renames` renamed. The original is shared and kept. */\nfunction renamed<T extends t.TSType>(node: T, renames: Map<string, string>): T {\n const copy = t.cloneNode(node, true)\n visitIdentifiers(copy, (identifier) => {\n identifier.name = renames.get(identifier.name) ?? identifier.name\n })\n return copy\n}\n\n/**\n * Adds the identifiers a type mentions: the names of the types it refers to, and the computed\n * keys of its properties, which name a symbol. Plain property names are not references.\n */\nfunction collectReferences(node: t.Node, into: Set<string>): void {\n visitIdentifiers(node, (identifier) => into.add(identifier.name))\n}\n\nfunction visitIdentifiers(node: t.Node, visit: (identifier: t.Identifier) => void): void {\n if (t.isIdentifier(node)) {\n visit(node)\n return\n }\n for (const key of t.VISITOR_KEYS[node.type] ?? []) {\n if (key === 'key' && t.isTSPropertySignature(node) && !node.computed) continue\n const child = (node as unknown as Record<string, t.Node | t.Node[] | null>)[key]\n for (const item of Array.isArray(child) ? child : [child]) {\n if (item) visitIdentifiers(item, visit)\n }\n }\n}\n","import {type Readable, type Writable} from 'node:stream'\n\ntype JsonRpcId = number | string | null\n\n/** @beta */\nexport interface JsonRpcRequest {\n jsonrpc: '2.0'\n method: string\n\n id?: JsonRpcId\n params?: unknown\n}\n\n/** @beta */\nexport const JsonRpcErrorCode = {\n InternalError: -32_603,\n InvalidParams: -32_602,\n InvalidRequest: -32_600,\n MethodNotFound: -32_601,\n ParseError: -32_700,\n} as const\n\n/**\n * An error a request handler throws to answer with a specific JSON-RPC error code. Any other\n * error is answered as an internal error with its message.\n * @beta\n */\nexport class JsonRpcError extends Error {\n readonly code: number\n\n constructor(code: number, message: string) {\n super(message)\n this.name = 'JsonRpcError'\n this.code = code\n }\n}\n\n/** @beta */\nexport interface ServeJsonRpcOptions {\n /** Answers a request, or throws. The result is sent back as the response. */\n handle: (request: JsonRpcRequest) => Promise<unknown>\n input: Readable\n output: Writable\n}\n\n/**\n * Serves JSON-RPC 2.0 over a pair of streams, framed with `Content-Length` headers the way the\n * LSP base protocol and TypeScript's content mapper host do. Requests are answered one at a\n * time, in order. Resolves once `input` ends and the last answer is written, and rejects if\n * `input` errors.\n * @beta\n */\nexport async function serveJsonRpc({handle, input, output}: ServeJsonRpcOptions): Promise<void> {\n let buffer = Buffer.alloc(0)\n for await (const chunk of input) {\n buffer = Buffer.concat([buffer, typeof chunk === 'string' ? Buffer.from(chunk) : chunk])\n for (let frame = readFrame(buffer); frame; frame = readFrame(buffer)) {\n buffer = buffer.subarray(frame.consumed)\n // oxlint-disable-next-line no-await-in-loop -- requests are answered one at a time, in order\n await respond(frame.body, handle, output)\n }\n }\n}\n\n/** The next complete frame in `buffer`, or `undefined` while it is still arriving. */\nfunction readFrame(buffer: Buffer): {body: Buffer | undefined; consumed: number} | undefined {\n const headerEnd = buffer.indexOf('\\r\\n\\r\\n')\n if (headerEnd === -1) return undefined\n const length = Number(/content-length:\\s*(\\d+)/i.exec(buffer.toString('utf8', 0, headerEnd))?.[1])\n // Without a length the body cannot be found. Only the header is dropped, and it is answered\n // as an invalid request so the host learns something was lost.\n if (!Number.isSafeInteger(length)) return {body: undefined, consumed: headerEnd + 4}\n const bodyStart = headerEnd + 4\n if (buffer.length < bodyStart + length) return undefined\n return {body: buffer.subarray(bodyStart, bodyStart + length), consumed: bodyStart + length}\n}\n\nasync function respond(\n body: Buffer | undefined,\n handle: ServeJsonRpcOptions['handle'],\n output: Writable,\n): Promise<void> {\n if (body === undefined) {\n writeError(output, null, JsonRpcErrorCode.InvalidRequest, 'Invalid Request')\n return\n }\n let message: unknown\n try {\n message = JSON.parse(body.toString('utf8'))\n } catch {\n writeError(output, null, JsonRpcErrorCode.ParseError, 'Parse error')\n return\n }\n if (!isRequest(message)) {\n writeError(output, idOf(message), JsonRpcErrorCode.InvalidRequest, 'Invalid Request')\n return\n }\n try {\n const result = await handle(message)\n // A request without an id is a notification, which is not answered.\n if (message.id !== undefined) write(output, {id: message.id, jsonrpc: '2.0', result})\n } catch (error) {\n if (message.id === undefined) return\n const code = error instanceof JsonRpcError ? error.code : JsonRpcErrorCode.InternalError\n const text = error instanceof Error ? error.message : 'Internal error'\n writeError(output, message.id, code, text)\n }\n}\n\nfunction isRequest(value: unknown): value is JsonRpcRequest {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) return false\n const record = value as {id?: unknown; jsonrpc?: unknown; method?: unknown}\n return (\n record.jsonrpc === '2.0' &&\n typeof record.method === 'string' &&\n (!('id' in record) || isId(record.id))\n )\n}\n\nfunction idOf(value: unknown): JsonRpcId {\n if (typeof value !== 'object' || value === null || !('id' in value)) return null\n return isId(value.id) ? value.id : null\n}\n\nfunction isId(value: unknown): value is JsonRpcId {\n return value === null || typeof value === 'string' || typeof value === 'number'\n}\n\nfunction writeError(output: Writable, id: JsonRpcId, code: number, message: string): void {\n write(output, {error: {code, message}, id, jsonrpc: '2.0'})\n}\n\nfunction write(output: Writable, message: unknown): void {\n const body = Buffer.from(JSON.stringify(message), 'utf8')\n output.write(Buffer.concat([Buffer.from(`Content-Length: ${body.length}\\r\\n\\r\\n`), body]))\n}\n","import {readFile} from 'node:fs/promises'\nimport {isAbsolute, resolve, sep} from 'node:path'\n\nimport {type SchemaType} from 'groq-js'\nimport * as v from 'valibot'\n\nimport {getMessage} from './helpers.js'\n\n/**\n * One schema and the folders whose `.groq` files it types.\n * @beta\n */\nexport interface GroqFilesSchema {\n /**\n * One or more folders, relative to the tsconfig. A `.groq` file under one of them is typed\n * against `schema`. The longest matching folder wins, so a nested folder can have a schema\n * of its own.\n */\n include: string | string[]\n /** The file `sanity schema extract` writes, relative to the tsconfig. */\n schema: string\n}\n\n/**\n * The `options` of the mapper's `contentMappers` entry in `tsconfig.json`, which is the only\n * place the mapper is configured. One of the two is required.\n * @beta\n */\nexport interface GroqFilesOptions {\n /** The schema for every `.groq` file no `schemas` entry claims. */\n schema?: string\n /**\n * One schema per folder, for a codebase that queries more than one project or dataset.\n * TypeScript registers a content mapper by file extension alone, so the folders are\n * scoped here rather than in separate `contentMappers` entries.\n */\n schemas?: GroqFilesSchema[]\n}\n\nconst pathString = v.pipe(v.string(), v.nonEmpty('Must not be empty'))\n\nconst schemaEntry: v.GenericSchema<unknown, GroqFilesSchema> = v.strictObject({\n include: v.union([pathString, v.pipe(v.array(pathString), v.minLength(1, 'List a folder'))]),\n schema: pathString,\n})\n\n/** Something wrong with a `GroqFilesOptions` object, at `path` within it. */\nexport interface GroqFilesOptionIssue {\n message: string\n path: (number | string)[]\n}\n\n/**\n * Validates the options object of a `contentMappers` entry. What is well-formed is kept, so one\n * bad entry does not stop the others from typing their files, and each problem is reported\n * with its path into the object.\n */\nexport function parseGroqFilesOptions(input: unknown): {\n issues: GroqFilesOptionIssue[]\n options: GroqFilesOptions\n} {\n const issues: GroqFilesOptionIssue[] = []\n const options: GroqFilesOptions = {}\n if (input !== undefined && !isRecord(input)) {\n issues.push({message: 'The options must be an object.', path: []})\n return {issues, options}\n }\n const record: Record<string, unknown> & {schema?: unknown; schemas?: unknown} = input ?? {}\n\n for (const key of Object.keys(record)) {\n if (key !== 'schema' && key !== 'schemas') {\n issues.push({\n message: `Unknown option \"${key}\". The options are \"schema\" and \"schemas\".`,\n path: [key],\n })\n }\n }\n if (record.schema !== undefined) {\n if (typeof record.schema === 'string' && record.schema.length > 0)\n options.schema = record.schema\n else issues.push({message: '\"schema\" must be the path of a schema file.', path: ['schema']})\n }\n if (record.schemas !== undefined) {\n if (Array.isArray(record.schemas)) {\n options.schemas = []\n for (const [index, item] of record.schemas.entries()) {\n const parsed = v.safeParse(schemaEntry, item)\n if (parsed.success) {\n options.schemas.push(parsed.output)\n continue\n }\n for (const issue of parsed.issues) {\n issues.push({\n message: issue.message,\n path: [\n 'schemas',\n index,\n ...(issue.path ?? []).map((item) => item.key as number | string),\n ],\n })\n }\n }\n } else {\n issues.push({\n message: '\"schemas\" must be a list of {include, schema} entries.',\n path: ['schemas'],\n })\n }\n }\n if (options.schema === undefined && !options.schemas?.length) {\n issues.push({\n message:\n 'Set \"schema\" to the file \"sanity schema extract\" writes, or \"schemas\" to one such file per folder.',\n path: [],\n })\n }\n return {issues, options}\n}\n\n/** A schema located for `.groq` files, read if it could be. */\nexport interface GroqFileSchema {\n /** The schema file's bytes, for the project's configuration identity. */\n bytes?: Buffer\n /** Why `schema` is absent. */\n error?: string\n schema?: SchemaType\n /** The schema file, absolute. */\n schemaPath?: string\n}\n\ninterface ScopedSchema extends GroqFileSchema {\n /** Absolute, normalized folders, without a trailing separator. */\n folders: string[]\n}\n\n/** `GroqFilesOptions` with every path resolved and every schema read. */\nexport interface ResolvedGroqFiles {\n scopes: ScopedSchema[]\n /** Absolute paths whose content decides the result: every schema file. */\n watchedFiles: string[]\n\n /** The schema for files no `schemas` entry claims, when `schema` is set. */\n fallback?: GroqFileSchema\n\n /** The directory relative paths were resolved against, when there was one. */\n root?: string\n}\n\n/**\n * Resolves `options` against `root`, the tsconfig's directory, and reads every schema it names.\n * A schema that cannot be read is kept with its `error`, which the mapper reports on every\n * `.groq` file that needed it, so the imports keep resolving while the schema is fixed.\n *\n * Without a `root`, as for a TypeScript project that has no tsconfig, only absolute paths can\n * be resolved; a relative one is an error on the schema it was meant to locate.\n */\nexport async function resolveGroqFiles({\n options,\n root,\n}: {\n options: GroqFilesOptions\n root?: string\n}): Promise<ResolvedGroqFiles> {\n const locate = (path: string): string | undefined =>\n root === undefined ? (isAbsolute(path) ? path : undefined) : resolve(root, path)\n const load = async (path: string): Promise<GroqFileSchema> => {\n const located = locate(path)\n if (located === undefined) {\n return {\n error: `Without a tsconfig.json to resolve it against, \"${path}\" must be an absolute path.`,\n }\n }\n return loadSchema(located)\n }\n\n const fallback = options.schema === undefined ? undefined : await load(options.schema)\n const scopes = await Promise.all(\n (options.schemas ?? []).map(async (entry): Promise<ScopedSchema> => {\n const folders = (Array.isArray(entry.include) ? entry.include : [entry.include]).flatMap(\n (folder) => {\n const located = locate(folder)\n return located === undefined ? [] : [normalizePath(located)]\n },\n )\n return Object.assign(await load(entry.schema), {folders})\n }),\n )\n\n const watchedFiles = [fallback, ...scopes].flatMap((located) =>\n located?.schemaPath === undefined ? [] : [located.schemaPath],\n )\n return {fallback, root, scopes, watchedFiles: [...new Set(watchedFiles)]}\n}\n\n/**\n * The schema for a `.groq` file: that of the `schemas` entry whose longest folder contains it,\n * else `schema`, else an error saying neither covers the file.\n */\nexport function schemaFor(resolved: ResolvedGroqFiles, file: string): GroqFileSchema {\n const path = normalizePath(file)\n let best: GroqFileSchema | undefined\n let depth = -1\n for (const scope of resolved.scopes) {\n for (const folder of scope.folders) {\n if (folder.length > depth && path.startsWith(`${folder}${sep}`)) {\n best = scope\n depth = folder.length\n }\n }\n }\n if (best) return best\n if (resolved.fallback) return resolved.fallback\n return {\n error:\n resolved.scopes.length > 0\n ? 'This file is outside every \"schemas\" folder, and no \"schema\" is set for the rest.'\n : 'No schema is configured. Set the content mapper option \"schema\" to the file \"sanity schema extract\" writes.',\n }\n}\n\nasync function loadSchema(schemaPath: string): Promise<GroqFileSchema> {\n let bytes: Buffer\n try {\n bytes = await readFile(schemaPath)\n } catch (error) {\n const missing =\n typeof error === 'object' && error !== null && 'code' in error && error.code === 'ENOENT'\n const reason = missing\n ? `No schema file at ${schemaPath}. Run \"sanity schema extract\" to create it.`\n : `Could not read the schema at ${schemaPath}: ${getMessage(error)}`\n return {error: reason, schemaPath}\n }\n let schema: unknown\n try {\n schema = JSON.parse(bytes.toString('utf8'))\n } catch (error) {\n return {\n bytes,\n error: `Could not parse the schema at ${schemaPath}: ${getMessage(error)}`,\n schemaPath,\n }\n }\n if (!Array.isArray(schema)) {\n return {\n bytes,\n error: `${schemaPath} is not the array \"sanity schema extract\" writes.`,\n schemaPath,\n }\n }\n return {bytes, schema: schema as SchemaType, schemaPath}\n}\n\n/** Resolved, without a trailing separator, and case-folded where the file system is. */\nfunction normalizePath(path: string): string {\n const resolved = resolve(path)\n return process.platform === 'win32' || process.platform === 'darwin'\n ? resolved.toLowerCase()\n : resolved\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n","import {createHash} from 'node:crypto'\nimport {dirname} from 'node:path'\nimport {type Readable, type Writable} from 'node:stream'\n\nimport * as v from 'valibot'\n\nimport {\n generateGroqModule,\n type GroqFileDiagnostic,\n GroqFileDiagnosticCode,\n renderGroqModule,\n} from './groqModule.js'\nimport {JsonRpcError, JsonRpcErrorCode, type JsonRpcRequest, serveJsonRpc} from './jsonRpc.js'\nimport {\n parseGroqFilesOptions,\n type ResolvedGroqFiles,\n resolveGroqFiles,\n schemaFor,\n} from './schemas.js'\n\n/**\n * The source TypeScript shows for the mapper's diagnostics, as in `error groq2`.\n * @beta\n */\nexport const DIAGNOSTIC_SOURCE = 'groq'\n\n/** The code of every option diagnostic: the message says what is wrong. */\nconst INVALID_OPTION = 1\n\n/** The protocol version this mapper speaks. The 7.1 beta does not send one; later hosts do. */\nconst PROTOCOL_VERSION = 1\n\n/**\n * The content mapper protocol of TypeScript 7.1, as far as this mapper uses it.\n * https://github.com/microsoft/typescript-go/pull/4712\n */\ninterface InitializeResult {\n diagnosticSource: string\n positionEncoding: 'utf-16'\n protocolVersion: number\n}\n\ninterface OpenProjectResult {\n configIdentity: string\n watchedFiles: string[]\n\n optionDiagnostics?: OptionDiagnostic[]\n}\n\ninterface OptionDiagnostic {\n code: number\n messageText: string\n /** Property names and array indexes into the mapper entry's `options` object. */\n path: (number | string)[]\n}\n\ninterface TransformResult {\n /** `.mts`: the module is an ES module whatever the nearest package.json says, as every loader evaluates it. */\n extension: '.mts'\n text: string\n\n diagnostics?: GroqFileDiagnostic[]\n}\n\ninterface Project {\n resolved: ResolvedGroqFiles\n}\n\nconst initializeParams = v.looseObject({\n positionEncodings: v.array(v.string()),\n protocolVersion: v.optional(v.number()),\n})\n\nconst openProjectParams = v.looseObject({\n configFileName: v.string(),\n options: v.optional(v.unknown()),\n projectHandle: v.string(),\n})\n\nconst transformParams = v.looseObject({\n content: v.string(),\n fileName: v.string(),\n projectHandle: v.string(),\n})\n\nconst closeProjectParams = v.looseObject({projectHandle: v.string()})\n\n/**\n * A TypeScript 7.1 content mapper that types `.groq` files from their live content, so\n * `import query from './posts.groq'` is typed with nothing generated to disk. TypeScript\n * starts it from the `typescript.contentMapper` field of this package's `package.json` when a\n * `tsconfig.json` registers it:\n *\n * ```jsonc\n * {\n * \"contentMappers\": [\n * {\"package\": \"@sanity-labs/groq-content-mapper\", \"extensions\": [\".groq\"], \"options\": {\"schema\": \"./schema.json\"}}\n * ]\n * }\n * ```\n *\n * The tsconfig is the only place the mapper is configured. `options` is a `GroqFilesOptions`\n * object: `schema`, the file `sanity schema extract` writes, or `schemas`, one such file per\n * folder for a codebase that queries more than one project or dataset. The mapper declares\n * `dynamicConfig`, so every schema is watched and the project is reopened when one changes.\n *\n * One instance serves any number of projects, each under the handle TypeScript assigns it.\n * @beta\n */\nexport class ContentMapper {\n private projects = new Map<string, Project>()\n\n private static initialize({\n positionEncodings,\n protocolVersion,\n }: v.InferOutput<typeof initializeParams>): InitializeResult {\n if (protocolVersion !== undefined && protocolVersion !== PROTOCOL_VERSION) {\n throw new JsonRpcError(\n JsonRpcErrorCode.InvalidParams,\n `This content mapper speaks protocol version ${PROTOCOL_VERSION}, not ${protocolVersion}.`,\n )\n }\n // Positions are JavaScript string offsets, which are UTF-16 code units.\n if (!positionEncodings.includes('utf-16')) {\n throw new JsonRpcError(\n JsonRpcErrorCode.InvalidParams,\n 'This content mapper reports positions in utf-16, which the host does not accept.',\n )\n }\n return {\n diagnosticSource: DIAGNOSTIC_SOURCE,\n positionEncoding: 'utf-16',\n protocolVersion: PROTOCOL_VERSION,\n }\n }\n\n /**\n * Answers one request of the protocol: `initialize`, `openProject`, `transform` or\n * `closeProject`. Throws a `JsonRpcError` for a request the mapper cannot answer.\n */\n async handle(method: string, params: unknown): Promise<unknown> {\n switch (method) {\n case 'closeProject': {\n this.projects.delete(parse(closeProjectParams, params, method).projectHandle)\n return {}\n }\n case 'initialize': {\n return ContentMapper.initialize(parse(initializeParams, params, method))\n }\n case 'openProject': {\n return this.openProject(parse(openProjectParams, params, method))\n }\n case 'transform': {\n return this.transform(parse(transformParams, params, method))\n }\n default: {\n throw new JsonRpcError(JsonRpcErrorCode.MethodNotFound, `Unknown method \"${method}\".`)\n }\n }\n }\n\n /** Serves the protocol over the streams until `input` ends. */\n serve({input, output}: {input: Readable; output: Writable}): Promise<void> {\n return serveJsonRpc({\n handle: (request: JsonRpcRequest) => this.handle(request.method, request.params),\n input,\n output,\n })\n }\n\n private async openProject({\n configFileName,\n options,\n projectHandle,\n }: v.InferOutput<typeof openProjectParams>): Promise<OpenProjectResult> {\n // The protocol sends \"\" for a project without a tsconfig. The host starts this process in\n // the package directory, so without one only absolute paths in the options are usable.\n const root = configFileName === '' ? undefined : dirname(configFileName)\n const parsed = parseGroqFilesOptions(options)\n const optionDiagnostics = parsed.issues.map(({message, path}): OptionDiagnostic => ({\n code: INVALID_OPTION,\n messageText: message,\n path,\n }))\n\n const resolved = await resolveGroqFiles({options: parsed.options, root})\n this.projects.set(projectHandle, {resolved})\n\n // Every schema's path and content: a change to either reopens the project.\n const identity = createHash('sha256')\n for (const located of [resolved.fallback, ...resolved.scopes]) {\n identity.update(`${located?.schemaPath ?? ''}\\0`)\n identity.update(located?.bytes ?? 'missing')\n identity.update('\\0')\n }\n return {\n configIdentity: identity.digest('hex'),\n ...(optionDiagnostics.length > 0 ? {optionDiagnostics} : {}),\n watchedFiles: resolved.watchedFiles,\n }\n }\n\n private transform({\n content,\n fileName,\n projectHandle,\n }: v.InferOutput<typeof transformParams>): TransformResult {\n const project = this.projects.get(projectHandle)\n if (!project) {\n throw new JsonRpcError(JsonRpcErrorCode.InvalidParams, `Unknown project \"${projectHandle}\".`)\n }\n\n const {resolved} = project\n const root = resolved.root ?? dirname(fileName)\n const located = schemaFor(resolved, fileName)\n if (!located.schema) {\n const messageText = located.error ?? 'No schema is configured.'\n const {code} = renderGroqModule({\n filename: fileName,\n notes: [messageText],\n query: content,\n root,\n schemaPath: located.schemaPath,\n })\n return {\n diagnostics: [\n {\n code: GroqFileDiagnosticCode.SchemaUnavailable,\n length: Math.min(1, content.length),\n messageText,\n start: 0,\n },\n ],\n extension: '.mts',\n text: code,\n }\n }\n\n const {code, diagnostics} = generateGroqModule({\n content,\n filename: fileName,\n root,\n schema: located.schema,\n schemaPath: located.schemaPath,\n })\n return {\n ...(diagnostics.length > 0 ? {diagnostics} : {}),\n extension: '.mts',\n text: code,\n }\n }\n}\n\nfunction parse<TSchema extends v.GenericSchema>(\n schema: TSchema,\n params: unknown,\n method: string,\n): v.InferOutput<TSchema> {\n const result = v.safeParse(schema, params)\n if (result.success) return result.output\n const issues = result.issues.map(\n (issue) => `${v.getDotPath(issue) ?? 'params'}: ${issue.message}`,\n )\n throw new JsonRpcError(\n JsonRpcErrorCode.InvalidParams,\n `Invalid params for ${method}: ${issues.join('; ')}`,\n )\n}\n"],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { t as ContentMapper, n as DIAGNOSTIC_SOURCE, o as GroqFileDiagnosticCode, r as JsonRpcError, i as JsonRpcErrorCode, s as generateGroqModule, a as serveJsonRpc } from "./contentMapper-
|
|
1
|
+
export { t as ContentMapper, n as DIAGNOSTIC_SOURCE, o as GroqFileDiagnosticCode, r as JsonRpcError, i as JsonRpcErrorCode, s as generateGroqModule, a as serveJsonRpc } from "./contentMapper-BRyFa5Y0.js";
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"contentMapper-DuDm_e25.js","names":["resolve","exhaustive","parse"],"sources":["../src/helpers.ts","../src/safeParseQuery.ts","../src/inferParams.ts","../src/schemaTypes.ts","../src/groqModule.ts","../src/jsonRpc.ts","../src/schemas.ts","../src/contentMapper.ts"],"sourcesContent":["import path from 'node:path'\n\nimport {CodeGenerator} from '@babel/generator'\nimport * as t from '@babel/types'\n\n/**\n * Names `@sanity/codegen` gives the helpers a schema type can refer to. A module that refers to\n * one declares it locally, as `sanity.types.ts` does.\n */\nexport const ARRAY_OF = 'ArrayOf'\nexport const INTERNAL_REFERENCE_SYMBOL = 'internalGroqTypeReferenceTo'\n\nconst RESERVED_IDENTIFIERS = new Set([\n 'AllSanitySchemaTypes',\n ARRAY_OF,\n INTERNAL_REFERENCE_SYMBOL,\n 'SanityQueries',\n])\n\n/** `filename` relative to `root`, with forward slashes on every platform. */\nexport function normalizePrintablePath(root: string, filename: string): string {\n return path.relative(root, path.resolve(root, filename)).replaceAll('\\\\', '/')\n}\n\n/** Whether a string is a valid ECMAScript IdentifierName. */\nexport function isIdentifierName(input: string): boolean {\n return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(input)\n}\n\n/** A PascalCase identifier for `name` that is not in `taken`, suffixed `_2`, `_3`… as needed. */\nexport function getUniqueIdentifierForName(name: string, taken: Set<string>): t.Identifier {\n const sanitized = name\n .replace(/^\\d/, '_')\n .replaceAll(/[^$\\w]+(.)/g, (_, char: string) => char.toUpperCase())\n const desired = `${sanitized.charAt(0).toUpperCase()}${sanitized.slice(1)}`\n let resulting = desired\n for (let index = 2; taken.has(resulting) || RESERVED_IDENTIFIERS.has(resulting); index++) {\n resulting = `${desired}_${index}`\n }\n return t.identifier(resulting)\n}\n\nexport function generateCode(node: t.Node): string {\n return `${new CodeGenerator(node).generate().code.trim()}\\n\\n`\n}\n\nexport function getMessage(error: unknown): string {\n return typeof error === 'object' &&\n !!error &&\n 'message' in error &&\n typeof error.message === 'string'\n ? error.message\n : 'Unknown error'\n}\n","import {type ExprNode, parse} from 'groq-js'\n\n/**\n * Parses a GROQ query for type evaluation. groq-js only accepts constant slice bounds, so a\n * `$param` used as one is bound to `0` first: the value does not matter for its type. Not for\n * queries that are executed.\n */\nexport function safeParseQuery(query: string): ExprNode {\n const params: Record<string, unknown> = {}\n for (const param of extractSliceParams(query)) {\n params[param] = 0\n }\n return parse(query, {params})\n}\n\n/** The names of the `$params` used as slice bounds, as in `[$start...$end]` or `[10..$end]`. */\nexport function* extractSliceParams(query: string): Generator<string> {\n const sliceRegex = /\\[\\s*(\\$(\\w+)|\\d+)\\s*\\.\\.\\.?\\s*(\\$(\\w+)|\\d+)\\s*\\]/g\n for (const match of query.matchAll(sliceRegex)) {\n if (match[1] === `$${match[2]}`) yield match[2]!\n if (match[3] === `$${match[4]}`) yield match[4]!\n }\n}\n","import {type SchemaType, typeEvaluate, type TypeNode} from 'groq-js'\n\nimport {\n type ExprNode,\n type InRangeNode,\n type ObjectNode,\n type OpCall,\n type OpCallNode,\n type ParameterNode,\n} from './groqAst.js'\nimport {extractSliceParams} from './safeParseQuery.js'\n\n/** The attribute a probe projection writes the counterpart's type to. */\nconst PROBE = '__sanityGroqParam'\nconst UNKNOWN: TypeNode = {type: 'unknown'}\nconst PARAMETER = /\\$([A-Za-z_]\\w*)/g\n\n/**\n * Where an expression is evaluated. `wrap` turns an expression meant for this scope into a\n * root-level query whose result holds the expression's type `depth` probe objects deep: each\n * scope-creating ancestor keeps its base and swaps its body for a projection of the probe, so\n * groq-js resolves the scope exactly as it does for the query itself.\n */\ninterface Scope {\n depth: number\n wrap: (expr: ExprNode) => ExprNode\n}\n\nconst ROOT: Scope = {depth: 0, wrap: (expr) => expr}\n\n/** A placeholder on one side of an operator, with the expression on the other side. */\ninterface Comparison {\n counterpart: ExprNode\n name: string\n op: 'range' | OpCall\n paramOnLeft: boolean\n scope: Scope\n}\n\ninterface Collected {\n comparisons: Comparison[]\n names: Set<string>\n}\n\n/**\n * The type of every `$param` in a query, in order of first appearance.\n *\n * A placeholder compared with a field takes the field's type: `slug.current == $slug` is\n * `string`, `role == $role` keeps a string enum, `tags == $tags` is `Array<string>`,\n * `$tag in tags` is `string`, `_id in $ids` is `Array<string>`, and `title match $term` is\n * `string`. Slice bounds are `number`. Field types come from groq-js's own type evaluation, so\n * dereferences, `_type` narrowing in a filter, nested scopes and inline types resolve as they do\n * for the result type. A placeholder compared with a literal widens to the literal's primitive.\n * One that is only passed to a function or projected is `unknown`, and still required.\n *\n * @param ast - The query as `safeParseQuery` parsed it, so slice bounds are already constants\n */\nexport function inferParams({\n ast,\n query,\n schema,\n}: {\n ast: ExprNode\n query: string\n schema: SchemaType\n}): Map<string, TypeNode> {\n const found: Collected = {comparisons: [], names: new Set()}\n walk(ast, ROOT, found)\n\n // Slice bounds are substituted before parsing, so the AST no longer names them.\n const code = withoutLiterals(query)\n const types = new Map<string, TypeNode[]>()\n for (const name of extractSliceParams(code)) types.set(name, [{type: 'number'}])\n for (const name of found.names) types.set(name, types.get(name) ?? [])\n for (const comparison of found.comparisons) {\n const type = resolve(comparison, schema)\n if (type) types.get(comparison.name)?.push(type)\n }\n\n const params = new Map<string, TypeNode>()\n const inOrder = [...code.matchAll(PARAMETER)].map((match) => match[1]!)\n for (const name of [...inOrder, ...types.keys()]) {\n const candidates = types.get(name)\n if (candidates && !params.has(name)) params.set(name, combine(candidates))\n }\n return params\n}\n\nfunction walk(node: ExprNode, scope: Scope, found: Collected): void {\n switch (node.type) {\n case 'Filter': {\n walk(node.base, scope, found)\n // The probe projects the filtered set, so `_type` checks in the filter narrow it.\n walk(\n node.expr,\n nested(scope, (probe) => mapElements(node, probe)),\n found,\n )\n return\n }\n case 'FlatMap':\n case 'Map': {\n walk(node.base, scope, found)\n // `base[]{...}` parses as a map of `@{...}`, the scope `^` resolves from.\n const projects = node.expr.type === 'Projection' && node.expr.base.type === 'This'\n walk(\n node.expr,\n nested(scope, (probe) => ({...node, expr: projects ? ownScope(probe) : probe})),\n found,\n )\n return\n }\n case 'InRange': {\n noteRange(node, scope, found)\n break\n }\n case 'OpCall': {\n noteComparison(node, scope, found)\n break\n }\n case 'Parameter': {\n found.names.add(node.name)\n return\n }\n case 'PipeFuncCall': {\n // `order()` and `score()` evaluate their arguments once per element of the base.\n walk(node.base, scope, found)\n const inner = nested(scope, (probe) => mapElements(node.base, probe))\n for (const arg of node.args) walk(arg, inner, found)\n return\n }\n case 'Projection': {\n walk(node.base, scope, found)\n // `base{...}` over a set parses as a map of `@{...}`, which keeps the element as `@`.\n const inner =\n node.base.type === 'This' ? scope : nested(scope, (probe) => ({...node, expr: probe}))\n walk(node.expr, inner, found)\n return\n }\n case 'AccessAttribute':\n case 'AccessElement':\n case 'And':\n case 'Array':\n case 'ArrayCoerce':\n case 'Asc':\n case 'Context':\n case 'Deref':\n case 'Desc':\n case 'Everything':\n case 'FuncCall':\n case 'Group':\n case 'Neg':\n case 'Not':\n case 'Object':\n case 'Or':\n case 'Parent':\n case 'Pos':\n case 'Select':\n case 'SelectorFuncCall':\n case 'SelectorNested':\n case 'Slice':\n case 'This':\n case 'Tuple':\n case 'Value': {\n break\n }\n default: {\n node satisfies never\n }\n }\n for (const child of children(node)) walk(child, scope, found)\n}\n\nfunction nested(scope: Scope, build: (probe: ObjectNode) => ExprNode): Scope {\n return {\n depth: scope.depth + 1,\n wrap: (expr) =>\n scope.wrap(\n build({\n attributes: [{name: PROBE, type: 'ObjectAttributeValue', value: expr}],\n type: 'Object',\n }),\n ),\n }\n}\n\n/** The probe evaluated once per element of `base`, whether the elements are objects or not. */\nfunction mapElements(base: ExprNode, probe: ObjectNode): ExprNode {\n return {base, expr: ownScope(probe), type: 'Map'}\n}\n\n/**\n * groq-js hides a map's scope from `^`, so a probe that uses `^` projects `@` to get a scope of\n * its own, as a filter or `@{...}` has. That types only object elements, so other probes do not.\n */\nfunction ownScope(probe: ObjectNode): ExprNode {\n if (!some(probe, (node) => node.type === 'Parent')) return probe\n return {base: {type: 'This'}, expr: probe, type: 'Projection'}\n}\n\nfunction noteComparison(node: OpCallNode, scope: Scope, found: Collected): void {\n const left = asParameter(node.left)\n const right = asParameter(node.right)\n // Two placeholders say nothing about each other, and two fields involve no placeholder.\n if (Boolean(left) === Boolean(right)) return\n found.comparisons.push({\n counterpart: left ? node.right : node.left,\n name: (left ?? right)!.name,\n op: node.op,\n paramOnLeft: Boolean(left),\n scope,\n })\n}\n\nfunction noteRange(node: InRangeNode, scope: Scope, found: Collected): void {\n for (const bound of [node.left, node.right]) {\n const param = asParameter(bound)\n if (!param) continue\n found.comparisons.push({\n counterpart: node.base,\n name: param.name,\n op: 'range',\n paramOnLeft: true,\n scope,\n })\n }\n}\n\nfunction asParameter(node: ExprNode): ParameterNode | undefined {\n if (node.type === 'Group') return asParameter(node.base)\n return node.type === 'Parameter' ? node : undefined\n}\n\nfunction resolve(\n {counterpart, op, paramOnLeft, scope}: Comparison,\n schema: SchemaType,\n): TypeNode | undefined {\n if (op === 'match') return {type: 'string'}\n const expr = unwrapGroups(counterpart)\n const probed = probe(scope, expr, schema)\n if (!probed) return undefined\n // A comparison with a literal, as in `$role == \"admin\"`, is about a value of that primitive.\n const type = expr.type === 'Value' ? widen(probed) : withoutNull(probed)\n // An attribute the schema does not have evaluates to null, which says nothing about the value.\n if (type.type === 'null' && expr.type !== 'Value') return undefined\n if (op !== 'in') return type\n return paramOnLeft ? withoutNull(elementOf(type)) : {of: type, type: 'array'}\n}\n\n/** Evaluates `expr` in `scope`, or `undefined` when the probe cannot be typed. */\nfunction probe(scope: Scope, expr: ExprNode, schema: SchemaType): TypeNode | undefined {\n let evaluated: TypeNode\n try {\n evaluated = typeEvaluate(scope.wrap(expr), schema)\n } catch {\n return undefined\n }\n const types = dig(evaluated, scope.depth)\n return types.length > 0 ? union(types) : undefined\n}\n\n/** Reads the probe attribute `depth` levels down, through the arrays and unions on the way. */\nfunction dig(type: TypeNode, depth: number): TypeNode[] {\n if (depth === 0) return [type]\n switch (type.type) {\n case 'array': {\n return dig(type.of, depth)\n }\n case 'boolean':\n case 'inline':\n case 'null':\n case 'number':\n case 'string': {\n return []\n }\n case 'object': {\n const attribute = type.attributes[PROBE]\n return attribute ? dig(attribute.value, depth - 1) : []\n }\n case 'union': {\n return type.of.flatMap((member) => dig(member, depth))\n }\n case 'unknown': {\n return [type]\n }\n default: {\n const exhaustive: never = type\n throw new Error(`Unexpected type node ${JSON.stringify(exhaustive)}`)\n }\n }\n}\n\n/** One type per parameter: the union of what its comparisons say, or `unknown` if nothing does. */\nfunction combine(types: TypeNode[]): TypeNode {\n const known = types.flatMap((type) => members(type)).filter((type) => type.type !== 'unknown')\n return known.length > 0 ? union(known) : UNKNOWN\n}\n\nfunction members(type: TypeNode): TypeNode[] {\n return type.type === 'union' ? type.of.flatMap((member) => members(member)) : [type]\n}\n\nfunction union(types: TypeNode[]): TypeNode {\n const unique = new Map<string, TypeNode>()\n for (const type of types.flatMap((member) => members(member))) {\n unique.set(JSON.stringify(type), type)\n }\n const of = [...unique.values()]\n return of.length === 1 ? of[0]! : {of, type: 'union'}\n}\n\nfunction withoutNull(type: TypeNode): TypeNode {\n const of = members(type).filter((member) => member.type !== 'null')\n return of.length > 0 ? union(of) : type\n}\n\nfunction elementOf(type: TypeNode): TypeNode {\n return union(members(type).map((member) => (member.type === 'array' ? member.of : member)))\n}\n\nfunction widen(type: TypeNode): TypeNode {\n return union(\n members(type).map((member) =>\n member.type === 'string' || member.type === 'number' || member.type === 'boolean'\n ? {type: member.type}\n : member,\n ),\n )\n}\n\nfunction unwrapGroups(node: ExprNode): ExprNode {\n return node.type === 'Group' ? unwrapGroups(node.base) : node\n}\n\nfunction some(node: ExprNode, predicate: (node: ExprNode) => boolean): boolean {\n return predicate(node) || children(node).some((child) => some(child, predicate))\n}\n\nfunction children(node: ExprNode): ExprNode[] {\n switch (node.type) {\n case 'AccessAttribute': {\n return node.base ? [node.base] : []\n }\n case 'AccessElement':\n case 'ArrayCoerce':\n case 'Asc':\n case 'Deref':\n case 'Desc':\n case 'Group':\n case 'Neg':\n case 'Not':\n case 'Pos':\n case 'Slice': {\n return [node.base]\n }\n case 'And':\n case 'OpCall':\n case 'Or': {\n return [node.left, node.right]\n }\n case 'Array': {\n return node.elements.map((element) => element.value)\n }\n case 'Context':\n case 'Everything':\n case 'Parameter':\n case 'Parent':\n case 'This':\n case 'Value': {\n return []\n }\n case 'Filter':\n case 'FlatMap':\n case 'Map':\n case 'Projection': {\n return [node.base, node.expr]\n }\n case 'FuncCall': {\n return node.args\n }\n case 'InRange': {\n return [node.base, node.left, node.right]\n }\n case 'Object': {\n return node.attributes.flatMap((attribute) =>\n attribute.type === 'ObjectConditionalSplat'\n ? [attribute.condition, attribute.value]\n : [attribute.value],\n )\n }\n case 'PipeFuncCall': {\n return [node.base, ...node.args]\n }\n case 'Select': {\n return [\n ...node.alternatives.flatMap((alternative) => [alternative.condition, alternative.value]),\n ...(node.fallback ? [node.fallback] : []),\n ]\n }\n case 'SelectorFuncCall': {\n return [node.arg]\n }\n case 'SelectorNested': {\n return [node.base, node.nested]\n }\n case 'Tuple': {\n return node.members\n }\n default: {\n const exhaustive: never = node\n throw new Error(`Unexpected GROQ node ${JSON.stringify(exhaustive)}`)\n }\n }\n}\n\n/**\n * The query with the contents of string literals and comments blanked out, at the same\n * positions, so a `$name` or a slice inside them is neither read nor hides a real one.\n */\nfunction withoutLiterals(query: string): string {\n let code = ''\n let quote: string | undefined\n for (let index = 0; index < query.length; index++) {\n const char = query[index]!\n if (quote) {\n if (char === '\\\\') {\n code += ' '\n index++\n } else if (char === quote) {\n quote = undefined\n code += char\n } else {\n code += ' '\n }\n } else if (char === '\"' || char === \"'\") {\n quote = char\n code += char\n } else if (char === '/' && query[index + 1] === '/') {\n const end = query.indexOf('\\n', index)\n const length = (end === -1 ? query.length : end) - index\n code += ' '.repeat(length)\n index += length - 1\n } else {\n code += char\n }\n }\n return code\n}\n","import {SchemaTypeGenerator} from '@sanity/codegen'\nimport {type SchemaType} from 'groq-js'\n\nexport type SchemaTypes = SchemaTypeGenerator\n\nconst cache = new WeakMap<SchemaType, SchemaTypes>()\n\n/** The schema's types, computed once per schema object. */\nexport function schemaTypesFor(schema: SchemaType): SchemaTypes {\n let schemaTypes = cache.get(schema)\n if (!schemaTypes) cache.set(schema, (schemaTypes = new SchemaTypeGenerator(schema)))\n return schemaTypes\n}\n","import * as t from '@babel/types'\nimport {GroqSyntaxError, type SchemaType, typeEvaluate} from 'groq-js'\n\nimport {type ExprNode} from './groqAst.js'\nimport {\n ARRAY_OF,\n generateCode,\n getMessage,\n getUniqueIdentifierForName,\n INTERNAL_REFERENCE_SYMBOL,\n isIdentifierName,\n normalizePrintablePath,\n} from './helpers.js'\nimport {inferParams} from './inferParams.js'\nimport {safeParseQuery} from './safeParseQuery.js'\nimport {type SchemaTypes, schemaTypesFor} from './schemaTypes.js'\n\n/** The type exports of every typed `.groq` module. */\nconst QUERY_RESPONSE = 'QueryResponse'\nconst QUERY_PARAMS = 'QueryParams'\n\n/** The phantom properties the default export carries its types in. `@sanity/client` reads them. */\nconst GROQ_RESULT_BRAND = '__groqResult'\nconst GROQ_PARAMS_BRAND = '__groqParams'\n\n/** Names a module declares itself, which a schema type alias cannot take. */\nconst MODULE_NAMES = new Set(['query', QUERY_PARAMS, QUERY_RESPONSE])\n\n/**\n * Why a `.groq` file could not be typed, or not entirely. Reported by the content mapper with\n * `groq` as the diagnostic source, so an editor shows `groq2` for a syntax error.\n * @beta\n */\nexport const GroqFileDiagnosticCode = {\n /** The file holds no query. */\n EmptyFile: 1,\n /** groq-js could not evaluate the query against the schema. */\n EvaluationFailed: 4,\n /** No schema to type the query against. */\n SchemaUnavailable: 3,\n /** The query does not parse. `start` points at the error. */\n SyntaxError: 2,\n} as const\n\n/** @beta */\nexport type GroqFileDiagnosticCode =\n (typeof GroqFileDiagnosticCode)[keyof typeof GroqFileDiagnosticCode]\n\n/**\n * A problem with a `.groq` file. Positions are UTF-16 offsets into the file's content.\n * @beta\n */\nexport interface GroqFileDiagnostic {\n code: GroqFileDiagnosticCode\n length: number\n messageText: string\n start: number\n}\n\n/**\n * A `.groq` file typed as a TypeScript module. The default export is the query string, typed as\n * its own literal with the result and params types attached as optional phantom properties, and\n * `QueryResponse` and `QueryParams` are exported as types. Nothing is declared globally.\n * @beta\n */\nexport interface GroqModule {\n ast: t.Program\n code: string\n /**\n * Problems with the file. The module is still complete: an untyped query exports `unknown`\n * as its response and accepts any params, so the import keeps resolving.\n */\n diagnostics: GroqFileDiagnostic[]\n /** The query the default export evaluates to: the file's exact content, as a text import delivers it. */\n query: string\n}\n\nexport interface RenderGroqModuleOptions {\n /** The `.groq` file, for the `// Source:` comment. */\n filename: string\n /** Notes written as comments at the top of the module. */\n notes: string[]\n query: string\n\n /** The params object type. Absent when the query could not be parsed. */\n params?: t.TSType\n /** The result type, with the schema types it refers to. Absent when the query could not be typed. */\n result?: {schemaTypes: SchemaTypes; tsType: t.TSType}\n root?: string\n /** The schema file, for the `// Schema:` comment. */\n schemaPath?: string\n}\n\n/**\n * Options for typing one `.groq` file.\n * @beta\n */\nexport interface GenerateGroqModuleOptions {\n /** The file's content, which is also the query: a text import delivers the file as it is. */\n content: string\n /** The `.groq` file, named in a comment at the top of the module. */\n filename: string\n schema: SchemaType\n\n /** The directory file names in comments are relative to. Defaults to the working directory. */\n root?: string\n /** The schema file, named in a comment at the top of the module. */\n schemaPath?: string\n}\n\n/**\n * Types one `.groq` file as a TypeScript module, so a text import of the file,\n * `import query from './file.groq' with {type: 'text'}`, gives a query string that carries\n * its own types:\n *\n * ```ts\n * export type QueryResponse = Array<{title: string | null}>\n * export type QueryParams = {slug: string}\n * declare const query: '*[_type == \"post\" && slug.current == $slug]{title}\\n' & {\n * readonly __groqResult?: QueryResponse\n * readonly __groqParams?: QueryParams\n * }\n * export default query\n * ```\n *\n * The literal is the file's exact content, whitespace and all, because that is what a text\n * import evaluates to at run time; GROQ does not mind the whitespace. The result type is\n * evaluated as `@sanity/codegen` evaluates a `defineQuery` call, so `[0]` becomes `T | null`.\n * Params are inferred from the `$` placeholders: a placeholder compared with a field takes the\n * field's type, slice bounds are numbers, and anything else is `unknown`.\n *\n * A file that cannot be typed still yields a complete module, with `unknown` for what could\n * not be inferred, plus a diagnostic saying why. The schema's type aliases are computed once\n * per schema object.\n * @beta\n */\nexport function generateGroqModule(options: GenerateGroqModuleOptions): GroqModule {\n const {content, filename, root, schema, schemaPath} = options\n const query = content\n const diagnostics: GroqFileDiagnostic[] = []\n const notes: string[] = []\n const report = (\n code: GroqFileDiagnosticCode,\n messageText: string,\n start: number,\n length: number,\n ) => {\n const from = Math.min(start, content.length)\n diagnostics.push({\n code,\n length: Math.min(length, content.length - from),\n messageText,\n start: from,\n })\n }\n const render = (parts: Pick<RenderGroqModuleOptions, 'params' | 'result'>): GroqModule => ({\n ...renderGroqModule({filename, notes, query, root, schemaPath, ...parts}),\n diagnostics,\n query,\n })\n\n if (query.trim().length === 0) {\n report(GroqFileDiagnosticCode.EmptyFile, 'This .groq file has no query.', 0, content.length)\n return render({})\n }\n\n let ast: ReturnType<typeof safeParseQuery>\n try {\n ast = safeParseQuery(query)\n } catch (error) {\n const position = error instanceof GroqSyntaxError ? error.position : 0\n report(GroqFileDiagnosticCode.SyntaxError, getMessage(error), position, 1)\n return render({})\n }\n\n try {\n const schemaTypes = schemaTypesFor(schema)\n const params = new Map<string, t.TSType>()\n for (const [name, type] of inferParams({ast: ast as ExprNode, query, schema})) {\n params.set(name, schemaTypes.generateTsType(type))\n }\n const tsType = schemaTypes.generateTsType(typeEvaluate(ast, schema))\n return render({params: paramsType(params), result: {schemaTypes, tsType}})\n } catch (error) {\n const message = `Could not type this query against the schema: ${getMessage(error)}`\n report(GroqFileDiagnosticCode.EvaluationFailed, message, 0, query.length)\n notes.push(message)\n return render({})\n }\n}\n\n/**\n * The TypeScript module for a `.groq` file.\n *\n * The module is self-contained. Only the schema type aliases the result and params refer to are\n * declared, as module-local types, so a projection carries no schema at all and two files with\n * the same query text are interchangeable.\n */\nexport function renderGroqModule(\n options: RenderGroqModuleOptions,\n): Pick<GroqModule, 'ast' | 'code'> {\n const {filename, notes, query, result, root = process.cwd(), schemaPath} = options\n let response = result?.tsType ?? t.tsUnknownKeyword()\n let params = options.params ?? recordOf(t.tsUnknownKeyword())\n const referenced = new Set<string>()\n collectReferences(response, referenced)\n collectReferences(params, referenced)\n\n const body: t.Statement[] = []\n if (result) {\n let aliases: {id: t.Identifier; tsType: t.TSType}[] = referencedSchemaTypes(\n result.schemaTypes,\n referenced,\n )\n // A schema type named like one of the exports is renamed within this module.\n const renames = renamesFor(aliases.map(({id}) => id.name))\n if (renames.size > 0) {\n response = renamed(response, renames)\n params = renamed(params, renames)\n aliases = aliases.map(({id, tsType}) => ({\n id: t.identifier(renames.get(id.name) ?? id.name),\n tsType: renamed(tsType, renames),\n }))\n }\n if (referenced.has(INTERNAL_REFERENCE_SYMBOL)) body.push(internalReferenceSymbol())\n if (referenced.has(ARRAY_OF)) body.push(arrayOf())\n for (const {id, tsType} of aliases) body.push(t.tsTypeAliasDeclaration(id, null, tsType))\n }\n\n body.push(\n documented(\n t.exportNamedDeclaration(\n t.tsTypeAliasDeclaration(t.identifier(QUERY_RESPONSE), null, response),\n ),\n ' The result of this query, as `client.fetch` resolves it. ',\n ),\n documented(\n t.exportNamedDeclaration(t.tsTypeAliasDeclaration(t.identifier(QUERY_PARAMS), null, params)),\n ' The values for the `$` placeholders in this query. ',\n ),\n queryDeclaration(query),\n t.exportDefaultDeclaration(t.identifier('query')),\n )\n\n const comments = [\n ` Source: ${normalizePrintablePath(root, filename)}`,\n ...(schemaPath ? [` Schema: ${normalizePrintablePath(root, schemaPath)}`] : []),\n ...notes.flatMap((note) => note.split('\\n').map((line) => ` ${line}`)),\n ]\n t.addComments(\n body[0]!,\n 'leading',\n comments.map((value) => ({type: 'CommentLine', value})),\n )\n\n const ast = t.program(body)\n return {ast, code: body.map((statement) => generateCode(statement)).join('')}\n}\n\n/** `{name: type}` for the inferred params, or `Record<string, never>` for a query without any. */\nfunction paramsType(params: Map<string, t.TSType>): t.TSType {\n if (params.size === 0) return recordOf(t.tsNeverKeyword())\n return t.tsTypeLiteral(\n [...params].map(([name, type]) =>\n t.tsPropertySignature(\n isIdentifierName(name) ? t.identifier(name) : t.stringLiteral(name),\n t.tsTypeAnnotation(type),\n ),\n ),\n )\n}\n\n/**\n * The default export's declaration: the query's literal type intersected with an object of two\n * optional, readonly phantom properties, `__groqResult` and `__groqParams`. The properties never\n * exist at runtime, and because they are optional the value is still assignable to `string` and\n * to its own literal.\n */\nfunction queryDeclaration(query: string): t.VariableDeclaration {\n const brand = t.tsTypeLiteral([\n phantomProperty(GROQ_RESULT_BRAND, QUERY_RESPONSE),\n phantomProperty(GROQ_PARAMS_BRAND, QUERY_PARAMS),\n ])\n const id = t.identifier('query')\n id.typeAnnotation = t.tsTypeAnnotation(\n t.tsIntersectionType([t.tsLiteralType(t.stringLiteral(query)), brand]),\n )\n const declaration = t.variableDeclaration('const', [t.variableDeclarator(id)])\n declaration.declare = true\n return declaration\n}\n\nfunction phantomProperty(name: string, type: string): t.TSPropertySignature {\n const property = t.tsPropertySignature(\n t.identifier(name),\n t.tsTypeAnnotation(t.tsTypeReference(t.identifier(type))),\n )\n property.optional = true\n property.readonly = true\n return property\n}\n\nfunction recordOf(value: t.TSType): t.TSType {\n return t.tsTypeReference(\n t.identifier('Record'),\n t.tsTypeParameterInstantiation([t.tsStringKeyword(), value]),\n )\n}\n\nfunction documented<T extends t.Node>(node: T, comment: string): T {\n return t.addComment(node, 'leading', `*${comment}`, false)\n}\n\n/** `declare const internalGroqTypeReferenceTo: unique symbol`, as `sanity.types.ts` declares it. */\nfunction internalReferenceSymbol(): t.Statement {\n const id = t.identifier(INTERNAL_REFERENCE_SYMBOL)\n id.typeAnnotation = t.tsTypeAnnotation(t.tsTypeOperator(t.tsSymbolKeyword(), 'unique'))\n const declaration = t.variableDeclaration('const', [t.variableDeclarator(id)])\n declaration.declare = true\n return declaration\n}\n\n/** `type ArrayOf<T> = Array<T & {_key: string}>`, as `sanity.types.ts` declares it. */\nfunction arrayOf(): t.Statement {\n return t.tsTypeAliasDeclaration(\n t.identifier(ARRAY_OF),\n t.tsTypeParameterDeclaration([t.tsTypeParameter(null, null, 'T')]),\n t.tsTypeReference(\n t.identifier('Array'),\n t.tsTypeParameterInstantiation([\n t.tsIntersectionType([\n t.tsTypeReference(t.identifier('T')),\n t.tsTypeLiteral([\n t.tsPropertySignature(t.identifier('_key'), t.tsTypeAnnotation(t.tsStringKeyword())),\n ]),\n ]),\n ]),\n ),\n )\n}\n\n/**\n * The schema aliases `referenced` names, and the ones they name in turn, in schema order. Every\n * name found on the way is added to `referenced`.\n */\nfunction referencedSchemaTypes(schemaTypes: SchemaTypes, referenced: Set<string>) {\n const byName = new Map([...schemaTypes].map((schemaType) => [schemaType.id.name, schemaType]))\n const included = new Set<string>()\n const queue = [...referenced]\n for (let name = queue.shift(); name !== undefined; name = queue.shift()) {\n const schemaType = byName.get(name)\n if (!schemaType || included.has(name)) continue\n included.add(name)\n const inner = new Set<string>()\n collectReferences(schemaType.tsType, inner)\n for (const innerName of inner) {\n referenced.add(innerName)\n queue.push(innerName)\n }\n }\n return [...byName.values()].filter(({id}) => included.has(id.name))\n}\n\n/** New names for the aliases that collide with the module's own exports. */\nfunction renamesFor(aliasNames: string[]): Map<string, string> {\n const renames = new Map<string, string>()\n const taken = new Set([...MODULE_NAMES, ...aliasNames])\n for (const name of aliasNames) {\n if (!MODULE_NAMES.has(name)) continue\n const id = getUniqueIdentifierForName(name, taken)\n taken.add(id.name)\n renames.set(name, id.name)\n }\n return renames\n}\n\n/** A copy of `node` with the identifiers in `renames` renamed. The original is shared and kept. */\nfunction renamed<T extends t.TSType>(node: T, renames: Map<string, string>): T {\n const copy = t.cloneNode(node, true)\n visitIdentifiers(copy, (identifier) => {\n identifier.name = renames.get(identifier.name) ?? identifier.name\n })\n return copy\n}\n\n/**\n * Adds the identifiers a type mentions: the names of the types it refers to, and the computed\n * keys of its properties, which name a symbol. Plain property names are not references.\n */\nfunction collectReferences(node: t.Node, into: Set<string>): void {\n visitIdentifiers(node, (identifier) => into.add(identifier.name))\n}\n\nfunction visitIdentifiers(node: t.Node, visit: (identifier: t.Identifier) => void): void {\n if (t.isIdentifier(node)) {\n visit(node)\n return\n }\n for (const key of t.VISITOR_KEYS[node.type] ?? []) {\n if (key === 'key' && t.isTSPropertySignature(node) && !node.computed) continue\n const child = (node as unknown as Record<string, t.Node | t.Node[] | null>)[key]\n for (const item of Array.isArray(child) ? child : [child]) {\n if (item) visitIdentifiers(item, visit)\n }\n }\n}\n","import {type Readable, type Writable} from 'node:stream'\n\ntype JsonRpcId = number | string | null\n\n/** @beta */\nexport interface JsonRpcRequest {\n jsonrpc: '2.0'\n method: string\n\n id?: JsonRpcId\n params?: unknown\n}\n\n/** @beta */\nexport const JsonRpcErrorCode = {\n InternalError: -32_603,\n InvalidParams: -32_602,\n InvalidRequest: -32_600,\n MethodNotFound: -32_601,\n ParseError: -32_700,\n} as const\n\n/**\n * An error a request handler throws to answer with a specific JSON-RPC error code. Any other\n * error is answered as an internal error with its message.\n * @beta\n */\nexport class JsonRpcError extends Error {\n readonly code: number\n\n constructor(code: number, message: string) {\n super(message)\n this.name = 'JsonRpcError'\n this.code = code\n }\n}\n\n/** @beta */\nexport interface ServeJsonRpcOptions {\n /** Answers a request, or throws. The result is sent back as the response. */\n handle: (request: JsonRpcRequest) => Promise<unknown>\n input: Readable\n output: Writable\n}\n\n/**\n * Serves JSON-RPC 2.0 over a pair of streams, framed with `Content-Length` headers the way the\n * LSP base protocol and TypeScript's content mapper host do. Requests are answered one at a\n * time, in order. Resolves once `input` ends and the last answer is written, and rejects if\n * `input` errors.\n * @beta\n */\nexport async function serveJsonRpc({handle, input, output}: ServeJsonRpcOptions): Promise<void> {\n let buffer = Buffer.alloc(0)\n for await (const chunk of input) {\n buffer = Buffer.concat([buffer, typeof chunk === 'string' ? Buffer.from(chunk) : chunk])\n for (let frame = readFrame(buffer); frame; frame = readFrame(buffer)) {\n buffer = buffer.subarray(frame.consumed)\n // oxlint-disable-next-line no-await-in-loop -- requests are answered one at a time, in order\n await respond(frame.body, handle, output)\n }\n }\n}\n\n/** The next complete frame in `buffer`, or `undefined` while it is still arriving. */\nfunction readFrame(buffer: Buffer): {body: Buffer | undefined; consumed: number} | undefined {\n const headerEnd = buffer.indexOf('\\r\\n\\r\\n')\n if (headerEnd === -1) return undefined\n const length = Number(/content-length:\\s*(\\d+)/i.exec(buffer.toString('utf8', 0, headerEnd))?.[1])\n // Without a length the body cannot be found. Only the header is dropped, and it is answered\n // as an invalid request so the host learns something was lost.\n if (!Number.isSafeInteger(length)) return {body: undefined, consumed: headerEnd + 4}\n const bodyStart = headerEnd + 4\n if (buffer.length < bodyStart + length) return undefined\n return {body: buffer.subarray(bodyStart, bodyStart + length), consumed: bodyStart + length}\n}\n\nasync function respond(\n body: Buffer | undefined,\n handle: ServeJsonRpcOptions['handle'],\n output: Writable,\n): Promise<void> {\n if (body === undefined) {\n writeError(output, null, JsonRpcErrorCode.InvalidRequest, 'Invalid Request')\n return\n }\n let message: unknown\n try {\n message = JSON.parse(body.toString('utf8'))\n } catch {\n writeError(output, null, JsonRpcErrorCode.ParseError, 'Parse error')\n return\n }\n if (!isRequest(message)) {\n writeError(output, idOf(message), JsonRpcErrorCode.InvalidRequest, 'Invalid Request')\n return\n }\n try {\n const result = await handle(message)\n // A request without an id is a notification, which is not answered.\n if (message.id !== undefined) write(output, {id: message.id, jsonrpc: '2.0', result})\n } catch (error) {\n if (message.id === undefined) return\n const code = error instanceof JsonRpcError ? error.code : JsonRpcErrorCode.InternalError\n const text = error instanceof Error ? error.message : 'Internal error'\n writeError(output, message.id, code, text)\n }\n}\n\nfunction isRequest(value: unknown): value is JsonRpcRequest {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) return false\n const record = value as {id?: unknown; jsonrpc?: unknown; method?: unknown}\n return (\n record.jsonrpc === '2.0' &&\n typeof record.method === 'string' &&\n (!('id' in record) || isId(record.id))\n )\n}\n\nfunction idOf(value: unknown): JsonRpcId {\n if (typeof value !== 'object' || value === null || !('id' in value)) return null\n return isId(value.id) ? value.id : null\n}\n\nfunction isId(value: unknown): value is JsonRpcId {\n return value === null || typeof value === 'string' || typeof value === 'number'\n}\n\nfunction writeError(output: Writable, id: JsonRpcId, code: number, message: string): void {\n write(output, {error: {code, message}, id, jsonrpc: '2.0'})\n}\n\nfunction write(output: Writable, message: unknown): void {\n const body = Buffer.from(JSON.stringify(message), 'utf8')\n output.write(Buffer.concat([Buffer.from(`Content-Length: ${body.length}\\r\\n\\r\\n`), body]))\n}\n","import {readFile} from 'node:fs/promises'\nimport {isAbsolute, resolve, sep} from 'node:path'\n\nimport {type SchemaType} from 'groq-js'\nimport * as v from 'valibot'\n\nimport {getMessage} from './helpers.js'\n\n/**\n * One schema and the folders whose `.groq` files it types.\n * @beta\n */\nexport interface GroqFilesSchema {\n /**\n * One or more folders, relative to the tsconfig. A `.groq` file under one of them is typed\n * against `schema`. The longest matching folder wins, so a nested folder can have a schema\n * of its own.\n */\n include: string | string[]\n /** The file `sanity schema extract` writes, relative to the tsconfig. */\n schema: string\n}\n\n/**\n * The `options` of the mapper's `contentMappers` entry in `tsconfig.json`, which is the only\n * place the mapper is configured. One of the two is required.\n * @beta\n */\nexport interface GroqFilesOptions {\n /** The schema for every `.groq` file no `schemas` entry claims. */\n schema?: string\n /**\n * One schema per folder, for a codebase that queries more than one project or dataset.\n * TypeScript registers a content mapper by file extension alone, so the folders are\n * scoped here rather than in separate `contentMappers` entries.\n */\n schemas?: GroqFilesSchema[]\n}\n\nconst pathString = v.pipe(v.string(), v.nonEmpty('Must not be empty'))\n\nconst schemaEntry: v.GenericSchema<unknown, GroqFilesSchema> = v.strictObject({\n include: v.union([pathString, v.pipe(v.array(pathString), v.minLength(1, 'List a folder'))]),\n schema: pathString,\n})\n\n/** Something wrong with a `GroqFilesOptions` object, at `path` within it. */\nexport interface GroqFilesOptionIssue {\n message: string\n path: (number | string)[]\n}\n\n/**\n * Validates the options object of a `contentMappers` entry. What is well-formed is kept, so one\n * bad entry does not stop the others from typing their files, and each problem is reported\n * with its path into the object.\n */\nexport function parseGroqFilesOptions(input: unknown): {\n issues: GroqFilesOptionIssue[]\n options: GroqFilesOptions\n} {\n const issues: GroqFilesOptionIssue[] = []\n const options: GroqFilesOptions = {}\n if (input !== undefined && !isRecord(input)) {\n issues.push({message: 'The options must be an object.', path: []})\n return {issues, options}\n }\n const record: Record<string, unknown> & {schema?: unknown; schemas?: unknown} = input ?? {}\n\n for (const key of Object.keys(record)) {\n if (key !== 'schema' && key !== 'schemas') {\n issues.push({\n message: `Unknown option \"${key}\". The options are \"schema\" and \"schemas\".`,\n path: [key],\n })\n }\n }\n if (record.schema !== undefined) {\n if (typeof record.schema === 'string' && record.schema.length > 0)\n options.schema = record.schema\n else issues.push({message: '\"schema\" must be the path of a schema file.', path: ['schema']})\n }\n if (record.schemas !== undefined) {\n if (Array.isArray(record.schemas)) {\n options.schemas = []\n for (const [index, item] of record.schemas.entries()) {\n const parsed = v.safeParse(schemaEntry, item)\n if (parsed.success) {\n options.schemas.push(parsed.output)\n continue\n }\n for (const issue of parsed.issues) {\n issues.push({\n message: issue.message,\n path: [\n 'schemas',\n index,\n ...(issue.path ?? []).map((item) => item.key as number | string),\n ],\n })\n }\n }\n } else {\n issues.push({\n message: '\"schemas\" must be a list of {include, schema} entries.',\n path: ['schemas'],\n })\n }\n }\n if (options.schema === undefined && !options.schemas?.length) {\n issues.push({\n message:\n 'Set \"schema\" to the file \"sanity schema extract\" writes, or \"schemas\" to one such file per folder.',\n path: [],\n })\n }\n return {issues, options}\n}\n\n/** A schema located for `.groq` files, read if it could be. */\nexport interface GroqFileSchema {\n /** The schema file's bytes, for the project's configuration identity. */\n bytes?: Buffer\n /** Why `schema` is absent. */\n error?: string\n schema?: SchemaType\n /** The schema file, absolute. */\n schemaPath?: string\n}\n\ninterface ScopedSchema extends GroqFileSchema {\n /** Absolute, normalized folders, without a trailing separator. */\n folders: string[]\n}\n\n/** `GroqFilesOptions` with every path resolved and every schema read. */\nexport interface ResolvedGroqFiles {\n scopes: ScopedSchema[]\n /** Absolute paths whose content decides the result: every schema file. */\n watchedFiles: string[]\n\n /** The schema for files no `schemas` entry claims, when `schema` is set. */\n fallback?: GroqFileSchema\n\n /** The directory relative paths were resolved against, when there was one. */\n root?: string\n}\n\n/**\n * Resolves `options` against `root`, the tsconfig's directory, and reads every schema it names.\n * A schema that cannot be read is kept with its `error`, which the mapper reports on every\n * `.groq` file that needed it, so the imports keep resolving while the schema is fixed.\n *\n * Without a `root`, as for a TypeScript project that has no tsconfig, only absolute paths can\n * be resolved; a relative one is an error on the schema it was meant to locate.\n */\nexport async function resolveGroqFiles({\n options,\n root,\n}: {\n options: GroqFilesOptions\n root?: string\n}): Promise<ResolvedGroqFiles> {\n const locate = (path: string): string | undefined =>\n root === undefined ? (isAbsolute(path) ? path : undefined) : resolve(root, path)\n const load = async (path: string): Promise<GroqFileSchema> => {\n const located = locate(path)\n if (located === undefined) {\n return {\n error: `Without a tsconfig.json to resolve it against, \"${path}\" must be an absolute path.`,\n }\n }\n return loadSchema(located)\n }\n\n const fallback = options.schema === undefined ? undefined : await load(options.schema)\n const scopes = await Promise.all(\n (options.schemas ?? []).map(async (entry): Promise<ScopedSchema> => {\n const folders = (Array.isArray(entry.include) ? entry.include : [entry.include]).flatMap(\n (folder) => {\n const located = locate(folder)\n return located === undefined ? [] : [normalizePath(located)]\n },\n )\n return Object.assign(await load(entry.schema), {folders})\n }),\n )\n\n const watchedFiles = [fallback, ...scopes].flatMap((located) =>\n located?.schemaPath === undefined ? [] : [located.schemaPath],\n )\n return {fallback, root, scopes, watchedFiles: [...new Set(watchedFiles)]}\n}\n\n/**\n * The schema for a `.groq` file: that of the `schemas` entry whose longest folder contains it,\n * else `schema`, else an error saying neither covers the file.\n */\nexport function schemaFor(resolved: ResolvedGroqFiles, file: string): GroqFileSchema {\n const path = normalizePath(file)\n let best: GroqFileSchema | undefined\n let depth = -1\n for (const scope of resolved.scopes) {\n for (const folder of scope.folders) {\n if (folder.length > depth && path.startsWith(`${folder}${sep}`)) {\n best = scope\n depth = folder.length\n }\n }\n }\n if (best) return best\n if (resolved.fallback) return resolved.fallback\n return {\n error:\n resolved.scopes.length > 0\n ? 'This file is outside every \"schemas\" folder, and no \"schema\" is set for the rest.'\n : 'No schema is configured. Set the content mapper option \"schema\" to the file \"sanity schema extract\" writes.',\n }\n}\n\nasync function loadSchema(schemaPath: string): Promise<GroqFileSchema> {\n let bytes: Buffer\n try {\n bytes = await readFile(schemaPath)\n } catch (error) {\n const missing =\n typeof error === 'object' && error !== null && 'code' in error && error.code === 'ENOENT'\n const reason = missing\n ? `No schema file at ${schemaPath}. Run \"sanity schema extract\" to create it.`\n : `Could not read the schema at ${schemaPath}: ${getMessage(error)}`\n return {error: reason, schemaPath}\n }\n let schema: unknown\n try {\n schema = JSON.parse(bytes.toString('utf8'))\n } catch (error) {\n return {\n bytes,\n error: `Could not parse the schema at ${schemaPath}: ${getMessage(error)}`,\n schemaPath,\n }\n }\n if (!Array.isArray(schema)) {\n return {\n bytes,\n error: `${schemaPath} is not the array \"sanity schema extract\" writes.`,\n schemaPath,\n }\n }\n return {bytes, schema: schema as SchemaType, schemaPath}\n}\n\n/** Resolved, without a trailing separator, and case-folded where the file system is. */\nfunction normalizePath(path: string): string {\n const resolved = resolve(path)\n return process.platform === 'win32' || process.platform === 'darwin'\n ? resolved.toLowerCase()\n : resolved\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n","import {createHash} from 'node:crypto'\nimport {dirname} from 'node:path'\nimport {type Readable, type Writable} from 'node:stream'\n\nimport * as v from 'valibot'\n\nimport {\n generateGroqModule,\n type GroqFileDiagnostic,\n GroqFileDiagnosticCode,\n renderGroqModule,\n} from './groqModule.js'\nimport {JsonRpcError, JsonRpcErrorCode, type JsonRpcRequest, serveJsonRpc} from './jsonRpc.js'\nimport {\n parseGroqFilesOptions,\n type ResolvedGroqFiles,\n resolveGroqFiles,\n schemaFor,\n} from './schemas.js'\n\n/**\n * The source TypeScript shows for the mapper's diagnostics, as in `error groq2`.\n * @beta\n */\nexport const DIAGNOSTIC_SOURCE = 'groq'\n\n/** The code of every option diagnostic: the message says what is wrong. */\nconst INVALID_OPTION = 1\n\n/** The protocol version this mapper speaks. The 7.1 beta does not send one; later hosts do. */\nconst PROTOCOL_VERSION = 1\n\n/**\n * The content mapper protocol of TypeScript 7.1, as far as this mapper uses it.\n * https://github.com/microsoft/typescript-go/pull/4712\n */\ninterface InitializeResult {\n diagnosticSource: string\n positionEncoding: 'utf-16'\n protocolVersion: number\n}\n\ninterface OpenProjectResult {\n configIdentity: string\n watchedFiles: string[]\n\n optionDiagnostics?: OptionDiagnostic[]\n}\n\ninterface OptionDiagnostic {\n code: number\n messageText: string\n /** Property names and array indexes into the mapper entry's `options` object. */\n path: (number | string)[]\n}\n\ninterface TransformResult {\n /** `.mts`: the module is an ES module whatever the nearest package.json says, as every loader evaluates it. */\n extension: '.mts'\n text: string\n\n diagnostics?: GroqFileDiagnostic[]\n}\n\ninterface Project {\n resolved: ResolvedGroqFiles\n}\n\nconst initializeParams = v.looseObject({\n positionEncodings: v.array(v.string()),\n protocolVersion: v.optional(v.number()),\n})\n\nconst openProjectParams = v.looseObject({\n configFileName: v.string(),\n options: v.optional(v.unknown()),\n projectHandle: v.string(),\n})\n\nconst transformParams = v.looseObject({\n content: v.string(),\n fileName: v.string(),\n projectHandle: v.string(),\n})\n\nconst closeProjectParams = v.looseObject({projectHandle: v.string()})\n\n/**\n * A TypeScript 7.1 content mapper that types `.groq` files from their live content, so\n * `import query from './posts.groq'` is typed with nothing generated to disk. TypeScript\n * starts it from the `typescript.contentMapper` field of this package's `package.json` when a\n * `tsconfig.json` registers it:\n *\n * ```jsonc\n * {\n * \"contentMappers\": [\n * {\"package\": \"@sanity-labs/groq-content-mapper\", \"extensions\": [\".groq\"], \"options\": {\"schema\": \"./schema.json\"}}\n * ]\n * }\n * ```\n *\n * The tsconfig is the only place the mapper is configured. `options` is a `GroqFilesOptions`\n * object: `schema`, the file `sanity schema extract` writes, or `schemas`, one such file per\n * folder for a codebase that queries more than one project or dataset. The mapper declares\n * `dynamicConfig`, so every schema is watched and the project is reopened when one changes.\n *\n * One instance serves any number of projects, each under the handle TypeScript assigns it.\n * @beta\n */\nexport class ContentMapper {\n private projects = new Map<string, Project>()\n\n private static initialize({\n positionEncodings,\n protocolVersion,\n }: v.InferOutput<typeof initializeParams>): InitializeResult {\n if (protocolVersion !== undefined && protocolVersion !== PROTOCOL_VERSION) {\n throw new JsonRpcError(\n JsonRpcErrorCode.InvalidParams,\n `This content mapper speaks protocol version ${PROTOCOL_VERSION}, not ${protocolVersion}.`,\n )\n }\n // Positions are JavaScript string offsets, which are UTF-16 code units.\n if (!positionEncodings.includes('utf-16')) {\n throw new JsonRpcError(\n JsonRpcErrorCode.InvalidParams,\n 'This content mapper reports positions in utf-16, which the host does not accept.',\n )\n }\n return {\n diagnosticSource: DIAGNOSTIC_SOURCE,\n positionEncoding: 'utf-16',\n protocolVersion: PROTOCOL_VERSION,\n }\n }\n\n /**\n * Answers one request of the protocol: `initialize`, `openProject`, `transform` or\n * `closeProject`. Throws a `JsonRpcError` for a request the mapper cannot answer.\n */\n async handle(method: string, params: unknown): Promise<unknown> {\n switch (method) {\n case 'closeProject': {\n this.projects.delete(parse(closeProjectParams, params, method).projectHandle)\n return {}\n }\n case 'initialize': {\n return ContentMapper.initialize(parse(initializeParams, params, method))\n }\n case 'openProject': {\n return this.openProject(parse(openProjectParams, params, method))\n }\n case 'transform': {\n return this.transform(parse(transformParams, params, method))\n }\n default: {\n throw new JsonRpcError(JsonRpcErrorCode.MethodNotFound, `Unknown method \"${method}\".`)\n }\n }\n }\n\n /** Serves the protocol over the streams until `input` ends. */\n serve({input, output}: {input: Readable; output: Writable}): Promise<void> {\n return serveJsonRpc({\n handle: (request: JsonRpcRequest) => this.handle(request.method, request.params),\n input,\n output,\n })\n }\n\n private async openProject({\n configFileName,\n options,\n projectHandle,\n }: v.InferOutput<typeof openProjectParams>): Promise<OpenProjectResult> {\n // The protocol sends \"\" for a project without a tsconfig. The host starts this process in\n // the package directory, so without one only absolute paths in the options are usable.\n const root = configFileName === '' ? undefined : dirname(configFileName)\n const parsed = parseGroqFilesOptions(options)\n const optionDiagnostics = parsed.issues.map(({message, path}): OptionDiagnostic => ({\n code: INVALID_OPTION,\n messageText: message,\n path,\n }))\n\n const resolved = await resolveGroqFiles({options: parsed.options, root})\n this.projects.set(projectHandle, {resolved})\n\n // Every schema's path and content: a change to either reopens the project.\n const identity = createHash('sha256')\n for (const located of [resolved.fallback, ...resolved.scopes]) {\n identity.update(`${located?.schemaPath ?? ''}\\0`)\n identity.update(located?.bytes ?? 'missing')\n identity.update('\\0')\n }\n return {\n configIdentity: identity.digest('hex'),\n ...(optionDiagnostics.length > 0 ? {optionDiagnostics} : {}),\n watchedFiles: resolved.watchedFiles,\n }\n }\n\n private transform({\n content,\n fileName,\n projectHandle,\n }: v.InferOutput<typeof transformParams>): TransformResult {\n const project = this.projects.get(projectHandle)\n if (!project) {\n throw new JsonRpcError(JsonRpcErrorCode.InvalidParams, `Unknown project \"${projectHandle}\".`)\n }\n\n const {resolved} = project\n const root = resolved.root ?? dirname(fileName)\n const located = schemaFor(resolved, fileName)\n if (!located.schema) {\n const messageText = located.error ?? 'No schema is configured.'\n const {code} = renderGroqModule({\n filename: fileName,\n notes: [messageText],\n query: content,\n root,\n schemaPath: located.schemaPath,\n })\n return {\n diagnostics: [\n {\n code: GroqFileDiagnosticCode.SchemaUnavailable,\n length: Math.min(1, content.length),\n messageText,\n start: 0,\n },\n ],\n extension: '.mts',\n text: code,\n }\n }\n\n const {code, diagnostics} = generateGroqModule({\n content,\n filename: fileName,\n root,\n schema: located.schema,\n schemaPath: located.schemaPath,\n })\n return {\n ...(diagnostics.length > 0 ? {diagnostics} : {}),\n extension: '.mts',\n text: code,\n }\n }\n}\n\nfunction parse<TSchema extends v.GenericSchema>(\n schema: TSchema,\n params: unknown,\n method: string,\n): v.InferOutput<TSchema> {\n const result = v.safeParse(schema, params)\n if (result.success) return result.output\n const issues = result.issues.map(\n (issue) => `${v.getDotPath(issue) ?? 'params'}: ${issue.message}`,\n )\n throw new JsonRpcError(\n JsonRpcErrorCode.InvalidParams,\n `Invalid params for ${method}: ${issues.join('; ')}`,\n )\n}\n"],"mappings":"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"}
|