Skip to content

Commit a4f84c0

Browse files
committed
refactor: update validation
1 parent 687a92c commit a4f84c0

File tree

4 files changed

+40
-14
lines changed

4 files changed

+40
-14
lines changed

packages/build/src/plugins_core/frameworks_api/skew_protection.ts

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,28 +18,37 @@ export type SkewProtectionConfig = z.infer<typeof skewProtectionConfigSchema>
1818
export type DeployIDSource = z.infer<typeof deployIDSourceSchema>
1919
export type DeployIDSourceType = z.infer<typeof deployIDSourceTypeSchema>
2020

21-
const validateSkewProtectionConfig = (data: unknown): SkewProtectionConfig => {
22-
try {
23-
return skewProtectionConfigSchema.parse(data)
24-
} catch (error) {
25-
if (error instanceof z.ZodError) {
26-
throw new Error(`Invalid skew protection configuration: ${error.message}`)
27-
}
21+
const validateSkewProtectionConfig = (input: unknown): SkewProtectionConfig => {
22+
const { data, error, success } = skewProtectionConfigSchema.safeParse(input)
2823

29-
throw error
24+
if (success) {
25+
return data
3026
}
27+
28+
throw new Error(`Invalid skew protection configuration:\n\n${formatSchemaError(error)}`)
3129
}
3230

3331
export const loadSkewProtectionConfig = async (configPath: string) => {
32+
let parsedData: unknown
33+
3434
try {
3535
const data = await fs.readFile(configPath, 'utf8')
36-
const config = validateSkewProtectionConfig(JSON.parse(data))
3736

38-
return config
39-
} catch (err) {
37+
parsedData = JSON.parse(data)
38+
} catch (error) {
4039
// If the file doesn't exist, this is a non-error.
41-
if ((err as NodeJS.ErrnoException).code !== 'ENOENT') {
42-
throw err
40+
if ((error as NodeJS.ErrnoException).code === 'ENOENT') {
41+
return
4342
}
43+
44+
throw new Error('Invalid skew protection configuration', { cause: error })
4445
}
46+
47+
return validateSkewProtectionConfig(parsedData)
48+
}
49+
50+
const formatSchemaError = (error: z.ZodError) => {
51+
const lines = error.issues.map((issue) => `- ${issue.path.join('.')}: ${issue.message}`)
52+
53+
return lines.join('\n')
4554
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { mkdir, writeFile } from 'node:fs/promises'
2+
3+
await mkdir('.netlify/v1', { recursive: true })
4+
5+
await writeFile('.netlify/v1/skew-protection.json', `{"patterns":`)
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[build]
2+
command = "node build.mjs"

packages/build/tests/frameworks_api/tests.js

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,13 +156,23 @@ test('Throws an error if the skew protection configuration file is invalid', asy
156156
const { output, success } = await new Fixture('./fixtures/skew_protection_invalid').runWithBuildAndIntrospect()
157157
t.false(success)
158158
t.true(output.includes('Invalid skew protection configuration'))
159+
t.true(
160+
output.includes(
161+
`sources.0.type: Invalid enum value. Expected 'cookie' | 'header' | 'query', received 'invalid_type'`,
162+
),
163+
)
164+
})
165+
166+
test('Throws an error if the skew protection configuration file is malformed', async (t) => {
167+
const { output, success } = await new Fixture('./fixtures/skew_protection_malformed').runWithBuildAndIntrospect()
168+
t.false(success)
169+
t.true(output.includes('Invalid skew protection configuration'))
159170
})
160171

161172
test('Does not create dist file when skew protection file is missing', async (t) => {
162173
const fixture = new Fixture('./fixtures/skew_protection_missing')
163174
const { success } = await fixture.runWithBuildAndIntrospect()
164175
const distPath = resolve(fixture.repositoryRoot, '.netlify/deploy-config/deploy-config.json')
165-
166176
t.true(success)
167177

168178
try {

0 commit comments

Comments
 (0)