UNPKG

next-page-tester

Version:
118 lines (117 loc) 4.76 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const makeContextObject_1 = require("./makeContextObject"); const server_1 = require("../server"); const _error_1 = require("../_error"); const constants_1 = require("../constants"); function ensureNoMultipleDataFetchingMethods({ page, }) { let methodsCounter = 0; if (page.getServerSideProps) { methodsCounter++; } if (page.getStaticProps) { methodsCounter++; } if (page.default.getInitialProps) { methodsCounter++; } if (methodsCounter > 1) { throw new _error_1.InternalError('Only one data fetching method is allowed'); } } // Pages' fetching methods may return "notFound" and "redirect" object function ensurePageDataHasProps({ pageData, }) { const allowedKeys = ['props', 'redirect', 'notFound']; for (const key of allowedKeys) { if (key in pageData) { return; } } const errorMessage = `[next-page-tester] Page's fetching method returned an object with unsupported fields. Supported fields are: "[${allowedKeys.join(', ')}]". Returned value is available in error.payload.`; const error = new Error(errorMessage); error.payload = pageData; throw error; } function mergePageDataWithAppData({ pageData, appInitialProps, }) { const { props: pageProps, ...restOfPageData } = pageData; const { pageProps: appPageProps, ...restOfAppInitialProps } = appInitialProps || {}; //appInitialProps.pageProps gets merged with pageData.props return { props: { ...appPageProps, ...pageProps, }, appProps: restOfAppInitialProps, ...restOfPageData, }; } /* * fetchPageData behaves differently depending on whether custom /_app * fetches data or not (appInitialProps) * * /_app HAS NOT fetched data: * fetch page data using the first available method: * - getInitialProps * - getServerSideProps * - getStaticProps * * /_app HAS fetched data: * DO NOT call getInitialProps, if available * If available, call getServerSideProps or getServerSideProps * and merge returned object's prop property with appInitialProps.pageProps * * If no fetching methods available, return appInitialProps.pageProps as {props: appInitialProps.pageProp} */ async function fetchPageData({ pageObject, appInitialProps, options, }) { const { env } = options; const { files } = pageObject; const pageFile = files[env].pageFile; ensureNoMultipleDataFetchingMethods({ page: pageFile }); const pageComponent = pageFile.default; const { getInitialProps } = pageComponent; if (getInitialProps && // getInitialProps is not called when custom App has the same method !appInitialProps) { const ctx = (0, makeContextObject_1.makeGetInitialPropsContext)({ options, pageObject, }); if (env === constants_1.RuntimeEnvironment.CLIENT) { const initialProps = await getInitialProps(ctx); return { props: initialProps }; } else { const initialProps = await (0, server_1.executeAsIfOnServer)(() => getInitialProps(ctx)); return { props: initialProps }; } } // Data fetching methods available to actual pages only if (pageObject.type === 'found') { const { files, params } = pageObject; const serverPageFile = files.server.pageFile; if (serverPageFile.getServerSideProps) { const { getServerSideProps } = serverPageFile; const ctx = (0, makeContextObject_1.makeGetServerSidePropsContext)({ options, pageObject }); const pageData = await (0, server_1.executeAsIfOnServer)(() => getServerSideProps(ctx)); ensurePageDataHasProps({ pageData }); return mergePageDataWithAppData({ pageData, appInitialProps }); } if (serverPageFile.getStaticProps) { const { getStaticProps } = serverPageFile; const ctx = (0, makeContextObject_1.makeStaticPropsContext)({ pageObject, }); // @TODO introduce `getStaticPaths` logic // https://nextjs.org/docs/basic-features/data-fetching#getstaticpaths-static-generation const pageData = await (0, server_1.executeAsIfOnServer)(() => getStaticProps(ctx)); ensurePageDataHasProps({ pageData }); return mergePageDataWithAppData({ pageData, appInitialProps }); } if (appInitialProps) { const { pageProps, ...restOfAppInitialProps } = appInitialProps; return { props: pageProps, appProps: restOfAppInitialProps }; } } return {}; } exports.default = fetchPageData;