@netlify/zip-it-and-ship-it 8.5.0 → 8.6.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 CHANGED
@@ -47,7 +47,7 @@ A directory or a list of directories containing the source files. If a string is
47
47
  must exist. If an array of strings is provided, at least one directory must exist.
48
48
 
49
49
  In Netlify, this directory is the
50
- ["Functions folder"](https://docs.netlify.com/functions/configure-and-deploy/#configure-the-functions-folder).
50
+ ["Functions folder"](https://docs.netlify.com/functions/optional-configuration/?fn-language=ts#directory).
51
51
 
52
52
  A source folder can contain:
53
53
 
@@ -279,7 +279,7 @@ import { zipFunction } from '@netlify/zip-it-and-ship-it'
279
279
  const archive = await zipFunction('functions/function.js', 'functions-dist')
280
280
  ```
281
281
 
282
- This is like [`zipFunctions()`](#zipfunctionssrcfolder-destfolder-options) except it bundles a single Function.
282
+ This is like [`zipFunctions()`](#zipfunctionssrcfolders-destfolder-options) except it bundles a single Function.
283
283
 
284
284
  The return value is `undefined` if the function is invalid.
285
285
 
@@ -334,7 +334,7 @@ Each object has the following properties:
334
334
 
335
335
  ## listFunctionsFiles(srcFolders)
336
336
 
337
- Like [`listFunctions()`](#listfunctionssrcfolder), except it returns not only the Functions main files, but also all
337
+ Like [`listFunctions()`](#listfunctionssrcfolders-options), except it returns not only the Functions main files, but also all
338
338
  their required files. This is much slower.
339
339
 
340
340
  ```js
@@ -358,7 +358,7 @@ See [feature flags](#feature-flags).
358
358
 
359
359
  ### Return value
360
360
 
361
- The return value is the same as [`listFunctions()`](#listfunctionssrcfolder) but with the following additional
361
+ The return value is the same as [`listFunctions()`](#listfunctionssrcfolders-options) but with the following additional
362
362
  properties.
363
363
 
364
364
  - `srcFile`: `string`
@@ -371,7 +371,7 @@ properties.
371
371
  $ zip-it-and-ship-it srcFolder destFolder
372
372
  ```
373
373
 
374
- The CLI performs the same logic as [`zipFunctions()`](#zipfunctionssrcfolder-destfolder-options). The archives are
374
+ The CLI performs the same logic as [`zipFunctions()`](#zipfunctionssrcfolders-destfolder-options). The archives are
375
375
  printed on `stdout` as a JSON array.
376
376
 
377
377
  # Bundling Node.js functions
@@ -429,7 +429,7 @@ These are supplied to each of the entrypoint functions (`zipFunction`, `zipFunct
429
429
  `listFunctionsFiles`) as a named parameter called `featureFlags`. It consists of an object where each key is the name of
430
430
  a feature flag and the values are Booleans indicating whether each feature flag is enabled or disabled.
431
431
 
432
- The list of all feature flags currently being used can be found [here](src/feature_flags.js).
432
+ The list of all feature flags currently being used can be found [here](src/feature_flags.ts).
433
433
 
434
434
  # Troubleshooting
435
435
 
@@ -468,7 +468,7 @@ In Netlify, this is done by ensuring that the following Node.js versions are the
468
468
  - Build-time Node.js version: this defaults to Node `16`, but can be
469
469
  [overridden with a `.nvmrc` or `NODE_VERSION` environment variable](https://docs.netlify.com/configure-builds/manage-dependencies/#node-js-and-javascript).
470
470
  - Function runtime Node.js version: this defaults to `nodejs16.x` but can be
471
- [overridden with a `AWS_LAMBDA_JS_RUNTIME` environment variable](https://docs.netlify.com/functions/build-with-javascript/#runtime-settings).
471
+ [overridden with a `AWS_LAMBDA_JS_RUNTIME` environment variable](https://docs.netlify.com/functions/optional-configuration/?fn-language=js#node-js-version-for-runtime-2).
472
472
 
473
473
  Note that this problem might not apply for Node.js native modules using the [N-API](https://nodejs.org/api/n-api.html).
474
474
 
@@ -16,6 +16,8 @@ export const defaultFlags = {
16
16
  project_deploy_configuration_api_use_per_function_configuration_files: false,
17
17
  // Output CJS file extension
18
18
  zisi_output_cjs_extension: false,
19
+ // Do not allow ___netlify-entry-point as function or file name
20
+ zisi_disallow_new_entry_name: false,
19
21
  };
20
22
  // List of supported flags and their default value.
21
23
  export const getFlags = (input = {}, flags = defaultFlags) => Object.entries(flags).reduce((result, [key, defaultValue]) => ({
@@ -1,8 +1,10 @@
1
1
  import { extname, basename } from 'path';
2
2
  import { getConfigForFunction } from '../config.js';
3
3
  import { defaultFlags } from '../feature_flags.js';
4
+ import { FunctionBundlingUserError } from '../utils/error.js';
4
5
  import goRuntime from './go/index.js';
5
6
  import jsRuntime from './node/index.js';
7
+ import { ENTRY_FILE_NAME } from './node/utils/entry_file.js';
6
8
  import rustRuntime from './rust/index.js';
7
9
  /**
8
10
  * Finds functions for a list of paths using a specific runtime. The return
@@ -17,15 +19,23 @@ const findFunctionsInRuntime = async function ({ cache, dedupe = false, featureF
17
19
  // `srcPath`, so that both functions are returned.
18
20
  const key = dedupe ? 'name' : 'srcPath';
19
21
  // Augmenting the function objects with additional information.
20
- const augmentedFunctions = functions.map((func) => [
21
- func[key],
22
- {
23
- ...func,
24
- extension: extname(func.mainFile),
25
- filename: basename(func.srcPath),
26
- runtime,
27
- },
28
- ]);
22
+ const augmentedFunctions = functions.map((func) => {
23
+ if (featureFlags.zisi_disallow_new_entry_name && func.name === ENTRY_FILE_NAME) {
24
+ throw new FunctionBundlingUserError(`'${ENTRY_FILE_NAME}' is a reserved word and cannot be used as a function name.`, {
25
+ functionName: func.name,
26
+ runtime: runtime.name,
27
+ });
28
+ }
29
+ return [
30
+ func[key],
31
+ {
32
+ ...func,
33
+ extension: extname(func.mainFile),
34
+ filename: basename(func.srcPath),
35
+ runtime,
36
+ },
37
+ ];
38
+ });
29
39
  const usedPaths = new Set(augmentedFunctions.map(([path]) => path));
30
40
  const remainingPaths = paths.filter((path) => !usedPaths.has(path));
31
41
  return { functions: augmentedFunctions, remainingPaths };
@@ -1,5 +1,6 @@
1
1
  import type { FeatureFlags } from '../../../feature_flags.js';
2
2
  import { ModuleFormat } from './module_format.js';
3
+ export declare const ENTRY_FILE_NAME = "___netlify-entry-point";
3
4
  export interface EntryFile {
4
5
  contents: string;
5
6
  filename: string;
@@ -8,8 +9,10 @@ export declare const isNamedLikeEntryFile: (file: string, { basePath, filename,
8
9
  basePath: string;
9
10
  filename: string;
10
11
  }) => boolean;
11
- export declare const conflictsWithEntryFile: (srcFiles: string[], { basePath, mainFile, filename, }: {
12
+ export declare const conflictsWithEntryFile: (srcFiles: string[], { basePath, extension, featureFlags, filename, mainFile, }: {
12
13
  basePath: string;
14
+ extension: string;
15
+ featureFlags: FeatureFlags;
13
16
  filename: string;
14
17
  mainFile: string;
15
18
  }) => boolean;
@@ -1,6 +1,8 @@
1
1
  import { basename, extname, resolve } from 'path';
2
+ import { FunctionBundlingUserError } from '../../../utils/error.js';
2
3
  import { getFileExtensionForFormat } from './module_format.js';
3
4
  import { normalizeFilePath } from './normalize_path.js';
5
+ export const ENTRY_FILE_NAME = '___netlify-entry-point';
4
6
  const getEntryFileContents = (mainPath, moduleFormat) => {
5
7
  const importPath = `.${mainPath.startsWith('/') ? mainPath : `/${mainPath}`}`;
6
8
  if (moduleFormat === "cjs" /* ModuleFormat.COMMONJS */) {
@@ -17,7 +19,21 @@ export const isNamedLikeEntryFile = (file, { basePath, filename, }) => POSSIBLE_
17
19
  return entryFilePath === file;
18
20
  });
19
21
  // Check if any src file (except the mainFile) is considered an entry file for AWS Lambda
20
- export const conflictsWithEntryFile = (srcFiles, { basePath, mainFile, filename, }) => srcFiles.some((srcFile) => isNamedLikeEntryFile(srcFile, { basePath, filename }) && srcFile !== mainFile);
22
+ export const conflictsWithEntryFile = (srcFiles, { basePath, extension, featureFlags, filename, mainFile, }) => {
23
+ let hasConflict = false;
24
+ srcFiles.forEach((srcFile) => {
25
+ if (featureFlags.zisi_disallow_new_entry_name && srcFile.includes(ENTRY_FILE_NAME)) {
26
+ throw new FunctionBundlingUserError(`'${ENTRY_FILE_NAME}' is a reserved word and cannot be used as a file or directory name.`, {
27
+ functionName: basename(filename, extension),
28
+ runtime: "js" /* RuntimeType.JAVASCRIPT */,
29
+ });
30
+ }
31
+ if (!hasConflict && isNamedLikeEntryFile(srcFile, { basePath, filename }) && srcFile !== mainFile) {
32
+ hasConflict = true;
33
+ }
34
+ });
35
+ return hasConflict;
36
+ };
21
37
  // Returns the name for the AWS Lambda entry file
22
38
  // We do set the handler in AWS Lambda to `<func-name>.handler` and because of
23
39
  // this it considers `<func-name>.(c|m)?js` as possible entry-points
@@ -53,6 +53,8 @@ const createZipArchive = async function ({ aliases, basePath, cache, destFolder,
53
53
  // take.
54
54
  const hasEntryFileConflict = conflictsWithEntryFile(srcFiles, {
55
55
  basePath,
56
+ extension,
57
+ featureFlags,
56
58
  filename,
57
59
  mainFile,
58
60
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@netlify/zip-it-and-ship-it",
3
- "version": "8.5.0",
3
+ "version": "8.6.0",
4
4
  "description": "Zip it and ship it",
5
5
  "main": "./dist/main.js",
6
6
  "type": "module",