Skip to content

Commit

Permalink
fix(cli): improve error handling on missing extracted schema (#6204)
Browse files Browse the repository at this point in the history
* fix(cli): allow `--config-path` flag for `typegen generate` command

* fix(cli): improve error handling on missing extracted schema

* fix(cli): rethrow error if schema file cannot be read

Co-authored-by: Sindre Gulseth <sgulseth@gmail.com>

* refactor(cli): allow only dash-cased `--config-path` for typegen

* fix(cli): use correct check for schema path not being a file

---------

Co-authored-by: Sindre Gulseth <sgulseth@gmail.com>
  • Loading branch information
rexxars and sgulseth committed Apr 4, 2024
1 parent 69ff7ff commit 4fb0e66
Show file tree
Hide file tree
Showing 7 changed files with 163 additions and 4 deletions.
22 changes: 18 additions & 4 deletions packages/@sanity/cli/src/actions/typegen/generateAction.ts
Original file line number Diff line number Diff line change
@@ -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'
Expand All @@ -13,7 +13,7 @@ import {
import {TypesGeneratedTrace} from './generate.telemetry'

export interface TypegenGenerateTypesCommandFlags {
configPath?: string
'config-path'?: string
}

const generatedFileWarning = `/**
Expand All @@ -40,8 +40,22 @@ export default async function typegenGenerateAction(
const trace = telemetry.trace(TypesGeneratedTrace)
trace.start()

const codegenConfig = await readConfig(flags.configPath || 'sanity-typegen.json')

const codegenConfig = await readConfig(flags['config-path'] || 'sanity-typegen.json')

try {
const schemaStats = await stat(codegenConfig.schema)
if (!schemaStats.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}`)
}
throw err
}
const workerPath = await getCliWorkerPath('typegenGenerate')

const spinner = output.spinner({}).start('Generating types')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ Usage
sanity typegen generate [options]
Options:
--config-path <path>
Specifies the path to the typegen configuration file. This file should be a JSON file that contains settings for the type generation process.
Default: "sanity-typegen.json"
--help, -h
Displays this help message, providing information on command usage and options.
Expand Down
3 changes: 3 additions & 0 deletions packages/@sanity/cli/test/__fixtures__/v3/folder-typegen.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"schema": "./components"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"schema": "./custom-schema.json"
}
84 changes: 84 additions & 0 deletions packages/@sanity/cli/test/__fixtures__/v3/working-schema.json
Original file line number Diff line number Diff line change
@@ -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
}
}
}
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"schema": "./working-schema.json"
}
48 changes: 48 additions & 0 deletions packages/@sanity/cli/test/typegen.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
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: typegen config is not a file', async () => {
const err = await runSanityCmdCommand('v3', [
'typegen',
'generate',
'--config-path',
'folder-typegen.json',
]).catch((error) => error)
expect(err.code).toBe(1)
expect(err.stderr).toContain('Schema path is not a file')
})

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.stderr).toContain('Generated TypeScript types for 2 schema types')
})
})

0 comments on commit 4fb0e66

Please sign in to comment.