Skip to content
This repository has been archived by the owner on May 22, 2024. It is now read-only.

Commit

Permalink
refactor: migrate components to TypeScript (#753)
Browse files Browse the repository at this point in the history
* refactor: use RuntimeName type

* refactor: unify GetSrcFilesFunction type

* refactor: migrate main file

* refactor: add FunctionArchive type

* refactor: migrate archive_size

* refactor: create ZipFunctionResult type

* refactor: migrate format_result

* refactor: improve typings in zip file

* refactor: migrate manifest

* refactor: migrate polyfills

* refactor: migrate consts

* refactor: migrate bin file

* chore: add comments

* refactor: remove type
  • Loading branch information
eduardoboucas committed Oct 20, 2021
1 parent bb9b217 commit d51c860
Show file tree
Hide file tree
Showing 23 changed files with 243 additions and 214 deletions.
31 changes: 31 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@
"@types/resolve": "^1.20.1",
"@types/semver": "^7.3.8",
"@types/unixify": "^1.0.0",
"@types/yargs": "^17.0.4",
"adm-zip": "0.5.5",
"ava": "^3.0.0",
"cpy": "^8.0.0",
Expand Down
20 changes: 14 additions & 6 deletions src/bin.js → src/bin.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
#!/usr/bin/env node
const { exit } = require('process')
import { exit } from 'process'

const yargs = require('yargs')
import yargs from 'yargs'

const zipIt = require('./main')
const { ARCHIVE_FORMAT_NONE, ARCHIVE_FORMAT_ZIP } = require('./utils/consts')
import { zipFunctions } from './main'
import { ARCHIVE_FORMAT_NONE, ARCHIVE_FORMAT_ZIP } from './utils/consts'

// CLI entry point
const runCli = async function () {
// @ts-expect-error TODO: `destFolder` and `srcFolder` are not being passed
// back from `parseArgs()`.
const { destFolder, srcFolder, ...options } = parseArgs()

try {
const zipped = await zipIt.zipFunctions(srcFolder, destFolder, options)
// @ts-expect-error TODO: `options` is not getting the right types.
const zipped = await zipFunctions(srcFolder, destFolder, options)
console.log(JSON.stringify(zipped, null, 2))
} catch (error) {
console.error(error.toString())
Expand All @@ -20,7 +23,12 @@ const runCli = async function () {
}

const parseArgs = function () {
return yargs.command('* <srcFolder> <destFolder>').options(OPTIONS).usage(USAGE).strict().parse()
return yargs
.command('* <srcFolder> <destFolder>', 'Create ZIP archives from a directory')
.options(OPTIONS)
.usage(USAGE)
.strict()
.parse()
}

const OPTIONS = {
Expand Down
14 changes: 12 additions & 2 deletions src/function.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@
import { Stats } from 'fs'

import type { FunctionConfig } from './config'
import type { Runtime } from './runtimes/runtime'
import type { Runtime, ZipFunctionResult } from './runtimes/runtime'

// A function that has been processed and turned into an archive.
type FunctionArchive = ZipFunctionResult & {
mainFile: string
name: string
runtime: Runtime
size?: number
}

// A function file found on the filesystem.
interface SourceFile {
extension: string
filename: string
Expand All @@ -13,9 +22,10 @@ interface SourceFile {
stat: Stats
}

// A function associated with a runtime.
type FunctionSource = SourceFile & {
config: FunctionConfig
runtime: Runtime
}

export { FunctionSource, SourceFile }
export { FunctionArchive, FunctionSource, SourceFile }
97 changes: 0 additions & 97 deletions src/main.js

This file was deleted.

92 changes: 92 additions & 0 deletions src/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import { extname } from 'path'

import './utils/polyfills'
import { Config } from './config'
import { FeatureFlags, getFlags } from './feature_flags'
import { FunctionSource } from './function'
import { getFunctionsFromPaths } from './runtimes'
import { getPluginsModulesPath } from './runtimes/node/utils/plugin_modules_path'
import { GetSrcFilesFunction, RuntimeName } from './runtimes/runtime'
import { listFunctionsDirectories, resolveFunctionsDirectories } from './utils/fs'
import { zipFunction, zipFunctions } from './zip'

interface ListedFunction {
name: string
mainFile: string
runtime: RuntimeName
extension: string
}

type ListedFunctionFile = ListedFunction & {
srcFile: string
}

interface ListFunctionsOptions {
basePath?: string
config?: Config
featureFlags?: FeatureFlags
pluginsModulesPath?: string
}

// List all Netlify Functions main entry files for a specific directory
const listFunctions = async function (
relativeSrcFolders: string | string[],
{ featureFlags: inputFeatureFlags }: { featureFlags?: FeatureFlags } = {},
) {
const featureFlags = getFlags(inputFeatureFlags)
const srcFolders = resolveFunctionsDirectories(relativeSrcFolders)
const paths = await listFunctionsDirectories(srcFolders)
const functions = await getFunctionsFromPaths(paths, { featureFlags })
const listedFunctions = [...functions.values()].map(getListedFunction)
return listedFunctions
}

// List all Netlify Functions files for a specific directory
const listFunctionsFiles = async function (
relativeSrcFolders: string | string[],
{ basePath, config, featureFlags: inputFeatureFlags }: ListFunctionsOptions = {},
) {
const featureFlags = getFlags(inputFeatureFlags)
const srcFolders = resolveFunctionsDirectories(relativeSrcFolders)
const paths = await listFunctionsDirectories(srcFolders)
const [functions, pluginsModulesPath] = await Promise.all([
getFunctionsFromPaths(paths, { config, featureFlags }),
getPluginsModulesPath(srcFolders[0]),
])
const listedFunctionsFiles = await Promise.all(
[...functions.values()].map((func) => getListedFunctionFiles(func, { basePath, featureFlags, pluginsModulesPath })),
)

return listedFunctionsFiles.flat()
}

const getListedFunction = function ({ runtime, name, mainFile, extension }: FunctionSource): ListedFunction {
return { name, mainFile, runtime: runtime.name, extension }
}

const getListedFunctionFiles = async function (
func: FunctionSource,
options: { basePath?: string; featureFlags: FeatureFlags; pluginsModulesPath?: string },
): Promise<ListedFunctionFile[]> {
const srcFiles = await getSrcFiles({ ...func, ...options })
const { name, mainFile, runtime } = func

return srcFiles.map((srcFile) => ({ srcFile, name, mainFile, runtime: runtime.name, extension: extname(srcFile) }))
}

const getSrcFiles: GetSrcFilesFunction = async function ({ extension, runtime, srcPath, ...args }) {
const { getSrcFiles: getRuntimeSrcFiles } = runtime

if (extension === '.zip' || typeof getRuntimeSrcFiles !== 'function') {
return [srcPath]
}

return await getRuntimeSrcFiles({
extension,
runtime,
srcPath,
...args,
})
}

export { zipFunctions, zipFunction, listFunctions, listFunctionsFiles }
22 changes: 0 additions & 22 deletions src/manifest.js

This file was deleted.

28 changes: 28 additions & 0 deletions src/manifest.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { resolve } from 'path'
import { arch, platform } from 'process'

import { FunctionResult } from './utils/format_result'
import { writeFile } from './utils/fs'

const MANIFEST_VERSION = 1

const createManifest = async ({ functions, path }: { functions: FunctionResult[]; path: string }) => {
const formattedFunctions = functions.map(formatFunctionForManifest)
const payload = {
functions: formattedFunctions,
system: { arch, platform },
timestamp: Date.now(),
version: MANIFEST_VERSION,
}

await writeFile(path, JSON.stringify(payload))
}

const formatFunctionForManifest = ({ mainFile, name, path, runtime }: FunctionResult) => ({
mainFile,
name,
path: resolve(path),
runtime,
})

export { createManifest }
4 changes: 2 additions & 2 deletions src/runtimes/go/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { RUNTIME_GO } from '../../utils/consts'
import { cachedLstat, cachedReaddir, FsCache } from '../../utils/fs'
import { nonNullable } from '../../utils/non_nullable'
import { detectBinaryRuntime } from '../detect_runtime'
import { FindFunctionsInPathsFunction, ZipFunction } from '../runtime'
import { FindFunctionsInPathsFunction, Runtime, ZipFunction } from '../runtime'

import { build } from './builder'

Expand Down Expand Up @@ -115,6 +115,6 @@ const zipFunction: ZipFunction = async function ({ config, destFolder, filename,
return { config, path: destPath }
}

const runtime = { findFunctionsInPaths, name: RUNTIME_GO, zipFunction }
const runtime: Runtime = { findFunctionsInPaths, name: 'go', zipFunction }

export default runtime
2 changes: 1 addition & 1 deletion src/runtimes/node/bundlers/esbuild/src_files.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { GetSrcFilesFunction } from '..'
import type { GetSrcFilesFunction } from '../../../runtime'
import { filterExcludedPaths, getPathsOfIncludedFiles } from '../../utils/included_files'
import { getPackageJson, PackageJson } from '../../utils/package_json'
import { getNewCache, TraversalCache } from '../../utils/traversal_cache'
Expand Down

1 comment on commit d51c860

@github-actions
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⏱ Benchmark results

largeDepsEsbuild: 8.7s

largeDepsNft: 57.2s

largeDepsZisi: 1m 11.4s

Please sign in to comment.