@sanity/codegen 4.19.1-next.8 → 4.20.0-next.40
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/index.js +144 -147
- package/lib/index.js.map +1 -1
- package/package.json +11 -13
- package/lib/index.d.mts +0 -216
- package/lib/index.mjs +0 -771
- package/lib/index.mjs.map +0 -1
package/lib/index.js
CHANGED
|
@@ -1,42 +1,36 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
}
|
|
20
|
-
}), n.default = e, Object.freeze(n);
|
|
21
|
-
}
|
|
22
|
-
var fs__default$1 = /* @__PURE__ */ _interopDefaultCompat(fs), json5__default = /* @__PURE__ */ _interopDefaultCompat(json5), z__namespace = /* @__PURE__ */ _interopNamespaceCompat(z), createDebug__default = /* @__PURE__ */ _interopDefaultCompat(createDebug), glob__default = /* @__PURE__ */ _interopDefaultCompat(glob), fs__default = /* @__PURE__ */ _interopDefaultCompat(fs$1), path__default = /* @__PURE__ */ _interopDefaultCompat(path), t__namespace = /* @__PURE__ */ _interopNamespaceCompat(t), traverse__default = /* @__PURE__ */ _interopDefaultCompat(traverse), register__default = /* @__PURE__ */ _interopDefaultCompat(register);
|
|
23
|
-
const configDefinition = z__namespace.object({
|
|
24
|
-
path: z__namespace.string().or(z__namespace.array(z__namespace.string())).default([
|
|
1
|
+
import fs$1, { readFile } from "node:fs/promises";
|
|
2
|
+
import json5 from "json5";
|
|
3
|
+
import * as z from "zod";
|
|
4
|
+
import { parse } from "groq-js";
|
|
5
|
+
import createDebug from "debug";
|
|
6
|
+
import glob from "globby";
|
|
7
|
+
import fs, { existsSync } from "node:fs";
|
|
8
|
+
import path, { dirname, join, resolve } from "node:path";
|
|
9
|
+
import { createRequire } from "node:module";
|
|
10
|
+
import { fileURLToPath } from "node:url";
|
|
11
|
+
import { parse as parse$1, traverse as traverse$1 } from "@babel/core";
|
|
12
|
+
import * as t from "@babel/types";
|
|
13
|
+
import traverse, { Scope } from "@babel/traverse";
|
|
14
|
+
import { loadConfig, createMatchPath } from "tsconfig-paths";
|
|
15
|
+
import register from "@babel/register";
|
|
16
|
+
import { CodeGenerator } from "@babel/generator";
|
|
17
|
+
const configDefinition = z.object({
|
|
18
|
+
path: z.string().or(z.array(z.string())).default([
|
|
25
19
|
"./src/**/*.{ts,tsx,js,jsx,mjs,cjs,astro}",
|
|
26
20
|
"./app/**/*.{ts,tsx,js,jsx,mjs,cjs}",
|
|
27
21
|
"./sanity/**/*.{ts,tsx,js,jsx,mjs,cjs}"
|
|
28
22
|
]),
|
|
29
|
-
schema:
|
|
30
|
-
generates:
|
|
31
|
-
formatGeneratedCode:
|
|
32
|
-
overloadClientMethods:
|
|
23
|
+
schema: z.string().default("./schema.json"),
|
|
24
|
+
generates: z.string().default("./sanity.types.ts"),
|
|
25
|
+
formatGeneratedCode: z.boolean().default(!0),
|
|
26
|
+
overloadClientMethods: z.boolean().default(!0)
|
|
33
27
|
});
|
|
34
28
|
async function readConfig(path2) {
|
|
35
29
|
try {
|
|
36
|
-
const content = await
|
|
30
|
+
const content = await readFile(path2, "utf-8"), json = json5.parse(content);
|
|
37
31
|
return configDefinition.parseAsync(json);
|
|
38
32
|
} catch (error) {
|
|
39
|
-
if (error instanceof
|
|
33
|
+
if (error instanceof z.ZodError)
|
|
40
34
|
throw new Error(
|
|
41
35
|
`Error in config file
|
|
42
36
|
${error.errors.map((err) => err.message).join(`
|
|
@@ -49,14 +43,14 @@ async function readConfig(path2) {
|
|
|
49
43
|
}
|
|
50
44
|
}
|
|
51
45
|
async function readSchema(path2) {
|
|
52
|
-
const content = await
|
|
46
|
+
const content = await readFile(path2, "utf-8");
|
|
53
47
|
return JSON.parse(content);
|
|
54
48
|
}
|
|
55
49
|
function safeParseQuery(query) {
|
|
56
50
|
const params = {};
|
|
57
51
|
for (const param of extractSliceParams(query))
|
|
58
52
|
params[param] = 0;
|
|
59
|
-
return
|
|
53
|
+
return parse(query, { params });
|
|
60
54
|
}
|
|
61
55
|
function* extractSliceParams(query) {
|
|
62
56
|
const sliceRegex = /\[(\$(\w+)|\d)\.\.\.?(\$(\w+)|\d)\]/g, matches = query.matchAll(sliceRegex);
|
|
@@ -68,22 +62,23 @@ function* extractSliceParams(query) {
|
|
|
68
62
|
end !== null && (yield end);
|
|
69
63
|
}
|
|
70
64
|
}
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
65
|
+
const __dirname$1 = dirname(new URL(import.meta.url).pathname);
|
|
66
|
+
function findBabelConfig(path2) {
|
|
67
|
+
const configPath = join(path2, "babel.config.json");
|
|
68
|
+
if (existsSync(configPath))
|
|
74
69
|
return configPath;
|
|
75
|
-
const parent =
|
|
76
|
-
if (parent && parent !==
|
|
70
|
+
const parent = resolve(join(path2, ".."));
|
|
71
|
+
if (parent && parent !== path2)
|
|
77
72
|
return findBabelConfig(parent);
|
|
78
73
|
throw new Error("Could not find `babel.config.json` in @sanity/codegen");
|
|
79
74
|
}
|
|
80
75
|
function getBabelConfig(path2) {
|
|
81
|
-
return { extends: findBabelConfig(__dirname) };
|
|
76
|
+
return { extends: findBabelConfig(__dirname$1) };
|
|
82
77
|
}
|
|
83
78
|
function parseSourceFile(_source, _filename, babelOptions) {
|
|
84
79
|
let source = _source, filename = _filename;
|
|
85
80
|
filename.endsWith(".astro") ? (filename += ".ts", source = parseAstro(source)) : filename.endsWith(".vue") && (filename += ".ts", source = parseVue(source));
|
|
86
|
-
const result =
|
|
81
|
+
const result = parse$1(source, {
|
|
87
82
|
...babelOptions,
|
|
88
83
|
filename
|
|
89
84
|
});
|
|
@@ -112,7 +107,7 @@ function matchAllPolyfill(str, regex) {
|
|
|
112
107
|
matches.push(match);
|
|
113
108
|
return matches;
|
|
114
109
|
}
|
|
115
|
-
const debug$2 =
|
|
110
|
+
const debug$2 = createDebug("sanity:codegen:findQueries:debug"), TAGGED_TEMPLATE_ALLOW_LIST = ["groq"], FUNCTION_WRAPPER_ALLOW_LIST = ["defineQuery"];
|
|
116
111
|
function resolveExpression({
|
|
117
112
|
node,
|
|
118
113
|
file,
|
|
@@ -125,7 +120,7 @@ function resolveExpression({
|
|
|
125
120
|
}) {
|
|
126
121
|
if (debug$2(
|
|
127
122
|
`Resolving node ${node.type} in ${filename}:${node.loc?.start.line}:${node.loc?.start.column}`
|
|
128
|
-
),
|
|
123
|
+
), t.isTaggedTemplateExpression(node) && t.isIdentifier(node.tag) && TAGGED_TEMPLATE_ALLOW_LIST.includes(node.tag.name))
|
|
129
124
|
return resolveExpression({
|
|
130
125
|
node: node.quasi,
|
|
131
126
|
scope,
|
|
@@ -136,7 +131,7 @@ function resolveExpression({
|
|
|
136
131
|
babelConfig,
|
|
137
132
|
fnArguments
|
|
138
133
|
});
|
|
139
|
-
if (
|
|
134
|
+
if (t.isTemplateLiteral(node)) {
|
|
140
135
|
const resolvedExpressions = node.expressions.map(
|
|
141
136
|
(expression) => resolveExpression({
|
|
142
137
|
node: expression,
|
|
@@ -151,12 +146,12 @@ function resolveExpression({
|
|
|
151
146
|
);
|
|
152
147
|
return node.quasis.map((quasi, idx) => (quasi.value.cooked || "") + (resolvedExpressions[idx] || "")).join("");
|
|
153
148
|
}
|
|
154
|
-
if (
|
|
149
|
+
if (t.isLiteral(node)) {
|
|
155
150
|
if (node.type === "NullLiteral" || node.type === "RegExpLiteral")
|
|
156
151
|
throw new Error(`Unsupported literal type: ${node.type}`);
|
|
157
152
|
return node.value.toString();
|
|
158
153
|
}
|
|
159
|
-
if (
|
|
154
|
+
if (t.isIdentifier(node))
|
|
160
155
|
return resolveIdentifier({
|
|
161
156
|
node,
|
|
162
157
|
scope,
|
|
@@ -167,8 +162,8 @@ function resolveExpression({
|
|
|
167
162
|
babelConfig,
|
|
168
163
|
params
|
|
169
164
|
});
|
|
170
|
-
if (
|
|
171
|
-
const init = node.init ?? (
|
|
165
|
+
if (t.isVariableDeclarator(node)) {
|
|
166
|
+
const init = node.init ?? (t.isAssignmentPattern(node.id) && node.id.right);
|
|
172
167
|
if (!init)
|
|
173
168
|
throw new Error("Unsupported variable declarator");
|
|
174
169
|
return resolveExpression({
|
|
@@ -181,7 +176,7 @@ function resolveExpression({
|
|
|
181
176
|
resolver
|
|
182
177
|
});
|
|
183
178
|
}
|
|
184
|
-
if (
|
|
179
|
+
if (t.isCallExpression(node) && t.isIdentifier(node.callee) && FUNCTION_WRAPPER_ALLOW_LIST.includes(node.callee.name))
|
|
185
180
|
return resolveExpression({
|
|
186
181
|
node: node.arguments[0],
|
|
187
182
|
scope,
|
|
@@ -191,7 +186,7 @@ function resolveExpression({
|
|
|
191
186
|
babelConfig,
|
|
192
187
|
params
|
|
193
188
|
});
|
|
194
|
-
if (
|
|
189
|
+
if (t.isCallExpression(node))
|
|
195
190
|
return resolveCallExpression({
|
|
196
191
|
node,
|
|
197
192
|
scope,
|
|
@@ -201,8 +196,8 @@ function resolveExpression({
|
|
|
201
196
|
babelConfig,
|
|
202
197
|
params
|
|
203
198
|
});
|
|
204
|
-
if (
|
|
205
|
-
const newScope = new
|
|
199
|
+
if (t.isArrowFunctionExpression(node) || t.isFunctionDeclaration(node) || t.isFunctionExpression(node)) {
|
|
200
|
+
const newScope = new Scope(scope.path, scope);
|
|
206
201
|
return params.forEach((param, i) => {
|
|
207
202
|
newScope.push({
|
|
208
203
|
id: param,
|
|
@@ -219,7 +214,7 @@ function resolveExpression({
|
|
|
219
214
|
resolver
|
|
220
215
|
});
|
|
221
216
|
}
|
|
222
|
-
if (
|
|
217
|
+
if (t.isNewExpression(node))
|
|
223
218
|
return resolveExpression({
|
|
224
219
|
node: node.callee,
|
|
225
220
|
scope,
|
|
@@ -228,9 +223,9 @@ function resolveExpression({
|
|
|
228
223
|
babelConfig,
|
|
229
224
|
resolver
|
|
230
225
|
});
|
|
231
|
-
if (
|
|
226
|
+
if (t.isImportDefaultSpecifier(node) || t.isImportSpecifier(node))
|
|
232
227
|
return resolveImportSpecifier({ node, file, filename, fnArguments, resolver, babelConfig });
|
|
233
|
-
if (
|
|
228
|
+
if (t.isAssignmentPattern(node))
|
|
234
229
|
return resolveExpression({
|
|
235
230
|
node: node.right,
|
|
236
231
|
scope,
|
|
@@ -256,10 +251,10 @@ function resolveIdentifier({
|
|
|
256
251
|
params
|
|
257
252
|
}) {
|
|
258
253
|
const paramIndex = params.findIndex(
|
|
259
|
-
(param) =>
|
|
254
|
+
(param) => t.isIdentifier(param) && node.name === param.name || t.isAssignmentPattern(param) && t.isIdentifier(param.left) && node.name === param.left.name
|
|
260
255
|
);
|
|
261
256
|
let argument = fnArguments[paramIndex];
|
|
262
|
-
if (!argument && paramIndex >= 0 &&
|
|
257
|
+
if (!argument && paramIndex >= 0 && t.isAssignmentPattern(params[paramIndex]) && (argument = params[paramIndex].right), argument && t.isLiteral(argument))
|
|
263
258
|
return resolveExpression({
|
|
264
259
|
node: argument,
|
|
265
260
|
scope,
|
|
@@ -272,7 +267,7 @@ function resolveIdentifier({
|
|
|
272
267
|
});
|
|
273
268
|
const binding = scope.getBinding(node.name);
|
|
274
269
|
if (binding) {
|
|
275
|
-
if (
|
|
270
|
+
if (t.isIdentifier(binding.path.node) && binding.path.node.name === node.name)
|
|
276
271
|
throw new Error(
|
|
277
272
|
`Could not resolve same identifier "${node.name}" in "${filename}:${node.loc?.start.line}:${node.loc?.start.column}"`
|
|
278
273
|
);
|
|
@@ -321,11 +316,11 @@ function resolveImportSpecifier({
|
|
|
321
316
|
babelConfig
|
|
322
317
|
}) {
|
|
323
318
|
let importDeclaration;
|
|
324
|
-
if (
|
|
319
|
+
if (traverse(file, {
|
|
325
320
|
ImportDeclaration(n) {
|
|
326
|
-
if (
|
|
321
|
+
if (t.isImportDeclaration(n.node))
|
|
327
322
|
for (const specifier of n.node.specifiers) {
|
|
328
|
-
if (
|
|
323
|
+
if (t.isImportDefaultSpecifier(specifier) && specifier.local.loc?.identifierName === node.local.name) {
|
|
329
324
|
importDeclaration = n.node;
|
|
330
325
|
break;
|
|
331
326
|
}
|
|
@@ -334,9 +329,9 @@ function resolveImportSpecifier({
|
|
|
334
329
|
}
|
|
335
330
|
}), !importDeclaration)
|
|
336
331
|
throw new Error(`Could not find import declaration for ${node.local.name}`);
|
|
337
|
-
const importName = node.local.name, importFileName = importDeclaration.source.value, importPath = importFileName.startsWith("./") || importFileName.startsWith("../") ?
|
|
332
|
+
const importName = node.local.name, importFileName = importDeclaration.source.value, importPath = importFileName.startsWith("./") || importFileName.startsWith("../") ? path.resolve(path.dirname(filename), importFileName) : importFileName, resolvedFile = resolver(importPath), source = fs.readFileSync(resolvedFile), tree = parseSourceFile(source.toString(), resolvedFile, babelConfig);
|
|
338
333
|
let newScope;
|
|
339
|
-
if (
|
|
334
|
+
if (traverse(tree, {
|
|
340
335
|
Program(p) {
|
|
341
336
|
newScope = p.scope;
|
|
342
337
|
}
|
|
@@ -354,7 +349,7 @@ function resolveImportSpecifier({
|
|
|
354
349
|
resolver
|
|
355
350
|
});
|
|
356
351
|
let namedExport, newImportName;
|
|
357
|
-
if (
|
|
352
|
+
if (traverse(tree, {
|
|
358
353
|
ExportDeclaration(p) {
|
|
359
354
|
if (p.node.type === "ExportNamedDeclaration")
|
|
360
355
|
for (const specifier of p.node.specifiers)
|
|
@@ -370,7 +365,7 @@ function resolveImportSpecifier({
|
|
|
370
365
|
babelConfig
|
|
371
366
|
});
|
|
372
367
|
let result;
|
|
373
|
-
if (
|
|
368
|
+
if (traverse(tree, {
|
|
374
369
|
ExportDeclaration(p) {
|
|
375
370
|
if (p.node.type === "ExportAllDeclaration")
|
|
376
371
|
try {
|
|
@@ -399,9 +394,9 @@ function resolveExportSpecifier({
|
|
|
399
394
|
}) {
|
|
400
395
|
if (!node.source)
|
|
401
396
|
throw new Error(`Could not find source for export "${importName}" in ${filename}`);
|
|
402
|
-
const importFileName = node.source.value, importPath =
|
|
397
|
+
const importFileName = node.source.value, importPath = path.resolve(path.dirname(filename), importFileName), resolvedFile = resolver(importPath), source = fs.readFileSync(resolvedFile), tree = parseSourceFile(source.toString(), resolvedFile, babelConfig);
|
|
403
398
|
let newScope;
|
|
404
|
-
if (
|
|
399
|
+
if (traverse(tree, {
|
|
405
400
|
Program(p) {
|
|
406
401
|
newScope = p.scope;
|
|
407
402
|
}
|
|
@@ -422,15 +417,15 @@ function resolveExportSpecifier({
|
|
|
422
417
|
cause: `noBinding:${importName}`
|
|
423
418
|
});
|
|
424
419
|
}
|
|
425
|
-
const
|
|
426
|
-
function findQueriesInSource(source, filename, babelConfig = getBabelConfig(), resolver = require$
|
|
420
|
+
const __filename$1 = fileURLToPath(import.meta.url), require$2 = createRequire(__filename$1), groqTagName = "groq", defineQueryFunctionName = "defineQuery", groqModuleName = "groq", nextSanityModuleName = "next-sanity", ignoreValue = "@sanity-typegen-ignore";
|
|
421
|
+
function findQueriesInSource(source, filename, babelConfig = getBabelConfig(), resolver = require$2.resolve) {
|
|
427
422
|
const queries = [], file = parseSourceFile(source, filename, babelConfig);
|
|
428
|
-
return
|
|
423
|
+
return traverse$1(file, {
|
|
429
424
|
// Look for variable declarations, e.g. `const myQuery = groq`... and extract the query.
|
|
430
425
|
// The variable name is used as the name of the query result type
|
|
431
426
|
VariableDeclarator(path2) {
|
|
432
|
-
const { node, scope } = path2, init = node.init, isGroqTemplateTag =
|
|
433
|
-
if (
|
|
427
|
+
const { node, scope } = path2, init = node.init, isGroqTemplateTag = t.isTaggedTemplateExpression(init) && t.isIdentifier(init.tag) && init.tag.name === groqTagName, isDefineQueryCall = t.isCallExpression(init) && (isImportFrom(groqModuleName, defineQueryFunctionName, scope, init.callee) || isImportFrom(nextSanityModuleName, defineQueryFunctionName, scope, init.callee));
|
|
428
|
+
if (t.isIdentifier(node.id) && (isGroqTemplateTag || isDefineQueryCall)) {
|
|
434
429
|
if (declarationLeadingCommentContains(path2, ignoreValue))
|
|
435
430
|
return;
|
|
436
431
|
const queryName = `${node.id.name}`, queryResult = resolveExpression({
|
|
@@ -462,47 +457,47 @@ function declarationLeadingCommentContains(path2, comment) {
|
|
|
462
457
|
)) : !1;
|
|
463
458
|
}
|
|
464
459
|
function isImportFrom(moduleName, importName, scope, node) {
|
|
465
|
-
if (
|
|
460
|
+
if (t.isIdentifier(node)) {
|
|
466
461
|
const binding = scope.getBinding(node.name);
|
|
467
462
|
if (!binding)
|
|
468
463
|
return !1;
|
|
469
464
|
const { path: path2 } = binding;
|
|
470
|
-
if (
|
|
471
|
-
return path2.node.importKind === "value" && path2.parentPath &&
|
|
472
|
-
if (
|
|
465
|
+
if (t.isImportSpecifier(path2.node))
|
|
466
|
+
return path2.node.importKind === "value" && path2.parentPath && t.isImportDeclaration(path2.parentPath.node) && path2.parentPath.node.source.value === moduleName && t.isIdentifier(path2.node.imported) && path2.node.imported.name === importName;
|
|
467
|
+
if (t.isVariableDeclarator(path2.node)) {
|
|
473
468
|
const { init } = path2.node;
|
|
474
|
-
return
|
|
469
|
+
return t.isCallExpression(init) && t.isIdentifier(init.callee) && init.callee.name === "require" && t.isStringLiteral(init.arguments[0]) && init.arguments[0].value === moduleName;
|
|
475
470
|
}
|
|
476
471
|
}
|
|
477
|
-
if (
|
|
472
|
+
if (t.isMemberExpression(node)) {
|
|
478
473
|
const { object, property } = node;
|
|
479
|
-
if (!
|
|
474
|
+
if (!t.isIdentifier(object))
|
|
480
475
|
return !1;
|
|
481
476
|
const binding = scope.getBinding(object.name);
|
|
482
477
|
if (!binding)
|
|
483
478
|
return !1;
|
|
484
479
|
const { path: path2 } = binding;
|
|
485
|
-
return
|
|
480
|
+
return t.isIdentifier(object) && t.isIdentifier(property) && property.name === importName && t.isImportNamespaceSpecifier(path2.node) && path2.parentPath && t.isImportDeclaration(path2.parentPath.node) && path2.parentPath.node.source.value === moduleName;
|
|
486
481
|
}
|
|
487
482
|
return !1;
|
|
488
483
|
}
|
|
489
|
-
const debug$1 =
|
|
484
|
+
const require$1 = createRequire(import.meta.url), debug$1 = createDebug("sanity:codegen:moduleResolver");
|
|
490
485
|
function getResolver(cwd) {
|
|
491
|
-
const tsConfig =
|
|
486
|
+
const tsConfig = loadConfig(cwd);
|
|
492
487
|
if (tsConfig.resultType === "failed")
|
|
493
|
-
return debug$1("Could not load tsconfig, using default resolver: %s", tsConfig.message), require.resolve;
|
|
494
|
-
const matchPath =
|
|
488
|
+
return debug$1("Could not load tsconfig, using default resolver: %s", tsConfig.message), require$1.resolve;
|
|
489
|
+
const matchPath = createMatchPath(
|
|
495
490
|
tsConfig.absoluteBaseUrl,
|
|
496
491
|
tsConfig.paths,
|
|
497
492
|
tsConfig.mainFields,
|
|
498
493
|
tsConfig.addMatchAll
|
|
499
|
-
),
|
|
494
|
+
), resolve2 = function(request, options) {
|
|
500
495
|
const found = matchPath(request);
|
|
501
|
-
return found !== void 0 ? require.resolve(found, options) : require.resolve(request, options);
|
|
496
|
+
return found !== void 0 ? require$1.resolve(found, options) : require$1.resolve(request, options);
|
|
502
497
|
};
|
|
503
|
-
return
|
|
498
|
+
return resolve2.paths = (request) => require$1.resolve.paths(request), resolve2;
|
|
504
499
|
}
|
|
505
|
-
const debug =
|
|
500
|
+
const debug = createDebug("sanity:codegen:findQueries:debug");
|
|
506
501
|
async function* findQueriesInPath({
|
|
507
502
|
path: path2,
|
|
508
503
|
babelOptions = getBabelConfig(),
|
|
@@ -510,7 +505,7 @@ async function* findQueriesInPath({
|
|
|
510
505
|
}) {
|
|
511
506
|
const queryNames = /* @__PURE__ */ new Set();
|
|
512
507
|
debug(`Globing ${path2}`);
|
|
513
|
-
const files =
|
|
508
|
+
const files = glob.sync(path2, {
|
|
514
509
|
absolute: !1,
|
|
515
510
|
ignore: ["**/node_modules/**"],
|
|
516
511
|
// we never want to look in node_modules
|
|
@@ -520,7 +515,7 @@ async function* findQueriesInPath({
|
|
|
520
515
|
if (typeof filename == "string") {
|
|
521
516
|
debug(`Found file "${filename}"`);
|
|
522
517
|
try {
|
|
523
|
-
const source = await
|
|
518
|
+
const source = await fs$1.readFile(filename, "utf8"), queries = findQueriesInSource(source, filename, babelOptions, resolver);
|
|
524
519
|
for (const query of queries) {
|
|
525
520
|
if (queryNames.has(query.name))
|
|
526
521
|
throw new Error(
|
|
@@ -536,7 +531,7 @@ async function* findQueriesInPath({
|
|
|
536
531
|
}
|
|
537
532
|
function registerBabel(babelOptions) {
|
|
538
533
|
const options = babelOptions || getBabelConfig();
|
|
539
|
-
|
|
534
|
+
register({ ...options, extensions: [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"] });
|
|
540
535
|
}
|
|
541
536
|
const REFERENCE_SYMBOL_NAME = "internalGroqTypeReferenceTo", ALL_SCHEMA_TYPES = "AllSanitySchemaTypes";
|
|
542
537
|
class TypeGenerator {
|
|
@@ -565,19 +560,19 @@ class TypeGenerator {
|
|
|
565
560
|
if (!schemaName)
|
|
566
561
|
throw new Error(`Schema name not found for schema ${schema.name}`);
|
|
567
562
|
schemaNames.add(schemaName);
|
|
568
|
-
const typeAlias =
|
|
569
|
-
typeDeclarations.push(
|
|
563
|
+
const typeAlias = t.tsTypeAliasDeclaration(t.identifier(schemaName), null, typeLiteral);
|
|
564
|
+
typeDeclarations.push(t.exportNamedDeclaration(typeAlias));
|
|
570
565
|
}), typeDeclarations.push(
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
566
|
+
t.exportNamedDeclaration(
|
|
567
|
+
t.tsTypeAliasDeclaration(
|
|
568
|
+
t.identifier(this.getTypeName(ALL_SCHEMA_TYPES)),
|
|
574
569
|
null,
|
|
575
|
-
|
|
576
|
-
[...schemaNames].map((typeName) =>
|
|
570
|
+
t.tsUnionType(
|
|
571
|
+
[...schemaNames].map((typeName) => t.tsTypeReference(t.identifier(typeName)))
|
|
577
572
|
)
|
|
578
573
|
)
|
|
579
574
|
)
|
|
580
|
-
), typeDeclarations.map((decl) => new
|
|
575
|
+
), typeDeclarations.map((decl) => new CodeGenerator(decl).generate().code).join(`
|
|
581
576
|
|
|
582
577
|
`);
|
|
583
578
|
}
|
|
@@ -590,14 +585,14 @@ class TypeGenerator {
|
|
|
590
585
|
* @beta
|
|
591
586
|
*/
|
|
592
587
|
generateTypeNodeTypes(identifierName, typeNode) {
|
|
593
|
-
const type = this.getTypeNodeType(typeNode), typeName = this.getTypeName(identifierName, typeNode), typeAlias =
|
|
594
|
-
return new
|
|
588
|
+
const type = this.getTypeNodeType(typeNode), typeName = this.getTypeName(identifierName, typeNode), typeAlias = t.tsTypeAliasDeclaration(t.identifier(typeName), null, type);
|
|
589
|
+
return new CodeGenerator(t.exportNamedDeclaration(typeAlias)).generate().code.trim();
|
|
595
590
|
}
|
|
596
591
|
static generateKnownTypes() {
|
|
597
|
-
const typeOperator =
|
|
598
|
-
identifier.typeAnnotation =
|
|
599
|
-
const decleration =
|
|
600
|
-
return decleration.declare = !0, new
|
|
592
|
+
const typeOperator = t.tsTypeOperator(t.tsSymbolKeyword(), "unique"), identifier = t.identifier(REFERENCE_SYMBOL_NAME);
|
|
593
|
+
identifier.typeAnnotation = t.tsTypeAnnotation(typeOperator);
|
|
594
|
+
const decleration = t.variableDeclaration("const", [t.variableDeclarator(identifier)]);
|
|
595
|
+
return decleration.declare = !0, new CodeGenerator(t.exportNamedDeclaration(decleration)).generate().code.trim();
|
|
601
596
|
}
|
|
602
597
|
/**
|
|
603
598
|
* Takes a list of queries from the codebase and generates a type declaration
|
|
@@ -617,23 +612,23 @@ class TypeGenerator {
|
|
|
617
612
|
const name = this.typeNodeNameMap.get(query.typeNode);
|
|
618
613
|
name && (typesByQuerystring[query.query] ??= [], typesByQuerystring[query.query].push(name));
|
|
619
614
|
}
|
|
620
|
-
const queryReturnInterface =
|
|
621
|
-
|
|
615
|
+
const queryReturnInterface = t.tsInterfaceDeclaration(
|
|
616
|
+
t.identifier("SanityQueries"),
|
|
622
617
|
null,
|
|
623
618
|
[],
|
|
624
|
-
|
|
625
|
-
Object.entries(typesByQuerystring).map(([query, types]) =>
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
619
|
+
t.tsInterfaceBody(
|
|
620
|
+
Object.entries(typesByQuerystring).map(([query, types]) => t.tsPropertySignature(
|
|
621
|
+
t.stringLiteral(query),
|
|
622
|
+
t.tsTypeAnnotation(
|
|
623
|
+
t.tsUnionType(types.map((type) => t.tsTypeReference(t.identifier(type))))
|
|
629
624
|
)
|
|
630
625
|
))
|
|
631
626
|
)
|
|
632
|
-
), declareModule =
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
), clientImport =
|
|
636
|
-
return new
|
|
627
|
+
), declareModule = t.declareModule(
|
|
628
|
+
t.stringLiteral("@sanity/client"),
|
|
629
|
+
t.blockStatement([queryReturnInterface])
|
|
630
|
+
), clientImport = t.importDeclaration([], t.stringLiteral("@sanity/client"));
|
|
631
|
+
return new CodeGenerator(t.program([clientImport, declareModule])).generate().code.trim();
|
|
637
632
|
}
|
|
638
633
|
/**
|
|
639
634
|
* Since we are sanitizing identifiers we migt end up with collisions. Ie there might be a type mux.video and muxVideo, both these
|
|
@@ -650,13 +645,13 @@ class TypeGenerator {
|
|
|
650
645
|
getTypeNodeType(typeNode) {
|
|
651
646
|
switch (typeNode.type) {
|
|
652
647
|
case "string":
|
|
653
|
-
return typeNode.value !== void 0 ?
|
|
648
|
+
return typeNode.value !== void 0 ? t.tsLiteralType(t.stringLiteral(typeNode.value)) : t.tsStringKeyword();
|
|
654
649
|
case "number":
|
|
655
|
-
return typeNode.value !== void 0 ?
|
|
650
|
+
return typeNode.value !== void 0 ? t.tsLiteralType(t.numericLiteral(typeNode.value)) : t.tsNumberKeyword();
|
|
656
651
|
case "boolean":
|
|
657
|
-
return typeNode.value !== void 0 ?
|
|
652
|
+
return typeNode.value !== void 0 ? t.tsLiteralType(t.booleanLiteral(typeNode.value)) : t.tsBooleanKeyword();
|
|
658
653
|
case "unknown":
|
|
659
|
-
return
|
|
654
|
+
return t.tsUnknownKeyword();
|
|
660
655
|
case "document":
|
|
661
656
|
return this.generateDocumentType(typeNode);
|
|
662
657
|
case "type":
|
|
@@ -670,7 +665,7 @@ class TypeGenerator {
|
|
|
670
665
|
case "inline":
|
|
671
666
|
return this.generateInlineTsType(typeNode);
|
|
672
667
|
case "null":
|
|
673
|
-
return
|
|
668
|
+
return t.tsNullKeyword();
|
|
674
669
|
default:
|
|
675
670
|
throw new Error(`Type "${typeNode.type}" not found in schema`);
|
|
676
671
|
}
|
|
@@ -678,16 +673,16 @@ class TypeGenerator {
|
|
|
678
673
|
// Helper function used to generate TS types for array type nodes.
|
|
679
674
|
generateArrayTsType(typeNode) {
|
|
680
675
|
const typeNodes = this.getTypeNodeType(typeNode.of);
|
|
681
|
-
return
|
|
682
|
-
|
|
683
|
-
|
|
676
|
+
return t.tsTypeReference(
|
|
677
|
+
t.identifier("Array"),
|
|
678
|
+
t.tsTypeParameterInstantiation([typeNodes])
|
|
684
679
|
);
|
|
685
680
|
}
|
|
686
681
|
// Helper function used to generate TS types for object properties.
|
|
687
682
|
generateObjectProperty(key, attribute) {
|
|
688
|
-
const type = this.getTypeNodeType(attribute.value), propertySignature =
|
|
689
|
-
|
|
690
|
-
|
|
683
|
+
const type = this.getTypeNodeType(attribute.value), propertySignature = t.tsPropertySignature(
|
|
684
|
+
t.identifier(sanitizeIdentifier(key)),
|
|
685
|
+
t.tsTypeAnnotation(type)
|
|
691
686
|
);
|
|
692
687
|
return propertySignature.optional = attribute.optional, propertySignature;
|
|
693
688
|
}
|
|
@@ -701,7 +696,7 @@ class TypeGenerator {
|
|
|
701
696
|
if (rest !== void 0)
|
|
702
697
|
switch (rest.type) {
|
|
703
698
|
case "unknown":
|
|
704
|
-
return
|
|
699
|
+
return t.tsUnknownKeyword();
|
|
705
700
|
case "object": {
|
|
706
701
|
Object.entries(rest.attributes).forEach(([key, attribute]) => {
|
|
707
702
|
props.push(this.generateObjectProperty(key, attribute));
|
|
@@ -710,27 +705,27 @@ class TypeGenerator {
|
|
|
710
705
|
}
|
|
711
706
|
case "inline": {
|
|
712
707
|
const resolved = this.generateInlineTsType(rest);
|
|
713
|
-
return
|
|
708
|
+
return t.isTSUnknownKeyword(resolved) ? resolved : t.tsIntersectionType([t.tsTypeLiteral(props), resolved]);
|
|
714
709
|
}
|
|
715
710
|
default:
|
|
716
711
|
throw new Error(`Type "${rest.type}" not found in schema`);
|
|
717
712
|
}
|
|
718
713
|
if (typeNode.dereferencesTo !== void 0) {
|
|
719
|
-
const derefType =
|
|
720
|
-
|
|
721
|
-
|
|
714
|
+
const derefType = t.tsPropertySignature(
|
|
715
|
+
t.identifier(REFERENCE_SYMBOL_NAME),
|
|
716
|
+
t.tsTypeAnnotation(t.tsLiteralType(t.stringLiteral(typeNode.dereferencesTo)))
|
|
722
717
|
);
|
|
723
718
|
derefType.computed = !0, derefType.optional = !0, props.push(derefType);
|
|
724
719
|
}
|
|
725
|
-
return
|
|
720
|
+
return t.tsTypeLiteral(props);
|
|
726
721
|
}
|
|
727
722
|
generateInlineTsType(typeNode) {
|
|
728
723
|
const referencedTypeNode = this.schema.find((schema) => schema.name === typeNode.name);
|
|
729
724
|
if (referencedTypeNode === void 0) {
|
|
730
725
|
const generatedName2 = this.typeNameMap.get(typeNode.name);
|
|
731
726
|
if (generatedName2)
|
|
732
|
-
return
|
|
733
|
-
const missing =
|
|
727
|
+
return t.tsTypeReference(t.identifier(generatedName2));
|
|
728
|
+
const missing = t.tsUnknownKeyword();
|
|
734
729
|
return missing.trailingComments = [
|
|
735
730
|
{
|
|
736
731
|
type: "CommentLine",
|
|
@@ -739,23 +734,23 @@ class TypeGenerator {
|
|
|
739
734
|
], missing;
|
|
740
735
|
}
|
|
741
736
|
const generatedName = this.typeNameMap.get(referencedTypeNode.name);
|
|
742
|
-
return generatedName ?
|
|
737
|
+
return generatedName ? t.tsTypeReference(t.identifier(generatedName)) : t.tsUnknownKeyword();
|
|
743
738
|
}
|
|
744
739
|
// Helper function used to generate TS types for union type nodes.
|
|
745
740
|
generateUnionTsType(typeNode) {
|
|
746
741
|
if (typeNode.of.length === 0)
|
|
747
|
-
return
|
|
742
|
+
return t.tsNeverKeyword();
|
|
748
743
|
if (typeNode.of.length === 1)
|
|
749
744
|
return this.getTypeNodeType(typeNode.of[0]);
|
|
750
745
|
const typeNodes = typeNode.of.map((node) => this.getTypeNodeType(node));
|
|
751
|
-
return
|
|
746
|
+
return t.tsUnionType(typeNodes);
|
|
752
747
|
}
|
|
753
748
|
// Helper function used to generate TS types for document type nodes.
|
|
754
749
|
generateDocumentType(document) {
|
|
755
750
|
const props = Object.entries(document.attributes).map(
|
|
756
751
|
([key, node]) => this.generateObjectProperty(key, node)
|
|
757
752
|
);
|
|
758
|
-
return
|
|
753
|
+
return t.tsTypeLiteral(props);
|
|
759
754
|
}
|
|
760
755
|
}
|
|
761
756
|
function uppercaseFirstLetter(input) {
|
|
@@ -764,13 +759,15 @@ function uppercaseFirstLetter(input) {
|
|
|
764
759
|
function sanitizeIdentifier(input) {
|
|
765
760
|
return `${input.replace(/^\d/, "_").replace(/[^$\w]+(.)/g, (_, char) => char.toUpperCase())}`;
|
|
766
761
|
}
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
762
|
+
export {
|
|
763
|
+
TypeGenerator,
|
|
764
|
+
configDefinition,
|
|
765
|
+
findQueriesInPath,
|
|
766
|
+
findQueriesInSource,
|
|
767
|
+
getResolver,
|
|
768
|
+
readConfig,
|
|
769
|
+
readSchema,
|
|
770
|
+
registerBabel,
|
|
771
|
+
safeParseQuery
|
|
772
|
+
};
|
|
776
773
|
//# sourceMappingURL=index.js.map
|