From 816d60582180c8e5d4e651b9ab4ee0758109977f Mon Sep 17 00:00:00 2001
From: Steven
Date: Tue, 2 May 2023 11:00:14 -0400
Subject: [PATCH 1/5] chore: rename draft mode enabled to isEnabled
---
packages/next/src/client/components/headers.ts | 4 ++--
packages/next/src/server/async-storage/draft-mode.ts | 4 ++--
packages/next/types/index.d.ts | 2 +-
test/e2e/app-dir/draft-mode/app/page.tsx | 4 ++--
test/e2e/app-dir/draft-mode/app/state/route.ts | 4 ++--
test/e2e/app-dir/draft-mode/app/with-edge/page.tsx | 4 ++--
test/e2e/app-dir/draft-mode/app/with-edge/state/route.ts | 4 ++--
test/e2e/app-dir/hooks/app/hooks/use-draft-mode/page.js | 4 ++--
8 files changed, 15 insertions(+), 15 deletions(-)
diff --git a/packages/next/src/client/components/headers.ts b/packages/next/src/client/components/headers.ts
index 388d768d2067..48bde0d4907c 100644
--- a/packages/next/src/client/components/headers.ts
+++ b/packages/next/src/client/components/headers.ts
@@ -57,8 +57,8 @@ export function draftMode(): DraftMode {
)
}
return {
- get enabled() {
- return requestStore.draftMode.enabled
+ get isEnabled() {
+ return requestStore.draftMode.isEnabled
},
enable() {
if (staticGenerationBailout('draftMode().enable()')) {
diff --git a/packages/next/src/server/async-storage/draft-mode.ts b/packages/next/src/server/async-storage/draft-mode.ts
index e3f3f82b8fdc..edf451338740 100644
--- a/packages/next/src/server/async-storage/draft-mode.ts
+++ b/packages/next/src/server/async-storage/draft-mode.ts
@@ -11,7 +11,7 @@ import {
} from '../api-utils'
export class DraftMode {
- public readonly enabled: boolean
+ public readonly isEnabled: boolean
private readonly previewModeId: string | undefined
@@ -29,7 +29,7 @@ export class DraftMode {
const cookieValue = this.cookies.get(COOKIE_NAME_PRERENDER_BYPASS)?.value
- this.enabled = Boolean(
+ this.isEnabled = Boolean(
!isOnDemandRevalidate &&
cookieValue &&
previewProps &&
diff --git a/packages/next/types/index.d.ts b/packages/next/types/index.d.ts
index 9942b6c11842..152e85800abc 100644
--- a/packages/next/types/index.d.ts
+++ b/packages/next/types/index.d.ts
@@ -146,7 +146,7 @@ export type DraftMode = {
* Get the current value of Draft Mode.
* True when enabled, false when disabled.
*/
- enabled: boolean
+ isEnabled: boolean
/**
* Set the value of Draft Mode to true.
*/
diff --git a/test/e2e/app-dir/draft-mode/app/page.tsx b/test/e2e/app-dir/draft-mode/app/page.tsx
index aa408718d721..65b59b64e32a 100644
--- a/test/e2e/app-dir/draft-mode/app/page.tsx
+++ b/test/e2e/app-dir/draft-mode/app/page.tsx
@@ -2,7 +2,7 @@ import React from 'react'
import { draftMode } from 'next/headers'
export default function Page() {
- const { enabled } = draftMode()
+ const { isEnabled } = draftMode()
return (
<>
@@ -11,7 +11,7 @@ export default function Page() {
Random: {Math.random()}
- State: {enabled ? 'ENABLED' : 'DISABLED'}
+ State: {isEnabled ? 'ENABLED' : 'DISABLED'}
>
)
diff --git a/test/e2e/app-dir/draft-mode/app/state/route.ts b/test/e2e/app-dir/draft-mode/app/state/route.ts
index c4081345262d..c5568ed06b89 100644
--- a/test/e2e/app-dir/draft-mode/app/state/route.ts
+++ b/test/e2e/app-dir/draft-mode/app/state/route.ts
@@ -1,6 +1,6 @@
import { draftMode } from 'next/headers'
export function GET() {
- const { enabled } = draftMode()
- return new Response(enabled ? 'ENABLED' : 'DISABLED')
+ const { isEnabled } = draftMode()
+ return new Response(isEnabled ? 'ENABLED' : 'DISABLED')
}
diff --git a/test/e2e/app-dir/draft-mode/app/with-edge/page.tsx b/test/e2e/app-dir/draft-mode/app/with-edge/page.tsx
index 84b5fb6f099d..bdcd910fa793 100644
--- a/test/e2e/app-dir/draft-mode/app/with-edge/page.tsx
+++ b/test/e2e/app-dir/draft-mode/app/with-edge/page.tsx
@@ -4,7 +4,7 @@ import { draftMode } from 'next/headers'
export const runtime = 'experimental-edge'
export default function Page() {
- const { enabled } = draftMode()
+ const { isEnabled } = draftMode()
return (
<>
@@ -13,7 +13,7 @@ export default function Page() {
Random: {Math.random()}
- State: {enabled ? 'ENABLED' : 'DISABLED'}
+ State: {isEnabled ? 'ENABLED' : 'DISABLED'}
>
)
diff --git a/test/e2e/app-dir/draft-mode/app/with-edge/state/route.ts b/test/e2e/app-dir/draft-mode/app/with-edge/state/route.ts
index 50426a2ec42c..04083518e8b6 100644
--- a/test/e2e/app-dir/draft-mode/app/with-edge/state/route.ts
+++ b/test/e2e/app-dir/draft-mode/app/with-edge/state/route.ts
@@ -3,6 +3,6 @@ import { draftMode } from 'next/headers'
export const runtime = 'edge'
export function GET() {
- const { enabled } = draftMode()
- return new Response(enabled ? 'ENABLED' : 'DISABLED')
+ const { isEnabled } = draftMode()
+ return new Response(isEnabled ? 'ENABLED' : 'DISABLED')
}
diff --git a/test/e2e/app-dir/hooks/app/hooks/use-draft-mode/page.js b/test/e2e/app-dir/hooks/app/hooks/use-draft-mode/page.js
index 141d1afc7320..bf91e2ee399f 100644
--- a/test/e2e/app-dir/hooks/app/hooks/use-draft-mode/page.js
+++ b/test/e2e/app-dir/hooks/app/hooks/use-draft-mode/page.js
@@ -1,7 +1,7 @@
import { draftMode } from 'next/headers'
export default function Page() {
- const { enabled } = draftMode()
+ const { isEnabled } = draftMode()
return (
<>
@@ -9,7 +9,7 @@ export default function Page() {
Rand: {Math.random()}
- {enabled ? 'ENABLED' : 'DISABLED'}
+ {isEnabled ? 'ENABLED' : 'DISABLED'}
>
)
}
From 8ac63c843df8b70a01ddbb183be2b786e9109e91 Mon Sep 17 00:00:00 2001
From: Steven
Date: Tue, 2 May 2023 11:12:22 -0400
Subject: [PATCH 2/5] Fix a test
---
test/e2e/app-dir/app-static/app-static.test.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/test/e2e/app-dir/app-static/app-static.test.ts b/test/e2e/app-dir/app-static/app-static.test.ts
index 4496c3e3c55d..035028afb954 100644
--- a/test/e2e/app-dir/app-static/app-static.test.ts
+++ b/test/e2e/app-dir/app-static/app-static.test.ts
@@ -1327,7 +1327,7 @@ createNextDescribe(
.elementByCss('#draft-mode')
.text()
- expect(content).toBe('{"result":{"enabled":false}}')
+ expect(content).toBe('{"result":{"isEnabled":false}}')
})
it('should force SSR correctly for headers usage', async () => {
From e93527d5512a5b4b3385b6834a78344b3ded8d9f Mon Sep 17 00:00:00 2001
From: Steven
Date: Tue, 2 May 2023 13:27:01 -0400
Subject: [PATCH 3/5] Use a class instead
---
.../next/src/client/components/draft-mode.ts | 24 +++++++++++++++++++
.../next/src/client/components/headers.ts | 22 +++--------------
.../components/request-async-storage.ts | 4 ++--
.../{draft-mode.ts => draft-mode-provider.ts} | 24 ++++++++++---------
.../request-async-storage-wrapper.ts | 6 ++---
packages/next/types/index.d.ts | 16 -------------
6 files changed, 45 insertions(+), 51 deletions(-)
create mode 100644 packages/next/src/client/components/draft-mode.ts
rename packages/next/src/server/async-storage/{draft-mode.ts => draft-mode-provider.ts} (79%)
diff --git a/packages/next/src/client/components/draft-mode.ts b/packages/next/src/client/components/draft-mode.ts
new file mode 100644
index 000000000000..f0de773578ce
--- /dev/null
+++ b/packages/next/src/client/components/draft-mode.ts
@@ -0,0 +1,24 @@
+import { RequestStore } from './request-async-storage'
+import { staticGenerationBailout } from './static-generation-bailout'
+
+export class DraftMode {
+ #requestStore: RequestStore
+ constructor(requestStore: RequestStore) {
+ this.#requestStore = requestStore
+ }
+ get isEnabled() {
+ return this.#requestStore.draftMode.isEnabled
+ }
+ public enable() {
+ if (staticGenerationBailout('draftMode().enable()')) {
+ return
+ }
+ return this.#requestStore.draftMode.enable()
+ }
+ public disable() {
+ if (staticGenerationBailout('draftMode().disable()')) {
+ return
+ }
+ return this.#requestStore.draftMode.disable()
+ }
+}
diff --git a/packages/next/src/client/components/headers.ts b/packages/next/src/client/components/headers.ts
index 48bde0d4907c..650849d95d69 100644
--- a/packages/next/src/client/components/headers.ts
+++ b/packages/next/src/client/components/headers.ts
@@ -7,7 +7,7 @@ import { RequestCookies } from '../../server/web/spec-extension/cookies'
import { requestAsyncStorage } from './request-async-storage'
import { actionAsyncStorage } from './action-async-storage'
import { staticGenerationBailout } from './static-generation-bailout'
-import { DraftMode } from '../../../types'
+import { DraftMode } from './draft-mode'
export function headers() {
if (staticGenerationBailout('headers')) {
@@ -49,28 +49,12 @@ export function cookies() {
return requestStore.cookies
}
-export function draftMode(): DraftMode {
+export function draftMode() {
const requestStore = requestAsyncStorage.getStore()
if (!requestStore) {
throw new Error(
`Invariant: Method expects to have requestAsyncStorage, none available`
)
}
- return {
- get isEnabled() {
- return requestStore.draftMode.isEnabled
- },
- enable() {
- if (staticGenerationBailout('draftMode().enable()')) {
- return
- }
- return requestStore.draftMode.enable()
- },
- disable() {
- if (staticGenerationBailout('draftMode().disable()')) {
- return
- }
- return requestStore.draftMode.disable()
- },
- }
+ return new DraftMode(requestStore)
}
diff --git a/packages/next/src/client/components/request-async-storage.ts b/packages/next/src/client/components/request-async-storage.ts
index d2879e12c6b0..a8a71c790662 100644
--- a/packages/next/src/client/components/request-async-storage.ts
+++ b/packages/next/src/client/components/request-async-storage.ts
@@ -1,6 +1,6 @@
import type { AsyncLocalStorage } from 'async_hooks'
+import type { DraftModeProvider } from '../../server/async-storage/draft-mode-provider'
import type { ResponseCookies } from '../../server/web/spec-extension/cookies'
-import type { DraftMode } from '../../../types'
import type { ReadonlyHeaders } from '../../server/web/spec-extension/adapters/headers'
import type { ReadonlyRequestCookies } from '../../server/web/spec-extension/adapters/request-cookies'
@@ -10,7 +10,7 @@ export interface RequestStore {
readonly headers: ReadonlyHeaders
readonly cookies: ReadonlyRequestCookies
readonly mutableCookies: ResponseCookies
- readonly draftMode: DraftMode
+ readonly draftMode: DraftModeProvider
}
export type RequestAsyncStorage = AsyncLocalStorage
diff --git a/packages/next/src/server/async-storage/draft-mode.ts b/packages/next/src/server/async-storage/draft-mode-provider.ts
similarity index 79%
rename from packages/next/src/server/async-storage/draft-mode.ts
rename to packages/next/src/server/async-storage/draft-mode-provider.ts
index edf451338740..eb1d343cd8ab 100644
--- a/packages/next/src/server/async-storage/draft-mode.ts
+++ b/packages/next/src/server/async-storage/draft-mode-provider.ts
@@ -10,16 +10,17 @@ import {
__ApiPreviewProps,
} from '../api-utils'
-export class DraftMode {
+export class DraftModeProvider {
public readonly isEnabled: boolean
- private readonly previewModeId: string | undefined
+ #previewModeId: string | undefined
+ #mutableCookies: ResponseCookies
constructor(
previewProps: __ApiPreviewProps | undefined,
req: IncomingMessage | BaseNextRequest | NextRequest,
- private readonly cookies: ReadonlyRequestCookies,
- private readonly mutableCookies: ResponseCookies
+ cookies: ReadonlyRequestCookies,
+ mutableCookies: ResponseCookies
) {
// The logic for draftMode() is very similar to tryGetPreviewData()
// but Draft Mode does not have any data associated with it.
@@ -27,7 +28,7 @@ export class DraftMode {
previewProps &&
checkIsOnDemandRevalidate(req, previewProps).isOnDemandRevalidate
- const cookieValue = this.cookies.get(COOKIE_NAME_PRERENDER_BYPASS)?.value
+ const cookieValue = cookies.get(COOKIE_NAME_PRERENDER_BYPASS)?.value
this.isEnabled = Boolean(
!isOnDemandRevalidate &&
@@ -36,19 +37,20 @@ export class DraftMode {
cookieValue === previewProps.previewModeId
)
- this.previewModeId = previewProps?.previewModeId
+ this.#previewModeId = previewProps?.previewModeId
+ this.#mutableCookies = mutableCookies
}
enable() {
- if (!this.previewModeId) {
+ if (!this.#previewModeId) {
throw new Error(
- 'Invariant: previewProps missing previewModeId this should not be hit'
+ 'Invariant: previewProps missing previewModeId this should never happen'
)
}
- this.mutableCookies.set({
+ this.#mutableCookies.set({
name: COOKIE_NAME_PRERENDER_BYPASS,
- value: this.previewModeId,
+ value: this.#previewModeId,
httpOnly: true,
sameSite: process.env.NODE_ENV !== 'development' ? 'none' : 'lax',
secure: process.env.NODE_ENV !== 'development',
@@ -60,7 +62,7 @@ export class DraftMode {
// To delete a cookie, set `expires` to a date in the past:
// https://tools.ietf.org/html/rfc6265#section-4.1.1
// `Max-Age: 0` is not valid, thus ignored, and the cookie is persisted.
- this.mutableCookies.set({
+ this.#mutableCookies.set({
name: COOKIE_NAME_PRERENDER_BYPASS,
value: '',
httpOnly: true,
diff --git a/packages/next/src/server/async-storage/request-async-storage-wrapper.ts b/packages/next/src/server/async-storage/request-async-storage-wrapper.ts
index 860de534258a..4d91f7f77806 100644
--- a/packages/next/src/server/async-storage/request-async-storage-wrapper.ts
+++ b/packages/next/src/server/async-storage/request-async-storage-wrapper.ts
@@ -18,7 +18,7 @@ import {
} from '../web/spec-extension/adapters/request-cookies'
import { RequestCookies, ResponseCookies } from '../web/spec-extension/cookies'
import { __ApiPreviewProps } from '../api-utils'
-import { DraftMode } from './draft-mode'
+import { DraftModeProvider } from './draft-mode-provider'
function getHeaders(headers: Headers | IncomingHttpHeaders): ReadonlyHeaders {
const cleaned = HeadersAdapter.from(headers)
@@ -79,7 +79,7 @@ export const RequestAsyncStorageWrapper: AsyncStorageWrapper<
headers?: ReadonlyHeaders
cookies?: ReadonlyRequestCookies
mutableCookies?: ResponseCookies
- draftMode?: DraftMode
+ draftMode?: DraftModeProvider
} = {}
const store: RequestStore = {
@@ -109,7 +109,7 @@ export const RequestAsyncStorageWrapper: AsyncStorageWrapper<
},
get draftMode() {
if (!cache.draftMode) {
- cache.draftMode = new DraftMode(
+ cache.draftMode = new DraftModeProvider(
previewProps,
req,
this.cookies,
diff --git a/packages/next/types/index.d.ts b/packages/next/types/index.d.ts
index 152e85800abc..297e169cd2b7 100644
--- a/packages/next/types/index.d.ts
+++ b/packages/next/types/index.d.ts
@@ -141,22 +141,6 @@ export {
export type PreviewData = string | false | object | undefined
-export type DraftMode = {
- /**
- * Get the current value of Draft Mode.
- * True when enabled, false when disabled.
- */
- isEnabled: boolean
- /**
- * Set the value of Draft Mode to true.
- */
- enable: () => void
- /**
- * Set the value of Draft Mode to false.
- */
- disable: () => void
-}
-
/**
* Context object passed into `getStaticProps`.
* @link https://nextjs.org/docs/api-reference/data-fetching/get-static-props#context-parameter
From 0311f217633fa27f09c590fa4c21e93d5d856dd1 Mon Sep 17 00:00:00 2001
From: Steven
Date: Tue, 2 May 2023 13:57:24 -0400
Subject: [PATCH 4/5] Fix test
---
test/e2e/app-dir/app-static/app-static.test.ts | 2 +-
.../app-static/app/ssg-draft-mode/[[...route]]/page.js | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/test/e2e/app-dir/app-static/app-static.test.ts b/test/e2e/app-dir/app-static/app-static.test.ts
index 9b55397fb871..a0e1f8a6759c 100644
--- a/test/e2e/app-dir/app-static/app-static.test.ts
+++ b/test/e2e/app-dir/app-static/app-static.test.ts
@@ -1356,7 +1356,7 @@ createNextDescribe(
.elementByCss('#draft-mode')
.text()
- expect(content).toBe('{"result":{"isEnabled":false}}')
+ expect(content).toBe('{"isEnabled":false}')
})
it('should force SSR correctly for headers usage', async () => {
diff --git a/test/e2e/app-dir/app-static/app/ssg-draft-mode/[[...route]]/page.js b/test/e2e/app-dir/app-static/app/ssg-draft-mode/[[...route]]/page.js
index 13a7ce2660f6..ad91464d34d6 100644
--- a/test/e2e/app-dir/app-static/app/ssg-draft-mode/[[...route]]/page.js
+++ b/test/e2e/app-dir/app-static/app/ssg-draft-mode/[[...route]]/page.js
@@ -1,11 +1,11 @@
import { draftMode } from 'next/headers'
export default function Page() {
- const result = draftMode()
+ const { isEnabled } = draftMode()
return (
- {JSON.stringify({ result })}
+ {JSON.stringify({ isEnabled })}
)
}
From 65f4000ee207f0b4933897621efcf0083bd7897b Mon Sep 17 00:00:00 2001
From: Steven
Date: Tue, 2 May 2023 14:52:48 -0400
Subject: [PATCH 5/5] Swtich from js private to ts private
---
.../next/src/client/components/draft-mode.ts | 18 +++++++++------
.../next/src/client/components/headers.ts | 2 +-
.../async-storage/draft-mode-provider.ts | 23 ++++++++++++-------
3 files changed, 27 insertions(+), 16 deletions(-)
diff --git a/packages/next/src/client/components/draft-mode.ts b/packages/next/src/client/components/draft-mode.ts
index f0de773578ce..b1af9a4c2d7b 100644
--- a/packages/next/src/client/components/draft-mode.ts
+++ b/packages/next/src/client/components/draft-mode.ts
@@ -1,24 +1,28 @@
-import { RequestStore } from './request-async-storage'
+import { DraftModeProvider } from '../../server/async-storage/draft-mode-provider'
import { staticGenerationBailout } from './static-generation-bailout'
export class DraftMode {
- #requestStore: RequestStore
- constructor(requestStore: RequestStore) {
- this.#requestStore = requestStore
+ /**
+ * @internal - this declaration is stripped via `tsc --stripInternal`
+ */
+ private readonly _provider: DraftModeProvider
+
+ constructor(provider: DraftModeProvider) {
+ this._provider = provider
}
get isEnabled() {
- return this.#requestStore.draftMode.isEnabled
+ return this._provider.isEnabled
}
public enable() {
if (staticGenerationBailout('draftMode().enable()')) {
return
}
- return this.#requestStore.draftMode.enable()
+ return this._provider.enable()
}
public disable() {
if (staticGenerationBailout('draftMode().disable()')) {
return
}
- return this.#requestStore.draftMode.disable()
+ return this._provider.disable()
}
}
diff --git a/packages/next/src/client/components/headers.ts b/packages/next/src/client/components/headers.ts
index 650849d95d69..2b239c9b8763 100644
--- a/packages/next/src/client/components/headers.ts
+++ b/packages/next/src/client/components/headers.ts
@@ -56,5 +56,5 @@ export function draftMode() {
`Invariant: Method expects to have requestAsyncStorage, none available`
)
}
- return new DraftMode(requestStore)
+ return new DraftMode(requestStore.draftMode)
}
diff --git a/packages/next/src/server/async-storage/draft-mode-provider.ts b/packages/next/src/server/async-storage/draft-mode-provider.ts
index eb1d343cd8ab..06138db7dd16 100644
--- a/packages/next/src/server/async-storage/draft-mode-provider.ts
+++ b/packages/next/src/server/async-storage/draft-mode-provider.ts
@@ -13,8 +13,15 @@ import {
export class DraftModeProvider {
public readonly isEnabled: boolean
- #previewModeId: string | undefined
- #mutableCookies: ResponseCookies
+ /**
+ * @internal - this declaration is stripped via `tsc --stripInternal`
+ */
+ private readonly _previewModeId: string | undefined
+
+ /**
+ * @internal - this declaration is stripped via `tsc --stripInternal`
+ */
+ private readonly _mutableCookies: ResponseCookies
constructor(
previewProps: __ApiPreviewProps | undefined,
@@ -37,20 +44,20 @@ export class DraftModeProvider {
cookieValue === previewProps.previewModeId
)
- this.#previewModeId = previewProps?.previewModeId
- this.#mutableCookies = mutableCookies
+ this._previewModeId = previewProps?.previewModeId
+ this._mutableCookies = mutableCookies
}
enable() {
- if (!this.#previewModeId) {
+ if (!this._previewModeId) {
throw new Error(
'Invariant: previewProps missing previewModeId this should never happen'
)
}
- this.#mutableCookies.set({
+ this._mutableCookies.set({
name: COOKIE_NAME_PRERENDER_BYPASS,
- value: this.#previewModeId,
+ value: this._previewModeId,
httpOnly: true,
sameSite: process.env.NODE_ENV !== 'development' ? 'none' : 'lax',
secure: process.env.NODE_ENV !== 'development',
@@ -62,7 +69,7 @@ export class DraftModeProvider {
// To delete a cookie, set `expires` to a date in the past:
// https://tools.ietf.org/html/rfc6265#section-4.1.1
// `Max-Age: 0` is not valid, thus ignored, and the cookie is persisted.
- this.#mutableCookies.set({
+ this._mutableCookies.set({
name: COOKIE_NAME_PRERENDER_BYPASS,
value: '',
httpOnly: true,