@netlify/zip-it-and-ship-it 6.0.1-beta → 7.0.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.
Files changed (70) hide show
  1. package/README.md +6 -6
  2. package/dist/bin.d.ts +3 -0
  3. package/dist/bin.js +1 -0
  4. package/dist/config.d.ts +12 -8
  5. package/dist/config.js +35 -2
  6. package/dist/feature_flags.js +10 -1
  7. package/dist/main.d.ts +8 -5
  8. package/dist/main.js +2 -2
  9. package/dist/runtimes/detect_runtime.d.ts +2 -2
  10. package/dist/runtimes/detect_runtime.js +22 -8
  11. package/dist/runtimes/go/builder.js +2 -3
  12. package/dist/runtimes/go/index.js +2 -2
  13. package/dist/runtimes/index.d.ts +2 -1
  14. package/dist/runtimes/index.js +6 -4
  15. package/dist/runtimes/node/bundlers/esbuild/bundler.d.ts +5 -2
  16. package/dist/runtimes/node/bundlers/esbuild/bundler.js +22 -15
  17. package/dist/runtimes/node/bundlers/esbuild/bundler_target.d.ts +5 -4
  18. package/dist/runtimes/node/bundlers/esbuild/bundler_target.js +10 -3
  19. package/dist/runtimes/node/bundlers/esbuild/index.d.ts +2 -2
  20. package/dist/runtimes/node/bundlers/esbuild/index.js +3 -2
  21. package/dist/runtimes/node/bundlers/esbuild/plugin_dynamic_imports.js +0 -1
  22. package/dist/runtimes/node/bundlers/esbuild/plugin_native_modules.d.ts +1 -1
  23. package/dist/runtimes/node/bundlers/esbuild/plugin_native_modules.js +1 -1
  24. package/dist/runtimes/node/bundlers/esbuild/src_files.d.ts +1 -1
  25. package/dist/runtimes/node/bundlers/index.d.ts +6 -46
  26. package/dist/runtimes/node/bundlers/index.js +27 -13
  27. package/dist/runtimes/node/bundlers/nft/es_modules.js +11 -3
  28. package/dist/runtimes/node/bundlers/nft/index.d.ts +1 -1
  29. package/dist/runtimes/node/bundlers/nft/transpile.js +7 -8
  30. package/dist/runtimes/node/bundlers/none/index.d.ts +7 -0
  31. package/dist/runtimes/node/bundlers/none/index.js +77 -0
  32. package/dist/runtimes/node/bundlers/types.d.ts +50 -0
  33. package/dist/runtimes/node/bundlers/types.js +3 -0
  34. package/dist/runtimes/node/bundlers/zisi/index.d.ts +2 -2
  35. package/dist/runtimes/node/bundlers/zisi/index.js +1 -1
  36. package/dist/runtimes/node/bundlers/zisi/list_imports.js +6 -7
  37. package/dist/runtimes/node/bundlers/zisi/resolve.js +1 -3
  38. package/dist/runtimes/node/bundlers/zisi/src_files.d.ts +1 -1
  39. package/dist/runtimes/node/bundlers/zisi/src_files.js +0 -2
  40. package/dist/runtimes/node/finder.js +9 -1
  41. package/dist/runtimes/node/in_source_config/index.d.ts +1 -1
  42. package/dist/runtimes/node/in_source_config/index.js +17 -6
  43. package/dist/runtimes/node/index.js +20 -15
  44. package/dist/runtimes/node/parser/bindings.js +0 -1
  45. package/dist/runtimes/node/parser/helpers.js +0 -1
  46. package/dist/runtimes/node/parser/index.d.ts +1 -1
  47. package/dist/runtimes/node/parser/index.js +0 -3
  48. package/dist/runtimes/node/utils/entry_file.d.ts +3 -10
  49. package/dist/runtimes/node/utils/entry_file.js +4 -18
  50. package/dist/runtimes/node/utils/module_format.d.ts +11 -1
  51. package/dist/runtimes/node/utils/module_format.js +8 -0
  52. package/dist/runtimes/node/utils/node_version.d.ts +4 -3
  53. package/dist/runtimes/node/utils/node_version.js +1 -1
  54. package/dist/runtimes/node/utils/package_json.d.ts +1 -1
  55. package/dist/runtimes/node/utils/zip.d.ts +2 -2
  56. package/dist/runtimes/node/utils/zip.js +11 -17
  57. package/dist/runtimes/runtime.d.ts +8 -4
  58. package/dist/runtimes/rust/builder.js +3 -5
  59. package/dist/runtimes/rust/index.js +2 -2
  60. package/dist/utils/error.d.ts +19 -0
  61. package/dist/utils/error.js +22 -0
  62. package/dist/utils/format_result.d.ts +2 -2
  63. package/dist/utils/fs.d.ts +6 -6
  64. package/dist/utils/fs.js +20 -19
  65. package/dist/utils/remove_undefined.d.ts +3 -1
  66. package/dist/zip.d.ts +4 -3
  67. package/dist/zip.js +2 -2
  68. package/package.json +8 -7
  69. package/dist/runtimes/node/runtime_api/index.d.ts +0 -3
  70. package/dist/runtimes/node/runtime_api/index.js +0 -46
package/README.md CHANGED
@@ -51,9 +51,8 @@ In Netlify, this directory is the
51
51
 
52
52
  A source folder can contain:
53
53
 
54
- - Sub-directories with a main file called `index.js`, `index.ts`, `{dir}.js` or `{dir}.ts` where `{dir}` is the
55
- sub-directory name.
56
- - `.js` or `.ts` files (Node.js)
54
+ - Sub-directories with a main file called `index.js` or `{dir}.js` where `{dir}` is the sub-directory name.
55
+ - `.js`, `.mjs`, `.cjs`, `.ts`, `.tsx`, `.mts` or `.cts` files (Node.js)
57
56
  - `.zip` archives with Node.js already ready to upload to AWS Lambda.
58
57
  - Go programs already compiled. Those are copied as is.
59
58
  - Rust programs already compiled. Those are zipped.
@@ -129,7 +128,7 @@ The following properties are accepted:
129
128
  - `nodeVersion`
130
129
 
131
130
  - _Type_: `string`\
132
- - _Default value_: `12.x`
131
+ - _Default value_: `16.x`
133
132
 
134
133
  The version of Node.js to use as the compilation target. Possible values:
135
134
 
@@ -137,6 +136,7 @@ The following properties are accepted:
137
136
  - `10.x` (or `nodejs10.x`)
138
137
  - `12.x` (or `nodejs12.x`)
139
138
  - `14.x` (or `nodejs14.x`)
139
+ - `16.x` (or `nodejs16.x`)
140
140
 
141
141
  - `rustTargetDirectory`
142
142
 
@@ -441,9 +441,9 @@ need to be the same as the one used when installing those native modules.
441
441
 
442
442
  In Netlify, this is done by ensuring that the following Node.js versions are the same:
443
443
 
444
- - Build-time Node.js version: this defaults to Node `12`, but can be
444
+ - Build-time Node.js version: this defaults to Node `16`, but can be
445
445
  [overridden with a `.nvmrc` or `NODE_VERSION` environment variable](https://docs.netlify.com/configure-builds/manage-dependencies/#node-js-and-javascript).
446
- - Function runtime Node.js version: this defaults to `nodejs12.x` but can be
446
+ - Function runtime Node.js version: this defaults to `nodejs16.x` but can be
447
447
  [overridden with a `AWS_LAMBDA_JS_RUNTIME` environment variable](https://docs.netlify.com/functions/build-with-javascript/#runtime-settings).
448
448
 
449
449
  Note that this problem might not apply for Node.js native modules using the [N-API](https://nodejs.org/api/n-api.html).
package/dist/bin.d.ts CHANGED
@@ -1,2 +1,5 @@
1
1
  #!/usr/bin/env node
2
+ declare global {
3
+ var ZISI_CLI: boolean;
4
+ }
2
5
  export {};
package/dist/bin.js CHANGED
@@ -14,6 +14,7 @@ const runCli = async function () {
14
14
  // back from `parseArgs()`.
15
15
  const { destFolder, srcFolder, ...options } = parseArgs();
16
16
  try {
17
+ global.ZISI_CLI = true;
17
18
  // @ts-expect-error TODO: `options` is not getting the right types.
18
19
  const zipped = await (0, main_js_1.zipFunctions)(srcFolder, destFolder, options);
19
20
  console.log(JSON.stringify(zipped, null, 2));
package/dist/config.d.ts CHANGED
@@ -1,12 +1,13 @@
1
+ import type { FeatureFlags } from './feature_flags.js';
1
2
  import { FunctionSource } from './function.js';
2
- import type { NodeBundlerName } from './runtimes/node/bundlers/index.js';
3
+ import type { NodeBundlerType } from './runtimes/node/bundlers/types.js';
3
4
  import type { NodeVersionString } from './runtimes/node/index.js';
4
- export interface FunctionConfig {
5
+ interface FunctionConfig {
5
6
  externalNodeModules?: string[];
6
7
  includedFiles?: string[];
7
8
  includedFilesBasePath?: string;
8
9
  ignoredNodeModules?: string[];
9
- nodeBundler?: NodeBundlerName;
10
+ nodeBundler?: NodeBundlerType;
10
11
  nodeSourcemap?: boolean;
11
12
  nodeVersion?: NodeVersionString;
12
13
  processDynamicNodeImports?: boolean;
@@ -15,9 +16,12 @@ export interface FunctionConfig {
15
16
  zipGo?: boolean;
16
17
  }
17
18
  declare type GlobPattern = string;
18
- export declare type Config = Record<GlobPattern, FunctionConfig>;
19
- export declare const getConfigForFunction: ({ config, func, }: {
19
+ declare type Config = Record<GlobPattern, FunctionConfig>;
20
+ declare type FunctionWithoutConfig = Omit<FunctionSource, 'config'>;
21
+ declare const getConfigForFunction: ({ config, configFileDirectories, func, featureFlags, }: {
20
22
  config?: Config | undefined;
21
- func: Omit<FunctionSource, 'config'>;
22
- }) => FunctionConfig;
23
- export {};
23
+ configFileDirectories?: string[] | undefined;
24
+ func: FunctionWithoutConfig;
25
+ featureFlags: FeatureFlags;
26
+ }) => Promise<FunctionConfig>;
27
+ export { Config, FunctionConfig, FunctionWithoutConfig, getConfigForFunction };
package/dist/config.js CHANGED
@@ -4,9 +4,28 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.getConfigForFunction = void 0;
7
+ const fs_1 = require("fs");
8
+ const path_1 = require("path");
9
+ const is_path_inside_1 = __importDefault(require("is-path-inside"));
7
10
  const merge_options_1 = __importDefault(require("merge-options"));
8
11
  const matching_js_1 = require("./utils/matching.js");
9
- const getConfigForFunction = ({ config, func, }) => {
12
+ const getConfigForFunction = async ({ config, configFileDirectories, func, featureFlags, }) => {
13
+ const fromConfig = getFromMainConfig({ config, func });
14
+ // We try to read from a function config file if the function directory is
15
+ // inside one of `configFileDirectories`.
16
+ const shouldReadConfigFile = featureFlags.project_deploy_configuration_api_use_per_function_configuration_files &&
17
+ (configFileDirectories === null || configFileDirectories === void 0 ? void 0 : configFileDirectories.some((directory) => (0, is_path_inside_1.default)(func.mainFile, directory)));
18
+ if (!shouldReadConfigFile) {
19
+ return fromConfig;
20
+ }
21
+ const fromFile = await getFromFile(func);
22
+ return {
23
+ ...fromConfig,
24
+ ...fromFile,
25
+ };
26
+ };
27
+ exports.getConfigForFunction = getConfigForFunction;
28
+ const getFromMainConfig = ({ config, func, }) => {
10
29
  if (!config) {
11
30
  return {};
12
31
  }
@@ -29,5 +48,19 @@ const getConfigForFunction = ({ config, func, }) => {
29
48
  .map(({ expression }) => config[expression]);
30
49
  return merge_options_1.default.apply({ concatArrays: true, ignoreUndefined: true }, matches);
31
50
  };
32
- exports.getConfigForFunction = getConfigForFunction;
51
+ const getFromFile = async (func) => {
52
+ const filename = `${(0, path_1.basename)(func.mainFile, (0, path_1.extname)(func.mainFile))}.json`;
53
+ const configFilePath = (0, path_1.join)((0, path_1.dirname)(func.mainFile), filename);
54
+ try {
55
+ const data = await fs_1.promises.readFile(configFilePath, 'utf8');
56
+ const configFile = JSON.parse(data);
57
+ if (configFile.version === 1) {
58
+ return configFile.config;
59
+ }
60
+ }
61
+ catch {
62
+ // no-op
63
+ }
64
+ return {};
65
+ };
33
66
  //# sourceMappingURL=config.js.map
@@ -3,11 +3,20 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getFlags = exports.defaultFlags = void 0;
4
4
  const process_1 = require("process");
5
5
  exports.defaultFlags = {
6
+ // Build Rust functions from source.
6
7
  buildRustSource: Boolean(process_1.env.NETLIFY_EXPERIMENTAL_BUILD_RUST_SOURCE),
8
+ // Use esbuild to trace dependencies in the legacy bundler.
7
9
  parseWithEsbuild: false,
10
+ // Use NFT as the default bundler.
8
11
  traceWithNft: false,
12
+ // Output pure (i.e. untranspiled) ESM files when the function file has ESM
13
+ // syntax and the parent `package.json` file has `{"type": "module"}`.
9
14
  zisi_pure_esm: false,
10
- zisi_functions_api_v2: false,
15
+ // Output pure (i.e. untranspiled) ESM files when the function file has a
16
+ // `.mjs` extension.
17
+ zisi_pure_esm_mjs: false,
18
+ // Load configuration from per-function JSON files.
19
+ project_deploy_configuration_api_use_per_function_configuration_files: false,
11
20
  };
12
21
  // List of supported flags and their default value.
13
22
  const getFlags = (input = {}, flags = exports.defaultFlags) => Object.entries(flags).reduce((result, [key, defaultValue]) => ({
package/dist/main.d.ts CHANGED
@@ -1,11 +1,14 @@
1
1
  import { Config } from './config.js';
2
2
  import { FeatureFlags } from './feature_flags.js';
3
- import { RuntimeName } from './runtimes/runtime.js';
3
+ import { RuntimeType } from './runtimes/runtime.js';
4
4
  export { zipFunction, zipFunctions } from './zip.js';
5
+ export { NodeBundlerType } from './runtimes/node/bundlers/types.js';
6
+ export { RuntimeType } from './runtimes/runtime.js';
7
+ export { ModuleFormat } from './runtimes/node/utils/module_format.js';
5
8
  interface ListedFunction {
6
9
  name: string;
7
10
  mainFile: string;
8
- runtime: RuntimeName;
11
+ runtime: RuntimeType;
9
12
  extension: string;
10
13
  schedule?: string;
11
14
  }
@@ -18,14 +21,14 @@ interface ListFunctionsOptions {
18
21
  featureFlags?: FeatureFlags;
19
22
  parseISC?: boolean;
20
23
  }
21
- export declare const listFunctions: (relativeSrcFolders: string | string[], { featureFlags: inputFeatureFlags, config, parseISC, }?: {
24
+ export declare const listFunctions: (relativeSrcFolders: string | string[], { featureFlags, config, parseISC, }?: {
22
25
  featureFlags?: FeatureFlags | undefined;
23
26
  config?: Config | undefined;
24
27
  parseISC?: boolean | undefined;
25
28
  }) => Promise<ListedFunction[]>;
26
- export declare const listFunction: (path: string, { featureFlags: inputFeatureFlags, config, parseISC, }?: {
29
+ export declare const listFunction: (path: string, { featureFlags, config, parseISC, }?: {
27
30
  featureFlags?: FeatureFlags | undefined;
28
31
  config?: Config | undefined;
29
32
  parseISC?: boolean | undefined;
30
33
  }) => Promise<ListedFunction | undefined>;
31
- export declare const listFunctionsFiles: (relativeSrcFolders: string | string[], { basePath, config, featureFlags: inputFeatureFlags, parseISC }?: ListFunctionsOptions) => Promise<ListedFunctionFile[]>;
34
+ export declare const listFunctionsFiles: (relativeSrcFolders: string | string[], { basePath, config, featureFlags, parseISC }?: ListFunctionsOptions) => Promise<ListedFunctionFile[]>;
package/dist/main.js CHANGED
@@ -11,10 +11,10 @@ Object.defineProperty(exports, "zipFunction", { enumerable: true, get: function
11
11
  Object.defineProperty(exports, "zipFunctions", { enumerable: true, get: function () { return zip_js_1.zipFunctions; } });
12
12
  const augmentWithISC = async (func) => {
13
13
  // ISC is currently only supported in JavaScript and TypeScript functions.
14
- if (func.runtime.name !== 'js') {
14
+ if (func.runtime.name !== "js" /* RuntimeType.JAVASCRIPT */) {
15
15
  return func;
16
16
  }
17
- const inSourceConfig = await (0, index_js_2.findISCDeclarationsInPath)(func.mainFile);
17
+ const inSourceConfig = await (0, index_js_2.findISCDeclarationsInPath)(func.mainFile, func.name);
18
18
  return { ...func, inSourceConfig };
19
19
  };
20
20
  // List all Netlify Functions main entry files for a specific directory
@@ -1,6 +1,6 @@
1
1
  import { FsCache } from '../utils/fs.js';
2
- import type { RuntimeName } from './runtime.js';
2
+ import { RuntimeType } from './runtime.js';
3
3
  export declare const detectBinaryRuntime: ({ fsCache, path, }: {
4
4
  fsCache: FsCache;
5
5
  path: string;
6
- }) => Promise<RuntimeName | undefined>;
6
+ }) => Promise<RuntimeType | undefined>;
@@ -1,8 +1,17 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.detectBinaryRuntime = void 0;
4
- const elf_cam_1 = require("elf-cam");
4
+ const binary_info_1 = require("@netlify/binary-info");
5
5
  const fs_js_1 = require("../utils/fs.js");
6
+ const isValidFunctionBinary = (info) => info.arch === binary_info_1.Arch.Amd64 && info.platform === binary_info_1.Platform.Linux;
7
+ const warnIncompatibleBinary = function (path, binaryInfo) {
8
+ if (!global.ZISI_CLI) {
9
+ console.warn(`
10
+ Found incompatible prebuilt function binary in ${path}.
11
+ The binary needs to be built for Linux/Amd64, but it was built for ${binary_info_1.Platform[binaryInfo.platform]}/${binary_info_1.Arch[binaryInfo.arch]}`);
12
+ }
13
+ return undefined;
14
+ };
6
15
  // Try to guess the runtime by inspecting the binary file.
7
16
  const detectBinaryRuntime = async function ({ fsCache, path, }) {
8
17
  try {
@@ -10,17 +19,22 @@ const detectBinaryRuntime = async function ({ fsCache, path, }) {
10
19
  // We're using the Type Assertion because the `cachedReadFile` abstraction
11
20
  // loses part of the return type information. We can safely say it's a
12
21
  // Buffer in this case because we're not specifying an encoding.
13
- const binaryType = (0, elf_cam_1.detect)(buffer);
14
- switch (binaryType) {
15
- case elf_cam_1.Runtime.Go:
16
- return 'go';
17
- case elf_cam_1.Runtime.Rust:
18
- return 'rs';
22
+ const binaryInfo = (0, binary_info_1.detect)(buffer);
23
+ if (!isValidFunctionBinary(binaryInfo)) {
24
+ return warnIncompatibleBinary(path, binaryInfo);
25
+ }
26
+ switch (binaryInfo.runtime) {
27
+ case binary_info_1.Runtime.Go:
28
+ return "go" /* RuntimeType.GO */;
29
+ case binary_info_1.Runtime.Rust:
30
+ return "rs" /* RuntimeType.RUST */;
19
31
  default:
20
32
  return undefined;
21
33
  }
22
34
  }
23
- catch { }
35
+ catch {
36
+ // Possible errors are: non binary files, arch/platforms not supported by binary-info, path is directory
37
+ }
24
38
  };
25
39
  exports.detectBinaryRuntime = detectBinaryRuntime;
26
40
  //# sourceMappingURL=detect_runtime.js.map
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.build = void 0;
4
4
  const fs_1 = require("fs");
5
5
  const path_1 = require("path");
6
+ const error_js_1 = require("../../utils/error.js");
6
7
  const shell_js_1 = require("../../utils/shell.js");
7
8
  const build = async ({ destPath, mainFile, srcDir }) => {
8
9
  const functionName = (0, path_1.basename)(srcDir);
@@ -17,10 +18,8 @@ const build = async ({ destPath, mainFile, srcDir }) => {
17
18
  });
18
19
  }
19
20
  catch (error) {
20
- const runtime = 'go';
21
- error.customErrorInfo = { type: 'functionsBundling', location: { functionName, runtime } };
22
21
  console.error(`Could not compile Go function ${functionName}:\n`);
23
- throw error;
22
+ throw error_js_1.FunctionBundlingUserError.addCustomErrorInfo(error, { functionName, runtime: "go" /* RuntimeType.GO */ });
24
23
  }
25
24
  const stat = await fs_1.promises.lstat(destPath);
26
25
  return {
@@ -31,7 +31,7 @@ const findFunctionsInPaths = async function ({ featureFlags, fsCache, paths }) {
31
31
  };
32
32
  const findFunctionInPath = async function ({ fsCache, path }) {
33
33
  const runtime = await (0, detect_runtime_js_1.detectBinaryRuntime)({ fsCache, path });
34
- if (runtime === 'go') {
34
+ if (runtime === "go" /* RuntimeType.GO */) {
35
35
  return processBinary({ fsCache, path });
36
36
  }
37
37
  const goSourceFile = await detectGoFunction({ fsCache, path });
@@ -109,6 +109,6 @@ const zipFunction = async function ({ config, destFolder, filename, mainFile, sr
109
109
  }
110
110
  return { config, path: destPath };
111
111
  };
112
- const runtime = { findFunctionsInPaths, findFunctionInPath, name: 'go', zipFunction };
112
+ const runtime = { findFunctionsInPaths, findFunctionInPath, name: "go" /* RuntimeType.GO */, zipFunction };
113
113
  exports.default = runtime;
114
114
  //# sourceMappingURL=index.js.map
@@ -5,8 +5,9 @@ declare type FunctionMap = Map<string, FunctionSource>;
5
5
  /**
6
6
  * Gets a list of functions found in a list of paths.
7
7
  */
8
- export declare const getFunctionsFromPaths: (paths: string[], { config, dedupe, featureFlags, }?: {
8
+ export declare const getFunctionsFromPaths: (paths: string[], { config, configFileDirectories, dedupe, featureFlags, }?: {
9
9
  config?: Config | undefined;
10
+ configFileDirectories?: string[] | undefined;
10
11
  dedupe?: boolean | undefined;
11
12
  featureFlags?: FeatureFlags | undefined;
12
13
  }) => Promise<FunctionMap>;
@@ -47,7 +47,7 @@ const RUNTIMES = [index_js_2.default, index_js_1.default, index_js_3.default];
47
47
  /**
48
48
  * Gets a list of functions found in a list of paths.
49
49
  */
50
- const getFunctionsFromPaths = async (paths, { config, dedupe = false, featureFlags = feature_flags_js_1.defaultFlags, } = {}) => {
50
+ const getFunctionsFromPaths = async (paths, { config, configFileDirectories = [], dedupe = false, featureFlags = feature_flags_js_1.defaultFlags, } = {}) => {
51
51
  const fsCache = makeFsCache();
52
52
  // We cycle through the ordered array of runtimes, passing each one of them
53
53
  // through `findFunctionsInRuntime`. For each iteration, we collect all the
@@ -67,9 +67,10 @@ const getFunctionsFromPaths = async (paths, { config, dedupe = false, featureFla
67
67
  remainingPaths: runtimePaths,
68
68
  };
69
69
  }, Promise.resolve({ functions: [], remainingPaths: paths }));
70
- const functionsWithConfig = functions.map(([name, func]) => [
70
+ const functionConfigs = await Promise.all(functions.map(([, func]) => (0, config_js_1.getConfigForFunction)({ config, configFileDirectories, func, featureFlags })));
71
+ const functionsWithConfig = functions.map(([name, func], index) => [
71
72
  name,
72
- { ...func, config: (0, config_js_1.getConfigForFunction)({ config, func }) },
73
+ { ...func, config: functionConfigs[index] },
73
74
  ]);
74
75
  return new Map(functionsWithConfig);
75
76
  };
@@ -82,10 +83,11 @@ const getFunctionFromPath = async (path, { config, featureFlags = feature_flags_
82
83
  for (const runtime of RUNTIMES) {
83
84
  const func = await runtime.findFunctionInPath({ path, fsCache, featureFlags });
84
85
  if (func) {
86
+ const functionConfig = await (0, config_js_1.getConfigForFunction)({ config, func: { ...func, runtime }, featureFlags });
85
87
  return {
86
88
  ...func,
87
89
  runtime,
88
- config: (0, config_js_1.getConfigForFunction)({ config, func: { ...func, runtime } }),
90
+ config: functionConfig,
89
91
  };
90
92
  }
91
93
  }
@@ -1,13 +1,15 @@
1
1
  import type { FunctionConfig } from '../../../../config.js';
2
2
  import { FeatureFlags } from '../../../../feature_flags.js';
3
+ import { ModuleFileExtension, ModuleFormat } from '../../utils/module_format.js';
3
4
  export declare const ESBUILD_LOG_LIMIT = 10;
4
- export declare const bundleJsFile: ({ additionalModulePaths, basePath, config, externalModules, featureFlags, ignoredModules, name, srcDir, srcFile, }: {
5
+ export declare const bundleJsFile: ({ additionalModulePaths, basePath, config, externalModules, featureFlags, ignoredModules, mainFile, name, srcDir, srcFile, }: {
5
6
  additionalModulePaths?: string[] | undefined;
6
7
  basePath?: string | undefined;
7
8
  config: FunctionConfig;
8
9
  externalModules: string[];
9
10
  featureFlags: FeatureFlags;
10
11
  ignoredModules: string[];
12
+ mainFile: string;
11
13
  name: string;
12
14
  srcDir: string;
13
15
  srcFile: string;
@@ -15,8 +17,9 @@ export declare const bundleJsFile: ({ additionalModulePaths, basePath, config, e
15
17
  additionalPaths: string[];
16
18
  bundlePaths: Map<string, string>;
17
19
  cleanTempFiles: () => Promise<void>;
20
+ extension: ModuleFileExtension;
18
21
  inputs: string[];
19
- moduleFormat: import("../../utils/module_format.js").ModuleFormat;
22
+ moduleFormat: ModuleFormat;
20
23
  nativeNodeModules: {};
21
24
  nodeModulesWithDynamicImports: string[];
22
25
  warnings: import("@netlify/esbuild").Message[];
@@ -4,7 +4,9 @@ exports.bundleJsFile = exports.ESBUILD_LOG_LIMIT = void 0;
4
4
  const path_1 = require("path");
5
5
  const esbuild_1 = require("@netlify/esbuild");
6
6
  const tmp_promise_1 = require("tmp-promise");
7
+ const error_js_1 = require("../../../../utils/error.js");
7
8
  const fs_js_1 = require("../../../../utils/fs.js");
9
+ const module_format_js_1 = require("../../utils/module_format.js");
8
10
  const bundler_target_js_1 = require("./bundler_target.js");
9
11
  const plugin_dynamic_imports_js_1 = require("./plugin_dynamic_imports.js");
10
12
  const plugin_native_modules_js_1 = require("./plugin_native_modules.js");
@@ -15,9 +17,9 @@ const plugin_node_builtin_js_1 = require("./plugin_node_builtin.js");
15
17
  exports.ESBUILD_LOG_LIMIT = 10;
16
18
  // When resolving imports with no extension (e.g. require('./foo')), these are
17
19
  // the extensions that esbuild will look for, in this order.
18
- const RESOLVE_EXTENSIONS = ['.js', '.jsx', '.mjs', '.cjs', '.ts', '.json'];
20
+ const RESOLVE_EXTENSIONS = ['.js', '.jsx', '.mjs', '.cjs', '.ts', '.tsx', '.mts', '.cts', '.json'];
19
21
  // eslint-disable-next-line max-statements
20
- const bundleJsFile = async function ({ additionalModulePaths, basePath, config, externalModules = [], featureFlags, ignoredModules = [], name, srcDir, srcFile, }) {
22
+ const bundleJsFile = async function ({ additionalModulePaths, basePath, config, externalModules = [], featureFlags, ignoredModules = [], mainFile, name, srcDir, srcFile, }) {
21
23
  // We use a temporary directory as the destination for esbuild files to avoid
22
24
  // any naming conflicts with files generated by other functions.
23
25
  const targetDirectory = await (0, tmp_promise_1.tmpName)();
@@ -55,7 +57,11 @@ const bundleJsFile = async function ({ additionalModulePaths, basePath, config,
55
57
  // Configuring the output format of esbuild. The `includedFiles` array we get
56
58
  // here contains additional paths to include with the bundle, like the path
57
59
  // to a `package.json` with {"type": "module"} in case of an ESM function.
58
- const { includedFiles: includedFilesFromModuleDetection, moduleFormat } = await (0, bundler_target_js_1.getModuleFormat)(srcDir, featureFlags, config.nodeVersion);
60
+ const { includedFiles: includedFilesFromModuleDetection, moduleFormat } = await (0, bundler_target_js_1.getModuleFormat)(srcDir, featureFlags, (0, path_1.extname)(mainFile), config.nodeVersion);
61
+ // The extension of the output file.
62
+ const extension = (0, module_format_js_1.getFileExtensionForFormat)(moduleFormat, featureFlags);
63
+ // When outputting an ESM file, configure esbuild to produce a `.mjs` file.
64
+ const outExtension = moduleFormat === "esm" /* ModuleFormat.ESM */ ? { [".js" /* ModuleFileExtension.JS */]: ".mjs" /* ModuleFileExtension.MJS */ } : undefined;
59
65
  try {
60
66
  const { metafile = { inputs: {}, outputs: {} }, warnings } = await (0, esbuild_1.build)({
61
67
  bundle: true,
@@ -66,6 +72,7 @@ const bundleJsFile = async function ({ additionalModulePaths, basePath, config,
66
72
  logLimit: exports.ESBUILD_LOG_LIMIT,
67
73
  metafile: true,
68
74
  nodePaths: additionalModulePaths,
75
+ outExtension,
69
76
  outdir: targetDirectory,
70
77
  platform: 'node',
71
78
  plugins,
@@ -76,6 +83,7 @@ const bundleJsFile = async function ({ additionalModulePaths, basePath, config,
76
83
  });
77
84
  const bundlePaths = getBundlePaths({
78
85
  destFolder: targetDirectory,
86
+ extension,
79
87
  outputs: metafile.outputs,
80
88
  srcFile,
81
89
  });
@@ -86,6 +94,7 @@ const bundleJsFile = async function ({ additionalModulePaths, basePath, config,
86
94
  additionalPaths,
87
95
  bundlePaths,
88
96
  cleanTempFiles,
97
+ extension,
89
98
  inputs,
90
99
  moduleFormat,
91
100
  nativeNodeModules,
@@ -94,13 +103,11 @@ const bundleJsFile = async function ({ additionalModulePaths, basePath, config,
94
103
  };
95
104
  }
96
105
  catch (error) {
97
- const bundler = 'esbuild';
98
- const runtime = 'js';
99
- error.customErrorInfo = {
100
- type: 'functionsBundling',
101
- location: { bundler, functionName: name, runtime },
102
- };
103
- throw error;
106
+ throw error_js_1.FunctionBundlingUserError.addCustomErrorInfo(error, {
107
+ functionName: name,
108
+ runtime: "js" /* RuntimeType.JAVASCRIPT */,
109
+ bundler: "esbuild" /* NodeBundlerType.ESBUILD */,
110
+ });
104
111
  }
105
112
  };
106
113
  exports.bundleJsFile = bundleJsFile;
@@ -108,8 +115,8 @@ exports.bundleJsFile = bundleJsFile;
108
115
  // absolute paths of the generated files as keys, and the paths that those
109
116
  // files should take in the generated bundle as values. This is compatible
110
117
  // with the `aliases` format used upstream.
111
- const getBundlePaths = ({ destFolder, outputs, srcFile, }) => {
112
- const bundleFilename = `${(0, path_1.basename)(srcFile, (0, path_1.extname)(srcFile))}.js`;
118
+ const getBundlePaths = ({ destFolder, extension: outputExtension, outputs, srcFile, }) => {
119
+ const bundleFilename = (0, path_1.basename)(srcFile, (0, path_1.extname)(srcFile)) + outputExtension;
113
120
  const mainFileDirectory = (0, path_1.dirname)(srcFile);
114
121
  const bundlePaths = new Map();
115
122
  // The paths returned by esbuild are relative to the current directory, which
@@ -122,11 +129,11 @@ const getBundlePaths = ({ destFolder, outputs, srcFile, }) => {
122
129
  const extension = (0, path_1.extname)(path);
123
130
  const absolutePath = (0, path_1.join)(destFolder, filename);
124
131
  if (output.entryPoint && (0, path_1.basename)(output.entryPoint) === (0, path_1.basename)(srcFile)) {
125
- // Ensuring the main file has a `.js` extension.
126
- const normalizedSrcFile = (0, fs_js_1.getPathWithExtension)(srcFile, '.js');
132
+ // Ensuring the main file has the right extension.
133
+ const normalizedSrcFile = (0, fs_js_1.getPathWithExtension)(srcFile, outputExtension);
127
134
  bundlePaths.set(absolutePath, normalizedSrcFile);
128
135
  }
129
- else if (extension === '.js' || filename === `${bundleFilename}.map`) {
136
+ else if (extension === outputExtension || filename === `${bundleFilename}.map`) {
130
137
  bundlePaths.set(absolutePath, (0, path_1.join)(mainFileDirectory, filename));
131
138
  }
132
139
  });
@@ -1,15 +1,16 @@
1
1
  import { FeatureFlags } from '../../../../feature_flags';
2
2
  import { ModuleFormat } from '../../utils/module_format';
3
+ import { NodeVersionString } from '../../utils/node_version';
3
4
  declare const versionMap: {
4
5
  readonly '8.x': "node8";
5
6
  readonly '10.x': "node10";
6
7
  readonly '12.x': "node12";
7
8
  readonly '14.x': "node14";
9
+ readonly '16.x': "node16";
8
10
  };
9
- declare type VersionKeys = keyof typeof versionMap;
10
- declare type VersionValues = typeof versionMap[VersionKeys];
11
- declare const getBundlerTarget: (suppliedVersion?: string) => VersionValues;
12
- declare const getModuleFormat: (srcDir: string, featureFlags: FeatureFlags, configVersion?: string) => Promise<{
11
+ declare type VersionValues = typeof versionMap[keyof typeof versionMap];
12
+ declare const getBundlerTarget: (suppliedVersion?: NodeVersionString) => VersionValues;
13
+ declare const getModuleFormat: (srcDir: string, featureFlags: FeatureFlags, extension: string, configVersion?: string) => Promise<{
13
14
  includedFiles: string[];
14
15
  moduleFormat: ModuleFormat;
15
16
  }>;
@@ -8,6 +8,7 @@ const versionMap = {
8
8
  '10.x': 'node10',
9
9
  '12.x': 'node12',
10
10
  '14.x': 'node14',
11
+ '16.x': 'node16',
11
12
  };
12
13
  const getBundlerTarget = (suppliedVersion) => {
13
14
  const version = normalizeVersion(suppliedVersion);
@@ -17,18 +18,24 @@ const getBundlerTarget = (suppliedVersion) => {
17
18
  return versionMap[`${node_version_1.DEFAULT_NODE_VERSION}.x`];
18
19
  };
19
20
  exports.getBundlerTarget = getBundlerTarget;
20
- const getModuleFormat = async (srcDir, featureFlags, configVersion) => {
21
+ const getModuleFormat = async (srcDir, featureFlags, extension, configVersion) => {
22
+ if (extension === ".mjs" /* ModuleFileExtension.MJS */ && featureFlags.zisi_pure_esm_mjs) {
23
+ return {
24
+ includedFiles: [],
25
+ moduleFormat: "esm" /* ModuleFormat.ESM */,
26
+ };
27
+ }
21
28
  const packageJsonFile = await (0, package_json_1.getClosestPackageJson)(srcDir);
22
29
  const nodeSupport = (0, node_version_1.getNodeSupportMatrix)(configVersion);
23
30
  if (featureFlags.zisi_pure_esm && (packageJsonFile === null || packageJsonFile === void 0 ? void 0 : packageJsonFile.contents.type) === 'module' && nodeSupport.esm) {
24
31
  return {
25
32
  includedFiles: [packageJsonFile.path],
26
- moduleFormat: 'esm',
33
+ moduleFormat: "esm" /* ModuleFormat.ESM */,
27
34
  };
28
35
  }
29
36
  return {
30
37
  includedFiles: [],
31
- moduleFormat: 'cjs',
38
+ moduleFormat: "cjs" /* ModuleFormat.COMMONJS */,
32
39
  };
33
40
  };
34
41
  exports.getModuleFormat = getModuleFormat;
@@ -1,6 +1,6 @@
1
- import type { BundleFunction } from '../index.js';
1
+ import type { BundleFunction } from '../types.js';
2
2
  declare const bundler: {
3
3
  bundle: BundleFunction;
4
- getSrcFiles: import("../index.js").GetSrcFilesFunction;
4
+ getSrcFiles: import("../types.js").GetSrcFilesFunction;
5
5
  };
6
6
  export default bundler;
@@ -30,13 +30,14 @@ const getExternalAndIgnoredModules = async ({ config, srcDir }) => {
30
30
  };
31
31
  const bundle = async ({ basePath, config = {}, extension, featureFlags, filename, mainFile, name, pluginsModulesPath, repositoryRoot, runtime, srcDir, srcPath, stat, }) => {
32
32
  const { externalModules, ignoredModules } = await getExternalAndIgnoredModules({ config, srcDir });
33
- const { additionalPaths, bundlePaths, cleanTempFiles, inputs, moduleFormat, nativeNodeModules = {}, nodeModulesWithDynamicImports, warnings, } = await (0, bundler_js_1.bundleJsFile)({
33
+ const { additionalPaths, bundlePaths, cleanTempFiles, extension: outputExtension, inputs, moduleFormat, nativeNodeModules = {}, nodeModulesWithDynamicImports, warnings, } = await (0, bundler_js_1.bundleJsFile)({
34
34
  additionalModulePaths: pluginsModulesPath ? [pluginsModulesPath] : [],
35
35
  basePath,
36
36
  config,
37
37
  externalModules,
38
38
  featureFlags,
39
39
  ignoredModules,
40
+ mainFile,
40
41
  name,
41
42
  srcDir,
42
43
  srcFile: mainFile,
@@ -65,7 +66,7 @@ const bundle = async ({ basePath, config = {}, extension, featureFlags, filename
65
66
  // path of the original, pre-bundling function file. We'll add the actual
66
67
  // bundled file further below.
67
68
  const supportingSrcFiles = srcFiles.filter((path) => path !== mainFile);
68
- const normalizedMainFile = (0, fs_js_1.getPathWithExtension)(mainFile, '.js');
69
+ const normalizedMainFile = (0, fs_js_1.getPathWithExtension)(mainFile, outputExtension);
69
70
  const functionBasePath = getFunctionBasePath({
70
71
  basePathFromConfig: basePath,
71
72
  mainFile,
@@ -20,7 +20,6 @@ const getDynamicImportsPlugin = ({ basePath, includedPaths, moduleNames, process
20
20
  name: 'dynamic-imports',
21
21
  setup(build) {
22
22
  const cache = new Map();
23
- // eslint-disable-next-line complexity
24
23
  build.onDynamicImport({ filter: /.*/ }, async (args) => {
25
24
  const { expression, resolveDir } = args;
26
25
  // Don't attempt to parse the expression if the base path isn't defined,
@@ -1,3 +1,3 @@
1
1
  import type { Plugin } from '@netlify/esbuild';
2
- import type { NativeNodeModules } from '../index.js';
2
+ import type { NativeNodeModules } from '../types.js';
3
3
  export declare const getNativeModulesPlugin: (externalizedModules: NativeNodeModules) => Plugin;
@@ -22,7 +22,7 @@ const getNativeModulesPlugin = (externalizedModules) => ({
22
22
  name: 'external-native-modules',
23
23
  setup(build) {
24
24
  const cache = {};
25
- // eslint-disable-next-line complexity, max-statements
25
+ // eslint-disable-next-line max-statements
26
26
  build.onResolve({ filter: packageFilter }, async (args) => {
27
27
  const pkg = packageName.exec(args.path);
28
28
  if (!pkg)
@@ -1,2 +1,2 @@
1
- import type { GetSrcFilesFunction } from '../index.js';
1
+ import type { GetSrcFilesFunction } from '../types.js';
2
2
  export declare const getSrcFiles: GetSrcFilesFunction;