Compare commits

...

27 Commits

Author SHA1 Message Date
Steven
e2f91094bc Publish
- @now/bash@0.2.3
 - @now/build-utils@0.5.4
 - @now/cgi@0.1.3
 - @now/go@0.4.5
 - @now/html-minifier@1.1.3
 - @now/lambda@0.5.3
 - @now/md@0.5.3
 - @now/mdx-deck@0.5.3
 - @now/next@0.3.1
 - @now/node-bridge@1.1.2
 - @now/node-server@0.7.1
 - @now/node@0.7.1
 - @now/optipng@0.6.1
 - @now/php-bridge@0.5.2
 - @now/php@0.5.3
 - @now/python@0.2.1
 - @now/rust@0.2.3
 - @now/static-build@0.5.5
 - @now/wordpress@0.5.2
2019-05-07 07:09:50 -04:00
Steven
38dba57378 Bump stable version 2019-05-07 07:00:57 -04:00
Nathan Rajlich
be6a6ba1d7 Publish
- @now/build-utils@0.5.2-canary.2
 - @now/next@0.2.1-canary.1
2019-05-06 17:07:12 -07:00
Nathan Rajlich
31fb5d9ec8 [now-next] Sync runtime env vars in dev server after app.prepare() (#467)
* [now-next] Sync runtime env vars in dev server after `app.prepare()`

* Update packages/now-next/src/index.ts

Co-Authored-By: TooTallNate <n@n8.io>

* Update packages/now-next/src/index.ts

Co-Authored-By: TooTallNate <n@n8.io>

* Add `syncEnvVars()` helper function for common logic
2019-05-06 16:43:20 -07:00
Joe Haddad
6c8f946a48 [now-build-utils] Remove mutable option and add sha+ephemeral scheme (#466)
Co-Authored-By: Steven <steven@ceriously.com>

* Add an ephemeral option for files

* Use array destructuring

Co-Authored-By: Timer <joe.haddad@zeit.co>

* Remove mutable option

* Remove code all together

* Introduce `sha+ephemeral` handling

* http => https

* Elaborate more on the cloudfront url

* Update comment a bit more

* Add comment explaining other url
2019-05-06 19:12:39 -04:00
Steven
d59e1b9789 Publish
- @now/build-utils@0.5.2-canary.1
 - @now/go@0.4.3-canary.1
2019-05-06 08:47:35 -04:00
Steven
2852d3fbc3 [now-build-utils] Add yarn --ignore-engines during install (#463) 2019-05-05 22:57:37 -04:00
Sophearak Tha
d0292eb751 Improve go checking in user dev machine (#460) 2019-05-06 09:11:24 +07:00
Steven
17bbf69346 Publish
- @now/node-server@0.6.1-canary.2
 - @now/python@0.1.1-canary.2
2019-05-03 19:48:26 -04:00
Steven
4fb4229c90 Remove python/pip installer (#459)
* Remove python/pip installer

* Add back PYTHONUSERBASE env var
2019-05-03 19:46:47 -04:00
Steven
03b7586b50 [now-node-server] Fix unit tests 2019-05-03 14:09:45 -04:00
Mickaël Allonneau
a1427866ca [now-node-server] 'config.includeFiles' accepts a string (#442)
* 1st try (fails)

* 2nd try (fails)

* 3rd try (fails)

* 4th try (fail)
2019-05-03 13:54:33 -04:00
Nathan Rajlich
5f787b8146 Publish
- @now/bash@0.2.1-canary.0
 - @now/cgi@0.1.1-canary.0
 - @now/html-minifier@1.1.1-canary.0
 - @now/lambda@0.5.1-canary.0
 - @now/md@0.5.1-canary.0
 - @now/node-server@0.6.1-canary.1
 - @now/node@0.6.1-canary.2
 - @now/optipng@0.5.1-canary.0
 - @now/php@0.5.1-canary.0
 - @now/python@0.1.1-canary.1
 - @now/rust@0.2.1-canary.0
2019-05-02 15:21:06 -07:00
Nathan Rajlich
b03405a665 Add default shouldServe() to appropriate builders (#456)
This adds the default `shouldServe()` implementation to the following
builders:

 * `@now/bash`
 * `@now/cgi`
 * `@now/html-minifier`
 * `@now/lambda`
 * `@now/md`
 * `@now/node-server`
 * `@now/node`
 * `@now/optipng`
 * `@now/php`
 * `@now/python`
 * `@now/rust`

The default implementation may be used for these builders because
they map 1-1 with their entrypoint file -> output file/lambda.
2019-05-02 15:09:58 -07:00
Steven
4393dad15a Publish
- @now/node@0.6.1-canary.1
 - @now/static-build@0.5.3-canary.1
2019-05-02 16:07:38 -04:00
Marios Antonoudiou
b4d604b2e9 [now-static-build] Fix @now/static-build nested build (#452) 2019-05-02 15:15:40 -04:00
Mickaël Allonneau
5fb6e5c0ba [now-node] 'config.includeFiles' accepts a string (#441) 2019-05-02 14:26:35 -04:00
Steven
9d7dd3a713 Publish
- @now/python@0.1.1-canary.0
2019-05-02 11:32:59 -04:00
Steven
4f867b320d [now-python] Upgrade build env to python3.6 (#450)
* [now-python] Upgarde build env to python3.6

* Add support for isDev
2019-05-02 11:00:39 -04:00
Nathan Rajlich
c153690104 Publish
- @now/build-utils@0.5.2-canary.0
 - @now/go@0.4.3-canary.0
 - @now/next@0.2.1-canary.0
 - @now/static-build@0.5.3-canary.0
2019-05-01 23:34:18 -07:00
Nathan Rajlich
8c1b96edf7 [now-build-utils] Use cross-spawn for Windows support (#449) 2019-05-01 23:26:20 -07:00
Carlos Alexandro Becker
15c83a69f7 [now-go] Add support for config.includeFiles (#447) 2019-05-01 17:39:53 -04:00
Steven
0986de85ee [now-static-build] Warn when now-dev script is missing (#443)
* Warn when now-dev script is missing

* Add link to local dev docs

* Update packages/now-static-build/index.js

Co-Authored-By: styfle <steven@ceriously.com>

* Fix url
2019-05-01 17:32:50 -04:00
Leo Lamprecht
94c5d83ccc Copy the entire process environment to child (#448)
* Copy the entire process environment to child

* Removed lockfile

* Removed useless code

* Add comment
2019-05-01 22:26:35 +02:00
Steven
ff49b9d32d Publish
- @now/node-server@0.6.1-canary.0
 - @now/node@0.6.1-canary.0
2019-05-01 14:20:43 -04:00
Steven
ec5290dab1 [node-node] Bump ncc to 0.18.2 (#446) 2019-05-01 12:19:43 -04:00
Steven
4f758ec84e Create CODE_OF_CONDUCT.md (#444) 2019-05-01 09:04:34 -04:00
52 changed files with 524 additions and 229 deletions

74
CODE_OF_CONDUCT.md Normal file
View File

@@ -0,0 +1,74 @@
## Code of Conduct
### Our Pledge
In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, gender identity and expression, level of experience,
nationality, personal appearance, race, religion, or sexual identity and
orientation.
### Our Standards
Examples of behavior that contributes to creating a positive environment
include:
- Using welcoming and inclusive language
- Being respectful of differing viewpoints and experiences
- Gracefully accepting constructive criticism
- Focusing on what is best for the community
- Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
- The use of sexualized language or imagery and unwelcome sexual attention or
advances
- Trolling, insulting/derogatory comments, and personal or political attacks
- Public or private harassment
- Publishing others' private information, such as a physical or electronic
address, without explicit permission
- Other conduct which could reasonably be considered inappropriate in a
professional setting
### Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.
### Scope
This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers.
### Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at [abuse@zeit.co](mailto:abuse@zeit.co). All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.
Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.
### Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
available at [http://contributor-covenant.org/version/1/4][version]
[homepage]: http://contributor-covenant.org
[version]: http://contributor-covenant.org/version/1/4/

View File

@@ -1,10 +1,13 @@
const execa = require('execa');
const { join } = require('path');
const snakeCase = require('snake-case');
const glob = require('@now/build-utils/fs/glob'); // eslint-disable-line import/no-extraneous-dependencies
const download = require('@now/build-utils/fs/download'); // eslint-disable-line import/no-extraneous-dependencies
const { createLambda } = require('@now/build-utils/lambda'); // eslint-disable-line import/no-extraneous-dependencies
const getWritableDirectory = require('@now/build-utils/fs/get-writable-directory'); // eslint-disable-line import/no-extraneous-dependencies
const {
glob,
download,
createLambda,
getWriteableDirectory,
shouldServe,
} = require('@now/build-utils'); // eslint-disable-line import/no-extraneous-dependencies
exports.config = {
maxLambdaSize: '10mb',
@@ -15,7 +18,7 @@ exports.analyze = ({ files, entrypoint }) => files[entrypoint].digest;
exports.build = async ({
workPath, files, entrypoint, config,
}) => {
const srcDir = await getWritableDirectory();
const srcDir = await getWriteableDirectory();
console.log('downloading files...');
await download(files, srcDir);
@@ -55,3 +58,5 @@ exports.build = async ({
[entrypoint]: lambda,
};
};
exports.shouldServe = shouldServe;

View File

@@ -1,6 +1,6 @@
{
"name": "@now/bash",
"version": "0.2.0",
"version": "0.2.3",
"description": "Now 2.0 builder for HTTP endpoints written in Bash",
"main": "index.js",
"author": "Nathan Rajlich <nate@zeit.co>",

View File

@@ -1,6 +1,6 @@
{
"name": "@now/build-utils",
"version": "0.5.1",
"version": "0.5.4",
"license": "MIT",
"main": "./dist/index.js",
"types": "./dist/index.d.js",
@@ -10,8 +10,10 @@
"directory": "packages/now-build-utils"
},
"dependencies": {
"@types/cross-spawn": "6.0.0",
"async-retry": "1.2.3",
"async-sema": "2.1.4",
"cross-spawn": "6.0.5",
"end-of-stream": "1.4.1",
"fs-extra": "7.0.0",
"glob": "7.1.3",

View File

@@ -8,7 +8,6 @@ import { File } from './types';
interface FileRefOptions {
mode?: number;
digest: string;
mutable?: boolean;
}
const semaToDownloadFromS3 = new Sema(5);
@@ -26,26 +25,29 @@ export default class FileRef implements File {
public type: 'FileRef';
public mode: number;
public digest: string;
public mutable: boolean;
constructor({ mode = 0o100644, digest, mutable = false }: FileRefOptions) {
constructor({ mode = 0o100644, digest }: FileRefOptions) {
assert(typeof mode === 'number');
assert(typeof digest === 'string');
assert(typeof mutable === 'boolean');
this.type = 'FileRef';
this.mode = mode;
this.digest = digest;
this.mutable = mutable;
}
async toStreamAsync(): Promise<NodeJS.ReadableStream> {
let url = '';
// sha:24be087eef9fac01d61b30a725c1a10d7b45a256
const digestParts = this.digest.split(':');
if (digestParts[0] === 'sha') {
url = this.mutable
? `https://s3.amazonaws.com/now-files/${digestParts[1]}`
: `https://dmmcy0pwk6bqi.cloudfront.net/${digestParts[1]}`;
const [digestType, digestHash] = this.digest.split(':');
if (digestType === 'sha') {
// This CloudFront URL edge caches the `now-files` S3 bucket to prevent
// overloading it
// `https://now-files.s3.amazonaws.com/${digestHash}`
url = `https://dmmcy0pwk6bqi.cloudfront.net/${digestHash}`;
} else if (digestType === 'sha+ephemeral') {
// This URL is currently only used for cache files that constantly
// change. We shouldn't cache it on CloudFront because it'd always be a
// MISS.
url = `https://now-ephemeral-files.s3.amazonaws.com/${digestHash}`;
} else {
throw new Error('Expected digest to be sha');
}
@@ -58,14 +60,14 @@ export default class FileRef implements File {
const resp = await fetch(url);
if (!resp.ok) {
const error = new BailableError(
`download: ${resp.status} ${resp.statusText} for ${url}`,
`download: ${resp.status} ${resp.statusText} for ${url}`
);
if (resp.status === 403) error.bail = true;
throw error;
}
return resp.body;
},
{ factor: 1, retries: 3 },
{ factor: 1, retries: 3 }
);
} finally {
// console.timeEnd(`downloading ${url}`);
@@ -77,15 +79,15 @@ export default class FileRef implements File {
let flag = false;
// eslint-disable-next-line consistent-return
return multiStream((cb) => {
return multiStream(cb => {
if (flag) return cb(null, null);
flag = true;
this.toStreamAsync()
.then((stream) => {
.then(stream => {
cb(null, stream);
})
.catch((error) => {
.catch(error => {
cb(error, null);
});
});

View File

@@ -1,22 +1,28 @@
import assert from 'assert';
import fs from 'fs-extra';
import path from 'path';
import { spawn, SpawnOptions } from 'child_process';
import spawn from 'cross-spawn';
import { SpawnOptions } from 'child_process';
function spawnAsync(command: string, args: string[], cwd: string, opts: SpawnOptions = {}) {
function spawnAsync(
command: string,
args: string[],
cwd: string,
opts: SpawnOptions = {}
) {
return new Promise<void>((resolve, reject) => {
const stderrLogs: Buffer[] = []
const stderrLogs: Buffer[] = [];
opts = { stdio: 'inherit', cwd, ...opts };
const child = spawn(command, args, opts);
if (opts.stdio === 'pipe'){
if (opts.stdio === 'pipe') {
child.stderr.on('data', data => stderrLogs.push(data));
}
child.on('error', reject);
child.on('close', (code, signal) => {
if (code === 0) {
return resolve()
return resolve();
}
const errorLogs = stderrLogs.map(line => line.toString()).join('');
@@ -58,13 +64,15 @@ async function scanParentDirs(destPath: string, scriptName?: string) {
// eslint-disable-next-line no-await-in-loop
if (await fs.pathExists(packageJsonPath)) {
// eslint-disable-next-line no-await-in-loop
const packageJson = JSON.parse(await fs.readFile(packageJsonPath, 'utf8'));
const packageJson = JSON.parse(
await fs.readFile(packageJsonPath, 'utf8')
);
hasScript = Boolean(
packageJson.scripts && scriptName && packageJson.scripts[scriptName],
packageJson.scripts && scriptName && packageJson.scripts[scriptName]
);
// eslint-disable-next-line no-await-in-loop
hasPackageLockJson = await fs.pathExists(
path.join(currentDestPath, 'package-lock.json'),
path.join(currentDestPath, 'package-lock.json')
);
break;
}
@@ -77,7 +85,10 @@ async function scanParentDirs(destPath: string, scriptName?: string) {
return { hasScript, hasPackageLockJson };
}
export async function installDependencies(destPath: string, args: string[] = []) {
export async function installDependencies(
destPath: string,
args: string[] = []
) {
assert(path.isAbsolute(destPath));
let commandArgs = args;
@@ -91,7 +102,7 @@ export async function installDependencies(destPath: string, args: string[] = [])
// Node.js version that `@now/node` and `@now/node-server` use
npm_config_target: '8.10.0',
},
stdio: 'pipe'
stdio: 'pipe',
};
if (hasPackageLockJson) {
@@ -105,9 +116,9 @@ export async function installDependencies(destPath: string, args: string[] = [])
} else {
await spawnAsync(
'yarn',
['--cwd', destPath].concat(commandArgs),
['--ignore-engines', '--cwd', destPath].concat(commandArgs),
destPath,
opts as SpawnOptions,
opts as SpawnOptions
);
}
}
@@ -120,7 +131,7 @@ export async function runPackageJsonScript(
assert(path.isAbsolute(destPath));
const { hasScript, hasPackageLockJson } = await scanParentDirs(
destPath,
scriptName,
scriptName
);
if (!hasScript) return false;
@@ -129,7 +140,12 @@ export async function runPackageJsonScript(
await spawnAsync('npm', ['run', scriptName], destPath, opts);
} else {
console.log(`running "yarn run ${scriptName}"`);
await spawnAsync('yarn', ['--cwd', destPath, 'run', scriptName], destPath, opts);
await spawnAsync(
'yarn',
['--cwd', destPath, 'run', scriptName],
destPath,
opts
);
}
return true;

View File

@@ -0,0 +1,9 @@
const scheduler = require('@google-cloud/scheduler');
module.exports = (_, res) => {
if (scheduler) {
res.end('found:RANDOMNESS_PLACEHOLDER');
} else {
res.end('nope:RANDOMNESS_PLACEHOLDER');
}
};

View File

@@ -0,0 +1,10 @@
{
"version": 2,
"builds": [
{ "src": "index.js", "use": "@now/node", "config": { "maxLambdaSize": "15mb" } }
],
"probes": [
{ "path": "/", "mustContain": "found:RANDOMNESS_PLACEHOLDER" }
]
}

View File

@@ -0,0 +1,8 @@
{
"name": "15-yarn-ignore-engines",
"version": "1.0.0",
"main": "index.js",
"dependencies": {
"@google-cloud/scheduler": "0.3.0"
}
}

View File

@@ -5,6 +5,7 @@ const glob = require('@now/build-utils/fs/glob'); // eslint-disable-line import/
const download = require('@now/build-utils/fs/download'); // eslint-disable-line import/no-extraneous-dependencies
const { createLambda } = require('@now/build-utils/lambda'); // eslint-disable-line import/no-extraneous-dependencies
const getWritableDirectory = require('@now/build-utils/fs/get-writable-directory'); // eslint-disable-line import/no-extraneous-dependencies
const { shouldServe } = require('@now/build-utils'); // eslint-disable-line import/no-extraneous-dependencies
exports.analyze = ({ files, entrypoint }) => files[entrypoint].digest;
@@ -40,3 +41,5 @@ exports.build = async ({ files, entrypoint }) => {
[entrypoint]: lambda,
};
};
exports.shouldServe = shouldServe;

View File

@@ -1,6 +1,6 @@
{
"name": "@now/cgi",
"version": "0.1.0",
"version": "0.1.3",
"license": "MIT",
"repository": {
"type": "git",

View File

@@ -3,6 +3,7 @@ import execa from 'execa';
import fetch from 'node-fetch';
import { mkdirp, pathExists } from 'fs-extra';
import { dirname, join } from 'path';
import { homedir } from 'os';
import Debug from 'debug';
const debug = Debug('@now/go:go-helpers');
@@ -118,16 +119,25 @@ export async function downloadGo(
platform = process.platform,
arch = process.arch
) {
debug('Installing `go` v%s to %o for %s %s', version, dir, platform, arch);
// Check default `Go` in user machine
const isUserGo = await pathExists(join(homedir(), 'go'));
const url = getGoUrl(version, platform, arch);
// if we found GOPATH in ENV, use it
if (process.env.GOPATH !== undefined) {
// If we found GOPATH in ENV, or default `Go` path exists
// asssume that user have `Go` installed
if (isUserGo || process.env.GOPATH !== undefined) {
return createGo(dir, platform, arch);
} else {
// Check `Go` bin in builder CWD
const isGoExist = await pathExists(join(dir, 'bin'));
if (!isGoExist) {
debug(
'Installing `go` v%s to %o for %s %s',
version,
dir,
platform,
arch
);
const url = getGoUrl(version, platform, arch);
debug('Downloading `go` URL: %o', url);
console.log('Downloading Go ...');
const res = await fetch(url);

View File

@@ -47,6 +47,7 @@ export async function build({
getWriteableDirectory(),
getWriteableDirectory(),
]);
if (meta.isDev) {
const devGoPath = `dev${entrypointArr[entrypointArr.length - 1]}`;
const goPathArr = goPath.split(sep);
@@ -57,6 +58,17 @@ export async function build({
const srcPath = join(goPath, 'src', 'lambda');
const downloadedFiles = await download(files, srcPath);
const input = dirname(downloadedFiles[entrypoint].fsPath);
var includedFiles: Files = {};
if (config && config.includeFiles) {
for (const pattern of config.includeFiles) {
const files = await glob(pattern, input);
for (const assetName of Object.keys(files)) {
includedFiles[assetName] = files[assetName];
}
}
}
console.log(`Parsing AST for "${entrypoint}"`);
let analyzed: string;
@@ -264,7 +276,7 @@ export async function build({
}
const lambda = await createLambda({
files: await glob('**', outDir),
files: { ...(await glob('**', outDir)), ...includedFiles },
handler: 'handler',
runtime: 'go1.x',
environment: {},

View File

@@ -1,6 +1,6 @@
{
"name": "@now/go",
"version": "0.4.2",
"version": "0.4.5",
"license": "MIT",
"repository": {
"type": "git",

View File

@@ -0,0 +1,16 @@
package cowsay
import (
"fmt"
"io/ioutil"
"net/http"
)
// Handler function
func Handler(w http.ResponseWriter, r *http.Request) {
bts, err := ioutil.ReadFile("templates/foo.txt")
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
fmt.Fprintf(w, string(bts))
}

View File

@@ -0,0 +1,20 @@
{
"version": 2,
"builds": [
{
"src": "index.go",
"use": "@now/go",
"config": {
"includeFiles": [
"templates/**"
]
}
}
],
"probes": [
{
"path": "/",
"mustContain": "foobar from file"
}
]
}

View File

@@ -0,0 +1 @@
foobar from file

View File

@@ -1,4 +1,4 @@
const FileBlob = require('@now/build-utils/file-blob.js'); // eslint-disable-line import/no-extraneous-dependencies
const { FileBlob, shouldServe } = require('@now/build-utils'); // eslint-disable-line import/no-extraneous-dependencies
const { minify } = require('html-minifier');
const defaultOptions = {
@@ -28,3 +28,5 @@ exports.build = async ({ files, entrypoint, config }) => {
return { [entrypoint]: result };
};
exports.shouldServe = shouldServe;

View File

@@ -1,6 +1,6 @@
{
"name": "@now/html-minifier",
"version": "1.1.0",
"version": "1.1.3",
"license": "MIT",
"repository": {
"type": "git",

View File

@@ -1,5 +1,6 @@
const { Lambda } = require('@now/build-utils/lambda.js'); // eslint-disable-line import/no-extraneous-dependencies
const streamToBuffer = require('@now/build-utils/fs/stream-to-buffer.js'); // eslint-disable-line import/no-extraneous-dependencies
const { shouldServe } = require('@now/build-utils'); // eslint-disable-line import/no-extraneous-dependencies
exports.build = async ({ files, entrypoint, config }) => {
if (!files[entrypoint]) throw new Error('Entrypoint not found in files');
@@ -10,3 +11,5 @@ exports.build = async ({ files, entrypoint, config }) => {
const lambda = new Lambda({ zipBuffer, handler, runtime });
return { [entrypoint]: lambda };
};
exports.shouldServe = shouldServe;

View File

@@ -1,6 +1,6 @@
{
"name": "@now/lambda",
"version": "0.5.0",
"version": "0.5.3",
"license": "MIT",
"repository": {
"type": "git",

View File

@@ -1,4 +1,4 @@
const FileBlob = require('@now/build-utils/file-blob.js'); // eslint-disable-line import/no-extraneous-dependencies
const { FileBlob, shouldServe } = require('@now/build-utils'); // eslint-disable-line import/no-extraneous-dependencies
const unified = require('unified');
const unifiedStream = require('unified-stream');
const markdown = require('remark-parse');
@@ -38,3 +38,5 @@ exports.build = async ({ files, entrypoint, config }) => {
return { [replacedEntrypoint]: result };
};
exports.shouldServe = shouldServe;

View File

@@ -1,6 +1,6 @@
{
"name": "@now/md",
"version": "0.5.0",
"version": "0.5.3",
"license": "MIT",
"repository": {
"type": "git",

View File

@@ -1,6 +1,6 @@
{
"name": "@now/mdx-deck",
"version": "0.5.0",
"version": "0.5.3",
"license": "MIT",
"repository": {
"type": "git",

View File

@@ -1,6 +1,6 @@
{
"name": "@now/next",
"version": "0.2.0",
"version": "0.3.1",
"license": "MIT",
"main": "./dist/index",
"scripts": {
@@ -14,7 +14,7 @@
"directory": "packages/now-next"
},
"dependencies": {
"@now/node-bridge": "^1.1.0",
"@now/node-bridge": "^1.1.2",
"fs-extra": "^7.0.0",
"get-port": "^5.0.0",
"resolve-from": "^5.0.0",

View File

@@ -2,18 +2,21 @@ import resolveFrom from 'resolve-from';
import { parse } from 'url';
import getPort from 'get-port';
import { createServer } from 'http';
import { syncEnvVars } from './utils';
export interface ProcessEnv {
[key: string]: string;
}
process.on('unhandledRejection', err => {
console.error('Exiting builder due to build error:');
console.error(err);
process.exit(1);
});
async function main(env: ProcessEnv, cwd: string) {
async function main(cwd: string) {
const next = require(resolveFrom(cwd, 'next'));
const app = next({ dev: true, dir: cwd });
const handler = app.getRequestHandler();
const openPort = await getPort({
port: [ 5000, 4000 ]
port: [5000, 4000],
});
const url = `http://localhost:${openPort}`;
@@ -21,21 +24,21 @@ async function main(env: ProcessEnv, cwd: string) {
// Prepare for incoming requests
await app.prepare();
// The runtime env vars are passed in to `argv[2]`
// as a base64-encoded JSON string
const runtimeEnv = JSON.parse(
Buffer.from(process.argv[2], 'base64').toString()
);
syncEnvVars(process.env, process.env, runtimeEnv);
createServer((req, res) => {
const parsedUrl = parse(req.url || '', true);
handler(req, res, parsedUrl);
}).listen(openPort, (error: NodeJS.ErrnoException) => {
if (error) {
console.error(error);
process.exit(1);
return;
}
}).listen(openPort, () => {
if (process.send) {
process.send(url);
}
});
}
main(process.env as ProcessEnv, process.cwd());
main(process.cwd());

View File

@@ -25,6 +25,7 @@ import {
import nextLegacyVersions from './legacy-versions';
import {
EnvConfig,
excludeFiles,
getNextConfig,
getPathsInside,
@@ -33,11 +34,14 @@ import {
normalizePackageJson,
onlyStaticDirectory,
stringMap,
syncEnvVars,
validateEntrypoint,
} from './utils';
interface BuildParamsMeta {
isDev: boolean | undefined;
env?: EnvConfig;
buildEnv?: EnvConfig;
}
interface BuildParamsType extends BuildOptions {
@@ -119,13 +123,17 @@ function isLegacyNext(nextVersion: string) {
const name = '[@now/next]';
const urls: stringMap = {};
function startDevServer(entryPath: string) {
const forked = fork(path.join(__dirname, 'dev-server.js'), [], {
function startDevServer(entryPath: string, runtimeEnv: EnvConfig) {
// The runtime env vars are encoded and passed in as `argv[2]`, so that the
// dev-server process can replace them onto `process.env` after the Next.js
// "prepare" step
const encodedEnv = Buffer.from(JSON.stringify(runtimeEnv)).toString('base64');
// `env` is omitted since that
// makes it default to `process.env`
const forked = fork(path.join(__dirname, 'dev-server.js'), [encodedEnv], {
cwd: entryPath,
execArgv: [],
env: {
NOW_REGION: 'dev1',
},
});
const getUrl = () =>
@@ -182,7 +190,13 @@ export const build = async ({
if (!urls[entrypoint]) {
console.log(`${name} Installing dependencies...`);
await runNpmInstall(entryPath, ['--prefer-offline']);
const { forked, getUrl } = startDevServer(entryPath);
// The runtime env vars consist of the base `process.env` vars, but with the
// build env vars removed, and the runtime env vars mixed in afterwards
const runtimeEnv: EnvConfig = Object.assign({}, process.env);
syncEnvVars(runtimeEnv, meta.buildEnv || {}, meta.env || {});
const { forked, getUrl } = startDevServer(entryPath, runtimeEnv);
urls[entrypoint] = await getUrl();
childProcess = forked;
console.log(

View File

@@ -2,18 +2,22 @@ import fs from 'fs-extra';
import path from 'path';
import { Files } from '@now/build-utils';
type stringMap = {[key: string]: string};
type stringMap = { [key: string]: string };
export interface EnvConfig {
[name: string]: string | undefined;
}
/**
* Validate if the entrypoint is allowed to be used
*/
function validateEntrypoint(entrypoint: string) {
if (
!/package\.json$/.exec(entrypoint)
&& !/next\.config\.js$/.exec(entrypoint)
!/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"',
'Specified "src" for "@now/next" has to be "package.json" or "next.config.js"'
);
}
}
@@ -21,7 +25,10 @@ function validateEntrypoint(entrypoint: string) {
/**
* Exclude certain files from the files object
*/
function excludeFiles(files: Files, matcher: (filePath: string) => boolean): Files {
function excludeFiles(
files: Files,
matcher: (filePath: string) => boolean
): Files {
return Object.keys(files).reduce((newFiles, filePath) => {
if (matcher(filePath)) {
return newFiles;
@@ -36,7 +43,10 @@ function excludeFiles(files: Files, matcher: (filePath: string) => boolean): Fil
/**
* Creates a new Files object holding only the entrypoint files
*/
function includeOnlyEntryDirectory(files: Files, entryDirectory: string): Files {
function includeOnlyEntryDirectory(
files: Files,
entryDirectory: string
): Files {
if (entryDirectory === '.') {
return files;
}
@@ -76,7 +86,13 @@ function onlyStaticDirectory(files: Files, entryDir: string): Files {
/**
* Enforce specific package.json configuration for smallest possible lambda
*/
function normalizePackageJson(defaultPackageJson: {dependencies?: stringMap, devDependencies?: stringMap, scripts?: stringMap} = {}) {
function normalizePackageJson(
defaultPackageJson: {
dependencies?: stringMap;
devDependencies?: stringMap;
scripts?: stringMap;
} = {}
) {
const dependencies: stringMap = {};
const devDependencies: stringMap = {
...defaultPackageJson.dependencies,
@@ -112,7 +128,8 @@ function normalizePackageJson(defaultPackageJson: {dependencies?: stringMap, dev
},
scripts: {
...defaultPackageJson.scripts,
'now-build': 'NODE_OPTIONS=--max_old_space_size=3000 next build --lambdas',
'now-build':
'NODE_OPTIONS=--max_old_space_size=3000 next build --lambdas',
},
};
}
@@ -151,7 +168,12 @@ function getPathsInside(entryDirectory: string, files: Files) {
return watch;
}
function getRoutes(entryDirectory: string, pathsInside: string[], files: Files, url: string): any[] {
function getRoutes(
entryDirectory: string,
pathsInside: string[],
files: Files,
url: string
): any[] {
const filesInside: Files = {};
const prefix = entryDirectory === `.` ? `/` : `/${entryDirectory}/`;
@@ -166,12 +188,12 @@ function getRoutes(entryDirectory: string, pathsInside: string[], files: Files,
const routes: any[] = [
{
src: `${prefix}_next/(.*)`,
dest: `${url}/_next/$1`
dest: `${url}/_next/$1`,
},
{
src: `${prefix}static/(.*)`,
dest: `${url}/static/$1`
}
dest: `${url}/static/$1`,
},
];
for (const file of Object.keys(filesInside)) {
@@ -192,7 +214,7 @@ function getRoutes(entryDirectory: string, pathsInside: string[], files: Files,
routes.push({
src: `${prefix}${pageName}`,
dest: `${url}/${pageName}`
dest: `${url}/${pageName}`,
});
if (pageName.endsWith('index')) {
@@ -200,7 +222,7 @@ function getRoutes(entryDirectory: string, pathsInside: string[], files: Files,
routes.push({
src: `${prefix}${resolvedIndex}`,
dest: `${url}/${resolvedIndex}`
dest: `${url}/${resolvedIndex}`,
});
}
}
@@ -208,6 +230,20 @@ function getRoutes(entryDirectory: string, pathsInside: string[], files: Files,
return routes;
}
function syncEnvVars(base: EnvConfig, removeEnv: EnvConfig, addEnv: EnvConfig) {
// Remove any env vars from `removeEnv`
// that are not present in the `addEnv`
const addKeys = new Set(Object.keys(addEnv));
for (const name of Object.keys(removeEnv)) {
if (!addKeys.has(name)) {
delete base[name];
}
}
// Add in the keys from `addEnv`
Object.assign(base, addEnv);
}
export {
excludeFiles,
validateEntrypoint,
@@ -219,4 +255,5 @@ export {
getPathsInside,
getRoutes,
stringMap,
syncEnvVars,
};

View File

@@ -1,6 +1,6 @@
{
"name": "@now/node-bridge",
"version": "1.1.0",
"version": "1.1.2",
"license": "MIT",
"main": "./index.js",
"repository": {

View File

@@ -9,6 +9,7 @@ const {
runNpmInstall,
runPackageJsonScript,
} = require('@now/build-utils/fs/run-user-scripts.js'); // eslint-disable-line import/no-extraneous-dependencies
const { shouldServe } = require('@now/build-utils'); // eslint-disable-line import/no-extraneous-dependencies
/** @typedef { import('@now/build-utils/file-ref') } FileRef */
/** @typedef {{[filePath: string]: FileRef}} Files */
@@ -49,8 +50,12 @@ async function compile(workPath, downloadedFiles, entrypoint, config) {
});
if (config && config.includeFiles) {
const includeFiles = typeof config.includeFiles === 'string'
? [config.includeFiles]
: config.includeFiles;
// eslint-disable-next-line no-restricted-syntax
for (const pattern of config.includeFiles) {
for (const pattern of includeFiles) {
// eslint-disable-next-line no-await-in-loop
const files = await glob(pattern, inputDir);
@@ -145,3 +150,5 @@ exports.prepareCache = async ({ workPath }) => ({
...(await glob('package-lock.json', workPath)),
...(await glob('yarn.lock', workPath)),
});
exports.shouldServe = shouldServe;

View File

@@ -1,6 +1,6 @@
{
"name": "@now/node-server",
"version": "0.6.0",
"version": "0.7.1",
"license": "MIT",
"repository": {
"type": "git",
@@ -8,8 +8,8 @@
"directory": "packages/now-node-server"
},
"dependencies": {
"@now/node-bridge": "^1.1.0",
"@zeit/ncc": "0.18.1",
"@now/node-bridge": "^1.1.2",
"@zeit/ncc": "0.18.2",
"fs-extra": "7.0.1"
},
"scripts": {

View File

@@ -0,0 +1,5 @@
const express = require('express');
const app = express();
app.listen();

View File

@@ -9,6 +9,13 @@
"templates/**"
]
}
},
{
"src": "accepts-string/index.js",
"use": "@now/node-server",
"config": {
"includeFiles": "templates/**"
}
}
],
"probes": [

View File

@@ -1,6 +1,6 @@
{
"name": "@now/node",
"version": "0.6.0",
"version": "0.7.1",
"license": "MIT",
"main": "./dist/index",
"repository": {
@@ -9,8 +9,8 @@
"directory": "packages/now-node"
},
"dependencies": {
"@now/node-bridge": "^1.1.0",
"@zeit/ncc": "0.18.1",
"@now/node-bridge": "^1.1.2",
"@zeit/ncc": "0.18.2",
"fs-extra": "7.0.1"
},
"scripts": {

View File

@@ -11,14 +11,15 @@ import {
runPackageJsonScript,
PrepareCacheOptions,
BuildOptions,
shouldServe,
} from '@now/build-utils';
interface CompilerConfig {
includeFiles?: string[]
includeFiles?: string | string[];
}
interface DownloadOptions {
files: Files,
files: Files;
entrypoint: string;
workPath: string;
npmArguments?: string[];
@@ -28,7 +29,7 @@ async function downloadInstallAndBundle({
files,
entrypoint,
workPath,
npmArguments = []
npmArguments = [],
}: DownloadOptions) {
console.log('downloading user files...');
const downloadedFiles = await download(files, workPath);
@@ -41,15 +42,27 @@ async function downloadInstallAndBundle({
return { entrypointPath, entrypointFsDirname };
}
async function compile(entrypointPath: string, entrypoint: string, config: CompilerConfig): Promise<Files> {
async function compile(
entrypointPath: string,
entrypoint: string,
config: CompilerConfig
): Promise<Files> {
const input = entrypointPath;
const inputDir = dirname(input);
const rootIncludeFiles = inputDir.split(sep).pop() || '';
const ncc = require('@zeit/ncc');
const { code, map, assets } = await ncc(input, { sourceMap: true, sourceMapRegister: true });
const { code, map, assets } = await ncc(input, {
sourceMap: true,
sourceMapRegister: true,
});
if (config && config.includeFiles) {
for (const pattern of config.includeFiles) {
const includeFiles =
typeof config.includeFiles === 'string'
? [config.includeFiles]
: config.includeFiles;
for (const pattern of includeFiles) {
const files = await glob(pattern, inputDir);
for (const assetName of Object.keys(files)) {
@@ -61,12 +74,12 @@ async function compile(entrypointPath: string, entrypoint: string, config: Compi
// if asset contain directory
// no need to use `rootIncludeFiles`
if (assetName.includes(sep)) {
fullPath = assetName
fullPath = assetName;
}
assets[fullPath] = {
'source': data,
'permissions': mode
source: data,
permissions: mode,
};
}
}
@@ -75,7 +88,9 @@ async function compile(entrypointPath: string, entrypoint: string, config: Compi
const preparedFiles: Files = {};
// move all user code to 'user' subdirectory
preparedFiles[entrypoint] = new FileBlob({ data: code });
preparedFiles[`${entrypoint.replace('.ts', '.js')}.map`] = new FileBlob({ data: map });
preparedFiles[`${entrypoint.replace('.ts', '.js')}.map`] = new FileBlob({
data: map,
});
// eslint-disable-next-line no-restricted-syntax
for (const assetName of Object.keys(assets)) {
const { source: data, permissions: mode } = assets[assetName];
@@ -87,16 +102,24 @@ async function compile(entrypointPath: string, entrypoint: string, config: Compi
}
export const config = {
maxLambdaSize: '5mb'
maxLambdaSize: '5mb',
};
export async function build({ files, entrypoint, workPath, config }: BuildOptions) {
export async function build({
files,
entrypoint,
workPath,
config,
}: BuildOptions) {
const {
entrypointPath,
entrypointFsDirname
} = await downloadInstallAndBundle(
{ files, entrypoint, workPath, npmArguments: ['--prefer-offline'] }
);
entrypointFsDirname,
} = await downloadInstallAndBundle({
files,
entrypoint,
workPath,
npmArguments: ['--prefer-offline'],
});
console.log('running user script...');
await runPackageJsonScript(entrypointFsDirname, 'now-build');
@@ -110,19 +133,19 @@ export async function build({ files, entrypoint, workPath, config }: BuildOption
'// PLACEHOLDER',
[
`listener = require("./${entrypoint}");`,
'if (listener.default) listener = listener.default;'
'if (listener.default) listener = listener.default;',
].join(' ')
);
const launcherFiles = {
'launcher.js': new FileBlob({ data: launcherData }),
'bridge.js': new FileFsRef({ fsPath: require('@now/node-bridge') })
'bridge.js': new FileFsRef({ fsPath: require('@now/node-bridge') }),
};
const lambda = await createLambda({
files: { ...preparedFiles, ...launcherFiles },
handler: 'launcher.launcher',
runtime: 'nodejs8.10'
runtime: 'nodejs8.10',
});
return { [entrypoint]: lambda };
@@ -132,6 +155,8 @@ export async function prepareCache({ workPath }: PrepareCacheOptions) {
return {
...(await glob('node_modules/**', workPath)),
...(await glob('package-lock.json', workPath)),
...(await glob('yarn.lock', workPath))
...(await glob('yarn.lock', workPath)),
};
}
export { shouldServe };

View File

@@ -0,0 +1,7 @@
const edge = require('edge.js');
module.exports = (req, resp) => {
edge.registerViews('templates');
resp.end(edge.render('accepts-string', { name: 'String!' }));
};

View File

@@ -18,6 +18,13 @@
"root.edge"
]
}
},
{
"src": "accepts-string.js",
"use": "@now/node",
"config": {
"includeFiles": "templates/accepts-string.edge"
}
}
],
"probes": [
@@ -25,6 +32,10 @@
"path": "/",
"mustContain": "hello Now!"
},
{
"path": "/accepts-string.js",
"mustContain": "hello String!"
},
{
"path": "/root.js",
"mustContain": "hello Root!"

View File

@@ -0,0 +1 @@
hello {{ name }}

View File

@@ -1,6 +1,6 @@
{
"name": "@now/optipng",
"version": "0.5.0",
"version": "0.6.1",
"license": "MIT",
"main": "./dist/index",
"files": [

View File

@@ -1,13 +1,14 @@
// eslint-disable-line import/no-extraneous-dependencies
import {
import {
FileBlob,
BuildOptions,
AnalyzeOptions
} from '@now/build-utils'
import OptiPng from 'optipng'
import pipe from 'multipipe'
AnalyzeOptions,
shouldServe,
} from '@now/build-utils';
import OptiPng from 'optipng';
import pipe from 'multipipe';
export function analyze({ files, entrypoint }: AnalyzeOptions) {
export function analyze({ files, entrypoint }: AnalyzeOptions) {
return files[entrypoint].digest;
}
@@ -20,3 +21,5 @@ export async function build({ files, entrypoint }: BuildOptions) {
const result = await FileBlob.fromStream({ stream });
return { [entrypoint]: result };
}
export { shouldServe };

View File

@@ -1,6 +1,6 @@
{
"name": "@now/php-bridge",
"version": "0.5.0",
"version": "0.5.2",
"license": "MIT",
"repository": {
"type": "git",

View File

@@ -1,5 +1,9 @@
const {
createLambda, rename, glob, download,
createLambda,
rename,
glob,
download,
shouldServe,
} = require('@now/build-utils'); // eslint-disable-line import/no-extraneous-dependencies
const path = require('path');
const { getFiles } = require('@now/php-bridge');
@@ -52,3 +56,5 @@ exports.build = async ({
return { [entrypoint]: lambda };
};
exports.shouldServe = shouldServe;

View File

@@ -1,6 +1,6 @@
{
"name": "@now/php",
"version": "0.5.0",
"version": "0.5.3",
"license": "MIT",
"repository": {
"type": "git",
@@ -8,7 +8,7 @@
"directory": "packages/now-php"
},
"dependencies": {
"@now/php-bridge": "^0.5.0"
"@now/php-bridge": "^0.5.2"
},
"scripts": {
"test": "jest"

View File

@@ -1,56 +0,0 @@
import { join } from 'path';
import fetch from 'node-fetch';
import execa from 'execa';
import { createWriteStream } from 'fs';
import { getWriteableDirectory } from '@now/build-utils';
const url = 'https://bootstrap.pypa.io/get-pip.py';
// downloads `get-pip.py` and returns its absolute path
async function downloadGetPipScript() {
console.log('downloading "get-pip.py"...');
const res = await fetch(url);
if (!res.ok || res.status !== 200) {
throw new Error(`Could not download "get-pip.py" from "${url}"`);
}
const dir = await getWriteableDirectory();
const filePath = join(dir, 'get-pip.py');
const writeStream = createWriteStream(filePath);
return new Promise<string>((resolve, reject) => {
res.body
.on('error', reject)
.pipe(writeStream)
.on('finish', () => resolve(filePath));
});
}
// downloads and installs `pip` (respecting
// process.env.PYTHONUSERBASE), and returns
// the absolute path to it
export async function downloadAndInstallPip() {
const { PYTHONUSERBASE } = process.env;
if (!PYTHONUSERBASE) {
// this is the directory in which `pip` will be
// 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',
);
}
const getPipFilePath = await downloadGetPipScript();
console.log('running "python get-pip.py"...');
try {
await execa('python3', [getPipFilePath, '--user'], { stdio: 'inherit' });
} catch (err) {
console.log('could not install pip');
throw err;
}
return join(PYTHONUSERBASE, 'bin', 'pip');
}

View File

@@ -9,20 +9,30 @@ import {
download,
glob,
createLambda,
shouldServe,
BuildOptions,
} from '@now/build-utils';
import { downloadAndInstallPip } from './download-and-install-pip';
async function pipInstall(pipPath: string, workDir: string, ...args: string[]) {
const target = '.';
console.log(`running "pip install --target ${target} --upgrade ${args.join(' ')}"...`);
console.log(
`running "pip install --target ${target} --upgrade ${args.join(' ')}"...`
);
try {
await execa(pipPath, ['install', '--target', target, '--upgrade', ...args], {
cwd: workDir,
stdio: 'inherit',
});
await execa(
pipPath,
['install', '--target', target, '--upgrade', ...args],
{
cwd: workDir,
stdio: 'inherit',
}
);
} catch (err) {
console.log(`failed to run "pip install --target ${target} --upgrade ${args.join(' ')}"...`);
console.log(
`failed to run "pip install --target ${target} --upgrade ${args.join(
' '
)}"...`
);
throw err;
}
}
@@ -42,11 +52,10 @@ async function pipInstallUser(pipPath: string, ...args: string[]) {
async function pipenvInstall(pyUserBase: string, srcDir: string) {
console.log('running "pipenv_to_requirements -f');
try {
await execa(
join(pyUserBase, 'bin', 'pipenv_to_requirements'),
['-f'],
{ cwd: srcDir, stdio: 'inherit' },
);
await execa(join(pyUserBase, 'bin', 'pipenv_to_requirements'), ['-f'], {
cwd: srcDir,
stdio: 'inherit',
});
} catch (err) {
console.log('failed to run "pipenv_to_requirements -f"');
throw err;
@@ -57,17 +66,18 @@ export const config = {
maxLambdaSize: '5mb',
};
export const build = async ({ workPath, files, entrypoint }: BuildOptions) => {
export const build = async ({
workPath,
files: originalFiles,
entrypoint,
meta = {},
}: BuildOptions) => {
console.log('downloading files...');
// eslint-disable-next-line no-param-reassign
files = await download(files, workPath);
// this is where `pip` will be installed to
// we need it to be under `/tmp`
const downloadedFiles = await download(originalFiles, workPath);
const foundLockFile = 'Pipfile.lock' in downloadedFiles;
const pyUserBase = await getWriteableDirectory();
process.env.PYTHONUSERBASE = pyUserBase;
const pipPath = await downloadAndInstallPip();
const pipPath = 'pip3';
try {
// See: https://stackoverflow.com/a/44728772/376773
@@ -77,8 +87,10 @@ export const build = async ({ workPath, files, entrypoint }: BuildOptions) => {
//
// distutils.errors.DistutilsOptionError: must supply either home
// or prefix/exec-prefix -- not both
const setupCfg = join(workPath, 'setup.cfg');
await writeFile(setupCfg, '[install]\nprefix=\n');
if (meta.isDev) {
const setupCfg = join(workPath, 'setup.cfg');
await writeFile(setupCfg, '[install]\nprefix=\n');
}
} catch (err) {
console.log('failed to create "setup.cfg" file');
throw err;
@@ -87,10 +99,7 @@ export const build = async ({ workPath, files, entrypoint }: BuildOptions) => {
await pipInstall(pipPath, workPath, 'werkzeug');
await pipInstall(pipPath, workPath, 'requests');
const entryDirectory = dirname(entrypoint);
const requirementsTxt = join(entryDirectory, 'requirements.txt');
if (files['Pipfile.lock']) {
if (foundLockFile) {
console.log('found "Pipfile.lock"');
// Install pipenv.
@@ -100,6 +109,8 @@ export const build = async ({ workPath, files, entrypoint }: BuildOptions) => {
}
const fsFiles = await glob('**', workPath);
const entryDirectory = dirname(entrypoint);
const requirementsTxt = join(entryDirectory, 'requirements.txt');
if (fsFiles[requirementsTxt]) {
console.log('found local "requirements.txt"');
@@ -122,7 +133,7 @@ export const build = async ({ workPath, files, entrypoint }: BuildOptions) => {
.replace(/\.py$/, '');
const nowHandlerPyContents = originalNowHandlerPyContents.replace(
/__NOW_HANDLER_FILENAME/g,
userHandlerFilePath,
userHandlerFilePath
);
// in order to allow the user to have `server.py`, we need our `server.py` to be called
@@ -131,7 +142,7 @@ export const build = async ({ workPath, files, entrypoint }: BuildOptions) => {
await writeFile(
join(workPath, `${nowHandlerPyFilename}.py`),
nowHandlerPyContents,
nowHandlerPyContents
);
const lambda = await createLambda({
@@ -145,3 +156,5 @@ export const build = async ({ workPath, files, entrypoint }: BuildOptions) => {
[entrypoint]: lambda,
};
};
export { shouldServe };

View File

@@ -1,6 +1,6 @@
{
"name": "@now/python",
"version": "0.1.0",
"version": "0.2.1",
"main": "index.js",
"license": "MIT",
"repository": {

View File

@@ -8,6 +8,7 @@ const glob = require('@now/build-utils/fs/glob.js'); // eslint-disable-line impo
const { runShellScript } = require('@now/build-utils/fs/run-user-scripts.js'); // eslint-disable-line import/no-extraneous-dependencies
const FileFsRef = require('@now/build-utils/file-fs-ref.js'); // eslint-disable-line import/no-extraneous-dependencies
const FileRef = require('@now/build-utils/file-ref.js'); // eslint-disable-line import/no-extraneous-dependencies
const { shouldServe } = require('@now/build-utils'); // eslint-disable-line import/no-extraneous-dependencies
const installRust = require('./install-rust.js');
exports.config = {
@@ -367,3 +368,5 @@ exports.getDefaultCache = ({ files, entrypoint }) => {
});
return { [targetFolderDir]: defaultCacheRef };
};
exports.shouldServe = shouldServe;

View File

@@ -1,6 +1,6 @@
{
"name": "@now/rust",
"version": "0.2.0",
"version": "0.2.3",
"license": "MIT",
"repository": {
"type": "git",

View File

@@ -15,7 +15,7 @@ function validateDistDir(distDir) {
const distDirName = path.basename(distDir);
if (!existsSync(distDir)) {
const message = `Build was unable to create the distDir: ${distDirName}.`
+ '\nMake sure you mentioned the correct dist directory: https://zeit.co/docs/v2/deployments/official-builders/static-build-now-static-build/#configuring-the-build-output-directory';
+ '\nMake sure you mentioned the correct dist directory: https://zeit.co/docs/v2/deployments/official-builders/static-build-now-static-build/#local-development';
throw new Error(message);
}
}
@@ -58,6 +58,7 @@ exports.build = async ({
devPort = await getPort();
nowDevScriptPorts.set(entrypoint, devPort);
const opts = {
cwd: entrypointFsDirname,
env: { ...process.env, PORT: String(devPort) },
};
const child = spawn('yarn', ['run', 'now-dev'], opts);
@@ -103,6 +104,12 @@ exports.build = async ({
dest: `http://localhost:${devPort}${srcBase}/$1`,
});
} else {
if (meta.isDev) {
console.log('WARN: "now-dev" script is missing from package.json');
console.log(
'See the local development docs: http://zeit.co/docs/v2/deployments/official-builders/static-now-static#local-development',
);
}
// Run the `now-build` script and wait for completion to collect the build
// outputs
console.log('running user "now-build" script from `package.json`...');

View File

@@ -1,6 +1,6 @@
{
"name": "@now/static-build",
"version": "0.5.2",
"version": "0.5.5",
"license": "MIT",
"repository": {
"type": "git",

View File

@@ -1,6 +1,6 @@
{
"name": "@now/wordpress",
"version": "0.5.0",
"version": "0.5.2",
"license": "MIT",
"repository": {
"type": "git",
@@ -8,7 +8,7 @@
"directory": "packages/now-wordpress"
},
"dependencies": {
"@now/php-bridge": "^0.5.0",
"@now/php-bridge": "^0.5.2",
"node-fetch": "2.3.0",
"yauzl": "2.10.0"
},

View File

@@ -940,6 +940,13 @@
dependencies:
"@babel/types" "^7.3.0"
"@types/cross-spawn@6.0.0":
version "6.0.0"
resolved "https://registry.yarnpkg.com/@types/cross-spawn/-/cross-spawn-6.0.0.tgz#320aaf1d1a12979f1b84fe7a5590a7e860bf3a80"
integrity sha512-evp2ZGsFw9YKprDbg8ySgC9NA15g3YgiI8ANkGmKKvvi0P2aDGYLPxQIC5qfeKNUOe3TjABVGuah6omPRpIYhg==
dependencies:
"@types/node" "*"
"@types/debug@^4.1.3":
version "4.1.4"
resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.4.tgz#56eec47706f0fd0b7c694eae2f3172e6b0b769da"
@@ -1128,10 +1135,10 @@
globby "8.0.0"
signal-exit "3.0.2"
"@zeit/ncc@0.18.1":
version "0.18.1"
resolved "https://registry.yarnpkg.com/@zeit/ncc/-/ncc-0.18.1.tgz#1723884210c792ba702ec6dccb390f387f0a3ba6"
integrity sha512-Tq13BzK+hAWBZY+VvncRZzpE5PHGks3kn2XJ+bcWSXgTZb4rTR/CTV1YYXilNNkX//jC1sziuM167FhLzFu2XA==
"@zeit/ncc@0.18.2":
version "0.18.2"
resolved "https://registry.yarnpkg.com/@zeit/ncc/-/ncc-0.18.2.tgz#b5f721ec1d23bfe531f3568633689ddab7c05638"
integrity sha512-liiuVTcxLaOIGQDftpZ2qhSS/vdEbuvmi2tkBWMfIwIyeKd/sh/jw+l8yONT3/unx/sSmfMTDnwfwUlY+saKiw==
JSONStream@^1.0.4, JSONStream@^1.3.4:
version "1.3.5"
@@ -2534,16 +2541,7 @@ create-error-class@^3.0.1:
dependencies:
capture-stack-trace "^1.0.0"
cross-spawn@^5.0.1:
version "5.1.0"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449"
integrity sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=
dependencies:
lru-cache "^4.0.1"
shebang-command "^1.2.0"
which "^1.2.9"
cross-spawn@^6.0.0, cross-spawn@^6.0.5:
cross-spawn@6.0.5, cross-spawn@^6.0.0, cross-spawn@^6.0.5:
version "6.0.5"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4"
integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==
@@ -2554,6 +2552,15 @@ cross-spawn@^6.0.0, cross-spawn@^6.0.5:
shebang-command "^1.2.0"
which "^1.2.9"
cross-spawn@^5.0.1:
version "5.1.0"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449"
integrity sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=
dependencies:
lru-cache "^4.0.1"
shebang-command "^1.2.0"
which "^1.2.9"
cssom@0.3.x, "cssom@>= 0.3.2 < 0.4.0":
version "0.3.4"
resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.4.tgz#8cd52e8a3acfd68d3aed38ee0a640177d2f9d797"