mirror of
https://github.com/LukeHagar/vercel.git
synced 2025-12-11 04:22:13 +00:00
Compare commits
64 Commits
@now/pytho
...
@now/pytho
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9a93713158 | ||
|
|
3392ef5636 | ||
|
|
9236e2b584 | ||
|
|
ffc4686ab9 | ||
|
|
1ff4b6bb4b | ||
|
|
0e7d8c3ff1 | ||
|
|
86885b8c38 | ||
|
|
8563f2b8b5 | ||
|
|
c36938bd95 | ||
|
|
957ab6c4e3 | ||
|
|
069e9b4052 | ||
|
|
0b06704be6 | ||
|
|
cf5a49e699 | ||
|
|
b671b23d8d | ||
|
|
fa44c23225 | ||
|
|
ba9da3cec5 | ||
|
|
0909aaf2b3 | ||
|
|
e276342a6f | ||
|
|
f6e1bdf0a1 | ||
|
|
2c2189b661 | ||
|
|
61522e2bc7 | ||
|
|
a20f3a5920 | ||
|
|
a5e58c2a8d | ||
|
|
a58451548f | ||
|
|
8e846c50b5 | ||
|
|
7613dcf68b | ||
|
|
bea499cad3 | ||
|
|
0f20a0dbbf | ||
|
|
1ea30588a3 | ||
|
|
a3b670675a | ||
|
|
c4374fe5a8 | ||
|
|
c3983ba1c2 | ||
|
|
ae1be4b243 | ||
|
|
b4b1131619 | ||
|
|
5fd923a7e7 | ||
|
|
f4e95eb59c | ||
|
|
a6cdaccd34 | ||
|
|
4f5fe8eba8 | ||
|
|
7239013989 | ||
|
|
75000ee334 | ||
|
|
5319610d59 | ||
|
|
6df0d69afa | ||
|
|
65b191f6b9 | ||
|
|
115f62bbba | ||
|
|
cdf6a98a18 | ||
|
|
bb75dfd993 | ||
|
|
b63062cfc5 | ||
|
|
5ad6dabd96 | ||
|
|
30060bee07 | ||
|
|
dd48a1c6d3 | ||
|
|
24d45736f1 | ||
|
|
d839fdbe81 | ||
|
|
cfdcd2f8d0 | ||
|
|
b3cac2b372 | ||
|
|
9d27d69656 | ||
|
|
04197b250c | ||
|
|
ce6f43eae7 | ||
|
|
2cfafe4054 | ||
|
|
b195949881 | ||
|
|
b7c47fa587 | ||
|
|
f3bcefe822 | ||
|
|
7a481c9515 | ||
|
|
af275c60bf | ||
|
|
ded377dfc2 |
@@ -4,6 +4,8 @@ jobs:
|
||||
docker:
|
||||
- image: circleci/node:10
|
||||
working_directory: ~/repo
|
||||
environment:
|
||||
GOPATH: $HOME/go
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
@@ -24,63 +26,17 @@ jobs:
|
||||
- run:
|
||||
name: Tests
|
||||
command: yarn test
|
||||
# publish-canary:
|
||||
# docker:
|
||||
# - image: circleci/node:10
|
||||
# working_directory: ~/repo
|
||||
# steps:
|
||||
# - checkout
|
||||
# - run:
|
||||
# name: Updating apt-get list
|
||||
# command: sudo apt-get update
|
||||
# - run:
|
||||
# name: Installing the latest version of Go
|
||||
# command: sudo apt-get install golang-go
|
||||
# - run: yarn install
|
||||
# - run: yarn bootstrap
|
||||
# - run:
|
||||
# name: Saving Authentication Information
|
||||
# command: echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" >> ~/.npmrc
|
||||
# - run:
|
||||
# name: Publishing to Canary Channel
|
||||
# command: yarn run lerna publish from-git --npm-tag canary --yes
|
||||
publish-stable:
|
||||
docker:
|
||||
- image: circleci/node:10
|
||||
working_directory: ~/repo
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
name: Updating apt-get list
|
||||
command: sudo apt-get update
|
||||
name: Potentially save npm token
|
||||
command: "([[ ! -z $NPM_TOKEN ]] && echo \"//registry.npmjs.org/:_authToken=$NPM_TOKEN\" >> ~/.npmrc) || echo \"Did not write npm token\""
|
||||
- run:
|
||||
name: Installing the latest version of Go
|
||||
command: sudo apt-get install golang-go
|
||||
- run: yarn install
|
||||
- run: yarn bootstrap
|
||||
name: Potentially publish canary release
|
||||
command: "if ls ~/.npmrc >/dev/null 2>&1 && [[ $(git describe --exact-match 2> /dev/null || :) =~ -canary ]]; then yarn run lerna publish from-git --npm-tag canary --yes; else echo \"Did not publish\"; fi"
|
||||
- run:
|
||||
name: Saving Authentication Information
|
||||
command: echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" >> ~/.npmrc
|
||||
- run:
|
||||
name: Publishing to Stable Channel
|
||||
command: yarn run lerna publish from-git --yes
|
||||
name: Potentially publish stable release
|
||||
command: "if ls ~/.npmrc >/dev/null 2>&1 && [[ ! $(git describe --exact-match 2> /dev/null || :) =~ -canary ]]; then yarn run lerna publish from-git --yes; else echo \"Did not publish\"; fi"
|
||||
workflows:
|
||||
version: 2
|
||||
unscheduled:
|
||||
build-and-deploy:
|
||||
jobs:
|
||||
- build:
|
||||
filters:
|
||||
tags:
|
||||
only: /.*/
|
||||
- publish-stable:
|
||||
requires:
|
||||
- build
|
||||
filters:
|
||||
tags:
|
||||
only: /^.*(\d+\.)(\d+\.)(\*|\d+)$/
|
||||
# - publish-canary:
|
||||
# requires:
|
||||
# - build
|
||||
# filters:
|
||||
# tags:
|
||||
# only: /^.*canary.*($|\b)/
|
||||
- build
|
||||
|
||||
16
.eslintrc
16
.eslintrc
@@ -5,6 +5,20 @@
|
||||
"import/no-unresolved": 0,
|
||||
"import/no-dynamic-require": 0,
|
||||
"global-require": 0
|
||||
}
|
||||
},
|
||||
"overrides": [
|
||||
{
|
||||
"files": ["test/**"],
|
||||
"rules": {
|
||||
"import/no-extraneous-dependencies": 0
|
||||
},
|
||||
"globals": {
|
||||
"describe": true,
|
||||
"it": true,
|
||||
"test": true,
|
||||
"expect": true
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
module.exports = {
|
||||
testEnvironment: 'node',
|
||||
rootDir: 'test',
|
||||
collectCoverageFrom: ['packages/**/*.{js,jsx}', '!**/node_modules/**'],
|
||||
};
|
||||
|
||||
@@ -26,14 +26,19 @@
|
||||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/fs-extra": "^5.0.4",
|
||||
"@types/glob": "^7.1.1",
|
||||
"@types/multistream": "^2.1.1",
|
||||
"@types/node": "^10.12.8",
|
||||
"eslint": "^5.9.0",
|
||||
"eslint-config-airbnb-base": "^13.1.0",
|
||||
"eslint-config-prettier": "^3.1.0",
|
||||
"eslint-plugin-import": "^2.14.0",
|
||||
"fs-extra": "^7.0.1",
|
||||
"glob": "^7.1.3",
|
||||
"jest": "^23.6.0",
|
||||
"lint-staged": "^8.0.4",
|
||||
"node-fetch": "^2.3.0",
|
||||
"pre-commit": "^1.2.2",
|
||||
"prettier": "^1.15.2",
|
||||
"typescript": "^3.1.6"
|
||||
|
||||
1
packages/now-build-utils/.npmignore
Normal file
1
packages/now-build-utils/.npmignore
Normal file
@@ -0,0 +1 @@
|
||||
/test
|
||||
@@ -1,20 +1,38 @@
|
||||
const assert = require('assert');
|
||||
const fs = require('fs-extra');
|
||||
const MultiStream = require('multistream');
|
||||
const multiStream = require('multistream');
|
||||
const path = require('path');
|
||||
const Sema = require('async-sema');
|
||||
|
||||
/** @typedef {{[filePath: string]: FileFsRef}} FsFiles */
|
||||
|
||||
const semaToPreventEMFILE = new Sema(30);
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @argument {Object} options
|
||||
* @argument {number} [options.mode=0o100644]
|
||||
* @argument {string} options.fsPath
|
||||
*/
|
||||
class FileFsRef {
|
||||
constructor({ mode = 0o100644, fsPath }) {
|
||||
assert(typeof mode === 'number');
|
||||
assert(typeof fsPath === 'string');
|
||||
/** @type {string} */
|
||||
this.type = 'FileFsRef';
|
||||
/** @type {number} */
|
||||
this.mode = mode;
|
||||
/** @type {string} */
|
||||
this.fsPath = fsPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* @argument {Object} options
|
||||
* @argument {number} [options.mode=0o100644]
|
||||
* @argument {NodeJS.ReadableStream} options.stream
|
||||
* @argument {string} options.fsPath
|
||||
* @returns {Promise<FileFsRef>}
|
||||
*/
|
||||
static async fromStream({ mode = 0o100644, stream, fsPath }) {
|
||||
assert(typeof mode === 'number');
|
||||
assert(typeof stream.pipe === 'function'); // is-stream
|
||||
@@ -33,6 +51,9 @@ class FileFsRef {
|
||||
return new FileFsRef({ mode, fsPath });
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {Promise<NodeJS.ReadableStream>}
|
||||
*/
|
||||
async toStreamAsync() {
|
||||
await semaToPreventEMFILE.acquire();
|
||||
const release = () => semaToPreventEMFILE.release();
|
||||
@@ -42,19 +63,24 @@ class FileFsRef {
|
||||
return stream;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {NodeJS.ReadableStream}
|
||||
*/
|
||||
toStream() {
|
||||
let flag;
|
||||
|
||||
// eslint-disable-next-line consistent-return
|
||||
return new MultiStream((cb) => {
|
||||
if (flag) return cb();
|
||||
return multiStream((cb) => {
|
||||
if (flag) return cb(null, null);
|
||||
flag = true;
|
||||
|
||||
this.toStreamAsync().then((stream) => {
|
||||
cb(undefined, stream);
|
||||
}).catch((error) => {
|
||||
cb(error);
|
||||
});
|
||||
this.toStreamAsync()
|
||||
.then((stream) => {
|
||||
cb(null, stream);
|
||||
})
|
||||
.catch((error) => {
|
||||
cb(error, null);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,8 @@ const multiStream = require('multistream');
|
||||
const retry = require('async-retry');
|
||||
const Sema = require('async-sema');
|
||||
|
||||
/** @typedef {{[filePath: string]: FileRef}} Files */
|
||||
|
||||
const semaToDownloadFromS3 = new Sema(10);
|
||||
|
||||
class BailableError extends Error {
|
||||
|
||||
@@ -1,20 +1,38 @@
|
||||
const path = require('path');
|
||||
const FileFsRef = require('../file-fs-ref.js');
|
||||
|
||||
/** @typedef {import('../file-ref')} FileRef */
|
||||
/** @typedef {import('../file-fs-ref')} FileFsRef */
|
||||
/** @typedef {{[filePath: string]: FileRef|FileFsRef}} Files */
|
||||
/** @typedef {{[filePath: string]: FileFsRef}|{}} DownloadedFiles */
|
||||
|
||||
/**
|
||||
* @param {FileRef|FileFsRef} file
|
||||
* @param {string} fsPath
|
||||
* @returns {Promise<FileFsRef>}
|
||||
*/
|
||||
async function downloadFile(file, fsPath) {
|
||||
const { mode } = file;
|
||||
const stream = file.toStream();
|
||||
return FileFsRef.fromStream({ mode, stream, fsPath });
|
||||
}
|
||||
|
||||
/**
|
||||
* Download files to disk
|
||||
* @argument {Files} files
|
||||
* @argument {string} basePath
|
||||
* @returns {Promise<DownloadedFiles>}
|
||||
*/
|
||||
module.exports = async function download(files, basePath) {
|
||||
const files2 = {};
|
||||
|
||||
await Promise.all(Object.keys(files).map(async (name) => {
|
||||
const file = files[name];
|
||||
const fsPath = path.join(basePath, name);
|
||||
files2[name] = await downloadFile(file, fsPath);
|
||||
}));
|
||||
await Promise.all(
|
||||
Object.keys(files).map(async (name) => {
|
||||
const file = files[name];
|
||||
const fsPath = path.join(basePath, name);
|
||||
files2[name] = await downloadFile(file, fsPath);
|
||||
}),
|
||||
);
|
||||
|
||||
return files2;
|
||||
};
|
||||
|
||||
@@ -3,15 +3,30 @@ const path = require('path');
|
||||
const vanillaGlob = require('glob');
|
||||
const FileFsRef = require('../file-fs-ref.js');
|
||||
|
||||
/** @typedef {import('fs').Stats} Stats */
|
||||
/** @typedef {import('glob').IOptions} GlobOptions */
|
||||
/** @typedef {import('../file-fs-ref').FsFiles|{}} GlobFiles */
|
||||
|
||||
/**
|
||||
* @argument {string} pattern
|
||||
* @argument {GlobOptions|string} opts
|
||||
* @argument {string} [mountpoint]
|
||||
* @returns {Promise<GlobFiles>}
|
||||
*/
|
||||
module.exports = function glob(pattern, opts = {}, mountpoint) {
|
||||
return new Promise((resolve, reject) => {
|
||||
let options = opts;
|
||||
if (typeof options === 'string') {
|
||||
options = { cwd: options };
|
||||
/** @type {GlobOptions} */
|
||||
let options;
|
||||
if (typeof opts === 'string') {
|
||||
options = { cwd: opts };
|
||||
} else {
|
||||
options = opts;
|
||||
}
|
||||
|
||||
if (!options.cwd) {
|
||||
throw new Error('Second argument (basePath) must be specified for names of resulting files');
|
||||
throw new Error(
|
||||
'Second argument (basePath) must be specified for names of resulting files',
|
||||
);
|
||||
}
|
||||
|
||||
if (!path.isAbsolute(options.cwd)) {
|
||||
@@ -26,21 +41,27 @@ module.exports = function glob(pattern, opts = {}, mountpoint) {
|
||||
vanillaGlob(pattern, options, (error, files) => {
|
||||
if (error) return reject(error);
|
||||
|
||||
resolve(files.reduce((files2, relativePath) => {
|
||||
const fsPath = path.join(options.cwd, relativePath);
|
||||
const stat = options.statCache[fsPath];
|
||||
assert(stat, `statCache does not contain value for ${relativePath} (resolved to ${fsPath})`);
|
||||
if (stat.isFile()) {
|
||||
let finalPath = relativePath;
|
||||
if (mountpoint) finalPath = path.join(mountpoint, finalPath);
|
||||
return {
|
||||
...files2,
|
||||
[finalPath]: new FileFsRef({ mode: stat.mode, fsPath }),
|
||||
};
|
||||
}
|
||||
resolve(
|
||||
files.reduce((files2, relativePath) => {
|
||||
const fsPath = path.join(options.cwd, relativePath);
|
||||
/** @type {Stats|any} */
|
||||
const stat = options.statCache[fsPath];
|
||||
assert(
|
||||
stat,
|
||||
`statCache does not contain value for ${relativePath} (resolved to ${fsPath})`,
|
||||
);
|
||||
if (stat && stat.isFile()) {
|
||||
let finalPath = relativePath;
|
||||
if (mountpoint) finalPath = path.join(mountpoint, finalPath);
|
||||
return {
|
||||
...files2,
|
||||
[finalPath]: new FileFsRef({ mode: stat.mode, fsPath }),
|
||||
};
|
||||
}
|
||||
|
||||
return files2;
|
||||
}, {}));
|
||||
return files2;
|
||||
}, {}),
|
||||
);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
@@ -1,6 +1,25 @@
|
||||
/** @typedef { import('@now/build-utils/file-ref') } FileRef */
|
||||
/** @typedef { import('@now/build-utils/file-fs-ref') } FileFsRef */
|
||||
/** @typedef {{[filePath: string]: FileRef|FileFsRef}} Files */
|
||||
|
||||
/**
|
||||
* @callback delegate
|
||||
* @argument {string} name
|
||||
* @returns {string}
|
||||
*/
|
||||
|
||||
/**
|
||||
* Rename files using delegate function
|
||||
* @argument {Files} files
|
||||
* @argument {delegate} delegate
|
||||
* @returns {Files}
|
||||
*/
|
||||
module.exports = function rename(files, delegate) {
|
||||
return Object.keys(files).reduce((newFiles, name) => ({
|
||||
...newFiles,
|
||||
[delegate(name)]: files[name],
|
||||
}), {});
|
||||
return Object.keys(files).reduce(
|
||||
(newFiles, name) => ({
|
||||
...newFiles,
|
||||
[delegate(name)]: files[name],
|
||||
}),
|
||||
{},
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
const assert = require('assert');
|
||||
const fs = require('fs-extra');
|
||||
const path = require('path');
|
||||
const { spawn } = require('child_process');
|
||||
@@ -13,22 +14,34 @@ function spawnAsync(command, args, cwd) {
|
||||
}
|
||||
|
||||
async function runShellScript(fsPath) {
|
||||
assert(path.isAbsolute(fsPath));
|
||||
const destPath = path.dirname(fsPath);
|
||||
await spawnAsync(`./${path.basename(fsPath)}`, [], destPath);
|
||||
return true;
|
||||
}
|
||||
|
||||
async function shouldUseNpm(destPath) {
|
||||
async function scanParentDirs(destPath, scriptName) {
|
||||
assert(path.isAbsolute(destPath));
|
||||
|
||||
let hasScript = false;
|
||||
let hasPackageLockJson = false;
|
||||
let currentDestPath = destPath;
|
||||
|
||||
// eslint-disable-next-line no-constant-condition
|
||||
while (true) {
|
||||
const packageJsonPath = path.join(currentDestPath, 'package.json');
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
if (await fs.exists(path.join(currentDestPath, 'package.json'))) {
|
||||
if (await fs.exists(packageJsonPath)) {
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
if (await fs.exists(path.join(currentDestPath, 'package-lock.json'))) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
const packageJson = JSON.parse(await fs.readFile(packageJsonPath));
|
||||
hasScript = Boolean(
|
||||
packageJson.scripts && packageJson.scripts[scriptName],
|
||||
);
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
hasPackageLockJson = await fs.exists(
|
||||
path.join(currentDestPath, 'package-lock.json'),
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
const newDestPath = path.dirname(currentDestPath);
|
||||
@@ -36,13 +49,17 @@ async function shouldUseNpm(destPath) {
|
||||
currentDestPath = newDestPath;
|
||||
}
|
||||
|
||||
return false;
|
||||
return { hasScript, hasPackageLockJson };
|
||||
}
|
||||
|
||||
async function runNpmInstall(destPath, args = []) {
|
||||
assert(path.isAbsolute(destPath));
|
||||
|
||||
let commandArgs = args;
|
||||
console.log(`installing to ${destPath}`);
|
||||
if (await shouldUseNpm(destPath)) {
|
||||
const { hasPackageLockJson } = await scanParentDirs(destPath);
|
||||
|
||||
if (hasPackageLockJson) {
|
||||
commandArgs = args.filter(a => a !== '--prefer-offline');
|
||||
await spawnAsync('npm', ['install'].concat(commandArgs), destPath);
|
||||
await spawnAsync('npm', ['cache', 'clean', '--force'], destPath);
|
||||
@@ -53,21 +70,19 @@ async function runNpmInstall(destPath, args = []) {
|
||||
}
|
||||
|
||||
async function runPackageJsonScript(destPath, scriptName) {
|
||||
try {
|
||||
if (await shouldUseNpm(destPath)) {
|
||||
console.log(`running "npm run ${scriptName}"`);
|
||||
await spawnAsync('npm', ['run', scriptName], destPath);
|
||||
} else {
|
||||
console.log(`running "yarn run ${scriptName}"`);
|
||||
await spawnAsync(
|
||||
'yarn',
|
||||
['--cwd', destPath, 'run', scriptName],
|
||||
destPath,
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error.message);
|
||||
return false;
|
||||
assert(path.isAbsolute(destPath));
|
||||
const { hasScript, hasPackageLockJson } = await scanParentDirs(
|
||||
destPath,
|
||||
scriptName,
|
||||
);
|
||||
if (!hasScript) return false;
|
||||
|
||||
if (hasPackageLockJson) {
|
||||
console.log(`running "npm run ${scriptName}"`);
|
||||
await spawnAsync('npm', ['run', scriptName], destPath);
|
||||
} else {
|
||||
console.log(`running "yarn run ${scriptName}"`);
|
||||
await spawnAsync('yarn', ['--cwd', destPath, 'run', scriptName], destPath);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -25,16 +25,21 @@ async function createLambda({
|
||||
assert(typeof environment === 'object', '"environment" is not an object');
|
||||
const zipFile = new ZipFile();
|
||||
|
||||
Object.keys(files).sort().forEach((name) => {
|
||||
const file = files[name];
|
||||
const stream = file.toStream();
|
||||
zipFile.addReadStream(stream, name, { mode: file.mode, mtime });
|
||||
});
|
||||
Object.keys(files)
|
||||
.sort()
|
||||
.forEach((name) => {
|
||||
const file = files[name];
|
||||
const stream = file.toStream();
|
||||
zipFile.addReadStream(stream, name, { mode: file.mode, mtime });
|
||||
});
|
||||
|
||||
zipFile.end();
|
||||
const zipBuffer = await streamToBuffer(zipFile.outputStream);
|
||||
return new Lambda({
|
||||
zipBuffer, handler, runtime, environment,
|
||||
zipBuffer,
|
||||
handler,
|
||||
runtime,
|
||||
environment,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@now/build-utils",
|
||||
"version": "0.4.29-canary.2",
|
||||
"version": "0.4.30",
|
||||
"dependencies": {
|
||||
"async-retry": "1.2.3",
|
||||
"async-sema": "2.1.4",
|
||||
@@ -11,5 +11,8 @@
|
||||
"multistream": "2.1.1",
|
||||
"node-fetch": "2.2.0",
|
||||
"yazl": "2.4.3"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "jest"
|
||||
}
|
||||
}
|
||||
|
||||
11
packages/now-build-utils/test/fixtures/08-yarn-npm/now.json
vendored
Normal file
11
packages/now-build-utils/test/fixtures/08-yarn-npm/now.json
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"version": 2,
|
||||
"builds": [
|
||||
{ "src": "with-npm/index.js", "use": "@now/node" },
|
||||
{ "src": "with-yarn/index.js", "use": "@now/node" }
|
||||
],
|
||||
"probes": [
|
||||
{ "path": "/with-npm", "mustContain": "npm:RANDOMNESS_PLACEHOLDER" },
|
||||
{ "path": "/with-yarn", "mustContain": "yarn:RANDOMNESS_PLACEHOLDER" }
|
||||
]
|
||||
}
|
||||
0
packages/now-build-utils/test/fixtures/08-yarn-npm/with-npm/index.js
vendored
Normal file
0
packages/now-build-utils/test/fixtures/08-yarn-npm/with-npm/index.js
vendored
Normal file
14
packages/now-build-utils/test/fixtures/08-yarn-npm/with-npm/must-be-npm.js
vendored
Normal file
14
packages/now-build-utils/test/fixtures/08-yarn-npm/with-npm/must-be-npm.js
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const execpath = path.basename(process.env.npm_execpath);
|
||||
console.log('execpath', execpath);
|
||||
|
||||
if (execpath === 'npm-cli.js') {
|
||||
fs.writeFileSync(
|
||||
'index.js',
|
||||
'module.exports = (_, resp) => resp.end("npm:RANDOMNESS_PLACEHOLDER");',
|
||||
);
|
||||
} else {
|
||||
throw new Error('npm is expected');
|
||||
}
|
||||
3
packages/now-build-utils/test/fixtures/08-yarn-npm/with-npm/package-lock.json
generated
vendored
Normal file
3
packages/now-build-utils/test/fixtures/08-yarn-npm/with-npm/package-lock.json
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"lockfileVersion": 1
|
||||
}
|
||||
5
packages/now-build-utils/test/fixtures/08-yarn-npm/with-npm/package.json
vendored
Normal file
5
packages/now-build-utils/test/fixtures/08-yarn-npm/with-npm/package.json
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"scripts": {
|
||||
"now-build": "node must-be-npm.js"
|
||||
}
|
||||
}
|
||||
0
packages/now-build-utils/test/fixtures/08-yarn-npm/with-yarn/index.js
vendored
Normal file
0
packages/now-build-utils/test/fixtures/08-yarn-npm/with-yarn/index.js
vendored
Normal file
14
packages/now-build-utils/test/fixtures/08-yarn-npm/with-yarn/must-be-yarn.js
vendored
Normal file
14
packages/now-build-utils/test/fixtures/08-yarn-npm/with-yarn/must-be-yarn.js
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const execpath = path.basename(process.env.npm_execpath);
|
||||
console.log('execpath', execpath);
|
||||
|
||||
if (execpath === 'yarn.js' || execpath === 'yarn') {
|
||||
fs.writeFileSync(
|
||||
'index.js',
|
||||
'module.exports = (_, resp) => resp.end("yarn:RANDOMNESS_PLACEHOLDER");',
|
||||
);
|
||||
} else {
|
||||
throw new Error('yarn is expected');
|
||||
}
|
||||
5
packages/now-build-utils/test/fixtures/08-yarn-npm/with-yarn/package.json
vendored
Normal file
5
packages/now-build-utils/test/fixtures/08-yarn-npm/with-yarn/package.json
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"scripts": {
|
||||
"now-build": "node must-be-yarn.js"
|
||||
}
|
||||
}
|
||||
53
packages/now-build-utils/test/test.js
Normal file
53
packages/now-build-utils/test/test.js
Normal file
@@ -0,0 +1,53 @@
|
||||
/* global beforeAll, expect, it, jest */
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const {
|
||||
packAndDeploy,
|
||||
testDeployment,
|
||||
} = require('../../../test/lib/deployment/test-deployment.js');
|
||||
|
||||
jest.setTimeout(2 * 60 * 1000);
|
||||
let buildUtilsUrl;
|
||||
|
||||
beforeAll(async () => {
|
||||
const buildUtilsPath = path.resolve(__dirname, '..');
|
||||
buildUtilsUrl = await packAndDeploy(buildUtilsPath);
|
||||
console.log('buildUtilsUrl', buildUtilsUrl);
|
||||
});
|
||||
|
||||
// own fixtures
|
||||
|
||||
const fixturesPath = path.resolve(__dirname, 'fixtures');
|
||||
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
for (const fixture of fs.readdirSync(fixturesPath)) {
|
||||
// eslint-disable-next-line no-loop-func
|
||||
it(`should build ${fixture}`, async () => {
|
||||
await expect(
|
||||
testDeployment({ buildUtilsUrl }, path.join(fixturesPath, fixture)),
|
||||
).resolves.toBe(undefined);
|
||||
});
|
||||
}
|
||||
|
||||
// few foreign tests
|
||||
|
||||
const buildersToTestWith = ['now-node-server', 'now-static-build'];
|
||||
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
for (const builder of buildersToTestWith) {
|
||||
const fixturesPath2 = path.resolve(
|
||||
__dirname,
|
||||
`../../${builder}/test/fixtures`,
|
||||
);
|
||||
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
for (const fixture of fs.readdirSync(fixturesPath2)) {
|
||||
// eslint-disable-next-line no-loop-func
|
||||
it(`should build ${builder}/${fixture}`, async () => {
|
||||
await expect(
|
||||
testDeployment({ buildUtilsUrl }, path.join(fixturesPath2, fixture)),
|
||||
).resolves.toBe(undefined);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
export GOOS=linux
|
||||
export GOARCH=amd64
|
||||
export GOPATH=$HOME/go
|
||||
go get github.com/aws/aws-lambda-go/events
|
||||
go get github.com/aws/aws-lambda-go/lambda
|
||||
go build -o handler main.go
|
||||
|
||||
@@ -70,7 +70,7 @@ func (h *CgiHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
Path: h.Script,
|
||||
Root: "/" + h.Script,
|
||||
Dir: h.Dir,
|
||||
Env: []string{"SERVER_PORT=443"},
|
||||
Env: []string{"SERVER_PORT=443", "HTTPS=on", "SERVER_SOFTWARE=@now/cgi"},
|
||||
}
|
||||
cgih.ServeHTTP(w, r)
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@now/cgi",
|
||||
"version": "0.0.12-canary.1",
|
||||
"version": "0.0.13",
|
||||
"scripts": {
|
||||
"test": "best -I test/*.js",
|
||||
"prepublish": "./build.sh"
|
||||
|
||||
@@ -91,7 +91,10 @@ func main() {
|
||||
for k, v := range req.Headers {
|
||||
internalReq.Header.Add(k, v)
|
||||
if strings.ToLower(k) == "host" {
|
||||
req.Host = v
|
||||
// we need to set `Host` in the request
|
||||
// because Go likes to ignore the `Host` header
|
||||
// see https://github.com/golang/go/issues/7682
|
||||
internalReq.Host = v
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@now/go",
|
||||
"version": "0.2.9-canary.1",
|
||||
"version": "0.2.10",
|
||||
"scripts": {
|
||||
"test": "best -I test/*.js",
|
||||
"prepublish": "./build.sh"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@now/html-minifier",
|
||||
"version": "1.0.5-canary.0",
|
||||
"version": "1.0.6",
|
||||
"dependencies": {
|
||||
"html-minifier": "3.5.21"
|
||||
},
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@now/lambda",
|
||||
"version": "0.4.6-canary.0",
|
||||
"version": "0.4.7",
|
||||
"peerDependencies": {
|
||||
"@now/build-utils": ">=0.0.1"
|
||||
}
|
||||
|
||||
@@ -22,12 +22,17 @@ exports.build = async ({ files, entrypoint, config }) => {
|
||||
.use(markdown)
|
||||
.use(remark2rehype)
|
||||
.use(doc, {
|
||||
title, language, meta, css,
|
||||
title,
|
||||
language,
|
||||
meta,
|
||||
css,
|
||||
})
|
||||
.use(format)
|
||||
.use(html);
|
||||
|
||||
const result = await FileBlob.fromStream({ stream: stream.pipe(unifiedStream(processor)) });
|
||||
const result = await FileBlob.fromStream({
|
||||
stream: stream.pipe(unifiedStream(processor)),
|
||||
});
|
||||
|
||||
console.log(result.data.toString());
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@now/md",
|
||||
"version": "0.4.6-canary.0",
|
||||
"version": "0.4.7",
|
||||
"dependencies": {
|
||||
"rehype-document": "^2.2.0",
|
||||
"rehype-format": "^2.3.0",
|
||||
|
||||
@@ -19,13 +19,19 @@ exports.build = async ({ files, entrypoint, workPath }) => {
|
||||
await writeFile(packageJsonPath, JSON.stringify(packageJson));
|
||||
console.log('running npm install...');
|
||||
process.env.PUPPETEER_SKIP_CHROMIUM_DOWNLOAD = '1'; // TODO opts argument for runNpmInstall
|
||||
await runNpmInstall(path.dirname(packageJsonPath), ['--prod', '--prefer-offline']);
|
||||
await runNpmInstall(path.dirname(packageJsonPath), [
|
||||
'--prod',
|
||||
'--prefer-offline',
|
||||
]);
|
||||
console.log('building...');
|
||||
const outDir = await getWritableDirectory();
|
||||
const entrypointFsPath = downloadedFiles[entrypoint].fsPath;
|
||||
const mountpoint = path.dirname(entrypoint);
|
||||
|
||||
const build = require(path.join(workPath, 'node_modules/mdx-deck/lib/build.js'));
|
||||
const build = require(path.join(
|
||||
workPath,
|
||||
'node_modules/mdx-deck/lib/build.js',
|
||||
));
|
||||
|
||||
await build({
|
||||
html: true,
|
||||
@@ -48,8 +54,8 @@ exports.prepareCache = async ({ cachePath }) => {
|
||||
await runNpmInstall(path.dirname(packageJsonPath), ['--prod']);
|
||||
|
||||
return {
|
||||
...await glob('node_modules/**', cachePath),
|
||||
...await glob('package-lock.json', cachePath),
|
||||
...await glob('yarn.lock', cachePath),
|
||||
...(await glob('node_modules/**', cachePath)),
|
||||
...(await glob('package-lock.json', cachePath)),
|
||||
...(await glob('yarn.lock', cachePath)),
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@now/mdx-deck",
|
||||
"version": "0.4.15-canary.0",
|
||||
"version": "0.4.16",
|
||||
"peerDependencies": {
|
||||
"@now/build-utils": ">=0.0.1"
|
||||
}
|
||||
|
||||
@@ -4,128 +4,107 @@ const FileFsRef = require('@now/build-utils/file-fs-ref.js');
|
||||
const FileBlob = require('@now/build-utils/file-blob');
|
||||
const path = require('path');
|
||||
const { readFile, writeFile, unlink } = require('fs.promised');
|
||||
const rename = require('@now/build-utils/fs/rename.js');
|
||||
const {
|
||||
runNpmInstall,
|
||||
runPackageJsonScript,
|
||||
} = require('@now/build-utils/fs/run-user-scripts.js');
|
||||
const glob = require('@now/build-utils/fs/glob.js');
|
||||
const {
|
||||
excludeFiles,
|
||||
validateEntrypoint,
|
||||
includeOnlyEntryDirectory,
|
||||
moveEntryDirectoryToRoot,
|
||||
excludeLockFiles,
|
||||
normalizePackageJson,
|
||||
excludeStaticDirectory,
|
||||
} = require('./utils');
|
||||
|
||||
// Exclude certain files from the files object
|
||||
function excludeFiles(files, matchFn) {
|
||||
return Object.keys(files).reduce((newFiles, fileName) => {
|
||||
if (matchFn(fileName)) {
|
||||
return newFiles;
|
||||
}
|
||||
return {
|
||||
...newFiles,
|
||||
[fileName]: files[fileName],
|
||||
};
|
||||
}, {});
|
||||
/** @typedef { import('@now/build-utils/file-ref').Files } Files */
|
||||
/** @typedef { import('@now/build-utils/fs/download').DownloadedFiles } DownloadedFiles */
|
||||
|
||||
/**
|
||||
* @typedef {Object} BuildParamsType
|
||||
* @property {Files} files - Files object
|
||||
* @property {string} entrypoint - Entrypoint specified for the builder
|
||||
* @property {string} workPath - Working directory for this build
|
||||
*/
|
||||
|
||||
/**
|
||||
* Read package.json from files
|
||||
* @param {DownloadedFiles} files
|
||||
*/
|
||||
async function readPackageJson(files) {
|
||||
if (!files['package.json']) {
|
||||
return {};
|
||||
}
|
||||
|
||||
const packageJsonPath = files['package.json'].fsPath;
|
||||
return JSON.parse(await readFile(packageJsonPath, 'utf8'));
|
||||
}
|
||||
|
||||
function shouldExcludeFile(entryDirectory) {
|
||||
return (file) => {
|
||||
// If the file is not in the entry directory
|
||||
if (entryDirectory !== '.' && !file.startsWith(entryDirectory)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Exclude static directory
|
||||
if (file.startsWith(path.join(entryDirectory, 'static'))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (file === 'package-lock.json') {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (file === 'yarn.lock') {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
}
|
||||
|
||||
exports.build = async ({ files, workPath, entrypoint }) => {
|
||||
if (
|
||||
!/package\.json$/.exec(entrypoint)
|
||||
&& !/next\.config\.js$/.exec(entrypoint)
|
||||
) {
|
||||
throw new Error(
|
||||
'Specified "src" for "@now/next" has to be "package.json" or "next.config.js"',
|
||||
);
|
||||
}
|
||||
|
||||
console.log('downloading user files...');
|
||||
const entryDirectory = path.dirname(entrypoint);
|
||||
const filesToDownload = excludeFiles(
|
||||
files,
|
||||
shouldExcludeFile(entryDirectory),
|
||||
);
|
||||
const entrypointHandledFilesToDownload = rename(filesToDownload, (file) => {
|
||||
if (entryDirectory !== '.') {
|
||||
return file.replace(new RegExp(`^${entryDirectory}/`), '');
|
||||
}
|
||||
return file;
|
||||
});
|
||||
let downloadedFiles = await download(
|
||||
entrypointHandledFilesToDownload,
|
||||
workPath,
|
||||
);
|
||||
|
||||
let packageJson = {};
|
||||
if (downloadedFiles['package.json']) {
|
||||
console.log('found package.json, overwriting');
|
||||
const packageJsonPath = downloadedFiles['package.json'].fsPath;
|
||||
packageJson = JSON.parse(await readFile(packageJsonPath, 'utf8'));
|
||||
}
|
||||
|
||||
packageJson = {
|
||||
...packageJson,
|
||||
dependencies: {
|
||||
...packageJson.dependencies,
|
||||
'next-server': 'canary',
|
||||
},
|
||||
devDependencies: {
|
||||
...packageJson.devDependencies,
|
||||
next: 'canary',
|
||||
},
|
||||
scripts: {
|
||||
...packageJson.scripts,
|
||||
'now-build': 'next build',
|
||||
},
|
||||
};
|
||||
|
||||
if (!packageJson.dependencies.react) {
|
||||
console.log(
|
||||
'"react" not found in dependencies, adding to "package.json" "dependencies"',
|
||||
);
|
||||
packageJson.dependencies.react = 'latest';
|
||||
}
|
||||
if (!packageJson.dependencies['react-dom']) {
|
||||
console.log(
|
||||
'"react-dom" not found in dependencies, adding to "package.json" "dependencies"',
|
||||
);
|
||||
packageJson.dependencies['react-dom'] = 'latest';
|
||||
}
|
||||
|
||||
// in case the user has `next` on their `dependencies`, we remove it
|
||||
delete packageJson.dependencies.next;
|
||||
|
||||
/**
|
||||
* Write package.json
|
||||
* @param {string} workPath
|
||||
* @param {Object} packageJson
|
||||
*/
|
||||
async function writePackageJson(workPath, packageJson) {
|
||||
await writeFile(
|
||||
path.join(workPath, 'package.json'),
|
||||
JSON.stringify(packageJson, null, 2),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write .npmrc with npm auth token
|
||||
* @param {string} workPath
|
||||
* @param {string} token
|
||||
*/
|
||||
async function writeNpmRc(workPath, token) {
|
||||
await writeFile(
|
||||
path.join(workPath, '.npmrc'),
|
||||
`//registry.npmjs.org/:_authToken=${token}`,
|
||||
);
|
||||
}
|
||||
|
||||
exports.config = {
|
||||
maxLambdaSize: '5mb',
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {BuildParamsType} buildParams
|
||||
* @returns {Promise<Files>}
|
||||
*/
|
||||
exports.build = async ({ files, workPath, entrypoint }) => {
|
||||
validateEntrypoint(entrypoint);
|
||||
|
||||
console.log('downloading user files...');
|
||||
const entryDirectory = path.dirname(entrypoint);
|
||||
const filesOnlyEntryDirectory = includeOnlyEntryDirectory(
|
||||
files,
|
||||
entryDirectory,
|
||||
);
|
||||
const filesWithEntryDirectoryRoot = moveEntryDirectoryToRoot(
|
||||
filesOnlyEntryDirectory,
|
||||
entryDirectory,
|
||||
);
|
||||
const filesWithoutLockfiles = excludeLockFiles(filesWithEntryDirectoryRoot);
|
||||
const filesWithoutStaticDirectory = excludeStaticDirectory(
|
||||
filesWithoutLockfiles,
|
||||
);
|
||||
let downloadedFiles = await download(filesWithoutStaticDirectory, workPath);
|
||||
|
||||
console.log('normalizing package.json');
|
||||
const packageJson = normalizePackageJson(
|
||||
await readPackageJson(downloadedFiles),
|
||||
);
|
||||
console.log('normalized package.json result: ', packageJson);
|
||||
await writePackageJson(workPath, packageJson);
|
||||
|
||||
if (process.env.NPM_AUTH_TOKEN) {
|
||||
console.log('found NPM_AUTH_TOKEN in environment, creating .npmrc');
|
||||
await writeFile(
|
||||
path.join(workPath, '.npmrc'),
|
||||
`//registry.npmjs.org/:_authToken=${process.env.NPM_AUTH_TOKEN}`,
|
||||
);
|
||||
await writeNpmRc(workPath, process.env.NPM_AUTH_TOKEN);
|
||||
}
|
||||
|
||||
downloadedFiles = await glob('**', workPath);
|
||||
|
||||
console.log('running npm install...');
|
||||
@@ -137,6 +116,7 @@ exports.build = async ({ files, workPath, entrypoint }) => {
|
||||
if (process.env.NPM_AUTH_TOKEN) {
|
||||
await unlink(path.join(workPath, '.npmrc'));
|
||||
}
|
||||
|
||||
downloadedFiles = await glob('**', workPath);
|
||||
|
||||
console.log('preparing lambda files...');
|
||||
@@ -203,6 +183,7 @@ exports.build = async ({ files, workPath, entrypoint }) => {
|
||||
],
|
||||
};
|
||||
|
||||
console.log(`Creating lambda for page: "${page}"...`);
|
||||
lambdas[path.join(entryDirectory, pathname)] = await createLambda({
|
||||
files: {
|
||||
...nextFiles,
|
||||
@@ -212,6 +193,7 @@ exports.build = async ({ files, workPath, entrypoint }) => {
|
||||
handler: 'now__launcher.launcher',
|
||||
runtime: 'nodejs8.10',
|
||||
});
|
||||
console.log(`Created lambda for page: "${page}"`);
|
||||
}),
|
||||
);
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@now/next",
|
||||
"version": "0.0.78-canary.1",
|
||||
"version": "0.0.80",
|
||||
"dependencies": {
|
||||
"@now/node-bridge": "0.1.4",
|
||||
"execa": "^1.0.0",
|
||||
|
||||
167
packages/now-next/utils.js
Normal file
167
packages/now-next/utils.js
Normal file
@@ -0,0 +1,167 @@
|
||||
const rename = require('@now/build-utils/fs/rename.js');
|
||||
|
||||
/** @typedef { import('@now/build-utils/file-ref') } FileRef */
|
||||
/** @typedef { import('@now/build-utils/file-fs-ref') } FileFsRef */
|
||||
/** @typedef {{[filePath: string]: FileRef|FileFsRef}} Files */
|
||||
|
||||
/**
|
||||
* Validate if the entrypoint is allowed to be used
|
||||
* @param {string} entrypoint
|
||||
* @throws {Error}
|
||||
*/
|
||||
function validateEntrypoint(entrypoint) {
|
||||
if (
|
||||
!/package\.json$/.exec(entrypoint)
|
||||
&& !/next\.config\.js$/.exec(entrypoint)
|
||||
) {
|
||||
throw new Error(
|
||||
'Specified "src" for "@now/next" has to be "package.json" or "next.config.js"',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This callback type is called `requestCallback` and is displayed as a global symbol.
|
||||
*
|
||||
* @callback matcher
|
||||
* @param {string} filePath
|
||||
* @returns {boolean}
|
||||
*/
|
||||
|
||||
/**
|
||||
* Exclude certain files from the files object
|
||||
* @param {Files} files
|
||||
* @param {matcher} matcher
|
||||
* @returns {Files}
|
||||
*/
|
||||
function excludeFiles(files, matcher) {
|
||||
return Object.keys(files).reduce((newFiles, filePath) => {
|
||||
if (matcher(filePath)) {
|
||||
return newFiles;
|
||||
}
|
||||
return {
|
||||
...newFiles,
|
||||
[filePath]: files[filePath],
|
||||
};
|
||||
}, {});
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new Files object holding only the entrypoint files
|
||||
* @param {Files} files
|
||||
* @param {string} entryDirectory
|
||||
* @returns {Files}
|
||||
*/
|
||||
function includeOnlyEntryDirectory(files, entryDirectory) {
|
||||
if (entryDirectory === '.') {
|
||||
return files;
|
||||
}
|
||||
|
||||
function matcher(filePath) {
|
||||
return !filePath.startsWith(entryDirectory);
|
||||
}
|
||||
|
||||
return excludeFiles(files, matcher);
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves all files under the entry directory to the root directory
|
||||
* @param {Files} files
|
||||
* @param {string} entryDirectory
|
||||
* @returns {Files}
|
||||
*/
|
||||
function moveEntryDirectoryToRoot(files, entryDirectory) {
|
||||
if (entryDirectory === '.') {
|
||||
return files;
|
||||
}
|
||||
|
||||
function delegate(filePath) {
|
||||
return filePath.replace(new RegExp(`^${entryDirectory}/`), '');
|
||||
}
|
||||
|
||||
return rename(files, delegate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Exclude package manager lockfiles from files
|
||||
* @param {Files} files
|
||||
* @returns {Files}
|
||||
*/
|
||||
function excludeLockFiles(files) {
|
||||
const newFiles = files;
|
||||
if (newFiles['package-lock.json']) {
|
||||
delete newFiles['package-lock.json'];
|
||||
}
|
||||
if (newFiles['yarn.lock']) {
|
||||
delete newFiles['yarn.lock'];
|
||||
}
|
||||
return files;
|
||||
}
|
||||
|
||||
/**
|
||||
* Exclude the static directory from files
|
||||
* @param {Files} files
|
||||
* @returns {Files}
|
||||
*/
|
||||
function excludeStaticDirectory(files) {
|
||||
function matcher(filePath) {
|
||||
return filePath.startsWith('static');
|
||||
}
|
||||
|
||||
return excludeFiles(files, matcher);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enforce specific package.json configuration for smallest possible lambda
|
||||
* @param {{dependencies?: any, devDependencies?: any, scripts?: any}} defaultPackageJson
|
||||
*/
|
||||
function normalizePackageJson(defaultPackageJson = {}) {
|
||||
const dependencies = {};
|
||||
const devDependencies = {
|
||||
...defaultPackageJson.dependencies,
|
||||
...defaultPackageJson.devDependencies,
|
||||
};
|
||||
|
||||
if (devDependencies.react) {
|
||||
dependencies.react = devDependencies.react;
|
||||
delete devDependencies.react;
|
||||
}
|
||||
|
||||
if (devDependencies['react-dom']) {
|
||||
dependencies['react-dom'] = devDependencies['react-dom'];
|
||||
delete devDependencies['react-dom'];
|
||||
}
|
||||
|
||||
return {
|
||||
...defaultPackageJson,
|
||||
dependencies: {
|
||||
// react and react-dom can be overwritten
|
||||
react: 'latest',
|
||||
'react-dom': 'latest',
|
||||
...dependencies, // override react if user provided it
|
||||
// next-server is forced to canary
|
||||
'next-server': 'canary',
|
||||
},
|
||||
devDependencies: {
|
||||
...devDependencies,
|
||||
// next is forced to canary
|
||||
next: 'canary',
|
||||
// next-server is a dependency here
|
||||
'next-server': undefined,
|
||||
},
|
||||
scripts: {
|
||||
...defaultPackageJson.scripts,
|
||||
'now-build': 'next build --lambdas',
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
excludeFiles,
|
||||
validateEntrypoint,
|
||||
includeOnlyEntryDirectory,
|
||||
moveEntryDirectoryToRoot,
|
||||
excludeLockFiles,
|
||||
normalizePackageJson,
|
||||
excludeStaticDirectory,
|
||||
};
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@now/node-bridge",
|
||||
"version": "0.1.8-canary.1",
|
||||
"version": "0.1.9",
|
||||
"peerDependencies": {
|
||||
"@now/build-utils": ">=0.0.1"
|
||||
}
|
||||
|
||||
1
packages/now-node-server/.npmignore
Normal file
1
packages/now-node-server/.npmignore
Normal file
@@ -0,0 +1 @@
|
||||
/test
|
||||
@@ -5,31 +5,41 @@ const FileFsRef = require('@now/build-utils/file-fs-ref.js');
|
||||
const fs = require('fs-extra');
|
||||
const glob = require('@now/build-utils/fs/glob.js');
|
||||
const path = require('path');
|
||||
const { promisify } = require('util');
|
||||
const rename = require('@now/build-utils/fs/rename.js');
|
||||
const {
|
||||
runNpmInstall,
|
||||
runPackageJsonScript,
|
||||
} = require('@now/build-utils/fs/run-user-scripts.js');
|
||||
|
||||
const fsp = {
|
||||
readFile: promisify(fs.readFile),
|
||||
};
|
||||
/** @typedef { import('@now/build-utils/file-ref') } FileRef */
|
||||
/** @typedef {{[filePath: string]: FileRef}} Files */
|
||||
|
||||
async function commonForTwo({
|
||||
files, entrypoint, workPath, cachePath,
|
||||
}) {
|
||||
const xPath = workPath || cachePath;
|
||||
const preferOfflineArgument = workPath ? ['--prefer-offline'] : [];
|
||||
/**
|
||||
* @typedef {Object} BuildParamsType
|
||||
* @property {Files} files - Files object
|
||||
* @property {string} entrypoint - Entrypoint specified for the builder
|
||||
* @property {Object} config - User-passed config from now.json
|
||||
* @property {string} workPath - Working directory for this build
|
||||
*/
|
||||
|
||||
const xUserPath = path.join(xPath, 'user');
|
||||
const xNccPath = path.join(xPath, 'ncc');
|
||||
/**
|
||||
* @param {BuildParamsType} buildParams
|
||||
* @param {Object} [options]
|
||||
* @param {string[]} [options.npmArguments]
|
||||
*/
|
||||
async function downloadInstallAndBundle(
|
||||
{ files, entrypoint, workPath },
|
||||
{ npmArguments = [] } = {},
|
||||
) {
|
||||
const userPath = path.join(workPath, 'user');
|
||||
const nccPath = path.join(workPath, 'ncc');
|
||||
|
||||
console.log('downloading user files...');
|
||||
const filesOnDisk = await download(files, xUserPath);
|
||||
const downloadedFiles = await download(files, userPath);
|
||||
|
||||
console.log('running npm install for user...');
|
||||
const entrypointFsDirname = path.join(xUserPath, path.dirname(entrypoint));
|
||||
await runNpmInstall(entrypointFsDirname, preferOfflineArgument);
|
||||
const entrypointFsDirname = path.join(userPath, path.dirname(entrypoint));
|
||||
await runNpmInstall(entrypointFsDirname, npmArguments);
|
||||
|
||||
console.log('writing ncc package.json...');
|
||||
await download(
|
||||
@@ -37,48 +47,77 @@ async function commonForTwo({
|
||||
'package.json': new FileBlob({
|
||||
data: JSON.stringify({
|
||||
dependencies: {
|
||||
'@zeit/ncc': '0.1.3-webpack',
|
||||
'@zeit/ncc': '0.1.12',
|
||||
},
|
||||
}),
|
||||
}),
|
||||
},
|
||||
xNccPath,
|
||||
nccPath,
|
||||
);
|
||||
|
||||
console.log('running npm install for ncc...');
|
||||
await runNpmInstall(xNccPath, preferOfflineArgument);
|
||||
return [filesOnDisk, xNccPath, entrypointFsDirname];
|
||||
await runNpmInstall(nccPath, npmArguments);
|
||||
return [downloadedFiles, userPath, nccPath, entrypointFsDirname];
|
||||
}
|
||||
|
||||
async function compile(workNccPath, input) {
|
||||
async function compile(workNccPath, downloadedFiles, entrypoint) {
|
||||
const input = downloadedFiles[entrypoint].fsPath;
|
||||
const ncc = require(path.join(workNccPath, 'node_modules/@zeit/ncc'));
|
||||
return ncc(input);
|
||||
const { code, assets } = await ncc(input);
|
||||
|
||||
const preparedFiles = {};
|
||||
const blob = new FileBlob({ data: code });
|
||||
// move all user code to 'user' subdirectory
|
||||
preparedFiles[path.join('user', entrypoint)] = blob;
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
for (const assetName of Object.keys(assets)) {
|
||||
const blob2 = new FileBlob({ data: assets[assetName] });
|
||||
preparedFiles[
|
||||
path.join('user', path.dirname(entrypoint), assetName)
|
||||
] = blob2;
|
||||
}
|
||||
|
||||
return preparedFiles;
|
||||
}
|
||||
|
||||
exports.config = {
|
||||
maxLambdaSize: '15mb',
|
||||
};
|
||||
|
||||
exports.build = async ({ files, entrypoint, workPath }) => {
|
||||
const [filesOnDisk, workNccPath, entrypointFsDirname] = await commonForTwo({
|
||||
files,
|
||||
entrypoint,
|
||||
workPath,
|
||||
});
|
||||
/**
|
||||
* @param {BuildParamsType} buildParams
|
||||
* @returns {Promise<Files>}
|
||||
*/
|
||||
exports.build = async ({
|
||||
files, entrypoint, config, workPath,
|
||||
}) => {
|
||||
const [
|
||||
downloadedFiles,
|
||||
workUserPath,
|
||||
workNccPath,
|
||||
entrypointFsDirname,
|
||||
] = await downloadInstallAndBundle(
|
||||
{ files, entrypoint, workPath },
|
||||
{ npmArguments: ['--prefer-offline'] },
|
||||
);
|
||||
|
||||
console.log('running user script...');
|
||||
await runPackageJsonScript(entrypointFsDirname, 'now-build');
|
||||
|
||||
console.log('compiling entrypoint with ncc...');
|
||||
const data = await compile(workNccPath, filesOnDisk[entrypoint].fsPath);
|
||||
const blob = new FileBlob({ data });
|
||||
|
||||
console.log('preparing lambda files...');
|
||||
// move all user code to 'user' subdirectory
|
||||
const compiledFiles = { [path.join('user', entrypoint)]: blob };
|
||||
const launcherPath = path.join(__dirname, 'launcher.js');
|
||||
let launcherData = await fsp.readFile(launcherPath, 'utf8');
|
||||
let preparedFiles;
|
||||
|
||||
if (config && config.bundle === false) {
|
||||
// move all user code to 'user' subdirectory
|
||||
preparedFiles = await glob('**', workUserPath);
|
||||
preparedFiles = rename(preparedFiles, name => path.join('user', name));
|
||||
} else {
|
||||
console.log('compiling entrypoint with ncc...');
|
||||
preparedFiles = await compile(workNccPath, downloadedFiles, entrypoint);
|
||||
}
|
||||
|
||||
const launcherPath = path.join(__dirname, 'launcher.js');
|
||||
let launcherData = await fs.readFile(launcherPath, 'utf8');
|
||||
launcherData = launcherData.replace(
|
||||
'// PLACEHOLDER',
|
||||
[
|
||||
@@ -93,7 +132,7 @@ exports.build = async ({ files, entrypoint, workPath }) => {
|
||||
};
|
||||
|
||||
const lambda = await createLambda({
|
||||
files: { ...compiledFiles, ...launcherFiles },
|
||||
files: { ...preparedFiles, ...launcherFiles },
|
||||
handler: 'launcher.launcher',
|
||||
runtime: 'nodejs8.10',
|
||||
});
|
||||
@@ -105,7 +144,7 @@ exports.prepareCache = async ({
|
||||
files, entrypoint, workPath, cachePath,
|
||||
}) => {
|
||||
await fs.remove(workPath);
|
||||
await commonForTwo({ files, entrypoint, cachePath });
|
||||
await downloadInstallAndBundle({ files, entrypoint, workPath: cachePath });
|
||||
|
||||
return {
|
||||
...(await glob('user/node_modules/**', cachePath)),
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
{
|
||||
"name": "@now/node-server",
|
||||
"version": "0.4.23-canary.3",
|
||||
"version": "0.4.24",
|
||||
"dependencies": {
|
||||
"@now/node-bridge": "^0.1.8-canary.1",
|
||||
"@now/node-bridge": "^0.1.9",
|
||||
"fs-extra": "7.0.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@now/build-utils": ">=0.0.1"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "jest"
|
||||
}
|
||||
}
|
||||
|
||||
11
packages/now-node-server/test/fixtures/01-cowsay/index.js
vendored
Normal file
11
packages/now-node-server/test/fixtures/01-cowsay/index.js
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
const cowsay = require('cowsay/build/cowsay.umd.js').say;
|
||||
const http = require('http');
|
||||
|
||||
// test that process.env is not replaced by webpack
|
||||
process.env.NODE_ENV = 'development';
|
||||
|
||||
const server = http.createServer((req, resp) => {
|
||||
resp.end(cowsay({ text: 'cow:RANDOMNESS_PLACEHOLDER' }));
|
||||
});
|
||||
|
||||
server.listen();
|
||||
11
packages/now-node-server/test/fixtures/01-cowsay/now.json
vendored
Normal file
11
packages/now-node-server/test/fixtures/01-cowsay/now.json
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"version": 2,
|
||||
"builds": [
|
||||
{ "src": "index.js", "use": "@now/node-server" },
|
||||
{ "src": "subdirectory/index.js", "use": "@now/node-server" }
|
||||
],
|
||||
"probes": [
|
||||
{ "path": "/", "mustContain": "cow:RANDOMNESS_PLACEHOLDER" },
|
||||
{ "path": "/subdirectory", "mustContain": "yoda:RANDOMNESS_PLACEHOLDER" }
|
||||
]
|
||||
}
|
||||
5
packages/now-node-server/test/fixtures/01-cowsay/package.json
vendored
Normal file
5
packages/now-node-server/test/fixtures/01-cowsay/package.json
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"cowsay": "^1.3.1"
|
||||
}
|
||||
}
|
||||
11
packages/now-node-server/test/fixtures/01-cowsay/subdirectory/index.js
vendored
Normal file
11
packages/now-node-server/test/fixtures/01-cowsay/subdirectory/index.js
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
const yodasay = require('yodasay/build/yodasay.umd.js').say;
|
||||
const http = require('http');
|
||||
|
||||
// test that process.env is not replaced by webpack
|
||||
process.env.NODE_ENV = 'development';
|
||||
|
||||
const server = http.createServer((req, resp) => {
|
||||
resp.end(yodasay({ text: 'yoda:RANDOMNESS_PLACEHOLDER' }));
|
||||
});
|
||||
|
||||
server.listen();
|
||||
5
packages/now-node-server/test/fixtures/01-cowsay/subdirectory/package.json
vendored
Normal file
5
packages/now-node-server/test/fixtures/01-cowsay/subdirectory/package.json
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"yodasay": "^1.1.6"
|
||||
}
|
||||
}
|
||||
10
packages/now-node-server/test/fixtures/03-env-vars/build-env/index.js
vendored
Normal file
10
packages/now-node-server/test/fixtures/03-env-vars/build-env/index.js
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
const assert = require('assert');
|
||||
const http = require('http');
|
||||
|
||||
const server = http.createServer((req, resp) => {
|
||||
assert(!process.env.RANDOMNESS_BUILD_ENV_VAR);
|
||||
assert(process.env.RANDOMNESS_ENV_VAR);
|
||||
resp.end('BUILD_TIME_PLACEHOLDER:build-env');
|
||||
});
|
||||
|
||||
server.listen();
|
||||
12
packages/now-node-server/test/fixtures/03-env-vars/build-env/now-build.js
vendored
Normal file
12
packages/now-node-server/test/fixtures/03-env-vars/build-env/now-build.js
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
const assert = require('assert');
|
||||
const fs = require('fs');
|
||||
|
||||
assert(process.env.RANDOMNESS_BUILD_ENV_VAR);
|
||||
assert(!process.env.RANDOMNESS_ENV_VAR);
|
||||
|
||||
fs.writeFileSync(
|
||||
'index.js',
|
||||
fs
|
||||
.readFileSync('index.js', 'utf8')
|
||||
.replace('BUILD_TIME_PLACEHOLDER', process.env.RANDOMNESS_BUILD_ENV_VAR),
|
||||
);
|
||||
5
packages/now-node-server/test/fixtures/03-env-vars/build-env/package.json
vendored
Normal file
5
packages/now-node-server/test/fixtures/03-env-vars/build-env/package.json
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"scripts": {
|
||||
"now-build": "node now-build.js"
|
||||
}
|
||||
}
|
||||
10
packages/now-node-server/test/fixtures/03-env-vars/env/index.js
vendored
Normal file
10
packages/now-node-server/test/fixtures/03-env-vars/env/index.js
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
const assert = require('assert');
|
||||
const http = require('http');
|
||||
|
||||
const server = http.createServer((req, resp) => {
|
||||
assert(!process.env.RANDOMNESS_BUILD_ENV_VAR);
|
||||
assert(process.env.RANDOMNESS_ENV_VAR);
|
||||
resp.end(`${process.env.RANDOMNESS_ENV_VAR}:env`);
|
||||
});
|
||||
|
||||
server.listen();
|
||||
11
packages/now-node-server/test/fixtures/03-env-vars/now.json
vendored
Normal file
11
packages/now-node-server/test/fixtures/03-env-vars/now.json
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"version": 2,
|
||||
"builds": [
|
||||
{ "src": "build-env/index.js", "use": "@now/node-server" },
|
||||
{ "src": "env/index.js", "use": "@now/node-server" }
|
||||
],
|
||||
"probes": [
|
||||
{ "path": "/build-env", "mustContain": "RANDOMNESS_PLACEHOLDER:build-env" },
|
||||
{ "path": "/env", "mustContain": "RANDOMNESS_PLACEHOLDER:env" }
|
||||
]
|
||||
}
|
||||
11
packages/now-node-server/test/fixtures/09-no-bundle/now.json
vendored
Normal file
11
packages/now-node-server/test/fixtures/09-no-bundle/now.json
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"version": 2,
|
||||
"builds": [
|
||||
{ "src": "with-bundle/index.js", "use": "@now/node-server" },
|
||||
{ "src": "without-bundle/index.js", "use": "@now/node-server", "config": { "bundle": false } }
|
||||
],
|
||||
"probes": [
|
||||
{ "path": "/with-bundle", "mustContain": "RANDOMNESS_PLACEHOLDER" },
|
||||
{ "path": "/without-bundle", "mustContain": "RANDOMNESS_PLACEHOLDER" }
|
||||
]
|
||||
}
|
||||
8
packages/now-node-server/test/fixtures/09-no-bundle/with-bundle/index.js
vendored
Normal file
8
packages/now-node-server/test/fixtures/09-no-bundle/with-bundle/index.js
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
const http = require('http');
|
||||
const isBundled = require('./is-bundled.js');
|
||||
|
||||
const server = http.createServer((req, resp) => {
|
||||
resp.end(isBundled() ? 'RANDOMNESS_PLACEHOLDER' : '');
|
||||
});
|
||||
|
||||
server.listen();
|
||||
3
packages/now-node-server/test/fixtures/09-no-bundle/with-bundle/is-bundled.js
vendored
Normal file
3
packages/now-node-server/test/fixtures/09-no-bundle/with-bundle/is-bundled.js
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
const path = require('path');
|
||||
|
||||
module.exports = () => path.basename(__filename) === 'index.js';
|
||||
8
packages/now-node-server/test/fixtures/09-no-bundle/without-bundle/index.js
vendored
Normal file
8
packages/now-node-server/test/fixtures/09-no-bundle/without-bundle/index.js
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
const http = require('http');
|
||||
const isBundled = require('./is-bundled.js');
|
||||
|
||||
const server = http.createServer((req, resp) => {
|
||||
resp.end(isBundled() ? '' : 'RANDOMNESS_PLACEHOLDER');
|
||||
});
|
||||
|
||||
server.listen();
|
||||
3
packages/now-node-server/test/fixtures/09-no-bundle/without-bundle/is-bundled.js
vendored
Normal file
3
packages/now-node-server/test/fixtures/09-no-bundle/without-bundle/is-bundled.js
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
const path = require('path');
|
||||
|
||||
module.exports = () => path.basename(__filename) === 'index.js';
|
||||
24
packages/now-node-server/test/fixtures/10-others/apollo/index.js
vendored
Normal file
24
packages/now-node-server/test/fixtures/10-others/apollo/index.js
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
const express = require('express');
|
||||
const { ApolloServer, gql } = require('apollo-server-express');
|
||||
|
||||
const typeDefs = gql`
|
||||
type Query {
|
||||
hello: String
|
||||
}
|
||||
`;
|
||||
|
||||
const resolvers = {
|
||||
Query: {
|
||||
hello: () => 'apollo:RANDOMNESS_PLACEHOLDER',
|
||||
},
|
||||
};
|
||||
|
||||
const server = new ApolloServer({ typeDefs, resolvers, introspection: true });
|
||||
|
||||
const app = express();
|
||||
server.applyMiddleware({ app });
|
||||
app.get('/', (req, resp) => {
|
||||
resp.redirect('/graphql');
|
||||
});
|
||||
|
||||
app.listen({ port: 4000 });
|
||||
7
packages/now-node-server/test/fixtures/10-others/apollo/package.json
vendored
Normal file
7
packages/now-node-server/test/fixtures/10-others/apollo/package.json
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"apollo-server-express": "^2.2.2",
|
||||
"express": "^4.16.4",
|
||||
"graphql": "^14.0.2"
|
||||
}
|
||||
}
|
||||
1007
packages/now-node-server/test/fixtures/10-others/apollo/yarn.lock
vendored
Normal file
1007
packages/now-node-server/test/fixtures/10-others/apollo/yarn.lock
vendored
Normal file
File diff suppressed because it is too large
Load Diff
12
packages/now-node-server/test/fixtures/10-others/now.json
vendored
Normal file
12
packages/now-node-server/test/fixtures/10-others/now.json
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"version": 2,
|
||||
"builds": [
|
||||
{ "src": "apollo/index.js", "use": "@now/node-server" }
|
||||
],
|
||||
"routes": [
|
||||
{ "src": "/.*", "dest": "apollo/index.js" }
|
||||
],
|
||||
"probes": [
|
||||
{ "path": "/graphql", "method": "POST", "body": { "query": "{hello}" }, "mustContain": "apollo:RANDOMNESS_PLACEHOLDER" }
|
||||
]
|
||||
}
|
||||
29
packages/now-node-server/test/test.js
Normal file
29
packages/now-node-server/test/test.js
Normal file
@@ -0,0 +1,29 @@
|
||||
/* global beforeAll, expect, it, jest */
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const {
|
||||
packAndDeploy,
|
||||
testDeployment,
|
||||
} = require('../../../test/lib/deployment/test-deployment.js');
|
||||
|
||||
jest.setTimeout(2 * 60 * 1000);
|
||||
let builderUrl;
|
||||
|
||||
beforeAll(async () => {
|
||||
const builderPath = path.resolve(__dirname, '..');
|
||||
builderUrl = await packAndDeploy(builderPath);
|
||||
console.log('builderUrl', builderUrl);
|
||||
});
|
||||
|
||||
const fixturesPath = path.resolve(__dirname, 'fixtures');
|
||||
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
for (const fixture of fs.readdirSync(fixturesPath)) {
|
||||
// eslint-disable-next-line no-loop-func
|
||||
it(`should build ${fixture}`, async () => {
|
||||
await expect(
|
||||
testDeployment({ builderUrl }, path.join(fixturesPath, fixture)),
|
||||
).resolves.toBe(undefined);
|
||||
});
|
||||
}
|
||||
1
packages/now-node/.npmignore
Normal file
1
packages/now-node/.npmignore
Normal file
@@ -0,0 +1 @@
|
||||
/test
|
||||
@@ -5,14 +5,11 @@ const FileFsRef = require('@now/build-utils/file-fs-ref.js');
|
||||
const fs = require('fs-extra');
|
||||
const glob = require('@now/build-utils/fs/glob.js');
|
||||
const path = require('path');
|
||||
const { promisify } = require('util');
|
||||
const {
|
||||
runNpmInstall,
|
||||
runPackageJsonScript,
|
||||
} = require('@now/build-utils/fs/run-user-scripts.js');
|
||||
|
||||
const readFile = promisify(fs.readFile);
|
||||
|
||||
/** @typedef { import('@now/build-utils/file-ref') } FileRef */
|
||||
/** @typedef {{[filePath: string]: FileRef}} Files */
|
||||
|
||||
@@ -36,7 +33,7 @@ async function downloadInstallAndBundle(
|
||||
const nccPath = path.join(workPath, 'ncc');
|
||||
|
||||
console.log('downloading user files...');
|
||||
const filesOnDisk = await download(files, userPath);
|
||||
const downloadedFiles = await download(files, userPath);
|
||||
|
||||
console.log('running npm install for user...');
|
||||
const entrypointFsDirname = path.join(userPath, path.dirname(entrypoint));
|
||||
@@ -48,7 +45,7 @@ async function downloadInstallAndBundle(
|
||||
'package.json': new FileBlob({
|
||||
data: JSON.stringify({
|
||||
dependencies: {
|
||||
'@zeit/ncc': '0.1.3-webpack',
|
||||
'@zeit/ncc': '0.1.12',
|
||||
},
|
||||
}),
|
||||
}),
|
||||
@@ -58,12 +55,27 @@ async function downloadInstallAndBundle(
|
||||
|
||||
console.log('running npm install for ncc...');
|
||||
await runNpmInstall(nccPath, npmArguments);
|
||||
return [filesOnDisk, nccPath, entrypointFsDirname];
|
||||
return [downloadedFiles, nccPath, entrypointFsDirname];
|
||||
}
|
||||
|
||||
async function compile(workNccPath, input) {
|
||||
async function compile(workNccPath, downloadedFiles, entrypoint) {
|
||||
const input = downloadedFiles[entrypoint].fsPath;
|
||||
const ncc = require(path.join(workNccPath, 'node_modules/@zeit/ncc'));
|
||||
return ncc(input);
|
||||
const { code, assets } = await ncc(input);
|
||||
|
||||
const preparedFiles = {};
|
||||
const blob = new FileBlob({ data: code });
|
||||
// move all user code to 'user' subdirectory
|
||||
preparedFiles[path.join('user', entrypoint)] = blob;
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
for (const assetName of Object.keys(assets)) {
|
||||
const blob2 = new FileBlob({ data: assets[assetName] });
|
||||
preparedFiles[
|
||||
path.join('user', path.dirname(entrypoint), assetName)
|
||||
] = blob2;
|
||||
}
|
||||
|
||||
return preparedFiles;
|
||||
}
|
||||
|
||||
exports.config = {
|
||||
@@ -76,7 +88,7 @@ exports.config = {
|
||||
*/
|
||||
exports.build = async ({ files, entrypoint, workPath }) => {
|
||||
const [
|
||||
filesOnDisk,
|
||||
downloadedFiles,
|
||||
workNccPath,
|
||||
entrypointFsDirname,
|
||||
] = await downloadInstallAndBundle(
|
||||
@@ -88,14 +100,9 @@ exports.build = async ({ files, entrypoint, workPath }) => {
|
||||
await runPackageJsonScript(entrypointFsDirname, 'now-build');
|
||||
|
||||
console.log('compiling entrypoint with ncc...');
|
||||
const data = await compile(workNccPath, filesOnDisk[entrypoint].fsPath);
|
||||
const blob = new FileBlob({ data });
|
||||
|
||||
console.log('preparing lambda files...');
|
||||
// move all user code to 'user' subdirectory
|
||||
const compiledFiles = { [path.join('user', entrypoint)]: blob };
|
||||
const preparedFiles = await compile(workNccPath, downloadedFiles, entrypoint);
|
||||
const launcherPath = path.join(__dirname, 'launcher.js');
|
||||
let launcherData = await readFile(launcherPath, 'utf8');
|
||||
let launcherData = await fs.readFile(launcherPath, 'utf8');
|
||||
|
||||
launcherData = launcherData.replace(
|
||||
'// PLACEHOLDER',
|
||||
@@ -111,7 +118,7 @@ exports.build = async ({ files, entrypoint, workPath }) => {
|
||||
};
|
||||
|
||||
const lambda = await createLambda({
|
||||
files: { ...compiledFiles, ...launcherFiles },
|
||||
files: { ...preparedFiles, ...launcherFiles },
|
||||
handler: 'launcher.launcher',
|
||||
runtime: 'nodejs8.10',
|
||||
});
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
{
|
||||
"name": "@now/node",
|
||||
"version": "0.4.25-canary.3",
|
||||
"version": "0.4.26",
|
||||
"dependencies": {
|
||||
"@now/node-bridge": "^0.1.8-canary.1",
|
||||
"@now/node-bridge": "^0.1.9",
|
||||
"fs-extra": "7.0.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@now/build-utils": ">=0.0.1"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "jest"
|
||||
}
|
||||
}
|
||||
|
||||
8
packages/now-node/test/fixtures/01-cowsay/index.js
vendored
Normal file
8
packages/now-node/test/fixtures/01-cowsay/index.js
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
const cowsay = require('cowsay/build/cowsay.umd.js').say;
|
||||
|
||||
// test that process.env is not replaced by webpack
|
||||
process.env.NODE_ENV = 'development';
|
||||
|
||||
module.exports = (req, resp) => {
|
||||
resp.end(cowsay({ text: 'cow:RANDOMNESS_PLACEHOLDER' }));
|
||||
};
|
||||
11
packages/now-node/test/fixtures/01-cowsay/now.json
vendored
Normal file
11
packages/now-node/test/fixtures/01-cowsay/now.json
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"version": 2,
|
||||
"builds": [
|
||||
{ "src": "index.js", "use": "@now/node" },
|
||||
{ "src": "subdirectory/index.js", "use": "@now/node" }
|
||||
],
|
||||
"probes": [
|
||||
{ "path": "/", "mustContain": "cow:RANDOMNESS_PLACEHOLDER" },
|
||||
{ "path": "/subdirectory", "mustContain": "yoda:RANDOMNESS_PLACEHOLDER" }
|
||||
]
|
||||
}
|
||||
5
packages/now-node/test/fixtures/01-cowsay/package.json
vendored
Normal file
5
packages/now-node/test/fixtures/01-cowsay/package.json
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"cowsay": "^1.3.1"
|
||||
}
|
||||
}
|
||||
8
packages/now-node/test/fixtures/01-cowsay/subdirectory/index.js
vendored
Normal file
8
packages/now-node/test/fixtures/01-cowsay/subdirectory/index.js
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
const yodasay = require('yodasay/build/yodasay.umd.js').say;
|
||||
|
||||
// test that process.env is not replaced by webpack
|
||||
process.env.NODE_ENV = 'development';
|
||||
|
||||
module.exports = (req, resp) => {
|
||||
resp.end(yodasay({ text: 'yoda:RANDOMNESS_PLACEHOLDER' }));
|
||||
};
|
||||
5
packages/now-node/test/fixtures/01-cowsay/subdirectory/package.json
vendored
Normal file
5
packages/now-node/test/fixtures/01-cowsay/subdirectory/package.json
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"yodasay": "^1.1.6"
|
||||
}
|
||||
}
|
||||
7
packages/now-node/test/fixtures/03-env-vars/build-env/index.js
vendored
Normal file
7
packages/now-node/test/fixtures/03-env-vars/build-env/index.js
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
const assert = require('assert');
|
||||
|
||||
module.exports = (req, resp) => {
|
||||
assert(!process.env.RANDOMNESS_BUILD_ENV_VAR);
|
||||
assert(process.env.RANDOMNESS_ENV_VAR);
|
||||
resp.end('BUILD_TIME_PLACEHOLDER:build-env');
|
||||
};
|
||||
12
packages/now-node/test/fixtures/03-env-vars/build-env/now-build.js
vendored
Normal file
12
packages/now-node/test/fixtures/03-env-vars/build-env/now-build.js
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
const assert = require('assert');
|
||||
const fs = require('fs');
|
||||
|
||||
assert(process.env.RANDOMNESS_BUILD_ENV_VAR);
|
||||
assert(!process.env.RANDOMNESS_ENV_VAR);
|
||||
|
||||
fs.writeFileSync(
|
||||
'index.js',
|
||||
fs
|
||||
.readFileSync('index.js', 'utf8')
|
||||
.replace('BUILD_TIME_PLACEHOLDER', process.env.RANDOMNESS_BUILD_ENV_VAR),
|
||||
);
|
||||
5
packages/now-node/test/fixtures/03-env-vars/build-env/package.json
vendored
Normal file
5
packages/now-node/test/fixtures/03-env-vars/build-env/package.json
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"scripts": {
|
||||
"now-build": "node now-build.js"
|
||||
}
|
||||
}
|
||||
7
packages/now-node/test/fixtures/03-env-vars/env/index.js
vendored
Normal file
7
packages/now-node/test/fixtures/03-env-vars/env/index.js
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
const assert = require('assert');
|
||||
|
||||
module.exports = (req, resp) => {
|
||||
assert(!process.env.RANDOMNESS_BUILD_ENV_VAR);
|
||||
assert(process.env.RANDOMNESS_ENV_VAR);
|
||||
resp.end(`${process.env.RANDOMNESS_ENV_VAR}:env`);
|
||||
};
|
||||
11
packages/now-node/test/fixtures/03-env-vars/now.json
vendored
Normal file
11
packages/now-node/test/fixtures/03-env-vars/now.json
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"version": 2,
|
||||
"builds": [
|
||||
{ "src": "build-env/index.js", "use": "@now/node" },
|
||||
{ "src": "env/index.js", "use": "@now/node" }
|
||||
],
|
||||
"probes": [
|
||||
{ "path": "/build-env", "mustContain": "RANDOMNESS_PLACEHOLDER:build-env" },
|
||||
{ "path": "/env", "mustContain": "RANDOMNESS_PLACEHOLDER:env" }
|
||||
]
|
||||
}
|
||||
29
packages/now-node/test/test.js
Normal file
29
packages/now-node/test/test.js
Normal file
@@ -0,0 +1,29 @@
|
||||
/* global beforeAll, expect, it, jest */
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const {
|
||||
packAndDeploy,
|
||||
testDeployment,
|
||||
} = require('../../../test/lib/deployment/test-deployment.js');
|
||||
|
||||
jest.setTimeout(2 * 60 * 1000);
|
||||
let builderUrl;
|
||||
|
||||
beforeAll(async () => {
|
||||
const builderPath = path.resolve(__dirname, '..');
|
||||
builderUrl = await packAndDeploy(builderPath);
|
||||
console.log('builderUrl', builderUrl);
|
||||
});
|
||||
|
||||
const fixturesPath = path.resolve(__dirname, 'fixtures');
|
||||
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
for (const fixture of fs.readdirSync(fixturesPath)) {
|
||||
// eslint-disable-next-line no-loop-func
|
||||
it(`should build ${fixture}`, async () => {
|
||||
await expect(
|
||||
testDeployment({ builderUrl }, path.join(fixturesPath, fixture)),
|
||||
).resolves.toBe(undefined);
|
||||
});
|
||||
}
|
||||
@@ -6,7 +6,10 @@ exports.analyze = ({ files, entrypoint }) => files[entrypoint].digest;
|
||||
|
||||
exports.build = async ({ files, entrypoint }) => {
|
||||
const optimizer = new OptiPng(['-o9']);
|
||||
const stream = pipe(files[entrypoint].toStream(), optimizer);
|
||||
const stream = pipe(
|
||||
files[entrypoint].toStream(),
|
||||
optimizer,
|
||||
);
|
||||
const result = await FileBlob.fromStream({ stream });
|
||||
return { [entrypoint]: result };
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@now/optipng",
|
||||
"version": "0.4.6-canary.0",
|
||||
"version": "0.4.7",
|
||||
"dependencies": {
|
||||
"multipipe": "2.0.3",
|
||||
"optipng": "1.1.0"
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
/launcher
|
||||
/test
|
||||
|
||||
BIN
packages/now-php/dist/launcher
vendored
BIN
packages/now-php/dist/launcher
vendored
Binary file not shown.
@@ -5,7 +5,6 @@ import (
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os"
|
||||
"path"
|
||||
@@ -100,6 +99,5 @@ func main() {
|
||||
ex, _ := os.Executable()
|
||||
phpScript = os.Getenv("NOW_PHP_SCRIPT")
|
||||
phpScriptFull = path.Join(filepath.Dir(ex), phpScript)
|
||||
fmt.Printf("phpScriptFull %s\n", phpScriptFull)
|
||||
lambda.Start(handler)
|
||||
}
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
{
|
||||
"name": "@now/php",
|
||||
"version": "0.4.10-canary.1",
|
||||
"version": "0.4.11",
|
||||
"peerDependencies": {
|
||||
"@now/build-utils": ">=0.0.1"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "jest"
|
||||
}
|
||||
}
|
||||
|
||||
3
packages/now-php/test/fixtures/01-cowsay/index.php
vendored
Normal file
3
packages/now-php/test/fixtures/01-cowsay/index.php
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
<?php
|
||||
print "cow:RANDOMNESS_PLACEHOLDER";
|
||||
?>
|
||||
11
packages/now-php/test/fixtures/01-cowsay/now.json
vendored
Normal file
11
packages/now-php/test/fixtures/01-cowsay/now.json
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"version": 2,
|
||||
"builds": [
|
||||
{ "src": "index.php", "use": "@now/php" },
|
||||
{ "src": "subdirectory/index.php", "use": "@now/php" }
|
||||
],
|
||||
"probes": [
|
||||
{ "path": "/", "mustContain": "cow:RANDOMNESS_PLACEHOLDER" },
|
||||
{ "path": "/subdirectory", "mustContain": "yoda:RANDOMNESS_PLACEHOLDER" }
|
||||
]
|
||||
}
|
||||
3
packages/now-php/test/fixtures/01-cowsay/subdirectory/index.php
vendored
Normal file
3
packages/now-php/test/fixtures/01-cowsay/subdirectory/index.php
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
<?php
|
||||
print "yoda:RANDOMNESS_PLACEHOLDER";
|
||||
?>
|
||||
3
packages/now-php/test/fixtures/03-env-vars/env/index.php
vendored
Normal file
3
packages/now-php/test/fixtures/03-env-vars/env/index.php
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
<?php
|
||||
print $_ENV["RANDOMNESS_ENV_VAR"] . ":env";
|
||||
?>
|
||||
9
packages/now-php/test/fixtures/03-env-vars/now.json
vendored
Normal file
9
packages/now-php/test/fixtures/03-env-vars/now.json
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"version": 2,
|
||||
"builds": [
|
||||
{ "src": "env/index.php", "use": "@now/php" }
|
||||
],
|
||||
"probes": [
|
||||
{ "path": "/env", "mustContain": "RANDOMNESS_PLACEHOLDER:env" }
|
||||
]
|
||||
}
|
||||
29
packages/now-php/test/test.js
Normal file
29
packages/now-php/test/test.js
Normal file
@@ -0,0 +1,29 @@
|
||||
/* global beforeAll, expect, it, jest */
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const {
|
||||
packAndDeploy,
|
||||
testDeployment,
|
||||
} = require('../../../test/lib/deployment/test-deployment.js');
|
||||
|
||||
jest.setTimeout(2 * 60 * 1000);
|
||||
let builderUrl;
|
||||
|
||||
beforeAll(async () => {
|
||||
const builderPath = path.resolve(__dirname, '..');
|
||||
builderUrl = await packAndDeploy(builderPath);
|
||||
console.log('builderUrl', builderUrl);
|
||||
});
|
||||
|
||||
const fixturesPath = path.resolve(__dirname, 'fixtures');
|
||||
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
for (const fixture of fs.readdirSync(fixturesPath)) {
|
||||
// eslint-disable-next-line no-loop-func
|
||||
it(`should build ${fixture}`, async () => {
|
||||
await expect(
|
||||
testDeployment({ builderUrl }, path.join(fixturesPath, fixture)),
|
||||
).resolves.toBe(undefined);
|
||||
});
|
||||
}
|
||||
@@ -37,7 +37,9 @@ async function downloadAndInstallPip() {
|
||||
// installed to. `--user` will assume `~` if this
|
||||
// is not set, and `~` is not writeable on AWS Lambda.
|
||||
// let's refuse to proceed
|
||||
throw new Error('Could not install "pip": "PYTHONUSERBASE" env var is not set');
|
||||
throw new Error(
|
||||
'Could not install "pip": "PYTHONUSERBASE" env var is not set',
|
||||
);
|
||||
}
|
||||
const getPipFilePath = await downloadGetPipScript();
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@now/python",
|
||||
"version": "0.0.39-canary.1",
|
||||
"version": "0.0.40",
|
||||
"main": "index.js",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
|
||||
1
packages/now-static-build/.npmignore
Normal file
1
packages/now-static-build/.npmignore
Normal file
@@ -0,0 +1 @@
|
||||
/test
|
||||
@@ -2,7 +2,9 @@ const download = require('@now/build-utils/fs/download.js');
|
||||
const glob = require('@now/build-utils/fs/glob.js');
|
||||
const path = require('path');
|
||||
const {
|
||||
runNpmInstall, runPackageJsonScript, runShellScript,
|
||||
runNpmInstall,
|
||||
runPackageJsonScript,
|
||||
runShellScript,
|
||||
} = require('@now/build-utils/fs/run-user-scripts.js');
|
||||
|
||||
exports.build = async ({
|
||||
@@ -32,5 +34,5 @@ exports.build = async ({
|
||||
return glob('**', distPath, mountpoint);
|
||||
}
|
||||
|
||||
return {};
|
||||
throw new Error('Proper build script must be specified as entrypoint');
|
||||
};
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
{
|
||||
"name": "@now/static-build",
|
||||
"version": "0.4.14-canary.0",
|
||||
"version": "0.4.15",
|
||||
"peerDependencies": {
|
||||
"@now/build-utils": ">=0.0.1"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "jest"
|
||||
}
|
||||
}
|
||||
|
||||
11
packages/now-static-build/test/fixtures/01-cowsay/now.json
vendored
Normal file
11
packages/now-static-build/test/fixtures/01-cowsay/now.json
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"version": 2,
|
||||
"builds": [
|
||||
{ "src": "package.json", "use": "@now/static-build" },
|
||||
{ "src": "subdirectory/package.json", "use": "@now/static-build" }
|
||||
],
|
||||
"probes": [
|
||||
{ "path": "/", "mustContain": "cow:RANDOMNESS_PLACEHOLDER" },
|
||||
{ "path": "/subdirectory", "mustContain": "yoda:RANDOMNESS_PLACEHOLDER" }
|
||||
]
|
||||
}
|
||||
8
packages/now-static-build/test/fixtures/01-cowsay/package.json
vendored
Normal file
8
packages/now-static-build/test/fixtures/01-cowsay/package.json
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"cowsay": "^1.3.1"
|
||||
},
|
||||
"scripts": {
|
||||
"now-build": "mkdir dist && cowsay cow:RANDOMNESS_PLACEHOLDER > dist/index.txt"
|
||||
}
|
||||
}
|
||||
8
packages/now-static-build/test/fixtures/01-cowsay/subdirectory/package.json
vendored
Normal file
8
packages/now-static-build/test/fixtures/01-cowsay/subdirectory/package.json
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"yodasay": "^1.1.6"
|
||||
},
|
||||
"scripts": {
|
||||
"now-build": "mkdir dist && yodasay yoda:RANDOMNESS_PLACEHOLDER > dist/index.txt"
|
||||
}
|
||||
}
|
||||
11
packages/now-static-build/test/fixtures/02-cowsay-sh/now.json
vendored
Normal file
11
packages/now-static-build/test/fixtures/02-cowsay-sh/now.json
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"version": 2,
|
||||
"builds": [
|
||||
{ "src": "some-build.sh", "use": "@now/static-build" },
|
||||
{ "src": "subdirectory/some-build.sh", "use": "@now/static-build" }
|
||||
],
|
||||
"probes": [
|
||||
{ "path": "/", "mustContain": "cow:RANDOMNESS_PLACEHOLDER" },
|
||||
{ "path": "/subdirectory", "mustContain": "yoda:RANDOMNESS_PLACEHOLDER" }
|
||||
]
|
||||
}
|
||||
5
packages/now-static-build/test/fixtures/02-cowsay-sh/package.json
vendored
Normal file
5
packages/now-static-build/test/fixtures/02-cowsay-sh/package.json
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"cowsay": "^1.3.1"
|
||||
}
|
||||
}
|
||||
3
packages/now-static-build/test/fixtures/02-cowsay-sh/some-build.sh
vendored
Normal file
3
packages/now-static-build/test/fixtures/02-cowsay-sh/some-build.sh
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
yarn install
|
||||
mkdir dist
|
||||
./node_modules/.bin/cowsay cow:RANDOMNESS_PLACEHOLDER > dist/index.txt
|
||||
5
packages/now-static-build/test/fixtures/02-cowsay-sh/subdirectory/package.json
vendored
Normal file
5
packages/now-static-build/test/fixtures/02-cowsay-sh/subdirectory/package.json
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"yodasay": "^1.1.6"
|
||||
}
|
||||
}
|
||||
3
packages/now-static-build/test/fixtures/02-cowsay-sh/subdirectory/some-build.sh
vendored
Normal file
3
packages/now-static-build/test/fixtures/02-cowsay-sh/subdirectory/some-build.sh
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
yarn install
|
||||
mkdir dist
|
||||
./node_modules/.bin/yodasay yoda:RANDOMNESS_PLACEHOLDER > dist/index.txt
|
||||
10
packages/now-static-build/test/fixtures/03-env-vars/build-env/now-build.js
vendored
Normal file
10
packages/now-static-build/test/fixtures/03-env-vars/build-env/now-build.js
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
const assert = require('assert');
|
||||
const fs = require('fs');
|
||||
|
||||
assert(process.env.RANDOMNESS_BUILD_ENV_VAR);
|
||||
assert(!process.env.RANDOMNESS_ENV_VAR);
|
||||
|
||||
fs.writeFileSync(
|
||||
'dist/index.html',
|
||||
`${process.env.RANDOMNESS_BUILD_ENV_VAR}:build-env`,
|
||||
);
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user