1
1
// @ts -check
2
2
import cp from 'child_process'
3
3
import fs from 'fs'
4
- import { mkdir } from 'fs/promises'
4
+ import { mkdir , readdir , unlink } from 'fs/promises'
5
5
import { createRequire } from 'module'
6
6
import path , { dirname } from 'path'
7
7
import process from 'process'
8
- import { fileURLToPath } from 'url'
8
+ import { fileURLToPath , pathToFileURL } from 'url'
9
9
import { promisify } from 'util'
10
10
11
11
import copyTemplateDirOriginal from 'copy-template-dir'
@@ -16,6 +16,7 @@ import inquirerAutocompletePrompt from 'inquirer-autocomplete-prompt'
16
16
import fetch from 'node-fetch'
17
17
import ora from 'ora'
18
18
19
+ import { fileExistsAsync } from '../../lib/fs.mjs'
19
20
import { getAddons , getCurrentAddon , getSiteData } from '../../utils/addons/prepare.mjs'
20
21
import { NETLIFYDEVERR , NETLIFYDEVLOG , NETLIFYDEVWARN , chalk , error , log } from '../../utils/command-helpers.mjs'
21
22
import { injectEnvVariables } from '../../utils/dev.mjs'
@@ -90,19 +91,26 @@ const filterRegistry = function (registry, input) {
90
91
} )
91
92
}
92
93
93
- const formatRegistryArrayForInquirer = function ( lang , funcType ) {
94
- const folderNames = fs . readdirSync ( path . join ( templatesDir , lang ) )
95
- const registry = folderNames
96
- // filter out markdown files
97
- . filter ( ( folderName ) => ! folderName . endsWith ( '.md' ) )
94
+ const formatRegistryArrayForInquirer = async function ( lang , funcType ) {
95
+ const folderNames = await readdir ( path . join ( templatesDir , lang ) )
98
96
99
- . map ( ( folderName ) =>
100
- // eslint-disable-next-line import/no-dynamic-require
101
- require ( path . join ( templatesDir , lang , folderName , '.netlify-function-template.cjs' ) ) ,
102
- )
103
- . filter ( ( folderName ) => folderName . functionType === funcType )
104
- . sort ( ( folderNameA , folderNameB ) => {
105
- const priorityDiff = ( folderNameA . priority || DEFAULT_PRIORITY ) - ( folderNameB . priority || DEFAULT_PRIORITY )
97
+ const imports = await Promise . all (
98
+ folderNames
99
+ // filter out markdown files
100
+ . filter ( ( folderName ) => ! folderName . endsWith ( '.md' ) )
101
+ . map ( async ( folderName ) => {
102
+ const templatePath = path . join ( templatesDir , lang , folderName , '.netlify-function-template.mjs' )
103
+ // eslint-disable-next-line import/no-dynamic-require
104
+ const template = await import ( pathToFileURL ( templatePath ) )
105
+
106
+ return template . default
107
+ } ) ,
108
+ )
109
+
110
+ const registry = imports
111
+ . filter ( ( template ) => template . functionType === funcType )
112
+ . sort ( ( templateA , templateB ) => {
113
+ const priorityDiff = ( templateA . priority || DEFAULT_PRIORITY ) - ( templateB . priority || DEFAULT_PRIORITY )
106
114
107
115
if ( priorityDiff !== 0 ) {
108
116
return priorityDiff
@@ -112,7 +120,7 @@ const formatRegistryArrayForInquirer = function (lang, funcType) {
112
120
// until Node 11, so the original sorting order from `fs.readdirSync`
113
121
// was not respected. We can simplify this once we drop support for
114
122
// Node 10.
115
- return folderNameA - folderNameB
123
+ return templateA - templateB
116
124
} )
117
125
. map ( ( t ) => {
118
126
t . lang = lang
@@ -170,7 +178,7 @@ const pickTemplate = async function ({ language: languageFromFlag }, funcType) {
170
178
let templatesForLanguage
171
179
172
180
try {
173
- templatesForLanguage = formatRegistryArrayForInquirer ( language , funcType )
181
+ templatesForLanguage = await formatRegistryArrayForInquirer ( language , funcType )
174
182
} catch {
175
183
throw error ( `Invalid language: ${ language } ` )
176
184
}
@@ -292,14 +300,14 @@ const ensureFunctionDirExists = async function (command) {
292
300
}
293
301
}
294
302
295
- if ( ! fs . existsSync ( functionsDirHolder ) ) {
303
+ if ( ! ( await fileExistsAsync ( functionsDirHolder ) ) ) {
296
304
log (
297
305
`${ NETLIFYDEVLOG } functions directory ${ chalk . magenta . inverse (
298
306
functionsDirHolder ,
299
307
) } does not exist yet, creating it...`,
300
308
)
301
309
302
- fs . mkdirSync ( functionsDirHolder , { recursive : true } )
310
+ await mkdir ( functionsDirHolder , { recursive : true } )
303
311
304
312
log ( `${ NETLIFYDEVLOG } functions directory ${ chalk . magenta . inverse ( functionsDirHolder ) } created` )
305
313
}
@@ -350,15 +358,17 @@ const downloadFromURL = async function (command, options, argumentName, function
350
358
} )
351
359
352
360
// read, execute, and delete function template file if exists
353
- const fnTemplateFile = path . join ( fnFolder , '.netlify-function-template.cjs' )
354
- if ( fs . existsSync ( fnTemplateFile ) ) {
355
- // eslint-disable-next-line import/no-dynamic-require
356
- const { onComplete, addons = [ ] } = require ( fnTemplateFile )
361
+ const fnTemplateFile = path . join ( fnFolder , '.netlify-function-template.mjs' )
362
+ if ( await fileExistsAsync ( fnTemplateFile ) ) {
363
+ const {
364
+ default : { onComplete, addons = [ ] } ,
365
+ // eslint-disable-next-line import/no-dynamic-require
366
+ } = await import ( pathToFileURL ( fnTemplateFile ) . href )
357
367
358
368
await installAddons ( command , addons , path . resolve ( fnFolder ) )
359
369
await handleOnComplete ( { command, onComplete } )
360
370
// delete
361
- fs . unlinkSync ( fnTemplateFile )
371
+ await unlink ( fnTemplateFile )
362
372
}
363
373
}
364
374
@@ -471,7 +481,7 @@ const scaffoldFromTemplate = async function (command, options, argumentName, fun
471
481
472
482
// These files will not be part of the log message because they'll likely
473
483
// be removed before the command finishes.
474
- const omittedFromOutput = new Set ( [ '.netlify-function-template.cjs ' , 'package.json' , 'package-lock.json' ] )
484
+ const omittedFromOutput = new Set ( [ '.netlify-function-template.mjs ' , 'package.json' , 'package-lock.json' ] )
475
485
const createdFiles = await copyTemplateDir ( pathToTemplate , functionPath , vars )
476
486
createdFiles . forEach ( ( filePath ) => {
477
487
const filename = path . basename ( filePath )
@@ -487,7 +497,7 @@ const scaffoldFromTemplate = async function (command, options, argumentName, fun
487
497
} )
488
498
489
499
// delete function template file that was copied over by copydir
490
- fs . unlinkSync ( path . join ( functionPath , '.netlify-function-template.cjs ' ) )
500
+ await unlink ( path . join ( functionPath , '.netlify-function-template.mjs ' ) )
491
501
492
502
// npm install
493
503
if ( functionPackageJson !== undefined ) {
0 commit comments