Skip to content

Commit baf7cf0

Browse files
sgulsethtzhelyazkova
andauthoredMar 19, 2024
feat(codegen): add typegen methods to codegen package (#5981)
Co-authored-by: Tonina Zhelyazkova <zhelyazkova.tonina@gmail.com>
1 parent 7addeef commit baf7cf0

File tree

11 files changed

+2200
-0
lines changed

11 files changed

+2200
-0
lines changed
 

‎packages/@sanity/codegen/package.json

+4
Original file line numberDiff line numberDiff line change
@@ -59,18 +59,22 @@
5959
},
6060
"dependencies": {
6161
"@babel/core": "^7.23.9",
62+
"@babel/generator": "^7.23.6",
6263
"@babel/preset-env": "^7.23.8",
6364
"@babel/preset-react": "^7.23.3",
6465
"@babel/preset-typescript": "^7.23.3",
6566
"@babel/register": "^7.23.7",
6667
"@babel/traverse": "^7.23.5",
6768
"@babel/types": "^7.23.9",
6869
"debug": "^4.3.4",
70+
"globby": "^10.0.0",
71+
"groq-js": "1.5.0-canary.1",
6972
"tsconfig-paths": "^4.2.0"
7073
},
7174
"devDependencies": {
7275
"@jest/globals": "^29.7.0",
7376
"@types/babel__core": "^7.20.5",
77+
"@types/babel__generator": "^7.6.8",
7478
"@types/babel__register": "^7.17.3",
7579
"@types/babel__traverse": "^7.18.1",
7680
"@types/debug": "^4.1.12",
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
export {readSchema} from '../readSchema'
2+
export {findQueriesInPath} from '../typescript/findQueriesInPath'
13
export {findQueriesInSource} from '../typescript/findQueriesInSource'
24
export {getResolver} from '../typescript/moduleResolver'
35
export {registerBabel} from '../typescript/registerBabel'
6+
export {TypeGenerator} from '../typescript/typeGenerator'
+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import {readFile} from 'fs/promises'
2+
import {type SchemaType} from 'groq-js'
3+
4+
/**
5+
* Read a schema from a given path
6+
* @param path - The path to the schema
7+
* @returns The schema
8+
* @internal
9+
* @beta
10+
**/
11+
export async function readSchema(path: string): Promise<SchemaType> {
12+
const content = await readFile(path, 'utf-8')
13+
return JSON.parse(content) // todo: ZOD validation?
14+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,222 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`generateSchemaTypes generateTypeNodeTypes should be able to generate types for type nodes: boolean 1`] = `"export type test_2 = boolean;"`;
4+
5+
exports[`generateSchemaTypes generateTypeNodeTypes should be able to generate types for type nodes: null 1`] = `"export type test_5 = null;"`;
6+
7+
exports[`generateSchemaTypes generateTypeNodeTypes should be able to generate types for type nodes: number 1`] = `"export type test_3 = number;"`;
8+
9+
exports[`generateSchemaTypes generateTypeNodeTypes should be able to generate types for type nodes: string 1`] = `"export type test = string;"`;
10+
11+
exports[`generateSchemaTypes generateTypeNodeTypes should be able to generate types for type nodes: unknown 1`] = `"export type test_4 = unknown;"`;
12+
13+
exports[`generateSchemaTypes should generate TypeScript type declarations for a schema 1`] = `
14+
"export type Author = {
15+
_id: string;
16+
_type: \\"author\\";
17+
_createdAt: string;
18+
_updatedAt: string;
19+
_rev: string;
20+
name?: string;
21+
};
22+
23+
export type Post = {
24+
_id: string;
25+
_type: \\"post\\";
26+
_createdAt: string;
27+
_updatedAt: string;
28+
_rev: string;
29+
title?: string;
30+
author?: {
31+
_ref: string;
32+
_weak?: boolean;
33+
} | {
34+
_ref: string;
35+
_weak?: boolean;
36+
};
37+
slug?: Slug;
38+
excerpt?: string;
39+
mainImage?: {
40+
_type: \\"image\\";
41+
asset: {
42+
_ref: string;
43+
_weak?: boolean;
44+
};
45+
caption?: string;
46+
attribution?: string;
47+
hotspot?: {
48+
_type: \\"sanity.imageHotspot\\";
49+
x: number;
50+
y: number;
51+
height: number;
52+
width: number;
53+
};
54+
crop?: {
55+
_type: \\"sanity.imageCrop\\";
56+
top: number;
57+
bottom: number;
58+
left: number;
59+
right: number;
60+
};
61+
};
62+
body?: BlockContent;
63+
};
64+
65+
export type Ghost = {
66+
_id: string;
67+
_type: \\"ghost\\";
68+
_createdAt: string;
69+
_updatedAt: string;
70+
_rev: string;
71+
name?: string;
72+
};
73+
74+
export type BlockContent = Array<{
75+
_key: string;
76+
level?: number;
77+
style?: \\"normal\\" | \\"h1\\" | \\"h2\\" | \\"h3\\" | \\"h4\\" | \\"blockquote\\";
78+
listItem?: \\"bullet\\";
79+
children: Array<{
80+
_key: string;
81+
text: string;
82+
marks: Array<string | \\"strong\\" | \\"em\\">;
83+
}>;
84+
markDefs: Array<{
85+
href?: string;
86+
}>;
87+
_key: string;
88+
}>;
89+
90+
export type SanityAssetSourceData = {
91+
name?: string;
92+
id?: string;
93+
url?: string;
94+
_type: \\"sanity.assetSourceData\\";
95+
};
96+
97+
export type Slug = {
98+
current?: string;
99+
source?: string;
100+
_type: \\"slug\\";
101+
};
102+
103+
export type Geopoint = {
104+
lat?: number;
105+
lng?: number;
106+
alt?: number;
107+
_type: \\"geopoint\\";
108+
};
109+
110+
export type SanityImageAsset = {
111+
_id: string;
112+
_type: \\"sanity.imageAsset\\";
113+
_createdAt: string;
114+
_updatedAt: string;
115+
_rev: string;
116+
originalFilename?: string;
117+
label?: string;
118+
title?: string;
119+
description?: string;
120+
altText?: string;
121+
sha1hash?: string;
122+
extension?: string;
123+
mimeType?: string;
124+
size?: number;
125+
assetId?: string;
126+
uploadId?: string;
127+
path?: string;
128+
url?: string;
129+
metadata?: SanityImageMetadata;
130+
source?: SanityAssetSourceData;
131+
};
132+
133+
export type SanityFileAsset = {
134+
_id: string;
135+
_type: \\"sanity.fileAsset\\";
136+
_createdAt: string;
137+
_updatedAt: string;
138+
_rev: string;
139+
originalFilename?: string;
140+
label?: string;
141+
title?: string;
142+
description?: string;
143+
altText?: string;
144+
sha1hash?: string;
145+
extension?: string;
146+
mimeType?: string;
147+
size?: number;
148+
assetId?: string;
149+
uploadId?: string;
150+
path?: string;
151+
url?: string;
152+
source?: SanityAssetSourceData;
153+
};
154+
155+
export type SanityImageCrop = {
156+
top?: number;
157+
bottom?: number;
158+
left?: number;
159+
right?: number;
160+
_type: \\"sanity.imageCrop\\";
161+
};
162+
163+
export type SanityImageHotspot = {
164+
x?: number;
165+
y?: number;
166+
height?: number;
167+
width?: number;
168+
_type: \\"sanity.imageHotspot\\";
169+
};
170+
171+
export type SanityImageMetadata = {
172+
location?: Geopoint;
173+
dimensions?: SanityImageDimensions;
174+
palette?: SanityImagePalette;
175+
lqip?: string;
176+
blurHash?: string;
177+
hasAlpha?: boolean;
178+
isOpaque?: boolean;
179+
_type: \\"sanity.imageMetadata\\";
180+
};
181+
182+
export type SanityImageDimensions = {
183+
height?: number;
184+
width?: number;
185+
aspectRatio?: number;
186+
_type: \\"sanity.imageDimensions\\";
187+
};
188+
189+
export type SanityImagePalette = {
190+
darkMuted?: SanityImagePaletteSwatch;
191+
lightVibrant?: SanityImagePaletteSwatch;
192+
darkVibrant?: SanityImagePaletteSwatch;
193+
vibrant?: SanityImagePaletteSwatch;
194+
dominant?: SanityImagePaletteSwatch;
195+
lightMuted?: SanityImagePaletteSwatch;
196+
muted?: SanityImagePaletteSwatch;
197+
_type: \\"sanity.imagePalette\\";
198+
};
199+
200+
export type SanityImagePaletteSwatch = {
201+
background?: string;
202+
foreground?: string;
203+
population?: number;
204+
title?: string;
205+
_type: \\"sanity.imagePaletteSwatch\\";
206+
};"
207+
`;
208+
209+
exports[`generateSchemaTypes should generate correct types for document schema with inline fields 1`] = `
210+
"export type myObject = {
211+
inlineField: {
212+
test: string;
213+
} & Test;
214+
unknownObject: unknown;
215+
arrayField: Array<string>;
216+
unionField: {
217+
test: string;
218+
} | string | Test;
219+
};"
220+
`;
221+
222+
exports[`generateSchemaTypes should generate correct types for document schema with inline fields 2`] = `"export type someOtherType = MyObject;"`;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import assert from 'node:assert'
2+
import path from 'node:path'
3+
4+
import {describe, expect, test} from '@jest/globals'
5+
6+
import {findQueriesInPath} from '../findQueriesInPath'
7+
8+
describe('findQueriesInPath', () => {
9+
test('should throw an error if the query name already exists', async () => {
10+
const stream = findQueriesInPath({
11+
path: path.join(__dirname, 'fixtures', '{source1,source2}.ts'),
12+
})
13+
await stream.next()
14+
const result = await stream.next()
15+
if (!result.value) {
16+
throw new Error('Expected to yield a result')
17+
}
18+
expect(result.value.type).toBe('error')
19+
assert(result.value.type === 'error') // workaround for TS
20+
expect(result.value.error.message).toMatch(/Duplicate query name found:/)
21+
})
22+
})

0 commit comments

Comments
 (0)
Please sign in to comment.