Compare commits

..

25 Commits

Author SHA1 Message Date
JJ Kasper
e2ae497762 Publish Stable
- @now/next@2.5.2
2020-04-06 15:35:12 -05:00
JJ Kasper
89989719c2 Publish Canary
- @now/next@2.5.2-canary.0
 - @now/node@1.5.1-canary.0
 - @now/static-build@0.15.2-canary.3
2020-04-06 15:27:03 -05:00
Joe Haddad
8166b8e1e7 [now-next] Correctly Exclude API Routes from Pages (#4018)
This pull request correctly omits dependencies for API Routes from pages.
2020-04-06 20:19:08 +00:00
Logan McAnsh
1ceeac498c [now-node] Add NowApiHandler type (#4001)
* add NowApiHandler type

`now` equivalent of `NextApiHandler` introduced https://github.com/zeit/next.js/pull/10573

* chore: add fixture

Signed-off-by: Logan McAnsh <logan@mcan.sh>
2020-04-03 18:29:56 -04:00
Arunoda Susiripala
1c47d1360d [now-next] Fix some typos related to fixtures (#3995)
They should be `probes` I guess.
2020-04-03 13:43:22 +00:00
Leo Lamprecht
ddcd0918e9 Removed Environment Variables (#3997) 2020-04-03 01:52:02 +02:00
Steven
573b6b8110 [now-static-build] Fix 12-creact-react-app test fixture (#3990)
Since enabling `CI` environment variable for cloud builds, this test fails because it is meant to emit a warning however that warning has turned into an error.

```
05:40:53.148  Treating warnings as errors because process.env.CI = true.
05:40:53.148  Most CI servers set it automatically.
05:40:53.148  Failed to compile.
05:40:53.149  ./src/App.js
05:40:53.149    Line 1:  'useState' is defined but never used  no-unused-vars
05:40:53.172  error Command failed with exit code 1.
```

We can again treat lint errors as warnings by setting `CI=false`.
2020-04-01 14:27:11 +00:00
Steven
40039d7f9b Publish Canary
- @now/build-utils@2.2.1-canary.0
2020-03-31 17:18:32 -04:00
Steven
dcb37e92f5 [now-build-utils] Hide internal stack trace for errors (#3988)
Example build output given a user's build script named `shouldfail.js`:

## Before

```
/zeit/4af70cdc/shouldfail.js:3
throw new Error('This is my failure')
^
Error: This is my failure
    at Object.<anonymous> (/zeit/4af70cdc/shouldfail.js:3:7)
    at Module._compile (internal/modules/cjs/loader.js:955:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:991:10)
    at Module.load (internal/modules/cjs/loader.js:811:32)
    at Function.Module._load (internal/modules/cjs/loader.js:723:14)
    at Function.Module.runMain (internal/modules/cjs/loader.js:1043:10)
    at internal/main/run_main_module.js:17:11
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
Error: Exited with 1
    at ChildProcess.<anonymous> (/zeit/687b1c64/.build-utils/node_modules/@now/build-utils/dist/index.js:31350:24)
    at ChildProcess.emit (events.js:223:5)
    at ChildProcess.EventEmitter.emit (domain.js:475:20)
    at maybeClose (internal/child_process.js:1021:16)
    at Process.ChildProcess._handle.onexit (internal/child_process.js:283:5)
worker exited with code 20 and signal null
Done with "package.json"
```

## After 

```
/zeit/255bfdd/shouldfail.js:3
throw new Error('This is my failure')
^
Error: This is my failure
    at Object.<anonymous> (/zeit/255bfdd/shouldfail.js:3:7)
    at Module._compile (internal/modules/cjs/loader.js:955:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:991:10)
    at Module.load (internal/modules/cjs/loader.js:811:32)
    at Function.Module._load (internal/modules/cjs/loader.js:723:14)
    at Function.Module.runMain (internal/modules/cjs/loader.js:1043:10)
    at internal/main/run_main_module.js:17:11
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
Error: Command "yarn run build" exited with 1
worker exited with code 20 and signal null
Done with "package.json"
```
2020-03-31 21:09:57 +00:00
Steven
fe7f875549 Publish Canary
- now@17.1.2-canary.8
2020-03-31 12:20:59 -04:00
Steven
a516ed6fb8 [now-cli] Fix error message link to build logs (#3986)
The current error message prints a link that is not clickable from the terminal.

This PR adds the missing `https://` protocol prefix, so that the link is clickable.
2020-03-31 12:09:11 -04:00
Steven
ca2c5f85ef [now-cli] Fix for adding secret with hyphen prefix (#3983)
Follow up to #3982 which didn't actually fix the secret value. Instead it was adding `true` as the value.
2020-03-31 13:06:46 +00:00
Tim Neutkens
adb5a01cc0 Upgrade Next.js (#3984) 2020-03-31 12:24:21 +02:00
Steven
6b4d39ab4d Publish Canary
- now@17.1.2-canary.7
2020-03-30 18:27:55 -04:00
Steven
07ce3d2e34 [now-cli] Bump mri to 1.1.5 (#3982)
This fixes the error when attempting to add a secret with a hyphen and underscore such as the following:

```
$ now secret add name '-foo_bar'
Error! argv._.slice is not a function
```
2020-03-30 22:13:00 +00:00
JJ Kasper
93ffcf487b Publish Canary
- @now/routing-utils@1.8.1-canary.0
2020-03-30 14:18:01 -05:00
JJ Kasper
3631f0f4cf [now-routing-utils] Update to not add path segments to redirect query automatically (#3981)
As discussed this removes automatically adding path segments to redirect's destination query and only adds them if manually specified

x-ref: https://github.com/zeit/next.js/pull/11497
2020-03-30 18:57:24 +00:00
Steven
b67b5be8a9 Publish Canary
- now@17.1.2-canary.6
 - now-client@7.0.2-canary.2
 - @now/static-build@0.15.2-canary.2
2020-03-30 14:06:57 -04:00
Steven
bf67b1a29e [now-static-build][now-client] Ignore known static outputs (#3980)
We already ignore specific files such as `node_modules` and `.env` during the upload phase so these never make it to the build. However, if those files are generated during the build, that are still emitted.

This PR will ignore these specific files even if they end up in the output directory (for example, when the user assigns `outputDirectory='.'` in project settings)
2020-03-30 17:53:47 +00:00
Max Rovensky
ed86473f74 Publish Canary
- now@17.1.2-canary.5
 - now-client@7.0.2-canary.1
2020-03-30 17:57:56 +08:00
Max
399a3cd114 [now-cli][now-client] Change forceNewWithCache to withCache (#3966)
Follow up to https://github.com/zeit/now/pull/3953 that makes the flag composable
2020-03-30 09:51:05 +00:00
Steven
d0fd09810a Publish Stable
- @now/go@1.0.6
2020-03-28 18:33:40 -04:00
Steven
f298f2e894 Publish Canary
- @now/go@1.0.6-canary.0
2020-03-28 18:21:06 -04:00
Steven
569200ae0e [now-go] Fix import for go-bridge (#3976)
Somehow, PR #3973 broke Go since the bridge is imported from this repo's master branch.

Go has very strict file name constraints and the file `[...path].js` is not compatible.


Here's what a `@now/go` deployment error message looks like:

```
Error: Command failed: go mod tidy
go: finding github.com/zeit/now latest
go: downloading github.com/zeit/now v0.0.0-20200326223129-c91495338d5e
go: extracting github.com/zeit/now v0.0.0-20200326223129-c91495338d5e
-> unzip /tmp/5a0676f5/pkg/mod/cache/download/github.com/zeit/now/@v/v0.0.0-20200326223129-c91495338d5e.zip: malformed file path "packages/now-next/test/fixtures/22-ssg-v2-catchall/pages/[...path].js": double dot
handler imports
github.com/zeit/now/utils/go/bridge: unzip /tmp/5a0676f5/pkg/mod/cache/download/github.com/zeit/now/@v/v0.0.0-20200326223129-c91495338d5e.zip: malformed file path "packages/now-next/test/fixtures/22-ssg-v2-catchall/pages/[...path].js": double dot
```

The solution is to move Go Bridge into a separate repository: https://github.com/zeit/now-go-bridge

This will also have the side effect of speeding up Go imports because the repo will be much smaller.
2020-03-28 22:16:42 +00:00
Nathan Rajlich
c91495338d Update signal-exit to v3.0.3 (#3974)
@tootallnate's bug fix for `SIGHUB` on Windows has been merged and
published as `signal-exit@3.0.3`, so no more need for the "resolutions"
field in `package.json`.

The `yarn.lock` file has been updated accordingly.
2020-03-26 22:31:29 +00:00
42 changed files with 298 additions and 110 deletions

View File

@@ -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"
}
}

View File

@@ -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

View File

@@ -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

View File

@@ -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",

View File

@@ -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;

View File

@@ -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",

View File

@@ -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],

View File

@@ -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

View File

@@ -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,

View File

@@ -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);

View File

@@ -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);

View File

@@ -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,
};

View File

@@ -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,

View File

@@ -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: [

View File

@@ -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,

View File

@@ -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",

View File

@@ -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`
);
}

View File

@@ -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';

View File

@@ -19,7 +19,7 @@ export interface NowClientOptions {
teamId?: string;
apiUrl?: string;
force?: boolean;
forceNewWithCache?: boolean;
withCache?: boolean;
userAgent?: string;
defaultName?: string;
isDirectory?: boolean;

View File

@@ -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',

View File

@@ -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) {

View File

@@ -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() {

View File

@@ -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() {

View File

@@ -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",

View File

@@ -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",

View File

@@ -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 }
);

View File

@@ -12,7 +12,7 @@
}
}
],
"propes": [
"probes": [
{
"path": "/api/memory",
"status": 200,

View File

@@ -9,7 +9,7 @@
}
}
],
"propes": [
"probes": [
{
"path": "/",
"status": 200,

View File

@@ -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",

View File

@@ -15,3 +15,8 @@ export type NowResponse = ServerResponse & {
json: (jsonBody: any) => NowResponse;
status: (statusCode: number) => NowResponse;
};
export type NowApiHandler = (
req: NowRequest,
res: NowResponse
) => void;

View 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;

View File

@@ -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",

View File

@@ -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;
}
}
}

View File

@@ -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);

View File

@@ -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",

View File

@@ -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(/^\.\/?/, ''), '**/*')];

View File

@@ -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"
},

View File

@@ -0,0 +1 @@
<h1>Example Page</h1>

View File

@@ -0,0 +1,10 @@
{
"version": 2,
"builds": [
{
"src": "package.json",
"use": "@now/static-build",
"config": { "zeroConfig": true, "outputDirectory": "." }
}
]
}

View 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"
}
}

View 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 });
};

View File

@@ -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"