Compare commits

..

37 Commits

Author SHA1 Message Date
Steven
de2c08cfe8 Publish
- @now/build-utils@0.5.6-canary.0
2019-05-25 14:24:52 -04:00
Steven
9679f07124 [build-utils] add --unsafe-perm to npm install, so that postinstall runs (#530) 2019-05-25 14:24:01 -04:00
Steven
6ce24d6a4e Switch branch during publish (#529) 2019-05-24 17:28:29 -04:00
Steven
e3e029f5f6 Update README.md 2019-05-24 13:37:35 -04:00
Steven
89172a6e89 Publish
- @now/go@0.5.0
 - @now/next@0.4.0
 - @now/node-bridge@1.1.3
 - @now/node-server@0.7.3
 - @now/node@0.7.3
 - @now/python@0.2.4
 - @now/static-build@0.5.7
2019-05-24 12:29:57 -04:00
Steven
e8f1dbaa46 Empty commit to satisfy lerna 2019-05-24 12:27:37 -04:00
Sophearak Tha
16b5b6fdf3 Publish
- @now/python@0.2.4-canary.2
2019-05-24 20:59:19 +07:00
Sophearak Tha
3bab29ff76 Add custom path and proper check (#527)
* Add custom path and proper check

* Change route tests to use another name
2019-05-24 20:55:28 +07:00
Sophearak Tha
d675d2e668 Use unquote() for http handler (#525)
* Use unquote() for http handler

* Add tests for url params http handler
2019-05-24 20:27:44 +07:00
Joe Haddad
2dda88e676 Publish
- @now/next@0.3.4-canary.4
2019-05-23 15:32:28 -07:00
Joe Haddad
5a0090eb1f [now-next] Ensure route begins with a slash (#524)
* Ensure route begins with a slash

* Simplift

* Apply suggestions from code review

Co-Authored-By: Connor Davis <mail@connordav.is>

* Adjust spacing
2019-05-23 15:31:13 -07:00
Sophearak Tha
d438b4ec4e Publish
- @now/go@0.4.8-canary.1
 - @now/python@0.2.4-canary.1
2019-05-23 20:34:53 +07:00
Sophearak Tha
f8810fd7e6 [now-python] Make sure to pass decode url params (#496)
* Make sure to pass decode url params

* Add tests cover default and custom routes behaviour on url param

* Removed `unquote` since `urlparse` already return expected value

* Using unquote in both PATH_INFO and QUERY_STRING

* Better code structure now_init.py

* Better test
2019-05-23 09:27:44 -04:00
Sophearak Tha
a642cfea96 [now-go] Add option to use private Git for go get (#513)
* Add option to use private Git

* Update packages/now-go/index.ts

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

* Fix import error

* Using `GIT_CREDENTIALS` over multiple env vars

* Ignore initialize Git credentials in `meta.isDev`
2019-05-23 11:39:36 +07:00
Joe Haddad
2daa20a9f2 Publish
- @now/next@0.3.4-canary.3
2019-05-22 18:36:15 -07:00
JJ Kasper
4d5c0c40f0 [now-next] Update to use routes for static pages (#521) 2019-05-22 20:25:10 -05:00
Joe Haddad
29051681df Publish
- @now/next@0.3.4-canary.2
2019-05-22 16:18:59 -07:00
JJ Kasper
96d5e81538 [now-next] Handle statically exported pages (#520)
* Add support for auto exported pages

* Add entryDirectory to staticPages mapping

* Map to FsFileRef instead of path
2019-05-22 16:14:24 -07:00
Steven
9ba9dd6949 Publish
- @now/go@0.4.8-canary.0
 - @now/next@0.3.4-canary.1
 - @now/node-bridge@1.1.3-canary.0
 - @now/node-server@0.7.3-canary.0
 - @now/node@0.7.3-canary.0
 - @now/python@0.2.4-canary.0
2019-05-22 15:11:27 -04:00
Steven
b362d57270 [now-node-bridge] Disable callbackWaitsForEmptyEventLoop (#505)
* [now-node] Disable callbackWaitsForEmptyEventLoop

* Fix unit tests
2019-05-22 15:06:02 -04:00
Nathan Rajlich
4ff95e1718 Publish
- @now/go@0.4.7
 - @now/python@0.2.3
2019-05-20 12:40:51 -07:00
Sophearak Tha
ef02bedd4d Publish
- @now/python@0.2.3-canary.0
2019-05-20 23:54:04 +07:00
Sophearak Tha
ed68a09c3e Make sure cwd user clean by using cwd/.now (#516) 2019-05-20 23:53:03 +07:00
Leo Lamprecht
ac7ae5fc5d Run only tests for packages that changed (#515) 2019-05-20 18:10:42 +02:00
Sophearak Tha
9727b1f020 Publish
- @now/go@0.4.7-canary.1
2019-05-20 21:30:41 +07:00
Sophearak Tha
2dc454f15f [now-go] Give user descriptive error message when Go Modules not available (#514)
* Give user descriptive error message when Go Modules not available

* Include go1.11 onward
2019-05-20 21:29:36 +07:00
Sophearak Tha
4463af5c7a Publish
- @now/go@0.4.7-canary.0
 - @now/next@0.3.4-canary.0
2019-05-20 18:56:19 +07:00
Sophearak Tha
c00fb37cf6 [now-go] Use meta in download() (#495)
* Use meta in `download()`

* better handling cwd

* Ignore .now in during parsing entrypoint

* Make re-built faster
2019-05-20 18:52:50 +07:00
Marcel Haupenthal
4deb426f9c [now-go] Ignore folders in analyze.go (#503)(#504) (#506)
* [now-go] Ignore folders in `analyze.go` (#503)(#504)

This commit adds some changes to the way the AST for the source is
built.

The `analyze.go` program now ignores every `vendor`, `.git` and
`testdata` folder. This improves performance, since `vendor` and `.git`
are usually large folders (#504).

By ignoring `testdata`, we mimick the behaviour of `go build` and avoid
failing the parsing because of invalid Go code inside of `testdata` (#503)

* [now-go] Don't ignore `.git` in analyze (#506)

If the user wants to ignore `.git`, he should put it into `.nowignore`
2019-05-17 13:02:20 +07:00
Nathan Rajlich
008b04413a Publish
- @now/next@0.3.3
2019-05-16 11:49:42 -07:00
Nathan Rajlich
f177ba46e9 Publish
- @now/next@0.3.3-canary.0
 - @now/static-build@0.5.7-canary.0
2019-05-16 10:46:18 -07:00
Nathan Rajlich
c030fce589 [now-next] Default NODE_ENV to "development" for dev server (#493) 2019-05-15 18:46:26 -07:00
Nathan Rajlich
50a5150bb5 Publish
- @now/static-build@0.5.6
2019-05-14 10:40:21 -07:00
Nathan Rajlich
0578ccf47e Publish
- @now/static-build@0.5.6-canary.1
2019-05-13 15:58:26 -07:00
Nathan Rajlich
e32cd36ded [now-static-build] Remove srcBase from the proxy pass destination (#499)
The `srcBase` (directory where the entrypoint is located) should not be
in the `dest` proxy pass URL.

Consider an entrypoint like `www/package.json`. The development server
will be running within the `www` directory. A request for `GET
/static/foo.js` comes in, so we want to proxy pass to
`http://localhost:12345/static/foo.js` rather than
`http://localhost:12345/www/static/foo.js` which would lead to a 404.
2019-05-13 15:58:01 -07:00
Nathan Rajlich
6ac0ab121c Publish
- @now/static-build@0.5.6-canary.0
2019-05-13 13:12:35 -07:00
Nathan Rajlich
05db2e6a73 [now-static-build] Add err.sh link when dev server detection fails (#498)
* [now-static-build] Add `err.sh` link when dev server detection fails

The error message alone doesn't explain how to fix it, so adding this
`err.sh` link to guide the user to instructions on how to fix it.

For example: https://github.com/zeit/now-cli/issues/2339

* Shorter title

* should -> must
2019-05-13 13:11:03 -07:00
29 changed files with 364 additions and 101 deletions

View File

@@ -24,4 +24,4 @@ CircleCI will take care of publishing the updated packages to npm from there.
If for some reason CircleCI fails to publish the npm package, you may do so
manually by running `npm publish` from the package directory. Make sure to
include the `--tag canary` parameter if you are publishing a canary release!
use `npm publish --tag canary` if you are publishing a canary release!

View File

@@ -0,0 +1,38 @@
# `@now/static-build` Failed to detect a server running
#### Why This Warning Occurred
When running `now dev`, the `@now/static-build` builder proxies relevant HTTP
requests to the server that is created by the `now-dev` script in the
`package.json` file.
In order for `now dev` to know which port the server is running on, the builder
is provided a `$PORT` environment variable that the server *must* bind to. The
error "Failed to detect a server running on port" is printed if the builder fails
to detect a server listening on that specific port within five minutes.
#### Possible Ways to Fix It
Please ensure that your `now-dev` script binds the spawned development server on
the provided `$PORT` that the builder expects the server to bind to.
For example, if you are using Gatsby, your `now-dev` script must use the `-p`
(port) option to bind to the `$PORT` specified from the builder:
```
{
...
"scripts": {
...
"now-dev": "gatsby develop -p $PORT"
}
}
```
Consult your static builder program's `--help` or documentation to figure out what
the command line flag to bind to a specific port is (in many cases, it is one of:
`-p` / `-P` / `--port`).
### Useful Links
- [`@now/static-build` Local Development Documentation](https://zeit.co/docs/v2/deployments/official-builders/static-build-now-static-build#local-development)

View File

@@ -1,5 +1,37 @@
const childProcess = require('child_process');
const path = require('path');
const command = 'git diff HEAD~1 --name-only';
const diff = childProcess.execSync(command).toString();
const changed = diff
.split('\n')
.filter(item => Boolean(item) && item.includes('packages/'))
.map(item => path.relative('packages', item).split('/')[0]);
const matches = [];
if (changed.length > 0) {
console.log('The following packages have changed:');
changed.map((item) => {
matches.push(item);
console.log(item);
return null;
});
} else {
matches.push('now-node');
console.log(`No packages changed, defaulting to ${matches[0]}`);
}
const testMatch = Array.from(new Set(matches)).map(
item => `**/${item}/**/?(*.)+(spec|test).[jt]s?(x)`,
);
module.exports = {
testEnvironment: 'node',
testMatch,
collectCoverageFrom: [
'packages/(!test)/**/*.{js,jsx}',
'!**/node_modules/**',

View File

@@ -12,8 +12,8 @@
"scripts": {
"lerna": "lerna",
"bootstrap": "lerna bootstrap",
"publish-stable": "lerna version",
"publish-canary": "lerna version prerelease --preid canary",
"publish-stable": "git checkout master && git pull && lerna version",
"publish-canary": "git checkout canary && git pull && lerna version prerelease --preid canary",
"build": "./.circleci/build.sh",
"lint": "eslint .",
"codecov": "codecov",

View File

@@ -1,6 +1,6 @@
{
"name": "@now/build-utils",
"version": "0.5.5",
"version": "0.5.6-canary.0",
"license": "MIT",
"main": "./dist/index.js",
"types": "./dist/index.d.js",

View File

@@ -109,7 +109,7 @@ export async function installDependencies(
commandArgs = args.filter(a => a !== '--prefer-offline');
await spawnAsync(
'npm',
['install'].concat(commandArgs),
['install', '--unsafe-perm'].concat(commandArgs),
destPath,
opts as SpawnOptions
);

View File

@@ -125,7 +125,15 @@ export async function downloadGo(
// 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);
const { stdout } = await execa('go', ['version']);
if (parseInt(stdout.split('.')[1]) >= 11) {
return createGo(dir, platform, arch);
}
throw new Error(
`Your current ${stdout} doesn't support Go Modules. Please update.`
);
} else {
// Check `Go` bin in builder CWD
const isGoExist = await pathExists(join(dir, 'bin'));

View File

@@ -1,5 +1,7 @@
import { join, sep, dirname } from 'path';
import { readFile, writeFile, pathExists, move } from 'fs-extra';
import { join, sep, dirname, basename } from 'path';
import { readFile, writeFile, pathExists, move, copy } from 'fs-extra';
import { homedir } from 'os';
import execa from 'execa';
import {
glob,
@@ -29,6 +31,18 @@ interface BuildParamsType extends BuildOptions {
meta: BuildParamsMeta;
}
// Initialize private git repo for Go Modules
async function initPrivateGit(credentials: string) {
await execa('git', [
'config',
'--global',
'credential.helper',
`store --file ${join(homedir(), '.git-credentials')}`,
]);
await writeFile(join(homedir(), '.git-credentials'), credentials);
}
export const version = 2;
export const config = {
@@ -39,8 +53,14 @@ export async function build({
files,
entrypoint,
config,
workPath,
meta = {} as BuildParamsMeta,
}: BuildParamsType) {
if (process.env.GIT_CREDENTIALS && !meta.isDev) {
console.log('Initialize Git credentials...');
await initPrivateGit(process.env.GIT_CREDENTIALS);
}
console.log('Downloading user files...');
const entrypointArr = entrypoint.split(sep);
@@ -49,26 +69,12 @@ export async function build({
getWriteableDirectory(),
]);
if (meta.isDev) {
const devGoPath = `dev${entrypointArr[entrypointArr.length - 1]}`;
const goPathArr = goPath.split(sep);
goPathArr.pop();
goPathArr.push(devGoPath);
goPath = goPathArr.join(sep);
}
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];
}
}
let downloadedFiles;
if (meta.isDev) {
downloadedFiles = await download(files, workPath, meta);
} else {
downloadedFiles = await download(files, srcPath);
}
console.log(`Parsing AST for "${entrypoint}"`);
@@ -90,18 +96,71 @@ Learn more: https://zeit.co/docs/v2/deployments/official-builders/go-now-go/#ent
throw err;
}
const entrypointDirnameDev = dirname(downloadedFiles[entrypoint].fsPath);
const parsedAnalyzed = JSON.parse(analyzed) as Analyzed;
if (meta.isDev) {
const base = dirname(downloadedFiles['now.json'].fsPath);
const destNow = join(
base,
'.now',
'cache',
basename(entrypoint, '.go'),
'src',
'lambda'
);
const goMod = await pathExists(join(entrypointDirnameDev, 'go.mod'));
// this will ensure Go rebuilt fast
goPath = join(base, '.now', 'cache', basename(entrypoint, '.go'));
for (const file of parsedAnalyzed.watch) {
if (entrypointArr.length > 0) {
await copy(
join(base, dirname(entrypoint), file),
join(destNow, dirname(entrypoint), file)
);
if (goMod) {
await copy(
join(entrypointDirnameDev, 'go.mod'),
join(destNow, dirname(entrypoint), 'go.mod')
);
}
} else {
await copy(join(base, file), join(destNow, file));
if (goMod) {
await copy(
join(entrypointDirnameDev, 'go.mod'),
join(destNow, 'go.mod')
);
}
}
}
downloadedFiles = await glob('**', destNow);
}
const entrypointDirname = dirname(downloadedFiles[entrypoint].fsPath);
const input = entrypointDirname;
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];
}
}
}
const handlerFunctionName = parsedAnalyzed.functionName;
console.log(
`Found exported function "${handlerFunctionName}" in "${entrypoint}"`
);
// we need `main.go` in the same dir as the entrypoint,
// otherwise `go build` will refuse to build
const entrypointDirname = dirname(downloadedFiles[entrypoint].fsPath);
// check if package name other than main
// using `go.mod` way building the handler
const packageName = parsedAnalyzed.packageName;
const isGoModExist = await pathExists(join(entrypointDirname, 'go.mod'));
if (packageName !== 'main') {
@@ -228,6 +287,9 @@ Learn more: https://zeit.co/docs/v2/deployments/official-builders/go-now-go/#ent
);
}
} else {
// legacy mode
// we need `main.go` in the same dir as the entrypoint,
// otherwise `go build` will refuse to build
const go = await createGo(
goPath,
process.platform,

View File

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

View File

@@ -10,9 +10,22 @@ import (
"log"
"os"
"path/filepath"
"regexp"
"strings"
)
var ignoredFoldersRegex []*regexp.Regexp
func init() {
ignoredFolders := []string{"vendor", "testdata", ".now"}
// Build the regex that matches if a path contains the respective ignored folder
// The pattern will look like: (.*/)?vendor/.*, which matches every path that contains a vendor folder
for _, folder := range ignoredFolders {
ignoredFoldersRegex = append(ignoredFoldersRegex, regexp.MustCompile("(.*/)?"+folder+"/.*"))
}
}
type analyze struct {
PackageName string `json:"packageName"`
FuncName string `json:"functionName"`
@@ -40,8 +53,9 @@ func visit(files *[]string) filepath.WalkFunc {
}
// we don't need Dirs, or test files
// we only want `.go` files
if info.IsDir() || itf || filepath.Ext(path) != ".go" {
// we only want `.go` files. Further, we ignore
// every file that is in one of the ignored folders.
if info.IsDir() || itf || filepath.Ext(path) != ".go" || isInIgnoredFolder(path) {
return nil
}
@@ -50,6 +64,19 @@ func visit(files *[]string) filepath.WalkFunc {
}
}
// isInIgnoredFolder checks if the given path is in one of the ignored folders.
func isInIgnoredFolder(path string) bool {
// Make sure the regex works for Windows paths
path = filepath.ToSlash(path)
for _, pattern := range ignoredFoldersRegex {
if pattern.MatchString(path) {
return true
}
}
return false
}
// return unique file
func unique(files []string) []string {
encountered := map[string]bool{}

View File

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

View File

@@ -155,14 +155,13 @@ export const build = async ({
entrypoint,
meta = {} as BuildParamsMeta,
}: BuildParamsType): Promise<{
routes?: any[];
routes?: { src: string; dest: string }[];
output: Files;
watch?: string[];
childProcesses: ChildProcess[];
}> => {
validateEntrypoint(entrypoint);
const routes: any[] = [];
const entryDirectory = path.dirname(entrypoint);
const entryPath = path.join(workPath, entryDirectory);
const dotNext = path.join(entryPath, '.next');
@@ -191,6 +190,10 @@ export const build = async ({
console.log(`${name} Installing dependencies...`);
await runNpmInstall(entryPath, ['--prefer-offline']);
if (!process.env.NODE_ENV) {
process.env.NODE_ENV = 'development';
}
// 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);
@@ -285,7 +288,9 @@ export const build = async ({
await unlinkFile(path.join(entryPath, '.npmrc'));
}
const routes: { src: string; dest: string }[] = [];
const lambdas: { [key: string]: Lambda } = {};
const staticPages: { [key: string]: FileFsRef } = {};
if (isLegacy) {
const filesAfterBuild = await glob('**', entryPath);
@@ -377,10 +382,21 @@ export const build = async ({
fsPath: path.join(__dirname, 'launcher.js'),
}),
};
const pages = await glob(
'**/*.js',
path.join(entryPath, '.next', 'serverless', 'pages')
);
const pagesDir = path.join(entryPath, '.next', 'serverless', 'pages');
const pages = await glob('**/*.js', pagesDir);
const staticPageFiles = await glob('**/*.html', pagesDir);
Object.keys(staticPageFiles).forEach((page: string) => {
const staticRoute = path.join(entryDirectory, page);
staticPages[staticRoute] = staticPageFiles[page];
const pathname = page.replace(/\.html$/, '');
routes.push({
src: `^${path.join('/', entryDirectory, pathname)}$`,
dest: path.join('/', staticRoute),
});
});
const pageKeys = Object.keys(pages);
@@ -469,10 +485,11 @@ export const build = async ({
output: {
...publicFiles,
...lambdas,
...staticPages,
...staticFiles,
...staticDirectoryFiles,
},
routes: [],
routes,
watch: [],
childProcesses: [],
};

View File

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

View File

@@ -1,10 +1,10 @@
import { AddressInfo } from 'net';
import { APIGatewayProxyEvent } from 'aws-lambda';
import { APIGatewayProxyEvent, Context } from 'aws-lambda';
import {
Server,
IncomingHttpHeaders,
OutgoingHttpHeaders,
request
request,
} from 'http';
interface NowProxyEvent {
@@ -133,25 +133,25 @@ export class Bridge {
return this.server.listen({
host: '127.0.0.1',
port: 0
port: 0,
});
}
async launcher(
event: NowProxyEvent | APIGatewayProxyEvent
event: NowProxyEvent | APIGatewayProxyEvent,
context: Context
): Promise<NowProxyResponse> {
context.callbackWaitsForEmptyEventLoop = false;
const { port } = await this.listening;
const { isApiGateway, method, path, headers, body } = normalizeEvent(
event
);
const { isApiGateway, method, path, headers, body } = normalizeEvent(event);
const opts = {
hostname: '127.0.0.1',
port,
path,
method,
headers
headers,
};
// eslint-disable-next-line consistent-return
@@ -175,7 +175,7 @@ export class Bridge {
statusCode: response.statusCode || 200,
headers: response.headers,
body: bodyBuffer.toString('base64'),
encoding: 'base64'
encoding: 'base64',
});
});
});

View File

@@ -16,56 +16,70 @@ test('port binding', async () => {
});
test('`APIGatewayProxyEvent` normalizing', async () => {
const server = new Server((req, res) => res.end(
JSON.stringify({
method: req.method,
path: req.url,
headers: req.headers,
}),
));
const server = new Server((req, res) =>
res.end(
JSON.stringify({
method: req.method,
path: req.url,
headers: req.headers,
})
)
);
const bridge = new Bridge(server);
bridge.listen();
const result = await bridge.launcher({
httpMethod: 'GET',
headers: { foo: 'bar' },
path: '/apigateway',
body: null,
});
const context = {};
const result = await bridge.launcher(
{
httpMethod: 'GET',
headers: { foo: 'bar' },
path: '/apigateway',
body: null,
},
context
);
assert.equal(result.encoding, 'base64');
assert.equal(result.statusCode, 200);
const body = JSON.parse(Buffer.from(result.body, 'base64').toString());
assert.equal(body.method, 'GET');
assert.equal(body.path, '/apigateway');
assert.equal(body.headers.foo, 'bar');
assert.equal(context.callbackWaitsForEmptyEventLoop, false);
server.close();
});
test('`NowProxyEvent` normalizing', async () => {
const server = new Server((req, res) => res.end(
JSON.stringify({
method: req.method,
path: req.url,
headers: req.headers,
}),
));
const server = new Server((req, res) =>
res.end(
JSON.stringify({
method: req.method,
path: req.url,
headers: req.headers,
})
)
);
const bridge = new Bridge(server);
bridge.listen();
const result = await bridge.launcher({
Action: 'Invoke',
body: JSON.stringify({
method: 'POST',
headers: { foo: 'baz' },
path: '/nowproxy',
body: 'body=1',
}),
});
const context = { callbackWaitsForEmptyEventLoop: true };
const result = await bridge.launcher(
{
Action: 'Invoke',
body: JSON.stringify({
method: 'POST',
headers: { foo: 'baz' },
path: '/nowproxy',
body: 'body=1',
}),
},
context
);
assert.equal(result.encoding, 'base64');
assert.equal(result.statusCode, 200);
const body = JSON.parse(Buffer.from(result.body, 'base64').toString());
assert.equal(body.method, 'POST');
assert.equal(body.path, '/nowproxy');
assert.equal(body.headers.foo, 'baz');
assert.equal(context.callbackWaitsForEmptyEventLoop, false);
server.close();
});

View File

@@ -1,6 +1,6 @@
{
"name": "@now/node-server",
"version": "0.7.2",
"version": "0.7.3",
"license": "MIT",
"repository": {
"type": "git",
@@ -8,7 +8,7 @@
"directory": "packages/now-node-server"
},
"dependencies": {
"@now/node-bridge": "^1.1.2",
"@now/node-bridge": "^1.1.3",
"@zeit/ncc": "0.18.5",
"fs-extra": "7.0.1"
},

View File

@@ -1,6 +1,6 @@
{
"name": "@now/node",
"version": "0.7.2",
"version": "0.7.3",
"license": "MIT",
"main": "./dist/index",
"repository": {
@@ -9,7 +9,7 @@
"directory": "packages/now-node"
},
"dependencies": {
"@now/node-bridge": "^1.1.2",
"@now/node-bridge": "^1.1.3",
"@zeit/ncc": "0.18.5",
"fs-extra": "7.0.1"
},

View File

@@ -1,4 +1,4 @@
import { join, dirname } from 'path';
import { join, dirname, basename } from 'path';
import execa from 'execa';
import fs from 'fs';
import { promisify } from 'util';
@@ -73,7 +73,16 @@ export const build = async ({
meta = {},
}: BuildOptions) => {
console.log('downloading files...');
const downloadedFiles = await download(originalFiles, workPath, meta);
let downloadedFiles = await download(originalFiles, workPath, meta);
if (meta.isDev) {
const base = dirname(downloadedFiles['now.json'].fsPath);
const destNow = join(base, '.now', 'cache', basename(entrypoint, '.py'));
await download(downloadedFiles, destNow);
downloadedFiles = await glob('**', destNow);
workPath = destNow;
}
const foundLockFile = 'Pipfile.lock' in downloadedFiles;
const pyUserBase = await getWriteableDirectory();
process.env.PYTHONUSERBASE = pyUserBase;

View File

@@ -22,6 +22,7 @@ _now_imported, _now_is_legacy = _now_get_import()
if _now_is_legacy:
print('using HTTP Handler')
from http.server import HTTPServer
from urllib.parse import unquote
import requests
import _thread
server = HTTPServer(('', 0), _now_imported)
@@ -30,7 +31,7 @@ if _now_is_legacy:
_thread.start_new_thread(server.handle_request, ())
payload = json.loads(event['body'])
path = payload['path']
path = unquote(payload['path'])
headers = payload['headers']
method = payload['method']
encoding = payload.get('encoding')
@@ -53,10 +54,7 @@ if _now_is_legacy:
else:
print('using Web Server Gateway Interface (WSGI)')
import sys
try:
from urllib.parse import urlparse
except ImportError:
from urlparse import urlparse
from urllib.parse import urlparse, unquote
from werkzeug._compat import BytesIO
from werkzeug._compat import string_types
from werkzeug._compat import to_bytes
@@ -75,13 +73,14 @@ else:
if isinstance(body, string_types):
body = to_bytes(body, charset='utf-8')
urlinfo = urlparse(payload['path'])
path = unquote(payload['path'])
query = urlparse(path).query
environ = {
'CONTENT_LENGTH': str(len(body)),
'CONTENT_TYPE': headers.get('content-type', ''),
'PATH_INFO': payload['path'],
'QUERY_STRING': urlinfo.query,
'PATH_INFO': path,
'QUERY_STRING': query,
'REMOTE_ADDR': headers.get(
'x-forwarded-for', headers.get(
'x-real-ip', payload.get(
@@ -102,7 +101,7 @@ else:
}
for key, value in environ.items():
if isinstance(value, string_types):
if isinstance(value, string_types) and key != 'QUERY_STRING':
environ[key] = wsgi_encoding_dance(value)
for key, value in headers.items():

View File

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

View File

@@ -0,0 +1,7 @@
from flask import Flask, Response, __version__
app = Flask(__name__)
@app.route('/', defaults={'path': ''})
@app.route('/<path:path>')
def catch_all(path):
return Response("path=%s" %(path), mimetype='text/html')

View File

@@ -0,0 +1,7 @@
from flask import Flask, Response, __version__
app = Flask(__name__)
@app.route('/', defaults={'path': ''})
@app.route('/<path:path>')
def catch_all(path):
return Response("path=%s" %(path), mimetype='text/html')

View File

@@ -0,0 +1,13 @@
{
"version": 2,
"builds": [
{ "src": "*.py", "use": "@now/python" }
],
"routes": [
{ "src": "/another", "dest": "custom.py" }
],
"probes": [
{ "path": "/?hello=/", "mustContain": "path=?hello=/" },
{ "path": "/another?hello=/", "mustContain": "path=another?hello=/" }
]
}

View File

@@ -0,0 +1 @@
Flask==1.0.2

View File

@@ -0,0 +1,8 @@
from http.server import BaseHTTPRequestHandler
class handler(BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(200)
self.end_headers()
self.wfile.write(str("path=").encode()+self.path.encode())
return

View File

@@ -0,0 +1,8 @@
from http.server import BaseHTTPRequestHandler
class handler(BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(200)
self.end_headers()
self.wfile.write(str("path=").encode()+self.path.encode())
return

View File

@@ -0,0 +1,13 @@
{
"version": 2,
"builds": [
{ "src": "*.py", "use": "@now/python" }
],
"routes": [
{ "src": "/another", "dest": "custom.py" }
],
"probes": [
{ "path": "/?hello=/", "mustContain": "path=/?hello=/" },
{ "path": "/another?hello=/", "mustContain": "path=/another?hello=/" }
]
}

View File

@@ -88,7 +88,7 @@ exports.build = async ({
);
} catch (err) {
throw new Error(
`Failed to detect a server running on port ${devPort}`,
`Failed to detect a server running on port ${devPort}.\nDetails: https://err.sh/zeit/now-builders/now-static-build-failed-to-detect-a-server`,
);
}
@@ -101,7 +101,7 @@ exports.build = async ({
}
routes.push({
src: `${srcBase}/(.*)`,
dest: `http://localhost:${devPort}${srcBase}/$1`,
dest: `http://localhost:${devPort}/$1`,
});
} else {
if (meta.isDev) {

View File

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