From 3d1ec5177a6933145a649704727ce8981c3c43ef Mon Sep 17 00:00:00 2001 From: Tiffany Le-Nguyen Date: Tue, 30 Nov 2021 20:46:09 +0300 Subject: [PATCH 1/3] chore: type a couple files --- src/{constants.js => constants.ts} | 8 +- src/helpers/{cache.js => cache.ts} | 17 ++-- src/helpers/{config.js => config.ts} | 42 +++++--- src/helpers/requiredServerFilesType.ts | 129 +++++++++++++++++++++++++ test/__snapshots__/index.js.snap | 8 -- 5 files changed, 168 insertions(+), 36 deletions(-) rename src/{constants.js => constants.ts} (66%) rename src/helpers/{cache.js => cache.ts} (50%) rename src/helpers/{config.js => config.ts} (84%) create mode 100644 src/helpers/requiredServerFilesType.ts diff --git a/src/constants.js b/src/constants.ts similarity index 66% rename from src/constants.js rename to src/constants.ts index 6225993605..5058fd7257 100644 --- a/src/constants.js +++ b/src/constants.ts @@ -1,9 +1,9 @@ -const HANDLER_FUNCTION_NAME = '___netlify-handler' -const ODB_FUNCTION_NAME = '___netlify-odb-handler' -const IMAGE_FUNCTION_NAME = '_ipx' +export const HANDLER_FUNCTION_NAME = '___netlify-handler' +export const ODB_FUNCTION_NAME = '___netlify-odb-handler' +export const IMAGE_FUNCTION_NAME = '_ipx' // These are paths in .next that shouldn't be publicly accessible -const HIDDEN_PATHS = [ +export const HIDDEN_PATHS = [ '/cache/*', '/server/*', '/serverless/*', diff --git a/src/helpers/cache.js b/src/helpers/cache.ts similarity index 50% rename from src/helpers/cache.js rename to src/helpers/cache.ts index 5f6e4248b4..d2a61d100d 100644 --- a/src/helpers/cache.js +++ b/src/helpers/cache.ts @@ -1,9 +1,8 @@ -const { - posix: { join }, -} = require('path') +import { posix } from 'path' + +export const restoreCache = async ({ cache, publish }) => { + const cacheDir = posix.join(publish, 'cache') -exports.restoreCache = async ({ cache, publish }) => { - const cacheDir = join(publish, 'cache') if (await cache.restore(cacheDir)) { console.log('Next.js cache restored.') } else { @@ -11,13 +10,13 @@ exports.restoreCache = async ({ cache, publish }) => { } } -exports.saveCache = async ({ cache, publish }) => { - const cacheDir = join(publish, 'cache') +export const saveCache = async ({ cache, publish }) => { + const cacheDir = posix.join(publish, 'cache') - const buildManifest = join(publish, 'build-manifest.json') + const buildManifest = posix.join(publish, 'build-manifest.json') if (await cache.save(cacheDir, { digests: [buildManifest] })) { console.log('Next.js cache saved.') } else { console.log('No Next.js cache to save.') } -} +} \ No newline at end of file diff --git a/src/helpers/config.js b/src/helpers/config.ts similarity index 84% rename from src/helpers/config.js rename to src/helpers/config.ts index 87a9693d50..b7c5a19a16 100644 --- a/src/helpers/config.js +++ b/src/helpers/config.ts @@ -1,17 +1,21 @@ /* eslint-disable max-lines */ -const { yellowBright } = require('chalk') -const { readJSON, existsSync } = require('fs-extra') -const { outdent } = require('outdent') -const { join, dirname, relative } = require('pathe') -const slash = require('slash') +import { NetlifyConfig } from '@netlify/build' +import { yellowBright } from 'chalk' +import { readJSON } from 'fs-extra' +import { PrerenderManifest } from 'next/dist/build' +import { outdent } from 'outdent' +import { join, dirname, relative } from 'pathe' +import slash from 'slash' -const defaultFailBuild = (message, { error }) => { +import { HANDLER_FUNCTION_NAME, ODB_FUNCTION_NAME, HIDDEN_PATHS } from '../constants' + +import { RequiredServerFiles } from './requiredServerFilesType' + +const defaultFailBuild = (message: string, { error } ): never => { throw new Error(`${message}\n${error && error.stack}`) } -const { HANDLER_FUNCTION_NAME, ODB_FUNCTION_NAME, HIDDEN_PATHS } = require('../constants') - const ODB_FUNCTION_PATH = `/.netlify/builders/${ODB_FUNCTION_NAME}` const HANDLER_FUNCTION_PATH = `/.netlify/functions/${HANDLER_FUNCTION_NAME}` @@ -19,7 +23,7 @@ const CATCH_ALL_REGEX = /\/\[\.{3}(.*)](.json)?$/ const OPTIONAL_CATCH_ALL_REGEX = /\/\[{2}\.{3}(.*)]{2}(.json)?$/ const DYNAMIC_PARAMETER_REGEX = /\/\[(.*?)]/g -const getNetlifyRoutes = (nextRoute) => { +const getNetlifyRoutes = (nextRoute: string): Array => { let netlifyRoutes = [nextRoute] // If the route is an optional catch-all route, we need to add a second @@ -54,8 +58,12 @@ const getNetlifyRoutes = (nextRoute) => { return netlifyRoutes } -exports.generateRedirects = async ({ netlifyConfig, basePath, i18n }) => { - const { dynamicRoutes, routes: staticRoutes } = await readJSON( +export const generateRedirects = async ({ netlifyConfig, basePath, i18n }: { + netlifyConfig: NetlifyConfig, + basePath: string, + i18n +}) => { + const { dynamicRoutes, routes: staticRoutes }: PrerenderManifest = await readJSON( join(netlifyConfig.build.publish, 'prerender-manifest.json'), ) @@ -123,6 +131,8 @@ exports.generateRedirects = async ({ netlifyConfig, basePath, i18n }) => { from: `${basePath}/*`, to: HANDLER_FUNCTION_PATH, status: 200, + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore conditions: { Cookie: ['__prerender_bypass', '__next_preview_data'] }, force: true, }, @@ -158,14 +168,16 @@ exports.generateRedirects = async ({ netlifyConfig, basePath, i18n }) => { } } -exports.getNextConfig = async function getNextConfig({ publish, failBuild = defaultFailBuild }) { +export const getNextConfig = async function getNextConfig({ publish, failBuild = defaultFailBuild }) { try { - const { config, appDir, ignore } = await readJSON(join(publish, 'required-server-files.json')) + const { config, appDir, ignore }: RequiredServerFiles = await readJSON(join(publish, 'required-server-files.json')) if (!config) { + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore return failBuild('Error loading your Next config') } return { ...config, appDir, ignore } - } catch (error) { + } catch (error: unknown) { return failBuild('Error loading your Next config', { error }) } } @@ -180,7 +192,7 @@ const resolveModuleRoot = (moduleName) => { const DEFAULT_EXCLUDED_MODULES = ['sharp', 'electron'] -exports.configureHandlerFunctions = ({ netlifyConfig, publish, ignore = [] }) => { +export const configureHandlerFunctions = ({ netlifyConfig, publish, ignore = [] }) => { /* eslint-disable no-underscore-dangle */ netlifyConfig.functions._ipx ||= {} netlifyConfig.functions._ipx.node_bundler = 'nft' diff --git a/src/helpers/requiredServerFilesType.ts b/src/helpers/requiredServerFilesType.ts new file mode 100644 index 0000000000..486331804e --- /dev/null +++ b/src/helpers/requiredServerFilesType.ts @@ -0,0 +1,129 @@ +/* eslint-disable eslint-comments/disable-enable-pair, @typescript-eslint/no-empty-interface, no-use-before-define */ +/** + * This was generated using @see {@link https://quicktype.io/}, and using the + * demo's {@code demos/default/.next/required-server-files.json} file. I was + * unable to find any types for this file so instead this was manually generated + */ + +export interface RequiredServerFiles { + version?: number; + config?: Config; + appDir?: string; + files?: string[]; + ignore?: string[]; +} + +export interface Env { +} + +export interface Config { + env?: Env; + webpack?: null; + webpackDevMiddleware?: null; + eslint?: Eslint; + typescript?: Typescript; + distDir?: string; + cleanDistDir?: boolean; + assetPrefix?: string; + configOrigin?: string; + useFileSystemPublicRoutes?: boolean; + generateEtags?: boolean; + pageExtensions?: string[]; + target?: string; + poweredByHeader?: boolean; + compress?: boolean; + analyticsId?: string; + images?: Images; + devIndicators?: DevIndicators; + onDemandEntries?: OnDemandEntries; + amp?: Amp; + basePath?: string; + sassOptions?: Env; + trailingSlash?: boolean; + i18n?: I18N; + productionBrowserSourceMaps?: boolean; + optimizeFonts?: boolean; + excludeDefaultMomentLocales?: boolean; + serverRuntimeConfig?: Env; + publicRuntimeConfig?: Env; + reactStrictMode?: boolean; + httpAgentOptions?: HTTPAgentOptions; + outputFileTracing?: boolean; + staticPageGenerationTimeout?: number; + swcMinify?: boolean; + experimental?: Experimental; + future?: Future; + configFileName?: string; +} + +export interface Amp { + canonicalBase?: string; +} + +export interface DevIndicators { + buildActivity?: boolean; + buildActivityPosition?: string; +} + +export interface Eslint { + ignoreDuringBuilds?: boolean; +} + +export interface Experimental { + cpus?: number; + sharedPool?: boolean; + plugins?: boolean; + profiling?: boolean; + isrFlushToDisk?: boolean; + workerThreads?: boolean; + pageEnv?: boolean; + optimizeImages?: boolean; + optimizeCss?: boolean; + scrollRestoration?: boolean; + externalDir?: boolean; + reactRoot?: boolean; + disableOptimizedLoading?: boolean; + gzipSize?: boolean; + craCompat?: boolean; + esmExternals?: boolean; + isrMemoryCacheSize?: number; + concurrentFeatures?: boolean; + serverComponents?: boolean; + fullySpecified?: boolean; + outputFileTracingRoot?: string; + outputStandalone?: boolean; +} + +export interface Future { + strictPostcssConfiguration?: boolean; +} + +export interface HTTPAgentOptions { + keepAlive?: boolean; +} + +export interface I18N { + defaultLocale?: string; + locales?: string[]; +} + +export interface Images { + deviceSizes?: number[]; + imageSizes?: number[]; + path?: string; + loader?: string; + domains?: any[]; + disableStaticImages?: boolean; + minimumCacheTTL?: number; + formats?: string[]; +} + +export interface OnDemandEntries { + maxInactiveAge?: number; + pagesBufferLength?: number; +} + +export interface Typescript { + ignoreBuildErrors?: boolean; + tsconfigPath?: string; +} diff --git a/test/__snapshots__/index.js.snap b/test/__snapshots__/index.js.snap index 75aed6b492..04e1fb49b5 100644 --- a/test/__snapshots__/index.js.snap +++ b/test/__snapshots__/index.js.snap @@ -18,7 +18,6 @@ exports.resolvePages = () => { require.resolve('../../../.next/server/pages/getServerSideProps/all/[[...slug]].js') require.resolve('../../../.next/server/pages/getServerSideProps/static.js') require.resolve('../../../.next/server/pages/getStaticProps/[id].js') - require.resolve('../../../.next/server/pages/getStaticProps/env.js') require.resolve('../../../.next/server/pages/getStaticProps/static.js') require.resolve('../../../.next/server/pages/getStaticProps/with-revalidate.js') require.resolve('../../../.next/server/pages/getStaticProps/withFallback/[...slug].js') @@ -53,7 +52,6 @@ exports.resolvePages = () => { require.resolve('../../../.next/server/pages/getServerSideProps/all/[[...slug]].js') require.resolve('../../../.next/server/pages/getServerSideProps/static.js') require.resolve('../../../.next/server/pages/getStaticProps/[id].js') - require.resolve('../../../.next/server/pages/getStaticProps/env.js') require.resolve('../../../.next/server/pages/getStaticProps/static.js') require.resolve('../../../.next/server/pages/getStaticProps/with-revalidate.js') require.resolve('../../../.next/server/pages/getStaticProps/withFallback/[...slug].js') @@ -76,8 +74,6 @@ Array [ "en/getStaticProps/1.json", "en/getStaticProps/2.html", "en/getStaticProps/2.json", - "en/getStaticProps/env.html", - "en/getStaticProps/env.json", "en/getStaticProps/static.html", "en/getStaticProps/static.json", "en/getStaticProps/withFallback/3.html", @@ -96,16 +92,12 @@ Array [ "en/previewTest.html", "en/previewTest.json", "en/static.html", - "es/getStaticProps/env.html", - "es/getStaticProps/env.json", "es/getStaticProps/static.html", "es/getStaticProps/static.json", "es/image.html", "es/previewTest.html", "es/previewTest.json", "es/static.html", - "fr/getStaticProps/env.html", - "fr/getStaticProps/env.json", "fr/getStaticProps/static.html", "fr/getStaticProps/static.json", "fr/image.html", From 8ef023c2b9b33ef0a2eccf802ead30bba213a8ca Mon Sep 17 00:00:00 2001 From: Tiffany Le-Nguyen Date: Tue, 30 Nov 2021 20:59:04 +0300 Subject: [PATCH 2/3] chore: update snapidoos --- test/__snapshots__/index.js.snap | 41 +++----------------------------- 1 file changed, 3 insertions(+), 38 deletions(-) diff --git a/test/__snapshots__/index.js.snap b/test/__snapshots__/index.js.snap index 04e1fb49b5..a6380cd942 100644 --- a/test/__snapshots__/index.js.snap +++ b/test/__snapshots__/index.js.snap @@ -18,6 +18,7 @@ exports.resolvePages = () => { require.resolve('../../../.next/server/pages/getServerSideProps/all/[[...slug]].js') require.resolve('../../../.next/server/pages/getServerSideProps/static.js') require.resolve('../../../.next/server/pages/getStaticProps/[id].js') + require.resolve('../../../.next/server/pages/getStaticProps/env.js') require.resolve('../../../.next/server/pages/getStaticProps/static.js') require.resolve('../../../.next/server/pages/getStaticProps/with-revalidate.js') require.resolve('../../../.next/server/pages/getStaticProps/withFallback/[...slug].js') @@ -52,6 +53,7 @@ exports.resolvePages = () => { require.resolve('../../../.next/server/pages/getServerSideProps/all/[[...slug]].js') require.resolve('../../../.next/server/pages/getServerSideProps/static.js') require.resolve('../../../.next/server/pages/getStaticProps/[id].js') + require.resolve('../../../.next/server/pages/getStaticProps/env.js') require.resolve('../../../.next/server/pages/getStaticProps/static.js') require.resolve('../../../.next/server/pages/getStaticProps/with-revalidate.js') require.resolve('../../../.next/server/pages/getStaticProps/withFallback/[...slug].js') @@ -68,44 +70,7 @@ exports.resolvePages = () => { }" `; -exports[`onBuild() generates static files manifest 1`] = ` -Array [ - "en/getStaticProps/1.html", - "en/getStaticProps/1.json", - "en/getStaticProps/2.html", - "en/getStaticProps/2.json", - "en/getStaticProps/static.html", - "en/getStaticProps/static.json", - "en/getStaticProps/withFallback/3.html", - "en/getStaticProps/withFallback/3.json", - "en/getStaticProps/withFallback/4.html", - "en/getStaticProps/withFallback/4.json", - "en/getStaticProps/withFallback/my/path/1.html", - "en/getStaticProps/withFallback/my/path/1.json", - "en/getStaticProps/withFallback/my/path/2.html", - "en/getStaticProps/withFallback/my/path/2.json", - "en/getStaticProps/withFallbackBlocking/3.html", - "en/getStaticProps/withFallbackBlocking/3.json", - "en/getStaticProps/withFallbackBlocking/4.html", - "en/getStaticProps/withFallbackBlocking/4.json", - "en/image.html", - "en/previewTest.html", - "en/previewTest.json", - "en/static.html", - "es/getStaticProps/static.html", - "es/getStaticProps/static.json", - "es/image.html", - "es/previewTest.html", - "es/previewTest.json", - "es/static.html", - "fr/getStaticProps/static.html", - "fr/getStaticProps/static.json", - "fr/image.html", - "fr/previewTest.html", - "fr/previewTest.json", - "fr/static.html", -] -`; +exports[`onBuild() generates static files manifest 1`] = `Array []`; exports[`onBuild() writes correct redirects to netlifyConfig 1`] = ` Array [ From 2c32256bb280c4fcf402540305414ddce7906f4d Mon Sep 17 00:00:00 2001 From: Tiffany Le-Nguyen Date: Wed, 1 Dec 2021 12:35:45 +0300 Subject: [PATCH 3/3] chore: revert snapidoo --- test/__snapshots__/index.js.snap | 45 +++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/test/__snapshots__/index.js.snap b/test/__snapshots__/index.js.snap index a6380cd942..75aed6b492 100644 --- a/test/__snapshots__/index.js.snap +++ b/test/__snapshots__/index.js.snap @@ -70,7 +70,50 @@ exports.resolvePages = () => { }" `; -exports[`onBuild() generates static files manifest 1`] = `Array []`; +exports[`onBuild() generates static files manifest 1`] = ` +Array [ + "en/getStaticProps/1.html", + "en/getStaticProps/1.json", + "en/getStaticProps/2.html", + "en/getStaticProps/2.json", + "en/getStaticProps/env.html", + "en/getStaticProps/env.json", + "en/getStaticProps/static.html", + "en/getStaticProps/static.json", + "en/getStaticProps/withFallback/3.html", + "en/getStaticProps/withFallback/3.json", + "en/getStaticProps/withFallback/4.html", + "en/getStaticProps/withFallback/4.json", + "en/getStaticProps/withFallback/my/path/1.html", + "en/getStaticProps/withFallback/my/path/1.json", + "en/getStaticProps/withFallback/my/path/2.html", + "en/getStaticProps/withFallback/my/path/2.json", + "en/getStaticProps/withFallbackBlocking/3.html", + "en/getStaticProps/withFallbackBlocking/3.json", + "en/getStaticProps/withFallbackBlocking/4.html", + "en/getStaticProps/withFallbackBlocking/4.json", + "en/image.html", + "en/previewTest.html", + "en/previewTest.json", + "en/static.html", + "es/getStaticProps/env.html", + "es/getStaticProps/env.json", + "es/getStaticProps/static.html", + "es/getStaticProps/static.json", + "es/image.html", + "es/previewTest.html", + "es/previewTest.json", + "es/static.html", + "fr/getStaticProps/env.html", + "fr/getStaticProps/env.json", + "fr/getStaticProps/static.html", + "fr/getStaticProps/static.json", + "fr/image.html", + "fr/previewTest.html", + "fr/previewTest.json", + "fr/static.html", +] +`; exports[`onBuild() writes correct redirects to netlifyConfig 1`] = ` Array [