Compare commits

...

24 Commits

Author SHA1 Message Date
Nathan Rajlich
0b89d30d6c Publish
- @now/build-utils@0.5.5
 - @now/cgi@0.1.4
 - @now/go@0.4.6
 - @now/mdx-deck@0.5.4
 - @now/next@0.3.2
 - @now/node-server@0.7.2
 - @now/node@0.7.2
 - @now/php@0.5.4
 - @now/python@0.2.2
 - @now/rust@0.2.4
2019-05-11 08:13:57 -07:00
Tim Neutkens
8a021c9417 [now-next] Add support for /api routes (#494) 2019-05-11 16:18:23 +02:00
Nathan Rajlich
f218771382 Publish
- @now/cgi@0.1.4-canary.0
 - @now/go@0.4.6-canary.0
 - @now/mdx-deck@0.5.4-canary.0
 - @now/node-server@0.7.2-canary.1
 - @now/node@0.7.2-canary.2
 - @now/php@0.5.4-canary.0
 - @now/python@0.2.2-canary.0
 - @now/rust@0.2.4-canary.1
2019-05-10 19:19:15 -07:00
Nathan Rajlich
17309291ed [now-node-server] Pass meta to download() function (#489) 2019-05-10 19:18:31 -07:00
Nathan Rajlich
86300577ae [now-rust] Pass meta to download() function 2019-05-10 17:14:22 -07:00
Nathan Rajlich
f9594e0d61 [now-python] Pass meta to download() function (#491) 2019-05-11 01:13:48 +02:00
Nathan Rajlich
20fd4b2e12 [now-php] Download files to workPath and pass meta (#490)
It's not clear to me why we were installing to `userfiles` directory,
so let me know if this breaks something.
2019-05-11 01:13:14 +02:00
Nathan Rajlich
718e4d0e0c [now-mdx-deck] Pass meta to download() function (#488) 2019-05-11 01:12:46 +02:00
Nathan Rajlich
dc3584cd08 [now-cgi] Download files to workPath and pass meta (#487) 2019-05-11 01:12:12 +02:00
Nathan Rajlich
b41788b241 Update yarn.lock 2019-05-10 13:17:05 -07:00
Nathan Rajlich
af9a2f9792 [now-node-server] Update @zeit/ncc to v0.18.5 2019-05-10 13:17:05 -07:00
Nathan Rajlich
f8b8e760de [now-node] Update @zeit/ncc to v0.18.5 2019-05-10 13:17:05 -07:00
Sophearak Tha
93d6ec8024 [now-go] Only use valid exported function with net/http interface (#477)
* Only use valid exported function with `net/http` interface

* Improve log, show link to docs if we coudn't parsed the entrypoint
2019-05-10 21:13:44 +07:00
Nathan Rajlich
7ed6b84056 Remove packages/now-rust/now-rust-0.2.3.tgz (#480)
It appears to have been accidentally committed in
bd2d05344e.
2019-05-08 14:50:57 -07:00
Nathan Rajlich
31da488365 Publish
- @now/build-utils@0.5.5-canary.1
 - @now/next@0.3.2-canary.1
 - @now/node@0.7.2-canary.1
2019-05-08 12:22:17 -07:00
Nathan Rajlich
8eaf05f782 Add initial CODEOWNERS file (#479)
* Add initial `CODEOWNERS` file

* Add `@now/go` to `CODEOWNERS` file
2019-05-08 12:07:32 -07:00
Nathan Rajlich
9311e90f27 [now-next] Fix failing unit test when isDev: true (#478) 2019-05-08 12:00:35 -07:00
Steven
c0de970de2 Add coverage to .gitignore (#473)
* Add coverage to `.gitignore`

* Add .tgz to `.gitignore`

* *.tgz
2019-05-07 17:57:09 -07:00
Nathan Rajlich
465ac2093d [now-node] Pass in the meta object to download() (#475)
Depends on https://github.com/zeit/now-builders/pull/474.
2019-05-07 17:56:39 -07:00
Nathan Rajlich
19ab0e8698 [now-build-utils] Make download() a no-op in now dev (#474)
This will be necessary for the update in `now dev` to have the builder
`workPath` be equal to the `cwd` source directory of the dev server.

Otherwise, unnecessary file modifications are made (copying the source
file to itself) and file corruption often occurs.
2019-05-07 17:56:16 -07:00
Steven
02fa98e5e3 Publish
- @now/build-utils@0.5.5-canary.0
 - @now/next@0.3.2-canary.0
 - @now/node-server@0.7.2-canary.0
 - @now/node@0.7.2-canary.0
 - @now/rust@0.2.4-canary.0
2019-05-07 17:08:55 -04:00
Steven
4aef9d48b0 [now-node] Bump ncc to 0.18.3 (#472) 2019-05-07 15:40:14 -04:00
Luis Fernando Alvarez D
bd2d05344e [now-next] Add public files to the output (#468) 2019-05-07 14:06:05 -05:00
Steven
edc7696623 Add newline to .gitignore 2019-05-07 09:28:59 -04:00
38 changed files with 267 additions and 92 deletions

7
.github/CODEOWNERS vendored Normal file
View File

@@ -0,0 +1,7 @@
# Documentation
# https://help.github.com/en/articles/about-code-owners
* @styfle
/packages/now-node @styfle @tootallnate
/packages/now-next @styfle @dav-is
/packages/now-go @styfle @sophearak

4
.gitignore vendored
View File

@@ -1,4 +1,6 @@
node_modules node_modules
tmp tmp
target/ target/
.next .next
coverage
*.tgz

View File

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

View File

@@ -4,11 +4,11 @@ import { File, Files, Meta } from '../types';
import { remove, mkdirp, readlink, symlink } from 'fs-extra'; import { remove, mkdirp, readlink, symlink } from 'fs-extra';
export interface DownloadedFiles { export interface DownloadedFiles {
[filePath: string]: FileFsRef [filePath: string]: FileFsRef;
} }
const S_IFMT = 61440; /* 0170000 type of file */ const S_IFMT = 61440; /* 0170000 type of file */
const S_IFLNK = 40960; /* 0120000 symbolic link */ const S_IFLNK = 40960; /* 0120000 symbolic link */
export function isSymbolicLink(mode: number): boolean { export function isSymbolicLink(mode: number): boolean {
return (mode & S_IFMT) === S_IFLNK; return (mode & S_IFMT) === S_IFLNK;
@@ -17,9 +17,9 @@ export function isSymbolicLink(mode: number): boolean {
async function downloadFile(file: File, fsPath: string): Promise<FileFsRef> { async function downloadFile(file: File, fsPath: string): Promise<FileFsRef> {
const { mode } = file; const { mode } = file;
if (mode && isSymbolicLink(mode) && file.type === 'FileFsRef') { if (mode && isSymbolicLink(mode) && file.type === 'FileFsRef') {
const [ target ] = await Promise.all([ const [target] = await Promise.all([
readlink((file as FileFsRef).fsPath), readlink((file as FileFsRef).fsPath),
mkdirp(path.dirname(fsPath)) mkdirp(path.dirname(fsPath)),
]); ]);
await symlink(target, fsPath); await symlink(target, fsPath);
return FileFsRef.fromFsPath({ mode, fsPath }); return FileFsRef.fromFsPath({ mode, fsPath });
@@ -34,12 +34,25 @@ async function removeFile(basePath: string, fileMatched: string) {
await remove(file); await remove(file);
} }
export default async function download(files: Files, basePath: string, meta?: Meta): Promise<DownloadedFiles> { export default async function download(
files: Files,
basePath: string,
meta?: Meta
): Promise<DownloadedFiles> {
const { isDev = false, filesChanged = null, filesRemoved = null } =
meta || {};
if (isDev) {
// In `now dev`, the `download()` function is a no-op because
// the `basePath` matches the `cwd` of the dev server, so the
// source files are already available.
return files as DownloadedFiles;
}
const files2: DownloadedFiles = {}; const files2: DownloadedFiles = {};
const { filesChanged = null, filesRemoved = null } = meta || {};
await Promise.all( await Promise.all(
Object.keys(files).map(async (name) => { Object.keys(files).map(async name => {
// If the file does not exist anymore, remove it. // If the file does not exist anymore, remove it.
if (Array.isArray(filesRemoved) && filesRemoved.includes(name)) { if (Array.isArray(filesRemoved) && filesRemoved.includes(name)) {
await removeFile(basePath, name); await removeFile(basePath, name);
@@ -55,7 +68,7 @@ export default async function download(files: Files, basePath: string, meta?: Me
const fsPath = path.join(basePath, name); const fsPath = path.join(basePath, name);
files2[name] = await downloadFile(file, fsPath); files2[name] = await downloadFile(file, fsPath);
}), })
); );
return files2; return files2;

View File

@@ -8,12 +8,16 @@ import FileFsRef from '../file-fs-ref';
type GlobOptions = vanillaGlob_.IOptions; type GlobOptions = vanillaGlob_.IOptions;
interface FsFiles { interface FsFiles {
[filePath: string]: FileFsRef [filePath: string]: FileFsRef;
} }
const vanillaGlob = promisify(vanillaGlob_); const vanillaGlob = promisify(vanillaGlob_);
export default async function glob(pattern: string, opts: GlobOptions | string, mountpoint?: string): Promise<FsFiles> { export default async function glob(
pattern: string,
opts: GlobOptions | string,
mountpoint?: string
): Promise<FsFiles> {
let options: GlobOptions; let options: GlobOptions;
if (typeof opts === 'string') { if (typeof opts === 'string') {
options = { cwd: opts }; options = { cwd: opts };
@@ -23,7 +27,7 @@ export default async function glob(pattern: string, opts: GlobOptions | string,
if (!options.cwd) { if (!options.cwd) {
throw new Error( throw new Error(
'Second argument (basePath) must be specified for names of resulting files', 'Second argument (basePath) must be specified for names of resulting files'
); );
} }
@@ -41,11 +45,11 @@ export default async function glob(pattern: string, opts: GlobOptions | string,
const files = await vanillaGlob(pattern, options); const files = await vanillaGlob(pattern, options);
for (const relativePath of files) { for (const relativePath of files) {
const fsPath = path.join(options.cwd!, relativePath); const fsPath = path.join(options.cwd!, relativePath).replace(/\\/g, '/');
let stat: Stats = options.statCache![fsPath] as Stats; let stat: Stats = options.statCache![fsPath] as Stats;
assert( assert(
stat, stat,
`statCache does not contain value for ${relativePath} (resolved to ${fsPath})`, `statCache does not contain value for ${relativePath} (resolved to ${fsPath})`
); );
if (stat.isFile()) { if (stat.isFile()) {
const isSymlink = options.symlinks![fsPath]; const isSymlink = options.symlinks![fsPath];

View File

@@ -9,12 +9,13 @@ const { shouldServe } = require('@now/build-utils'); // eslint-disable-line impo
exports.analyze = ({ files, entrypoint }) => files[entrypoint].digest; exports.analyze = ({ files, entrypoint }) => files[entrypoint].digest;
exports.build = async ({ files, entrypoint }) => { exports.build = async ({
workPath, files, entrypoint, meta,
}) => {
console.log('downloading files...'); console.log('downloading files...');
const srcDir = await getWritableDirectory();
const outDir = await getWritableDirectory(); const outDir = await getWritableDirectory();
await download(files, srcDir); await download(files, workPath, meta);
const handlerPath = path.join(__dirname, 'handler'); const handlerPath = path.join(__dirname, 'handler');
await copyFile(handlerPath, path.join(outDir, 'handler')); await copyFile(handlerPath, path.join(outDir, 'handler'));
@@ -24,7 +25,7 @@ exports.build = async ({ files, entrypoint }) => {
// For now only the entrypoint file is copied into the lambda // For now only the entrypoint file is copied into the lambda
await copyFile( await copyFile(
path.join(srcDir, entrypoint), path.join(workPath, entrypoint),
path.join(outDir, entrypoint), path.join(outDir, entrypoint),
); );

View File

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

View File

@@ -14,6 +14,7 @@ import {
import { createGo, getAnalyzedEntrypoint } from './go-helpers'; import { createGo, getAnalyzedEntrypoint } from './go-helpers';
interface Analyzed { interface Analyzed {
found?: boolean;
packageName: string; packageName: string;
functionName: string; functionName: string;
watch: string[]; watch: string[];
@@ -81,7 +82,9 @@ export async function build({
if (!analyzed) { if (!analyzed) {
const err = new Error( const err = new Error(
`Could not find an exported function in "${entrypoint}"` `Could not find an exported function in "${entrypoint}"
Learn more: https://zeit.co/docs/v2/deployments/official-builders/go-now-go/#entrypoint
`
); );
console.log(err.message); console.log(err.message);
throw err; throw err;

View File

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

View File

@@ -0,0 +1,22 @@
package function
import (
"fmt"
"net/http"
)
// Person struct
type Person struct {
name string
age int
}
// NewPerson struct method
func NewPerson(name string, age int) *Person {
return &Person{name: name, age: age}
}
// H func
func H(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "RANDOMNESS_PLACEHOLDER")
}

View File

@@ -0,0 +1,9 @@
{
"version": 2,
"builds": [
{ "src": "index.go", "use": "@now/go" }
],
"probes": [
{ "path": "/", "mustContain": "RANDOMNESS_PLACEHOLDER" }
]
}

View File

@@ -138,24 +138,32 @@ func main() {
} }
parsed := parse(fileName) parsed := parse(fileName)
offset := parsed.Pos()
reqRep := "*http.Request http.ResponseWriter"
for _, decl := range parsed.Decls { for _, decl := range parsed.Decls {
fn, ok := decl.(*ast.FuncDecl) fn, ok := decl.(*ast.FuncDecl)
if !ok { if !ok {
// this declaraction is not a function // this declaration is not a function
// so we're not interested // so we're not interested
continue continue
} }
if fn.Name.IsExported() == true { if fn.Name.IsExported() == true {
// we found the first exported function // find a valid `net/http` handler function
// we're done! for _, param := range fn.Type.Params.List {
analyzed := analyze{ if strings.Contains(reqRep, string(rf[param.Type.Pos()-offset:param.Type.End()-offset])) {
PackageName: parsed.Name.Name, // we found the first exported function with `net/http`
FuncName: fn.Name.Name, // we're done!
Watch: unique(relatedFiles), analyzed := analyze{
PackageName: parsed.Name.Name,
FuncName: fn.Name.Name,
Watch: unique(relatedFiles),
}
analyzedJSON, _ := json.Marshal(analyzed)
fmt.Print(string(analyzedJSON))
os.Exit(0)
}
} }
json, _ := json.Marshal(analyzed)
fmt.Print(string(json))
os.Exit(0)
} }
} }
} }

View File

@@ -8,9 +8,11 @@ const { runNpmInstall } = require('@now/build-utils/fs/run-user-scripts.js'); //
const writeFile = promisify(fs.writeFile); const writeFile = promisify(fs.writeFile);
exports.build = async ({ files, entrypoint, workPath }) => { exports.build = async ({
files, entrypoint, workPath, meta,
}) => {
console.log('downloading user files...'); console.log('downloading user files...');
const downloadedFiles = await download(files, workPath); const downloadedFiles = await download(files, workPath, meta);
console.log('writing package.json...'); console.log('writing package.json...');
const packageJson = { dependencies: { 'mdx-deck': '1.7.15' } }; const packageJson = { dependencies: { 'mdx-deck': '1.7.15' } };
const packageJsonPath = path.join(workPath, 'package.json'); const packageJsonPath = path.join(workPath, 'package.json');

View File

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

View File

@@ -1,6 +1,6 @@
{ {
"name": "@now/next", "name": "@now/next",
"version": "0.3.1", "version": "0.3.2",
"license": "MIT", "license": "MIT",
"main": "./dist/index", "main": "./dist/index",
"scripts": { "scripts": {

View File

@@ -32,7 +32,7 @@ import {
getRoutes, getRoutes,
includeOnlyEntryDirectory, includeOnlyEntryDirectory,
normalizePackageJson, normalizePackageJson,
onlyStaticDirectory, filesFromDirectory,
stringMap, stringMap,
syncEnvVars, syncEnvVars,
validateEntrypoint, validateEntrypoint,
@@ -448,13 +448,30 @@ export const build = async ({
{} {}
); );
const staticDirectoryFiles = onlyStaticDirectory( const entryDirectoryFiles = includeOnlyEntryDirectory(files, entryDirectory);
includeOnlyEntryDirectory(files, entryDirectory), const staticDirectoryFiles = filesFromDirectory(
entryDirectory entryDirectoryFiles,
path.join(entryDirectory, 'static')
);
const publicDirectoryFiles = filesFromDirectory(
entryDirectoryFiles,
path.join(entryDirectory, 'public')
);
const publicFiles = Object.keys(publicDirectoryFiles).reduce(
(mappedFiles, file) => ({
...mappedFiles,
[file.replace(/public[/\\]+/, '')]: publicDirectoryFiles[file],
}),
{}
); );
return { return {
output: { ...lambdas, ...staticFiles, ...staticDirectoryFiles }, output: {
...publicFiles,
...lambdas,
...staticFiles,
...staticDirectoryFiles,
},
routes: [], routes: [],
watch: [], watch: [],
childProcesses: [], childProcesses: [],

View File

@@ -1,12 +1,16 @@
if (!process.env.NODE_ENV) { if (!process.env.NODE_ENV) {
process.env.NODE_ENV = process.env.NOW_REGION === 'dev1' ? 'development' : 'production'; process.env.NODE_ENV =
process.env.NOW_REGION === 'dev1' ? 'development' : 'production';
} }
const { Server } = require('http'); const { Server } = require('http');
const { Bridge } = require('./now__bridge'); const { Bridge } = require('./now__bridge');
const page = require('./page'); const page = require('./page');
const server = new Server(page.render); // page.render is for React rendering
// page.default is for /api rendering
// page is for module.exports in /api
const server = new Server(page.render || page.default || page);
const bridge = new Bridge(server); const bridge = new Bridge(server);
bridge.listen(); bridge.listen();

View File

@@ -73,11 +73,11 @@ function excludeLockFiles(files: Files): Files {
} }
/** /**
* Include the static directory from files * Include only the files from a selected directory
*/ */
function onlyStaticDirectory(files: Files, entryDir: string): Files { function filesFromDirectory(files: Files, dir: string): Files {
function matcher(filePath: string) { function matcher(filePath: string) {
return !filePath.startsWith(path.join(entryDir, 'static')); return !filePath.startsWith(dir.replace(/\\/g, '/'));
} }
return excludeFiles(files, matcher); return excludeFiles(files, matcher);
@@ -195,8 +195,9 @@ function getRoutes(
dest: `${url}/static/$1`, dest: `${url}/static/$1`,
}, },
]; ];
const filePaths = Object.keys(filesInside);
for (const file of Object.keys(filesInside)) { for (const file of filePaths) {
const relativePath = path.relative(entryDirectory, file); const relativePath = path.relative(entryDirectory, file);
const isPage = pathIsInside('pages', relativePath); const isPage = pathIsInside('pages', relativePath);
@@ -227,6 +228,25 @@ function getRoutes(
} }
} }
// Add public folder routes
for (const file of filePaths) {
const relativePath = path.relative(entryDirectory, file);
const isPublic = pathIsInside('public', relativePath);
if (!isPublic) continue;
const fileName = path.relative('public', relativePath);
const route = {
src: `${prefix}${fileName}`,
dest: `${url}/${fileName}`,
};
// Only add the route if a page is not already using it
if (!routes.some(r => r.src === route.src)) {
routes.push(route);
}
}
return routes; return routes;
} }
@@ -250,7 +270,7 @@ export {
includeOnlyEntryDirectory, includeOnlyEntryDirectory,
excludeLockFiles, excludeLockFiles,
normalizePackageJson, normalizePackageJson,
onlyStaticDirectory, filesFromDirectory,
getNextConfig, getNextConfig,
getPathsInside, getPathsInside,
getRoutes, getRoutes,

View File

@@ -28,6 +28,7 @@ it(
} = await runBuildLambda(path.join(__dirname, 'monorepo')); } = await runBuildLambda(path.join(__dirname, 'monorepo'));
expect(output['www/index']).toBeDefined(); expect(output['www/index']).toBeDefined();
expect(output['www/static/test.txt']).toBeDefined(); expect(output['www/static/test.txt']).toBeDefined();
expect(output['www/data.txt']).toBeDefined();
const filePaths = Object.keys(output); const filePaths = Object.keys(output);
const hasUnderScoreAppStaticFile = filePaths.some(filePath => filePath.match(/static.*\/pages\/_app\.js$/)); const hasUnderScoreAppStaticFile = filePaths.some(filePath => filePath.match(/static.*\/pages\/_app\.js$/));
const hasUnderScoreErrorStaticFile = filePaths.some(filePath => filePath.match(/static.*\/pages\/_error\.js$/)); const hasUnderScoreErrorStaticFile = filePaths.some(filePath => filePath.match(/static.*\/pages\/_error\.js$/));
@@ -96,3 +97,14 @@ it(
}, },
FOUR_MINUTES, FOUR_MINUTES,
); );
it(
'Should build the public-files test',
async () => {
const {
buildResult: { output },
} = await runBuildLambda(path.join(__dirname, 'public-files'));
expect(output['robots.txt']).toBeDefined();
},
FOUR_MINUTES,
);

View File

@@ -0,0 +1 @@
data

View File

@@ -0,0 +1,3 @@
module.exports = {
target: 'serverless',
};

View File

@@ -0,0 +1,6 @@
{
"version": 2,
"builds": [
{"src": "next.config.js", "use": "@now/next"}
]
}

View File

@@ -0,0 +1,10 @@
{
"scripts": {
"now-build": "next build"
},
"dependencies": {
"next": "8",
"react": "16",
"react-dom": "16"
}
}

View File

@@ -0,0 +1 @@
export default () => 'Index page';

View File

@@ -0,0 +1,2 @@
User-agent: *
Disallow: /

View File

@@ -2,7 +2,7 @@
const path = require('path'); const path = require('path');
const os = require('os'); const os = require('os');
const { build } = require('@now/next'); const { build } = require('@now/next');
const { FileBlob } = require('@now/build-utils'); const { download, FileBlob } = require('@now/build-utils');
jest.setTimeout(45000); jest.setTimeout(45000);
@@ -22,6 +22,15 @@ describe('build meta dev', () => {
export default () => 'Index page' export default () => 'Index page'
`, `,
}), }),
// This file should be omitted because `pages/index.js` will use the same route
'public/index': new FileBlob({
mode: 0o777,
data: 'text',
}),
'public/data.txt': new FileBlob({
mode: 0o777,
data: 'data',
}),
'package.json': new FileBlob({ 'package.json': new FileBlob({
mode: 0o777, mode: 0o777,
data: ` data: `
@@ -46,24 +55,12 @@ describe('build meta dev', () => {
.slice(3), .slice(3),
); );
console.log('workPath directory: ', workPath); console.log('workPath directory: ', workPath);
/*
it('should have builder v2 response isDev=false', async () => {
const meta = { isDev: false, requestPath: null };
const { output, routes, watch } = await build({
files,
workPath,
entrypoint,
meta,
});
//console.log('output: ', Object.keys(output));
expect(Object.keys(output).length).toBe(7);
expect(output.index.type).toBe('Lambda');
expect(routes.length).toBe(0);
expect(watch.length).toBe(0);
});
*/
it('should have builder v2 response isDev=true', async () => { it('should have builder v2 response isDev=true', async () => {
// Since `download()` is a no-op when `isDev=true`, the assumption is that the
// source files are already present, so manually download them here first.
await download(files, workPath);
const meta = { isDev: true, requestPath: null }; const meta = { isDev: true, requestPath: null };
const { const {
output, routes, watch, childProcesses, output, routes, watch, childProcesses,
@@ -83,8 +80,15 @@ describe('build meta dev', () => {
{ src: '/static/(.*)', dest: 'http://localhost:5000/static/$1' }, { src: '/static/(.*)', dest: 'http://localhost:5000/static/$1' },
{ src: '/index', dest: 'http://localhost:5000/index' }, { src: '/index', dest: 'http://localhost:5000/index' },
{ src: '/', dest: 'http://localhost:5000/' }, { src: '/', dest: 'http://localhost:5000/' },
{ src: '/data.txt', dest: 'http://localhost:5000/data.txt' },
]);
expect(watch).toEqual([
'next.config.js',
'pages/index.js',
'public/index',
'public/data.txt',
'package.json',
]); ]);
expect(watch).toEqual(['next.config.js', 'pages/index.js', 'package.json']);
childProcesses.forEach(cp => cp.kill()); childProcesses.forEach(cp => cp.kill());
}); });
}); });

View File

@@ -28,11 +28,13 @@ const { shouldServe } = require('@now/build-utils'); // eslint-disable-line impo
* @param {string[]} [options.npmArguments] * @param {string[]} [options.npmArguments]
*/ */
async function downloadInstallAndBundle( async function downloadInstallAndBundle(
{ files, entrypoint, workPath }, {
files, entrypoint, workPath, meta,
},
{ npmArguments = [] } = {}, { npmArguments = [] } = {},
) { ) {
console.log('downloading user files...'); console.log('downloading user files...');
const downloadedFiles = await download(files, workPath); const downloadedFiles = await download(files, workPath, meta);
console.log("installing dependencies for user's code..."); console.log("installing dependencies for user's code...");
const entrypointFsDirname = path.join(workPath, path.dirname(entrypoint)); const entrypointFsDirname = path.join(workPath, path.dirname(entrypoint));
@@ -99,10 +101,12 @@ exports.config = {
* @returns {Promise<Files>} * @returns {Promise<Files>}
*/ */
exports.build = async ({ exports.build = async ({
files, entrypoint, config, workPath, files, entrypoint, config, workPath, meta,
}) => { }) => {
const [downloadedFiles, entrypointFsDirname] = await downloadInstallAndBundle( const [downloadedFiles, entrypointFsDirname] = await downloadInstallAndBundle(
{ files, entrypoint, workPath }, {
files, entrypoint, workPath, meta,
},
{ npmArguments: ['--prefer-offline'] }, { npmArguments: ['--prefer-offline'] },
); );

View File

@@ -1,6 +1,6 @@
{ {
"name": "@now/node-server", "name": "@now/node-server",
"version": "0.7.1", "version": "0.7.2",
"license": "MIT", "license": "MIT",
"repository": { "repository": {
"type": "git", "type": "git",
@@ -9,7 +9,7 @@
}, },
"dependencies": { "dependencies": {
"@now/node-bridge": "^1.1.2", "@now/node-bridge": "^1.1.2",
"@zeit/ncc": "0.18.2", "@zeit/ncc": "0.18.5",
"fs-extra": "7.0.1" "fs-extra": "7.0.1"
}, },
"scripts": { "scripts": {

View File

@@ -1,6 +1,6 @@
{ {
"name": "@now/node", "name": "@now/node",
"version": "0.7.1", "version": "0.7.2",
"license": "MIT", "license": "MIT",
"main": "./dist/index", "main": "./dist/index",
"repository": { "repository": {
@@ -10,7 +10,7 @@
}, },
"dependencies": { "dependencies": {
"@now/node-bridge": "^1.1.2", "@now/node-bridge": "^1.1.2",
"@zeit/ncc": "0.18.2", "@zeit/ncc": "0.18.5",
"fs-extra": "7.0.1" "fs-extra": "7.0.1"
}, },
"scripts": { "scripts": {

View File

@@ -6,6 +6,7 @@ import {
FileBlob, FileBlob,
FileFsRef, FileFsRef,
Files, Files,
Meta,
createLambda, createLambda,
runNpmInstall, runNpmInstall,
runPackageJsonScript, runPackageJsonScript,
@@ -22,6 +23,7 @@ interface DownloadOptions {
files: Files; files: Files;
entrypoint: string; entrypoint: string;
workPath: string; workPath: string;
meta?: Meta;
npmArguments?: string[]; npmArguments?: string[];
} }
@@ -29,10 +31,11 @@ async function downloadInstallAndBundle({
files, files,
entrypoint, entrypoint,
workPath, workPath,
meta,
npmArguments = [], npmArguments = [],
}: DownloadOptions) { }: DownloadOptions) {
console.log('downloading user files...'); console.log('downloading user files...');
const downloadedFiles = await download(files, workPath); const downloadedFiles = await download(files, workPath, meta);
console.log("installing dependencies for user's code..."); console.log("installing dependencies for user's code...");
const entrypointFsDirname = join(workPath, dirname(entrypoint)); const entrypointFsDirname = join(workPath, dirname(entrypoint));
@@ -110,6 +113,7 @@ export async function build({
entrypoint, entrypoint,
workPath, workPath,
config, config,
meta,
}: BuildOptions) { }: BuildOptions) {
const { const {
entrypointPath, entrypointPath,
@@ -118,6 +122,7 @@ export async function build({
files, files,
entrypoint, entrypoint,
workPath, workPath,
meta,
npmArguments: ['--prefer-offline'], npmArguments: ['--prefer-offline'],
}); });

View File

@@ -13,11 +13,10 @@ exports.config = {
}; };
exports.build = async ({ exports.build = async ({
files, entrypoint, workPath, config, files, entrypoint, workPath, config, meta,
}) => { }) => {
// Download all files to workPath // Download all files to workPath
const fileDir = path.join(workPath, 'userfiles'); const downloadedFiles = await download(files, workPath, meta);
const downloadedFiles = await download(files, fileDir);
let includedFiles = {}; let includedFiles = {};
if (config && config.includeFiles) { if (config && config.includeFiles) {
@@ -25,7 +24,7 @@ exports.build = async ({
// eslint-disable-next-line no-restricted-syntax // eslint-disable-next-line no-restricted-syntax
for (const pattern of config.includeFiles) { for (const pattern of config.includeFiles) {
// eslint-disable-next-line no-await-in-loop // eslint-disable-next-line no-await-in-loop
const matchedFiles = await glob(pattern, fileDir); const matchedFiles = await glob(pattern, workPath);
Object.assign(includedFiles, matchedFiles); Object.assign(includedFiles, matchedFiles);
} }
// explicit and always include the entrypoint // explicit and always include the entrypoint

View File

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

View File

@@ -73,7 +73,7 @@ export const build = async ({
meta = {}, meta = {},
}: BuildOptions) => { }: BuildOptions) => {
console.log('downloading files...'); console.log('downloading files...');
const downloadedFiles = await download(originalFiles, workPath); const downloadedFiles = await download(originalFiles, workPath, meta);
const foundLockFile = 'Pipfile.lock' in downloadedFiles; const foundLockFile = 'Pipfile.lock' in downloadedFiles;
const pyUserBase = await getWriteableDirectory(); const pyUserBase = await getWriteableDirectory();
process.env.PYTHONUSERBASE = pyUserBase; process.env.PYTHONUSERBASE = pyUserBase;

View File

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

View File

@@ -254,10 +254,10 @@ async function buildSingleFile({
exports.build = async (m) => { exports.build = async (m) => {
const { const {
files, entrypoint, workPath, config, files, entrypoint, workPath, config, meta,
} = m; } = m;
console.log('downloading files'); console.log('downloading files');
const downloadedFiles = await download(files, workPath); const downloadedFiles = await download(files, workPath, meta);
const entryPath = downloadedFiles[entrypoint].fsPath; const entryPath = downloadedFiles[entrypoint].fsPath;
await installRust(); await installRust();

View File

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

View File

@@ -28,11 +28,27 @@ async function runBuildLambda(inputPath) {
entrypoint, entrypoint,
config: build.config, config: build.config,
}); });
console.log(analyzeResult);
const workPath = await getWritableDirectory(); const workPath = await getWritableDirectory();
const buildResult = await wrapper.build({ const buildResult = await wrapper.build({
files: inputFiles, entrypoint, config: build.config, workPath, files: inputFiles,
entrypoint,
config: build.config,
workPath,
}); });
const { output } = buildResult;
// Windows support
if (output) {
buildResult.output = Object.keys(output).reduce(
(result, path) => ({
...result,
[path.replace(/\\/g, '/')]: output[path],
}),
{},
);
}
return { return {
analyzeResult, analyzeResult,
buildResult, buildResult,

View File

@@ -1135,10 +1135,10 @@
globby "8.0.0" globby "8.0.0"
signal-exit "3.0.2" signal-exit "3.0.2"
"@zeit/ncc@0.18.2": "@zeit/ncc@0.18.5":
version "0.18.2" version "0.18.5"
resolved "https://registry.yarnpkg.com/@zeit/ncc/-/ncc-0.18.2.tgz#b5f721ec1d23bfe531f3568633689ddab7c05638" resolved "https://registry.yarnpkg.com/@zeit/ncc/-/ncc-0.18.5.tgz#5687df6c32f1a2e2486aa110b3454ccebda4fb9c"
integrity sha512-liiuVTcxLaOIGQDftpZ2qhSS/vdEbuvmi2tkBWMfIwIyeKd/sh/jw+l8yONT3/unx/sSmfMTDnwfwUlY+saKiw== integrity sha512-F+SbvEAh8rchiRXqQbmD1UmbePY7dCOKTbvfFtbVbK2xMH/tyri5YKfNxXKK7eL9EWkkbqB3NTVQO6nokApeBA==
JSONStream@^1.0.4, JSONStream@^1.3.4: JSONStream@^1.0.4, JSONStream@^1.3.4:
version "1.3.5" version "1.3.5"