@netlify/zip-it-and-ship-it 8.0.0 → 8.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/archive.d.ts +1 -1
- package/dist/config.d.ts +3 -3
- package/dist/feature_flags.d.ts +2 -2
- package/dist/feature_flags.js +6 -0
- package/dist/function.d.ts +2 -2
- package/dist/main.d.ts +1 -1
- package/dist/main.js +7 -3
- package/dist/runtimes/detect_runtime.d.ts +1 -3
- package/dist/runtimes/detect_runtime.js +4 -7
- package/dist/runtimes/go/index.js +14 -16
- package/dist/runtimes/index.d.ts +6 -3
- package/dist/runtimes/index.js +6 -12
- package/dist/runtimes/node/bundlers/esbuild/bundler.js +11 -0
- package/dist/runtimes/node/bundlers/esbuild/bundler_target.d.ts +2 -1
- package/dist/runtimes/node/bundlers/esbuild/bundler_target.js +1 -0
- package/dist/runtimes/node/bundlers/esbuild/plugin_dynamic_imports.js +9 -7
- package/dist/runtimes/node/bundlers/esbuild/plugin_native_modules.js +1 -1
- package/dist/runtimes/node/bundlers/esbuild/src_files.js +2 -2
- package/dist/runtimes/node/bundlers/nft/es_modules.d.ts +3 -3
- package/dist/runtimes/node/bundlers/nft/es_modules.js +11 -10
- package/dist/runtimes/node/bundlers/nft/index.js +11 -12
- package/dist/runtimes/node/bundlers/types.d.ts +7 -5
- package/dist/runtimes/node/bundlers/zisi/list_imports.d.ts +3 -1
- package/dist/runtimes/node/bundlers/zisi/list_imports.js +19 -1
- package/dist/runtimes/node/bundlers/zisi/resolve.js +1 -1
- package/dist/runtimes/node/bundlers/zisi/src_files.js +2 -5
- package/dist/runtimes/node/finder.js +10 -8
- package/dist/runtimes/node/in_source_config/index.d.ts +2 -2
- package/dist/runtimes/node/index.js +3 -1
- package/dist/runtimes/node/parser/bindings.d.ts +2 -2
- package/dist/runtimes/node/parser/index.js +4 -0
- package/dist/runtimes/node/utils/node_version.d.ts +3 -3
- package/dist/runtimes/node/utils/package_json.d.ts +2 -1
- package/dist/runtimes/node/utils/package_json.js +8 -8
- package/dist/runtimes/node/utils/plugin_modules_path.js +1 -1
- package/dist/runtimes/node/utils/zip.d.ts +3 -1
- package/dist/runtimes/node/utils/zip.js +5 -5
- package/dist/runtimes/runtime.d.ts +12 -11
- package/dist/runtimes/rust/builder.d.ts +4 -2
- package/dist/runtimes/rust/builder.js +6 -5
- package/dist/runtimes/rust/index.js +17 -19
- package/dist/utils/cache.d.ts +16 -0
- package/dist/utils/cache.js +10 -0
- package/dist/utils/error.d.ts +1 -1
- package/dist/utils/format_result.d.ts +1 -1
- package/dist/utils/fs.d.ts +5 -11
- package/dist/utils/fs.js +26 -15
- package/dist/utils/logger.d.ts +8 -0
- package/dist/utils/logger.js +15 -0
- package/dist/utils/remove_undefined.js +3 -2
- package/dist/utils/shell.d.ts +2 -20
- package/dist/utils/shell.js +1 -1
- package/dist/utils/timer.d.ts +2 -0
- package/dist/utils/timer.js +12 -0
- package/dist/zip.d.ts +6 -3
- package/dist/zip.js +38 -4
- package/package.json +13 -13
package/README.md
CHANGED
package/dist/archive.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { Stats } from 'fs';
|
|
|
3
3
|
import { Writable } from 'stream';
|
|
4
4
|
import { Archiver } from 'archiver';
|
|
5
5
|
export { Archiver as ZipArchive } from 'archiver';
|
|
6
|
-
export
|
|
6
|
+
export type ArchiveFormat = 'none' | 'zip';
|
|
7
7
|
export declare const startZip: (destPath: string) => {
|
|
8
8
|
archive: Archiver;
|
|
9
9
|
output: Writable;
|
package/dist/config.d.ts
CHANGED
|
@@ -17,9 +17,9 @@ interface FunctionConfig {
|
|
|
17
17
|
zipGo?: boolean;
|
|
18
18
|
nodeModuleFormat?: ModuleFormat;
|
|
19
19
|
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
20
|
+
type GlobPattern = string;
|
|
21
|
+
type Config = Record<GlobPattern, FunctionConfig>;
|
|
22
|
+
type FunctionWithoutConfig = Omit<FunctionSource, 'config'>;
|
|
23
23
|
declare const getConfigForFunction: ({ config, configFileDirectories, func, featureFlags, }: {
|
|
24
24
|
config?: Config | undefined;
|
|
25
25
|
configFileDirectories?: string[] | undefined;
|
package/dist/feature_flags.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export declare const defaultFlags: Record<string, boolean>;
|
|
2
|
-
export
|
|
3
|
-
export
|
|
2
|
+
export type FeatureFlag = keyof typeof defaultFlags;
|
|
3
|
+
export type FeatureFlags = Record<FeatureFlag, boolean>;
|
|
4
4
|
export declare const getFlags: (input?: Record<string, boolean>, flags?: Record<string, boolean>) => FeatureFlags;
|
package/dist/feature_flags.js
CHANGED
|
@@ -14,6 +14,12 @@ export const defaultFlags = {
|
|
|
14
14
|
zisi_pure_esm_mjs: false,
|
|
15
15
|
// Load configuration from per-function JSON files.
|
|
16
16
|
project_deploy_configuration_api_use_per_function_configuration_files: false,
|
|
17
|
+
// Enable runtime cache for NFT
|
|
18
|
+
zisi_nft_use_cache: false,
|
|
19
|
+
// Raise file IO limit for NFT
|
|
20
|
+
zisi_nft_higher_fileio_limit: false,
|
|
21
|
+
// Provide banner to esbuild which allows requires in ESM output
|
|
22
|
+
zisi_esbuild_require_banner: false,
|
|
17
23
|
};
|
|
18
24
|
// List of supported flags and their default value.
|
|
19
25
|
export const getFlags = (input = {}, flags = defaultFlags) => Object.entries(flags).reduce((result, [key, defaultValue]) => ({
|
package/dist/function.d.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { Stats } from 'fs';
|
|
3
3
|
import type { FunctionConfig } from './config.js';
|
|
4
4
|
import type { Runtime, ZipFunctionResult } from './runtimes/runtime.js';
|
|
5
|
-
export
|
|
5
|
+
export type FunctionArchive = ZipFunctionResult & {
|
|
6
6
|
mainFile: string;
|
|
7
7
|
name: string;
|
|
8
8
|
runtime: Runtime;
|
|
@@ -17,7 +17,7 @@ export interface SourceFile {
|
|
|
17
17
|
srcPath: string;
|
|
18
18
|
stat: Stats;
|
|
19
19
|
}
|
|
20
|
-
export
|
|
20
|
+
export type FunctionSource = SourceFile & {
|
|
21
21
|
config: FunctionConfig;
|
|
22
22
|
runtime: Runtime;
|
|
23
23
|
};
|
package/dist/main.d.ts
CHANGED
package/dist/main.js
CHANGED
|
@@ -2,6 +2,7 @@ import { extname } from 'path';
|
|
|
2
2
|
import { getFlags } from './feature_flags.js';
|
|
3
3
|
import { getFunctionFromPath, getFunctionsFromPaths } from './runtimes/index.js';
|
|
4
4
|
import { findISCDeclarationsInPath } from './runtimes/node/in_source_config/index.js';
|
|
5
|
+
import { RuntimeCache } from './utils/cache.js';
|
|
5
6
|
import { listFunctionsDirectories, resolveFunctionsDirectories } from './utils/fs.js';
|
|
6
7
|
export { zipFunction, zipFunctions } from './zip.js';
|
|
7
8
|
const augmentWithISC = async (func) => {
|
|
@@ -17,7 +18,8 @@ export const listFunctions = async function (relativeSrcFolders, { featureFlags:
|
|
|
17
18
|
const featureFlags = getFlags(inputFeatureFlags);
|
|
18
19
|
const srcFolders = resolveFunctionsDirectories(relativeSrcFolders);
|
|
19
20
|
const paths = await listFunctionsDirectories(srcFolders);
|
|
20
|
-
const
|
|
21
|
+
const cache = new RuntimeCache();
|
|
22
|
+
const functionsMap = await getFunctionsFromPaths(paths, { cache, config, featureFlags });
|
|
21
23
|
const functions = [...functionsMap.values()];
|
|
22
24
|
const augmentedFunctions = parseISC ? await Promise.all(functions.map(augmentWithISC)) : functions;
|
|
23
25
|
return augmentedFunctions.map(getListedFunction);
|
|
@@ -25,7 +27,8 @@ export const listFunctions = async function (relativeSrcFolders, { featureFlags:
|
|
|
25
27
|
// Finds a function at a specific path.
|
|
26
28
|
export const listFunction = async function (path, { featureFlags: inputFeatureFlags, config, parseISC = false, } = {}) {
|
|
27
29
|
const featureFlags = getFlags(inputFeatureFlags);
|
|
28
|
-
const
|
|
30
|
+
const cache = new RuntimeCache();
|
|
31
|
+
const func = await getFunctionFromPath(path, { cache, config, featureFlags });
|
|
29
32
|
if (!func) {
|
|
30
33
|
return;
|
|
31
34
|
}
|
|
@@ -37,7 +40,8 @@ export const listFunctionsFiles = async function (relativeSrcFolders, { basePath
|
|
|
37
40
|
const featureFlags = getFlags(inputFeatureFlags);
|
|
38
41
|
const srcFolders = resolveFunctionsDirectories(relativeSrcFolders);
|
|
39
42
|
const paths = await listFunctionsDirectories(srcFolders);
|
|
40
|
-
const
|
|
43
|
+
const cache = new RuntimeCache();
|
|
44
|
+
const functionsMap = await getFunctionsFromPaths(paths, { cache, config, featureFlags });
|
|
41
45
|
const functions = [...functionsMap.values()];
|
|
42
46
|
const augmentedFunctions = parseISC ? await Promise.all(functions.map(augmentWithISC)) : functions;
|
|
43
47
|
const listedFunctionsFiles = await Promise.all(augmentedFunctions.map((func) => getListedFunctionFiles(func, { basePath, featureFlags })));
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
import { FsCache } from '../utils/fs.js';
|
|
2
1
|
import { RuntimeType } from './runtime.js';
|
|
3
|
-
export declare const detectBinaryRuntime: ({
|
|
4
|
-
fsCache: FsCache;
|
|
2
|
+
export declare const detectBinaryRuntime: ({ path }: {
|
|
5
3
|
path: string;
|
|
6
4
|
}) => Promise<RuntimeType | undefined>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import { readFile } from 'fs/promises';
|
|
1
2
|
import { detect, Runtime as BinaryRuntime, Arch, Platform } from '@netlify/binary-info';
|
|
2
|
-
import { cachedReadFile } from '../utils/fs.js';
|
|
3
3
|
const isValidFunctionBinary = (info) => info.arch === Arch.Amd64 && info.platform === Platform.Linux;
|
|
4
4
|
const warnIncompatibleBinary = function (path, binaryInfo) {
|
|
5
5
|
if (!global.ZISI_CLI) {
|
|
@@ -10,13 +10,10 @@ The binary needs to be built for Linux/Amd64, but it was built for ${Platform[bi
|
|
|
10
10
|
return undefined;
|
|
11
11
|
};
|
|
12
12
|
// Try to guess the runtime by inspecting the binary file.
|
|
13
|
-
export const detectBinaryRuntime = async function ({
|
|
13
|
+
export const detectBinaryRuntime = async function ({ path }) {
|
|
14
14
|
try {
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
// loses part of the return type information. We can safely say it's a
|
|
18
|
-
// Buffer in this case because we're not specifying an encoding.
|
|
19
|
-
const binaryInfo = detect(buffer);
|
|
15
|
+
const fileContents = await readFile(path);
|
|
16
|
+
const binaryInfo = detect(fileContents);
|
|
20
17
|
if (!isValidFunctionBinary(binaryInfo)) {
|
|
21
18
|
return warnIncompatibleBinary(path, binaryInfo);
|
|
22
19
|
}
|
|
@@ -5,37 +5,35 @@ import { nonNullable } from '../../utils/non_nullable.js';
|
|
|
5
5
|
import { zipBinary } from '../../zip_binary.js';
|
|
6
6
|
import { detectBinaryRuntime } from '../detect_runtime.js';
|
|
7
7
|
import { build } from './builder.js';
|
|
8
|
-
const detectGoFunction = async ({
|
|
9
|
-
const stat = await cachedLstat(
|
|
8
|
+
const detectGoFunction = async ({ cache, path }) => {
|
|
9
|
+
const stat = await cachedLstat(cache.lstatCache, path);
|
|
10
10
|
if (!stat.isDirectory()) {
|
|
11
11
|
return;
|
|
12
12
|
}
|
|
13
13
|
const directoryName = basename(path);
|
|
14
|
-
|
|
15
|
-
// return value of `readdir` to be incorrectly typed.
|
|
16
|
-
const files = (await cachedReaddir(fsCache, path));
|
|
14
|
+
const files = await cachedReaddir(cache.readdirCache, path);
|
|
17
15
|
const mainFileName = [`${directoryName}.go`, 'main.go'].find((name) => files.includes(name));
|
|
18
16
|
if (mainFileName === undefined) {
|
|
19
17
|
return;
|
|
20
18
|
}
|
|
21
19
|
return mainFileName;
|
|
22
20
|
};
|
|
23
|
-
const findFunctionsInPaths = async function ({
|
|
24
|
-
const functions = await Promise.all(paths.map((path) => findFunctionInPath({
|
|
21
|
+
const findFunctionsInPaths = async function ({ cache, featureFlags, paths }) {
|
|
22
|
+
const functions = await Promise.all(paths.map((path) => findFunctionInPath({ cache, featureFlags, path })));
|
|
25
23
|
return functions.filter(nonNullable);
|
|
26
24
|
};
|
|
27
|
-
const findFunctionInPath = async function ({
|
|
28
|
-
const runtime = await detectBinaryRuntime({
|
|
25
|
+
const findFunctionInPath = async function ({ cache, path }) {
|
|
26
|
+
const runtime = await detectBinaryRuntime({ path });
|
|
29
27
|
if (runtime === "go" /* RuntimeType.GO */) {
|
|
30
|
-
return processBinary({
|
|
28
|
+
return processBinary({ cache, path });
|
|
31
29
|
}
|
|
32
|
-
const goSourceFile = await detectGoFunction({
|
|
30
|
+
const goSourceFile = await detectGoFunction({ cache, path });
|
|
33
31
|
if (goSourceFile) {
|
|
34
|
-
return processSource({
|
|
32
|
+
return processSource({ cache, mainFile: goSourceFile, path });
|
|
35
33
|
}
|
|
36
34
|
};
|
|
37
|
-
const processBinary = async ({
|
|
38
|
-
const stat =
|
|
35
|
+
const processBinary = async ({ cache, path }) => {
|
|
36
|
+
const stat = await cachedLstat(cache.lstatCache, path);
|
|
39
37
|
const extension = extname(path);
|
|
40
38
|
const filename = basename(path);
|
|
41
39
|
const name = basename(path, extname(path));
|
|
@@ -49,12 +47,12 @@ const processBinary = async ({ fsCache, path }) => {
|
|
|
49
47
|
stat,
|
|
50
48
|
};
|
|
51
49
|
};
|
|
52
|
-
const processSource = async ({
|
|
50
|
+
const processSource = async ({ cache, mainFile, path, }) => {
|
|
53
51
|
// TODO: This `stat` value is not going to be used, but we need it to satisfy
|
|
54
52
|
// the `FunctionSource` interface. We should revisit whether `stat` should be
|
|
55
53
|
// part of that interface in the first place, or whether we could compute it
|
|
56
54
|
// downstream when needed (maybe using the FS cache as an optimisation).
|
|
57
|
-
const stat = (await cachedLstat(
|
|
55
|
+
const stat = (await cachedLstat(cache.lstatCache, path));
|
|
58
56
|
const filename = basename(path);
|
|
59
57
|
const extension = extname(mainFile);
|
|
60
58
|
const name = basename(path, extname(path));
|
package/dist/runtimes/index.d.ts
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { Config } from '../config.js';
|
|
2
2
|
import { FeatureFlags } from '../feature_flags.js';
|
|
3
3
|
import { FunctionSource } from '../function.js';
|
|
4
|
-
|
|
4
|
+
import type { RuntimeCache } from '../utils/cache.js';
|
|
5
|
+
type FunctionMap = Map<string, FunctionSource>;
|
|
5
6
|
/**
|
|
6
7
|
* Gets a list of functions found in a list of paths.
|
|
7
8
|
*/
|
|
8
|
-
export declare const getFunctionsFromPaths: (paths: string[], { config, configFileDirectories, dedupe, featureFlags, }
|
|
9
|
+
export declare const getFunctionsFromPaths: (paths: string[], { cache, config, configFileDirectories, dedupe, featureFlags, }: {
|
|
10
|
+
cache: RuntimeCache;
|
|
9
11
|
config?: Config | undefined;
|
|
10
12
|
configFileDirectories?: string[] | undefined;
|
|
11
13
|
dedupe?: boolean | undefined;
|
|
@@ -14,7 +16,8 @@ export declare const getFunctionsFromPaths: (paths: string[], { config, configFi
|
|
|
14
16
|
/**
|
|
15
17
|
* Gets a list of functions found in a list of paths.
|
|
16
18
|
*/
|
|
17
|
-
export declare const getFunctionFromPath: (path: string, { config, featureFlags }
|
|
19
|
+
export declare const getFunctionFromPath: (path: string, { cache, config, featureFlags }: {
|
|
20
|
+
cache: RuntimeCache;
|
|
18
21
|
config?: Config | undefined;
|
|
19
22
|
featureFlags?: FeatureFlags | undefined;
|
|
20
23
|
}) => Promise<FunctionSource | undefined>;
|
package/dist/runtimes/index.js
CHANGED
|
@@ -10,8 +10,8 @@ import rustRuntime from './rust/index.js';
|
|
|
10
10
|
* and an array with the paths that haven't been recognized by the runtime
|
|
11
11
|
* (`remainingPaths`).
|
|
12
12
|
*/
|
|
13
|
-
const findFunctionsInRuntime = async function ({ dedupe = false, featureFlags,
|
|
14
|
-
const functions = await runtime.findFunctionsInPaths({
|
|
13
|
+
const findFunctionsInRuntime = async function ({ cache, dedupe = false, featureFlags, paths, runtime, }) {
|
|
14
|
+
const functions = await runtime.findFunctionsInPaths({ cache, featureFlags, paths });
|
|
15
15
|
// If `dedupe` is true, we use the function name (`filename`) as the map key,
|
|
16
16
|
// so that `function-1.js` will overwrite `function-1.go`. Otherwise, we use
|
|
17
17
|
// `srcPath`, so that both functions are returned.
|
|
@@ -30,10 +30,6 @@ const findFunctionsInRuntime = async function ({ dedupe = false, featureFlags, f
|
|
|
30
30
|
const remainingPaths = paths.filter((path) => !usedPaths.has(path));
|
|
31
31
|
return { functions: augmentedFunctions, remainingPaths };
|
|
32
32
|
};
|
|
33
|
-
// An object to cache filesystem operations. This allows different functions
|
|
34
|
-
// to perform IO operations on the same file (i.e. getting its stats or its
|
|
35
|
-
// contents) without duplicating work.
|
|
36
|
-
const makeFsCache = () => ({});
|
|
37
33
|
// The order of this array determines the priority of the runtimes. If a path
|
|
38
34
|
// is used by the first time, it won't be made available to the subsequent
|
|
39
35
|
// runtimes.
|
|
@@ -41,8 +37,7 @@ const RUNTIMES = [jsRuntime, goRuntime, rustRuntime];
|
|
|
41
37
|
/**
|
|
42
38
|
* Gets a list of functions found in a list of paths.
|
|
43
39
|
*/
|
|
44
|
-
export const getFunctionsFromPaths = async (paths, { config, configFileDirectories = [], dedupe = false, featureFlags = defaultFlags, }
|
|
45
|
-
const fsCache = makeFsCache();
|
|
40
|
+
export const getFunctionsFromPaths = async (paths, { cache, config, configFileDirectories = [], dedupe = false, featureFlags = defaultFlags, }) => {
|
|
46
41
|
// We cycle through the ordered array of runtimes, passing each one of them
|
|
47
42
|
// through `findFunctionsInRuntime`. For each iteration, we collect all the
|
|
48
43
|
// functions found plus the list of paths that still need to be evaluated,
|
|
@@ -50,9 +45,9 @@ export const getFunctionsFromPaths = async (paths, { config, configFileDirectori
|
|
|
50
45
|
const { functions } = await RUNTIMES.reduce(async (aggregate, runtime) => {
|
|
51
46
|
const { functions: aggregateFunctions, remainingPaths: aggregatePaths } = await aggregate;
|
|
52
47
|
const { functions: runtimeFunctions, remainingPaths: runtimePaths } = await findFunctionsInRuntime({
|
|
48
|
+
cache,
|
|
53
49
|
dedupe,
|
|
54
50
|
featureFlags,
|
|
55
|
-
fsCache,
|
|
56
51
|
paths: aggregatePaths,
|
|
57
52
|
runtime,
|
|
58
53
|
});
|
|
@@ -71,10 +66,9 @@ export const getFunctionsFromPaths = async (paths, { config, configFileDirectori
|
|
|
71
66
|
/**
|
|
72
67
|
* Gets a list of functions found in a list of paths.
|
|
73
68
|
*/
|
|
74
|
-
export const getFunctionFromPath = async (path, { config, featureFlags = defaultFlags }
|
|
75
|
-
const fsCache = makeFsCache();
|
|
69
|
+
export const getFunctionFromPath = async (path, { cache, config, featureFlags = defaultFlags }) => {
|
|
76
70
|
for (const runtime of RUNTIMES) {
|
|
77
|
-
const func = await runtime.findFunctionInPath({ path,
|
|
71
|
+
const func = await runtime.findFunctionInPath({ path, cache, featureFlags });
|
|
78
72
|
if (func) {
|
|
79
73
|
const functionConfig = await getConfigForFunction({ config, func: { ...func, runtime }, featureFlags });
|
|
80
74
|
return {
|
|
@@ -59,8 +59,19 @@ export const bundleJsFile = async function ({ additionalModulePaths, basePath, c
|
|
|
59
59
|
const extension = getFileExtensionForFormat(moduleFormat, featureFlags);
|
|
60
60
|
// When outputting an ESM file, configure esbuild to produce a `.mjs` file.
|
|
61
61
|
const outExtension = moduleFormat === "esm" /* ModuleFormat.ESM */ ? { [".js" /* ModuleFileExtension.JS */]: ".mjs" /* ModuleFileExtension.MJS */ } : undefined;
|
|
62
|
+
// We add this banner so that calls to require() still work in ESM modules, especially when importing node built-ins
|
|
63
|
+
// We have to do this until this is fixed in esbuild: https://github.com/evanw/esbuild/pull/2067
|
|
64
|
+
const esmJSBanner = `
|
|
65
|
+
import {createRequire as ___nfyCreateRequire} from "module";
|
|
66
|
+
import {fileURLToPath as ___nfyFileURLToPath} from "url";
|
|
67
|
+
import {dirname as ___nfyPathDirname} from "path";
|
|
68
|
+
let __filename=___nfyFileURLToPath(import.meta.url);
|
|
69
|
+
let __dirname=___nfyPathDirname(___nfyFileURLToPath(import.meta.url));
|
|
70
|
+
let require=___nfyCreateRequire(import.meta.url);
|
|
71
|
+
`;
|
|
62
72
|
try {
|
|
63
73
|
const { metafile = { inputs: {}, outputs: {} }, warnings } = await build({
|
|
74
|
+
banner: moduleFormat === "esm" /* ModuleFormat.ESM */ && featureFlags.zisi_esbuild_require_banner ? { js: esmJSBanner } : undefined,
|
|
64
75
|
bundle: true,
|
|
65
76
|
entryPoints: [srcFile],
|
|
66
77
|
external,
|
|
@@ -7,8 +7,9 @@ declare const versionMap: {
|
|
|
7
7
|
readonly '12.x': "node12";
|
|
8
8
|
readonly '14.x': "node14";
|
|
9
9
|
readonly '16.x': "node16";
|
|
10
|
+
readonly '18.x': "node18";
|
|
10
11
|
};
|
|
11
|
-
|
|
12
|
+
type VersionValues = typeof versionMap[keyof typeof versionMap];
|
|
12
13
|
declare const getBundlerTarget: (suppliedVersion?: NodeVersionString) => VersionValues;
|
|
13
14
|
declare const getModuleFormat: (srcDir: string, featureFlags: FeatureFlags, extension: string, configVersion?: string) => Promise<{
|
|
14
15
|
includedFiles: string[];
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { basename, join, relative } from 'path';
|
|
2
|
-
import findUp from 'find-up';
|
|
2
|
+
import { findUp, findUpStop, pathExists } from 'find-up';
|
|
3
3
|
import normalizePath from 'normalize-path';
|
|
4
|
-
import readPackageJson from 'read-package-json-fast';
|
|
5
4
|
import { parseExpression } from '../../parser/index.js';
|
|
5
|
+
import { readPackageJson } from '../../utils/package_json.js';
|
|
6
6
|
// This plugin intercepts module imports using dynamic expressions and does a
|
|
7
7
|
// couple of things with them. First of all, it figures out whether the call
|
|
8
8
|
// is being made from within a Node module, and if so it adds the name of the
|
|
@@ -49,10 +49,10 @@ const getPackageName = async ({ resolveDir, srcDir }) => {
|
|
|
49
49
|
// We stop traversing if we're about to leave the boundaries of the
|
|
50
50
|
// function directory or any node_modules directory.
|
|
51
51
|
if (directory === srcDir || basename(directory) === 'node_modules') {
|
|
52
|
-
return
|
|
52
|
+
return findUpStop;
|
|
53
53
|
}
|
|
54
54
|
const path = join(directory, 'package.json');
|
|
55
|
-
const hasPackageJson = await
|
|
55
|
+
const hasPackageJson = await pathExists(path);
|
|
56
56
|
return hasPackageJson ? path : undefined;
|
|
57
57
|
}, { cwd: resolveDir });
|
|
58
58
|
if (packageJsonPath !== undefined) {
|
|
@@ -61,10 +61,12 @@ const getPackageName = async ({ resolveDir, srcDir }) => {
|
|
|
61
61
|
}
|
|
62
62
|
};
|
|
63
63
|
const getPackageNameCached = ({ cache, resolveDir, srcDir, }) => {
|
|
64
|
-
|
|
65
|
-
|
|
64
|
+
let result = cache.get(resolveDir);
|
|
65
|
+
if (result === undefined) {
|
|
66
|
+
result = getPackageName({ resolveDir, srcDir });
|
|
67
|
+
cache.set(resolveDir, result);
|
|
66
68
|
}
|
|
67
|
-
return
|
|
69
|
+
return result;
|
|
68
70
|
};
|
|
69
71
|
const getShimContents = ({ expressionType, resolveDir, srcDir, }) => {
|
|
70
72
|
// The shim needs to modify the path of the import, since originally it was
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import path from 'path';
|
|
2
|
-
import readPackageJson from 'read-package-json-fast';
|
|
3
2
|
import { isNativeModule } from '../../utils/detect_native_module.js';
|
|
3
|
+
import { readPackageJson } from '../../utils/package_json.js';
|
|
4
4
|
// Filters out relative or absolute file paths.
|
|
5
5
|
const packageFilter = /^([^./]*)$/;
|
|
6
6
|
// Filters valid package names and extracts the base directory.
|
|
@@ -6,8 +6,8 @@ export const getSrcFiles = async ({ config, mainFile, pluginsModulesPath, srcDir
|
|
|
6
6
|
const { externalNodeModules = [], includedFiles = [], includedFilesBasePath } = config;
|
|
7
7
|
const { excludePatterns, paths: includedFilePaths } = await getPathsOfIncludedFiles(includedFiles, includedFilesBasePath);
|
|
8
8
|
const dependencyPaths = await getSrcFilesForDependencies({
|
|
9
|
-
dependencies: externalNodeModules,
|
|
10
9
|
basedir: srcDir,
|
|
10
|
+
dependencies: externalNodeModules,
|
|
11
11
|
pluginsModulesPath,
|
|
12
12
|
});
|
|
13
13
|
const srcFiles = filterExcludedPaths(dependencyPaths, excludePatterns);
|
|
@@ -17,7 +17,7 @@ export const getSrcFiles = async ({ config, mainFile, pluginsModulesPath, srcDir
|
|
|
17
17
|
includedFiles: includedPaths,
|
|
18
18
|
};
|
|
19
19
|
};
|
|
20
|
-
const getSrcFilesForDependencies = async function ({ dependencies: dependencyNames,
|
|
20
|
+
const getSrcFilesForDependencies = async function ({ basedir, dependencies: dependencyNames, state = getNewCache(), pluginsModulesPath, }) {
|
|
21
21
|
if (dependencyNames.length === 0) {
|
|
22
22
|
return [];
|
|
23
23
|
}
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { NodeFileTraceReasons } from '@vercel/nft';
|
|
2
2
|
import type { FunctionConfig } from '../../../../config.js';
|
|
3
3
|
import { FeatureFlags } from '../../../../feature_flags.js';
|
|
4
|
-
import {
|
|
4
|
+
import type { RuntimeCache } from '../../../../utils/cache.js';
|
|
5
5
|
import { ModuleFormat } from '../../utils/module_format.js';
|
|
6
|
-
export declare const processESM: ({ basePath, config, esmPaths, featureFlags,
|
|
6
|
+
export declare const processESM: ({ basePath, cache, config, esmPaths, featureFlags, mainFile, reasons, name, }: {
|
|
7
7
|
basePath: string | undefined;
|
|
8
|
+
cache: RuntimeCache;
|
|
8
9
|
config: FunctionConfig;
|
|
9
10
|
esmPaths: Set<string>;
|
|
10
11
|
featureFlags: FeatureFlags;
|
|
11
|
-
fsCache: FsCache;
|
|
12
12
|
mainFile: string;
|
|
13
13
|
reasons: NodeFileTraceReasons;
|
|
14
14
|
name: string;
|
|
@@ -3,8 +3,8 @@ import { cachedReadFile } from '../../../../utils/fs.js';
|
|
|
3
3
|
import { getNodeSupportMatrix } from '../../utils/node_version.js';
|
|
4
4
|
import { getPackageJsonIfAvailable } from '../../utils/package_json.js';
|
|
5
5
|
import { transpile } from './transpile.js';
|
|
6
|
-
const getPatchedESMPackages = async (packages,
|
|
7
|
-
const patchedPackages = await Promise.all(packages.map((path) => patchESMPackage(path,
|
|
6
|
+
const getPatchedESMPackages = async (packages, cache) => {
|
|
7
|
+
const patchedPackages = await Promise.all(packages.map((path) => patchESMPackage(path, cache)));
|
|
8
8
|
const patchedPackagesMap = new Map();
|
|
9
9
|
packages.forEach((packagePath, index) => {
|
|
10
10
|
patchedPackagesMap.set(packagePath, patchedPackages[index]);
|
|
@@ -16,8 +16,8 @@ const isEntrypointESM = ({ basePath, esmPaths, mainFile, }) => {
|
|
|
16
16
|
const entrypointIsESM = absoluteESMPaths.has(mainFile);
|
|
17
17
|
return entrypointIsESM;
|
|
18
18
|
};
|
|
19
|
-
const patchESMPackage = async (path,
|
|
20
|
-
const file =
|
|
19
|
+
const patchESMPackage = async (path, cache) => {
|
|
20
|
+
const file = await cachedReadFile(cache.fileCache, path);
|
|
21
21
|
const packageJson = JSON.parse(file);
|
|
22
22
|
const patchedPackageJson = {
|
|
23
23
|
...packageJson,
|
|
@@ -25,7 +25,7 @@ const patchESMPackage = async (path, fsCache) => {
|
|
|
25
25
|
};
|
|
26
26
|
return JSON.stringify(patchedPackageJson);
|
|
27
27
|
};
|
|
28
|
-
export const processESM = async ({ basePath, config, esmPaths, featureFlags,
|
|
28
|
+
export const processESM = async ({ basePath, cache, config, esmPaths, featureFlags, mainFile, reasons, name, }) => {
|
|
29
29
|
const extension = extname(mainFile);
|
|
30
30
|
// If this is a .mjs file and we want to output pure ESM files, we don't need
|
|
31
31
|
// to transpile anything.
|
|
@@ -47,7 +47,7 @@ export const processESM = async ({ basePath, config, esmPaths, featureFlags, fsC
|
|
|
47
47
|
moduleFormat: "esm" /* ModuleFormat.ESM */,
|
|
48
48
|
};
|
|
49
49
|
}
|
|
50
|
-
const rewrites = await transpileESM({ basePath, config, esmPaths,
|
|
50
|
+
const rewrites = await transpileESM({ basePath, cache, config, esmPaths, reasons, name });
|
|
51
51
|
return {
|
|
52
52
|
moduleFormat: "cjs" /* ModuleFormat.COMMONJS */,
|
|
53
53
|
rewrites,
|
|
@@ -79,9 +79,10 @@ const shouldTranspile = (path, cache, esmPaths, reasons) => {
|
|
|
79
79
|
cache.set(path, shouldTranspilePath);
|
|
80
80
|
return shouldTranspilePath;
|
|
81
81
|
};
|
|
82
|
-
const transpileESM = async ({ basePath, config, esmPaths,
|
|
83
|
-
|
|
84
|
-
const
|
|
82
|
+
const transpileESM = async ({ basePath, cache, config, esmPaths, reasons, name, }) => {
|
|
83
|
+
// Used for memoizing the check for whether a path should be transpiled.
|
|
84
|
+
const shouldCompileCache = new Map();
|
|
85
|
+
const pathsToTranspile = [...esmPaths].filter((path) => shouldTranspile(path, shouldCompileCache, esmPaths, reasons));
|
|
85
86
|
const pathsToTranspileSet = new Set(pathsToTranspile);
|
|
86
87
|
const packageJsonPaths = [...reasons.entries()]
|
|
87
88
|
.filter(([path, reason]) => {
|
|
@@ -92,7 +93,7 @@ const transpileESM = async ({ basePath, config, esmPaths, fsCache, reasons, name
|
|
|
92
93
|
return needsPatch;
|
|
93
94
|
})
|
|
94
95
|
.map(([path]) => (basePath ? resolve(basePath, path) : resolve(path)));
|
|
95
|
-
const rewrites = await getPatchedESMPackages(packageJsonPaths,
|
|
96
|
+
const rewrites = await getPatchedESMPackages(packageJsonPaths, cache);
|
|
96
97
|
await Promise.all(pathsToTranspile.map(async (path) => {
|
|
97
98
|
const absolutePath = resolvePath(path, basePath);
|
|
98
99
|
const transpiled = await transpile(absolutePath, config, name);
|
|
@@ -1,23 +1,20 @@
|
|
|
1
1
|
import { basename, dirname, join, normalize, resolve } from 'path';
|
|
2
2
|
import { nodeFileTrace } from '@vercel/nft';
|
|
3
|
-
import
|
|
3
|
+
import resolveDependency from '@vercel/nft/out/resolve-dependency.js';
|
|
4
4
|
import { cachedReadFile } from '../../../../utils/fs.js';
|
|
5
5
|
import { minimatch } from '../../../../utils/matching.js';
|
|
6
6
|
import { getBasePath } from '../../utils/base_path.js';
|
|
7
7
|
import { filterExcludedPaths, getPathsOfIncludedFiles } from '../../utils/included_files.js';
|
|
8
8
|
import { processESM } from './es_modules.js';
|
|
9
|
-
// @ts-expect-error vitest with esbuild already resolves the default export, whereas Node.js does not
|
|
10
|
-
const resolveDependency = nftResolveDependency.default
|
|
11
|
-
? nftResolveDependency.default
|
|
12
|
-
: nftResolveDependency;
|
|
13
9
|
// Paths that will be excluded from the tracing process.
|
|
14
10
|
const ignore = ['node_modules/aws-sdk/**'];
|
|
15
11
|
const appearsToBeModuleName = (name) => !name.startsWith('.');
|
|
16
|
-
const bundle = async ({ basePath, config, featureFlags, mainFile, name, pluginsModulesPath, repositoryRoot = basePath, }) => {
|
|
12
|
+
const bundle = async ({ basePath, cache, config, featureFlags, mainFile, name, pluginsModulesPath, repositoryRoot = basePath, }) => {
|
|
17
13
|
const { includedFiles = [], includedFilesBasePath } = config;
|
|
18
14
|
const { excludePatterns, paths: includedFilePaths } = await getPathsOfIncludedFiles(includedFiles, includedFilesBasePath || basePath);
|
|
19
15
|
const { moduleFormat, paths: dependencyPaths, rewrites, } = await traceFilesAndTranspile({
|
|
20
16
|
basePath: repositoryRoot,
|
|
17
|
+
cache,
|
|
21
18
|
config,
|
|
22
19
|
featureFlags,
|
|
23
20
|
mainFile,
|
|
@@ -43,14 +40,16 @@ const ignoreFunction = (path) => {
|
|
|
43
40
|
const shouldIgnore = ignore.some((expression) => minimatch(path, expression));
|
|
44
41
|
return shouldIgnore;
|
|
45
42
|
};
|
|
46
|
-
const traceFilesAndTranspile = async function ({ basePath, config, featureFlags, mainFile, pluginsModulesPath, name, }) {
|
|
47
|
-
const fsCache = {};
|
|
43
|
+
const traceFilesAndTranspile = async function ({ basePath, cache, config, featureFlags, mainFile, pluginsModulesPath, name, }) {
|
|
48
44
|
const { fileList: dependencyPaths, esmFileList, reasons, } = await nodeFileTrace([mainFile], {
|
|
45
|
+
// Default is 1024. Allowing double the fileIO in parallel makes nft faster, but uses a little more memory.
|
|
46
|
+
fileIOConcurrency: featureFlags.zisi_nft_higher_fileio_limit ? 2048 : 1024,
|
|
49
47
|
base: basePath,
|
|
48
|
+
cache: featureFlags.zisi_nft_use_cache ? cache.nftCache : undefined,
|
|
50
49
|
ignore: ignoreFunction,
|
|
51
50
|
readFile: async (path) => {
|
|
52
51
|
try {
|
|
53
|
-
const source =
|
|
52
|
+
const source = await cachedReadFile(cache.fileCache, path);
|
|
54
53
|
return source;
|
|
55
54
|
}
|
|
56
55
|
catch (error) {
|
|
@@ -62,7 +61,7 @@ const traceFilesAndTranspile = async function ({ basePath, config, featureFlags,
|
|
|
62
61
|
},
|
|
63
62
|
resolve: async (specifier, parent, ...args) => {
|
|
64
63
|
try {
|
|
65
|
-
return await resolveDependency(specifier, parent, ...args);
|
|
64
|
+
return await resolveDependency.default(specifier, parent, ...args);
|
|
66
65
|
}
|
|
67
66
|
catch (error) {
|
|
68
67
|
// If we get a `MODULE_NOT_FOUND` error for what appears to be a module
|
|
@@ -70,7 +69,7 @@ const traceFilesAndTranspile = async function ({ basePath, config, featureFlags,
|
|
|
70
69
|
// as the base directory.
|
|
71
70
|
if (error.code === 'MODULE_NOT_FOUND' && pluginsModulesPath && appearsToBeModuleName(specifier)) {
|
|
72
71
|
const newParent = join(pluginsModulesPath, basename(parent));
|
|
73
|
-
return await resolveDependency(specifier, newParent, ...args);
|
|
72
|
+
return await resolveDependency.default(specifier, newParent, ...args);
|
|
74
73
|
}
|
|
75
74
|
throw error;
|
|
76
75
|
}
|
|
@@ -79,10 +78,10 @@ const traceFilesAndTranspile = async function ({ basePath, config, featureFlags,
|
|
|
79
78
|
const normalizedDependencyPaths = [...dependencyPaths].map((path) => basePath ? resolve(basePath, path) : resolve(path));
|
|
80
79
|
const { moduleFormat, rewrites } = await processESM({
|
|
81
80
|
basePath,
|
|
81
|
+
cache,
|
|
82
82
|
config,
|
|
83
83
|
esmPaths: esmFileList,
|
|
84
84
|
featureFlags,
|
|
85
|
-
fsCache,
|
|
86
85
|
mainFile,
|
|
87
86
|
reasons,
|
|
88
87
|
name,
|
|
@@ -2,6 +2,7 @@ import type { Message } from '@netlify/esbuild';
|
|
|
2
2
|
import type { FunctionConfig } from '../../../config.js';
|
|
3
3
|
import type { FeatureFlag, FeatureFlags } from '../../../feature_flags.js';
|
|
4
4
|
import type { FunctionSource } from '../../../function.js';
|
|
5
|
+
import type { RuntimeCache } from '../../../utils/cache.js';
|
|
5
6
|
import type { ModuleFormat } from '../utils/module_format.js';
|
|
6
7
|
export declare const enum NodeBundlerType {
|
|
7
8
|
ESBUILD = "esbuild",
|
|
@@ -10,11 +11,12 @@ export declare const enum NodeBundlerType {
|
|
|
10
11
|
ZISI = "zisi",
|
|
11
12
|
NONE = "none"
|
|
12
13
|
}
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
export
|
|
16
|
-
export
|
|
14
|
+
type BundlerWarning = Message;
|
|
15
|
+
type CleanupFunction = () => Promise<void>;
|
|
16
|
+
export type NativeNodeModules = Record<string, Record<string, string | undefined>>;
|
|
17
|
+
export type BundleFunction = (args: {
|
|
17
18
|
basePath?: string;
|
|
19
|
+
cache: RuntimeCache;
|
|
18
20
|
config: FunctionConfig;
|
|
19
21
|
featureFlags: Record<FeatureFlag, boolean>;
|
|
20
22
|
pluginsModulesPath?: string;
|
|
@@ -33,7 +35,7 @@ export declare type BundleFunction = (args: {
|
|
|
33
35
|
nodeModulesWithDynamicImports?: string[];
|
|
34
36
|
srcFiles: string[];
|
|
35
37
|
}>;
|
|
36
|
-
export
|
|
38
|
+
export type GetSrcFilesFunction = (args: {
|
|
37
39
|
basePath?: string;
|
|
38
40
|
config: FunctionConfig;
|
|
39
41
|
featureFlags: FeatureFlags;
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
import { FeatureFlags } from '../../../../feature_flags.js';
|
|
2
|
+
export declare const listImports: ({ featureFlags, ...args }: {
|
|
3
|
+
featureFlags: FeatureFlags;
|
|
2
4
|
functionName: string;
|
|
3
5
|
path: string;
|
|
4
6
|
}) => Promise<string[]>;
|