@@ -3,11 +3,12 @@ import { EOL } from 'os'
33import path from 'path'
44import process from 'process'
55
6- import { stripIndent } from 'common-tags '
6+ import { NetlifyConfig } from '@netlify/build '
77import fs , { existsSync } from 'fs-extra'
88import type { GatsbyConfig , PluginRef } from 'gatsby'
99
1010import { checkPackageVersion } from './files'
11+ import type { FunctionList } from './functions'
1112
1213export async function spliceConfig ( {
1314 startMarker,
@@ -114,64 +115,126 @@ export async function checkConfig({ utils, netlifyConfig }): Promise<void> {
114115 }
115116}
116117
118+ export async function modifyConfig ( {
119+ netlifyConfig,
120+ cacheDir,
121+ neededFunctions,
122+ } : {
123+ netlifyConfig : NetlifyConfig
124+ cacheDir : string
125+ neededFunctions : FunctionList
126+ } ) : Promise < void > {
127+ mutateConfig ( { netlifyConfig, cacheDir, neededFunctions } )
128+
129+ if ( neededFunctions . includes ( 'API' ) ) {
130+ // Editing _redirects so it works with ntl dev
131+ await spliceConfig ( {
132+ startMarker : '# @netlify/plugin-gatsby redirects start' ,
133+ endMarker : '# @netlify/plugin-gatsby redirects end' ,
134+ contents : '/api/* /.netlify/functions/__api 200' ,
135+ fileName : path . join ( netlifyConfig . build . publish , '_redirects' ) ,
136+ } )
137+ }
138+ }
139+
117140export function mutateConfig ( {
118141 netlifyConfig,
119- compiledFunctionsDir,
120142 cacheDir,
143+ neededFunctions,
144+ } : {
145+ netlifyConfig : NetlifyConfig
146+ cacheDir : string
147+ neededFunctions : FunctionList
121148} ) : void {
122149 /* eslint-disable no-underscore-dangle, no-param-reassign */
123- netlifyConfig . functions . __api = {
124- included_files : [ path . posix . join ( compiledFunctionsDir , '**' ) ] ,
125- external_node_modules : [ 'msgpackr-extract' ] ,
150+ if ( neededFunctions . includes ( 'API' ) ) {
151+ netlifyConfig . functions . __api = {
152+ included_files : [ path . posix . join ( cacheDir , 'functions' , '**' ) ] ,
153+ external_node_modules : [ 'msgpackr-extract' ] ,
154+ }
126155 }
127156
128- netlifyConfig . functions . __dsg = {
129- included_files : [
130- 'public/404.html' ,
131- 'public/500.html' ,
132- path . posix . join ( cacheDir , 'data' , '**' ) ,
133- path . posix . join ( cacheDir , 'query-engine' , '**' ) ,
134- path . posix . join ( cacheDir , 'page-ssr' , '**' ) ,
135- '!**/*.js.map' ,
136- ] ,
137- external_node_modules : [ 'msgpackr-extract' ] ,
138- node_bundler : 'esbuild' ,
157+ if ( neededFunctions . includes ( 'DSG' ) ) {
158+ netlifyConfig . functions . __dsg = {
159+ included_files : [
160+ 'public/404.html' ,
161+ 'public/500.html' ,
162+ path . posix . join ( cacheDir , 'data' , '**' ) ,
163+ path . posix . join ( cacheDir , 'query-engine' , '**' ) ,
164+ path . posix . join ( cacheDir , 'page-ssr' , '**' ) ,
165+ '!**/*.js.map' ,
166+ ] ,
167+ external_node_modules : [ 'msgpackr-extract' ] ,
168+ node_bundler : 'esbuild' ,
169+ }
139170 }
140171
141- netlifyConfig . functions . __ssr = { ...netlifyConfig . functions . __dsg }
172+ if ( neededFunctions . includes ( 'SSR' ) ) {
173+ netlifyConfig . functions . __ssr = {
174+ included_files : [
175+ 'public/404.html' ,
176+ 'public/500.html' ,
177+ path . posix . join ( cacheDir , 'data' , '**' ) ,
178+ path . posix . join ( cacheDir , 'query-engine' , '**' ) ,
179+ path . posix . join ( cacheDir , 'page-ssr' , '**' ) ,
180+ '!**/*.js.map' ,
181+ ] ,
182+ external_node_modules : [ 'msgpackr-extract' ] ,
183+ node_bundler : 'esbuild' ,
184+ }
185+ }
142186 /* eslint-enable no-underscore-dangle, no-param-reassign */
143187}
144188
145- export function shouldSkipFunctions ( cacheDir : string ) : boolean {
146- if (
147- process . env . NETLIFY_SKIP_GATSBY_FUNCTIONS === 'true' ||
148- process . env . NETLIFY_SKIP_GATSBY_FUNCTIONS === '1'
149- ) {
150- console . log (
151- 'Skipping Gatsby Functions and SSR/DSG support because the environment variable NETLIFY_SKIP_GATSBY_FUNCTIONS is set to true' ,
152- )
153- return true
154- }
189+ export async function getNeededFunctions (
190+ cacheDir : string ,
191+ ) : Promise < FunctionList > {
192+ if ( ! existsSync ( path . join ( cacheDir , 'functions' ) ) ) return [ ]
155193
156- if ( ! existsSync ( path . join ( cacheDir , 'functions' ) ) ) {
157- console . log (
158- `Skipping Gatsby Functions and SSR/DSG support because the site's Gatsby version does not support them` ,
159- )
160- return true
194+ const neededFunctions = overrideNeededFunctions (
195+ await readFunctionSkipFile ( cacheDir ) ,
196+ )
197+
198+ const functionList = Object . keys ( neededFunctions ) . filter (
199+ ( name ) => neededFunctions [ name ] === true ,
200+ ) as FunctionList
201+
202+ if ( functionList . length === 0 ) {
203+ console . log ( 'Skipping Gatsby Functions and SSR/DSG support' )
204+ } else {
205+ console . log ( `Enabling Gatsby ${ functionList . join ( '/' ) } support` )
161206 }
162207
163- const skipFile = path . join ( cacheDir , '.nf-skip-gatsby-functions' )
208+ return functionList
209+ }
210+
211+ async function readFunctionSkipFile ( cacheDir : string ) {
212+ try {
213+ // read skip file from gatsby-plugin-netlify
214+ return await fs . readJson ( path . join ( cacheDir , '.nf-skip-gatsby-functions' ) )
215+ } catch ( error ) {
216+ // missing skip file = all functions needed
217+ // empty or invalid skip file = no functions needed
218+ return error . code === 'ENOENT' ? { API : true , SSR : true , DSG : true } : { }
219+ }
220+ }
164221
165- if ( existsSync ( skipFile ) ) {
166- console . log (
167- stripIndent `
168- Skipping Gatsby Functions and SSR/DSG support because gatsby-plugin-netlify reported that this site does not use them.
169- If this is incorrect, remove the file "${ skipFile } " and try again.` ,
170- )
171- return true
222+ // eslint-disable-next-line complexity
223+ function overrideNeededFunctions ( neededFunctions ) {
224+ const skipAll = isEnvSet ( 'NETLIFY_SKIP_GATSBY_FUNCTIONS' )
225+ const skipAPI = isEnvSet ( 'NETLIFY_SKIP_API_FUNCTION' )
226+ const skipSSR = isEnvSet ( 'NETLIFY_SKIP_SSR_FUNCTION' )
227+ const skipDSG = isEnvSet ( 'NETLIFY_SKIP_DSG_FUNCTION' )
228+
229+ return {
230+ API : skipAll || skipAPI ? false : neededFunctions . API ,
231+ SSR : skipAll || skipSSR ? false : neededFunctions . SSR ,
232+ DSG : skipAll || skipDSG ? false : neededFunctions . DSG ,
172233 }
234+ }
173235
174- return false
236+ function isEnvSet ( envVar : string ) {
237+ return process . env [ envVar ] === 'true' || process . env [ envVar ] === '1'
175238}
176239
177240export function getGatsbyRoot ( publish : string ) : string {
0 commit comments