11// @ts -check
22import cp from 'child_process'
33import fs from 'fs'
4- import { mkdir } from 'fs/promises'
4+ import { mkdir , readdir , unlink } from 'fs/promises'
55import { createRequire } from 'module'
66import path , { dirname } from 'path'
77import process from 'process'
8- import { fileURLToPath } from 'url'
8+ import { fileURLToPath , pathToFileURL } from 'url'
99import { promisify } from 'util'
1010
1111import copyTemplateDirOriginal from 'copy-template-dir'
@@ -16,6 +16,7 @@ import inquirerAutocompletePrompt from 'inquirer-autocomplete-prompt'
1616import fetch from 'node-fetch'
1717import ora from 'ora'
1818
19+ import { fileExistsAsync } from '../../lib/fs.mjs'
1920import { getAddons , getCurrentAddon , getSiteData } from '../../utils/addons/prepare.mjs'
2021import { NETLIFYDEVERR , NETLIFYDEVLOG , NETLIFYDEVWARN , chalk , error , log } from '../../utils/command-helpers.mjs'
2122import { injectEnvVariables } from '../../utils/dev.mjs'
@@ -90,19 +91,26 @@ const filterRegistry = function (registry, input) {
9091 } )
9192}
9293
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 ) )
9896
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 )
106114
107115 if ( priorityDiff !== 0 ) {
108116 return priorityDiff
@@ -112,7 +120,7 @@ const formatRegistryArrayForInquirer = function (lang, funcType) {
112120 // until Node 11, so the original sorting order from `fs.readdirSync`
113121 // was not respected. We can simplify this once we drop support for
114122 // Node 10.
115- return folderNameA - folderNameB
123+ return templateA - templateB
116124 } )
117125 . map ( ( t ) => {
118126 t . lang = lang
@@ -170,7 +178,7 @@ const pickTemplate = async function ({ language: languageFromFlag }, funcType) {
170178 let templatesForLanguage
171179
172180 try {
173- templatesForLanguage = formatRegistryArrayForInquirer ( language , funcType )
181+ templatesForLanguage = await formatRegistryArrayForInquirer ( language , funcType )
174182 } catch {
175183 throw error ( `Invalid language: ${ language } ` )
176184 }
@@ -292,14 +300,14 @@ const ensureFunctionDirExists = async function (command) {
292300 }
293301 }
294302
295- if ( ! fs . existsSync ( functionsDirHolder ) ) {
303+ if ( ! ( await fileExistsAsync ( functionsDirHolder ) ) ) {
296304 log (
297305 `${ NETLIFYDEVLOG } functions directory ${ chalk . magenta . inverse (
298306 functionsDirHolder ,
299307 ) } does not exist yet, creating it...`,
300308 )
301309
302- fs . mkdirSync ( functionsDirHolder , { recursive : true } )
310+ await mkdir ( functionsDirHolder , { recursive : true } )
303311
304312 log ( `${ NETLIFYDEVLOG } functions directory ${ chalk . magenta . inverse ( functionsDirHolder ) } created` )
305313 }
@@ -350,15 +358,17 @@ const downloadFromURL = async function (command, options, argumentName, function
350358 } )
351359
352360 // 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 )
357367
358368 await installAddons ( command , addons , path . resolve ( fnFolder ) )
359369 await handleOnComplete ( { command, onComplete } )
360370 // delete
361- fs . unlinkSync ( fnTemplateFile )
371+ await unlink ( fnTemplateFile )
362372 }
363373}
364374
@@ -471,7 +481,7 @@ const scaffoldFromTemplate = async function (command, options, argumentName, fun
471481
472482 // These files will not be part of the log message because they'll likely
473483 // 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' ] )
475485 const createdFiles = await copyTemplateDir ( pathToTemplate , functionPath , vars )
476486 createdFiles . forEach ( ( filePath ) => {
477487 const filename = path . basename ( filePath )
@@ -487,7 +497,7 @@ const scaffoldFromTemplate = async function (command, options, argumentName, fun
487497 } )
488498
489499 // 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 ' ) )
491501
492502 // npm install
493503 if ( functionPackageJson !== undefined ) {
0 commit comments