@vercel/build-utils 2.13.1-canary.2 → 2.14.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.
@@ -3,8 +3,8 @@ ncc: Version 0.24.0
3
3
  ncc: Compiling file index.js
4
4
  ncc: Using typescript@4.3.4 (local user-provided)
5
5
  0kB dist/main/should-serve.d.ts
6
+ 0kB dist/main/get-platform-env.d.ts
6
7
  0kB dist/main/get-ignore-filter.d.ts
7
- 0kB dist/main/detect-framework.d.ts
8
8
  0kB dist/main/fs/stream-to-buffer.d.ts
9
9
  0kB dist/main/fs/rename.d.ts
10
10
  0kB dist/main/fs/read-config-file.d.ts
@@ -13,9 +13,11 @@ ncc: Using typescript@4.3.4 (local user-provided)
13
13
  0kB dist/main/fs/glob.d.ts
14
14
  0kB dist/main/fs/get-writable-directory.d.ts
15
15
  0kB dist/main/fs/download.d.ts
16
+ 0kB dist/main/detect-framework.d.ts
16
17
  0kB dist/main/debug.d.ts
17
18
  1kB dist/main/schemas.d.ts
18
19
  1kB dist/main/prerender.d.ts
20
+ 1kB dist/main/nodejs-lambda.d.ts
19
21
  1kB dist/main/lambda.d.ts
20
22
  1kB dist/main/file-ref.d.ts
21
23
  1kB dist/main/file-fs-ref.d.ts
@@ -23,10 +25,9 @@ ncc: Using typescript@4.3.4 (local user-provided)
23
25
  1kB dist/main/errors.d.ts
24
26
  1kB dist/main/detect-file-system-api.d.ts
25
27
  1kB dist/main/detect-builders.d.ts
28
+ 2kB dist/main/index.d.ts
26
29
  2kB dist/main/detectors/filesystem.d.ts
27
- 2kB dist/main/convert-runtime-to-plugin.d.ts
28
- 3kB dist/main/index.d.ts
29
30
  4kB dist/main/fs/run-user-scripts.d.ts
30
- 9kB dist/main/types.d.ts
31
- 1245kB dist/main/index.js
32
- 1274kB [9973ms] - ncc 0.24.0
31
+ 10kB dist/main/types.d.ts
32
+ 1230kB dist/main/index.js
33
+ 1258kB [8263ms] - ncc 0.24.0
package/dist/debug.js CHANGED
@@ -1,8 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- const _1 = require("./");
3
+ const get_platform_env_1 = require("./get-platform-env");
4
4
  function debug(message, ...additional) {
5
- if (_1.getPlatformEnv('BUILDER_DEBUG')) {
5
+ if (get_platform_env_1.getPlatformEnv('BUILDER_DEBUG')) {
6
6
  console.log(message, ...additional);
7
7
  }
8
8
  }
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Helper function to support both `VERCEL_` and legacy `NOW_` env vars.
3
+ * Throws an error if *both* env vars are defined.
4
+ */
5
+ export declare const getPlatformEnv: (name: string) => string | undefined;
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getPlatformEnv = void 0;
4
+ const errors_1 = require("./errors");
5
+ /**
6
+ * Helper function to support both `VERCEL_` and legacy `NOW_` env vars.
7
+ * Throws an error if *both* env vars are defined.
8
+ */
9
+ const getPlatformEnv = (name) => {
10
+ const vName = `VERCEL_${name}`;
11
+ const nName = `NOW_${name}`;
12
+ const v = process.env[vName];
13
+ const n = process.env[nName];
14
+ if (typeof v === 'string') {
15
+ if (typeof n === 'string') {
16
+ throw new errors_1.NowBuildError({
17
+ code: 'CONFLICTING_ENV_VAR_NAMES',
18
+ message: `Both "${vName}" and "${nName}" env vars are defined. Please only define the "${vName}" env var.`,
19
+ link: 'https://vercel.link/combining-old-and-new-config',
20
+ });
21
+ }
22
+ return v;
23
+ }
24
+ return n;
25
+ };
26
+ exports.getPlatformEnv = getPlatformEnv;
package/dist/index.d.ts CHANGED
@@ -2,6 +2,7 @@ import FileBlob from './file-blob';
2
2
  import FileFsRef from './file-fs-ref';
3
3
  import FileRef from './file-ref';
4
4
  import { Lambda, createLambda, getLambdaOptionsFromFunction } from './lambda';
5
+ import { NodejsLambda } from './nodejs-lambda';
5
6
  import { Prerender } from './prerender';
6
7
  import download, { DownloadedFiles, isSymbolicLink } from './fs/download';
7
8
  import getWriteableDirectory from './fs/get-writable-directory';
@@ -13,14 +14,14 @@ import streamToBuffer from './fs/stream-to-buffer';
13
14
  import shouldServe from './should-serve';
14
15
  import debug from './debug';
15
16
  import getIgnoreFilter from './get-ignore-filter';
16
- export { FileBlob, FileFsRef, FileRef, Lambda, createLambda, Prerender, download, DownloadedFiles, getWriteableDirectory, glob, GlobOptions, rename, execAsync, spawnAsync, getScriptName, installDependencies, runPackageJsonScript, execCommand, spawnCommand, walkParentDirs, getNodeBinPath, runNpmInstall, runBundleInstall, runPipInstall, runShellScript, runCustomInstallCommand, getEnvForPackageManager, getNodeVersion, getLatestNodeVersion, getDiscontinuedNodeVersions, getSpawnOptions, streamToBuffer, shouldServe, debug, isSymbolicLink, getLambdaOptionsFromFunction, scanParentDirs, getIgnoreFilter, };
17
+ import { getPlatformEnv } from './get-platform-env';
18
+ export { FileBlob, FileFsRef, FileRef, Lambda, NodejsLambda, createLambda, Prerender, download, DownloadedFiles, getWriteableDirectory, glob, GlobOptions, rename, execAsync, spawnAsync, getScriptName, installDependencies, runPackageJsonScript, execCommand, spawnCommand, walkParentDirs, getNodeBinPath, runNpmInstall, runBundleInstall, runPipInstall, runShellScript, runCustomInstallCommand, getEnvForPackageManager, getNodeVersion, getLatestNodeVersion, getDiscontinuedNodeVersions, getSpawnOptions, getPlatformEnv, streamToBuffer, shouldServe, debug, isSymbolicLink, getLambdaOptionsFromFunction, scanParentDirs, getIgnoreFilter, };
17
19
  export { detectBuilders, detectOutputDirectory, detectApiDirectory, detectApiExtensions, } from './detect-builders';
18
20
  export { detectFileSystemAPI } from './detect-file-system-api';
19
21
  export { detectFramework } from './detect-framework';
20
22
  export { DetectorFilesystem } from './detectors/filesystem';
21
23
  export { readConfigFile } from './fs/read-config-file';
22
24
  export { normalizePath } from './fs/normalize-path';
23
- export { _experimental_convertRuntimeToPlugin, _experimental_updateFunctionsManifest, _experimental_updateRoutesManifest, } from './convert-runtime-to-plugin';
24
25
  export * from './schemas';
25
26
  export * from './types';
26
27
  export * from './errors';
@@ -29,8 +30,3 @@ export * from './errors';
29
30
  */
30
31
  export declare const isOfficialRuntime: (desired: string, name?: string | undefined) => boolean;
31
32
  export declare const isStaticRuntime: (name?: string | undefined) => boolean;
32
- /**
33
- * Helper function to support both `VERCEL_` and legacy `NOW_` env vars.
34
- * Throws an error if *both* env vars are defined.
35
- */
36
- export declare const getPlatformEnv: (name: string) => string | undefined;
package/dist/index.js CHANGED
@@ -32713,310 +32713,6 @@ module.exports = new Type('tag:yaml.org,2002:timestamp', {
32713
32713
  });
32714
32714
 
32715
32715
 
32716
- /***/ }),
32717
-
32718
- /***/ 7276:
32719
- /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
32720
-
32721
- "use strict";
32722
-
32723
- var __importDefault = (this && this.__importDefault) || function (mod) {
32724
- return (mod && mod.__esModule) ? mod : { "default": mod };
32725
- };
32726
- Object.defineProperty(exports, "__esModule", ({ value: true }));
32727
- exports._experimental_updateRoutesManifest = exports._experimental_updateFunctionsManifest = exports._experimental_convertRuntimeToPlugin = void 0;
32728
- const fs_extra_1 = __importDefault(__webpack_require__(5392));
32729
- const path_1 = __webpack_require__(5622);
32730
- const glob_1 = __importDefault(__webpack_require__(4240));
32731
- const normalize_path_1 = __webpack_require__(6261);
32732
- const _1 = __webpack_require__(2855);
32733
- // `.output` was already created by the Build Command, so we have
32734
- // to ensure its contents don't get bundled into the Lambda. Similarily,
32735
- // we don't want to bundle anything from `.vercel` either. Lastly,
32736
- // Builders/Runtimes didn't have `vercel.json` or `now.json`.
32737
- const ignoredPaths = ['.output', '.vercel', 'vercel.json', 'now.json'];
32738
- const shouldIgnorePath = (file, ignoreFilter, ignoreFile) => {
32739
- const isNative = ignoredPaths.some(item => {
32740
- return file.startsWith(item);
32741
- });
32742
- if (!ignoreFile) {
32743
- return isNative;
32744
- }
32745
- return isNative || ignoreFilter(file);
32746
- };
32747
- const getSourceFiles = async (workPath, ignoreFilter) => {
32748
- const list = await glob_1.default('**', {
32749
- cwd: workPath,
32750
- });
32751
- // We're not passing this as an `ignore` filter to the `glob` function above,
32752
- // so that we can re-use exactly the same `getIgnoreFilter` method that the
32753
- // Build Step uses (literally the same code). Note that this exclusion only applies
32754
- // when deploying. Locally, another exclusion is needed, which is handled
32755
- // further below in the `convertRuntimeToPlugin` function.
32756
- for (const file in list) {
32757
- if (shouldIgnorePath(file, ignoreFilter, true)) {
32758
- delete list[file];
32759
- }
32760
- }
32761
- return list;
32762
- };
32763
- /**
32764
- * Convert legacy Runtime to a Plugin.
32765
- * @param buildRuntime - a legacy build() function from a Runtime
32766
- * @param packageName - the name of the package, for example `vercel-plugin-python`
32767
- * @param ext - the file extension, for example `.py`
32768
- */
32769
- function _experimental_convertRuntimeToPlugin(buildRuntime, packageName, ext) {
32770
- // This `build()` signature should match `plugin.build()` signature in `vercel build`.
32771
- return async function build({ workPath }) {
32772
- // We also don't want to provide any files to Runtimes that were ignored
32773
- // through `.vercelignore` or `.nowignore`, because the Build Step does the same.
32774
- const ignoreFilter = await _1.getIgnoreFilter(workPath);
32775
- // Retrieve the files that are currently available on the File System,
32776
- // before the Legacy Runtime has even started to build.
32777
- const sourceFilesPreBuild = await getSourceFiles(workPath, ignoreFilter);
32778
- // Instead of doing another `glob` to get all the matching source files,
32779
- // we'll filter the list of existing files down to only the ones
32780
- // that are matching the entrypoint pattern, so we're first creating
32781
- // a clean new list to begin.
32782
- const entrypoints = Object.assign({}, sourceFilesPreBuild);
32783
- const entrypointMatch = new RegExp(`^api/.*${ext}$`);
32784
- // Up next, we'll strip out the files from the list of entrypoints
32785
- // that aren't actually considered entrypoints.
32786
- for (const file in entrypoints) {
32787
- if (!entrypointMatch.test(file)) {
32788
- delete entrypoints[file];
32789
- }
32790
- }
32791
- const pages = {};
32792
- const pluginName = packageName.replace('vercel-plugin-', '');
32793
- const outputPath = path_1.join(workPath, '.output');
32794
- const traceDir = path_1.join(outputPath, `inputs`,
32795
- // Legacy Runtimes can only provide API Routes, so that's
32796
- // why we can use this prefix for all of them. Here, we have to
32797
- // make sure to not use a cryptic hash name, because people
32798
- // need to be able to easily inspect the output.
32799
- `api-routes-${pluginName}`);
32800
- await fs_extra_1.default.ensureDir(traceDir);
32801
- const entryRoot = path_1.join(outputPath, 'server', 'pages');
32802
- for (const entrypoint of Object.keys(entrypoints)) {
32803
- const { output } = await buildRuntime({
32804
- files: sourceFilesPreBuild,
32805
- entrypoint,
32806
- workPath,
32807
- config: {
32808
- zeroConfig: true,
32809
- },
32810
- meta: {
32811
- avoidTopLevelInstall: true,
32812
- skipDownload: true,
32813
- },
32814
- });
32815
- const lambdaFiles = output.files;
32816
- // When deploying, the `files` that are passed to the Legacy Runtimes already
32817
- // have certain files that are ignored stripped, but locally, that list of
32818
- // files isn't used by the Legacy Runtimes, so we need to apply the filters
32819
- // to the outputs that they are returning instead.
32820
- for (const file in lambdaFiles) {
32821
- if (shouldIgnorePath(file, ignoreFilter, false)) {
32822
- delete lambdaFiles[file];
32823
- }
32824
- }
32825
- let handlerFileBase = output.handler;
32826
- let handlerFile = lambdaFiles[handlerFileBase];
32827
- let handlerHasImport = false;
32828
- const { handler } = output;
32829
- const handlerMethod = handler.split('.').pop();
32830
- const handlerFileName = handler.replace(`.${handlerMethod}`, '');
32831
- // For compiled languages, the launcher file for the Lambda generated
32832
- // by the Legacy Runtime matches the `handler` defined for it, but for
32833
- // interpreted languages, the `handler` consists of the launcher file name
32834
- // without an extension, plus the name of the method inside of that file
32835
- // that should be invoked, so we have to construct the file path explicitly.
32836
- if (!handlerFile) {
32837
- handlerFileBase = handlerFileName + ext;
32838
- handlerFile = lambdaFiles[handlerFileBase];
32839
- handlerHasImport = true;
32840
- }
32841
- if (!handlerFile || !handlerFile.fsPath) {
32842
- throw new Error(`Could not find a handler file. Please ensure that \`files\` for the returned \`Lambda\` contains an \`FileFsRef\` named "${handlerFileBase}" with a valid \`fsPath\`.`);
32843
- }
32844
- const handlerExtName = path_1.extname(handlerFile.fsPath);
32845
- const entryBase = path_1.basename(entrypoint).replace(ext, handlerExtName);
32846
- const entryPath = path_1.join(path_1.dirname(entrypoint), entryBase);
32847
- const entry = path_1.join(entryRoot, entryPath);
32848
- // Create the parent directory of the API Route that will be created
32849
- // for the current entrypoint inside of `.output/server/pages/api`.
32850
- await fs_extra_1.default.ensureDir(path_1.dirname(entry));
32851
- // For compiled languages, the launcher file will be binary and therefore
32852
- // won't try to import a user-provided request handler (instead, it will
32853
- // contain it). But for interpreted languages, the launcher might try to
32854
- // load a user-provided request handler from the source file instead of bundling
32855
- // it, so we have to adjust the import statement inside the launcher to point
32856
- // to the respective source file. Previously, Legacy Runtimes simply expected
32857
- // the user-provided request-handler to be copied right next to the launcher,
32858
- // but with the new File System API, files won't be moved around unnecessarily.
32859
- if (handlerHasImport) {
32860
- const { fsPath } = handlerFile;
32861
- const encoding = 'utf-8';
32862
- // This is the true directory of the user-provided request handler in the
32863
- // source files, so that's what we will use as an import path in the launcher.
32864
- const locationPrefix = path_1.relative(entry, outputPath);
32865
- let handlerContent = await fs_extra_1.default.readFile(fsPath, encoding);
32866
- const importPaths = [
32867
- // This is the full entrypoint path, like `./api/test.py`. In our tests
32868
- // Python didn't support importing from a parent directory without using different
32869
- // code in the launcher that registers it as a location for modules and then changing
32870
- // the importing syntax, but continuing to import it like before seems to work. If
32871
- // other languages need this, we should consider excluding Python explicitly.
32872
- // `./${entrypoint}`,
32873
- // This is the entrypoint path without extension, like `api/test`
32874
- entrypoint.slice(0, -ext.length),
32875
- ];
32876
- // Generate a list of regular expressions that we can use for
32877
- // finding matches, but only allow matches if the import path is
32878
- // wrapped inside single (') or double quotes (").
32879
- const patterns = importPaths.map(path => {
32880
- // eslint-disable-next-line no-useless-escape
32881
- return new RegExp(`('|")(${path.replace(/\./g, '\\.')})('|")`, 'g');
32882
- });
32883
- let replacedMatch = null;
32884
- for (const pattern of patterns) {
32885
- const newContent = handlerContent.replace(pattern, (_, p1, p2, p3) => {
32886
- return `${p1}${path_1.join(locationPrefix, p2)}${p3}`;
32887
- });
32888
- if (newContent !== handlerContent) {
32889
- _1.debug(`Replaced "${pattern}" inside "${entry}" to ensure correct import of user-provided request handler`);
32890
- handlerContent = newContent;
32891
- replacedMatch = true;
32892
- }
32893
- }
32894
- if (!replacedMatch) {
32895
- new Error(`No replacable matches for "${importPaths[0]}" or "${importPaths[1]}" found in "${fsPath}"`);
32896
- }
32897
- await fs_extra_1.default.writeFile(entry, handlerContent, encoding);
32898
- }
32899
- else {
32900
- await fs_extra_1.default.copy(handlerFile.fsPath, entry);
32901
- }
32902
- // Legacy Runtimes based on interpreted languages will create a new launcher file
32903
- // for every entrypoint, but they will create each one inside `workPath`, which means that
32904
- // the launcher for one entrypoint will overwrite the launcher provided for the previous
32905
- // entrypoint. That's why, above, we copy the file contents into the new destination (and
32906
- // optionally transform them along the way), instead of linking. We then also want to remove
32907
- // the copy origin right here, so that the `workPath` doesn't contain a useless launcher file
32908
- // once the build has finished running.
32909
- await fs_extra_1.default.remove(handlerFile.fsPath);
32910
- _1.debug(`Removed temporary file "${handlerFile.fsPath}"`);
32911
- const nft = `${entry}.nft.json`;
32912
- const json = JSON.stringify({
32913
- version: 2,
32914
- files: Object.keys(lambdaFiles)
32915
- .map(file => {
32916
- const { fsPath } = lambdaFiles[file];
32917
- if (!fsPath) {
32918
- throw new Error(`File "${file}" is missing valid \`fsPath\` property`);
32919
- }
32920
- // The handler was already moved into position above.
32921
- if (file === handlerFileBase) {
32922
- return;
32923
- }
32924
- return normalize_path_1.normalizePath(path_1.relative(path_1.dirname(nft), fsPath));
32925
- })
32926
- .filter(Boolean),
32927
- });
32928
- await fs_extra_1.default.writeFile(nft, json);
32929
- // Add an entry that will later on be added to the `functions-manifest.json`
32930
- // file that is placed inside of the `.output` directory.
32931
- pages[normalize_path_1.normalizePath(entryPath)] = {
32932
- // Because the underlying file used as a handler was placed
32933
- // inside `.output/server/pages/api`, it no longer has the name it originally
32934
- // had and is now named after the API Route that it's responsible for,
32935
- // so we have to adjust the name of the Lambda handler accordingly.
32936
- handler: handler.replace(handlerFileName, path_1.parse(entry).name),
32937
- runtime: output.runtime,
32938
- memory: output.memory,
32939
- maxDuration: output.maxDuration,
32940
- environment: output.environment,
32941
- allowQuery: output.allowQuery,
32942
- };
32943
- }
32944
- // Add any Serverless Functions that were exposed by the Legacy Runtime
32945
- // to the `functions-manifest.json` file provided in `.output`.
32946
- await _experimental_updateFunctionsManifest({ workPath, pages });
32947
- };
32948
- }
32949
- exports._experimental_convertRuntimeToPlugin = _experimental_convertRuntimeToPlugin;
32950
- async function readJson(filePath) {
32951
- try {
32952
- const str = await fs_extra_1.default.readFile(filePath, 'utf8');
32953
- return JSON.parse(str);
32954
- }
32955
- catch (err) {
32956
- if (err.code === 'ENOENT') {
32957
- return {};
32958
- }
32959
- throw err;
32960
- }
32961
- }
32962
- /**
32963
- * If `.output/functions-manifest.json` exists, append to the pages
32964
- * property. Otherwise write a new file.
32965
- */
32966
- async function _experimental_updateFunctionsManifest({ workPath, pages, }) {
32967
- const functionsManifestPath = path_1.join(workPath, '.output', 'functions-manifest.json');
32968
- const functionsManifest = await readJson(functionsManifestPath);
32969
- if (!functionsManifest.version)
32970
- functionsManifest.version = 2;
32971
- if (!functionsManifest.pages)
32972
- functionsManifest.pages = {};
32973
- for (const [pageKey, pageConfig] of Object.entries(pages)) {
32974
- functionsManifest.pages[pageKey] = { ...pageConfig };
32975
- }
32976
- await fs_extra_1.default.writeFile(functionsManifestPath, JSON.stringify(functionsManifest));
32977
- }
32978
- exports._experimental_updateFunctionsManifest = _experimental_updateFunctionsManifest;
32979
- /**
32980
- * Append routes to the `routes-manifest.json` file.
32981
- * If the file does not exist, it will be created.
32982
- */
32983
- async function _experimental_updateRoutesManifest({ workPath, redirects, rewrites, headers, dynamicRoutes, staticRoutes, }) {
32984
- const routesManifestPath = path_1.join(workPath, '.output', 'routes-manifest.json');
32985
- const routesManifest = await readJson(routesManifestPath);
32986
- if (!routesManifest.version)
32987
- routesManifest.version = 3;
32988
- if (routesManifest.pages404 === undefined)
32989
- routesManifest.pages404 = true;
32990
- if (redirects) {
32991
- if (!routesManifest.redirects)
32992
- routesManifest.redirects = [];
32993
- routesManifest.redirects.push(...redirects);
32994
- }
32995
- if (rewrites) {
32996
- if (!routesManifest.rewrites)
32997
- routesManifest.rewrites = [];
32998
- routesManifest.rewrites.push(...rewrites);
32999
- }
33000
- if (headers) {
33001
- if (!routesManifest.headers)
33002
- routesManifest.headers = [];
33003
- routesManifest.headers.push(...headers);
33004
- }
33005
- if (dynamicRoutes) {
33006
- if (!routesManifest.dynamicRoutes)
33007
- routesManifest.dynamicRoutes = [];
33008
- routesManifest.dynamicRoutes.push(...dynamicRoutes);
33009
- }
33010
- if (staticRoutes) {
33011
- if (!routesManifest.staticRoutes)
33012
- routesManifest.staticRoutes = [];
33013
- routesManifest.staticRoutes.push(...staticRoutes);
33014
- }
33015
- await fs_extra_1.default.writeFile(routesManifestPath, JSON.stringify(routesManifest));
33016
- }
33017
- exports._experimental_updateRoutesManifest = _experimental_updateRoutesManifest;
33018
-
33019
-
33020
32716
  /***/ }),
33021
32717
 
33022
32718
  /***/ 1868:
@@ -33025,9 +32721,9 @@ exports._experimental_updateRoutesManifest = _experimental_updateRoutesManifest;
33025
32721
  "use strict";
33026
32722
 
33027
32723
  Object.defineProperty(exports, "__esModule", ({ value: true }));
33028
- const _1 = __webpack_require__(2855);
32724
+ const get_platform_env_1 = __webpack_require__(4678);
33029
32725
  function debug(message, ...additional) {
33030
- if (_1.getPlatformEnv('BUILDER_DEBUG')) {
32726
+ if (get_platform_env_1.getPlatformEnv('BUILDER_DEBUG')) {
33031
32727
  console.log(message, ...additional);
33032
32728
  }
33033
32729
  }
@@ -35288,6 +34984,40 @@ async function default_1(downloadPath, rootDirectory) {
35288
34984
  exports.default = default_1;
35289
34985
 
35290
34986
 
34987
+ /***/ }),
34988
+
34989
+ /***/ 4678:
34990
+ /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
34991
+
34992
+ "use strict";
34993
+
34994
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
34995
+ exports.getPlatformEnv = void 0;
34996
+ const errors_1 = __webpack_require__(3983);
34997
+ /**
34998
+ * Helper function to support both `VERCEL_` and legacy `NOW_` env vars.
34999
+ * Throws an error if *both* env vars are defined.
35000
+ */
35001
+ const getPlatformEnv = (name) => {
35002
+ const vName = `VERCEL_${name}`;
35003
+ const nName = `NOW_${name}`;
35004
+ const v = process.env[vName];
35005
+ const n = process.env[nName];
35006
+ if (typeof v === 'string') {
35007
+ if (typeof n === 'string') {
35008
+ throw new errors_1.NowBuildError({
35009
+ code: 'CONFLICTING_ENV_VAR_NAMES',
35010
+ message: `Both "${vName}" and "${nName}" env vars are defined. Please only define the "${vName}" env var.`,
35011
+ link: 'https://vercel.link/combining-old-and-new-config',
35012
+ });
35013
+ }
35014
+ return v;
35015
+ }
35016
+ return n;
35017
+ };
35018
+ exports.getPlatformEnv = getPlatformEnv;
35019
+
35020
+
35291
35021
  /***/ }),
35292
35022
 
35293
35023
  /***/ 2855:
@@ -35321,8 +35051,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
35321
35051
  return (mod && mod.__esModule) ? mod : { "default": mod };
35322
35052
  };
35323
35053
  Object.defineProperty(exports, "__esModule", ({ value: true }));
35324
- exports.isStaticRuntime = exports.isOfficialRuntime = exports._experimental_updateRoutesManifest = exports._experimental_updateFunctionsManifest = exports._experimental_convertRuntimeToPlugin = exports.normalizePath = exports.readConfigFile = exports.DetectorFilesystem = exports.detectFramework = exports.detectFileSystemAPI = exports.detectApiExtensions = exports.detectApiDirectory = exports.detectOutputDirectory = exports.detectBuilders = exports.getIgnoreFilter = exports.scanParentDirs = exports.getLambdaOptionsFromFunction = exports.isSymbolicLink = exports.debug = exports.shouldServe = exports.streamToBuffer = exports.getSpawnOptions = exports.getDiscontinuedNodeVersions = exports.getLatestNodeVersion = exports.getNodeVersion = exports.getEnvForPackageManager = exports.runCustomInstallCommand = exports.runShellScript = exports.runPipInstall = exports.runBundleInstall = exports.runNpmInstall = exports.getNodeBinPath = exports.walkParentDirs = exports.spawnCommand = exports.execCommand = exports.runPackageJsonScript = exports.installDependencies = exports.getScriptName = exports.spawnAsync = exports.execAsync = exports.rename = exports.glob = exports.getWriteableDirectory = exports.download = exports.Prerender = exports.createLambda = exports.Lambda = exports.FileRef = exports.FileFsRef = exports.FileBlob = void 0;
35325
- exports.getPlatformEnv = void 0;
35054
+ exports.isStaticRuntime = exports.isOfficialRuntime = exports.normalizePath = exports.readConfigFile = exports.DetectorFilesystem = exports.detectFramework = exports.detectFileSystemAPI = exports.detectApiExtensions = exports.detectApiDirectory = exports.detectOutputDirectory = exports.detectBuilders = exports.getIgnoreFilter = exports.scanParentDirs = exports.getLambdaOptionsFromFunction = exports.isSymbolicLink = exports.debug = exports.shouldServe = exports.streamToBuffer = exports.getPlatformEnv = exports.getSpawnOptions = exports.getDiscontinuedNodeVersions = exports.getLatestNodeVersion = exports.getNodeVersion = exports.getEnvForPackageManager = exports.runCustomInstallCommand = exports.runShellScript = exports.runPipInstall = exports.runBundleInstall = exports.runNpmInstall = exports.getNodeBinPath = exports.walkParentDirs = exports.spawnCommand = exports.execCommand = exports.runPackageJsonScript = exports.installDependencies = exports.getScriptName = exports.spawnAsync = exports.execAsync = exports.rename = exports.glob = exports.getWriteableDirectory = exports.download = exports.Prerender = exports.createLambda = exports.NodejsLambda = exports.Lambda = exports.FileRef = exports.FileFsRef = exports.FileBlob = void 0;
35326
35055
  const file_blob_1 = __importDefault(__webpack_require__(2397));
35327
35056
  exports.FileBlob = file_blob_1.default;
35328
35057
  const file_fs_ref_1 = __importDefault(__webpack_require__(9331));
@@ -35333,6 +35062,8 @@ const lambda_1 = __webpack_require__(6721);
35333
35062
  Object.defineProperty(exports, "Lambda", ({ enumerable: true, get: function () { return lambda_1.Lambda; } }));
35334
35063
  Object.defineProperty(exports, "createLambda", ({ enumerable: true, get: function () { return lambda_1.createLambda; } }));
35335
35064
  Object.defineProperty(exports, "getLambdaOptionsFromFunction", ({ enumerable: true, get: function () { return lambda_1.getLambdaOptionsFromFunction; } }));
35065
+ const nodejs_lambda_1 = __webpack_require__(7049);
35066
+ Object.defineProperty(exports, "NodejsLambda", ({ enumerable: true, get: function () { return nodejs_lambda_1.NodejsLambda; } }));
35336
35067
  const prerender_1 = __webpack_require__(2850);
35337
35068
  Object.defineProperty(exports, "Prerender", ({ enumerable: true, get: function () { return prerender_1.Prerender; } }));
35338
35069
  const download_1 = __importStar(__webpack_require__(1611));
@@ -35366,7 +35097,6 @@ Object.defineProperty(exports, "scanParentDirs", ({ enumerable: true, get: funct
35366
35097
  const node_version_1 = __webpack_require__(7903);
35367
35098
  Object.defineProperty(exports, "getLatestNodeVersion", ({ enumerable: true, get: function () { return node_version_1.getLatestNodeVersion; } }));
35368
35099
  Object.defineProperty(exports, "getDiscontinuedNodeVersions", ({ enumerable: true, get: function () { return node_version_1.getDiscontinuedNodeVersions; } }));
35369
- const errors_1 = __webpack_require__(3983);
35370
35100
  const stream_to_buffer_1 = __importDefault(__webpack_require__(2560));
35371
35101
  exports.streamToBuffer = stream_to_buffer_1.default;
35372
35102
  const should_serve_1 = __importDefault(__webpack_require__(2564));
@@ -35375,6 +35105,8 @@ const debug_1 = __importDefault(__webpack_require__(1868));
35375
35105
  exports.debug = debug_1.default;
35376
35106
  const get_ignore_filter_1 = __importDefault(__webpack_require__(1148));
35377
35107
  exports.getIgnoreFilter = get_ignore_filter_1.default;
35108
+ const get_platform_env_1 = __webpack_require__(4678);
35109
+ Object.defineProperty(exports, "getPlatformEnv", ({ enumerable: true, get: function () { return get_platform_env_1.getPlatformEnv; } }));
35378
35110
  var detect_builders_1 = __webpack_require__(4246);
35379
35111
  Object.defineProperty(exports, "detectBuilders", ({ enumerable: true, get: function () { return detect_builders_1.detectBuilders; } }));
35380
35112
  Object.defineProperty(exports, "detectOutputDirectory", ({ enumerable: true, get: function () { return detect_builders_1.detectOutputDirectory; } }));
@@ -35390,10 +35122,6 @@ var read_config_file_1 = __webpack_require__(7792);
35390
35122
  Object.defineProperty(exports, "readConfigFile", ({ enumerable: true, get: function () { return read_config_file_1.readConfigFile; } }));
35391
35123
  var normalize_path_1 = __webpack_require__(6261);
35392
35124
  Object.defineProperty(exports, "normalizePath", ({ enumerable: true, get: function () { return normalize_path_1.normalizePath; } }));
35393
- var convert_runtime_to_plugin_1 = __webpack_require__(7276);
35394
- Object.defineProperty(exports, "_experimental_convertRuntimeToPlugin", ({ enumerable: true, get: function () { return convert_runtime_to_plugin_1._experimental_convertRuntimeToPlugin; } }));
35395
- Object.defineProperty(exports, "_experimental_updateFunctionsManifest", ({ enumerable: true, get: function () { return convert_runtime_to_plugin_1._experimental_updateFunctionsManifest; } }));
35396
- Object.defineProperty(exports, "_experimental_updateRoutesManifest", ({ enumerable: true, get: function () { return convert_runtime_to_plugin_1._experimental_updateRoutesManifest; } }));
35397
35125
  __exportStar(__webpack_require__(2416), exports);
35398
35126
  __exportStar(__webpack_require__(5748), exports);
35399
35127
  __exportStar(__webpack_require__(3983), exports);
@@ -35414,28 +35142,6 @@ const isStaticRuntime = (name) => {
35414
35142
  return exports.isOfficialRuntime('static', name);
35415
35143
  };
35416
35144
  exports.isStaticRuntime = isStaticRuntime;
35417
- /**
35418
- * Helper function to support both `VERCEL_` and legacy `NOW_` env vars.
35419
- * Throws an error if *both* env vars are defined.
35420
- */
35421
- const getPlatformEnv = (name) => {
35422
- const vName = `VERCEL_${name}`;
35423
- const nName = `NOW_${name}`;
35424
- const v = process.env[vName];
35425
- const n = process.env[nName];
35426
- if (typeof v === 'string') {
35427
- if (typeof n === 'string') {
35428
- throw new errors_1.NowBuildError({
35429
- code: 'CONFLICTING_ENV_VAR_NAMES',
35430
- message: `Both "${vName}" and "${nName}" env vars are defined. Please only define the "${vName}" env var.`,
35431
- link: 'https://vercel.link/combining-old-and-new-config',
35432
- });
35433
- }
35434
- return v;
35435
- }
35436
- return n;
35437
- };
35438
- exports.getPlatformEnv = getPlatformEnv;
35439
35145
 
35440
35146
 
35441
35147
  /***/ }),
@@ -35564,6 +35270,28 @@ async function getLambdaOptionsFromFunction({ sourceFile, config, }) {
35564
35270
  exports.getLambdaOptionsFromFunction = getLambdaOptionsFromFunction;
35565
35271
 
35566
35272
 
35273
+ /***/ }),
35274
+
35275
+ /***/ 7049:
35276
+ /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
35277
+
35278
+ "use strict";
35279
+
35280
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
35281
+ exports.NodejsLambda = void 0;
35282
+ const lambda_1 = __webpack_require__(6721);
35283
+ class NodejsLambda extends lambda_1.Lambda {
35284
+ constructor({ shouldAddHelpers, shouldAddSourcemapSupport, awsLambdaHandler, ...opts }) {
35285
+ super(opts);
35286
+ this.launcherType = 'Nodejs';
35287
+ this.shouldAddHelpers = shouldAddHelpers;
35288
+ this.shouldAddSourcemapSupport = shouldAddSourcemapSupport;
35289
+ this.awsLambdaHandler = awsLambdaHandler;
35290
+ }
35291
+ }
35292
+ exports.NodejsLambda = NodejsLambda;
35293
+
35294
+
35567
35295
  /***/ }),
35568
35296
 
35569
35297
  /***/ 2850:
package/dist/lambda.d.ts CHANGED
@@ -3,7 +3,7 @@ import { Files, Config } from './types';
3
3
  interface Environment {
4
4
  [key: string]: string;
5
5
  }
6
- interface LambdaOptions {
6
+ export interface LambdaOptions {
7
7
  files: Files;
8
8
  handler: string;
9
9
  runtime: string;
@@ -0,0 +1,14 @@
1
+ import { Lambda, LambdaOptions } from './lambda';
2
+ interface NodejsLambdaOptions extends LambdaOptions {
3
+ shouldAddHelpers: boolean;
4
+ shouldAddSourcemapSupport: boolean;
5
+ awsLambdaHandler?: string;
6
+ }
7
+ export declare class NodejsLambda extends Lambda {
8
+ launcherType: 'Nodejs';
9
+ shouldAddHelpers: boolean;
10
+ shouldAddSourcemapSupport: boolean;
11
+ awsLambdaHandler?: string;
12
+ constructor({ shouldAddHelpers, shouldAddSourcemapSupport, awsLambdaHandler, ...opts }: NodejsLambdaOptions);
13
+ }
14
+ export {};
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.NodejsLambda = void 0;
4
+ const lambda_1 = require("./lambda");
5
+ class NodejsLambda extends lambda_1.Lambda {
6
+ constructor({ shouldAddHelpers, shouldAddSourcemapSupport, awsLambdaHandler, ...opts }) {
7
+ super(opts);
8
+ this.launcherType = 'Nodejs';
9
+ this.shouldAddHelpers = shouldAddHelpers;
10
+ this.shouldAddSourcemapSupport = shouldAddSourcemapSupport;
11
+ this.awsLambdaHandler = awsLambdaHandler;
12
+ }
13
+ }
14
+ exports.NodejsLambda = NodejsLambda;
package/dist/types.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  /// <reference types="node" />
2
2
  import FileRef from './file-ref';
3
3
  import FileFsRef from './file-fs-ref';
4
+ import { Lambda } from './lambda';
4
5
  export interface Env {
5
6
  [name: string]: string | undefined;
6
7
  }
@@ -319,3 +320,40 @@ export interface ProjectSettings {
319
320
  directoryListing?: boolean;
320
321
  gitForkProtection?: boolean;
321
322
  }
323
+ export interface BuilderV2 {
324
+ version: 2;
325
+ build: BuildV2;
326
+ prepareCache?: PrepareCache;
327
+ }
328
+ export interface BuilderV3 {
329
+ version: 3;
330
+ build: BuildV3;
331
+ prepareCache?: PrepareCache;
332
+ startDevServer?: StartDevServer;
333
+ }
334
+ declare type ImageFormat = 'image/avif' | 'image/webp';
335
+ export interface Images {
336
+ domains: string[];
337
+ sizes: number[];
338
+ minimumCacheTTL?: number;
339
+ formats?: ImageFormat[];
340
+ }
341
+ export interface BuildResultV2 {
342
+ routes: any[];
343
+ images?: Images;
344
+ output: {
345
+ [key: string]: File | Lambda;
346
+ };
347
+ wildcard?: Array<{
348
+ domain: string;
349
+ value: string;
350
+ }>;
351
+ }
352
+ export interface BuildResultV3 {
353
+ output: Lambda;
354
+ }
355
+ export declare type BuildV2 = (options: BuildOptions) => Promise<BuildResultV2>;
356
+ export declare type BuildV3 = (options: BuildOptions) => Promise<BuildResultV3>;
357
+ export declare type PrepareCache = (options: PrepareCacheOptions) => Promise<Files>;
358
+ export declare type StartDevServer = (options: StartDevServerOptions) => Promise<StartDevServerResult>;
359
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vercel/build-utils",
3
- "version": "2.13.1-canary.2",
3
+ "version": "2.14.0",
4
4
  "license": "MIT",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.js",
@@ -30,7 +30,7 @@
30
30
  "@types/node-fetch": "^2.1.6",
31
31
  "@types/semver": "6.0.0",
32
32
  "@types/yazl": "^2.4.1",
33
- "@vercel/frameworks": "0.5.1-canary.21",
33
+ "@vercel/frameworks": "0.6.0",
34
34
  "@vercel/ncc": "0.24.0",
35
35
  "aggregate-error": "3.0.1",
36
36
  "async-retry": "1.2.3",
@@ -49,5 +49,5 @@
49
49
  "typescript": "4.3.4",
50
50
  "yazl": "2.4.3"
51
51
  },
52
- "gitHead": "28f3bf9ef6e492156eb127c7cbdcbfcfeafdf7e4"
52
+ "gitHead": "99fa729966c4334aa2d64c592421cc65e1644bdb"
53
53
  }
@@ -1,65 +0,0 @@
1
- import { Lambda } from './lambda';
2
- import type { BuildOptions } from './types';
3
- /**
4
- * Convert legacy Runtime to a Plugin.
5
- * @param buildRuntime - a legacy build() function from a Runtime
6
- * @param packageName - the name of the package, for example `vercel-plugin-python`
7
- * @param ext - the file extension, for example `.py`
8
- */
9
- export declare function _experimental_convertRuntimeToPlugin(buildRuntime: (options: BuildOptions) => Promise<{
10
- output: Lambda;
11
- }>, packageName: string, ext: string): ({ workPath }: {
12
- workPath: string;
13
- }) => Promise<void>;
14
- /**
15
- * If `.output/functions-manifest.json` exists, append to the pages
16
- * property. Otherwise write a new file.
17
- */
18
- export declare function _experimental_updateFunctionsManifest({ workPath, pages, }: {
19
- workPath: string;
20
- pages: {
21
- [key: string]: any;
22
- };
23
- }): Promise<void>;
24
- /**
25
- * Append routes to the `routes-manifest.json` file.
26
- * If the file does not exist, it will be created.
27
- */
28
- export declare function _experimental_updateRoutesManifest({ workPath, redirects, rewrites, headers, dynamicRoutes, staticRoutes, }: {
29
- workPath: string;
30
- redirects?: {
31
- source: string;
32
- destination: string;
33
- statusCode: number;
34
- regex: string;
35
- }[];
36
- rewrites?: {
37
- source: string;
38
- destination: string;
39
- regex: string;
40
- }[];
41
- headers?: {
42
- source: string;
43
- headers: {
44
- key: string;
45
- value: string;
46
- }[];
47
- regex: string;
48
- }[];
49
- dynamicRoutes?: {
50
- page: string;
51
- regex: string;
52
- namedRegex?: string;
53
- routeKeys?: {
54
- [named: string]: string;
55
- };
56
- }[];
57
- staticRoutes?: {
58
- page: string;
59
- regex: string;
60
- namedRegex?: string;
61
- routeKeys?: {
62
- [named: string]: string;
63
- };
64
- }[];
65
- }): Promise<void>;
@@ -1,296 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports._experimental_updateRoutesManifest = exports._experimental_updateFunctionsManifest = exports._experimental_convertRuntimeToPlugin = void 0;
7
- const fs_extra_1 = __importDefault(require("fs-extra"));
8
- const path_1 = require("path");
9
- const glob_1 = __importDefault(require("./fs/glob"));
10
- const normalize_path_1 = require("./fs/normalize-path");
11
- const _1 = require(".");
12
- // `.output` was already created by the Build Command, so we have
13
- // to ensure its contents don't get bundled into the Lambda. Similarily,
14
- // we don't want to bundle anything from `.vercel` either. Lastly,
15
- // Builders/Runtimes didn't have `vercel.json` or `now.json`.
16
- const ignoredPaths = ['.output', '.vercel', 'vercel.json', 'now.json'];
17
- const shouldIgnorePath = (file, ignoreFilter, ignoreFile) => {
18
- const isNative = ignoredPaths.some(item => {
19
- return file.startsWith(item);
20
- });
21
- if (!ignoreFile) {
22
- return isNative;
23
- }
24
- return isNative || ignoreFilter(file);
25
- };
26
- const getSourceFiles = async (workPath, ignoreFilter) => {
27
- const list = await glob_1.default('**', {
28
- cwd: workPath,
29
- });
30
- // We're not passing this as an `ignore` filter to the `glob` function above,
31
- // so that we can re-use exactly the same `getIgnoreFilter` method that the
32
- // Build Step uses (literally the same code). Note that this exclusion only applies
33
- // when deploying. Locally, another exclusion is needed, which is handled
34
- // further below in the `convertRuntimeToPlugin` function.
35
- for (const file in list) {
36
- if (shouldIgnorePath(file, ignoreFilter, true)) {
37
- delete list[file];
38
- }
39
- }
40
- return list;
41
- };
42
- /**
43
- * Convert legacy Runtime to a Plugin.
44
- * @param buildRuntime - a legacy build() function from a Runtime
45
- * @param packageName - the name of the package, for example `vercel-plugin-python`
46
- * @param ext - the file extension, for example `.py`
47
- */
48
- function _experimental_convertRuntimeToPlugin(buildRuntime, packageName, ext) {
49
- // This `build()` signature should match `plugin.build()` signature in `vercel build`.
50
- return async function build({ workPath }) {
51
- // We also don't want to provide any files to Runtimes that were ignored
52
- // through `.vercelignore` or `.nowignore`, because the Build Step does the same.
53
- const ignoreFilter = await _1.getIgnoreFilter(workPath);
54
- // Retrieve the files that are currently available on the File System,
55
- // before the Legacy Runtime has even started to build.
56
- const sourceFilesPreBuild = await getSourceFiles(workPath, ignoreFilter);
57
- // Instead of doing another `glob` to get all the matching source files,
58
- // we'll filter the list of existing files down to only the ones
59
- // that are matching the entrypoint pattern, so we're first creating
60
- // a clean new list to begin.
61
- const entrypoints = Object.assign({}, sourceFilesPreBuild);
62
- const entrypointMatch = new RegExp(`^api/.*${ext}$`);
63
- // Up next, we'll strip out the files from the list of entrypoints
64
- // that aren't actually considered entrypoints.
65
- for (const file in entrypoints) {
66
- if (!entrypointMatch.test(file)) {
67
- delete entrypoints[file];
68
- }
69
- }
70
- const pages = {};
71
- const pluginName = packageName.replace('vercel-plugin-', '');
72
- const outputPath = path_1.join(workPath, '.output');
73
- const traceDir = path_1.join(outputPath, `inputs`,
74
- // Legacy Runtimes can only provide API Routes, so that's
75
- // why we can use this prefix for all of them. Here, we have to
76
- // make sure to not use a cryptic hash name, because people
77
- // need to be able to easily inspect the output.
78
- `api-routes-${pluginName}`);
79
- await fs_extra_1.default.ensureDir(traceDir);
80
- const entryRoot = path_1.join(outputPath, 'server', 'pages');
81
- for (const entrypoint of Object.keys(entrypoints)) {
82
- const { output } = await buildRuntime({
83
- files: sourceFilesPreBuild,
84
- entrypoint,
85
- workPath,
86
- config: {
87
- zeroConfig: true,
88
- },
89
- meta: {
90
- avoidTopLevelInstall: true,
91
- skipDownload: true,
92
- },
93
- });
94
- const lambdaFiles = output.files;
95
- // When deploying, the `files` that are passed to the Legacy Runtimes already
96
- // have certain files that are ignored stripped, but locally, that list of
97
- // files isn't used by the Legacy Runtimes, so we need to apply the filters
98
- // to the outputs that they are returning instead.
99
- for (const file in lambdaFiles) {
100
- if (shouldIgnorePath(file, ignoreFilter, false)) {
101
- delete lambdaFiles[file];
102
- }
103
- }
104
- let handlerFileBase = output.handler;
105
- let handlerFile = lambdaFiles[handlerFileBase];
106
- let handlerHasImport = false;
107
- const { handler } = output;
108
- const handlerMethod = handler.split('.').pop();
109
- const handlerFileName = handler.replace(`.${handlerMethod}`, '');
110
- // For compiled languages, the launcher file for the Lambda generated
111
- // by the Legacy Runtime matches the `handler` defined for it, but for
112
- // interpreted languages, the `handler` consists of the launcher file name
113
- // without an extension, plus the name of the method inside of that file
114
- // that should be invoked, so we have to construct the file path explicitly.
115
- if (!handlerFile) {
116
- handlerFileBase = handlerFileName + ext;
117
- handlerFile = lambdaFiles[handlerFileBase];
118
- handlerHasImport = true;
119
- }
120
- if (!handlerFile || !handlerFile.fsPath) {
121
- throw new Error(`Could not find a handler file. Please ensure that \`files\` for the returned \`Lambda\` contains an \`FileFsRef\` named "${handlerFileBase}" with a valid \`fsPath\`.`);
122
- }
123
- const handlerExtName = path_1.extname(handlerFile.fsPath);
124
- const entryBase = path_1.basename(entrypoint).replace(ext, handlerExtName);
125
- const entryPath = path_1.join(path_1.dirname(entrypoint), entryBase);
126
- const entry = path_1.join(entryRoot, entryPath);
127
- // Create the parent directory of the API Route that will be created
128
- // for the current entrypoint inside of `.output/server/pages/api`.
129
- await fs_extra_1.default.ensureDir(path_1.dirname(entry));
130
- // For compiled languages, the launcher file will be binary and therefore
131
- // won't try to import a user-provided request handler (instead, it will
132
- // contain it). But for interpreted languages, the launcher might try to
133
- // load a user-provided request handler from the source file instead of bundling
134
- // it, so we have to adjust the import statement inside the launcher to point
135
- // to the respective source file. Previously, Legacy Runtimes simply expected
136
- // the user-provided request-handler to be copied right next to the launcher,
137
- // but with the new File System API, files won't be moved around unnecessarily.
138
- if (handlerHasImport) {
139
- const { fsPath } = handlerFile;
140
- const encoding = 'utf-8';
141
- // This is the true directory of the user-provided request handler in the
142
- // source files, so that's what we will use as an import path in the launcher.
143
- const locationPrefix = path_1.relative(entry, outputPath);
144
- let handlerContent = await fs_extra_1.default.readFile(fsPath, encoding);
145
- const importPaths = [
146
- // This is the full entrypoint path, like `./api/test.py`. In our tests
147
- // Python didn't support importing from a parent directory without using different
148
- // code in the launcher that registers it as a location for modules and then changing
149
- // the importing syntax, but continuing to import it like before seems to work. If
150
- // other languages need this, we should consider excluding Python explicitly.
151
- // `./${entrypoint}`,
152
- // This is the entrypoint path without extension, like `api/test`
153
- entrypoint.slice(0, -ext.length),
154
- ];
155
- // Generate a list of regular expressions that we can use for
156
- // finding matches, but only allow matches if the import path is
157
- // wrapped inside single (') or double quotes (").
158
- const patterns = importPaths.map(path => {
159
- // eslint-disable-next-line no-useless-escape
160
- return new RegExp(`('|")(${path.replace(/\./g, '\\.')})('|")`, 'g');
161
- });
162
- let replacedMatch = null;
163
- for (const pattern of patterns) {
164
- const newContent = handlerContent.replace(pattern, (_, p1, p2, p3) => {
165
- return `${p1}${path_1.join(locationPrefix, p2)}${p3}`;
166
- });
167
- if (newContent !== handlerContent) {
168
- _1.debug(`Replaced "${pattern}" inside "${entry}" to ensure correct import of user-provided request handler`);
169
- handlerContent = newContent;
170
- replacedMatch = true;
171
- }
172
- }
173
- if (!replacedMatch) {
174
- new Error(`No replacable matches for "${importPaths[0]}" or "${importPaths[1]}" found in "${fsPath}"`);
175
- }
176
- await fs_extra_1.default.writeFile(entry, handlerContent, encoding);
177
- }
178
- else {
179
- await fs_extra_1.default.copy(handlerFile.fsPath, entry);
180
- }
181
- // Legacy Runtimes based on interpreted languages will create a new launcher file
182
- // for every entrypoint, but they will create each one inside `workPath`, which means that
183
- // the launcher for one entrypoint will overwrite the launcher provided for the previous
184
- // entrypoint. That's why, above, we copy the file contents into the new destination (and
185
- // optionally transform them along the way), instead of linking. We then also want to remove
186
- // the copy origin right here, so that the `workPath` doesn't contain a useless launcher file
187
- // once the build has finished running.
188
- await fs_extra_1.default.remove(handlerFile.fsPath);
189
- _1.debug(`Removed temporary file "${handlerFile.fsPath}"`);
190
- const nft = `${entry}.nft.json`;
191
- const json = JSON.stringify({
192
- version: 2,
193
- files: Object.keys(lambdaFiles)
194
- .map(file => {
195
- const { fsPath } = lambdaFiles[file];
196
- if (!fsPath) {
197
- throw new Error(`File "${file}" is missing valid \`fsPath\` property`);
198
- }
199
- // The handler was already moved into position above.
200
- if (file === handlerFileBase) {
201
- return;
202
- }
203
- return normalize_path_1.normalizePath(path_1.relative(path_1.dirname(nft), fsPath));
204
- })
205
- .filter(Boolean),
206
- });
207
- await fs_extra_1.default.writeFile(nft, json);
208
- // Add an entry that will later on be added to the `functions-manifest.json`
209
- // file that is placed inside of the `.output` directory.
210
- pages[normalize_path_1.normalizePath(entryPath)] = {
211
- // Because the underlying file used as a handler was placed
212
- // inside `.output/server/pages/api`, it no longer has the name it originally
213
- // had and is now named after the API Route that it's responsible for,
214
- // so we have to adjust the name of the Lambda handler accordingly.
215
- handler: handler.replace(handlerFileName, path_1.parse(entry).name),
216
- runtime: output.runtime,
217
- memory: output.memory,
218
- maxDuration: output.maxDuration,
219
- environment: output.environment,
220
- allowQuery: output.allowQuery,
221
- };
222
- }
223
- // Add any Serverless Functions that were exposed by the Legacy Runtime
224
- // to the `functions-manifest.json` file provided in `.output`.
225
- await _experimental_updateFunctionsManifest({ workPath, pages });
226
- };
227
- }
228
- exports._experimental_convertRuntimeToPlugin = _experimental_convertRuntimeToPlugin;
229
- async function readJson(filePath) {
230
- try {
231
- const str = await fs_extra_1.default.readFile(filePath, 'utf8');
232
- return JSON.parse(str);
233
- }
234
- catch (err) {
235
- if (err.code === 'ENOENT') {
236
- return {};
237
- }
238
- throw err;
239
- }
240
- }
241
- /**
242
- * If `.output/functions-manifest.json` exists, append to the pages
243
- * property. Otherwise write a new file.
244
- */
245
- async function _experimental_updateFunctionsManifest({ workPath, pages, }) {
246
- const functionsManifestPath = path_1.join(workPath, '.output', 'functions-manifest.json');
247
- const functionsManifest = await readJson(functionsManifestPath);
248
- if (!functionsManifest.version)
249
- functionsManifest.version = 2;
250
- if (!functionsManifest.pages)
251
- functionsManifest.pages = {};
252
- for (const [pageKey, pageConfig] of Object.entries(pages)) {
253
- functionsManifest.pages[pageKey] = { ...pageConfig };
254
- }
255
- await fs_extra_1.default.writeFile(functionsManifestPath, JSON.stringify(functionsManifest));
256
- }
257
- exports._experimental_updateFunctionsManifest = _experimental_updateFunctionsManifest;
258
- /**
259
- * Append routes to the `routes-manifest.json` file.
260
- * If the file does not exist, it will be created.
261
- */
262
- async function _experimental_updateRoutesManifest({ workPath, redirects, rewrites, headers, dynamicRoutes, staticRoutes, }) {
263
- const routesManifestPath = path_1.join(workPath, '.output', 'routes-manifest.json');
264
- const routesManifest = await readJson(routesManifestPath);
265
- if (!routesManifest.version)
266
- routesManifest.version = 3;
267
- if (routesManifest.pages404 === undefined)
268
- routesManifest.pages404 = true;
269
- if (redirects) {
270
- if (!routesManifest.redirects)
271
- routesManifest.redirects = [];
272
- routesManifest.redirects.push(...redirects);
273
- }
274
- if (rewrites) {
275
- if (!routesManifest.rewrites)
276
- routesManifest.rewrites = [];
277
- routesManifest.rewrites.push(...rewrites);
278
- }
279
- if (headers) {
280
- if (!routesManifest.headers)
281
- routesManifest.headers = [];
282
- routesManifest.headers.push(...headers);
283
- }
284
- if (dynamicRoutes) {
285
- if (!routesManifest.dynamicRoutes)
286
- routesManifest.dynamicRoutes = [];
287
- routesManifest.dynamicRoutes.push(...dynamicRoutes);
288
- }
289
- if (staticRoutes) {
290
- if (!routesManifest.staticRoutes)
291
- routesManifest.staticRoutes = [];
292
- routesManifest.staticRoutes.push(...staticRoutes);
293
- }
294
- await fs_extra_1.default.writeFile(routesManifestPath, JSON.stringify(routesManifest));
295
- }
296
- exports._experimental_updateRoutesManifest = _experimental_updateRoutesManifest;