mirror of
https://github.com/LukeHagar/vercel.git
synced 2025-12-11 04:22:13 +00:00
Compare commits
25 Commits
@now/ruby@
...
@now/php@0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f7bc3b3490 | ||
|
|
d83b09ffbd | ||
|
|
0c120f6202 | ||
|
|
48a01415f8 | ||
|
|
9198b72382 | ||
|
|
79048b83de | ||
|
|
f798e2cf19 | ||
|
|
be5057a738 | ||
|
|
059d44fde7 | ||
|
|
11ad481546 | ||
|
|
4061ed2eb7 | ||
|
|
b54c79e619 | ||
|
|
2203ae1a20 | ||
|
|
5e58c1738b | ||
|
|
290577ddfb | ||
|
|
a5e651403e | ||
|
|
df2769717b | ||
|
|
880ef77b7b | ||
|
|
af2616c283 | ||
|
|
4300f4d797 | ||
|
|
4921e541af | ||
|
|
6ce00eda8c | ||
|
|
060e952f6c | ||
|
|
1639127b24 | ||
|
|
ebbb62eaea |
@@ -14,3 +14,4 @@
|
||||
/packages/now-rust/dist/*
|
||||
/packages/now-ruby/dist/*
|
||||
/packages/now-static-build/dist/*
|
||||
/packages/now-static-build/test/fixtures/**
|
||||
|
||||
15
.github/CODEOWNERS
vendored
15
.github/CODEOWNERS
vendored
@@ -1,10 +1,11 @@
|
||||
# Documentation
|
||||
# https://help.github.com/en/articles/about-code-owners
|
||||
|
||||
* @styfle
|
||||
/packages/now-node @styfle @tootallnate
|
||||
/packages/now-next @timer @dav-is
|
||||
/packages/now-go @styfle @sophearak
|
||||
/packages/now-python @styfle @sophearak
|
||||
/packages/now-rust @styfle @mike-engel @anmonteiro
|
||||
/packages/now-ruby @styfle @coetry @nathancahill
|
||||
* @styfle
|
||||
/packages/now-node @styfle @tootallnate @lucleray
|
||||
/packages/now-node-bridge @styfle @tootallnate @lucleray
|
||||
/packages/now-next @timer @dav-is
|
||||
/packages/now-go @styfle @sophearak
|
||||
/packages/now-python @styfle @sophearak
|
||||
/packages/now-rust @styfle @mike-engel @anmonteiro
|
||||
/packages/now-ruby @styfle @coetry @nathancahill
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
{
|
||||
"name": "@now/bash",
|
||||
"version": "0.3.0",
|
||||
"version": "1.0.0",
|
||||
"description": "Now 2.0 builder for HTTP endpoints written in Bash",
|
||||
"main": "index.js",
|
||||
"author": "Nathan Rajlich <nate@zeit.co>",
|
||||
"license": "MIT",
|
||||
"homepage": "https://zeit.co/docs/v2/deployments/official-builders/bash-now-bash",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/zeit/now-builders.git",
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
{
|
||||
"name": "@now/build-utils",
|
||||
"version": "0.7.3",
|
||||
"version": "0.8.0",
|
||||
"license": "MIT",
|
||||
"main": "./dist/index.js",
|
||||
"types": "./dist/index.d.js",
|
||||
"homepage": "https://zeit.co/docs/v2/deployments/builders/developer-guide",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/zeit/now-builders.git",
|
||||
@@ -22,6 +23,7 @@
|
||||
"fs-extra": "7.0.0",
|
||||
"glob": "7.1.3",
|
||||
"into-stream": "5.0.0",
|
||||
"minimatch": "3.0.4",
|
||||
"multistream": "2.1.1",
|
||||
"node-fetch": "2.2.0",
|
||||
"semver": "6.1.1",
|
||||
|
||||
47
packages/now-build-utils/src/detect-builder.ts
Normal file
47
packages/now-build-utils/src/detect-builder.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
import { PackageJson, Builder, Config } from './types';
|
||||
import minimatch from 'minimatch';
|
||||
|
||||
const src: string = 'package.json';
|
||||
const config: Config = { zeroConfig: true };
|
||||
|
||||
// Static builders are special cased in `@now/static-build`
|
||||
const BUILDERS = new Map<string, Builder>([
|
||||
['next', { src, use: '@now/next', config }],
|
||||
]);
|
||||
|
||||
const API_BUILDERS: Builder[] = [
|
||||
{ src: 'api/**/*.js', use: '@now/node', config },
|
||||
{ src: 'api/**/*.ts', use: '@now/node', config },
|
||||
{ src: 'api/**/*.rs', use: '@now/rust', config },
|
||||
{ src: 'api/**/*.go', use: '@now/go', config },
|
||||
{ src: 'api/**/*.php', use: '@now/php', config },
|
||||
{ src: 'api/**/*.py', use: '@now/python', config },
|
||||
{ src: 'api/**/*.rb', use: '@now/ruby', config },
|
||||
{ src: 'api/**/*.sh', use: '@now/bash', config },
|
||||
];
|
||||
|
||||
export async function detectBuilder(pkg: PackageJson): Promise<Builder> {
|
||||
for (const [dependency, builder] of BUILDERS) {
|
||||
const deps = Object.assign({}, pkg.dependencies, pkg.devDependencies);
|
||||
|
||||
// Return the builder when a dependency matches
|
||||
if (deps[dependency]) {
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
|
||||
// By default we'll choose the `static-build` builder
|
||||
return { src, use: '@now/static-build', config };
|
||||
}
|
||||
|
||||
export async function detectApiBuilders(
|
||||
files: string[]
|
||||
): Promise<Builder[] | null> {
|
||||
const builds = files.map(file => {
|
||||
return API_BUILDERS.find(({ src }): boolean => minimatch(file, src));
|
||||
});
|
||||
|
||||
// We can use `new Set` here since `builds` contains references to `API_BUILDERS`
|
||||
const finishedBuilds = Array.from(new Set(builds.filter(Boolean)));
|
||||
return finishedBuilds.length > 0 ? (finishedBuilds as Builder[]) : null;
|
||||
}
|
||||
239
packages/now-build-utils/src/detect-routes.ts
Normal file
239
packages/now-build-utils/src/detect-routes.ts
Normal file
@@ -0,0 +1,239 @@
|
||||
import path from 'path';
|
||||
import { Route } from './types';
|
||||
|
||||
function concatArrayOfText(texts: string[]): string {
|
||||
const last = texts.pop();
|
||||
return `${texts.join(', ')}, and ${last}`;
|
||||
}
|
||||
|
||||
// Takes a filename or foldername, strips the extension
|
||||
// gets the part between the "[]" brackets.
|
||||
// It will return `null` if there are no brackets
|
||||
// and therefore no segment.
|
||||
function getSegmentName(segment: string): string | null {
|
||||
const { name } = path.parse(segment);
|
||||
|
||||
if (name.startsWith('[') && name.endsWith(']')) {
|
||||
return name.slice(1, -1);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function createRouteFromPath(filePath: string): Route {
|
||||
const parts = filePath.split('/');
|
||||
|
||||
let append: string = '';
|
||||
let counter: number = 1;
|
||||
const query: string[] = [];
|
||||
|
||||
const srcParts = parts.map(
|
||||
(segment, index): string => {
|
||||
const name = getSegmentName(segment);
|
||||
const isLast = index === parts.length - 1;
|
||||
|
||||
if (name !== null) {
|
||||
query.push(`${name}=$${counter++}`);
|
||||
|
||||
if (isLast) {
|
||||
// We append this to the last one
|
||||
// to make sure GET params still work
|
||||
// and are just appended to our GET params
|
||||
append += `$${counter++}`;
|
||||
return `([^\\/|\\?]+)\\/?(?:\\?(.*))?`;
|
||||
}
|
||||
|
||||
return `([^\\/]+)`;
|
||||
} else if (isLast) {
|
||||
// If it is the last part we want to remove the extension
|
||||
// and capture everything after that as regex group and append it
|
||||
const { name: fileName } = path.parse(segment);
|
||||
append += `$${counter++}`;
|
||||
return `${fileName}(.*)`;
|
||||
}
|
||||
|
||||
return segment;
|
||||
}
|
||||
);
|
||||
|
||||
const src = `^/${srcParts.join('/')}$`;
|
||||
const dest = `/${filePath}${query.length ? '?' : ''}${query.join('&')}${
|
||||
query.length ? '&' : ''
|
||||
}${append}`;
|
||||
|
||||
return { src, dest };
|
||||
}
|
||||
|
||||
// Check if the path partially matches and has the same
|
||||
// name for the path segment at the same position
|
||||
function partiallyMatches(pathA: string, pathB: string): boolean {
|
||||
const partsA = pathA.split('/');
|
||||
const partsB = pathB.split('/');
|
||||
|
||||
const long = partsA.length > partsB.length ? partsA : partsB;
|
||||
const short = long === partsA ? partsB : partsA;
|
||||
|
||||
let index = 0;
|
||||
|
||||
for (const segmentShort of short) {
|
||||
const segmentLong = long[index];
|
||||
|
||||
const nameLong = getSegmentName(segmentLong);
|
||||
const nameShort = getSegmentName(segmentShort);
|
||||
|
||||
// If there are no segments or the paths differ we
|
||||
// return as they are not matching
|
||||
if (segmentShort !== segmentLong && (!nameLong || !nameShort)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (nameLong !== nameShort) {
|
||||
return true;
|
||||
}
|
||||
|
||||
index += 1;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Counts how often a path occurres when all placeholders
|
||||
// got resolved, so we can check if they have conflicts
|
||||
function pathOccurrences(filePath: string, files: string[]): string[] {
|
||||
const getAbsolutePath = (unresolvedPath: string): string => {
|
||||
const { dir, name } = path.parse(unresolvedPath);
|
||||
const parts = path.join(dir, name).split('/');
|
||||
return parts.map(part => part.replace(/\[.*\]/, '1')).join('/');
|
||||
};
|
||||
|
||||
const currentAbsolutePath = getAbsolutePath(filePath);
|
||||
|
||||
return files.reduce((prev: string[], file: string): string[] => {
|
||||
const absolutePath = getAbsolutePath(file);
|
||||
|
||||
if (absolutePath === currentAbsolutePath) {
|
||||
prev.push(file);
|
||||
} else if (partiallyMatches(filePath, file)) {
|
||||
prev.push(file);
|
||||
}
|
||||
|
||||
return prev;
|
||||
}, []);
|
||||
}
|
||||
|
||||
// Checks if a placeholder with the same name is used
|
||||
// multiple times inside the same path
|
||||
function getConflictingSegment(filePath: string): string | null {
|
||||
const segments = new Set<string>();
|
||||
|
||||
for (const segment of filePath.split('/')) {
|
||||
const name = getSegmentName(segment);
|
||||
|
||||
if (name !== null && segments.has(name)) {
|
||||
return name;
|
||||
}
|
||||
|
||||
if (name) {
|
||||
segments.add(name);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function sortFilesBySegmentCount(fileA: string, fileB: string): number {
|
||||
const lengthA = fileA.split('/').length;
|
||||
const lengthB = fileB.split('/').length;
|
||||
|
||||
if (lengthA > lengthB) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (lengthA < lengthB) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Paths that have the same segment length but
|
||||
// less placeholders are preferred
|
||||
const countSegments = (prev: number, segment: string) =>
|
||||
getSegmentName(segment) ? prev + 1 : 0;
|
||||
const segmentLengthA = fileA.split('/').reduce(countSegments, 0);
|
||||
const segmentLengthB = fileB.split('/').reduce(countSegments, 0);
|
||||
|
||||
if (segmentLengthA > segmentLengthB) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (segmentLengthA < segmentLengthB) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
export async function detectApiRoutes(
|
||||
files: string[]
|
||||
): Promise<{
|
||||
defaultRoutes: Route[] | null;
|
||||
error: { [key: string]: string } | null;
|
||||
}> {
|
||||
if (!files || files.length === 0) {
|
||||
return { defaultRoutes: null, error: null };
|
||||
}
|
||||
|
||||
// The deepest routes need to be
|
||||
// the first ones to get handled
|
||||
const sortedFiles = files.sort(sortFilesBySegmentCount);
|
||||
|
||||
const defaultRoutes: Route[] = [];
|
||||
|
||||
for (const file of sortedFiles) {
|
||||
// We only consider every file in the api directory
|
||||
// as we will strip extensions as well as resolving "[segments]"
|
||||
if (!file.startsWith('api/')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const conflictingSegment = getConflictingSegment(file);
|
||||
|
||||
console.log({ file, conflictingSegment });
|
||||
|
||||
if (conflictingSegment) {
|
||||
return {
|
||||
defaultRoutes: null,
|
||||
error: {
|
||||
code: 'conflicting_path_segment',
|
||||
message:
|
||||
`The segment "${conflictingSegment}" occurres more than ` +
|
||||
`one time in your path "${file}". Please make sure that ` +
|
||||
`every segment in a path is unique`,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
const occurrences = pathOccurrences(file, sortedFiles).filter(
|
||||
name => name !== file
|
||||
);
|
||||
|
||||
if (occurrences.length > 0) {
|
||||
const messagePaths = concatArrayOfText(
|
||||
occurrences.map(name => `"${name}"`)
|
||||
);
|
||||
|
||||
return {
|
||||
defaultRoutes: null,
|
||||
error: {
|
||||
code: 'conflicting_file_path',
|
||||
message:
|
||||
`Two or more files have conflicting paths or names. ` +
|
||||
`Please make sure path segments and filenames, without their extension, are unique. ` +
|
||||
`The path "${file}" has conflicts with ${messagePaths}`,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
defaultRoutes.push(createRouteFromPath(file));
|
||||
}
|
||||
|
||||
return { defaultRoutes, error: null };
|
||||
}
|
||||
@@ -39,10 +39,10 @@ export default async function download(
|
||||
basePath: string,
|
||||
meta?: Meta
|
||||
): Promise<DownloadedFiles> {
|
||||
const { isDev = false, filesChanged = null, filesRemoved = null } =
|
||||
const { isDev = false, skipDownload = false, filesChanged = null, filesRemoved = null } =
|
||||
meta || {};
|
||||
|
||||
if (isDev) {
|
||||
if (isDev || skipDownload) {
|
||||
// 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.
|
||||
|
||||
@@ -13,15 +13,18 @@ export const defaultSelection = supportedOptions.find(
|
||||
) as NodeVersion;
|
||||
|
||||
export async function getSupportedNodeVersion(
|
||||
engineRange?: string
|
||||
engineRange?: string,
|
||||
silent?: boolean
|
||||
): Promise<NodeVersion> {
|
||||
let selection = defaultSelection;
|
||||
|
||||
if (!engineRange) {
|
||||
console.log(
|
||||
'missing `engines` in `package.json`, using default range: ' +
|
||||
selection.range
|
||||
);
|
||||
if (!silent) {
|
||||
console.log(
|
||||
'missing `engines` in `package.json`, using default range: ' +
|
||||
selection.range
|
||||
);
|
||||
}
|
||||
} else {
|
||||
const found = supportedOptions.some(o => {
|
||||
// the array is already in order so return the first
|
||||
@@ -30,15 +33,20 @@ export async function getSupportedNodeVersion(
|
||||
return intersects(o.range, engineRange);
|
||||
});
|
||||
if (found) {
|
||||
console.log(
|
||||
'found `engines` in `package.json`, selecting range: ' + selection.range
|
||||
);
|
||||
if (!silent) {
|
||||
console.log(
|
||||
'Found `engines` in `package.json`, selecting range: ' +
|
||||
selection.range
|
||||
);
|
||||
}
|
||||
} else {
|
||||
throw new Error(
|
||||
'found `engines` in `package.json` with an unsupported node range: ' +
|
||||
engineRange +
|
||||
'\nplease use `10.x` or `8.10.x` instead'
|
||||
);
|
||||
if (!silent) {
|
||||
throw new Error(
|
||||
'found `engines` in `package.json` with an unsupported node range: ' +
|
||||
engineRange +
|
||||
'\nplease use `10.x` or `8.10.x` instead'
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
return selection;
|
||||
|
||||
@@ -46,11 +46,15 @@ async function chmodPlusX(fsPath: string) {
|
||||
await fs.chmod(fsPath, base8);
|
||||
}
|
||||
|
||||
export async function runShellScript(fsPath: string) {
|
||||
export async function runShellScript(
|
||||
fsPath: string,
|
||||
args: string[] = [],
|
||||
spawnOpts?: SpawnOptions
|
||||
) {
|
||||
assert(path.isAbsolute(fsPath));
|
||||
const destPath = path.dirname(fsPath);
|
||||
await chmodPlusX(fsPath);
|
||||
await spawnAsync(`./${path.basename(fsPath)}`, [], destPath);
|
||||
await spawnAsync(`./${path.basename(fsPath)}`, args, destPath, spawnOpts);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -69,10 +73,15 @@ export function getSpawnOptions(
|
||||
return opts;
|
||||
}
|
||||
|
||||
export async function getNodeVersion(destPath: string): Promise<NodeVersion> {
|
||||
export async function getNodeVersion(
|
||||
destPath: string,
|
||||
minNodeVersion?: string
|
||||
): Promise<NodeVersion> {
|
||||
const { packageJson } = await scanParentDirs(destPath, true);
|
||||
const range = packageJson && packageJson.engines && packageJson.engines.node;
|
||||
return getSupportedNodeVersion(range);
|
||||
const range =
|
||||
(packageJson && packageJson.engines && packageJson.engines.node) ||
|
||||
minNodeVersion;
|
||||
return getSupportedNodeVersion(range, typeof minNodeVersion !== 'undefined');
|
||||
}
|
||||
|
||||
async function scanParentDirs(destPath: string, readPackageJson = false) {
|
||||
@@ -130,7 +139,13 @@ export async function runNpmInstall(
|
||||
} else {
|
||||
await spawnAsync(
|
||||
'yarn',
|
||||
commandArgs.concat(['--ignore-engines', '--cwd', destPath]),
|
||||
commandArgs.concat([
|
||||
'--ignore-engines',
|
||||
'--mutex',
|
||||
'network',
|
||||
'--cwd',
|
||||
destPath,
|
||||
]),
|
||||
destPath,
|
||||
opts
|
||||
);
|
||||
|
||||
@@ -1,16 +1,6 @@
|
||||
import FileBlob from './file-blob';
|
||||
import FileFsRef from './file-fs-ref';
|
||||
import FileRef from './file-ref';
|
||||
import {
|
||||
File,
|
||||
Files,
|
||||
AnalyzeOptions,
|
||||
BuildOptions,
|
||||
PrepareCacheOptions,
|
||||
ShouldServeOptions,
|
||||
Meta,
|
||||
Config,
|
||||
} from './types';
|
||||
import { Lambda, createLambda } from './lambda';
|
||||
import download, { DownloadedFiles } from './fs/download';
|
||||
import getWriteableDirectory from './fs/get-writable-directory';
|
||||
@@ -26,14 +16,13 @@ import {
|
||||
} from './fs/run-user-scripts';
|
||||
import streamToBuffer from './fs/stream-to-buffer';
|
||||
import shouldServe from './should-serve';
|
||||
import { detectBuilder, detectApiBuilders } from './detect-builder';
|
||||
import { detectApiRoutes } from './detect-routes';
|
||||
|
||||
export {
|
||||
FileBlob,
|
||||
FileFsRef,
|
||||
FileRef,
|
||||
Files,
|
||||
File,
|
||||
Meta,
|
||||
Lambda,
|
||||
createLambda,
|
||||
download,
|
||||
@@ -48,10 +37,10 @@ export {
|
||||
getNodeVersion,
|
||||
getSpawnOptions,
|
||||
streamToBuffer,
|
||||
AnalyzeOptions,
|
||||
BuildOptions,
|
||||
PrepareCacheOptions,
|
||||
ShouldServeOptions,
|
||||
shouldServe,
|
||||
Config,
|
||||
detectBuilder,
|
||||
detectApiBuilders,
|
||||
detectApiRoutes,
|
||||
};
|
||||
|
||||
export * from './types';
|
||||
|
||||
@@ -15,6 +15,16 @@ export interface Files {
|
||||
[filePath: string]: File;
|
||||
}
|
||||
|
||||
export interface Route {
|
||||
src?: string;
|
||||
dest?: string;
|
||||
handle?: string;
|
||||
type?: string;
|
||||
headers?: {
|
||||
[key: string]: string;
|
||||
};
|
||||
}
|
||||
|
||||
export interface Config {
|
||||
[key: string]:
|
||||
| string
|
||||
@@ -36,6 +46,7 @@ export interface Config {
|
||||
|
||||
export interface Meta {
|
||||
isDev?: boolean;
|
||||
skipDownload?: boolean;
|
||||
requestPath?: string;
|
||||
filesChanged?: string[];
|
||||
filesRemoved?: string[];
|
||||
@@ -195,3 +206,9 @@ export interface NodeVersion {
|
||||
range: string;
|
||||
runtime: string;
|
||||
}
|
||||
|
||||
export interface Builder {
|
||||
use: string;
|
||||
src: string;
|
||||
config?: Config;
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
{
|
||||
"src": "index.js",
|
||||
"use": "@now/node",
|
||||
"config": { "maxLambdaSize": "15mb" }
|
||||
"config": { "maxLambdaSize": "18mb" }
|
||||
}
|
||||
],
|
||||
"probes": [{ "path": "/", "mustContain": "found:RANDOMNESS_PLACEHOLDER" }]
|
||||
|
||||
@@ -16,6 +16,12 @@ const {
|
||||
testDeployment,
|
||||
} = require('../../../test/lib/deployment/test-deployment.js');
|
||||
|
||||
const {
|
||||
detectBuilder,
|
||||
detectApiBuilders,
|
||||
detectApiRoutes,
|
||||
} = require('../dist');
|
||||
|
||||
jest.setTimeout(4 * 60 * 1000);
|
||||
const builderUrl = '@canary';
|
||||
let buildUtilsUrl;
|
||||
@@ -158,3 +164,84 @@ for (const builder of buildersToTestWith) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
it('Test `detectBuilder`', async () => {
|
||||
{
|
||||
const pkg = { dependencies: { next: '1.0.0' } };
|
||||
const builder = await detectBuilder(pkg);
|
||||
expect(builder.use).toBe('@now/next');
|
||||
}
|
||||
|
||||
{
|
||||
const pkg = { devDependencies: { next: '1.0.0' } };
|
||||
const builder = await detectBuilder(pkg);
|
||||
expect(builder.use).toBe('@now/next');
|
||||
}
|
||||
|
||||
{
|
||||
const pkg = {};
|
||||
const builder = await detectBuilder(pkg);
|
||||
expect(builder.use).toBe('@now/static-build');
|
||||
}
|
||||
});
|
||||
|
||||
it('Test `detectApiBuilders`', async () => {
|
||||
{
|
||||
const files = ['package.json', 'api/user.js', 'api/team.js'];
|
||||
|
||||
const builders = await detectApiBuilders(files);
|
||||
expect(builders[0].use).toBe('@now/node');
|
||||
}
|
||||
|
||||
{
|
||||
const files = ['package.json', 'api/user.go', 'api/team.js'];
|
||||
|
||||
const builders = await detectApiBuilders(files);
|
||||
expect(builders.some(({ use }) => use === '@now/go')).toBeTruthy();
|
||||
expect(builders.some(({ use }) => use === '@now/node')).toBeTruthy();
|
||||
}
|
||||
|
||||
{
|
||||
const files = ['package.json'];
|
||||
|
||||
const builders = await detectApiBuilders(files);
|
||||
expect(builders).toBe(null);
|
||||
}
|
||||
});
|
||||
|
||||
it('Test `detectApiRoutes`', async () => {
|
||||
{
|
||||
const files = ['api/user.go', 'api/team.js'];
|
||||
|
||||
const { defaultRoutes } = await detectApiRoutes(files);
|
||||
expect(defaultRoutes.length).toBe(2);
|
||||
}
|
||||
|
||||
{
|
||||
const files = ['api/user.go', 'api/user.js'];
|
||||
|
||||
const { error } = await detectApiRoutes(files);
|
||||
expect(error.code).toBe('conflicting_file_path');
|
||||
}
|
||||
|
||||
{
|
||||
const files = ['api/[user].go', 'api/[team]/[id].js'];
|
||||
|
||||
const { error } = await detectApiRoutes(files);
|
||||
expect(error.code).toBe('conflicting_file_path');
|
||||
}
|
||||
|
||||
{
|
||||
const files = ['api/[team]/[team].js'];
|
||||
|
||||
const { error } = await detectApiRoutes(files);
|
||||
expect(error.code).toBe('conflicting_path_segment');
|
||||
}
|
||||
|
||||
{
|
||||
const files = ['api/[endpoint].js', 'api/[endpoint]/[id].js'];
|
||||
|
||||
const { defaultRoutes } = await detectApiRoutes(files);
|
||||
expect(defaultRoutes.length).toBe(2);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
{
|
||||
"name": "@now/go",
|
||||
"version": "0.5.3",
|
||||
"version": "0.5.4",
|
||||
"license": "MIT",
|
||||
"homepage": "https://zeit.co/docs/v2/deployments/official-builders/go-now-go",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/zeit/now-builders.git",
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
{
|
||||
"name": "@now/html-minifier",
|
||||
"version": "1.1.3",
|
||||
"version": "1.1.4",
|
||||
"license": "MIT",
|
||||
"homepage": "https://zeit.co/docs/v2/deployments/official-builders/html-minifier-now-html-minifier",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/zeit/now-builders.git",
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
{
|
||||
"name": "@now/md",
|
||||
"version": "0.5.4",
|
||||
"version": "0.5.5",
|
||||
"license": "MIT",
|
||||
"homepage": "https://zeit.co/docs/v2/deployments/official-builders/markdown-now-md",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/zeit/now-builders.git",
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
{
|
||||
"name": "@now/mdx-deck",
|
||||
"version": "0.5.4",
|
||||
"version": "0.5.5",
|
||||
"license": "MIT",
|
||||
"homepage": "https://zeit.co/docs/v2/deployments/official-builders/mdx-deck-now-mdx-deck",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/zeit/now-builders.git",
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
{
|
||||
"name": "@now/next",
|
||||
"version": "0.5.1",
|
||||
"version": "0.5.3",
|
||||
"license": "MIT",
|
||||
"main": "./dist/index",
|
||||
"homepage": "https://zeit.co/docs/v2/deployments/official-builders/next-js-now-next",
|
||||
"scripts": {
|
||||
"build": "./getBridgeTypes.sh && tsc",
|
||||
"test": "npm run build && jest",
|
||||
|
||||
@@ -165,6 +165,8 @@ export const build = async ({
|
||||
watch?: string[];
|
||||
childProcesses: ChildProcess[];
|
||||
}> => {
|
||||
process.env.__NEXT_BUILDER_EXPERIMENTAL_TARGET = 'serverless';
|
||||
|
||||
validateEntrypoint(entrypoint);
|
||||
|
||||
const entryDirectory = path.dirname(entrypoint);
|
||||
@@ -186,11 +188,7 @@ export const build = async ({
|
||||
);
|
||||
}
|
||||
|
||||
process.env.__NEXT_BUILDER_EXPERIMENTAL_TARGET = 'serverless';
|
||||
|
||||
if (meta.isDev) {
|
||||
// eslint-disable-next-line no-underscore-dangle
|
||||
process.env.__NEXT_BUILDER_EXPERIMENTAL_DEBUG = 'true';
|
||||
let childProcess: ChildProcess | undefined;
|
||||
|
||||
// If this is the initial build, we want to start the server
|
||||
@@ -287,10 +285,9 @@ export const build = async ({
|
||||
|
||||
console.log('running user script...');
|
||||
const memoryToConsume = Math.floor(os.totalmem() / 1024 ** 2) - 128;
|
||||
const buildSpawnOptions = { ...spawnOpts };
|
||||
const env = { ...buildSpawnOptions.env } as any;
|
||||
const env = { ...spawnOpts.env } as any;
|
||||
env.NODE_OPTIONS = `--max_old_space_size=${memoryToConsume}`;
|
||||
await runPackageJsonScript(entryPath, 'now-build', buildSpawnOptions);
|
||||
await runPackageJsonScript(entryPath, 'now-build', { ...spawnOpts, env });
|
||||
|
||||
if (isLegacy) {
|
||||
console.log('running npm install --production...');
|
||||
@@ -389,7 +386,7 @@ export const build = async ({
|
||||
'now__launcher.js': new FileBlob({ data: launcher }),
|
||||
},
|
||||
handler: 'now__launcher.launcher',
|
||||
runtime: 'nodejs8.10',
|
||||
runtime: nodeVersion.runtime,
|
||||
});
|
||||
console.log(`Created lambda for page: "${page}"`);
|
||||
})
|
||||
@@ -474,7 +471,7 @@ export const build = async ({
|
||||
'page.js': pages[page],
|
||||
},
|
||||
handler: 'now__launcher.launcher',
|
||||
runtime: 'nodejs8.10',
|
||||
runtime: nodeVersion.runtime,
|
||||
});
|
||||
console.log(`Created lambda for page: "${page}"`);
|
||||
})
|
||||
|
||||
@@ -10,7 +10,8 @@ it(
|
||||
const {
|
||||
buildResult: { output },
|
||||
} = await runBuildLambda(path.join(__dirname, 'standard'));
|
||||
expect(output.index).toBeDefined();
|
||||
expect(output['index.html']).toBeDefined();
|
||||
expect(output.goodbye).toBeDefined();
|
||||
const filePaths = Object.keys(output);
|
||||
const serverlessError = filePaths.some(filePath => filePath.match(/_error/));
|
||||
const hasUnderScoreAppStaticFile = filePaths.some(filePath => filePath.match(/static.*\/pages\/_app\.js$/));
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
module.exports = {
|
||||
target: 'serverless',
|
||||
};
|
||||
@@ -1,4 +1,4 @@
|
||||
{
|
||||
"version": 2,
|
||||
"builds": [{ "src": "next.config.js", "use": "@now/next" }]
|
||||
"builds": [{ "src": "package.json", "use": "@now/next" }]
|
||||
}
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
const F = () => 'Goodbye World!';
|
||||
F.getInitialProps = () => ({});
|
||||
export default F;
|
||||
@@ -157,10 +157,13 @@ exports.build = async ({
|
||||
'bridge.js': new FileFsRef({ fsPath: require('@now/node-bridge') }),
|
||||
};
|
||||
|
||||
// Use the system-installed version of `node` when running via `now dev`
|
||||
const runtime = meta.isDev ? 'nodejs' : nodeVersion.runtime;
|
||||
|
||||
const lambda = await createLambda({
|
||||
files: { ...preparedFiles, ...launcherFiles },
|
||||
handler: 'launcher.launcher',
|
||||
runtime: nodeVersion.runtime,
|
||||
runtime,
|
||||
});
|
||||
|
||||
return { [entrypoint]: lambda };
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
{
|
||||
"name": "@now/node-server",
|
||||
"version": "0.8.1",
|
||||
"version": "0.8.2",
|
||||
"license": "MIT",
|
||||
"homepage": "https://zeit.co/docs/v2/deployments/official-builders/node-js-server-now-node-server",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/zeit/now-builders.git",
|
||||
|
||||
1
packages/now-node/bench/.gitignore
vendored
Normal file
1
packages/now-node/bench/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
lambda
|
||||
19
packages/now-node/bench/entrypoint-express.js
Normal file
19
packages/now-node/bench/entrypoint-express.js
Normal file
@@ -0,0 +1,19 @@
|
||||
const express = require('express');
|
||||
|
||||
const app = express();
|
||||
|
||||
module.exports = app;
|
||||
|
||||
app.use(express.json());
|
||||
|
||||
app.post('*', (req, res) => {
|
||||
if (req.body == null) {
|
||||
return res.status(400).send({ error: 'no JSON object in the request' });
|
||||
}
|
||||
|
||||
return res.status(200).send(JSON.stringify(req.body, null, 4));
|
||||
});
|
||||
|
||||
app.all('*', (req, res) => {
|
||||
res.status(405).send({ error: 'only POST requests are accepted' });
|
||||
});
|
||||
7
packages/now-node/bench/entrypoint-helpers.js
Normal file
7
packages/now-node/bench/entrypoint-helpers.js
Normal file
@@ -0,0 +1,7 @@
|
||||
module.exports = (req, res) => {
|
||||
if (req.body == null) {
|
||||
return res.status(400).send({ error: 'no JSON object in the request' });
|
||||
}
|
||||
|
||||
return res.status(200).send(JSON.stringify(req.body, null, 4));
|
||||
};
|
||||
9
packages/now-node/bench/entrypoint-load-helpers.js
Normal file
9
packages/now-node/bench/entrypoint-load-helpers.js
Normal file
@@ -0,0 +1,9 @@
|
||||
function doNothing() {}
|
||||
|
||||
module.exports = (req, res) => {
|
||||
doNothing(req.query.who);
|
||||
doNothing(req.body);
|
||||
doNothing(req.cookies);
|
||||
|
||||
res.end('hello');
|
||||
};
|
||||
3
packages/now-node/bench/entrypoint-notload-helpers.js
Normal file
3
packages/now-node/bench/entrypoint-notload-helpers.js
Normal file
@@ -0,0 +1,3 @@
|
||||
module.exports = (req, res) => {
|
||||
res.end('hello');
|
||||
};
|
||||
10
packages/now-node/bench/package.json
Normal file
10
packages/now-node/bench/package.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"name": "bench",
|
||||
"version": "1.0.0",
|
||||
"main": "index.js",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"express": "4.17.1",
|
||||
"fs-extra": "8.0.1"
|
||||
}
|
||||
}
|
||||
91
packages/now-node/bench/run.js
Normal file
91
packages/now-node/bench/run.js
Normal file
@@ -0,0 +1,91 @@
|
||||
const fs = require('fs-extra');
|
||||
const { join } = require('path');
|
||||
const { makeLauncher } = require('../dist/launcher');
|
||||
|
||||
const setupFiles = async (entrypoint, shouldAddHelpers) => {
|
||||
await fs.remove(join(__dirname, 'lambda'));
|
||||
await fs.ensureDir(join(__dirname, 'lambda'));
|
||||
|
||||
await fs.copyFile(
|
||||
join(__dirname, '../dist/helpers.js'),
|
||||
join(__dirname, 'lambda/helpers.js'),
|
||||
);
|
||||
await fs.copyFile(
|
||||
require.resolve('@now/node-bridge/bridge'),
|
||||
join(__dirname, 'lambda/bridge.js'),
|
||||
);
|
||||
await fs.copyFile(
|
||||
join(process.cwd(), entrypoint),
|
||||
join(__dirname, 'lambda/entrypoint.js'),
|
||||
);
|
||||
|
||||
let launcher = makeLauncher('./entrypoint', shouldAddHelpers);
|
||||
launcher += '\nexports.bridge=bridge';
|
||||
|
||||
await fs.writeFile(join(__dirname, 'lambda/launcher.js'), launcher);
|
||||
};
|
||||
|
||||
const createBigJSONObj = () => {
|
||||
const obj = {};
|
||||
for (let i = 0; i < 1000; i += 1) {
|
||||
obj[`idx${i}`] = `val${i}`;
|
||||
}
|
||||
};
|
||||
|
||||
const createEvent = () => ({
|
||||
Action: 'Invoke',
|
||||
body: JSON.stringify({
|
||||
method: 'POST',
|
||||
path: '/',
|
||||
headers: { 'content-type': 'application/json' },
|
||||
encoding: undefined,
|
||||
body: createBigJSONObj(),
|
||||
}),
|
||||
});
|
||||
|
||||
const runTests = async (entrypoint, shouldAddHelpers = true, nb) => {
|
||||
console.log(
|
||||
`setting up files with entrypoint ${entrypoint} and ${
|
||||
shouldAddHelpers ? 'helpers' : 'no helpers'
|
||||
}`,
|
||||
);
|
||||
await setupFiles(entrypoint, shouldAddHelpers);
|
||||
|
||||
console.log('importing launcher');
|
||||
const launcher = require('./lambda/launcher');
|
||||
|
||||
const event = createEvent();
|
||||
const context = {};
|
||||
|
||||
const start = process.hrtime();
|
||||
|
||||
console.log(`throwing ${nb} events at lambda`);
|
||||
for (let i = 0; i < nb; i += 1) {
|
||||
// eslint-disable-next-line
|
||||
await launcher.launcher(event, context);
|
||||
}
|
||||
const timer = process.hrtime(start);
|
||||
const ms = (timer[0] * 1e9 + timer[1]) / 1e6;
|
||||
|
||||
await launcher.bridge.server.close();
|
||||
delete require.cache[require.resolve('./lambda/launcher')];
|
||||
|
||||
console.log({ nb, sum: ms, avg: ms / nb });
|
||||
};
|
||||
|
||||
const main = async () => {
|
||||
if (process.argv.length !== 5) {
|
||||
console.log(
|
||||
'usage : node run.js <entrypoint-file> <add-helpers> <nb-of-request>',
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
const [, , entrypoint, helpers, nbRequests] = process.argv;
|
||||
const shouldAddHelpers = helpers !== 'false' && helpers !== 'no';
|
||||
const nb = Number(nbRequests);
|
||||
|
||||
await runTests(entrypoint, shouldAddHelpers, nb);
|
||||
};
|
||||
|
||||
main();
|
||||
378
packages/now-node/bench/yarn.lock
Normal file
378
packages/now-node/bench/yarn.lock
Normal file
@@ -0,0 +1,378 @@
|
||||
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
accepts@~1.3.7:
|
||||
version "1.3.7"
|
||||
resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd"
|
||||
integrity sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==
|
||||
dependencies:
|
||||
mime-types "~2.1.24"
|
||||
negotiator "0.6.2"
|
||||
|
||||
array-flatten@1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2"
|
||||
integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=
|
||||
|
||||
body-parser@1.19.0:
|
||||
version "1.19.0"
|
||||
resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.0.tgz#96b2709e57c9c4e09a6fd66a8fd979844f69f08a"
|
||||
integrity sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==
|
||||
dependencies:
|
||||
bytes "3.1.0"
|
||||
content-type "~1.0.4"
|
||||
debug "2.6.9"
|
||||
depd "~1.1.2"
|
||||
http-errors "1.7.2"
|
||||
iconv-lite "0.4.24"
|
||||
on-finished "~2.3.0"
|
||||
qs "6.7.0"
|
||||
raw-body "2.4.0"
|
||||
type-is "~1.6.17"
|
||||
|
||||
bytes@3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6"
|
||||
integrity sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==
|
||||
|
||||
content-disposition@0.5.3:
|
||||
version "0.5.3"
|
||||
resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.3.tgz#e130caf7e7279087c5616c2007d0485698984fbd"
|
||||
integrity sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==
|
||||
dependencies:
|
||||
safe-buffer "5.1.2"
|
||||
|
||||
content-type@~1.0.4:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b"
|
||||
integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==
|
||||
|
||||
cookie-signature@1.0.6:
|
||||
version "1.0.6"
|
||||
resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c"
|
||||
integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw=
|
||||
|
||||
cookie@0.4.0:
|
||||
version "0.4.0"
|
||||
resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.0.tgz#beb437e7022b3b6d49019d088665303ebe9c14ba"
|
||||
integrity sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==
|
||||
|
||||
debug@2.6.9:
|
||||
version "2.6.9"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
|
||||
integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==
|
||||
dependencies:
|
||||
ms "2.0.0"
|
||||
|
||||
depd@~1.1.2:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9"
|
||||
integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=
|
||||
|
||||
destroy@~1.0.4:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80"
|
||||
integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=
|
||||
|
||||
ee-first@1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
|
||||
integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=
|
||||
|
||||
encodeurl@~1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59"
|
||||
integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=
|
||||
|
||||
escape-html@~1.0.3:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988"
|
||||
integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=
|
||||
|
||||
etag@~1.8.1:
|
||||
version "1.8.1"
|
||||
resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887"
|
||||
integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=
|
||||
|
||||
express@4.17.1:
|
||||
version "4.17.1"
|
||||
resolved "https://registry.yarnpkg.com/express/-/express-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134"
|
||||
integrity sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==
|
||||
dependencies:
|
||||
accepts "~1.3.7"
|
||||
array-flatten "1.1.1"
|
||||
body-parser "1.19.0"
|
||||
content-disposition "0.5.3"
|
||||
content-type "~1.0.4"
|
||||
cookie "0.4.0"
|
||||
cookie-signature "1.0.6"
|
||||
debug "2.6.9"
|
||||
depd "~1.1.2"
|
||||
encodeurl "~1.0.2"
|
||||
escape-html "~1.0.3"
|
||||
etag "~1.8.1"
|
||||
finalhandler "~1.1.2"
|
||||
fresh "0.5.2"
|
||||
merge-descriptors "1.0.1"
|
||||
methods "~1.1.2"
|
||||
on-finished "~2.3.0"
|
||||
parseurl "~1.3.3"
|
||||
path-to-regexp "0.1.7"
|
||||
proxy-addr "~2.0.5"
|
||||
qs "6.7.0"
|
||||
range-parser "~1.2.1"
|
||||
safe-buffer "5.1.2"
|
||||
send "0.17.1"
|
||||
serve-static "1.14.1"
|
||||
setprototypeof "1.1.1"
|
||||
statuses "~1.5.0"
|
||||
type-is "~1.6.18"
|
||||
utils-merge "1.0.1"
|
||||
vary "~1.1.2"
|
||||
|
||||
finalhandler@~1.1.2:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d"
|
||||
integrity sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==
|
||||
dependencies:
|
||||
debug "2.6.9"
|
||||
encodeurl "~1.0.2"
|
||||
escape-html "~1.0.3"
|
||||
on-finished "~2.3.0"
|
||||
parseurl "~1.3.3"
|
||||
statuses "~1.5.0"
|
||||
unpipe "~1.0.0"
|
||||
|
||||
forwarded@~0.1.2:
|
||||
version "0.1.2"
|
||||
resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84"
|
||||
integrity sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=
|
||||
|
||||
fresh@0.5.2:
|
||||
version "0.5.2"
|
||||
resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7"
|
||||
integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=
|
||||
|
||||
fs-extra@8.0.1:
|
||||
version "8.0.1"
|
||||
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.0.1.tgz#90294081f978b1f182f347a440a209154344285b"
|
||||
integrity sha512-W+XLrggcDzlle47X/XnS7FXrXu9sDo+Ze9zpndeBxdgv88FHLm1HtmkhEwavruS6koanBjp098rUpHs65EmG7A==
|
||||
dependencies:
|
||||
graceful-fs "^4.1.2"
|
||||
jsonfile "^4.0.0"
|
||||
universalify "^0.1.0"
|
||||
|
||||
graceful-fs@^4.1.2, graceful-fs@^4.1.6:
|
||||
version "4.1.15"
|
||||
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.15.tgz#ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00"
|
||||
integrity sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==
|
||||
|
||||
http-errors@1.7.2, http-errors@~1.7.2:
|
||||
version "1.7.2"
|
||||
resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.2.tgz#4f5029cf13239f31036e5b2e55292bcfbcc85c8f"
|
||||
integrity sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==
|
||||
dependencies:
|
||||
depd "~1.1.2"
|
||||
inherits "2.0.3"
|
||||
setprototypeof "1.1.1"
|
||||
statuses ">= 1.5.0 < 2"
|
||||
toidentifier "1.0.0"
|
||||
|
||||
iconv-lite@0.4.24:
|
||||
version "0.4.24"
|
||||
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
|
||||
integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==
|
||||
dependencies:
|
||||
safer-buffer ">= 2.1.2 < 3"
|
||||
|
||||
inherits@2.0.3:
|
||||
version "2.0.3"
|
||||
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
|
||||
integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=
|
||||
|
||||
ipaddr.js@1.9.0:
|
||||
version "1.9.0"
|
||||
resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.0.tgz#37df74e430a0e47550fe54a2defe30d8acd95f65"
|
||||
integrity sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA==
|
||||
|
||||
jsonfile@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb"
|
||||
integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=
|
||||
optionalDependencies:
|
||||
graceful-fs "^4.1.6"
|
||||
|
||||
media-typer@0.3.0:
|
||||
version "0.3.0"
|
||||
resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
|
||||
integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=
|
||||
|
||||
merge-descriptors@1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61"
|
||||
integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=
|
||||
|
||||
methods@~1.1.2:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee"
|
||||
integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=
|
||||
|
||||
mime-db@1.40.0:
|
||||
version "1.40.0"
|
||||
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.40.0.tgz#a65057e998db090f732a68f6c276d387d4126c32"
|
||||
integrity sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==
|
||||
|
||||
mime-types@~2.1.24:
|
||||
version "2.1.24"
|
||||
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.24.tgz#b6f8d0b3e951efb77dedeca194cff6d16f676f81"
|
||||
integrity sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==
|
||||
dependencies:
|
||||
mime-db "1.40.0"
|
||||
|
||||
mime@1.6.0:
|
||||
version "1.6.0"
|
||||
resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1"
|
||||
integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==
|
||||
|
||||
ms@2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
|
||||
integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=
|
||||
|
||||
ms@2.1.1:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a"
|
||||
integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==
|
||||
|
||||
negotiator@0.6.2:
|
||||
version "0.6.2"
|
||||
resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb"
|
||||
integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==
|
||||
|
||||
on-finished@~2.3.0:
|
||||
version "2.3.0"
|
||||
resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947"
|
||||
integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=
|
||||
dependencies:
|
||||
ee-first "1.1.1"
|
||||
|
||||
parseurl@~1.3.3:
|
||||
version "1.3.3"
|
||||
resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4"
|
||||
integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==
|
||||
|
||||
path-to-regexp@0.1.7:
|
||||
version "0.1.7"
|
||||
resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c"
|
||||
integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=
|
||||
|
||||
proxy-addr@~2.0.5:
|
||||
version "2.0.5"
|
||||
resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.5.tgz#34cbd64a2d81f4b1fd21e76f9f06c8a45299ee34"
|
||||
integrity sha512-t/7RxHXPH6cJtP0pRG6smSr9QJidhB+3kXu0KgXnbGYMgzEnUxRQ4/LDdfOwZEMyIh3/xHb8PX3t+lfL9z+YVQ==
|
||||
dependencies:
|
||||
forwarded "~0.1.2"
|
||||
ipaddr.js "1.9.0"
|
||||
|
||||
qs@6.7.0:
|
||||
version "6.7.0"
|
||||
resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc"
|
||||
integrity sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==
|
||||
|
||||
range-parser@~1.2.1:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031"
|
||||
integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==
|
||||
|
||||
raw-body@2.4.0:
|
||||
version "2.4.0"
|
||||
resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.0.tgz#a1ce6fb9c9bc356ca52e89256ab59059e13d0332"
|
||||
integrity sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==
|
||||
dependencies:
|
||||
bytes "3.1.0"
|
||||
http-errors "1.7.2"
|
||||
iconv-lite "0.4.24"
|
||||
unpipe "1.0.0"
|
||||
|
||||
safe-buffer@5.1.2:
|
||||
version "5.1.2"
|
||||
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
|
||||
integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
|
||||
|
||||
"safer-buffer@>= 2.1.2 < 3":
|
||||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
|
||||
integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
|
||||
|
||||
send@0.17.1:
|
||||
version "0.17.1"
|
||||
resolved "https://registry.yarnpkg.com/send/-/send-0.17.1.tgz#c1d8b059f7900f7466dd4938bdc44e11ddb376c8"
|
||||
integrity sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==
|
||||
dependencies:
|
||||
debug "2.6.9"
|
||||
depd "~1.1.2"
|
||||
destroy "~1.0.4"
|
||||
encodeurl "~1.0.2"
|
||||
escape-html "~1.0.3"
|
||||
etag "~1.8.1"
|
||||
fresh "0.5.2"
|
||||
http-errors "~1.7.2"
|
||||
mime "1.6.0"
|
||||
ms "2.1.1"
|
||||
on-finished "~2.3.0"
|
||||
range-parser "~1.2.1"
|
||||
statuses "~1.5.0"
|
||||
|
||||
serve-static@1.14.1:
|
||||
version "1.14.1"
|
||||
resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.14.1.tgz#666e636dc4f010f7ef29970a88a674320898b2f9"
|
||||
integrity sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==
|
||||
dependencies:
|
||||
encodeurl "~1.0.2"
|
||||
escape-html "~1.0.3"
|
||||
parseurl "~1.3.3"
|
||||
send "0.17.1"
|
||||
|
||||
setprototypeof@1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683"
|
||||
integrity sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==
|
||||
|
||||
"statuses@>= 1.5.0 < 2", statuses@~1.5.0:
|
||||
version "1.5.0"
|
||||
resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c"
|
||||
integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=
|
||||
|
||||
toidentifier@1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553"
|
||||
integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==
|
||||
|
||||
type-is@~1.6.17, type-is@~1.6.18:
|
||||
version "1.6.18"
|
||||
resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131"
|
||||
integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==
|
||||
dependencies:
|
||||
media-typer "0.3.0"
|
||||
mime-types "~2.1.24"
|
||||
|
||||
universalify@^0.1.0:
|
||||
version "0.1.2"
|
||||
resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66"
|
||||
integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==
|
||||
|
||||
unpipe@1.0.0, unpipe@~1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec"
|
||||
integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=
|
||||
|
||||
utils-merge@1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713"
|
||||
integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=
|
||||
|
||||
vary@~1.1.2:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"
|
||||
integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=
|
||||
@@ -13,12 +13,17 @@ cp -v "$bridge_defs" src
|
||||
# build ts files
|
||||
tsc
|
||||
|
||||
# todo: improve
|
||||
# copy type file for ts test
|
||||
cp dist/types.d.ts test/fixtures/15-helpers/ts/types.d.ts
|
||||
|
||||
# use types.d.ts as the main types export
|
||||
mv dist/types.d.ts dist/types
|
||||
rm dist/*.d.ts
|
||||
mv dist/types dist/index.d.ts
|
||||
|
||||
# bundle helpers.ts with ncc
|
||||
rm dist/helpers.js
|
||||
ncc build src/helpers.ts -o dist/helpers
|
||||
mv dist/helpers/index.js dist/helpers.js
|
||||
rm -rf dist/helpers
|
||||
|
||||
# todo: improve
|
||||
# copy type file for ts test
|
||||
cp dist/types.d.ts test/fixtures/15-helpers/ts/types.d.ts
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
{
|
||||
"name": "@now/node",
|
||||
"version": "0.11.0",
|
||||
"version": "0.11.1",
|
||||
"license": "MIT",
|
||||
"main": "./dist/index",
|
||||
"homepage": "https://zeit.co/docs/v2/deployments/official-builders/node-js-now-node",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/zeit/now-builders.git",
|
||||
|
||||
@@ -33,6 +33,10 @@ interface DownloadOptions {
|
||||
|
||||
const watchers: Map<string, NccWatcher> = new Map();
|
||||
|
||||
const LAUNCHER_FILENAME = '___now_launcher';
|
||||
const BRIDGE_FILENAME = '___now_bridge';
|
||||
const HELPERS_FILENAME = '___now_helpers';
|
||||
|
||||
function getWatcher(entrypoint: string, options: NccOptions): NccWatcher {
|
||||
let watcher = watchers.get(entrypoint);
|
||||
if (!watcher) {
|
||||
@@ -205,25 +209,35 @@ export async function build({
|
||||
);
|
||||
|
||||
const launcherFiles: Files = {
|
||||
'launcher.js': new FileBlob({
|
||||
data: makeLauncher(entrypoint, shouldAddHelpers),
|
||||
[`${LAUNCHER_FILENAME}.js`]: new FileBlob({
|
||||
data: makeLauncher({
|
||||
entrypointPath: `./${entrypoint}`,
|
||||
bridgePath: `./${BRIDGE_FILENAME}`,
|
||||
helpersPath: `./${HELPERS_FILENAME}`,
|
||||
shouldAddHelpers,
|
||||
}),
|
||||
}),
|
||||
[`${BRIDGE_FILENAME}.js`]: new FileFsRef({
|
||||
fsPath: require('@now/node-bridge'),
|
||||
}),
|
||||
'bridge.js': new FileFsRef({ fsPath: require('@now/node-bridge') }),
|
||||
};
|
||||
|
||||
if (shouldAddHelpers) {
|
||||
launcherFiles['helpers.js'] = new FileFsRef({
|
||||
launcherFiles[`${HELPERS_FILENAME}.js`] = new FileFsRef({
|
||||
fsPath: join(__dirname, 'helpers.js'),
|
||||
});
|
||||
}
|
||||
|
||||
// Use the system-installed version of `node` when running via `now dev`
|
||||
const runtime = meta.isDev ? 'nodejs' : nodeVersion.runtime;
|
||||
|
||||
const lambda = await createLambda({
|
||||
files: {
|
||||
...preparedFiles,
|
||||
...launcherFiles,
|
||||
},
|
||||
handler: 'launcher.launcher',
|
||||
runtime: nodeVersion.runtime,
|
||||
handler: `${LAUNCHER_FILENAME}.launcher`,
|
||||
runtime,
|
||||
});
|
||||
|
||||
const output = { [entrypoint]: lambda };
|
||||
|
||||
@@ -1,10 +1,29 @@
|
||||
export function makeLauncher(
|
||||
entrypoint: string,
|
||||
shouldAddHelpers: boolean
|
||||
): string {
|
||||
return `const { Bridge } = require("./bridge");
|
||||
type LauncherConfiguration = {
|
||||
entrypointPath: string;
|
||||
bridgePath: string;
|
||||
helpersPath: string;
|
||||
shouldAddHelpers?: boolean;
|
||||
};
|
||||
|
||||
let bridge;
|
||||
export function makeLauncher({
|
||||
entrypointPath,
|
||||
bridgePath,
|
||||
helpersPath,
|
||||
shouldAddHelpers = false,
|
||||
}: LauncherConfiguration): string {
|
||||
return `const { Bridge } = require("${bridgePath}");
|
||||
const { Server } = require("http");
|
||||
|
||||
let isServerListening = false;
|
||||
let bridge = new Bridge();
|
||||
const saveListen = Server.prototype.listen;
|
||||
Server.prototype.listen = function listen() {
|
||||
isServerListening = true;
|
||||
console.log('Legacy server listening...');
|
||||
bridge.setServer(this);
|
||||
Server.prototype.listen = saveListen;
|
||||
return bridge.listen();
|
||||
};
|
||||
|
||||
if (!process.env.NODE_ENV) {
|
||||
process.env.NODE_ENV =
|
||||
@@ -12,31 +31,39 @@ if (!process.env.NODE_ENV) {
|
||||
}
|
||||
|
||||
try {
|
||||
let listener = require("./${entrypoint}");
|
||||
let listener = require("${entrypointPath}");
|
||||
if (listener.default) listener = listener.default;
|
||||
|
||||
if(typeof listener.listen === 'function') {
|
||||
if (typeof listener.listen === 'function') {
|
||||
Server.prototype.listen = saveListen;
|
||||
const server = listener;
|
||||
bridge = new Bridge(server);
|
||||
} else if(typeof listener === 'function') {
|
||||
bridge.setServer(server);
|
||||
bridge.listen();
|
||||
} else if (typeof listener === 'function') {
|
||||
Server.prototype.listen = saveListen;
|
||||
let server;
|
||||
${
|
||||
shouldAddHelpers
|
||||
? [
|
||||
'bridge = new Bridge(undefined, true);',
|
||||
'const server = require("./helpers").createServerWithHelpers(listener, bridge);',
|
||||
'bridge.setServer(server);',
|
||||
].join('\n')
|
||||
: [
|
||||
'const server = require("http").createServer(listener);',
|
||||
'bridge = new Bridge(server);',
|
||||
`server = require("${helpersPath}").createServerWithHelpers(listener, bridge);`,
|
||||
].join('\n')
|
||||
: ['server = require("http").createServer(listener);'].join('\n')
|
||||
}
|
||||
bridge.setServer(server);
|
||||
bridge.listen();
|
||||
} else if (typeof listener === 'object' && Object.keys(listener).length === 0) {
|
||||
setTimeout(() => {
|
||||
if (!isServerListening) {
|
||||
console.error('No exports found in module "${entrypointPath}".');
|
||||
console.error('Did you forget to export a function or a server?');
|
||||
process.exit(1);
|
||||
}
|
||||
}, 5000);
|
||||
} else {
|
||||
console.error('Export in entrypoint is not valid');
|
||||
console.error('Did you forget to export a function or a server?');
|
||||
process.exit(1);
|
||||
console.error('Invalid export found in module "${entrypointPath}".');
|
||||
console.error('The default export must be a function or server.');
|
||||
}
|
||||
|
||||
} catch (err) {
|
||||
if (err.code === 'MODULE_NOT_FOUND') {
|
||||
console.error(err.message);
|
||||
@@ -48,7 +75,5 @@ try {
|
||||
}
|
||||
}
|
||||
|
||||
bridge.listen();
|
||||
|
||||
exports.launcher = bridge.launcher;`;
|
||||
}
|
||||
|
||||
25
packages/now-node/test/fixtures/02-node-server/hapi-async/index.js
vendored
Normal file
25
packages/now-node/test/fixtures/02-node-server/hapi-async/index.js
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
const Hapi = require('@hapi/hapi');
|
||||
|
||||
const init = async () => {
|
||||
const server = Hapi.server({
|
||||
port: 3000,
|
||||
host: 'localhost',
|
||||
});
|
||||
|
||||
server.route({
|
||||
method: 'GET',
|
||||
path: '/{p*}',
|
||||
handler: () => 'hapi-async:RANDOMNESS_PLACEHOLDER',
|
||||
});
|
||||
|
||||
await server.start();
|
||||
console.log('Hapi server running on %s', server.info.uri);
|
||||
};
|
||||
|
||||
process.on('unhandledRejection', (err) => {
|
||||
console.log('Hapi failed in an unexpected way');
|
||||
console.log(err);
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
init();
|
||||
5
packages/now-node/test/fixtures/02-node-server/hapi-async/package.json
vendored
Normal file
5
packages/now-node/test/fixtures/02-node-server/hapi-async/package.json
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"@hapi/hapi": "18.3.1"
|
||||
}
|
||||
}
|
||||
7
packages/now-node/test/fixtures/02-node-server/index.js
vendored
Normal file
7
packages/now-node/test/fixtures/02-node-server/index.js
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
const http = require('http');
|
||||
|
||||
const server = http.createServer((req, resp) => {
|
||||
resp.end('root:RANDOMNESS_PLACEHOLDER');
|
||||
});
|
||||
|
||||
server.listen();
|
||||
15
packages/now-node/test/fixtures/02-node-server/now.json
vendored
Normal file
15
packages/now-node/test/fixtures/02-node-server/now.json
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"version": 2,
|
||||
"builds": [{ "src": "**/*.js", "use": "@now/node" }],
|
||||
"probes": [
|
||||
{ "path": "/", "mustContain": "root:RANDOMNESS_PLACEHOLDER" },
|
||||
{
|
||||
"path": "/subdirectory/",
|
||||
"mustContain": "subdir:RANDOMNESS_PLACEHOLDER"
|
||||
},
|
||||
{
|
||||
"path": "/hapi-async/",
|
||||
"mustContain": "hapi-async:RANDOMNESS_PLACEHOLDER"
|
||||
}
|
||||
]
|
||||
}
|
||||
7
packages/now-node/test/fixtures/02-node-server/subdirectory/index.js
vendored
Normal file
7
packages/now-node/test/fixtures/02-node-server/subdirectory/index.js
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
const http = require('http');
|
||||
|
||||
const server = http.createServer((req, resp) => {
|
||||
resp.end('subdir:RANDOMNESS_PLACEHOLDER');
|
||||
});
|
||||
|
||||
server.listen();
|
||||
3
packages/now-node/test/fixtures/17-entrypoint-name-conflict/bridge.js
vendored
Normal file
3
packages/now-node/test/fixtures/17-entrypoint-name-conflict/bridge.js
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
module.exports = (req, res) => {
|
||||
res.end('bridge:RANDOMNESS_PLACEHOLDER');
|
||||
};
|
||||
3
packages/now-node/test/fixtures/17-entrypoint-name-conflict/helpers.js
vendored
Normal file
3
packages/now-node/test/fixtures/17-entrypoint-name-conflict/helpers.js
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
module.exports = (req, res) => {
|
||||
res.end('helpers:RANDOMNESS_PLACEHOLDER');
|
||||
};
|
||||
3
packages/now-node/test/fixtures/17-entrypoint-name-conflict/launcher.js
vendored
Normal file
3
packages/now-node/test/fixtures/17-entrypoint-name-conflict/launcher.js
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
module.exports = (req, res) => {
|
||||
res.end('launcher:RANDOMNESS_PLACEHOLDER');
|
||||
};
|
||||
18
packages/now-node/test/fixtures/17-entrypoint-name-conflict/now.json
vendored
Normal file
18
packages/now-node/test/fixtures/17-entrypoint-name-conflict/now.json
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"version": 2,
|
||||
"builds": [{ "src": "*.js", "use": "@now/node" }],
|
||||
"probes": [
|
||||
{
|
||||
"path": "/helpers.js",
|
||||
"mustContain": "helpers:RANDOMNESS_PLACEHOLDER"
|
||||
},
|
||||
{
|
||||
"path": "/bridge.js",
|
||||
"mustContain": "bridge:RANDOMNESS_PLACEHOLDER"
|
||||
},
|
||||
{
|
||||
"path": "/launcher.js",
|
||||
"mustContain": "launcher:RANDOMNESS_PLACEHOLDER"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,8 +1,9 @@
|
||||
{
|
||||
"name": "@now/optipng",
|
||||
"version": "0.6.3",
|
||||
"version": "0.6.4",
|
||||
"license": "MIT",
|
||||
"main": "./dist/index",
|
||||
"homepage": "https://zeit.co/docs/v2/deployments/official-builders/optipng-now-optipng",
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
{
|
||||
"name": "@now/php",
|
||||
"version": "0.5.5",
|
||||
"version": "0.5.6",
|
||||
"license": "MIT",
|
||||
"homepage": "https://zeit.co/docs/v2/deployments/official-builders/php-now-php",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/zeit/now-builders.git",
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
{
|
||||
"name": "@now/python",
|
||||
"version": "0.2.9",
|
||||
"version": "0.2.10",
|
||||
"main": "./dist/index.js",
|
||||
"license": "MIT",
|
||||
"homepage": "https://zeit.co/docs/v2/deployments/official-builders/python-now-python",
|
||||
"files": [
|
||||
"dist",
|
||||
"now_init.py"
|
||||
|
||||
@@ -64,6 +64,7 @@ async function bundleInstall(
|
||||
env: {
|
||||
BUNDLE_SILENCE_ROOT_WARNING: '1',
|
||||
BUNDLE_APP_CONFIG: bundleAppConfig,
|
||||
BUNDLE_JOBS: '4',
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
@@ -2,7 +2,7 @@ import { join } from 'path';
|
||||
import execa from 'execa';
|
||||
import { getWriteableDirectory } from '@now/build-utils';
|
||||
|
||||
const RUBY_VERSION = '2.5.3';
|
||||
const RUBY_VERSION = '2.5.5';
|
||||
|
||||
async function installRuby(version: string = RUBY_VERSION) {
|
||||
const baseDir = await getWriteableDirectory();
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
{
|
||||
"name": "@now/ruby",
|
||||
"author": "Nathan Cahill <nathan@nathancahill.com>",
|
||||
"version": "0.1.1",
|
||||
"version": "0.1.2",
|
||||
"license": "MIT",
|
||||
"main": "./dist/index",
|
||||
"homepage": "https://zeit.co/docs/v2/deployments/official-builders/ruby-now-ruby",
|
||||
"files": [
|
||||
"dist",
|
||||
"now_init.rb"
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
{
|
||||
"name": "@now/rust",
|
||||
"version": "0.2.7",
|
||||
"version": "0.2.8",
|
||||
"license": "MIT",
|
||||
"main": "./dist/index",
|
||||
"homepage": "https://zeit.co/docs/v2/deployments/official-builders/now-rust",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/zeit/now-builders.git",
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
{
|
||||
"name": "@now/static-build",
|
||||
"version": "0.6.2",
|
||||
"version": "0.7.0",
|
||||
"license": "MIT",
|
||||
"main": "./dist/index",
|
||||
"homepage": "https://zeit.co/docs/v2/deployments/official-builders/static-build-now-static-build",
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
|
||||
187
packages/now-static-build/src/frameworks.ts
Normal file
187
packages/now-static-build/src/frameworks.ts
Normal file
@@ -0,0 +1,187 @@
|
||||
import { readdir } from 'fs';
|
||||
import { promisify } from 'util';
|
||||
import { join } from 'path';
|
||||
|
||||
const readirPromise = promisify(readdir);
|
||||
|
||||
// Please note that is extremely important
|
||||
// that the `dependency` property needs
|
||||
// to reference a CLI. This is needed because
|
||||
// you might want (for example) a Gatsby
|
||||
// site that is powered by Preact, so you
|
||||
// can't look for the `preact` dependency.
|
||||
// Instead, you need to look for `preact-cli`
|
||||
// when optimizing Preact CLI projects.
|
||||
|
||||
export default [
|
||||
{
|
||||
name: 'Gatsby.js',
|
||||
dependency: 'gatsby',
|
||||
getOutputDirName: async () => 'public',
|
||||
},
|
||||
{
|
||||
name: 'Hexo',
|
||||
dependency: 'hexo',
|
||||
getOutputDirName: async () => 'public',
|
||||
},
|
||||
{
|
||||
name: 'Preact',
|
||||
dependency: 'preact-cli',
|
||||
getOutputDirName: async () => 'build',
|
||||
defaultRoutes: [
|
||||
{
|
||||
handle: 'filesystem',
|
||||
},
|
||||
{
|
||||
src: '/(.*)',
|
||||
dest: '/index.html',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'Vue.js',
|
||||
dependency: '@vue/cli-service',
|
||||
getOutputDirName: async () => 'dist',
|
||||
defaultRoutes: [
|
||||
{
|
||||
handle: 'filesystem',
|
||||
},
|
||||
{
|
||||
src: '^/js/(.*)',
|
||||
headers: { 'cache-control': 'max-age=31536000, immutable' },
|
||||
dest: '/js/$1',
|
||||
},
|
||||
{
|
||||
src: '^/css/(.*)',
|
||||
headers: { 'cache-control': 'max-age=31536000, immutable' },
|
||||
dest: '/css/$1',
|
||||
},
|
||||
{
|
||||
src: '^/img/(.*)',
|
||||
headers: { 'cache-control': 'max-age=31536000, immutable' },
|
||||
dest: '/img/$1',
|
||||
},
|
||||
{
|
||||
src: '/(.*)',
|
||||
dest: '/index.html',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'Angular',
|
||||
dependency: '@angular/cli',
|
||||
minNodeRange: '10.x',
|
||||
getOutputDirName: async (dirPrefix: string) => {
|
||||
const base = 'dist';
|
||||
const location = join(dirPrefix, base);
|
||||
const content = await readirPromise(location);
|
||||
|
||||
return join(base, content[0]);
|
||||
},
|
||||
defaultRoutes: [
|
||||
{
|
||||
handle: 'filesystem',
|
||||
},
|
||||
{
|
||||
src: '/(.*)',
|
||||
dest: '/index.html',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'Polymer',
|
||||
dependency: 'polymer-cli',
|
||||
getOutputDirName: async (dirPrefix: string) => {
|
||||
const base = 'build';
|
||||
const location = join(dirPrefix, base);
|
||||
const content = await readirPromise(location);
|
||||
const paths = content.filter(item => !item.includes('.'));
|
||||
|
||||
return join(base, paths[0]);
|
||||
},
|
||||
defaultRoutes: [
|
||||
{
|
||||
handle: 'filesystem',
|
||||
},
|
||||
{
|
||||
src: '/(.*)',
|
||||
dest: '/index.html',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'Svelte',
|
||||
dependency: 'sirv-cli',
|
||||
getOutputDirName: async () => 'public',
|
||||
defaultRoutes: [
|
||||
{
|
||||
handle: 'filesystem',
|
||||
},
|
||||
{
|
||||
src: '/(.*)',
|
||||
dest: '/index.html',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'Create React App',
|
||||
dependency: 'react-scripts',
|
||||
getOutputDirName: async () => 'build',
|
||||
defaultRoutes: [
|
||||
{
|
||||
src: '/static/(.*)',
|
||||
headers: { 'cache-control': 's-maxage=31536000, immutable' },
|
||||
dest: '/static/$1',
|
||||
},
|
||||
{
|
||||
src: '/favicon.ico',
|
||||
dest: '/favicon.ico',
|
||||
},
|
||||
{
|
||||
src: '/asset-manifest.json',
|
||||
dest: '/asset-manifest.json',
|
||||
},
|
||||
{
|
||||
src: '/manifest.json',
|
||||
dest: '/manifest.json',
|
||||
},
|
||||
{
|
||||
src: '/precache-manifest.(.*)',
|
||||
dest: '/precache-manifest.$1',
|
||||
},
|
||||
{
|
||||
src: '/service-worker.js',
|
||||
headers: { 'cache-control': 's-maxage=0' },
|
||||
dest: '/service-worker.js',
|
||||
},
|
||||
{
|
||||
src: '/sockjs-node/(.*)',
|
||||
dest: '/sockjs-node/$1',
|
||||
},
|
||||
{
|
||||
src: '/(.*)',
|
||||
headers: { 'cache-control': 's-maxage=0' },
|
||||
dest: '/index.html',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'Gridsome',
|
||||
dependency: 'gridsome',
|
||||
getOutputDirName: async () => 'dist',
|
||||
},
|
||||
{
|
||||
name: 'UmiJS',
|
||||
dependency: 'umi',
|
||||
getOutputDirName: async () => 'dist',
|
||||
defaultRoutes: [
|
||||
{
|
||||
handle: 'filesystem',
|
||||
},
|
||||
{
|
||||
src: '/(.*)',
|
||||
dest: '/index.html',
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
@@ -3,6 +3,7 @@ import spawn from 'cross-spawn';
|
||||
import getPort from 'get-port';
|
||||
import { timeout } from 'promise-timeout';
|
||||
import { existsSync, readFileSync, statSync, readdirSync } from 'fs';
|
||||
import frameworks from './frameworks';
|
||||
import {
|
||||
glob,
|
||||
download,
|
||||
@@ -12,6 +13,7 @@ import {
|
||||
getNodeVersion,
|
||||
getSpawnOptions,
|
||||
Files,
|
||||
Route,
|
||||
BuildOptions,
|
||||
Config,
|
||||
} from '@now/build-utils';
|
||||
@@ -20,6 +22,20 @@ interface PackageJson {
|
||||
scripts?: {
|
||||
[key: string]: string;
|
||||
};
|
||||
dependencies?: {
|
||||
[key: string]: string;
|
||||
};
|
||||
devDependencies?: {
|
||||
[key: string]: string;
|
||||
};
|
||||
}
|
||||
|
||||
interface Framework {
|
||||
name: string;
|
||||
dependency: string;
|
||||
getOutputDirName: (dirPrefix: string) => Promise<string>;
|
||||
defaultRoutes?: Route[];
|
||||
minNodeRange?: string;
|
||||
}
|
||||
|
||||
function validateDistDir(distDir: string, isDev: boolean | undefined) {
|
||||
@@ -77,6 +93,19 @@ export const version = 2;
|
||||
|
||||
const nowDevScriptPorts = new Map();
|
||||
|
||||
const getDevRoute = (srcBase: string, devPort: number, route: Route) => {
|
||||
const basic: Route = {
|
||||
src: `${srcBase}${route.src}`,
|
||||
dest: `http://localhost:${devPort}${route.dest}`,
|
||||
};
|
||||
|
||||
if (route.headers) {
|
||||
basic.headers = route.headers;
|
||||
}
|
||||
|
||||
return basic;
|
||||
};
|
||||
|
||||
export async function build({
|
||||
files,
|
||||
entrypoint,
|
||||
@@ -88,10 +117,9 @@ export async function build({
|
||||
await download(files, workPath, meta);
|
||||
|
||||
const mountpoint = path.dirname(entrypoint);
|
||||
const entrypointFsDirname = path.join(workPath, mountpoint);
|
||||
const nodeVersion = await getNodeVersion(entrypointFsDirname);
|
||||
const spawnOpts = getSpawnOptions(meta, nodeVersion);
|
||||
const distPath = path.join(
|
||||
const entrypointDir = path.join(workPath, mountpoint);
|
||||
|
||||
let distPath = path.join(
|
||||
workPath,
|
||||
path.dirname(entrypoint),
|
||||
(config && (config.distDir as string)) || 'dist'
|
||||
@@ -99,25 +127,56 @@ export async function build({
|
||||
|
||||
const entrypointName = path.basename(entrypoint);
|
||||
|
||||
if (entrypointName.endsWith('.sh')) {
|
||||
console.log(`Running build script "${entrypoint}"`);
|
||||
await runShellScript(path.join(workPath, entrypoint));
|
||||
validateDistDir(distPath, meta.isDev);
|
||||
return glob('**', distPath, mountpoint);
|
||||
}
|
||||
|
||||
if (entrypointName === 'package.json') {
|
||||
await runNpmInstall(entrypointFsDirname, ['--prefer-offline'], spawnOpts);
|
||||
|
||||
const pkgPath = path.join(workPath, entrypoint);
|
||||
const pkg = JSON.parse(readFileSync(pkgPath, 'utf8'));
|
||||
|
||||
let output: Files = {};
|
||||
const routes: { src: string; dest: string }[] = [];
|
||||
let framework: Framework | undefined = undefined;
|
||||
let minNodeRange: string | undefined = undefined;
|
||||
|
||||
const routes: Route[] = [];
|
||||
const devScript = getCommand(pkg, 'dev', config as Config);
|
||||
|
||||
if (config.zeroConfig) {
|
||||
const dependencies = Object.assign(
|
||||
{},
|
||||
pkg.dependencies,
|
||||
pkg.devDependencies
|
||||
);
|
||||
|
||||
framework = frameworks.find(({ dependency }) => dependencies[dependency]);
|
||||
}
|
||||
|
||||
if (framework) {
|
||||
console.log(
|
||||
`Detected ${framework.name} framework. Optimizing your deployment...`
|
||||
);
|
||||
|
||||
if (framework.minNodeRange) {
|
||||
minNodeRange = framework.minNodeRange;
|
||||
console.log(
|
||||
`${framework.name} requires Node.js ${
|
||||
framework.minNodeRange
|
||||
}. Switching...`
|
||||
);
|
||||
} else {
|
||||
console.log(
|
||||
`${
|
||||
framework.name
|
||||
} does not require a specific Node.js version. Continuing ...`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const nodeVersion = await getNodeVersion(entrypointDir, minNodeRange);
|
||||
const spawnOpts = getSpawnOptions(meta, nodeVersion);
|
||||
|
||||
await runNpmInstall(entrypointDir, ['--prefer-offline'], spawnOpts);
|
||||
|
||||
if (meta.isDev && pkg.scripts && pkg.scripts[devScript]) {
|
||||
let devPort = nowDevScriptPorts.get(entrypoint);
|
||||
let devPort: number | undefined = nowDevScriptPorts.get(entrypoint);
|
||||
|
||||
if (typeof devPort === 'number') {
|
||||
console.log(
|
||||
'`%s` server already running for %j',
|
||||
@@ -129,10 +188,12 @@ export async function build({
|
||||
// it will launch a dev server that never "completes"
|
||||
devPort = await getPort();
|
||||
nowDevScriptPorts.set(entrypoint, devPort);
|
||||
|
||||
const opts = {
|
||||
cwd: entrypointFsDirname,
|
||||
cwd: entrypointDir,
|
||||
env: { ...process.env, PORT: String(devPort) },
|
||||
};
|
||||
|
||||
const child = spawn('npm', ['run', devScript], opts);
|
||||
child.on('exit', () => nowDevScriptPorts.delete(entrypoint));
|
||||
child.stdout.setEncoding('utf8');
|
||||
@@ -168,13 +229,23 @@ export async function build({
|
||||
}
|
||||
|
||||
let srcBase = mountpoint.replace(/^\.\/?/, '');
|
||||
|
||||
if (srcBase.length > 0) {
|
||||
srcBase = `/${srcBase}`;
|
||||
}
|
||||
routes.push({
|
||||
src: `${srcBase}/(.*)`,
|
||||
dest: `http://localhost:${devPort}/$1`,
|
||||
});
|
||||
|
||||
if (framework && framework.defaultRoutes) {
|
||||
for (const route of framework.defaultRoutes) {
|
||||
routes.push(getDevRoute(srcBase, devPort, route));
|
||||
}
|
||||
}
|
||||
|
||||
routes.push(
|
||||
getDevRoute(srcBase, devPort, {
|
||||
src: '/(.*)',
|
||||
dest: '/$1',
|
||||
})
|
||||
);
|
||||
} else {
|
||||
if (meta.isDev) {
|
||||
console.log('WARN: "${devScript}" script is missing from package.json');
|
||||
@@ -182,26 +253,56 @@ export async function build({
|
||||
'See the local development docs: https://zeit.co/docs/v2/deployments/official-builders/static-build-now-static-build/#local-development'
|
||||
);
|
||||
}
|
||||
|
||||
const buildScript = getCommand(pkg, 'build', config as Config);
|
||||
console.log(`Running "${buildScript}" script in "${entrypoint}"`);
|
||||
|
||||
const found = await runPackageJsonScript(
|
||||
entrypointFsDirname,
|
||||
entrypointDir,
|
||||
buildScript,
|
||||
spawnOpts
|
||||
);
|
||||
|
||||
if (!found) {
|
||||
throw new Error(
|
||||
`Missing required "${buildScript}" script in "${entrypoint}"`
|
||||
);
|
||||
}
|
||||
|
||||
if (framework) {
|
||||
const outputDirPrefix = path.join(workPath, path.dirname(entrypoint));
|
||||
const outputDirName = await framework.getOutputDirName(outputDirPrefix);
|
||||
|
||||
distPath = path.join(outputDirPrefix, outputDirName);
|
||||
}
|
||||
|
||||
validateDistDir(distPath, meta.isDev);
|
||||
output = await glob('**', distPath, mountpoint);
|
||||
|
||||
if (framework && framework.defaultRoutes) {
|
||||
routes.push(...framework.defaultRoutes);
|
||||
}
|
||||
}
|
||||
|
||||
const watch = [path.join(mountpoint.replace(/^\.\/?/, ''), '**/*')];
|
||||
return { routes, watch, output };
|
||||
}
|
||||
|
||||
throw new Error(
|
||||
`Build "src" is "${entrypoint}" but expected "package.json" or "build.sh"`
|
||||
);
|
||||
if (!config.zeroConfig && entrypointName.endsWith('.sh')) {
|
||||
console.log(`Running build script "${entrypoint}"`);
|
||||
const nodeVersion = await getNodeVersion(entrypointDir);
|
||||
const spawnOpts = getSpawnOptions(meta, nodeVersion);
|
||||
await runShellScript(path.join(workPath, entrypoint), [], spawnOpts);
|
||||
validateDistDir(distPath, meta.isDev);
|
||||
|
||||
return glob('**', distPath, mountpoint);
|
||||
}
|
||||
|
||||
let message = `Build "src" is "${entrypoint}" but expected "package.json"`;
|
||||
|
||||
if (!config.zeroConfig) {
|
||||
message += ' or "build.sh"';
|
||||
}
|
||||
|
||||
throw new Error(message);
|
||||
}
|
||||
|
||||
7
packages/now-static-build/test/fixtures/02-cowsay-sh/node10sh/build.sh
vendored
Normal file
7
packages/now-static-build/test/fixtures/02-cowsay-sh/node10sh/build.sh
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
NODEVERSION=$(node --version)
|
||||
NPMVERSION=$(npm --version)
|
||||
|
||||
mkdir dist
|
||||
echo "node:$NODEVERSION:RANDOMNESS_PLACEHOLDER" >> dist/index.txt
|
||||
echo "npm:$NPMVERSION:RANDOMNESS_PLACEHOLDER" >> dist/index.txt
|
||||
|
||||
5
packages/now-static-build/test/fixtures/02-cowsay-sh/node10sh/package.json
vendored
Normal file
5
packages/now-static-build/test/fixtures/02-cowsay-sh/node10sh/package.json
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"engines": {
|
||||
"node": "10.x"
|
||||
}
|
||||
}
|
||||
@@ -2,10 +2,12 @@
|
||||
"version": 2,
|
||||
"builds": [
|
||||
{ "src": "some-build.sh", "use": "@now/static-build" },
|
||||
{ "src": "node10sh/build.sh", "use": "@now/static-build" },
|
||||
{ "src": "subdirectory/some-build.sh", "use": "@now/static-build" }
|
||||
],
|
||||
"probes": [
|
||||
{ "path": "/", "mustContain": "cow:RANDOMNESS_PLACEHOLDER" },
|
||||
{ "path": "/node10sh/", "mustContain": "node:v10" },
|
||||
{ "path": "/subdirectory/", "mustContain": "yoda:RANDOMNESS_PLACEHOLDER" }
|
||||
]
|
||||
}
|
||||
|
||||
69
packages/now-static-build/test/fixtures/10-gatsby/.gitignore
vendored
Normal file
69
packages/now-static-build/test/fixtures/10-gatsby/.gitignore
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
# Runtime data
|
||||
pids
|
||||
*.pid
|
||||
*.seed
|
||||
*.pid.lock
|
||||
|
||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||
lib-cov
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
coverage
|
||||
|
||||
# nyc test coverage
|
||||
.nyc_output
|
||||
|
||||
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
|
||||
.grunt
|
||||
|
||||
# Bower dependency directory (https://bower.io/)
|
||||
bower_components
|
||||
|
||||
# node-waf configuration
|
||||
.lock-wscript
|
||||
|
||||
# Compiled binary addons (http://nodejs.org/api/addons.html)
|
||||
build/Release
|
||||
|
||||
# Dependency directories
|
||||
node_modules/
|
||||
jspm_packages/
|
||||
|
||||
# Typescript v1 declaration files
|
||||
typings/
|
||||
|
||||
# Optional npm cache directory
|
||||
.npm
|
||||
|
||||
# Optional eslint cache
|
||||
.eslintcache
|
||||
|
||||
# Optional REPL history
|
||||
.node_repl_history
|
||||
|
||||
# Output of 'npm pack'
|
||||
*.tgz
|
||||
|
||||
# dotenv environment variables file
|
||||
.env
|
||||
|
||||
# gatsby files
|
||||
.cache/
|
||||
public
|
||||
|
||||
# Mac files
|
||||
.DS_Store
|
||||
|
||||
# Yarn
|
||||
yarn-error.log
|
||||
.pnp/
|
||||
.pnp.js
|
||||
# Yarn Integrity file
|
||||
.yarn-integrity
|
||||
7
packages/now-static-build/test/fixtures/10-gatsby/.prettierrc
vendored
Normal file
7
packages/now-static-build/test/fixtures/10-gatsby/.prettierrc
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"endOfLine": "lf",
|
||||
"semi": false,
|
||||
"singleQuote": false,
|
||||
"tabWidth": 2,
|
||||
"trailingComma": "es5"
|
||||
}
|
||||
22
packages/now-static-build/test/fixtures/10-gatsby/LICENSE
vendored
Normal file
22
packages/now-static-build/test/fixtures/10-gatsby/LICENSE
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 gatsbyjs
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
93
packages/now-static-build/test/fixtures/10-gatsby/README.md
vendored
Normal file
93
packages/now-static-build/test/fixtures/10-gatsby/README.md
vendored
Normal file
@@ -0,0 +1,93 @@
|
||||
<!-- AUTO-GENERATED-CONTENT:START (STARTER) -->
|
||||
<p align="center">
|
||||
<a href="https://www.gatsbyjs.org">
|
||||
<img alt="Gatsby" src="https://www.gatsbyjs.org/monogram.svg" width="60" />
|
||||
</a>
|
||||
</p>
|
||||
<h1 align="center">
|
||||
Gatsby's default starter
|
||||
</h1>
|
||||
|
||||
Kick off your project with this default boilerplate. This starter ships with the main Gatsby configuration files you might need to get up and running blazing fast with the blazing fast app generator for React.
|
||||
|
||||
_Have another more specific idea? You may want to check out our vibrant collection of [official and community-created starters](https://www.gatsbyjs.org/docs/gatsby-starters/)._
|
||||
|
||||
## 🚀 Quick start
|
||||
|
||||
1. **Create a Gatsby site.**
|
||||
|
||||
Use the Gatsby CLI to create a new site, specifying the default starter.
|
||||
|
||||
```sh
|
||||
# create a new Gatsby site using the default starter
|
||||
gatsby new my-default-starter https://github.com/gatsbyjs/gatsby-starter-default
|
||||
```
|
||||
|
||||
1. **Start developing.**
|
||||
|
||||
Navigate into your new site’s directory and start it up.
|
||||
|
||||
```sh
|
||||
cd my-default-starter/
|
||||
gatsby develop
|
||||
```
|
||||
|
||||
1. **Open the source code and start editing!**
|
||||
|
||||
Your site is now running at `http://localhost:8000`!
|
||||
|
||||
_Note: You'll also see a second link: _`http://localhost:8000/___graphql`_. This is a tool you can use to experiment with querying your data. Learn more about using this tool in the [Gatsby tutorial](https://www.gatsbyjs.org/tutorial/part-five/#introducing-graphiql)._
|
||||
|
||||
Open the `my-default-starter` directory in your code editor of choice and edit `src/pages/index.js`. Save your changes and the browser will update in real time!
|
||||
|
||||
## 🧐 What's inside?
|
||||
|
||||
A quick look at the top-level files and directories you'll see in a Gatsby project.
|
||||
|
||||
.
|
||||
├── node_modules
|
||||
├── src
|
||||
├── .gitignore
|
||||
├── .prettierrc
|
||||
├── gatsby-browser.js
|
||||
├── gatsby-config.js
|
||||
├── gatsby-node.js
|
||||
├── gatsby-ssr.js
|
||||
├── LICENSE
|
||||
├── package-lock.json
|
||||
├── package.json
|
||||
└── README.md
|
||||
|
||||
1. **`/node_modules`**: This directory contains all of the modules of code that your project depends on (npm packages) are automatically installed.
|
||||
|
||||
2. **`/src`**: This directory will contain all of the code related to what you will see on the front-end of your site (what you see in the browser) such as your site header or a page template. `src` is a convention for “source code”.
|
||||
|
||||
3. **`.gitignore`**: This file tells git which files it should not track / not maintain a version history for.
|
||||
|
||||
4. **`.prettierrc`**: This is a configuration file for [Prettier](https://prettier.io/). Prettier is a tool to help keep the formatting of your code consistent.
|
||||
|
||||
5. **`gatsby-browser.js`**: This file is where Gatsby expects to find any usage of the [Gatsby browser APIs](https://www.gatsbyjs.org/docs/browser-apis/) (if any). These allow customization/extension of default Gatsby settings affecting the browser.
|
||||
|
||||
6. **`gatsby-config.js`**: This is the main configuration file for a Gatsby site. This is where you can specify information about your site (metadata) like the site title and description, which Gatsby plugins you’d like to include, etc. (Check out the [config docs](https://www.gatsbyjs.org/docs/gatsby-config/) for more detail).
|
||||
|
||||
7. **`gatsby-node.js`**: This file is where Gatsby expects to find any usage of the [Gatsby Node APIs](https://www.gatsbyjs.org/docs/node-apis/) (if any). These allow customization/extension of default Gatsby settings affecting pieces of the site build process.
|
||||
|
||||
8. **`gatsby-ssr.js`**: This file is where Gatsby expects to find any usage of the [Gatsby server-side rendering APIs](https://www.gatsbyjs.org/docs/ssr-apis/) (if any). These allow customization of default Gatsby settings affecting server-side rendering.
|
||||
|
||||
9. **`LICENSE`**: Gatsby is licensed under the MIT license.
|
||||
|
||||
10. **`package-lock.json`** (See `package.json` below, first). This is an automatically generated file based on the exact versions of your npm dependencies that were installed for your project. **(You won’t change this file directly).**
|
||||
|
||||
11. **`package.json`**: A manifest file for Node.js projects, which includes things like metadata (the project’s name, author, etc). This manifest is how npm knows which packages to install for your project.
|
||||
|
||||
12. **`README.md`**: A text file containing useful reference information about your project.
|
||||
|
||||
## 🎓 Learning Gatsby
|
||||
|
||||
Looking for more guidance? Full documentation for Gatsby lives [on the website](https://www.gatsbyjs.org/). Here are some places to start:
|
||||
|
||||
- **For most developers, we recommend starting with our [in-depth tutorial for creating a site with Gatsby](https://www.gatsbyjs.org/tutorial/).** It starts with zero assumptions about your level of ability and walks through every step of the process.
|
||||
|
||||
- **To dive straight into code samples, head [to our documentation](https://www.gatsbyjs.org/docs/).** In particular, check out the _Guides_, _API Reference_, and _Advanced Tutorials_ sections in the sidebar.
|
||||
|
||||
<!-- AUTO-GENERATED-CONTENT:END -->
|
||||
7
packages/now-static-build/test/fixtures/10-gatsby/gatsby-browser.js
vendored
Normal file
7
packages/now-static-build/test/fixtures/10-gatsby/gatsby-browser.js
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
/**
|
||||
* Implement Gatsby's Browser APIs in this file.
|
||||
*
|
||||
* See: https://www.gatsbyjs.org/docs/browser-apis/
|
||||
*/
|
||||
|
||||
// You can delete this file if you're not using it
|
||||
34
packages/now-static-build/test/fixtures/10-gatsby/gatsby-config.js
vendored
Normal file
34
packages/now-static-build/test/fixtures/10-gatsby/gatsby-config.js
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
module.exports = {
|
||||
siteMetadata: {
|
||||
title: `Gatsby Default Starter`,
|
||||
description: `Kick off your next, great Gatsby project with this default starter. This barebones starter ships with the main Gatsby configuration files you might need.`,
|
||||
author: `@gatsbyjs`,
|
||||
},
|
||||
plugins: [
|
||||
`gatsby-plugin-react-helmet`,
|
||||
{
|
||||
resolve: `gatsby-source-filesystem`,
|
||||
options: {
|
||||
name: `images`,
|
||||
path: `${__dirname}/src/images`,
|
||||
},
|
||||
},
|
||||
`gatsby-transformer-sharp`,
|
||||
`gatsby-plugin-sharp`,
|
||||
{
|
||||
resolve: `gatsby-plugin-manifest`,
|
||||
options: {
|
||||
name: `gatsby-starter-default`,
|
||||
short_name: `starter`,
|
||||
start_url: `/`,
|
||||
background_color: `#663399`,
|
||||
theme_color: `#663399`,
|
||||
display: `minimal-ui`,
|
||||
icon: `src/images/gatsby-icon.png`, // This path is relative to the root of the site.
|
||||
},
|
||||
},
|
||||
// this (optional) plugin enables Progressive Web App + Offline functionality
|
||||
// To learn more, visit: https://gatsby.dev/offline
|
||||
// `gatsby-plugin-offline`,
|
||||
],
|
||||
}
|
||||
7
packages/now-static-build/test/fixtures/10-gatsby/gatsby-node.js
vendored
Normal file
7
packages/now-static-build/test/fixtures/10-gatsby/gatsby-node.js
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
/**
|
||||
* Implement Gatsby's Node APIs in this file.
|
||||
*
|
||||
* See: https://www.gatsbyjs.org/docs/node-apis/
|
||||
*/
|
||||
|
||||
// You can delete this file if you're not using it
|
||||
7
packages/now-static-build/test/fixtures/10-gatsby/gatsby-ssr.js
vendored
Normal file
7
packages/now-static-build/test/fixtures/10-gatsby/gatsby-ssr.js
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
/**
|
||||
* Implement Gatsby's SSR (Server Side Rendering) APIs in this file.
|
||||
*
|
||||
* See: https://www.gatsbyjs.org/docs/ssr-apis/
|
||||
*/
|
||||
|
||||
// You can delete this file if you're not using it
|
||||
9
packages/now-static-build/test/fixtures/10-gatsby/now.json
vendored
Normal file
9
packages/now-static-build/test/fixtures/10-gatsby/now.json
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"version": 2,
|
||||
"builds": [
|
||||
{ "src": "package.json", "use": "@now/static-build", "config": { "zeroConfig": true } }
|
||||
],
|
||||
"probes": [
|
||||
{ "path": "/", "mustContain": "Welcome to your new Gatsby site" }
|
||||
]
|
||||
}
|
||||
43
packages/now-static-build/test/fixtures/10-gatsby/package.json
vendored
Normal file
43
packages/now-static-build/test/fixtures/10-gatsby/package.json
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
{
|
||||
"name": "gatsby-starter-default",
|
||||
"private": true,
|
||||
"description": "A simple starter to get up and developing quickly with Gatsby",
|
||||
"version": "0.1.0",
|
||||
"author": "Kyle Mathews <mathews.kyle@gmail.com>",
|
||||
"dependencies": {
|
||||
"gatsby": "^2.13.3",
|
||||
"gatsby-image": "^2.2.4",
|
||||
"gatsby-plugin-manifest": "^2.2.1",
|
||||
"gatsby-plugin-offline": "^2.2.0",
|
||||
"gatsby-plugin-react-helmet": "^3.1.0",
|
||||
"gatsby-plugin-sharp": "^2.2.2",
|
||||
"gatsby-source-filesystem": "^2.1.2",
|
||||
"gatsby-transformer-sharp": "^2.2.1",
|
||||
"prop-types": "^15.7.2",
|
||||
"react": "^16.8.6",
|
||||
"react-dom": "^16.8.6",
|
||||
"react-helmet": "^5.2.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"prettier": "^1.18.2"
|
||||
},
|
||||
"keywords": [
|
||||
"gatsby"
|
||||
],
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"build": "gatsby build",
|
||||
"develop": "gatsby develop",
|
||||
"format": "prettier --write src/**/*.{js,jsx}",
|
||||
"start": "npm run develop",
|
||||
"serve": "gatsby serve",
|
||||
"test": "echo \"Write tests! -> https://gatsby.dev/unit-testing\""
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/gatsbyjs/gatsby-starter-default"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/gatsbyjs/gatsby/issues"
|
||||
}
|
||||
}
|
||||
42
packages/now-static-build/test/fixtures/10-gatsby/src/components/header.js
vendored
Normal file
42
packages/now-static-build/test/fixtures/10-gatsby/src/components/header.js
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
import { Link } from "gatsby"
|
||||
import PropTypes from "prop-types"
|
||||
import React from "react"
|
||||
|
||||
const Header = ({ siteTitle }) => (
|
||||
<header
|
||||
style={{
|
||||
background: `rebeccapurple`,
|
||||
marginBottom: `1.45rem`,
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
margin: `0 auto`,
|
||||
maxWidth: 960,
|
||||
padding: `1.45rem 1.0875rem`,
|
||||
}}
|
||||
>
|
||||
<h1 style={{ margin: 0 }}>
|
||||
<Link
|
||||
to="/"
|
||||
style={{
|
||||
color: `white`,
|
||||
textDecoration: `none`,
|
||||
}}
|
||||
>
|
||||
{siteTitle}
|
||||
</Link>
|
||||
</h1>
|
||||
</div>
|
||||
</header>
|
||||
)
|
||||
|
||||
Header.propTypes = {
|
||||
siteTitle: PropTypes.string,
|
||||
}
|
||||
|
||||
Header.defaultProps = {
|
||||
siteTitle: ``,
|
||||
}
|
||||
|
||||
export default Header
|
||||
32
packages/now-static-build/test/fixtures/10-gatsby/src/components/image.js
vendored
Normal file
32
packages/now-static-build/test/fixtures/10-gatsby/src/components/image.js
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
import React from "react"
|
||||
import { useStaticQuery, graphql } from "gatsby"
|
||||
import Img from "gatsby-image"
|
||||
|
||||
/*
|
||||
* This component is built using `gatsby-image` to automatically serve optimized
|
||||
* images with lazy loading and reduced file sizes. The image is loaded using a
|
||||
* `useStaticQuery`, which allows us to load the image from directly within this
|
||||
* component, rather than having to pass the image data down from pages.
|
||||
*
|
||||
* For more information, see the docs:
|
||||
* - `gatsby-image`: https://gatsby.dev/gatsby-image
|
||||
* - `useStaticQuery`: https://www.gatsbyjs.org/docs/use-static-query/
|
||||
*/
|
||||
|
||||
const Image = () => {
|
||||
const data = useStaticQuery(graphql`
|
||||
query {
|
||||
placeholderImage: file(relativePath: { eq: "gatsby-astronaut.png" }) {
|
||||
childImageSharp {
|
||||
fluid(maxWidth: 300) {
|
||||
...GatsbyImageSharpFluid
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`)
|
||||
|
||||
return <Img fluid={data.placeholderImage.childImageSharp.fluid} />
|
||||
}
|
||||
|
||||
export default Image
|
||||
622
packages/now-static-build/test/fixtures/10-gatsby/src/components/layout.css
vendored
Normal file
622
packages/now-static-build/test/fixtures/10-gatsby/src/components/layout.css
vendored
Normal file
@@ -0,0 +1,622 @@
|
||||
html {
|
||||
font-family: sans-serif;
|
||||
-ms-text-size-adjust: 100%;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
}
|
||||
body {
|
||||
margin: 0;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
article,
|
||||
aside,
|
||||
details,
|
||||
figcaption,
|
||||
figure,
|
||||
footer,
|
||||
header,
|
||||
main,
|
||||
menu,
|
||||
nav,
|
||||
section,
|
||||
summary {
|
||||
display: block;
|
||||
}
|
||||
audio,
|
||||
canvas,
|
||||
progress,
|
||||
video {
|
||||
display: inline-block;
|
||||
}
|
||||
audio:not([controls]) {
|
||||
display: none;
|
||||
height: 0;
|
||||
}
|
||||
progress {
|
||||
vertical-align: baseline;
|
||||
}
|
||||
[hidden],
|
||||
template {
|
||||
display: none;
|
||||
}
|
||||
a {
|
||||
background-color: transparent;
|
||||
-webkit-text-decoration-skip: objects;
|
||||
}
|
||||
a:active,
|
||||
a:hover {
|
||||
outline-width: 0;
|
||||
}
|
||||
abbr[title] {
|
||||
border-bottom: none;
|
||||
text-decoration: underline;
|
||||
text-decoration: underline dotted;
|
||||
}
|
||||
b,
|
||||
strong {
|
||||
font-weight: inherit;
|
||||
font-weight: bolder;
|
||||
}
|
||||
dfn {
|
||||
font-style: italic;
|
||||
}
|
||||
h1 {
|
||||
font-size: 2em;
|
||||
margin: 0.67em 0;
|
||||
}
|
||||
mark {
|
||||
background-color: #ff0;
|
||||
color: #000;
|
||||
}
|
||||
small {
|
||||
font-size: 80%;
|
||||
}
|
||||
sub,
|
||||
sup {
|
||||
font-size: 75%;
|
||||
line-height: 0;
|
||||
position: relative;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
sub {
|
||||
bottom: -0.25em;
|
||||
}
|
||||
sup {
|
||||
top: -0.5em;
|
||||
}
|
||||
img {
|
||||
border-style: none;
|
||||
}
|
||||
svg:not(:root) {
|
||||
overflow: hidden;
|
||||
}
|
||||
code,
|
||||
kbd,
|
||||
pre,
|
||||
samp {
|
||||
font-family: monospace, monospace;
|
||||
font-size: 1em;
|
||||
}
|
||||
figure {
|
||||
margin: 1em 40px;
|
||||
}
|
||||
hr {
|
||||
box-sizing: content-box;
|
||||
height: 0;
|
||||
overflow: visible;
|
||||
}
|
||||
button,
|
||||
input,
|
||||
optgroup,
|
||||
select,
|
||||
textarea {
|
||||
font: inherit;
|
||||
margin: 0;
|
||||
}
|
||||
optgroup {
|
||||
font-weight: 700;
|
||||
}
|
||||
button,
|
||||
input {
|
||||
overflow: visible;
|
||||
}
|
||||
button,
|
||||
select {
|
||||
text-transform: none;
|
||||
}
|
||||
[type="reset"],
|
||||
[type="submit"],
|
||||
button,
|
||||
html [type="button"] {
|
||||
-webkit-appearance: button;
|
||||
}
|
||||
[type="button"]::-moz-focus-inner,
|
||||
[type="reset"]::-moz-focus-inner,
|
||||
[type="submit"]::-moz-focus-inner,
|
||||
button::-moz-focus-inner {
|
||||
border-style: none;
|
||||
padding: 0;
|
||||
}
|
||||
[type="button"]:-moz-focusring,
|
||||
[type="reset"]:-moz-focusring,
|
||||
[type="submit"]:-moz-focusring,
|
||||
button:-moz-focusring {
|
||||
outline: 1px dotted ButtonText;
|
||||
}
|
||||
fieldset {
|
||||
border: 1px solid silver;
|
||||
margin: 0 2px;
|
||||
padding: 0.35em 0.625em 0.75em;
|
||||
}
|
||||
legend {
|
||||
box-sizing: border-box;
|
||||
color: inherit;
|
||||
display: table;
|
||||
max-width: 100%;
|
||||
padding: 0;
|
||||
white-space: normal;
|
||||
}
|
||||
textarea {
|
||||
overflow: auto;
|
||||
}
|
||||
[type="checkbox"],
|
||||
[type="radio"] {
|
||||
box-sizing: border-box;
|
||||
padding: 0;
|
||||
}
|
||||
[type="number"]::-webkit-inner-spin-button,
|
||||
[type="number"]::-webkit-outer-spin-button {
|
||||
height: auto;
|
||||
}
|
||||
[type="search"] {
|
||||
-webkit-appearance: textfield;
|
||||
outline-offset: -2px;
|
||||
}
|
||||
[type="search"]::-webkit-search-cancel-button,
|
||||
[type="search"]::-webkit-search-decoration {
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
::-webkit-input-placeholder {
|
||||
color: inherit;
|
||||
opacity: 0.54;
|
||||
}
|
||||
::-webkit-file-upload-button {
|
||||
-webkit-appearance: button;
|
||||
font: inherit;
|
||||
}
|
||||
html {
|
||||
font: 112.5%/1.45em georgia, serif;
|
||||
box-sizing: border-box;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
* {
|
||||
box-sizing: inherit;
|
||||
}
|
||||
*:before {
|
||||
box-sizing: inherit;
|
||||
}
|
||||
*:after {
|
||||
box-sizing: inherit;
|
||||
}
|
||||
body {
|
||||
color: hsla(0, 0%, 0%, 0.8);
|
||||
font-family: georgia, serif;
|
||||
font-weight: normal;
|
||||
word-wrap: break-word;
|
||||
font-kerning: normal;
|
||||
-moz-font-feature-settings: "kern", "liga", "clig", "calt";
|
||||
-ms-font-feature-settings: "kern", "liga", "clig", "calt";
|
||||
-webkit-font-feature-settings: "kern", "liga", "clig", "calt";
|
||||
font-feature-settings: "kern", "liga", "clig", "calt";
|
||||
}
|
||||
img {
|
||||
max-width: 100%;
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
margin-top: 0;
|
||||
padding-bottom: 0;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
padding-top: 0;
|
||||
margin-bottom: 1.45rem;
|
||||
}
|
||||
h1 {
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
margin-top: 0;
|
||||
padding-bottom: 0;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
padding-top: 0;
|
||||
margin-bottom: 1.45rem;
|
||||
color: inherit;
|
||||
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen,
|
||||
Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
|
||||
font-weight: bold;
|
||||
text-rendering: optimizeLegibility;
|
||||
font-size: 2.25rem;
|
||||
line-height: 1.1;
|
||||
}
|
||||
h2 {
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
margin-top: 0;
|
||||
padding-bottom: 0;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
padding-top: 0;
|
||||
margin-bottom: 1.45rem;
|
||||
color: inherit;
|
||||
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen,
|
||||
Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
|
||||
font-weight: bold;
|
||||
text-rendering: optimizeLegibility;
|
||||
font-size: 1.62671rem;
|
||||
line-height: 1.1;
|
||||
}
|
||||
h3 {
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
margin-top: 0;
|
||||
padding-bottom: 0;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
padding-top: 0;
|
||||
margin-bottom: 1.45rem;
|
||||
color: inherit;
|
||||
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen,
|
||||
Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
|
||||
font-weight: bold;
|
||||
text-rendering: optimizeLegibility;
|
||||
font-size: 1.38316rem;
|
||||
line-height: 1.1;
|
||||
}
|
||||
h4 {
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
margin-top: 0;
|
||||
padding-bottom: 0;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
padding-top: 0;
|
||||
margin-bottom: 1.45rem;
|
||||
color: inherit;
|
||||
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen,
|
||||
Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
|
||||
font-weight: bold;
|
||||
text-rendering: optimizeLegibility;
|
||||
font-size: 1rem;
|
||||
line-height: 1.1;
|
||||
}
|
||||
h5 {
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
margin-top: 0;
|
||||
padding-bottom: 0;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
padding-top: 0;
|
||||
margin-bottom: 1.45rem;
|
||||
color: inherit;
|
||||
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen,
|
||||
Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
|
||||
font-weight: bold;
|
||||
text-rendering: optimizeLegibility;
|
||||
font-size: 0.85028rem;
|
||||
line-height: 1.1;
|
||||
}
|
||||
h6 {
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
margin-top: 0;
|
||||
padding-bottom: 0;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
padding-top: 0;
|
||||
margin-bottom: 1.45rem;
|
||||
color: inherit;
|
||||
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen,
|
||||
Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
|
||||
font-weight: bold;
|
||||
text-rendering: optimizeLegibility;
|
||||
font-size: 0.78405rem;
|
||||
line-height: 1.1;
|
||||
}
|
||||
hgroup {
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
margin-top: 0;
|
||||
padding-bottom: 0;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
padding-top: 0;
|
||||
margin-bottom: 1.45rem;
|
||||
}
|
||||
ul {
|
||||
margin-left: 1.45rem;
|
||||
margin-right: 0;
|
||||
margin-top: 0;
|
||||
padding-bottom: 0;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
padding-top: 0;
|
||||
margin-bottom: 1.45rem;
|
||||
list-style-position: outside;
|
||||
list-style-image: none;
|
||||
}
|
||||
ol {
|
||||
margin-left: 1.45rem;
|
||||
margin-right: 0;
|
||||
margin-top: 0;
|
||||
padding-bottom: 0;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
padding-top: 0;
|
||||
margin-bottom: 1.45rem;
|
||||
list-style-position: outside;
|
||||
list-style-image: none;
|
||||
}
|
||||
dl {
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
margin-top: 0;
|
||||
padding-bottom: 0;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
padding-top: 0;
|
||||
margin-bottom: 1.45rem;
|
||||
}
|
||||
dd {
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
margin-top: 0;
|
||||
padding-bottom: 0;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
padding-top: 0;
|
||||
margin-bottom: 1.45rem;
|
||||
}
|
||||
p {
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
margin-top: 0;
|
||||
padding-bottom: 0;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
padding-top: 0;
|
||||
margin-bottom: 1.45rem;
|
||||
}
|
||||
figure {
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
margin-top: 0;
|
||||
padding-bottom: 0;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
padding-top: 0;
|
||||
margin-bottom: 1.45rem;
|
||||
}
|
||||
pre {
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
margin-top: 0;
|
||||
margin-bottom: 1.45rem;
|
||||
font-size: 0.85rem;
|
||||
line-height: 1.42;
|
||||
background: hsla(0, 0%, 0%, 0.04);
|
||||
border-radius: 3px;
|
||||
overflow: auto;
|
||||
word-wrap: normal;
|
||||
padding: 1.45rem;
|
||||
}
|
||||
table {
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
margin-top: 0;
|
||||
padding-bottom: 0;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
padding-top: 0;
|
||||
margin-bottom: 1.45rem;
|
||||
font-size: 1rem;
|
||||
line-height: 1.45rem;
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
}
|
||||
fieldset {
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
margin-top: 0;
|
||||
padding-bottom: 0;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
padding-top: 0;
|
||||
margin-bottom: 1.45rem;
|
||||
}
|
||||
blockquote {
|
||||
margin-left: 1.45rem;
|
||||
margin-right: 1.45rem;
|
||||
margin-top: 0;
|
||||
padding-bottom: 0;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
padding-top: 0;
|
||||
margin-bottom: 1.45rem;
|
||||
}
|
||||
form {
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
margin-top: 0;
|
||||
padding-bottom: 0;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
padding-top: 0;
|
||||
margin-bottom: 1.45rem;
|
||||
}
|
||||
noscript {
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
margin-top: 0;
|
||||
padding-bottom: 0;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
padding-top: 0;
|
||||
margin-bottom: 1.45rem;
|
||||
}
|
||||
iframe {
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
margin-top: 0;
|
||||
padding-bottom: 0;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
padding-top: 0;
|
||||
margin-bottom: 1.45rem;
|
||||
}
|
||||
hr {
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
margin-top: 0;
|
||||
padding-bottom: 0;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
padding-top: 0;
|
||||
margin-bottom: calc(1.45rem - 1px);
|
||||
background: hsla(0, 0%, 0%, 0.2);
|
||||
border: none;
|
||||
height: 1px;
|
||||
}
|
||||
address {
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
margin-top: 0;
|
||||
padding-bottom: 0;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
padding-top: 0;
|
||||
margin-bottom: 1.45rem;
|
||||
}
|
||||
b {
|
||||
font-weight: bold;
|
||||
}
|
||||
strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
dt {
|
||||
font-weight: bold;
|
||||
}
|
||||
th {
|
||||
font-weight: bold;
|
||||
}
|
||||
li {
|
||||
margin-bottom: calc(1.45rem / 2);
|
||||
}
|
||||
ol li {
|
||||
padding-left: 0;
|
||||
}
|
||||
ul li {
|
||||
padding-left: 0;
|
||||
}
|
||||
li > ol {
|
||||
margin-left: 1.45rem;
|
||||
margin-bottom: calc(1.45rem / 2);
|
||||
margin-top: calc(1.45rem / 2);
|
||||
}
|
||||
li > ul {
|
||||
margin-left: 1.45rem;
|
||||
margin-bottom: calc(1.45rem / 2);
|
||||
margin-top: calc(1.45rem / 2);
|
||||
}
|
||||
blockquote *:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
li *:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
p *:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
li > p {
|
||||
margin-bottom: calc(1.45rem / 2);
|
||||
}
|
||||
code {
|
||||
font-size: 0.85rem;
|
||||
line-height: 1.45rem;
|
||||
}
|
||||
kbd {
|
||||
font-size: 0.85rem;
|
||||
line-height: 1.45rem;
|
||||
}
|
||||
samp {
|
||||
font-size: 0.85rem;
|
||||
line-height: 1.45rem;
|
||||
}
|
||||
abbr {
|
||||
border-bottom: 1px dotted hsla(0, 0%, 0%, 0.5);
|
||||
cursor: help;
|
||||
}
|
||||
acronym {
|
||||
border-bottom: 1px dotted hsla(0, 0%, 0%, 0.5);
|
||||
cursor: help;
|
||||
}
|
||||
abbr[title] {
|
||||
border-bottom: 1px dotted hsla(0, 0%, 0%, 0.5);
|
||||
cursor: help;
|
||||
text-decoration: none;
|
||||
}
|
||||
thead {
|
||||
text-align: left;
|
||||
}
|
||||
td,
|
||||
th {
|
||||
text-align: left;
|
||||
border-bottom: 1px solid hsla(0, 0%, 0%, 0.12);
|
||||
font-feature-settings: "tnum";
|
||||
-moz-font-feature-settings: "tnum";
|
||||
-ms-font-feature-settings: "tnum";
|
||||
-webkit-font-feature-settings: "tnum";
|
||||
padding-left: 0.96667rem;
|
||||
padding-right: 0.96667rem;
|
||||
padding-top: 0.725rem;
|
||||
padding-bottom: calc(0.725rem - 1px);
|
||||
}
|
||||
th:first-child,
|
||||
td:first-child {
|
||||
padding-left: 0;
|
||||
}
|
||||
th:last-child,
|
||||
td:last-child {
|
||||
padding-right: 0;
|
||||
}
|
||||
tt,
|
||||
code {
|
||||
background-color: hsla(0, 0%, 0%, 0.04);
|
||||
border-radius: 3px;
|
||||
font-family: "SFMono-Regular", Consolas, "Roboto Mono", "Droid Sans Mono",
|
||||
"Liberation Mono", Menlo, Courier, monospace;
|
||||
padding: 0;
|
||||
padding-top: 0.2em;
|
||||
padding-bottom: 0.2em;
|
||||
}
|
||||
pre code {
|
||||
background: none;
|
||||
line-height: 1.42;
|
||||
}
|
||||
code:before,
|
||||
code:after,
|
||||
tt:before,
|
||||
tt:after {
|
||||
letter-spacing: -0.2em;
|
||||
content: " ";
|
||||
}
|
||||
pre code:before,
|
||||
pre code:after,
|
||||
pre tt:before,
|
||||
pre tt:after {
|
||||
content: "";
|
||||
}
|
||||
@media only screen and (max-width: 480px) {
|
||||
html {
|
||||
font-size: 100%;
|
||||
}
|
||||
}
|
||||
52
packages/now-static-build/test/fixtures/10-gatsby/src/components/layout.js
vendored
Normal file
52
packages/now-static-build/test/fixtures/10-gatsby/src/components/layout.js
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
/**
|
||||
* Layout component that queries for data
|
||||
* with Gatsby's useStaticQuery component
|
||||
*
|
||||
* See: https://www.gatsbyjs.org/docs/use-static-query/
|
||||
*/
|
||||
|
||||
import React from "react"
|
||||
import PropTypes from "prop-types"
|
||||
import { useStaticQuery, graphql } from "gatsby"
|
||||
|
||||
import Header from "./header"
|
||||
import "./layout.css"
|
||||
|
||||
const Layout = ({ children }) => {
|
||||
const data = useStaticQuery(graphql`
|
||||
query SiteTitleQuery {
|
||||
site {
|
||||
siteMetadata {
|
||||
title
|
||||
}
|
||||
}
|
||||
}
|
||||
`)
|
||||
|
||||
return (
|
||||
<>
|
||||
<Header siteTitle={data.site.siteMetadata.title} />
|
||||
<div
|
||||
style={{
|
||||
margin: `0 auto`,
|
||||
maxWidth: 960,
|
||||
padding: `0px 1.0875rem 1.45rem`,
|
||||
paddingTop: 0,
|
||||
}}
|
||||
>
|
||||
<main>{children}</main>
|
||||
<footer>
|
||||
© {new Date().getFullYear()}, Built with
|
||||
{` `}
|
||||
<a href="https://www.gatsbyjs.org">Gatsby</a>
|
||||
</footer>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
Layout.propTypes = {
|
||||
children: PropTypes.node.isRequired,
|
||||
}
|
||||
|
||||
export default Layout
|
||||
88
packages/now-static-build/test/fixtures/10-gatsby/src/components/seo.js
vendored
Normal file
88
packages/now-static-build/test/fixtures/10-gatsby/src/components/seo.js
vendored
Normal file
@@ -0,0 +1,88 @@
|
||||
/**
|
||||
* SEO component that queries for data with
|
||||
* Gatsby's useStaticQuery React hook
|
||||
*
|
||||
* See: https://www.gatsbyjs.org/docs/use-static-query/
|
||||
*/
|
||||
|
||||
import React from "react"
|
||||
import PropTypes from "prop-types"
|
||||
import Helmet from "react-helmet"
|
||||
import { useStaticQuery, graphql } from "gatsby"
|
||||
|
||||
function SEO({ description, lang, meta, title }) {
|
||||
const { site } = useStaticQuery(
|
||||
graphql`
|
||||
query {
|
||||
site {
|
||||
siteMetadata {
|
||||
title
|
||||
description
|
||||
author
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
)
|
||||
|
||||
const metaDescription = description || site.siteMetadata.description
|
||||
|
||||
return (
|
||||
<Helmet
|
||||
htmlAttributes={{
|
||||
lang,
|
||||
}}
|
||||
title={title}
|
||||
titleTemplate={`%s | ${site.siteMetadata.title}`}
|
||||
meta={[
|
||||
{
|
||||
name: `description`,
|
||||
content: metaDescription,
|
||||
},
|
||||
{
|
||||
property: `og:title`,
|
||||
content: title,
|
||||
},
|
||||
{
|
||||
property: `og:description`,
|
||||
content: metaDescription,
|
||||
},
|
||||
{
|
||||
property: `og:type`,
|
||||
content: `website`,
|
||||
},
|
||||
{
|
||||
name: `twitter:card`,
|
||||
content: `summary`,
|
||||
},
|
||||
{
|
||||
name: `twitter:creator`,
|
||||
content: site.siteMetadata.author,
|
||||
},
|
||||
{
|
||||
name: `twitter:title`,
|
||||
content: title,
|
||||
},
|
||||
{
|
||||
name: `twitter:description`,
|
||||
content: metaDescription,
|
||||
},
|
||||
].concat(meta)}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
SEO.defaultProps = {
|
||||
lang: `en`,
|
||||
meta: [],
|
||||
description: ``,
|
||||
}
|
||||
|
||||
SEO.propTypes = {
|
||||
description: PropTypes.string,
|
||||
lang: PropTypes.string,
|
||||
meta: PropTypes.arrayOf(PropTypes.object),
|
||||
title: PropTypes.string.isRequired,
|
||||
}
|
||||
|
||||
export default SEO
|
||||
BIN
packages/now-static-build/test/fixtures/10-gatsby/src/images/gatsby-astronaut.png
vendored
Normal file
BIN
packages/now-static-build/test/fixtures/10-gatsby/src/images/gatsby-astronaut.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 163 KiB |
BIN
packages/now-static-build/test/fixtures/10-gatsby/src/images/gatsby-icon.png
vendored
Normal file
BIN
packages/now-static-build/test/fixtures/10-gatsby/src/images/gatsby-icon.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 21 KiB |
14
packages/now-static-build/test/fixtures/10-gatsby/src/pages/404.js
vendored
Normal file
14
packages/now-static-build/test/fixtures/10-gatsby/src/pages/404.js
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
import React from "react"
|
||||
|
||||
import Layout from "../components/layout"
|
||||
import SEO from "../components/seo"
|
||||
|
||||
const NotFoundPage = () => (
|
||||
<Layout>
|
||||
<SEO title="404: Not found" />
|
||||
<h1>NOT FOUND</h1>
|
||||
<p>You just hit a route that doesn't exist... the sadness.</p>
|
||||
</Layout>
|
||||
)
|
||||
|
||||
export default NotFoundPage
|
||||
21
packages/now-static-build/test/fixtures/10-gatsby/src/pages/index.js
vendored
Normal file
21
packages/now-static-build/test/fixtures/10-gatsby/src/pages/index.js
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
import React from "react"
|
||||
import { Link } from "gatsby"
|
||||
|
||||
import Layout from "../components/layout"
|
||||
import Image from "../components/image"
|
||||
import SEO from "../components/seo"
|
||||
|
||||
const IndexPage = () => (
|
||||
<Layout>
|
||||
<SEO title="Home" />
|
||||
<h1>Hi people</h1>
|
||||
<p>Welcome to your new Gatsby site.</p>
|
||||
<p>Now go build something great.</p>
|
||||
<div style={{ maxWidth: `300px`, marginBottom: `1.45rem` }}>
|
||||
<Image />
|
||||
</div>
|
||||
<Link to="/page-2/">Go to page 2</Link>
|
||||
</Layout>
|
||||
)
|
||||
|
||||
export default IndexPage
|
||||
16
packages/now-static-build/test/fixtures/10-gatsby/src/pages/page-2.js
vendored
Normal file
16
packages/now-static-build/test/fixtures/10-gatsby/src/pages/page-2.js
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
import React from "react"
|
||||
import { Link } from "gatsby"
|
||||
|
||||
import Layout from "../components/layout"
|
||||
import SEO from "../components/seo"
|
||||
|
||||
const SecondPage = () => (
|
||||
<Layout>
|
||||
<SEO title="Page two" />
|
||||
<h1>Hi from the second page</h1>
|
||||
<p>Welcome to page 2</p>
|
||||
<Link to="/">Go back to the homepage</Link>
|
||||
</Layout>
|
||||
)
|
||||
|
||||
export default SecondPage
|
||||
11640
packages/now-static-build/test/fixtures/10-gatsby/yarn.lock
vendored
Normal file
11640
packages/now-static-build/test/fixtures/10-gatsby/yarn.lock
vendored
Normal file
File diff suppressed because it is too large
Load Diff
3
packages/now-static-build/test/fixtures/11-svelte/.gitignore
vendored
Normal file
3
packages/now-static-build/test/fixtures/11-svelte/.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
.DS_Store
|
||||
node_modules
|
||||
public/bundle.*
|
||||
68
packages/now-static-build/test/fixtures/11-svelte/README.md
vendored
Normal file
68
packages/now-static-build/test/fixtures/11-svelte/README.md
vendored
Normal file
@@ -0,0 +1,68 @@
|
||||
*Psst — looking for a shareable component template? Go here --> [sveltejs/component-template](https://github.com/sveltejs/component-template)*
|
||||
|
||||
---
|
||||
|
||||
# svelte app
|
||||
|
||||
This is a project template for [Svelte](https://svelte.dev) apps. It lives at https://github.com/sveltejs/template.
|
||||
|
||||
To create a new project based on this template using [degit](https://github.com/Rich-Harris/degit):
|
||||
|
||||
```bash
|
||||
npx degit sveltejs/template svelte-app
|
||||
cd svelte-app
|
||||
```
|
||||
|
||||
*Note that you will need to have [Node.js](https://nodejs.org) installed.*
|
||||
|
||||
|
||||
## Get started
|
||||
|
||||
Install the dependencies...
|
||||
|
||||
```bash
|
||||
cd svelte-app
|
||||
npm install
|
||||
```
|
||||
|
||||
...then start [Rollup](https://rollupjs.org):
|
||||
|
||||
```bash
|
||||
npm run dev
|
||||
```
|
||||
|
||||
Navigate to [localhost:5000](http://localhost:5000). You should see your app running. Edit a component file in `src`, save it, and reload the page to see your changes.
|
||||
|
||||
|
||||
## Deploying to the web
|
||||
|
||||
### With [now](https://zeit.co/now)
|
||||
|
||||
Install `now` if you haven't already:
|
||||
|
||||
```bash
|
||||
npm install -g now
|
||||
```
|
||||
|
||||
Then, from within your project folder:
|
||||
|
||||
```bash
|
||||
now
|
||||
```
|
||||
|
||||
As an alternative, use the [Now desktop client](https://zeit.co/download) and simply drag the unzipped project folder to the taskbar icon.
|
||||
|
||||
### With [surge](https://surge.sh/)
|
||||
|
||||
Install `surge` if you haven't already:
|
||||
|
||||
```bash
|
||||
npm install -g surge
|
||||
```
|
||||
|
||||
Then, from within your project folder:
|
||||
|
||||
```bash
|
||||
npm run build
|
||||
surge public
|
||||
```
|
||||
11
packages/now-static-build/test/fixtures/11-svelte/now.json
vendored
Normal file
11
packages/now-static-build/test/fixtures/11-svelte/now.json
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"version": 2,
|
||||
"builds": [
|
||||
{ "src": "package.json", "use": "@now/static-build", "config": { "zeroConfig": true } }
|
||||
],
|
||||
"probes": [
|
||||
{ "path": "/", "mustContain": "Svelte app" },
|
||||
{ "path": "/bundle.js", "mustContain": "Hello" },
|
||||
{ "path": "/iudieufwunifiwwnuwfuw", "mustContain": "Svelte app" }
|
||||
]
|
||||
}
|
||||
24
packages/now-static-build/test/fixtures/11-svelte/package.json
vendored
Normal file
24
packages/now-static-build/test/fixtures/11-svelte/package.json
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"name": "svelte-app",
|
||||
"version": "1.0.0",
|
||||
"devDependencies": {
|
||||
"npm-run-all": "^4.1.5",
|
||||
"rollup": "^1.10.1",
|
||||
"rollup-plugin-commonjs": "^9.3.4",
|
||||
"rollup-plugin-livereload": "^1.0.0",
|
||||
"rollup-plugin-node-resolve": "^4.2.3",
|
||||
"rollup-plugin-svelte": "^5.0.3",
|
||||
"rollup-plugin-terser": "^4.0.4",
|
||||
"svelte": "^3.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"sirv-cli": "^0.4.4"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "rollup -c",
|
||||
"autobuild": "rollup -c -w",
|
||||
"dev": "run-p start:dev autobuild",
|
||||
"start": "sirv public --single",
|
||||
"start:dev": "sirv public --single --dev"
|
||||
}
|
||||
}
|
||||
BIN
packages/now-static-build/test/fixtures/11-svelte/public/favicon.png
vendored
Normal file
BIN
packages/now-static-build/test/fixtures/11-svelte/public/favicon.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.1 KiB |
62
packages/now-static-build/test/fixtures/11-svelte/public/global.css
vendored
Normal file
62
packages/now-static-build/test/fixtures/11-svelte/public/global.css
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
html, body {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
color: #333;
|
||||
margin: 0;
|
||||
padding: 8px;
|
||||
box-sizing: border-box;
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
|
||||
}
|
||||
|
||||
a {
|
||||
color: rgb(0,100,200);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
a:visited {
|
||||
color: rgb(0,80,160);
|
||||
}
|
||||
|
||||
label {
|
||||
display: block;
|
||||
}
|
||||
|
||||
input, button, select, textarea {
|
||||
font-family: inherit;
|
||||
font-size: inherit;
|
||||
padding: 0.4em;
|
||||
margin: 0 0 0.5em 0;
|
||||
box-sizing: border-box;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
input:disabled {
|
||||
color: #ccc;
|
||||
}
|
||||
|
||||
input[type="range"] {
|
||||
height: 0;
|
||||
}
|
||||
|
||||
button {
|
||||
color: #333;
|
||||
background-color: #f4f4f4;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
button:active {
|
||||
background-color: #ddd;
|
||||
}
|
||||
|
||||
button:focus {
|
||||
border-color: #666;
|
||||
}
|
||||
17
packages/now-static-build/test/fixtures/11-svelte/public/index.html
vendored
Normal file
17
packages/now-static-build/test/fixtures/11-svelte/public/index.html
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset='utf8'>
|
||||
<meta name='viewport' content='width=device-width'>
|
||||
|
||||
<title>Svelte app</title>
|
||||
|
||||
<link rel='icon' type='image/png' href='/favicon.png'>
|
||||
<link rel='stylesheet' href='/global.css'>
|
||||
<link rel='stylesheet' href='/bundle.css'>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<script src='/bundle.js'></script>
|
||||
</body>
|
||||
</html>
|
||||
47
packages/now-static-build/test/fixtures/11-svelte/rollup.config.js
vendored
Normal file
47
packages/now-static-build/test/fixtures/11-svelte/rollup.config.js
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
import svelte from 'rollup-plugin-svelte';
|
||||
import resolve from 'rollup-plugin-node-resolve';
|
||||
import commonjs from 'rollup-plugin-commonjs';
|
||||
import livereload from 'rollup-plugin-livereload';
|
||||
import { terser } from 'rollup-plugin-terser';
|
||||
|
||||
const production = !process.env.ROLLUP_WATCH;
|
||||
|
||||
export default {
|
||||
input: 'src/main.js',
|
||||
output: {
|
||||
sourcemap: true,
|
||||
format: 'iife',
|
||||
name: 'app',
|
||||
file: 'public/bundle.js'
|
||||
},
|
||||
plugins: [
|
||||
svelte({
|
||||
// enable run-time checks when not in production
|
||||
dev: !production,
|
||||
// we'll extract any component CSS out into
|
||||
// a separate file — better for performance
|
||||
css: css => {
|
||||
css.write('public/bundle.css');
|
||||
}
|
||||
}),
|
||||
|
||||
// If you have external dependencies installed from
|
||||
// npm, you'll most likely need these plugins. In
|
||||
// some cases you'll need additional configuration —
|
||||
// consult the documentation for details:
|
||||
// https://github.com/rollup/rollup-plugin-commonjs
|
||||
resolve({ browser: true }),
|
||||
commonjs(),
|
||||
|
||||
// Watch the `public` directory and refresh the
|
||||
// browser on changes when not in production
|
||||
!production && livereload('public'),
|
||||
|
||||
// If we're building for production (npm run build
|
||||
// instead of npm run dev), minify
|
||||
production && terser()
|
||||
],
|
||||
watch: {
|
||||
clearScreen: false
|
||||
}
|
||||
};
|
||||
11
packages/now-static-build/test/fixtures/11-svelte/src/App.svelte
vendored
Normal file
11
packages/now-static-build/test/fixtures/11-svelte/src/App.svelte
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
<script>
|
||||
export let name;
|
||||
</script>
|
||||
|
||||
<style>
|
||||
h1 {
|
||||
color: purple;
|
||||
}
|
||||
</style>
|
||||
|
||||
<h1>Hello {name}!</h1>
|
||||
10
packages/now-static-build/test/fixtures/11-svelte/src/main.js
vendored
Normal file
10
packages/now-static-build/test/fixtures/11-svelte/src/main.js
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
import App from './App.svelte';
|
||||
|
||||
const app = new App({
|
||||
target: document.body,
|
||||
props: {
|
||||
name: 'world'
|
||||
}
|
||||
});
|
||||
|
||||
export default app;
|
||||
23
packages/now-static-build/test/fixtures/12-create-react-app/.gitignore
vendored
Normal file
23
packages/now-static-build/test/fixtures/12-create-react-app/.gitignore
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||
|
||||
# dependencies
|
||||
/node_modules
|
||||
/.pnp
|
||||
.pnp.js
|
||||
|
||||
# testing
|
||||
/coverage
|
||||
|
||||
# production
|
||||
/build
|
||||
|
||||
# misc
|
||||
.DS_Store
|
||||
.env.local
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
68
packages/now-static-build/test/fixtures/12-create-react-app/README.md
vendored
Normal file
68
packages/now-static-build/test/fixtures/12-create-react-app/README.md
vendored
Normal file
@@ -0,0 +1,68 @@
|
||||
This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
|
||||
|
||||
## Available Scripts
|
||||
|
||||
In the project directory, you can run:
|
||||
|
||||
### `npm start`
|
||||
|
||||
Runs the app in the development mode.<br>
|
||||
Open [http://localhost:3000](http://localhost:3000) to view it in the browser.
|
||||
|
||||
The page will reload if you make edits.<br>
|
||||
You will also see any lint errors in the console.
|
||||
|
||||
### `npm test`
|
||||
|
||||
Launches the test runner in the interactive watch mode.<br>
|
||||
See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.
|
||||
|
||||
### `npm run build`
|
||||
|
||||
Builds the app for production to the `build` folder.<br>
|
||||
It correctly bundles React in production mode and optimizes the build for the best performance.
|
||||
|
||||
The build is minified and the filenames include the hashes.<br>
|
||||
Your app is ready to be deployed!
|
||||
|
||||
See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
|
||||
|
||||
### `npm run eject`
|
||||
|
||||
**Note: this is a one-way operation. Once you `eject`, you can’t go back!**
|
||||
|
||||
If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.
|
||||
|
||||
Instead, it will copy all the configuration files and the transitive dependencies (Webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own.
|
||||
|
||||
You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it.
|
||||
|
||||
## Learn More
|
||||
|
||||
You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).
|
||||
|
||||
To learn React, check out the [React documentation](https://reactjs.org/).
|
||||
|
||||
### Code Splitting
|
||||
|
||||
This section has moved here: https://facebook.github.io/create-react-app/docs/code-splitting
|
||||
|
||||
### Analyzing the Bundle Size
|
||||
|
||||
This section has moved here: https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size
|
||||
|
||||
### Making a Progressive Web App
|
||||
|
||||
This section has moved here: https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app
|
||||
|
||||
### Advanced Configuration
|
||||
|
||||
This section has moved here: https://facebook.github.io/create-react-app/docs/advanced-configuration
|
||||
|
||||
### Deployment
|
||||
|
||||
This section has moved here: https://facebook.github.io/create-react-app/docs/deployment
|
||||
|
||||
### `npm run build` fails to minify
|
||||
|
||||
This section has moved here: https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify
|
||||
9
packages/now-static-build/test/fixtures/12-create-react-app/now.json
vendored
Normal file
9
packages/now-static-build/test/fixtures/12-create-react-app/now.json
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"version": 2,
|
||||
"builds": [
|
||||
{ "src": "package.json", "use": "@now/static-build", "config": { "zeroConfig": true } }
|
||||
],
|
||||
"probes": [
|
||||
{ "path": "/", "mustContain": "React App" }
|
||||
]
|
||||
}
|
||||
31
packages/now-static-build/test/fixtures/12-create-react-app/package.json
vendored
Normal file
31
packages/now-static-build/test/fixtures/12-create-react-app/package.json
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"name": "12-create-react-app",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"react": "^16.8.6",
|
||||
"react-dom": "^16.8.6",
|
||||
"react-scripts": "3.0.1"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "react-scripts start",
|
||||
"build": "react-scripts build",
|
||||
"test": "react-scripts test",
|
||||
"eject": "react-scripts eject"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"extends": "react-app"
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
">0.2%",
|
||||
"not dead",
|
||||
"not op_mini all"
|
||||
],
|
||||
"development": [
|
||||
"last 1 chrome version",
|
||||
"last 1 firefox version",
|
||||
"last 1 safari version"
|
||||
]
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user