mirror of
https://github.com/LukeHagar/vercel.git
synced 2025-12-26 11:49:15 +00:00
Compare commits
25 Commits
@now/next@
...
@now/next@
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e2ae497762 | ||
|
|
89989719c2 | ||
|
|
8166b8e1e7 | ||
|
|
1ceeac498c | ||
|
|
1c47d1360d | ||
|
|
ddcd0918e9 | ||
|
|
573b6b8110 | ||
|
|
40039d7f9b | ||
|
|
dcb37e92f5 | ||
|
|
fe7f875549 | ||
|
|
a516ed6fb8 | ||
|
|
ca2c5f85ef | ||
|
|
adb5a01cc0 | ||
|
|
6b4d39ab4d | ||
|
|
07ce3d2e34 | ||
|
|
93ffcf487b | ||
|
|
3631f0f4cf | ||
|
|
b67b5be8a9 | ||
|
|
bf67b1a29e | ||
|
|
ed86473f74 | ||
|
|
399a3cd114 | ||
|
|
d0fd09810a | ||
|
|
f298f2e894 | ||
|
|
569200ae0e | ||
|
|
c91495338d |
@@ -8,8 +8,8 @@
|
||||
"start": "next start"
|
||||
},
|
||||
"dependencies": {
|
||||
"next": "9.2.2",
|
||||
"react": "16.13.0",
|
||||
"react-dom": "16.13.0"
|
||||
"next": "^9.3.3",
|
||||
"react": "^16.13.0",
|
||||
"react-dom": "^16.13.0"
|
||||
}
|
||||
}
|
||||
|
||||
4
now.json
4
now.json
@@ -9,10 +9,6 @@
|
||||
"destination": "/api/frameworks"
|
||||
}
|
||||
],
|
||||
"env": {
|
||||
"GITHUB_ACCESS_TOKEN": "@now-api-examples-github-token",
|
||||
"SENTRY_DSN": "@sentry-product-dsn"
|
||||
},
|
||||
"github": {
|
||||
"silent": true,
|
||||
"autoJobCancelation": true
|
||||
|
||||
@@ -59,9 +59,6 @@
|
||||
"pre-commit": "lint-staged"
|
||||
}
|
||||
},
|
||||
"resolutions": {
|
||||
"signal-exit": "TooTallNate/signal-exit#update/sighub-to-sigint-on-windows"
|
||||
},
|
||||
"prettier": {
|
||||
"trailingComma": "es5",
|
||||
"singleQuote": true
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@now/build-utils",
|
||||
"version": "2.2.0",
|
||||
"version": "2.2.1-canary.0",
|
||||
"license": "MIT",
|
||||
"main": "./dist/index.js",
|
||||
"types": "./dist/index.d.js",
|
||||
|
||||
@@ -6,13 +6,18 @@ import spawn from 'cross-spawn';
|
||||
import { SpawnOptions } from 'child_process';
|
||||
import { deprecate } from 'util';
|
||||
import { cpus } from 'os';
|
||||
import { NowBuildError } from '../errors';
|
||||
import { Meta, PackageJson, NodeVersion, Config } from '../types';
|
||||
import { getSupportedNodeVersion, getLatestNodeVersion } from './node-version';
|
||||
|
||||
interface SpawnOptionsExtended extends SpawnOptions {
|
||||
prettyCommand?: string;
|
||||
}
|
||||
|
||||
export function spawnAsync(
|
||||
command: string,
|
||||
args: string[],
|
||||
opts: SpawnOptions = {}
|
||||
opts: SpawnOptionsExtended = {}
|
||||
) {
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
const stderrLogs: Buffer[] = [];
|
||||
@@ -29,12 +34,18 @@ export function spawnAsync(
|
||||
return resolve();
|
||||
}
|
||||
|
||||
const errorLogs = stderrLogs.map(line => line.toString()).join('');
|
||||
if (opts.stdio !== 'inherit') {
|
||||
reject(new Error(`Exited with ${code || signal}\n${errorLogs}`));
|
||||
} else {
|
||||
reject(new Error(`Exited with ${code || signal}`));
|
||||
}
|
||||
const cmd = opts.prettyCommand
|
||||
? `Command "${opts.prettyCommand}"`
|
||||
: 'Command';
|
||||
reject(
|
||||
new NowBuildError({
|
||||
code: `NOW_BUILD_UTILS_SPAWN_${code || signal}`,
|
||||
message:
|
||||
opts.stdio === 'inherit'
|
||||
? `${cmd} exited with ${code || signal}`
|
||||
: stderrLogs.map(line => line.toString()).join(''),
|
||||
})
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -42,7 +53,7 @@ export function spawnAsync(
|
||||
export function execAsync(
|
||||
command: string,
|
||||
args: string[],
|
||||
opts: SpawnOptions = {}
|
||||
opts: SpawnOptionsExtended = {}
|
||||
) {
|
||||
return new Promise<{ stdout: string; stderr: string; code: number }>(
|
||||
(resolve, reject) => {
|
||||
@@ -64,10 +75,15 @@ export function execAsync(
|
||||
child.on('error', reject);
|
||||
child.on('close', (code, signal) => {
|
||||
if (code !== 0) {
|
||||
const cmd = opts.prettyCommand
|
||||
? `Command "${opts.prettyCommand}"`
|
||||
: 'Command';
|
||||
|
||||
return reject(
|
||||
new Error(
|
||||
`Program "${command}" exited with non-zero exit code ${code} ${signal}.`
|
||||
)
|
||||
new NowBuildError({
|
||||
code: `NOW_BUILD_UTILS_EXEC_${code || signal}`,
|
||||
message: `${cmd} exited with ${code || signal}`,
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
@@ -82,18 +98,20 @@ export function execAsync(
|
||||
}
|
||||
|
||||
export function spawnCommand(command: string, options: SpawnOptions = {}) {
|
||||
const opts = { ...options, prettyCommand: command };
|
||||
if (process.platform === 'win32') {
|
||||
return spawn('cmd.exe', ['/C', command], options);
|
||||
return spawn('cmd.exe', ['/C', command], opts);
|
||||
}
|
||||
|
||||
return spawn('sh', ['-c', command], options);
|
||||
return spawn('sh', ['-c', command], opts);
|
||||
}
|
||||
|
||||
export async function execCommand(command: string, options: SpawnOptions = {}) {
|
||||
const opts = { ...options, prettyCommand: command };
|
||||
if (process.platform === 'win32') {
|
||||
await spawnAsync('cmd.exe', ['/C', command], options);
|
||||
await spawnAsync('cmd.exe', ['/C', command], opts);
|
||||
} else {
|
||||
await spawnAsync('sh', ['-c', command], options);
|
||||
await spawnAsync('sh', ['-c', command], opts);
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -120,9 +138,11 @@ export async function runShellScript(
|
||||
assert(path.isAbsolute(fsPath));
|
||||
const destPath = path.dirname(fsPath);
|
||||
await chmodPlusX(fsPath);
|
||||
await spawnAsync(`./${path.basename(fsPath)}`, args, {
|
||||
cwd: destPath,
|
||||
const command = `./${path.basename(fsPath)}`;
|
||||
await spawnAsync(command, args, {
|
||||
...spawnOpts,
|
||||
cwd: destPath,
|
||||
prettyCommand: command,
|
||||
});
|
||||
return true;
|
||||
}
|
||||
@@ -249,7 +269,7 @@ export async function runNpmInstall(
|
||||
debug(`Installing to ${destPath}`);
|
||||
|
||||
const { hasPackageLockJson } = await scanParentDirs(destPath);
|
||||
const opts: SpawnOptions = { cwd: destPath, ...spawnOpts };
|
||||
const opts: SpawnOptionsExtended = { cwd: destPath, ...spawnOpts };
|
||||
const env = opts.env ? { ...opts.env } : { ...process.env };
|
||||
delete env.NODE_ENV;
|
||||
opts.env = env;
|
||||
@@ -258,11 +278,13 @@ export async function runNpmInstall(
|
||||
let commandArgs: string[];
|
||||
|
||||
if (hasPackageLockJson) {
|
||||
opts.prettyCommand = 'npm install';
|
||||
command = 'npm';
|
||||
commandArgs = args
|
||||
.filter(a => a !== '--prefer-offline')
|
||||
.concat(['install', '--no-audit', '--unsafe-perm']);
|
||||
} else {
|
||||
opts.prettyCommand = 'yarn install';
|
||||
command = 'yarn';
|
||||
commandArgs = args.concat(['install', '--ignore-engines']);
|
||||
}
|
||||
@@ -285,7 +307,7 @@ export async function runBundleInstall(
|
||||
}
|
||||
|
||||
assert(path.isAbsolute(destPath));
|
||||
const opts = { cwd: destPath, ...spawnOpts };
|
||||
const opts = { ...spawnOpts, cwd: destPath, prettyCommand: 'bundle install' };
|
||||
|
||||
await spawnAsync(
|
||||
'bundle',
|
||||
@@ -313,7 +335,7 @@ export async function runPipInstall(
|
||||
}
|
||||
|
||||
assert(path.isAbsolute(destPath));
|
||||
const opts = { cwd: destPath, ...spawnOpts };
|
||||
const opts = { ...spawnOpts, cwd: destPath, prettyCommand: 'pip3 install' };
|
||||
|
||||
await spawnAsync(
|
||||
'pip3',
|
||||
@@ -340,18 +362,22 @@ export async function runPackageJsonScript(
|
||||
);
|
||||
if (!hasScript) return false;
|
||||
|
||||
const opts = { cwd: destPath, ...spawnOpts };
|
||||
|
||||
if (hasPackageLockJson) {
|
||||
console.log(`Running "npm run ${scriptName}"`);
|
||||
await spawnAsync('npm', ['run', scriptName], opts);
|
||||
const prettyCommand = `npm run ${scriptName}`;
|
||||
console.log(`Running "${prettyCommand}"`);
|
||||
await spawnAsync('npm', ['run', scriptName], {
|
||||
...spawnOpts,
|
||||
cwd: destPath,
|
||||
prettyCommand,
|
||||
});
|
||||
} else {
|
||||
console.log(`Running "yarn run ${scriptName}"`);
|
||||
await spawnAsync(
|
||||
'yarn',
|
||||
['--ignore-engines', '--cwd', destPath, 'run', scriptName],
|
||||
opts
|
||||
);
|
||||
const prettyCommand = `yarn run ${scriptName}`;
|
||||
console.log(`Running "${prettyCommand}"`);
|
||||
await spawnAsync('yarn', ['--ignore-engines', 'run', scriptName], {
|
||||
...spawnOpts,
|
||||
cwd: destPath,
|
||||
prettyCommand,
|
||||
});
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "now",
|
||||
"version": "17.1.2-canary.4",
|
||||
"version": "17.1.2-canary.8",
|
||||
"preferGlobal": true,
|
||||
"license": "Apache-2.0",
|
||||
"description": "The command-line interface for Now",
|
||||
@@ -141,7 +141,7 @@
|
||||
"micro": "9.1.2",
|
||||
"mime-types": "2.1.24",
|
||||
"minimatch": "3.0.4",
|
||||
"mri": "1.1.0",
|
||||
"mri": "1.1.5",
|
||||
"ms": "2.1.2",
|
||||
"node-fetch": "2.6.0",
|
||||
"npm-package-arg": "6.1.0",
|
||||
|
||||
@@ -46,7 +46,7 @@ export const latestHelp = () => `
|
||||
)} Path to the global ${'`.now`'} directory
|
||||
-d, --debug Debug mode [off]
|
||||
-f, --force Force a new deployment even if nothing has changed
|
||||
--force-with-cache Force a new deployment even if nothing has changed but retain build cache
|
||||
--with-cache Retain build cache when using "--force"
|
||||
-t ${chalk.underline('TOKEN')}, --token=${chalk.underline(
|
||||
'TOKEN'
|
||||
)} Login token
|
||||
@@ -98,7 +98,7 @@ export const latestHelp = () => `
|
||||
|
||||
export const latestArgs = {
|
||||
'--force': Boolean,
|
||||
'--force-with-cache': Boolean,
|
||||
'--with-cache': Boolean,
|
||||
'--public': Boolean,
|
||||
'--no-clipboard': Boolean,
|
||||
'--env': [String],
|
||||
|
||||
@@ -506,7 +506,7 @@ export default async function main(
|
||||
env: deploymentEnv,
|
||||
build: { env: deploymentBuildEnv },
|
||||
forceNew: argv['--force'],
|
||||
forceNewWithCache: argv['--force-with-cache'],
|
||||
withCache: argv['--with-cache'],
|
||||
quiet,
|
||||
wantsPublic: argv['--public'] || localConfig.public,
|
||||
isFile,
|
||||
@@ -666,7 +666,7 @@ export default async function main(
|
||||
if (err instanceof BuildError) {
|
||||
output.error('Build failed');
|
||||
output.error(
|
||||
`Check your logs at ${now.url}/_logs or run ${code(
|
||||
`Check your logs at https://${now.url}/_logs or run ${code(
|
||||
`now logs ${now.url}`,
|
||||
{
|
||||
// Backticks are interpreted as part of the URL, causing CMD+Click
|
||||
|
||||
@@ -93,7 +93,7 @@ let paths: string[];
|
||||
|
||||
// Options
|
||||
let forceNew: boolean;
|
||||
let forceNewWithCache: boolean;
|
||||
let withCache: boolean;
|
||||
let deploymentName: string;
|
||||
let sessionAffinity: string;
|
||||
let log: any;
|
||||
@@ -239,7 +239,7 @@ export default async function main(
|
||||
|
||||
// Options
|
||||
forceNew = argv.force;
|
||||
forceNewWithCache = argv['force-with-cache'];
|
||||
withCache = argv['with-cache'];
|
||||
deploymentName = argv.name;
|
||||
sessionAffinity = argv['session-affinity'];
|
||||
debugEnabled = argv.debug;
|
||||
@@ -743,7 +743,7 @@ async function sync({
|
||||
meta: metadata,
|
||||
followSymlinks,
|
||||
forceNew,
|
||||
forceNewWithCache,
|
||||
withCache,
|
||||
forwardNpm,
|
||||
quiet,
|
||||
scale,
|
||||
|
||||
@@ -110,7 +110,7 @@ const main = async ctx => {
|
||||
}
|
||||
|
||||
try {
|
||||
await run({ output, token, contextName, currentTeam });
|
||||
await run({ output, token, contextName, currentTeam, ctx });
|
||||
} catch (err) {
|
||||
handleError(err);
|
||||
exit(1);
|
||||
@@ -126,7 +126,7 @@ export default async ctx => {
|
||||
}
|
||||
};
|
||||
|
||||
async function run({ output, token, contextName, currentTeam }) {
|
||||
async function run({ output, token, contextName, currentTeam, ctx }) {
|
||||
const secrets = new NowSecrets({ apiUrl, token, debug, currentTeam });
|
||||
const args = argv._.slice(1);
|
||||
const start = Date.now();
|
||||
@@ -260,7 +260,28 @@ async function run({ output, token, contextName, currentTeam }) {
|
||||
return exit(1);
|
||||
}
|
||||
|
||||
const [name, value] = args;
|
||||
const [name, parsedValue] = args;
|
||||
const [originalName, originalValue] = ctx.argv.slice(-2);
|
||||
|
||||
let value = parsedValue;
|
||||
if (
|
||||
name === originalName &&
|
||||
typeof parsedValue === 'boolean' &&
|
||||
parsedValue !== originalValue
|
||||
) {
|
||||
// Corner case where `mri` transforms the secret value into a boolean because
|
||||
// it starts with a `-` so it thinks its a flag, so we use the original value instead.
|
||||
value = originalValue;
|
||||
}
|
||||
|
||||
if (typeof value === 'boolean') {
|
||||
const example = chalk.cyan(`$ now secret add -- "${name}"`);
|
||||
console.log(
|
||||
`If your secret starts with '-', make sure to terminate command options with double dash and wrap it in quotes. Example: \n ${example} `
|
||||
);
|
||||
return exit(1);
|
||||
}
|
||||
|
||||
await secrets.add(name, value);
|
||||
const elapsed = ms(new Date() - start);
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ export default class Client extends EventEmitter {
|
||||
_apiUrl: string;
|
||||
_debug: boolean;
|
||||
_forceNew: boolean;
|
||||
_forceNewWithCache: boolean;
|
||||
_withCache: boolean;
|
||||
_output: Output;
|
||||
_token: string;
|
||||
currentTeam?: string;
|
||||
@@ -31,21 +31,21 @@ export default class Client extends EventEmitter {
|
||||
token,
|
||||
currentTeam,
|
||||
forceNew = false,
|
||||
forceNewWithCache = false,
|
||||
withCache = false,
|
||||
debug = false,
|
||||
}: {
|
||||
apiUrl: string;
|
||||
token: string;
|
||||
currentTeam?: string;
|
||||
forceNew?: boolean;
|
||||
forceNewWithCache?: boolean;
|
||||
withCache?: boolean;
|
||||
debug?: boolean;
|
||||
}) {
|
||||
super();
|
||||
this._token = token;
|
||||
this._debug = debug;
|
||||
this._forceNew = forceNew;
|
||||
this._forceNewWithCache = forceNewWithCache;
|
||||
this._withCache = withCache;
|
||||
this._output = createOutput({ debug });
|
||||
this._apiUrl = apiUrl;
|
||||
this._onRetry = this._onRetry.bind(this);
|
||||
|
||||
@@ -66,7 +66,7 @@ export default async function processDeployment({
|
||||
quiet: boolean;
|
||||
nowConfig?: NowConfig;
|
||||
force?: boolean;
|
||||
forceNewWithCache?: boolean;
|
||||
withCache?: boolean;
|
||||
org: Org;
|
||||
projectName: string;
|
||||
isSettingUpProject: boolean;
|
||||
@@ -83,7 +83,7 @@ export default async function processDeployment({
|
||||
requestBody,
|
||||
deployStamp,
|
||||
force,
|
||||
forceNewWithCache,
|
||||
withCache,
|
||||
nowConfig,
|
||||
quiet,
|
||||
} = args;
|
||||
@@ -101,7 +101,7 @@ export default async function processDeployment({
|
||||
userAgent: ua,
|
||||
path: paths[0],
|
||||
force,
|
||||
forceNewWithCache,
|
||||
withCache,
|
||||
skipAutoDetectionConfirmation,
|
||||
};
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ export default class Now extends EventEmitter {
|
||||
token,
|
||||
currentTeam,
|
||||
forceNew = false,
|
||||
forceNewWithCache = false,
|
||||
withCache = false,
|
||||
debug = false,
|
||||
}) {
|
||||
super();
|
||||
@@ -42,7 +42,7 @@ export default class Now extends EventEmitter {
|
||||
this._token = token;
|
||||
this._debug = debug;
|
||||
this._forceNew = forceNew;
|
||||
this._forceNewWithCache = forceNewWithCache;
|
||||
this._withCache = withCache;
|
||||
this._output = createOutput({ debug });
|
||||
this._apiUrl = apiUrl;
|
||||
this._onRetry = this._onRetry.bind(this);
|
||||
@@ -72,7 +72,7 @@ export default class Now extends EventEmitter {
|
||||
env,
|
||||
build,
|
||||
forceNew = false,
|
||||
forceNewWithCache = false,
|
||||
withCache = false,
|
||||
target = null,
|
||||
deployStamp,
|
||||
projectSettings,
|
||||
@@ -164,7 +164,7 @@ export default class Now extends EventEmitter {
|
||||
meta,
|
||||
public: wantsPublic || nowConfig.public,
|
||||
forceNew,
|
||||
forceNewWithCache,
|
||||
withCache,
|
||||
name,
|
||||
project,
|
||||
description,
|
||||
@@ -190,7 +190,7 @@ export default class Now extends EventEmitter {
|
||||
quiet,
|
||||
nowConfig,
|
||||
force: forceNew,
|
||||
forceNewWithCache: forceNewWithCache,
|
||||
withCache,
|
||||
org,
|
||||
projectName: name,
|
||||
isSettingUpProject,
|
||||
|
||||
@@ -323,6 +323,21 @@ CMD ["node", "index.js"]`,
|
||||
'index.html': 'Home page',
|
||||
'secret/file.txt': 'my secret',
|
||||
},
|
||||
'build-secret': {
|
||||
'package.json': JSON.stringify({
|
||||
private: true,
|
||||
scripts: {
|
||||
build: 'mkdir public && echo $MY_SECRET > public/index.txt',
|
||||
},
|
||||
}),
|
||||
'now.json': JSON.stringify({
|
||||
build: {
|
||||
env: {
|
||||
MY_SECRET: '@mysecret',
|
||||
},
|
||||
},
|
||||
}),
|
||||
},
|
||||
'alias-rules': {
|
||||
'rules.json': JSON.stringify({
|
||||
rules: [
|
||||
|
||||
44
packages/now-cli/test/integration.js
vendored
44
packages/now-cli/test/integration.js
vendored
@@ -390,6 +390,50 @@ test('should error with suggestion for secrets subcommand', async t => {
|
||||
);
|
||||
});
|
||||
|
||||
test('should add secret with hyphen prefix', async t => {
|
||||
const target = fixture('build-secret');
|
||||
const key = 'mysecret';
|
||||
const value = '-foo_bar';
|
||||
|
||||
let secretCall = await execa(
|
||||
binaryPath,
|
||||
['secrets', 'add', ...defaultArgs, key, value],
|
||||
{
|
||||
cwd: target,
|
||||
reject: false,
|
||||
}
|
||||
);
|
||||
|
||||
t.is(
|
||||
secretCall.exitCode,
|
||||
0,
|
||||
formatOutput({ stderr: secretCall.stderr, stdout: secretCall.stdout })
|
||||
);
|
||||
|
||||
let targetCall = await execa(binaryPath, [...defaultArgs, '--confirm'], {
|
||||
cwd: target,
|
||||
reject: false,
|
||||
});
|
||||
|
||||
t.is(
|
||||
targetCall.exitCode,
|
||||
0,
|
||||
formatOutput({ stderr: targetCall.stderr, stdout: targetCall.stdout })
|
||||
);
|
||||
const { host } = new URL(targetCall.stdout);
|
||||
const response = await fetch(`https://${host}`);
|
||||
t.is(
|
||||
response.status,
|
||||
200,
|
||||
formatOutput({ stderr: targetCall.stderr, stdout: targetCall.stdout })
|
||||
);
|
||||
t.is(
|
||||
await response.text(),
|
||||
`${value}\n`,
|
||||
formatOutput({ stderr: targetCall.stderr, stdout: targetCall.stdout })
|
||||
);
|
||||
});
|
||||
|
||||
test('login with unregistered user', async t => {
|
||||
const { stdout, stderr, exitCode } = await execa(
|
||||
binaryPath,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "now-client",
|
||||
"version": "7.0.2-canary.0",
|
||||
"version": "7.0.2-canary.2",
|
||||
"main": "dist/index.js",
|
||||
"typings": "dist/index.d.ts",
|
||||
"homepage": "https://zeit.co",
|
||||
|
||||
@@ -169,9 +169,9 @@ export async function* deploy(
|
||||
deploymentOptions.forceNew = clientOptions.force;
|
||||
}
|
||||
|
||||
if (clientOptions.forceNewWithCache) {
|
||||
if (clientOptions.withCache) {
|
||||
debug(
|
||||
`'forceNewWithCache' is provided. Force deploy will be performed with cache retention`
|
||||
`'withCache' is provided. Force deploy will be performed with cache retention`
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import buildCreateDeployment from './create-deployment';
|
||||
|
||||
export { getNowIgnore } from './utils/index';
|
||||
export const createDeployment = buildCreateDeployment(2);
|
||||
export const createLegacyDeployment = buildCreateDeployment(1);
|
||||
export * from './errors';
|
||||
|
||||
@@ -19,7 +19,7 @@ export interface NowClientOptions {
|
||||
teamId?: string;
|
||||
apiUrl?: string;
|
||||
force?: boolean;
|
||||
forceNewWithCache?: boolean;
|
||||
withCache?: boolean;
|
||||
userAgent?: string;
|
||||
defaultName?: string;
|
||||
isDirectory?: boolean;
|
||||
|
||||
@@ -5,6 +5,7 @@ import { nodeFetch, zeitFetch } from './fetch';
|
||||
import { join, sep, relative } from 'path';
|
||||
import qs from 'querystring';
|
||||
import ignore from 'ignore';
|
||||
type Ignore = ReturnType<typeof ignore>;
|
||||
import { pkgVersion } from '../pkg';
|
||||
import { NowClientOptions, DeploymentOptions, NowConfig } from '../types';
|
||||
import { Sema } from 'async-sema';
|
||||
@@ -74,15 +75,17 @@ const maybeRead = async function<T>(path: string, default_: T) {
|
||||
}
|
||||
};
|
||||
|
||||
export async function getNowIgnore(path: string | string[]): Promise<any> {
|
||||
let ignores: string[] = [
|
||||
'.hg',
|
||||
'.git',
|
||||
export async function getNowIgnore(
|
||||
path: string | string[]
|
||||
): Promise<{ ig: Ignore; ignores: string[] }> {
|
||||
const ignores: string[] = [
|
||||
'.hg/',
|
||||
'.git/',
|
||||
'.gitmodules',
|
||||
'.svn',
|
||||
'.svn/',
|
||||
'.cache',
|
||||
'.next',
|
||||
'.now',
|
||||
'.next/',
|
||||
'.now/',
|
||||
'.npmignore',
|
||||
'.dockerignore',
|
||||
'.gitignore',
|
||||
@@ -95,7 +98,7 @@ export async function getNowIgnore(path: string | string[]): Promise<any> {
|
||||
'.venv',
|
||||
'npm-debug.log',
|
||||
'config.gypi',
|
||||
'node_modules',
|
||||
'node_modules/',
|
||||
'__pycache__/',
|
||||
'venv/',
|
||||
'CVS',
|
||||
|
||||
@@ -12,8 +12,8 @@ export function generateQueryString(clientOptions: NowClientOptions): string {
|
||||
options.set('forceNew', '1');
|
||||
}
|
||||
|
||||
if (clientOptions.forceNewWithCache) {
|
||||
options.set('forceNewWithCache', '1');
|
||||
if (clientOptions.withCache) {
|
||||
options.set('withCache', '1');
|
||||
}
|
||||
|
||||
if (clientOptions.skipAutoDetectionConfirmation) {
|
||||
|
||||
@@ -2,7 +2,7 @@ package main
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
now "github.com/zeit/now/utils/go/bridge"
|
||||
now "github.com/zeit/now-go-bridge/go/bridge"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
"net/http"
|
||||
"__NOW_HANDLER_PACKAGE_NAME"
|
||||
|
||||
now "github.com/zeit/now/utils/go/bridge"
|
||||
now "github.com/zeit/now-go-bridge/go/bridge"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@now/go",
|
||||
"version": "1.0.5",
|
||||
"version": "1.0.6",
|
||||
"license": "MIT",
|
||||
"main": "./dist/index",
|
||||
"homepage": "https://zeit.co/docs/runtimes#official-runtimes/go",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@now/next",
|
||||
"version": "2.5.1",
|
||||
"version": "2.5.2",
|
||||
"license": "MIT",
|
||||
"main": "./dist/index",
|
||||
"homepage": "https://zeit.co/docs/runtimes#official-runtimes/next-js",
|
||||
|
||||
@@ -829,7 +829,7 @@ export const build = async ({
|
||||
} = await nodeFileTrace(apiPages, { base: workPath });
|
||||
|
||||
const { fileList, reasons: nonApiReasons } = await nodeFileTrace(
|
||||
Object.keys(pages).map(page => pages[page].fsPath),
|
||||
nonApiPages,
|
||||
{ base: workPath }
|
||||
);
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
}
|
||||
}
|
||||
],
|
||||
"propes": [
|
||||
"probes": [
|
||||
{
|
||||
"path": "/api/memory",
|
||||
"status": 200,
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
}
|
||||
}
|
||||
],
|
||||
"propes": [
|
||||
"probes": [
|
||||
{
|
||||
"path": "/",
|
||||
"status": 200,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@now/node",
|
||||
"version": "1.5.0",
|
||||
"version": "1.5.1-canary.0",
|
||||
"license": "MIT",
|
||||
"main": "./dist/index",
|
||||
"homepage": "https://zeit.co/docs/runtimes#official-runtimes/node-js",
|
||||
|
||||
@@ -15,3 +15,8 @@ export type NowResponse = ServerResponse & {
|
||||
json: (jsonBody: any) => NowResponse;
|
||||
status: (statusCode: number) => NowResponse;
|
||||
};
|
||||
|
||||
export type NowApiHandler = (
|
||||
req: NowRequest,
|
||||
res: NowResponse
|
||||
) => void;
|
||||
|
||||
8
packages/now-node/test/fixtures/15-helpers/ts/handler.ts
vendored
Normal file
8
packages/now-node/test/fixtures/15-helpers/ts/handler.ts
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
import { NowApiHandler } from './types';
|
||||
|
||||
const listener: NowApiHandler = (req, res) => {
|
||||
res.status(200);
|
||||
res.send('hello:RANDOMNESS_PLACEHOLDER');
|
||||
};
|
||||
|
||||
export default listener;
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@now/routing-utils",
|
||||
"version": "1.8.0",
|
||||
"version": "1.8.1-canary.0",
|
||||
"description": "ZEIT Now routing utilities",
|
||||
"main": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
|
||||
@@ -172,19 +172,13 @@ function replaceSegments(
|
||||
}
|
||||
}
|
||||
|
||||
for (const [name, value] of Object.entries(indexes)) {
|
||||
if (
|
||||
isRedirect &&
|
||||
new RegExp(`\\${value}(?!\\d)`).test(pathname + (hash || ''))
|
||||
) {
|
||||
// Don't add segment to query if used in destination
|
||||
// and it's a redirect so that we don't pollute the query
|
||||
// with unwanted values
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!(name in query)) {
|
||||
query[name] = value;
|
||||
// We only add path segments to redirect queries if manually
|
||||
// specified
|
||||
if (!isRedirect) {
|
||||
for (const [name, value] of Object.entries(indexes)) {
|
||||
if (!(name in query)) {
|
||||
query[name] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -211,7 +211,7 @@ test('convertRedirects', () => {
|
||||
},
|
||||
{
|
||||
src: '^\\/projects(?:\\/([^\\/]+?))(?:\\/([^\\/]+?))$',
|
||||
headers: { Location: '/projects.html?id=$1&action=$2' },
|
||||
headers: { Location: '/projects.html' },
|
||||
status: 308,
|
||||
},
|
||||
{
|
||||
@@ -236,7 +236,7 @@ test('convertRedirects', () => {
|
||||
},
|
||||
{
|
||||
src: '^\\/catchme(?:\\/((?:[^\\/]+?)(?:\\/(?:[^\\/]+?))*))?$',
|
||||
headers: { Location: '/api/user?id=$1' },
|
||||
headers: { Location: '/api/user' },
|
||||
status: 308,
|
||||
},
|
||||
{
|
||||
@@ -321,6 +321,8 @@ test('convertRewrites', () => {
|
||||
destination: '/another-catch/:hello+',
|
||||
},
|
||||
{ source: '/catchme/:id*', destination: '/api/user' },
|
||||
{ source: '/:path', destination: '/test?path=:path' },
|
||||
{ source: '/:path/:two', destination: '/test?path=:path' },
|
||||
]);
|
||||
|
||||
const expected = [
|
||||
@@ -386,6 +388,16 @@ test('convertRewrites', () => {
|
||||
dest: '/api/user?id=$1',
|
||||
check: true,
|
||||
},
|
||||
{
|
||||
src: '^(?:\\/([^\\/]+?))$',
|
||||
dest: '/test?path=$1',
|
||||
check: true,
|
||||
},
|
||||
{
|
||||
check: true,
|
||||
dest: '/test?path=$1&two=$2',
|
||||
src: '^(?:\\/([^\\/]+?))(?:\\/([^\\/]+?))$',
|
||||
},
|
||||
];
|
||||
|
||||
deepEqual(actual, expected);
|
||||
@@ -404,6 +416,8 @@ test('convertRewrites', () => {
|
||||
['/catchall/first/', '/catchall/first/second/'],
|
||||
['/another-catch/first/', '/another-catch/first/second/'],
|
||||
['/catchme/id-1', '/catchme/id/2'],
|
||||
['/first', '/another'],
|
||||
['/first/second', '/one/two'],
|
||||
];
|
||||
|
||||
const mustNotMatch = [
|
||||
@@ -420,6 +434,8 @@ test('convertRewrites', () => {
|
||||
['/random-catch/'],
|
||||
['/another-catch/'],
|
||||
['/catchm', '/random'],
|
||||
['/another/one'],
|
||||
['/not', '/these'],
|
||||
];
|
||||
|
||||
assertRegexMatches(actual, mustMatch, mustNotMatch);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@now/static-build",
|
||||
"version": "0.15.2-canary.1",
|
||||
"version": "0.15.2-canary.3",
|
||||
"license": "MIT",
|
||||
"main": "./dist/index",
|
||||
"homepage": "https://zeit.co/docs/runtimes#official-runtimes/static-builds",
|
||||
|
||||
@@ -30,6 +30,7 @@ import {
|
||||
NowBuildError,
|
||||
} from '@now/build-utils';
|
||||
import { Route, Source } from '@now/routing-utils';
|
||||
import { getNowIgnore } from 'now-client';
|
||||
|
||||
const sleep = (n: number) => new Promise(resolve => setTimeout(resolve, n));
|
||||
|
||||
@@ -475,7 +476,15 @@ export async function build({
|
||||
routes.push(...frameworkRoutes);
|
||||
}
|
||||
|
||||
output = await glob('**', distPath, mountpoint);
|
||||
let ignore: string[] = [];
|
||||
if (config.zeroConfig) {
|
||||
const result = await getNowIgnore(distPath);
|
||||
ignore = result.ignores
|
||||
.map(file => (file.endsWith('/') ? `${file}**` : file))
|
||||
.concat(['yarn.lock', 'package-lock.json', 'package.json']);
|
||||
debug(`Using ignore: ${JSON.stringify(ignore)}`);
|
||||
}
|
||||
output = await glob('**', { cwd: distPath, ignore }, mountpoint);
|
||||
}
|
||||
|
||||
const watch = [path.join(mountpoint.replace(/^\.\/?/, ''), '**/*')];
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
},
|
||||
"scripts": {
|
||||
"start": "react-scripts start",
|
||||
"build": "react-scripts build",
|
||||
"build": "CI=false react-scripts build",
|
||||
"test": "react-scripts test",
|
||||
"eject": "react-scripts eject"
|
||||
},
|
||||
|
||||
1
packages/now-static-build/test/fixtures/55-ignore-output/example.html
vendored
Normal file
1
packages/now-static-build/test/fixtures/55-ignore-output/example.html
vendored
Normal file
@@ -0,0 +1 @@
|
||||
<h1>Example Page</h1>
|
||||
10
packages/now-static-build/test/fixtures/55-ignore-output/now.json
vendored
Normal file
10
packages/now-static-build/test/fixtures/55-ignore-output/now.json
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"version": 2,
|
||||
"builds": [
|
||||
{
|
||||
"src": "package.json",
|
||||
"use": "@now/static-build",
|
||||
"config": { "zeroConfig": true, "outputDirectory": "." }
|
||||
}
|
||||
]
|
||||
}
|
||||
9
packages/now-static-build/test/fixtures/55-ignore-output/package.json
vendored
Normal file
9
packages/now-static-build/test/fixtures/55-ignore-output/package.json
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"copee": "1.0.6"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "echo 'Output Page' > output.html && echo 'foo' > .env && git init && ls -lA"
|
||||
}
|
||||
}
|
||||
28
packages/now-static-build/test/fixtures/55-ignore-output/probe.js
vendored
Normal file
28
packages/now-static-build/test/fixtures/55-ignore-output/probe.js
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
const assert = require('assert').strict;
|
||||
|
||||
async function tryTest({ path, status, deploymentUrl, fetch }) {
|
||||
const res = await fetch(`https://${deploymentUrl}${path}`);
|
||||
assert.equal(res.status, status);
|
||||
console.log(`Finished testing "${path}" probe.`);
|
||||
}
|
||||
|
||||
module.exports = async ({ deploymentUrl, fetch }) => {
|
||||
await tryTest({ path: '/example.html', status: 200, deploymentUrl, fetch });
|
||||
await tryTest({ path: '/output.html', status: 200, deploymentUrl, fetch });
|
||||
await tryTest({
|
||||
path: '/node_modules/copee/package.json',
|
||||
status: 404,
|
||||
deploymentUrl,
|
||||
fetch,
|
||||
});
|
||||
await tryTest({ path: '/.git/HEAD', status: 404, deploymentUrl, fetch });
|
||||
await tryTest({ path: '/.env', status: 404, deploymentUrl, fetch });
|
||||
await tryTest({ path: '/yarn.lock', status: 404, deploymentUrl, fetch });
|
||||
await tryTest({
|
||||
path: '/package-lock.json',
|
||||
status: 404,
|
||||
deploymentUrl,
|
||||
fetch,
|
||||
});
|
||||
await tryTest({ path: '/package.json', status: 404, deploymentUrl, fetch });
|
||||
};
|
||||
13
yarn.lock
13
yarn.lock
@@ -7776,6 +7776,11 @@ mri@1.1.0:
|
||||
resolved "https://registry.yarnpkg.com/mri/-/mri-1.1.0.tgz#5c0a3f29c8ccffbbb1ec941dcec09d71fa32f36a"
|
||||
integrity sha1-XAo/KcjM/7ux7JQdzsCdcfoy82o=
|
||||
|
||||
mri@1.1.5:
|
||||
version "1.1.5"
|
||||
resolved "https://registry.yarnpkg.com/mri/-/mri-1.1.5.tgz#ce21dba2c69f74a9b7cf8a1ec62307e089e223e0"
|
||||
integrity sha512-d2RKzMD4JNyHMbnbWnznPaa8vbdlq/4pNZ3IgdaGrVbBhebBsGUUE/6qorTMYNS6TwuH3ilfOlD2bf4Igh8CKg==
|
||||
|
||||
ms@2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
|
||||
@@ -9733,10 +9738,10 @@ shellwords@^0.1.1:
|
||||
resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b"
|
||||
integrity sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==
|
||||
|
||||
signal-exit@TooTallNate/signal-exit#update/sighub-to-sigint-on-windows, signal-exit@^3.0.0, signal-exit@^3.0.2:
|
||||
version "3.0.2"
|
||||
uid "58088fa7f715149f8411e089a4a6e3fe6ed265ec"
|
||||
resolved "https://codeload.github.com/TooTallNate/signal-exit/tar.gz/58088fa7f715149f8411e089a4a6e3fe6ed265ec"
|
||||
signal-exit@^3.0.0, signal-exit@^3.0.2:
|
||||
version "3.0.3"
|
||||
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c"
|
||||
integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==
|
||||
|
||||
sinon@4.4.2:
|
||||
version "4.4.2"
|
||||
|
||||
Reference in New Issue
Block a user