Skip to content

Commit

Permalink
Add generated types for each configured profile
Browse files Browse the repository at this point in the history
  • Loading branch information
sebmarkbage committed Oct 14, 2024
1 parent 58be5bb commit ad57736
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 2 deletions.
1 change: 1 addition & 0 deletions packages/next/src/build/webpack-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1931,6 +1931,7 @@ export default async function getBaseWebpackConfig(
isEdgeServer,
pageExtensions: config.pageExtensions,
typedRoutes: enableTypedRoutes,
cacheLifeConfig: config.experimental.cacheLife,
originalRewrites,
originalRedirects,
}),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ describe('next-types-plugin', () => {
isEdgeServer: false,
pageExtensions: ['tsx', 'ts', 'jsx', 'js'],
typedRoutes: false,
cacheLifeConfig: undefined,
originalRewrites: undefined,
originalRedirects: undefined,
})
Expand Down Expand Up @@ -40,6 +41,7 @@ describe('next-types-plugin', () => {
isEdgeServer: false,
pageExtensions: ['tsx', 'ts', 'jsx', 'js'],
typedRoutes: false,
cacheLifeConfig: undefined,
originalRewrites: undefined,
originalRedirects: undefined,
})
Expand All @@ -60,6 +62,7 @@ describe('next-types-plugin', () => {
isEdgeServer: false,
pageExtensions: ['tsx', 'ts', 'jsx', 'js'],
typedRoutes: false,
cacheLifeConfig: undefined,
originalRewrites: undefined,
originalRedirects: undefined,
})
Expand Down
49 changes: 49 additions & 0 deletions packages/next/src/build/webpack/plugins/next-types-plugin/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { getPageFromPath } from '../../../entries'
import type { PageExtensions } from '../../../page-extensions-type'
import { devPageFiles } from './shared'
import { getProxiedPluginState } from '../../../build-context'
import type { CacheLife } from '../../../../server/use-cache/cache-life'

const PLUGIN_NAME = 'NextTypesPlugin'

Expand All @@ -34,6 +35,7 @@ interface Options {
isEdgeServer: boolean
pageExtensions: PageExtensions
typedRoutes: boolean
cacheLifeConfig: undefined | { [profile: string]: CacheLife }
originalRewrites: Rewrites | undefined
originalRedirects: Redirect[] | undefined
}
Expand Down Expand Up @@ -525,6 +527,40 @@ declare module 'next/form' {
`
}

function createCustomCacheLifeDefinitions(cacheLife: {
[profile: string]: CacheLife
}) {
const profiles = Object.keys(cacheLife)
if (!profiles.includes('default')) {
profiles.push('default')
}
for (let i = 0; i < profiles.length; i++) {
profiles[i] = JSON.stringify(profiles[i])
}

// TODO: Annotate each option with their expanded values for IDE support.
const profilesEnum = profiles.join(' | ')

// Redefine the cacheLife() accepted arguments.
return `// Type definitions for Next.js cacheLife configs
declare module 'next/cache' {
export { unstable_cache } from 'next/dist/server/web/spec-extension/unstable-cache'
export {
revalidateTag,
revalidatePath,
} from 'next/dist/server/web/spec-extension/revalidate'
export { unstable_noStore } from 'next/dist/server/web/spec-extension/unstable-no-store'
import type { CacheLife } from 'next/dist/server/use-cache/cache-life'
export function unstable_cacheLife(profile: ${profilesEnum} | CacheLife): void
export { cacheTag as unstable_cacheTag } from 'next/dist/server/use-cache/cache-tag'
}
`
}

const appTypesBasePath = path.join('types', 'app')

export class NextTypesPlugin {
Expand All @@ -536,6 +572,7 @@ export class NextTypesPlugin {
pageExtensions: string[]
pagesDir: string
typedRoutes: boolean
cacheLifeConfig: undefined | { [profile: string]: CacheLife }
distDirAbsolutePath: string

constructor(options: Options) {
Expand All @@ -547,6 +584,7 @@ export class NextTypesPlugin {
this.pageExtensions = options.pageExtensions
this.pagesDir = path.join(this.appDir, '..', 'pages')
this.typedRoutes = options.typedRoutes
this.cacheLifeConfig = options.cacheLifeConfig
this.distDirAbsolutePath = path.join(this.dir, this.distDir)
if (this.typedRoutes && !redirectsRewritesTypesProcessed) {
redirectsRewritesTypesProcessed = true
Expand Down Expand Up @@ -780,6 +818,17 @@ export class NextTypesPlugin {
) as unknown as webpack.sources.RawSource
}

if (this.cacheLifeConfig) {
const cacheLifeAssetPath = path.join(
assetDirRelative,
'types/cache-life.d.ts'
)

assets[cacheLifeAssetPath] = new sources.RawSource(
createCustomCacheLifeDefinitions(this.cacheLifeConfig)
) as unknown as webpack.sources.RawSource
}

callback()
}
)
Expand Down
2 changes: 1 addition & 1 deletion packages/next/src/server/use-cache/cache-life.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export type CacheLife = {
// The default revalidates relatively frequently but doesn't expire to ensure it's always
// able to serve fast results but by default doesn't hang.

type CacheLifeProfiles = 'default' // TODO: Generate from the config
type CacheLifeProfiles = 'default' // This gets overridden by the next-types-plugin

function validateCacheLife(profile: CacheLife) {
if (profile.stale !== undefined) {
Expand Down
2 changes: 1 addition & 1 deletion test/e2e/app-dir/use-cache/app/cache-life/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { unstable_cacheLife as cacheLife } from 'next/cache'

async function getCachedRandom() {
'use cache'
cacheLife('frequent' as any) // TODO: Generate types
cacheLife('frequent')
return Math.random()
}

Expand Down

0 comments on commit ad57736

Please sign in to comment.