-
Notifications
You must be signed in to change notification settings - Fork 27.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor: added more strict app segment config parsing
- Loading branch information
Showing
7 changed files
with
433 additions
and
220 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
import { AppSegmentConfigSchema } from './app-segment-config' | ||
|
||
describe('AppConfigSchema', () => { | ||
it('should only support zero, a positive number or false for revalidate', () => { | ||
const valid = [0, 1, 100, false] | ||
|
||
for (const value of valid) { | ||
expect( | ||
AppSegmentConfigSchema.safeParse({ revalidate: value }).success | ||
).toBe(true) | ||
} | ||
|
||
const invalid = [-1, -100, true] | ||
|
||
for (const value of invalid) { | ||
expect( | ||
AppSegmentConfigSchema.safeParse({ revalidate: value }).success | ||
).toBe(false) | ||
} | ||
}) | ||
|
||
it('should support an empty config', () => { | ||
expect(AppSegmentConfigSchema.safeParse({}).success).toBe(true) | ||
}) | ||
|
||
it('should support a boolean for dynamicParams', () => { | ||
expect( | ||
AppSegmentConfigSchema.safeParse({ dynamicParams: true }).success | ||
).toBe(true) | ||
expect( | ||
AppSegmentConfigSchema.safeParse({ dynamicParams: false }).success | ||
).toBe(true) | ||
expect( | ||
AppSegmentConfigSchema.safeParse({ dynamicParams: 'foo' }).success | ||
).toBe(false) | ||
}) | ||
|
||
it('should support "auto" | "force-dynamic" | "error" | "force-static" for dynamic', () => { | ||
expect(AppSegmentConfigSchema.safeParse({ dynamic: 'auto' }).success).toBe( | ||
true | ||
) | ||
expect( | ||
AppSegmentConfigSchema.safeParse({ dynamic: 'force-dynamic' }).success | ||
).toBe(true) | ||
expect(AppSegmentConfigSchema.safeParse({ dynamic: 'error' }).success).toBe( | ||
true | ||
) | ||
expect( | ||
AppSegmentConfigSchema.safeParse({ dynamic: 'force-static' }).success | ||
).toBe(true) | ||
}) | ||
|
||
it('should support "edge" | "nodejs" for runtime', () => { | ||
expect(AppSegmentConfigSchema.safeParse({ runtime: 'edge' }).success).toBe( | ||
true | ||
) | ||
expect( | ||
AppSegmentConfigSchema.safeParse({ runtime: 'nodejs' }).success | ||
).toBe(true) | ||
expect(AppSegmentConfigSchema.safeParse({ runtime: 'foo' }).success).toBe( | ||
false | ||
) | ||
}) | ||
|
||
it('should support a positive number or zero for maxDuration', () => { | ||
expect(AppSegmentConfigSchema.safeParse({ maxDuration: 0 }).success).toBe( | ||
true | ||
) | ||
expect(AppSegmentConfigSchema.safeParse({ maxDuration: 100 }).success).toBe( | ||
true | ||
) | ||
expect(AppSegmentConfigSchema.safeParse({ maxDuration: -1 }).success).toBe( | ||
false | ||
) | ||
}) | ||
|
||
it('should support "force-cache" | "only-cache" for fetchCache', () => { | ||
expect( | ||
AppSegmentConfigSchema.safeParse({ fetchCache: 'force-cache' }).success | ||
).toBe(true) | ||
expect( | ||
AppSegmentConfigSchema.safeParse({ fetchCache: 'only-cache' }).success | ||
).toBe(true) | ||
expect( | ||
AppSegmentConfigSchema.safeParse({ fetchCache: 'foo' }).success | ||
).toBe(false) | ||
}) | ||
|
||
it('should support a string or an array of strings for preferredRegion', () => { | ||
expect( | ||
AppSegmentConfigSchema.safeParse({ preferredRegion: 'foo' }).success | ||
).toBe(true) | ||
expect( | ||
AppSegmentConfigSchema.safeParse({ preferredRegion: ['foo', 'bar'] }) | ||
.success | ||
).toBe(true) | ||
}) | ||
|
||
it('should support a boolean for experimental_ppr', () => { | ||
expect( | ||
AppSegmentConfigSchema.safeParse({ experimental_ppr: true }).success | ||
).toBe(true) | ||
expect( | ||
AppSegmentConfigSchema.safeParse({ experimental_ppr: false }).success | ||
).toBe(true) | ||
expect( | ||
AppSegmentConfigSchema.safeParse({ experimental_ppr: 'foo' }).success | ||
).toBe(false) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
import { z } from 'next/dist/compiled/zod' | ||
|
||
/** | ||
* The schema for the dynamic behavior of a page. | ||
*/ | ||
export const AppSegmentConfigDynamicSchema = z.enum([ | ||
'auto', | ||
'error', | ||
'force-static', | ||
'force-dynamic', | ||
]) | ||
|
||
/** | ||
* The dynamic behavior of the page. | ||
*/ | ||
export type AppSegmentConfigDynamic = z.infer< | ||
typeof AppSegmentConfigDynamicSchema | ||
> | ||
|
||
/** | ||
* The schema for configuration for a page. | ||
*/ | ||
export const AppSegmentConfigSchema = z.object({ | ||
/** | ||
* The number of seconds to revalidate the page or false to disable revalidation. | ||
*/ | ||
revalidate: z | ||
.union([z.number().int().nonnegative(), z.literal(false)]) | ||
.optional(), | ||
|
||
/** | ||
* Whether the page supports dynamic parameters. | ||
*/ | ||
dynamicParams: z.boolean().optional(), | ||
|
||
/** | ||
* The dynamic behavior of the page. | ||
*/ | ||
dynamic: AppSegmentConfigDynamicSchema.optional(), | ||
|
||
/** | ||
* The caching behavior of the page. | ||
*/ | ||
fetchCache: z.enum(['force-cache', 'only-cache']).optional(), | ||
|
||
/** | ||
* The preferred region for the page. | ||
*/ | ||
preferredRegion: z.union([z.string(), z.array(z.string())]).optional(), | ||
|
||
/** | ||
* Whether the page supports partial prerendering. When true, the page will be | ||
* served using partial prerendering. This setting will only take affect if | ||
* it's enabled via the `experimental.ppr = "incremental"` option. | ||
*/ | ||
experimental_ppr: z.boolean().optional(), | ||
|
||
/** | ||
* The runtime to use for the page. | ||
*/ | ||
runtime: z.enum(['edge', 'nodejs']).optional(), | ||
|
||
/** | ||
* The maximum duration for the page in seconds. | ||
*/ | ||
maxDuration: z.number().int().nonnegative().optional(), | ||
}) | ||
|
||
/** | ||
* The configuration for a page. | ||
*/ | ||
export type AppSegmentConfig = z.infer<typeof AppSegmentConfigSchema> | ||
|
||
export const AppSegmentConfigSchemaKeys = AppSegmentConfigSchema.keyof().options |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.