diff --git a/packages/@sanity/codegen/src/typescript/__tests__/__snapshots__/typeGenerator.test.ts.snap b/packages/@sanity/codegen/src/typescript/__tests__/__snapshots__/typeGenerator.test.ts.snap index 3fb5ace33076..2fa9289ae2f4 100644 --- a/packages/@sanity/codegen/src/typescript/__tests__/__snapshots__/typeGenerator.test.ts.snap +++ b/packages/@sanity/codegen/src/typescript/__tests__/__snapshots__/typeGenerator.test.ts.snap @@ -1,5 +1,7 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`generateSchemaTypes can generate well known types 1`] = `"export declare const internalGroqTypeReferenceTo: unique symbol;"`; + exports[`generateSchemaTypes generateTypeNodeTypes should be able to generate types for type nodes: boolean 1`] = `"export type test_2 = boolean;"`; exports[`generateSchemaTypes generateTypeNodeTypes should be able to generate types for type nodes: null 1`] = `"export type test_5 = null;"`; @@ -30,9 +32,11 @@ export type Post = { author?: { _ref: string; _weak?: boolean; + [internalGroqTypeReferenceTo]?: \\"author\\"; } | { _ref: string; _weak?: boolean; + [internalGroqTypeReferenceTo]?: \\"ghost\\"; }; slug?: Slug; excerpt?: string; @@ -41,6 +45,7 @@ export type Post = { asset: { _ref: string; _weak?: boolean; + [internalGroqTypeReferenceTo]?: \\"sanity.imageAsset\\"; }; caption?: string; attribution?: string; diff --git a/packages/@sanity/codegen/src/typescript/__tests__/typeGenerator.test.ts b/packages/@sanity/codegen/src/typescript/__tests__/typeGenerator.test.ts index 9aeea17344c3..49a66fd73f91 100644 --- a/packages/@sanity/codegen/src/typescript/__tests__/typeGenerator.test.ts +++ b/packages/@sanity/codegen/src/typescript/__tests__/typeGenerator.test.ts @@ -24,6 +24,12 @@ describe('generateSchemaTypes', () => { expect(typeDeclarations).toMatchSnapshot() }) + test('can generate well known types', async () => { + const typeDeclarations = TypeGenerator.generateKnownTypes() + + expect(typeDeclarations).toMatchSnapshot() + }) + test('should generate correct types for document schema with string fields', () => { const schema: SchemaType = [ { @@ -247,6 +253,7 @@ describe('generateSchemaTypes', () => { _ref: string; _type: \\"reference\\"; _weak?: boolean; + [internalGroqTypeReferenceTo]?: \\"author\\"; }; }; diff --git a/packages/@sanity/codegen/src/typescript/typeGenerator.ts b/packages/@sanity/codegen/src/typescript/typeGenerator.ts index 70d0ba8141c8..cc70b42f5d6c 100644 --- a/packages/@sanity/codegen/src/typescript/typeGenerator.ts +++ b/packages/@sanity/codegen/src/typescript/typeGenerator.ts @@ -11,6 +11,8 @@ import { type UnionTypeNode, } from 'groq-js' +const REFERENCE_SYMBOL_NAME = 'internalGroqTypeReferenceTo' + /** * A class used to generate TypeScript types from a given schema * @internal @@ -71,6 +73,18 @@ export class TypeGenerator { return new CodeGenerator(t.exportNamedDeclaration(typeAlias)).generate().code } + static generateKnownTypes(): string { + const typeOperator = t.tsTypeOperator(t.tsSymbolKeyword()) + typeOperator.operator = 'unique' + + const identifier = t.identifier(REFERENCE_SYMBOL_NAME) + identifier.typeAnnotation = t.tsTypeAnnotation(typeOperator) + + const decleration = t.variableDeclaration('const', [t.variableDeclarator(identifier)]) + decleration.declare = true + return new CodeGenerator(t.exportNamedDeclaration(decleration)).generate().code + } + /** * Since we are sanitizing identifiers we migt end up with collisions. Ie there might be a type mux.video and muxVideo, both these * types would be sanityized into MuxVideo. To avoid this we keep track of the generated type names and add a index to the name. @@ -204,6 +218,15 @@ export class TypeGenerator { } } } + if (typeNode.dereferencesTo !== undefined) { + const derefType = t.tsPropertySignature( + t.identifier(REFERENCE_SYMBOL_NAME), + t.tsTypeAnnotation(t.tsLiteralType(t.stringLiteral(typeNode.dereferencesTo))), + ) + derefType.computed = true + derefType.optional = true + props.push(derefType) + } return t.tsTypeLiteral(props) } diff --git a/packages/sanity/src/_internal/cli/threads/codegenGenerateTypes.ts b/packages/sanity/src/_internal/cli/threads/codegenGenerateTypes.ts index 471fb515a0b5..e94cb527db65 100644 --- a/packages/sanity/src/_internal/cli/threads/codegenGenerateTypes.ts +++ b/packages/sanity/src/_internal/cli/threads/codegenGenerateTypes.ts @@ -58,7 +58,10 @@ async function main() { const schema = await readSchema(opts.schemaPath) const typeGenerator = new TypeGenerator(schema) - const schemaTypes = typeGenerator.generateSchemaTypes() + const schemaTypes = [ + typeGenerator.generateSchemaTypes(), + TypeGenerator.generateKnownTypes(), + ].join('\n') const resolver = getResolver() parentPort?.postMessage({