@vercel/redwood 2.0.1 → 2.0.3

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 (2) hide show
  1. package/dist/index.js +236 -216
  2. package/package.json +4 -4
package/dist/index.js CHANGED
@@ -1,231 +1,251 @@
1
1
  "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.prepareCache = exports.build = exports.version = void 0;
4
- const path_1 = require("path");
5
- const fs_1 = require("fs");
6
- const semver_1 = require("semver");
7
- const build_utils_1 = require("@vercel/build-utils");
8
- const nft_1 = require("@vercel/nft");
9
- const routing_utils_1 = require("@vercel/routing-utils");
10
- // Do not change this version for RW specific config,
11
- // it refers to Vercels builder version
12
- exports.version = 2;
13
- const build = async ({ workPath, files, entrypoint, meta = {}, config = {}, }) => {
14
- await (0, build_utils_1.download)(files, workPath, meta);
15
- const prefixedEnvs = (0, build_utils_1.getPrefixedEnvVars)({
16
- envPrefix: 'REDWOOD_ENV_',
17
- envs: process.env,
18
- });
19
- for (const [key, value] of Object.entries(prefixedEnvs)) {
20
- process.env[key] = value;
21
- }
22
- const { installCommand, buildCommand } = config;
23
- const mountpoint = (0, path_1.dirname)(entrypoint);
24
- const entrypointFsDirname = (0, path_1.join)(workPath, mountpoint);
25
- const nodeVersion = await (0, build_utils_1.getNodeVersion)(entrypointFsDirname, undefined, config, meta);
26
- const spawnOpts = (0, build_utils_1.getSpawnOptions)(meta, nodeVersion);
27
- if (!spawnOpts.env) {
28
- spawnOpts.env = {};
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var src_exports = {};
22
+ __export(src_exports, {
23
+ build: () => build,
24
+ prepareCache: () => prepareCache,
25
+ version: () => version
26
+ });
27
+ module.exports = __toCommonJS(src_exports);
28
+ var import_path = require("path");
29
+ var import_fs = require("fs");
30
+ var import_semver = require("semver");
31
+ var import_build_utils = require("@vercel/build-utils");
32
+ var import_nft = require("@vercel/nft");
33
+ var import_routing_utils = require("@vercel/routing-utils");
34
+ var version = 2;
35
+ var build = async ({
36
+ workPath,
37
+ files,
38
+ entrypoint,
39
+ meta = {},
40
+ config = {}
41
+ }) => {
42
+ await (0, import_build_utils.download)(files, workPath, meta);
43
+ const prefixedEnvs = (0, import_build_utils.getPrefixedEnvVars)({
44
+ envPrefix: "REDWOOD_ENV_",
45
+ envs: process.env
46
+ });
47
+ for (const [key, value] of Object.entries(prefixedEnvs)) {
48
+ process.env[key] = value;
49
+ }
50
+ const { installCommand, buildCommand } = config;
51
+ const mountpoint = (0, import_path.dirname)(entrypoint);
52
+ const entrypointFsDirname = (0, import_path.join)(workPath, mountpoint);
53
+ const nodeVersion = await (0, import_build_utils.getNodeVersion)(
54
+ entrypointFsDirname,
55
+ void 0,
56
+ config,
57
+ meta
58
+ );
59
+ const spawnOpts = (0, import_build_utils.getSpawnOptions)(meta, nodeVersion);
60
+ if (!spawnOpts.env) {
61
+ spawnOpts.env = {};
62
+ }
63
+ const { cliType, lockfileVersion } = await (0, import_build_utils.scanParentDirs)(
64
+ entrypointFsDirname
65
+ );
66
+ spawnOpts.env = (0, import_build_utils.getEnvForPackageManager)({
67
+ cliType,
68
+ lockfileVersion,
69
+ nodeVersion,
70
+ env: spawnOpts.env || {}
71
+ });
72
+ if (typeof installCommand === "string") {
73
+ if (installCommand.trim()) {
74
+ console.log(`Running "install" command: \`${installCommand}\`...`);
75
+ await (0, import_build_utils.execCommand)(installCommand, {
76
+ ...spawnOpts,
77
+ cwd: entrypointFsDirname
78
+ });
79
+ } else {
80
+ console.log(`Skipping "install" command...`);
29
81
  }
30
- const { cliType, lockfileVersion } = await (0, build_utils_1.scanParentDirs)(entrypointFsDirname);
31
- spawnOpts.env = (0, build_utils_1.getEnvForPackageManager)({
32
- cliType,
33
- lockfileVersion,
34
- nodeVersion,
35
- env: spawnOpts.env || {},
82
+ } else {
83
+ await (0, import_build_utils.runNpmInstall)(entrypointFsDirname, [], spawnOpts, meta, nodeVersion);
84
+ }
85
+ if (meta.isDev) {
86
+ throw new Error("Detected `@vercel/redwood` dev but this is not supported");
87
+ }
88
+ const pkg = await (0, import_build_utils.readConfigFile)((0, import_path.join)(workPath, "package.json"));
89
+ const toml = await (0, import_build_utils.readConfigFile)(
90
+ (0, import_path.join)(workPath, "redwood.toml")
91
+ );
92
+ if (buildCommand) {
93
+ (0, import_build_utils.debug)(`Executing build command "${buildCommand}"`);
94
+ await (0, import_build_utils.execCommand)(buildCommand, {
95
+ ...spawnOpts,
96
+ cwd: workPath
36
97
  });
37
- if (typeof installCommand === 'string') {
38
- if (installCommand.trim()) {
39
- console.log(`Running "install" command: \`${installCommand}\`...`);
40
- await (0, build_utils_1.execCommand)(installCommand, {
41
- ...spawnOpts,
42
- cwd: entrypointFsDirname,
43
- });
44
- }
45
- else {
46
- console.log(`Skipping "install" command...`);
47
- }
48
- }
49
- else {
50
- await (0, build_utils_1.runNpmInstall)(entrypointFsDirname, [], spawnOpts, meta, nodeVersion);
51
- }
52
- if (meta.isDev) {
53
- throw new Error('Detected `@vercel/redwood` dev but this is not supported');
54
- }
55
- const pkg = await (0, build_utils_1.readConfigFile)((0, path_1.join)(workPath, 'package.json'));
56
- const toml = await (0, build_utils_1.readConfigFile)((0, path_1.join)(workPath, 'redwood.toml'));
57
- if (buildCommand) {
58
- (0, build_utils_1.debug)(`Executing build command "${buildCommand}"`);
59
- await (0, build_utils_1.execCommand)(buildCommand, {
60
- ...spawnOpts,
61
- cwd: workPath,
62
- });
63
- }
64
- else if (hasScript('vercel-build', pkg)) {
65
- (0, build_utils_1.debug)(`Executing "yarn vercel-build"`);
66
- await (0, build_utils_1.runPackageJsonScript)(workPath, 'vercel-build', spawnOpts);
98
+ } else if (hasScript("vercel-build", pkg)) {
99
+ (0, import_build_utils.debug)(`Executing "yarn vercel-build"`);
100
+ await (0, import_build_utils.runPackageJsonScript)(workPath, "vercel-build", spawnOpts);
101
+ } else if (hasScript("build", pkg)) {
102
+ (0, import_build_utils.debug)(`Executing "yarn build"`);
103
+ await (0, import_build_utils.runPackageJsonScript)(workPath, "build", spawnOpts);
104
+ } else {
105
+ const { devDependencies = {} } = pkg || {};
106
+ const versionRange = devDependencies["@redwoodjs/core"];
107
+ let cmd;
108
+ if (!versionRange || !(0, import_semver.validRange)(versionRange)) {
109
+ console.log(
110
+ "WARNING: Unable to detect RedwoodJS version in package.json devDependencies"
111
+ );
112
+ cmd = "yarn rw deploy vercel";
113
+ } else if ((0, import_semver.intersects)(versionRange, "<0.25.0")) {
114
+ cmd = "yarn rw build && yarn rw db up --no-db-client --auto-approve && yarn rw dataMigrate up";
115
+ } else {
116
+ cmd = "yarn rw deploy vercel";
67
117
  }
68
- else if (hasScript('build', pkg)) {
69
- (0, build_utils_1.debug)(`Executing "yarn build"`);
70
- await (0, build_utils_1.runPackageJsonScript)(workPath, 'build', spawnOpts);
71
- }
72
- else {
73
- const { devDependencies = {} } = pkg || {};
74
- const versionRange = devDependencies['@redwoodjs/core'];
75
- let cmd;
76
- if (!versionRange || !(0, semver_1.validRange)(versionRange)) {
77
- console.log('WARNING: Unable to detect RedwoodJS version in package.json devDependencies');
78
- cmd = 'yarn rw deploy vercel'; // Assume 0.25.0 and newer
79
- }
80
- else if ((0, semver_1.intersects)(versionRange, '<0.25.0')) {
81
- // older than 0.25.0
82
- cmd =
83
- 'yarn rw build && yarn rw db up --no-db-client --auto-approve && yarn rw dataMigrate up';
84
- }
85
- else {
86
- // 0.25.0 and newer
87
- cmd = 'yarn rw deploy vercel';
88
- }
89
- await (0, build_utils_1.execCommand)(cmd, {
90
- ...spawnOpts,
91
- cwd: workPath,
92
- });
118
+ await (0, import_build_utils.execCommand)(cmd, {
119
+ ...spawnOpts,
120
+ cwd: workPath
121
+ });
122
+ }
123
+ const apiDir = toml?.web?.apiProxyPath?.replace(/^\//, "") ?? "api";
124
+ const apiDistPath = (0, import_path.join)(workPath, "api", "dist", "functions");
125
+ const webDistPath = (0, import_path.join)(workPath, "web", "dist");
126
+ const lambdaOutputs = {};
127
+ const webDistFiles = await (0, import_build_utils.glob)("**", webDistPath);
128
+ const staticOutputs = {};
129
+ for (const [fileName, fileFsRef] of Object.entries(webDistFiles)) {
130
+ const parsedPath = (0, import_path.parse)(fileFsRef.fsPath);
131
+ if (parsedPath.ext !== ".html") {
132
+ staticOutputs[fileName] = fileFsRef;
133
+ } else {
134
+ const fileNameWithoutExtension = (0, import_path.basename)(fileName, ".html");
135
+ const pathWithoutHtmlExtension = (0, import_path.join)(
136
+ parsedPath.dir,
137
+ fileNameWithoutExtension
138
+ );
139
+ fileFsRef.contentType = "text/html; charset=utf-8";
140
+ staticOutputs[(0, import_path.relative)(webDistPath, pathWithoutHtmlExtension)] = fileFsRef;
93
141
  }
94
- const apiDir = toml?.web?.apiProxyPath?.replace(/^\//, '') ?? 'api';
95
- const apiDistPath = (0, path_1.join)(workPath, 'api', 'dist', 'functions');
96
- const webDistPath = (0, path_1.join)(workPath, 'web', 'dist');
97
- const lambdaOutputs = {};
98
- // Strip out the .html extensions
99
- // And populate staticOutputs map with updated paths and contentType
100
- const webDistFiles = await (0, build_utils_1.glob)('**', webDistPath);
101
- const staticOutputs = {};
102
- for (const [fileName, fileFsRef] of Object.entries(webDistFiles)) {
103
- const parsedPath = (0, path_1.parse)(fileFsRef.fsPath);
104
- if (parsedPath.ext !== '.html') {
105
- // No need to transform non-html files
106
- staticOutputs[fileName] = fileFsRef;
107
- }
108
- else {
109
- const fileNameWithoutExtension = (0, path_1.basename)(fileName, '.html');
110
- const pathWithoutHtmlExtension = (0, path_1.join)(parsedPath.dir, fileNameWithoutExtension);
111
- fileFsRef.contentType = 'text/html; charset=utf-8';
112
- // @NOTE: Filename is relative to webDistPath
113
- // e.g. {'./200': fsRef}
114
- staticOutputs[(0, path_1.relative)(webDistPath, pathWithoutHtmlExtension)] =
115
- fileFsRef;
142
+ }
143
+ const functionFiles = {
144
+ ...await (0, import_build_utils.glob)("*.js", apiDistPath),
145
+ // top-level
146
+ ...await (0, import_build_utils.glob)("*/*.js", apiDistPath)
147
+ // one-level deep
148
+ };
149
+ const sourceCache = /* @__PURE__ */ new Map();
150
+ const fsCache = /* @__PURE__ */ new Map();
151
+ for (const [funcName, fileFsRef] of Object.entries(functionFiles)) {
152
+ const outputName = (0, import_path.join)(apiDir, (0, import_path.parse)(funcName).name);
153
+ const absEntrypoint = fileFsRef.fsPath;
154
+ const relativeEntrypoint = (0, import_path.relative)(workPath, absEntrypoint);
155
+ const awsLambdaHandler = getAWSLambdaHandler(relativeEntrypoint, "handler");
156
+ const sourceFile = relativeEntrypoint.replace("/dist/", "/src/");
157
+ const { fileList, esmFileList, warnings } = await (0, import_nft.nodeFileTrace)(
158
+ [absEntrypoint],
159
+ {
160
+ base: workPath,
161
+ processCwd: workPath,
162
+ ts: true,
163
+ mixedModules: true,
164
+ ignore: config.excludeFiles,
165
+ async readFile(fsPath) {
166
+ const relPath = (0, import_path.relative)(workPath, fsPath);
167
+ const cached = sourceCache.get(relPath);
168
+ if (cached)
169
+ return cached.toString();
170
+ if (cached === null)
171
+ return null;
172
+ try {
173
+ const source = (0, import_fs.readFileSync)(fsPath);
174
+ const { mode } = (0, import_fs.lstatSync)(fsPath);
175
+ let entry;
176
+ if ((0, import_build_utils.isSymbolicLink)(mode)) {
177
+ entry = new import_build_utils.FileFsRef({ fsPath, mode });
178
+ } else {
179
+ entry = new import_build_utils.FileBlob({ data: source, mode });
180
+ }
181
+ fsCache.set(relPath, entry);
182
+ sourceCache.set(relPath, source);
183
+ return source.toString();
184
+ } catch (e) {
185
+ if (e.code === "ENOENT" || e.code === "EISDIR") {
186
+ sourceCache.set(relPath, null);
187
+ return null;
188
+ }
189
+ throw e;
190
+ }
116
191
  }
192
+ }
193
+ );
194
+ for (const warning of warnings) {
195
+ (0, import_build_utils.debug)(`Warning from trace: ${warning.message}`);
117
196
  }
118
- // Each file in the `functions` dir will become a lambda
119
- // Also supports nested functions like:
120
- // ├── functions
121
- // │ ├── bazinga
122
- // │ │ ├── bazinga.js
123
- // │ ├── graphql.js
124
- const functionFiles = {
125
- ...(await (0, build_utils_1.glob)('*.js', apiDistPath)),
126
- ...(await (0, build_utils_1.glob)('*/*.js', apiDistPath)), // one-level deep
127
- };
128
- const sourceCache = new Map();
129
- const fsCache = new Map();
130
- for (const [funcName, fileFsRef] of Object.entries(functionFiles)) {
131
- const outputName = (0, path_1.join)(apiDir, (0, path_1.parse)(funcName).name); // remove `.js` extension
132
- const absEntrypoint = fileFsRef.fsPath;
133
- const relativeEntrypoint = (0, path_1.relative)(workPath, absEntrypoint);
134
- const awsLambdaHandler = getAWSLambdaHandler(relativeEntrypoint, 'handler');
135
- const sourceFile = relativeEntrypoint.replace('/dist/', '/src/');
136
- const { fileList, esmFileList, warnings } = await (0, nft_1.nodeFileTrace)([absEntrypoint], {
137
- base: workPath,
138
- processCwd: workPath,
139
- ts: true,
140
- mixedModules: true,
141
- ignore: config.excludeFiles,
142
- async readFile(fsPath) {
143
- const relPath = (0, path_1.relative)(workPath, fsPath);
144
- const cached = sourceCache.get(relPath);
145
- if (cached)
146
- return cached.toString();
147
- // null represents a not found
148
- if (cached === null)
149
- return null;
150
- try {
151
- const source = (0, fs_1.readFileSync)(fsPath);
152
- const { mode } = (0, fs_1.lstatSync)(fsPath);
153
- let entry;
154
- if ((0, build_utils_1.isSymbolicLink)(mode)) {
155
- entry = new build_utils_1.FileFsRef({ fsPath, mode });
156
- }
157
- else {
158
- entry = new build_utils_1.FileBlob({ data: source, mode });
159
- }
160
- fsCache.set(relPath, entry);
161
- sourceCache.set(relPath, source);
162
- return source.toString();
163
- }
164
- catch (e) {
165
- if (e.code === 'ENOENT' || e.code === 'EISDIR') {
166
- sourceCache.set(relPath, null);
167
- return null;
168
- }
169
- throw e;
170
- }
171
- },
172
- });
173
- for (const warning of warnings) {
174
- (0, build_utils_1.debug)(`Warning from trace: ${warning.message}`);
175
- }
176
- const lambdaFiles = {};
177
- const allFiles = [...fileList, ...esmFileList];
178
- for (const filePath of allFiles) {
179
- lambdaFiles[filePath] = await build_utils_1.FileFsRef.fromFsPath({
180
- fsPath: (0, path_1.join)(workPath, filePath),
181
- });
182
- }
183
- lambdaFiles[(0, path_1.relative)(workPath, fileFsRef.fsPath)] = fileFsRef;
184
- const lambdaOptions = await (0, build_utils_1.getLambdaOptionsFromFunction)({
185
- sourceFile,
186
- config,
187
- });
188
- const lambda = new build_utils_1.NodejsLambda({
189
- files: lambdaFiles,
190
- handler: relativeEntrypoint,
191
- runtime: nodeVersion.runtime,
192
- shouldAddHelpers: false,
193
- shouldAddSourcemapSupport: false,
194
- awsLambdaHandler,
195
- ...lambdaOptions,
196
- });
197
- lambdaOutputs[outputName] = lambda;
197
+ const lambdaFiles = {};
198
+ const allFiles = [...fileList, ...esmFileList];
199
+ for (const filePath of allFiles) {
200
+ lambdaFiles[filePath] = await import_build_utils.FileFsRef.fromFsPath({
201
+ fsPath: (0, import_path.join)(workPath, filePath)
202
+ });
198
203
  }
199
- // Older versions of redwood did not create 200.html automatically
200
- // From v0.50.0+ 200.html is always generated as part of web build
201
- // Note that in builder post-processing, we remove the .html extension
202
- const fallbackHtmlPage = (0, fs_1.existsSync)((0, path_1.join)(webDistPath, '200.html'))
203
- ? '/200'
204
- : '/index';
205
- const defaultRoutesConfig = (0, routing_utils_1.getTransformedRoutes)({
206
- // this makes sure we send back 200.html for unprerendered pages
207
- rewrites: [{ source: '/(.*)', destination: fallbackHtmlPage }],
208
- cleanUrls: true,
209
- trailingSlash: false,
204
+ lambdaFiles[(0, import_path.relative)(workPath, fileFsRef.fsPath)] = fileFsRef;
205
+ const lambdaOptions = await (0, import_build_utils.getLambdaOptionsFromFunction)({
206
+ sourceFile,
207
+ config
210
208
  });
211
- if (defaultRoutesConfig.error) {
212
- throw new Error(defaultRoutesConfig.error.message);
213
- }
214
- return {
215
- output: { ...staticOutputs, ...lambdaOutputs },
216
- routes: defaultRoutesConfig.routes,
217
- };
209
+ const lambda = new import_build_utils.NodejsLambda({
210
+ files: lambdaFiles,
211
+ handler: relativeEntrypoint,
212
+ runtime: nodeVersion.runtime,
213
+ shouldAddHelpers: false,
214
+ shouldAddSourcemapSupport: false,
215
+ awsLambdaHandler,
216
+ ...lambdaOptions
217
+ });
218
+ lambdaOutputs[outputName] = lambda;
219
+ }
220
+ const fallbackHtmlPage = (0, import_fs.existsSync)((0, import_path.join)(webDistPath, "200.html")) ? "/200" : "/index";
221
+ const defaultRoutesConfig = (0, import_routing_utils.getTransformedRoutes)({
222
+ // this makes sure we send back 200.html for unprerendered pages
223
+ rewrites: [{ source: "/(.*)", destination: fallbackHtmlPage }],
224
+ cleanUrls: true,
225
+ trailingSlash: false
226
+ });
227
+ if (defaultRoutesConfig.error) {
228
+ throw new Error(defaultRoutesConfig.error.message);
229
+ }
230
+ return {
231
+ output: { ...staticOutputs, ...lambdaOutputs },
232
+ routes: defaultRoutesConfig.routes
233
+ };
218
234
  };
219
- exports.build = build;
220
235
  function getAWSLambdaHandler(filePath, handlerName) {
221
- const { dir, name } = (0, path_1.parse)(filePath);
222
- return `${dir}${dir ? path_1.sep : ''}${name}.${handlerName}`;
236
+ const { dir, name } = (0, import_path.parse)(filePath);
237
+ return `${dir}${dir ? import_path.sep : ""}${name}.${handlerName}`;
223
238
  }
224
239
  function hasScript(scriptName, pkg) {
225
- const scripts = (pkg && pkg.scripts) || {};
226
- return typeof scripts[scriptName] === 'string';
240
+ const scripts = pkg && pkg.scripts || {};
241
+ return typeof scripts[scriptName] === "string";
227
242
  }
228
- const prepareCache = ({ repoRootPath, workPath }) => {
229
- return (0, build_utils_1.glob)('**/node_modules/**', repoRootPath || workPath);
243
+ var prepareCache = ({ repoRootPath, workPath }) => {
244
+ return (0, import_build_utils.glob)("**/node_modules/**", repoRootPath || workPath);
230
245
  };
231
- exports.prepareCache = prepareCache;
246
+ // Annotate the CommonJS export names for ESM import in node:
247
+ 0 && (module.exports = {
248
+ build,
249
+ prepareCache,
250
+ version
251
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vercel/redwood",
3
- "version": "2.0.1",
3
+ "version": "2.0.3",
4
4
  "main": "./dist/index.js",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://vercel.com/docs",
@@ -13,7 +13,7 @@
13
13
  "directory": "packages/redwood"
14
14
  },
15
15
  "dependencies": {
16
- "@vercel/nft": "0.22.5",
16
+ "@vercel/nft": "0.24.1",
17
17
  "@vercel/routing-utils": "3.0.0",
18
18
  "semver": "6.3.1"
19
19
  },
@@ -21,13 +21,13 @@
21
21
  "@types/aws-lambda": "8.10.19",
22
22
  "@types/node": "14.18.33",
23
23
  "@types/semver": "6.0.0",
24
- "@vercel/build-utils": "7.1.1",
24
+ "@vercel/build-utils": "7.2.1",
25
25
  "execa": "3.2.0",
26
26
  "fs-extra": "11.1.0",
27
27
  "jest-junit": "16.0.0"
28
28
  },
29
29
  "scripts": {
30
- "build": "node build.js",
30
+ "build": "node ../../utils/build-builder.mjs",
31
31
  "test-e2e": "pnpm test test/test.js",
32
32
  "test": "jest --reporters=default --reporters=jest-junit --env node --verbose --bail --runInBand",
33
33
  "test-unit": "pnpm test test/prepare-cache.test.js"