diff --git a/packages/@sanity/cli/src/actions/typegen/generateAction.ts b/packages/@sanity/cli/src/actions/typegen/generateAction.ts index fa9101c84df8..53b44dffcf33 100644 --- a/packages/@sanity/cli/src/actions/typegen/generateAction.ts +++ b/packages/@sanity/cli/src/actions/typegen/generateAction.ts @@ -1,4 +1,4 @@ -import {constants, open} from 'node:fs/promises' +import {constants, open, stat} from 'node:fs/promises' import {join} from 'node:path' import {readConfig} from '@sanity/codegen' @@ -45,6 +45,19 @@ export default async function typegenGenerateAction( flags.configPath || flags['config-path'] || 'sanity-typegen.json', ) + try { + const {isFile} = await stat(codegenConfig.schema) + if (!isFile) { + throw new Error(`Schema path is not a file: ${codegenConfig.schema}`) + } + } catch (err) { + if (err.code === 'ENOENT') { + // If the user has not provided a specific schema path (eg we're using the default), give some help + const hint = + codegenConfig.schema === './schema.json' ? ` - did you run "sanity schema extract"?` : '' + throw new Error(`Schema file not found: ${codegenConfig.schema}${hint}`) + } + } const workerPath = await getCliWorkerPath('typegenGenerate') const spinner = output.spinner({}).start('Generating types') diff --git a/packages/@sanity/cli/test/__fixtures__/v3/missing-typegen.json b/packages/@sanity/cli/test/__fixtures__/v3/missing-typegen.json new file mode 100644 index 000000000000..047787b9af8d --- /dev/null +++ b/packages/@sanity/cli/test/__fixtures__/v3/missing-typegen.json @@ -0,0 +1,3 @@ +{ + "schema": "./custom-schema.json" +} diff --git a/packages/@sanity/cli/test/__fixtures__/v3/working-schema.json b/packages/@sanity/cli/test/__fixtures__/v3/working-schema.json new file mode 100644 index 000000000000..e37c082f523f --- /dev/null +++ b/packages/@sanity/cli/test/__fixtures__/v3/working-schema.json @@ -0,0 +1,84 @@ +[ + { + "name": "person", + "type": "document", + "attributes": { + "_id": { + "type": "objectAttribute", + "value": { + "type": "string" + } + }, + "_type": { + "type": "objectAttribute", + "value": { + "type": "string", + "value": "person" + } + }, + "_createdAt": { + "type": "objectAttribute", + "value": { + "type": "string" + } + }, + "_updatedAt": { + "type": "objectAttribute", + "value": { + "type": "string" + } + }, + "_rev": { + "type": "objectAttribute", + "value": { + "type": "string" + } + }, + "name": { + "type": "objectAttribute", + "value": { + "type": "string" + }, + "optional": true + }, + "slug": { + "type": "objectAttribute", + "value": { + "type": "inline", + "name": "slug" + }, + "optional": true + } + } + }, + { + "name": "slug", + "type": "type", + "value": { + "type": "object", + "attributes": { + "_type": { + "type": "objectAttribute", + "value": { + "type": "string", + "value": "slug" + } + }, + "current": { + "type": "objectAttribute", + "value": { + "type": "string" + }, + "optional": true + }, + "source": { + "type": "objectAttribute", + "value": { + "type": "string" + }, + "optional": true + } + } + } + } +] diff --git a/packages/@sanity/cli/test/__fixtures__/v3/working-typegen.json b/packages/@sanity/cli/test/__fixtures__/v3/working-typegen.json new file mode 100644 index 000000000000..6b6bf2222a33 --- /dev/null +++ b/packages/@sanity/cli/test/__fixtures__/v3/working-typegen.json @@ -0,0 +1,3 @@ +{ + "schema": "./working-schema.json" +} diff --git a/packages/@sanity/cli/test/typegen.test.ts b/packages/@sanity/cli/test/typegen.test.ts new file mode 100644 index 000000000000..0cb379bc5bb5 --- /dev/null +++ b/packages/@sanity/cli/test/typegen.test.ts @@ -0,0 +1,37 @@ +import {expect, test} from '@jest/globals' + +import {describeCliTest} from './shared/describe' +import {runSanityCmdCommand} from './shared/environment' + +describeCliTest('CLI: `sanity typegen`', () => { + test('sanity typegen generate: missing schema, default path', async () => { + const err = await runSanityCmdCommand('v3', ['typegen', 'generate']).catch((error) => error) + expect(err.code).toBe(1) + expect(err.stderr).toContain('did you run "sanity schema extract"') + expect(err.stderr).toContain('Schema file not found') + }) + + test('sanity typegen generate: missing schema, custom path', async () => { + const err = await runSanityCmdCommand('v3', [ + 'typegen', + 'generate', + '--config-path', + 'missing-typegen.json', + ]).catch((error) => error) + expect(err.code).toBe(1) + expect(err.stderr).not.toContain('did you run "sanity schema extract"') + expect(err.stderr).toContain('custom-schema.json') + }) + + test('sanity typegen generate: working schema', async () => { + const result = await runSanityCmdCommand('v3', [ + 'typegen', + 'generate', + '--config-path', + 'working-typegen.json', + ]) + + expect(result.code).toBe(0) + expect(result.stdout).toContain('Generated TypeScript types for 2 schema types') + }) +})