From db0bc5677a4262de25f20653e768b75e758c224a Mon Sep 17 00:00:00 2001 From: art-alexeyenko Date: Wed, 13 Mar 2024 14:58:15 -0400 Subject: [PATCH] [sitecore-jss-nextjs] Revert on-demand ISR --- CHANGELOG.md | 1 - .../nextjs/src/pages/api/revalidate.ts | 52 --- packages/sitecore-jss-nextjs/package.json | 2 +- packages/sitecore-jss-nextjs/revalidate.d.ts | 1 - packages/sitecore-jss-nextjs/revalidate.js | 1 - .../src/revalidate/index.ts | 1 - .../revalidate/revalidate-middleware.test.ts | 278 --------------- .../src/revalidate/revalidate-middleware.ts | 337 ------------------ packages/sitecore-jss-nextjs/tsconfig.json | 1 - packages/sitecore-jss/src/debug.ts | 1 - 10 files changed, 1 insertion(+), 674 deletions(-) delete mode 100644 packages/create-sitecore-jss/src/templates/nextjs/src/pages/api/revalidate.ts delete mode 100644 packages/sitecore-jss-nextjs/revalidate.d.ts delete mode 100644 packages/sitecore-jss-nextjs/revalidate.js delete mode 100644 packages/sitecore-jss-nextjs/src/revalidate/index.ts delete mode 100644 packages/sitecore-jss-nextjs/src/revalidate/revalidate-middleware.test.ts delete mode 100644 packages/sitecore-jss-nextjs/src/revalidate/revalidate-middleware.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index c6db4c16e7..bd137ec06a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,7 +18,6 @@ Our versioning strategy is as follows: * Handle error in the _Placeholder_ component more gracefully by using an appropriate error _JssCanActivateRedirectError_ type for redirects handling. * _JssModule.forChild_ now accepts component or component map type as a parameter. * Fixed missing guard _this_ context when calling _canActivate_ guard -* `[nextjs/template]` `[sitecore-jss-nextjs]` On-demand ISR [#1674](https://github.com/Sitecore/jss/pull/1674)) * `[sitecore-jss]` `[templates/nextjs-xmcloud]` Load the content styles for the RichText component ([#1670](https://github.com/Sitecore/jss/pull/1670))([#1683](https://github.com/Sitecore/jss/pull/1683)) ([#1684](https://github.com/Sitecore/jss/pull/1684)) ([#1693](https://github.com/Sitecore/jss/pull/1693)) * `[templates/react]` `[sitecore-jss-react]` Replace package 'deep-equal' with 'fast-deep-equal'. No functionality change only performance improvement ([#1719](https://github.com/Sitecore/jss/pull/1719)) ([#1665](https://github.com/Sitecore/jss/pull/1665)) * `[templates/nextjs-xmcloud]` `[sitecore-jss]` `[sitecore-jss-nextjs]` `[sitecore-jss-react]` Add support for loading appropriate stylesheets whenever a theme is applied to BYOC and SXA components by introducing new function getComponentLibraryStylesheetLinks, which replaces getFEAASLibraryStylesheetLinks (which has been marked as deprecated) ([#1722](https://github.com/Sitecore/jss/pull/1722)) diff --git a/packages/create-sitecore-jss/src/templates/nextjs/src/pages/api/revalidate.ts b/packages/create-sitecore-jss/src/templates/nextjs/src/pages/api/revalidate.ts deleted file mode 100644 index e9f292346f..0000000000 --- a/packages/create-sitecore-jss/src/templates/nextjs/src/pages/api/revalidate.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { RevalidateMiddleware } from '@sitecore-jss/sitecore-jss-nextjs/revalidate'; -import { NextApiResponse, NextApiRequest } from 'next'; -import clientFactory from 'lib/graphql-client-factory'; -import nextConfig from '../../../next.config'; - -/** - * Nextjs API route /api/revalidate - * This revalidate endpoint is triggered by the configured Sitecore Experience Edge Webhooks - * whenever new content is published on Sitecore which initiates On-demand Incremental - * Static Regeneration (ISR) of the updated page. - * @param req The Next.js API request object - * @param res The Next.js API response object - */ -const handler = async (req: NextApiRequest, res: NextApiResponse) => { - const { query, body } = req; - const secret = query['secret']; - const i18n = nextConfig().i18n; - - const revalidateHandler = new RevalidateMiddleware({ - clientFactory, - // override this value through your webhook payload if using multi-site add-on - multiSite: body.multiSite || false, - // override this value through your webhook payload if personalization is configured - personalize: body.personalize || false, - // Function to generate language prefix based on i18n configurations - // it returns the language itself as the prefix based on the other languages configured in next.config. - localePrefix: (language: string) => { - if (!i18n || language === i18n.defaultLocale) { - return ''; - } else { - return language; - } - }, - }).getHandler(); - - /** - NOTE: It is highly recommended to add a secret to your revalidate endpoint before going to production. - This prevents unauthorized users from triggering revalidation requests. - */ - if (process.env.ISR_REVALIDATE_SECRET) { - if (!secret || secret !== process.env.ISR_REVALIDATE_SECRET) { - console.log('Invalid secret provided. Authentication failed.'); - res.status(401).end('Invalid secret'); - } - } else { - console.log('Secret not configured. Proceeding without authentication.'); - } - - await revalidateHandler(req, res); -}; - -export default handler; diff --git a/packages/sitecore-jss-nextjs/package.json b/packages/sitecore-jss-nextjs/package.json index 77c9c6da8d..c9a64dfabd 100644 --- a/packages/sitecore-jss-nextjs/package.json +++ b/packages/sitecore-jss-nextjs/package.json @@ -11,7 +11,7 @@ "test": "mocha --require ./test/setup.js \"./src/**/*.test.ts\" \"./src/**/*.test.tsx\" --exit", "prepublishOnly": "npm run build", "coverage": "nyc npm test", - "generate-docs": "npx typedoc --plugin typedoc-plugin-markdown --readme none --out ../../ref-docs/sitecore-jss-nextjs --entryPoints src/index.ts --entryPoints src/monitoring/index.ts --entryPoints src/editing/index.ts --entryPoints src/middleware/index.ts --entryPoints src/context/index.ts --entryPoints src/utils/index.ts --entryPoints src/site/index.ts --entryPoints src/graphql/index.ts --entryPoints src/revalidate/index.ts --githubPages false" + "generate-docs": "npx typedoc --plugin typedoc-plugin-markdown --readme none --out ../../ref-docs/sitecore-jss-nextjs --entryPoints src/index.ts --entryPoints src/monitoring/index.ts --entryPoints src/editing/index.ts --entryPoints src/middleware/index.ts --entryPoints src/context/index.ts --entryPoints src/utils/index.ts --entryPoints src/site/index.ts --entryPoints src/graphql/index.ts --githubPages false" }, "engines": { "node": ">=18" diff --git a/packages/sitecore-jss-nextjs/revalidate.d.ts b/packages/sitecore-jss-nextjs/revalidate.d.ts deleted file mode 100644 index e9673f0bf4..0000000000 --- a/packages/sitecore-jss-nextjs/revalidate.d.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './types/revalidate/index'; diff --git a/packages/sitecore-jss-nextjs/revalidate.js b/packages/sitecore-jss-nextjs/revalidate.js deleted file mode 100644 index eff3460510..0000000000 --- a/packages/sitecore-jss-nextjs/revalidate.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('./dist/cjs/revalidate/index'); diff --git a/packages/sitecore-jss-nextjs/src/revalidate/index.ts b/packages/sitecore-jss-nextjs/src/revalidate/index.ts deleted file mode 100644 index f377444906..0000000000 --- a/packages/sitecore-jss-nextjs/src/revalidate/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { RevalidateMiddleware } from './revalidate-middleware'; diff --git a/packages/sitecore-jss-nextjs/src/revalidate/revalidate-middleware.test.ts b/packages/sitecore-jss-nextjs/src/revalidate/revalidate-middleware.test.ts deleted file mode 100644 index aba096f717..0000000000 --- a/packages/sitecore-jss-nextjs/src/revalidate/revalidate-middleware.test.ts +++ /dev/null @@ -1,278 +0,0 @@ -import { RevalidateMiddleware } from './revalidate-middleware'; -import { expect } from 'chai'; -import { spy, stub } from 'sinon'; -import { NextApiRequest, NextApiResponse } from 'next'; // Replace with the correct import path for your Next.js types -import { GraphQLRequestClient } from '@sitecore-jss/sitecore-jss/graphql'; -import { GraphQLPersonalizeService } from '@sitecore-jss/sitecore-jss/personalize'; - -type Query = { - [key: string]: string; -}; -const variantId_1 = 'variantId-1'; -const variantId_2 = 'variantId-2'; -const id = 'item-id'; -const version = '1'; -const contentId = `${id}_en_${version}`.toLowerCase(); - -const mockRequest = (body?: any, query?: Query, method?: string, host?: string) => { - return ({ - body: body ?? {}, - method: method ?? 'POST', - query: query ?? {}, - headers: { host: host ?? 'localhost:3000' }, - } as unknown) as NextApiRequest; -}; - -const mockResponse = () => { - const res = {} as NextApiResponse; - res.status = spy(() => { - return res; - }); - res.json = spy(() => { - return res; - }); - res.end = spy(() => { - return res; - }); - res.getHeader = spy(() => { - return undefined; - }); - res.setHeader = spy(); - res.setPreviewData = spy(() => { - return res; - }); - res.revalidate = spy(); - return res; -}; -// webhook req payload -const mockUpdatedPaths = { - updates: [ - { - identifier: 'my-site/About', - entity_definition: 'LayoutData', - operation: 'Update', - entity_culture: 'en', - }, - { - identifier: 'my-site/', - entity_definition: 'LayoutData', - operation: 'Update', - entity_culture: 'en', - }, - { - identifier: 'EAB6F7C96E4A46AEB468D93EE9420A14', - entity_definition: 'Item', - operation: 'Update', - entity_culture: 'en', - }, - ], -}; - -describe('RevalidateMiddleware', () => { - const endpoint = 'http://site'; - const apiKey = 'api-key'; - const clientFactory = GraphQLRequestClient.createClientFactory({ - endpoint, - apiKey, - }); - - const getPersonalizeInfoStub = stub(GraphQLPersonalizeService.prototype, 'getPersonalizeInfo'); - const getPersonalizedResultsStub = stub(RevalidateMiddleware.prototype, 'getPersonalizedResults'); - - describe('when personalize is true', () => { - it('should return proper paths when all pages are personalized', async () => { - const res = mockResponse(); - const req = mockRequest({ ...mockUpdatedPaths }); - - getPersonalizeInfoStub.resolves({ - contentId: contentId, - variantIds: [variantId_1, variantId_2], - }); - - getPersonalizedResultsStub.resolves({ - personalized: [ - { path: 'my-site/', variantId: variantId_1 }, - { path: 'my-site/About', variantId: variantId_2 }, - ], - nonPersonalized: [], - }); - - const middleware = new RevalidateMiddleware({ clientFactory, personalize: true }); - await middleware.getHandler()(req, res); - const pathsToRevalidate = [/_variantId_variantId-1/, '_variantId_variantId-2/About']; - - expect(res.status).to.be.calledWith(200); - expect(res.json).to.be.calledWith({ revalidated: true }); - expect(res.revalidate.callCount).to.equal(pathsToRevalidate.length); - expect(res.revalidate).to.be.calledWith(`/_variantId_${variantId_1}/`); - expect(res.revalidate).to.be.calledWith(`/_variantId_${variantId_2}/About`); - }); - - it('should return proper paths when one page is personalized and other is not', async () => { - const res = mockResponse(); - const req = mockRequest({ ...mockUpdatedPaths }); - - getPersonalizeInfoStub.resolves({ - contentId: contentId, - variantIds: [variantId_1], - }); - - getPersonalizedResultsStub.resolves({ - personalized: [{ path: 'my-site/', variantId: variantId_1 }], - nonPersonalized: [{ path: 'my-site/About' }], - }); - - const middleware = new RevalidateMiddleware({ clientFactory, personalize: true }); - await middleware.getHandler()(req, res); - const pathsToRevalidate = [/_variantId_variantId-1/, '/About']; - - expect(res.status).to.be.calledWith(200); - expect(res.json).to.be.calledWith({ revalidated: true }); - expect(res.revalidate.callCount).to.equal(pathsToRevalidate.length); - expect(res.revalidate).to.be.calledWith(`/_variantId_${variantId_1}/`); - expect(res.revalidate).to.be.calledWith('/About'); - }); - - it('should return proper paths when one page is personalized and other is non-personalized with multiSite add-on', async () => { - const res = mockResponse(); - const req = mockRequest({ ...mockUpdatedPaths }); - - getPersonalizeInfoStub.resolves({ contentId: contentId, variantIds: [variantId_1] }); - - getPersonalizedResultsStub.resolves({ - personalized: [{ path: 'my-site/', variantId: variantId_1 }], - nonPersonalized: [{ path: 'my-site/About' }], - }); - - const middleware = new RevalidateMiddleware({ - clientFactory, - personalize: true, - multiSite: true, - }); - await middleware.getHandler()(req, res); - - const pathsToRevalidate = [ - `/_variantId_${variantId_1}/_site_my-site/`, - '/_site_my-site/About', - ]; - - expect(res.status).to.be.calledWith(200); - expect(res.json).to.be.calledWith({ revalidated: true }); - expect(res.revalidate.callCount).to.equal(pathsToRevalidate.length); - expect(res.revalidate).to.be.calledWith(`/_variantId_${variantId_1}/_site_my-site/`); - expect(res.revalidate).to.be.calledWith('/_site_my-site/About'); - }); - }); - - it('should return proper paths when only multiSite is true', async () => { - const res = mockResponse(); - const req = mockRequest({ ...mockUpdatedPaths }); - - const middleware = new RevalidateMiddleware({ clientFactory, multiSite: true }); - - await middleware.getHandler()(req, res); - - expect(res.status).to.be.calledWith(200); - expect(res.json).to.be.calledWith({ revalidated: true }); - expect(res.revalidate).to.have.been.calledWithExactly('/_site_my-site/'); - expect(res.revalidate).to.have.been.calledWithExactly('/_site_my-site/About'); - }); - - it('should return proper paths when both multiSite and personalize are false', async () => { - const res = mockResponse(); - const req = mockRequest({ ...mockUpdatedPaths }); - - const middleware = new RevalidateMiddleware({ clientFactory }); - await middleware.getHandler()(req, res); - - expect(res.status).to.be.calledWith(200); - expect(res.json).to.be.calledWith({ revalidated: true }); - expect(res.revalidate).to.have.been.calledWithExactly('/'); - expect(res.revalidate).to.have.been.calledWithExactly('/About'); - }); - - it('should return proper paths when other locales are configured besides defaultLocale and got updated', async () => { - const res = mockResponse(); - const req = mockRequest({ - updates: [ - { - identifier: 'my-site/About', - entity_definition: 'LayoutData', - operation: 'Update', - entity_culture: 'fr-CA', - }, - { - identifier: 'my-site/', - entity_definition: 'LayoutData', - operation: 'Update', - entity_culture: 'fr-CA', - }, - ], - }); - - const middleware = new RevalidateMiddleware({ - clientFactory, - localePrefix: () => 'fr-CA', - }); - - await middleware.getHandler()(req, res); - - expect(res.status).to.be.calledWith(200); - expect(res.json).to.be.calledWith({ revalidated: true }); - expect(res.revalidate).to.have.been.calledWithExactly('/fr-CA/'); - expect(res.revalidate).to.have.been.calledWithExactly('/fr-CA/About'); - }); - - it('should return proper paths when only defaultLanguage is configured', async () => { - const res = mockResponse(); - const req = mockRequest({ ...mockUpdatedPaths }); - - const middleware = new RevalidateMiddleware({ - clientFactory, - localePrefix: () => '', - }); - await middleware.getHandler()(req, res); - - expect(res.status).to.be.calledWith(200); - expect(res.json).to.be.calledWith({ revalidated: true }); - expect(res.revalidate).to.have.been.calledWithExactly('/'); - expect(res.revalidate).to.have.been.calledWithExactly('/About'); - }); - - it('should return 204 when there is nothing to revalidate ', async () => { - const res = mockResponse(); - const req = mockRequest({ - updates: [], - }); - - const middleware = new RevalidateMiddleware({ clientFactory }); - await middleware.getHandler()(req, res); - - expect(res.status).to.be.calledWith(204); - expect(res.json).to.be.calledWith({ message: 'No updates to revalidate' }); - }); - - it('should throw 500 if revalidation fails', async () => { - const res = mockResponse(); - const req = mockRequest({ ...mockUpdatedPaths }); - - const middleware = new RevalidateMiddleware({ - clientFactory, - }); - - await middleware.getHandler()(req, res); - - res.revalidate = stub().throws(new Error('revalidation failed')); - - try { - await middleware.getHandler()(req, res); - expect.fail('Error revalidating'); - } catch (error) { - expect(error.message).to.equal('Error revalidating'); - - // Ensure that res.status is called with 500 in the catch block - expect(res.status).to.be.calledWith(500); - expect(res.json).calledWith({ revalidated: false }); - } - }); -}); diff --git a/packages/sitecore-jss-nextjs/src/revalidate/revalidate-middleware.ts b/packages/sitecore-jss-nextjs/src/revalidate/revalidate-middleware.ts deleted file mode 100644 index efc8c69913..0000000000 --- a/packages/sitecore-jss-nextjs/src/revalidate/revalidate-middleware.ts +++ /dev/null @@ -1,337 +0,0 @@ -import { NextApiResponse, NextApiRequest } from 'next'; -// import { I18NConfig } from 'next/dist/server/config-shared'; -import { - GraphQLPersonalizeService, - getPersonalizedRewrite, -} from '@sitecore-jss/sitecore-jss/personalize'; -import { getSiteRewrite } from '@sitecore-jss/sitecore-jss/site'; -import { GraphQLRequestClientFactory } from '@sitecore-jss/sitecore-jss/graphql'; -import { debug } from '@sitecore-jss/sitecore-jss'; - -enum EntityDefinition { - LayoutData = 'LayoutData', - Item = 'Item', -} - -/** - * Object model of each updated entity returned from the webhook payload - */ -export type Entity = { - identifier: string; - entity_definition: EntityDefinition; - operation: string; - entity_culture: string; -}; - -/** - * Object model for updated paths returned from the webhook payload - */ -export type UpdatedPaths = { - path: string; - language: string; -}; - -/** - * Object model for personalized results from GraphqlPersonalizeService - */ -export type PersonalizedResult = { - path: string; - variantId: string; -}; - -export type RevalidateConfig = { - /** - * A GraphQL Request Client Factory is a function that accepts configuration and returns an instance of a GraphQLRequestClient. - * This factory function is used to create and configure GraphQL clients for making GraphQL API requests. - */ - clientFactory: GraphQLRequestClientFactory; - /** - * Indicates whether multisite functionality is enabled. - * Default is false - */ - multiSite?: boolean; - /** - * Indicates whether personalization is enabled. - * Default is false - */ - personalize?: boolean; - /** - * Function to handle language prefixes for different locales. - * @param language - The language to generate the prefix for. - * @returns The language prefix or null. - */ - localePrefix?: (language: string) => string | null; -}; - -/** - * Middleware / handler for on-demand ISR (e.g. '/api/revalidate'). - */ -export class RevalidateMiddleware { - private personalizeService: GraphQLPersonalizeService; - - constructor(protected config: RevalidateConfig) { - this.personalizeService = new GraphQLPersonalizeService({ - clientFactory: config.clientFactory, - }); - } - - /** - * Generates a Next.js API route handler that executes a revalidation process. - * @returns The route handler function for handling Next.js API requests. - */ - public getHandler(): (req: NextApiRequest, res: NextApiResponse) => Promise { - return async (req, res) => { - try { - await this.handler(req, res); - return res.status(200).json({ revalidated: true }); - } catch (error) { - console.log('Error Revalidating:'); - console.log(error); - return res.status(500).json({ revalidated: false }); - } - }; - } - - /** - * Gets personalized results for the updated paths - * @param {UpdatedPaths[]} filteredUpdates Updated paths - */ - public async getPersonalizedResults(filteredUpdates: UpdatedPaths[]) { - const personalizedResults: PersonalizedResult[] = []; - const nonPersonalizedResults: { path: string }[] = []; - - await Promise.all( - filteredUpdates.map(async (update) => { - const siteName = this.getSiteName(update.path); - const pathName = this.getPathName(update.path); - const personalizeInfo = await this.personalizeService.getPersonalizeInfo( - pathName, - update.language, - siteName - ); - - if (personalizeInfo && personalizeInfo.variantIds.length > 0) { - personalizeInfo.variantIds.forEach((variantId: string) => { - personalizedResults.push({ - path: update.path, - variantId, - }); - }); - } else { - // Collect paths without personalized info - nonPersonalizedResults.push({ - path: update.path, - }); - } - }) - ); - - return { - personalized: personalizedResults, - nonPersonalized: nonPersonalizedResults, - }; - } - - protected isEmpty(data: UpdatedPaths[]) { - return data.length === 0; - } - - /** - * Extracts the paths from the updated paths - * @param {UpdatedPaths[]} filteredUpdates Updated paths - * @returns {string[]} paths - */ - protected extractPaths(filteredUpdates: UpdatedPaths[]): string[] { - return filteredUpdates.map((update) => update.path); - } - - /** - * Gets the site name from the path name - * @param {string} pathname Path name - * @returns {string} site name - */ - protected getSiteName(pathname: string): string { - let siteName = ''; - - const path = pathname.endsWith('/') ? pathname : pathname + '/'; - const result = path.match('(.*?)\\/'); - - if (result && result[1] !== '') { - siteName = result[1]; - } - - return siteName; - } - - /** - * Gets the path name from the full path - * @param {string} fullPath Full path - * @returns {string} path name - */ - protected getPathName(fullPath: string): string { - const pathParts = fullPath.split('/').filter((part) => part !== ''); - - if (pathParts.length >= 2) { - const siteName = `/${pathParts[0]}/`; - const path = `/${pathParts.slice(1).join('/')}`; - return path.startsWith(siteName) ? path.slice(siteName.length) : path; - } - - return '/'; - } - - protected extractSiteName(path: string): string { - const siteName: string = path.split('/')[0]; - return siteName; - } - - /** - * Filters out the updated paths and language from the request body - * @param {NextApiRequest} req Next.js API request - * @returns {UpdatedPaths[]} updated paths - */ - protected getFilteredUpdates(req: NextApiRequest): UpdatedPaths[] { - if (!req.body?.updates || this.isEmpty(req.body.updates)) { - return []; - } - - return req.body?.updates - .filter( - (update: Entity) => - update.entity_definition === EntityDefinition.LayoutData && update.entity_culture - ) - .map((update: Entity) => { - if (update.identifier === 'website/') { - return null; - } - - return { - path: update.identifier, - language: update.entity_culture, - }; - }) - .filter(Boolean); - } - - protected handleMultiSitePersonalization( - personalizeInfo: { - personalized: PersonalizedResult[]; - nonPersonalized: { - path: string; - }[]; - }, - pathsToRevalidate: string[], - getPathName: (x: string) => string, - getSiteName: (x: string) => string - ) { - if (personalizeInfo.personalized.length > 0) { - const personalizedRewrite = personalizeInfo.personalized.map((info) => { - return getPersonalizedRewrite( - getSiteRewrite(getPathName(info.path), { siteName: getSiteName(info.path) }), - { - variantId: info.variantId, - } - ); - }); - pathsToRevalidate.push(...personalizedRewrite); - } - - if (personalizeInfo.nonPersonalized.length > 0) { - const nonPersonalizedRewrite = personalizeInfo.nonPersonalized.map((info) => { - return getSiteRewrite(getPathName(info.path), { - siteName: getSiteName(info.path), - }); - }); - pathsToRevalidate.push(...nonPersonalizedRewrite); - } - } - - protected handleNonMultiSitePersonalization( - personalizeInfo: { - personalized: PersonalizedResult[]; - nonPersonalized: { - path: string; - }[]; - }, - pathsToRevalidate: string[], - getPathName: (x: string) => string - ) { - const nonMultiSitePersonalizedRewrite = personalizeInfo.personalized.map((info) => { - return getPersonalizedRewrite(getPathName(info.path), { variantId: info.variantId }); - }); - - const nonMultiSiteNonPersonalizedRewrite = personalizeInfo.nonPersonalized.map((info) => { - return this.getPathName(info.path); - }); - - pathsToRevalidate.push( - ...nonMultiSitePersonalizedRewrite, - ...nonMultiSiteNonPersonalizedRewrite - ); - } - - private handler = async (req: NextApiRequest, res: NextApiResponse): Promise => { - // filter out updated paths and language from request.body - const filteredUpdates = this.getFilteredUpdates(req); - - if (this.isEmpty(filteredUpdates)) { - // nothing to revalidate - return res.status(204).json({ message: 'No updates to revalidate' }); - } - - // extract only paths from filtered updates object - const paths = this.extractPaths(filteredUpdates); - - const pathsToRevalidate: string[] = []; - - // when personalization is configured and when both multiSite and personalization are configured - if (this.config.personalize) { - const personalizeInfo = await this.getPersonalizedResults(filteredUpdates); - - if (this.config.multiSite) { - this.handleMultiSitePersonalization( - personalizeInfo, - pathsToRevalidate, - this.getPathName, - this.getSiteName - ); - } else { - this.handleNonMultiSitePersonalization( - personalizeInfo, - pathsToRevalidate, - this.getPathName - ); - } - } - - // when only multiSite is configured - if (this.config.multiSite && !this.config.personalize) { - const multiSitePaths = paths.map((path: string) => - getSiteRewrite(this.getPathName(path), { siteName: this.getSiteName(path) }) - ); - pathsToRevalidate.push(...multiSitePaths); - } - - // when both multiSite and personalization are not configured - if (!this.config.multiSite && !this.config.personalize) { - const defaultPaths = paths.map((path: string) => this.getPathName(path)); - pathsToRevalidate.push(...defaultPaths); - } - - // when other locales are configured besides defaultLocale - if (!this.isEmpty(filteredUpdates)) { - const filteredLanguage = [...new Set(filteredUpdates.map(({ language }) => language))].join( - ',' - ); - if (this.config.localePrefix) { - const language = this.config.localePrefix(filteredLanguage); - if (language) { - await Promise.all(pathsToRevalidate.map((path) => res.revalidate(`/${language}` + path))); - } - } - } - - await Promise.all(pathsToRevalidate.map((path) => res.revalidate(path))); - debug.revalidate(`revalidated paths: ${pathsToRevalidate.join(', ')}`); - }; -} diff --git a/packages/sitecore-jss-nextjs/tsconfig.json b/packages/sitecore-jss-nextjs/tsconfig.json index b83e14b665..9d2cf9eaff 100644 --- a/packages/sitecore-jss-nextjs/tsconfig.json +++ b/packages/sitecore-jss-nextjs/tsconfig.json @@ -18,7 +18,6 @@ "middleware.d.ts", "editing.d.ts", "monitoring.d.ts", - "revalidate.d.ts", "site.d.ts", "graphql.d.ts", "utils.d.ts", diff --git a/packages/sitecore-jss/src/debug.ts b/packages/sitecore-jss/src/debug.ts index b758c34b2d..83e87a34b9 100644 --- a/packages/sitecore-jss/src/debug.ts +++ b/packages/sitecore-jss/src/debug.ts @@ -39,5 +39,4 @@ export default { redirects: debug(`${rootNamespace}:redirects`), personalize: debug(`${rootNamespace}:personalize`), errorpages: debug(`${rootNamespace}:errorpages`), - revalidate: debug(`${rootNamespace}:revalidate`), };