mirror of
https://github.com/LukeHagar/vercel.git
synced 2025-12-11 12:57:46 +00:00
Compare commits
18 Commits
@now/pytho
...
@now/pytho
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
372a674625 | ||
|
|
fafeadb7ba | ||
|
|
966b1e763f | ||
|
|
bb60e1a5fe | ||
|
|
cac9f807cc | ||
|
|
a0b1254820 | ||
|
|
0faff4132b | ||
|
|
1793a1287d | ||
|
|
5b572239c1 | ||
|
|
f6a66d937e | ||
|
|
2cf9a2f489 | ||
|
|
454f4dcc61 | ||
|
|
6e1065fde2 | ||
|
|
80ce06b20c | ||
|
|
99f3ab8b64 | ||
|
|
ca4f6d2491 | ||
|
|
2ceb2a78aa | ||
|
|
d97da21afc |
@@ -115,15 +115,12 @@ jobs:
|
||||
|
||||
test-integration-macos-node-8:
|
||||
macos:
|
||||
xcode: '9.2.0'
|
||||
xcode: '9.0.1'
|
||||
working_directory: ~/repo
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace:
|
||||
at: .
|
||||
- run:
|
||||
name: Update Node.js
|
||||
command: curl -sfLS install-node.now.sh/8.11 | sh -s -- --yes
|
||||
- run:
|
||||
name: Output version
|
||||
command: node --version
|
||||
@@ -208,15 +205,12 @@ jobs:
|
||||
|
||||
test-integration-macos-now-dev-node-8:
|
||||
macos:
|
||||
xcode: '9.2.0'
|
||||
xcode: '9.0.1'
|
||||
working_directory: ~/repo
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace:
|
||||
at: .
|
||||
- run:
|
||||
name: Update Node.js
|
||||
command: curl -sfLS install-node.now.sh/8.11 | sh -s -- --yes
|
||||
- run:
|
||||
name: Output version
|
||||
command: node --version
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@now/build-utils",
|
||||
"version": "0.11.0",
|
||||
"version": "0.11.1",
|
||||
"license": "MIT",
|
||||
"main": "./dist/index.js",
|
||||
"types": "./dist/index.d.js",
|
||||
|
||||
@@ -191,23 +191,110 @@ export interface ShouldServeOptions {
|
||||
config: Config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Credit to Iain Reid, MIT license.
|
||||
* Source: https://gist.github.com/iainreid820/5c1cc527fe6b5b7dba41fec7fe54bf6e
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/no-namespace
|
||||
namespace PackageJson {
|
||||
/**
|
||||
* An author or contributor
|
||||
*/
|
||||
export interface Author {
|
||||
name: string;
|
||||
email?: string;
|
||||
homepage?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* A map of exposed bin commands
|
||||
*/
|
||||
export interface BinMap {
|
||||
[commandName: string]: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* A bugs link
|
||||
*/
|
||||
export interface Bugs {
|
||||
email: string;
|
||||
url: string;
|
||||
}
|
||||
|
||||
export interface Config {
|
||||
name?: string;
|
||||
config?: unknown;
|
||||
}
|
||||
|
||||
/**
|
||||
* A map of dependencies
|
||||
*/
|
||||
export interface DependencyMap {
|
||||
[dependencyName: string]: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* CommonJS package structure
|
||||
*/
|
||||
export interface Directories {
|
||||
lib?: string;
|
||||
bin?: string;
|
||||
man?: string;
|
||||
doc?: string;
|
||||
example?: string;
|
||||
}
|
||||
|
||||
export interface Engines {
|
||||
node?: string;
|
||||
npm?: string;
|
||||
}
|
||||
|
||||
export interface PublishConfig {
|
||||
registry?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* A project repository
|
||||
*/
|
||||
export interface Repository {
|
||||
type: string;
|
||||
url: string;
|
||||
}
|
||||
|
||||
export interface ScriptsMap {
|
||||
[scriptName: string]: string;
|
||||
}
|
||||
}
|
||||
|
||||
export interface PackageJson {
|
||||
name?: string;
|
||||
version?: string;
|
||||
engines?: {
|
||||
[key: string]: string;
|
||||
node: string;
|
||||
npm: string;
|
||||
};
|
||||
scripts?: {
|
||||
[key: string]: string;
|
||||
};
|
||||
dependencies?: {
|
||||
[key: string]: string;
|
||||
};
|
||||
devDependencies?: {
|
||||
[key: string]: string;
|
||||
};
|
||||
readonly name?: string;
|
||||
readonly version?: string;
|
||||
readonly description?: string;
|
||||
readonly keywords?: string[];
|
||||
readonly homepage?: string;
|
||||
readonly bugs?: string | PackageJson.Bugs;
|
||||
readonly license?: string;
|
||||
readonly author?: string | PackageJson.Author;
|
||||
readonly contributors?: string[] | PackageJson.Author[];
|
||||
readonly files?: string[];
|
||||
readonly main?: string;
|
||||
readonly bin?: string | PackageJson.BinMap;
|
||||
readonly man?: string | string[];
|
||||
readonly directories?: PackageJson.Directories;
|
||||
readonly repository?: string | PackageJson.Repository;
|
||||
readonly scripts?: PackageJson.ScriptsMap;
|
||||
readonly config?: PackageJson.Config;
|
||||
readonly dependencies?: PackageJson.DependencyMap;
|
||||
readonly devDependencies?: PackageJson.DependencyMap;
|
||||
readonly peerDependencies?: PackageJson.DependencyMap;
|
||||
readonly optionalDependencies?: PackageJson.DependencyMap;
|
||||
readonly bundledDependencies?: string[];
|
||||
readonly engines?: PackageJson.Engines;
|
||||
readonly os?: string[];
|
||||
readonly cpu?: string[];
|
||||
readonly preferGlobal?: boolean;
|
||||
readonly private?: boolean;
|
||||
readonly publishConfig?: PackageJson.PublishConfig;
|
||||
}
|
||||
|
||||
export interface NodeVersion {
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
To install the latest version of Now CLI, visit [zeit.co/download](https://zeit.co/download) or run this command:
|
||||
|
||||
```
|
||||
```bash
|
||||
npm i -g now
|
||||
```
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "now",
|
||||
"version": "16.4.0",
|
||||
"version": "16.4.1",
|
||||
"preferGlobal": true,
|
||||
"license": "Apache-2.0",
|
||||
"description": "The command-line interface for Now",
|
||||
@@ -58,7 +58,7 @@
|
||||
]
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 8.11"
|
||||
"node": ">= 8"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@sentry/node": "5.5.0",
|
||||
|
||||
@@ -127,6 +127,7 @@ export const legacyArgsMri = {
|
||||
'session-affinity',
|
||||
'regions',
|
||||
'dotenv',
|
||||
'target',
|
||||
],
|
||||
boolean: [
|
||||
'help',
|
||||
@@ -144,6 +145,7 @@ export const legacyArgsMri = {
|
||||
'no-scale',
|
||||
'no-verify',
|
||||
'dotenv',
|
||||
'prod',
|
||||
],
|
||||
default: {
|
||||
C: false,
|
||||
|
||||
@@ -388,7 +388,7 @@ export default async function main(
|
||||
|
||||
const deploymentResponse = handleCertError(
|
||||
output,
|
||||
await getDeploymentByIdOrHost(now, contextName, deployment.id, 'v9')
|
||||
await getDeploymentByIdOrHost(now, contextName, deployment.id, 'v10')
|
||||
);
|
||||
|
||||
if (deploymentResponse === 1) {
|
||||
|
||||
@@ -304,6 +304,18 @@ export default async function main(
|
||||
`You are using an old version of the Now Platform. More: ${link(infoUrl)}`
|
||||
);
|
||||
|
||||
if (argv.prod || argv.target) {
|
||||
error(
|
||||
`The option ${cmd(
|
||||
argv.prod ? '--prod' : '--target'
|
||||
)} is not supported for Now 1.0 deployments. To manually alias a deployment, use ${cmd(
|
||||
'now alias'
|
||||
)} instead.`
|
||||
);
|
||||
await exit(1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
const {
|
||||
authConfig: { token },
|
||||
config,
|
||||
|
||||
@@ -4,11 +4,11 @@ import { Deployment } from '../../types';
|
||||
import {
|
||||
DeploymentNotFound,
|
||||
DeploymentPermissionDenied,
|
||||
InvalidDeploymentId
|
||||
InvalidDeploymentId,
|
||||
} from '../errors-ts';
|
||||
import mapCertError from '../certs/map-cert-error';
|
||||
|
||||
type APIVersion = 'v5' | 'v9';
|
||||
type APIVersion = 'v5' | 'v10';
|
||||
|
||||
export default async function getDeploymentByIdOrHost(
|
||||
client: Client,
|
||||
|
||||
@@ -45,6 +45,7 @@ export default async function processDeployment({
|
||||
const opts: DeploymentOptions = {
|
||||
...requestBody,
|
||||
debug: now._debug,
|
||||
apiUrl: now._apiUrl,
|
||||
};
|
||||
|
||||
if (!legacy) {
|
||||
@@ -143,7 +144,7 @@ export default async function processDeployment({
|
||||
}
|
||||
|
||||
// Handle ready event
|
||||
if (event.type === 'ready') {
|
||||
if (event.type === 'alias-assigned') {
|
||||
if (deploySpinner) {
|
||||
deploySpinner();
|
||||
}
|
||||
|
||||
@@ -411,8 +411,16 @@ export async function shutdownBuilder(
|
||||
const ops: Promise<void>[] = [];
|
||||
|
||||
if (match.buildProcess) {
|
||||
debug(`Killing builder sub-process with PID ${match.buildProcess.pid}`);
|
||||
ops.push(treeKill(match.buildProcess.pid));
|
||||
const { pid } = match.buildProcess;
|
||||
debug(`Killing builder sub-process with PID ${pid}`);
|
||||
const killPromise = treeKill(pid)
|
||||
.then(() => {
|
||||
debug(`Killed builder with PID ${pid}`);
|
||||
})
|
||||
.catch((err: Error) => {
|
||||
debug(`Failed to kill builder with PID ${pid}: ${err}`);
|
||||
});
|
||||
ops.push(killPromise);
|
||||
delete match.buildProcess;
|
||||
}
|
||||
|
||||
|
||||
@@ -784,6 +784,19 @@ export class CantFindConfig extends NowError<
|
||||
}
|
||||
}
|
||||
|
||||
export class WorkingDirectoryDoesNotExist extends NowError<
|
||||
'CWD_DOES_NOT_EXIST',
|
||||
{}
|
||||
> {
|
||||
constructor() {
|
||||
super({
|
||||
code: 'CWD_DOES_NOT_EXIST',
|
||||
meta: {},
|
||||
message: 'The current working directory does not exist.',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export class FileNotFound extends NowError<'FILE_NOT_FOUND', { file: string }> {
|
||||
constructor(file: string) {
|
||||
super({
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
import path from 'path';
|
||||
import { CantParseJSONFile, CantFindConfig } from './errors-ts';
|
||||
import {
|
||||
CantParseJSONFile,
|
||||
CantFindConfig,
|
||||
WorkingDirectoryDoesNotExist,
|
||||
} from './errors-ts';
|
||||
import humanizePath from './humanize-path';
|
||||
import readJSONFile from './read-json-file';
|
||||
import readPackage from './read-package';
|
||||
@@ -8,13 +12,25 @@ import { Output } from './output';
|
||||
|
||||
let config: Config;
|
||||
|
||||
export default async function getConfig(output: Output, configFile?: string) {
|
||||
const localPath = process.cwd();
|
||||
|
||||
export default async function getConfig(
|
||||
output: Output,
|
||||
configFile?: string
|
||||
): Promise<Config | Error> {
|
||||
// If config was already read, just return it
|
||||
if (config) {
|
||||
return config;
|
||||
}
|
||||
|
||||
let localPath: string;
|
||||
try {
|
||||
localPath = process.cwd();
|
||||
} catch (err) {
|
||||
if (err.code === 'ENOENT') {
|
||||
return new WorkingDirectoryDoesNotExist();
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
|
||||
// First try with the config supplied by the user via --local-config
|
||||
if (configFile) {
|
||||
const localFilePath = path.resolve(localPath, configFile);
|
||||
|
||||
@@ -479,7 +479,7 @@ export default class Now extends EventEmitter {
|
||||
}
|
||||
|
||||
const url = `/${
|
||||
isBuilds ? 'v9' : 'v5'
|
||||
isBuilds ? 'v10' : 'v5'
|
||||
}/now/deployments/${encodeURIComponent(id)}`;
|
||||
|
||||
return this.retry(
|
||||
|
||||
@@ -263,18 +263,25 @@ if (satisfies(process.version, '10.x')) {
|
||||
console.log('Skipping `02-angular-node` test since it requires Node >= 10.9');
|
||||
}
|
||||
|
||||
test(
|
||||
'[now dev] 03-aurelia',
|
||||
testFixtureStdio('03-aurelia', async (t, port) => {
|
||||
const result = fetch(`http://localhost:${port}`);
|
||||
const response = await result;
|
||||
// eslint has `engines: { node: ">^6.14.0 || ^8.10.0 || >=9.10.0" }` in its `package.json`
|
||||
if (satisfies(process.version, '>^6.14.0 || ^8.10.0 || >=9.10.0')) {
|
||||
test(
|
||||
'[now dev] 03-aurelia',
|
||||
testFixtureStdio('03-aurelia', async (t, port) => {
|
||||
const result = fetch(`http://localhost:${port}`);
|
||||
const response = await result;
|
||||
|
||||
validateResponseHeaders(t, response);
|
||||
validateResponseHeaders(t, response);
|
||||
|
||||
const body = await response.text();
|
||||
t.regex(body, /Aurelia Navigation Skeleton/gm);
|
||||
})
|
||||
);
|
||||
const body = await response.text();
|
||||
t.regex(body, /Aurelia Navigation Skeleton/gm);
|
||||
})
|
||||
);
|
||||
} else {
|
||||
console.log(
|
||||
'Skipping `03-aurelia` test since it requires Node >= ^6.14.0 || ^8.10.0 || >=9.10.0'
|
||||
);
|
||||
}
|
||||
|
||||
// test(
|
||||
// '[now dev] 04-create-react-app-node',
|
||||
@@ -289,31 +296,45 @@ test(
|
||||
// })
|
||||
// );
|
||||
|
||||
test(
|
||||
'[now dev] 05-gatsby',
|
||||
testFixtureStdio('05-gatsby', async (t, port) => {
|
||||
const result = fetch(`http://localhost:${port}`);
|
||||
const response = await result;
|
||||
// eslint has `engines: { node: ">^6.14.0 || ^8.10.0 || >=9.10.0" }` in its `package.json`
|
||||
if (satisfies(process.version, '>^6.14.0 || ^8.10.0 || >=9.10.0')) {
|
||||
test(
|
||||
'[now dev] 05-gatsby',
|
||||
testFixtureStdio('05-gatsby', async (t, port) => {
|
||||
const result = fetch(`http://localhost:${port}`);
|
||||
const response = await result;
|
||||
|
||||
validateResponseHeaders(t, response);
|
||||
validateResponseHeaders(t, response);
|
||||
|
||||
const body = await response.text();
|
||||
t.regex(body, /Gatsby Default Starter/gm);
|
||||
})
|
||||
);
|
||||
const body = await response.text();
|
||||
t.regex(body, /Gatsby Default Starter/gm);
|
||||
})
|
||||
);
|
||||
} else {
|
||||
console.log(
|
||||
'Skipping `05-gatsby` test since it requires Node >= ^6.14.0 || ^8.10.0 || >=9.10.0'
|
||||
);
|
||||
}
|
||||
|
||||
test(
|
||||
'[now dev] 06-gridsome',
|
||||
testFixtureStdio('06-gridsome', async (t, port) => {
|
||||
const result = fetch(`http://localhost:${port}`);
|
||||
const response = await result;
|
||||
// mini-css-extract-plugin has `engines: { node: ">= 6.9.0 <7.0.0 || >= 8.9.0" }` in its `package.json`
|
||||
if (satisfies(process.version, '>= 6.9.0 <7.0.0 || >= 8.9.0')) {
|
||||
test(
|
||||
'[now dev] 06-gridsome',
|
||||
testFixtureStdio('06-gridsome', async (t, port) => {
|
||||
const result = fetch(`http://localhost:${port}`);
|
||||
const response = await result;
|
||||
|
||||
validateResponseHeaders(t, response);
|
||||
validateResponseHeaders(t, response);
|
||||
|
||||
const body = await response.text();
|
||||
t.regex(body, /Hello, world!/gm);
|
||||
})
|
||||
);
|
||||
const body = await response.text();
|
||||
t.regex(body, /Hello, world!/gm);
|
||||
})
|
||||
);
|
||||
} else {
|
||||
console.log(
|
||||
'Skipping `06-gridsome` test since it requires Node >= 6.9.0 <7.0.0 || >= 8.9.0'
|
||||
);
|
||||
}
|
||||
|
||||
test(
|
||||
'[now dev] 07-hexo-node',
|
||||
@@ -562,18 +583,25 @@ test('[now dev] double slashes redirect', async t => {
|
||||
}
|
||||
});
|
||||
|
||||
test(
|
||||
'[now dev] 18-marko',
|
||||
testFixtureStdio('18-marko', async (t, port) => {
|
||||
const result = fetch(`http://localhost:${port}`);
|
||||
const response = await result;
|
||||
// eslint has `engines: { node: ">^6.14.0 || ^8.10.0 || >=9.10.0" }` in its `package.json`
|
||||
if (satisfies(process.version, '>^6.14.0 || ^8.10.0 || >=9.10.0')) {
|
||||
test(
|
||||
'[now dev] 18-marko',
|
||||
testFixtureStdio('18-marko', async (t, port) => {
|
||||
const result = fetch(`http://localhost:${port}`);
|
||||
const response = await result;
|
||||
|
||||
validateResponseHeaders(t, response);
|
||||
validateResponseHeaders(t, response);
|
||||
|
||||
const body = await response.text();
|
||||
t.regex(body, /Marko Starter/gm);
|
||||
})
|
||||
);
|
||||
const body = await response.text();
|
||||
t.regex(body, /Marko Starter/gm);
|
||||
})
|
||||
);
|
||||
} else {
|
||||
console.log(
|
||||
'Skipping `18-marko` test since it requires Node >= ^6.14.0 || ^8.10.0 || >=9.10.0'
|
||||
);
|
||||
}
|
||||
|
||||
test(
|
||||
'[now dev] 19-mithril',
|
||||
@@ -601,18 +629,23 @@ test(
|
||||
})
|
||||
);
|
||||
|
||||
test(
|
||||
'[now dev] 21-charge',
|
||||
testFixtureStdio('21-charge', async (t, port) => {
|
||||
const result = fetch(`http://localhost:${port}`);
|
||||
const response = await result;
|
||||
// @static/charge has `engines: { node: ">= 8.10.0" }` in its `package.json`
|
||||
if (satisfies(process.version, '>= 8.10.0')) {
|
||||
test(
|
||||
'[now dev] 21-charge',
|
||||
testFixtureStdio('21-charge', async (t, port) => {
|
||||
const result = fetch(`http://localhost:${port}`);
|
||||
const response = await result;
|
||||
|
||||
validateResponseHeaders(t, response);
|
||||
validateResponseHeaders(t, response);
|
||||
|
||||
const body = await response.text();
|
||||
t.regex(body, /Welcome to my new Charge site/gm);
|
||||
})
|
||||
);
|
||||
const body = await response.text();
|
||||
t.regex(body, /Welcome to my new Charge site/gm);
|
||||
})
|
||||
);
|
||||
} else {
|
||||
console.log('Skipping `21-charge` test since it requires Node >= 8.10.0');
|
||||
}
|
||||
|
||||
test(
|
||||
'[now dev] 22-brunch',
|
||||
@@ -627,31 +660,43 @@ test(
|
||||
})
|
||||
);
|
||||
|
||||
test(
|
||||
'[now dev] 23-docusaurus',
|
||||
testFixtureStdio('23-docusaurus', async (t, port) => {
|
||||
const result = fetch(`http://localhost:${port}`);
|
||||
const response = await result;
|
||||
// react-dev-utils has `engines: { node: ">= 8.10" }` in its `package.json`
|
||||
if (satisfies(process.version, '>= 8.10')) {
|
||||
test(
|
||||
'[now dev] 23-docusaurus',
|
||||
testFixtureStdio('23-docusaurus', async (t, port) => {
|
||||
const result = fetch(`http://localhost:${port}`);
|
||||
const response = await result;
|
||||
|
||||
validateResponseHeaders(t, response);
|
||||
validateResponseHeaders(t, response);
|
||||
|
||||
const body = await response.text();
|
||||
t.regex(body, /Test Site · A website for testing/gm);
|
||||
})
|
||||
);
|
||||
const body = await response.text();
|
||||
t.regex(body, /Test Site · A website for testing/gm);
|
||||
})
|
||||
);
|
||||
} else {
|
||||
console.log('Skipping `23-docusaurus` test since it requires Node >= 8.10');
|
||||
}
|
||||
|
||||
test(
|
||||
'[now dev] 24-ember',
|
||||
testFixtureStdio('24-ember', async (t, port) => {
|
||||
const result = fetch(`http://localhost:${port}`);
|
||||
const response = await result;
|
||||
// eslint has `engines: { node: ">^6.14.0 || ^8.10.0 || >=9.10.0" }` in its `package.json`
|
||||
if (satisfies(process.version, '>^6.14.0 || ^8.10.0 || >=9.10.0')) {
|
||||
test(
|
||||
'[now dev] 24-ember',
|
||||
testFixtureStdio('24-ember', async (t, port) => {
|
||||
const result = fetch(`http://localhost:${port}`);
|
||||
const response = await result;
|
||||
|
||||
validateResponseHeaders(t, response);
|
||||
validateResponseHeaders(t, response);
|
||||
|
||||
const body = await response.text();
|
||||
t.regex(body, /HelloWorld/gm);
|
||||
})
|
||||
);
|
||||
const body = await response.text();
|
||||
t.regex(body, /HelloWorld/gm);
|
||||
})
|
||||
);
|
||||
} else {
|
||||
console.log(
|
||||
'Skipping `24-ember` test since it requires Node >= ^6.14.0 || ^8.10.0 || >=9.10.0'
|
||||
);
|
||||
}
|
||||
|
||||
test('[now dev] temporary directory listing', async t => {
|
||||
const directory = fixture('temporary-directory-listing');
|
||||
@@ -870,22 +915,28 @@ test('[now dev] do not rebuild for changes in the output directory', async t =>
|
||||
}
|
||||
});
|
||||
|
||||
test('[now dev] 25-nextjs-src-dir', async t => {
|
||||
const directory = fixture('25-nextjs-src-dir');
|
||||
const { dev, port } = await testFixture(directory);
|
||||
if (satisfies(process.version, '>= 8.9.0')) {
|
||||
test('[now dev] 25-nextjs-src-dir', async t => {
|
||||
const directory = fixture('25-nextjs-src-dir');
|
||||
const { dev, port } = await testFixture(directory);
|
||||
|
||||
try {
|
||||
// start `now dev` detached in child_process
|
||||
dev.unref();
|
||||
try {
|
||||
// start `now dev` detached in child_process
|
||||
dev.unref();
|
||||
|
||||
const result = await fetchWithRetry(`http://localhost:${port}`, 80);
|
||||
const response = await result;
|
||||
const result = await fetchWithRetry(`http://localhost:${port}`, 80);
|
||||
const response = await result;
|
||||
|
||||
validateResponseHeaders(t, response);
|
||||
validateResponseHeaders(t, response);
|
||||
|
||||
const body = await response.text();
|
||||
t.regex(body, /Next.js \+ Node.js API/gm);
|
||||
} finally {
|
||||
dev.kill('SIGTERM');
|
||||
}
|
||||
});
|
||||
const body = await response.text();
|
||||
t.regex(body, /Next.js \+ Node.js API/gm);
|
||||
} finally {
|
||||
dev.kill('SIGTERM');
|
||||
}
|
||||
});
|
||||
} else {
|
||||
console.log(
|
||||
'Skipping `25-nextjs-src-dir` test since it requires Node >= 8.9.0'
|
||||
);
|
||||
}
|
||||
|
||||
71
packages/now-cli/test/integration.js
vendored
71
packages/now-cli/test/integration.js
vendored
@@ -2037,6 +2037,40 @@ test('try to deploy with non-existing team', async t => {
|
||||
t.true(stderr.includes(goal));
|
||||
});
|
||||
|
||||
testv1('try to deploy v1 deployment with --prod', async t => {
|
||||
const target = fixture('node');
|
||||
const goal = `is not supported for Now 1.0 deployments`;
|
||||
|
||||
const { stderr, stdout, code } = await execa(binaryPath, [target, '--prod'], {
|
||||
reject: false,
|
||||
});
|
||||
|
||||
console.log(stderr);
|
||||
console.log(stdout);
|
||||
console.log(code);
|
||||
|
||||
t.is(code, 1);
|
||||
t.true(stderr.includes(goal));
|
||||
});
|
||||
|
||||
testv1('try to deploy v1 deployment with --target production', async t => {
|
||||
const target = fixture('node');
|
||||
const goal = `is not supported for Now 1.0 deployments`;
|
||||
|
||||
const { stderr, stdout, code } = await execa(
|
||||
binaryPath,
|
||||
[target, '--target', 'production'],
|
||||
{ reject: false }
|
||||
);
|
||||
|
||||
console.log(stderr);
|
||||
console.log(stdout);
|
||||
console.log(code);
|
||||
|
||||
t.is(code, 1);
|
||||
t.true(stderr.includes(goal));
|
||||
});
|
||||
|
||||
const verifyExampleAngular = (cwd, dir) =>
|
||||
fs.existsSync(path.join(cwd, dir, 'package.json')) &&
|
||||
fs.existsSync(path.join(cwd, dir, 'tsconfig.json')) &&
|
||||
@@ -2471,6 +2505,43 @@ test('now secret rm', async t => {
|
||||
t.is(output.code, 0, formatOutput(output));
|
||||
});
|
||||
|
||||
test('deploy with a custom API URL', async t => {
|
||||
const directory = fixture('static-single-file');
|
||||
|
||||
const { stdout, stderr, code } = await execa(
|
||||
binaryPath,
|
||||
[
|
||||
directory,
|
||||
'--public',
|
||||
'--name',
|
||||
session,
|
||||
'--api',
|
||||
'https://zeit.co/api',
|
||||
...defaultArgs,
|
||||
],
|
||||
{
|
||||
reject: false,
|
||||
}
|
||||
);
|
||||
|
||||
console.log(stderr);
|
||||
console.log(stdout);
|
||||
console.log(code);
|
||||
|
||||
// Ensure the exit code is right
|
||||
t.is(code, 0);
|
||||
|
||||
// Test if the output is really a URL
|
||||
const { href, host } = new URL(stdout);
|
||||
t.is(host.split('-')[0], session);
|
||||
|
||||
// Send a test request to the deployment
|
||||
const response = await fetch(href);
|
||||
const contentType = response.headers.get('content-type');
|
||||
|
||||
t.is(contentType, 'text/html; charset=utf-8');
|
||||
});
|
||||
|
||||
test.after.always(async () => {
|
||||
// Make sure the token gets revoked
|
||||
await execa(binaryPath, ['logout', ...defaultArgs]);
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
src
|
||||
types
|
||||
.git
|
||||
@@ -1,9 +1,18 @@
|
||||
{
|
||||
"name": "now-client",
|
||||
"version": "5.2.1",
|
||||
"version": "5.2.2",
|
||||
"main": "dist/src/index.js",
|
||||
"typings": "dist/src/index.d.ts",
|
||||
"homepage": "https://zeit.co",
|
||||
"license": "MIT",
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/zeit/now.git",
|
||||
"directory": "packages/now-client"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "tsc",
|
||||
"prepare": "npm run build",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { readdir as readRootFolder, lstatSync } from 'fs-extra';
|
||||
|
||||
import readdir from 'recursive-readdir';
|
||||
import { relative, join } from 'path';
|
||||
import { relative, join, isAbsolute } from 'path';
|
||||
import hashes, { mapToObject } from './utils/hashes';
|
||||
import uploadAndDeploy from './upload';
|
||||
import { getNowIgnore, createDebug, parseNowJSON } from './utils';
|
||||
@@ -53,6 +53,22 @@ export default function buildCreateDeployment(
|
||||
|
||||
let rootFiles: string[];
|
||||
|
||||
if (Array.isArray(path)) {
|
||||
for (const filePath of path) {
|
||||
if (!isAbsolute(filePath)) {
|
||||
throw new DeploymentError({
|
||||
code: 'invalid_path',
|
||||
message: `Provided path ${filePath} is not absolute`,
|
||||
});
|
||||
}
|
||||
}
|
||||
} else if (!isAbsolute(path)) {
|
||||
throw new DeploymentError({
|
||||
code: 'invalid_path',
|
||||
message: `Provided path ${path} is not absolute`,
|
||||
});
|
||||
}
|
||||
|
||||
if (isDirectory && !Array.isArray(path)) {
|
||||
debug(`Provided 'path' is a directory. Reading subpaths... `);
|
||||
rootFiles = await readRootFolder(path);
|
||||
@@ -171,9 +187,14 @@ export default function buildCreateDeployment(
|
||||
force,
|
||||
defaultName,
|
||||
debug: debug_,
|
||||
apiUrl,
|
||||
...metadata
|
||||
} = options;
|
||||
|
||||
if (apiUrl) {
|
||||
debug(`Using provided API URL: ${apiUrl}`);
|
||||
}
|
||||
|
||||
debug(`Setting platform version to ${version}`);
|
||||
metadata.version = version;
|
||||
|
||||
@@ -188,6 +209,7 @@ export default function buildCreateDeployment(
|
||||
force,
|
||||
defaultName,
|
||||
metadata,
|
||||
apiUrl,
|
||||
};
|
||||
|
||||
debug(`Creating the deployment and starting upload...`);
|
||||
|
||||
@@ -9,6 +9,7 @@ import {
|
||||
import checkDeploymentStatus from './deployment-status';
|
||||
import { generateQueryString } from './utils/query-string';
|
||||
import { Deployment, DeploymentOptions, NowJsonOptions } from './types';
|
||||
import { isReady, isAliasAssigned } from './utils/ready-state';
|
||||
|
||||
export interface Options {
|
||||
metadata: DeploymentOptions;
|
||||
@@ -22,6 +23,7 @@ export interface Options {
|
||||
preflight?: boolean;
|
||||
debug?: boolean;
|
||||
nowConfig?: NowJsonOptions;
|
||||
apiUrl?: string;
|
||||
}
|
||||
|
||||
async function* createDeployment(
|
||||
@@ -50,6 +52,7 @@ async function* createDeployment(
|
||||
...metadata,
|
||||
files: preparedFiles,
|
||||
}),
|
||||
apiUrl: options.apiUrl,
|
||||
}
|
||||
);
|
||||
|
||||
@@ -191,9 +194,12 @@ export default async function* deploy(
|
||||
}
|
||||
|
||||
if (deployment) {
|
||||
if (deployment.readyState === 'READY') {
|
||||
debug('Deployment is READY. Not performing additional polling');
|
||||
return yield { type: 'ready', payload: deployment };
|
||||
if (isReady(deployment) && isAliasAssigned(deployment)) {
|
||||
debug('Deployment state changed to READY 3');
|
||||
yield { type: 'ready', payload: deployment };
|
||||
|
||||
debug('Deployment alias assigned');
|
||||
return yield { type: 'alias-assigned', payload: deployment };
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -203,7 +209,8 @@ export default async function* deploy(
|
||||
options.token,
|
||||
metadata.version,
|
||||
options.teamId,
|
||||
debug
|
||||
debug,
|
||||
options.apiUrl
|
||||
)) {
|
||||
yield event;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,13 @@
|
||||
import sleep from 'sleep-promise';
|
||||
import ms from 'ms';
|
||||
import { fetch, API_DEPLOYMENTS, API_DEPLOYMENTS_LEGACY } from './utils';
|
||||
import { isDone, isReady, isFailed } from './utils/ready-state';
|
||||
import {
|
||||
isDone,
|
||||
isReady,
|
||||
isFailed,
|
||||
isAliasAssigned,
|
||||
isAliasError,
|
||||
} from './utils/ready-state';
|
||||
import { Deployment, DeploymentBuild } from './types';
|
||||
|
||||
interface DeploymentStatus {
|
||||
@@ -15,7 +21,8 @@ export default async function* checkDeploymentStatus(
|
||||
token: string,
|
||||
version: number | undefined,
|
||||
teamId: string | undefined,
|
||||
debug: Function
|
||||
debug: Function,
|
||||
apiUrl?: string
|
||||
): AsyncIterableIterator<DeploymentStatus> {
|
||||
let deploymentState = deployment;
|
||||
let allBuildsCompleted = false;
|
||||
@@ -25,20 +32,24 @@ export default async function* checkDeploymentStatus(
|
||||
debug(`Using ${version ? `${version}.0` : '2.0'} API for status checks`);
|
||||
|
||||
// If the deployment is ready, we don't want any of this to run
|
||||
if (isDone(deploymentState)) {
|
||||
debug(`Deployment is already READY. Not running status checks`);
|
||||
if (isDone(deploymentState) && isAliasAssigned(deploymentState)) {
|
||||
debug(
|
||||
`Deployment is already READY and aliases are assigned. Not running status checks`
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// Build polling
|
||||
debug('Waiting for builds and the deployment to complete...');
|
||||
let readyEventFired = false;
|
||||
while (true) {
|
||||
if (!allBuildsCompleted) {
|
||||
const buildsData = await fetch(
|
||||
`${apiDeployments}/${deployment.id}/builds${
|
||||
teamId ? `?teamId=${teamId}` : ''
|
||||
}`,
|
||||
token
|
||||
token,
|
||||
{ apiUrl }
|
||||
);
|
||||
|
||||
const data = await buildsData.json();
|
||||
@@ -84,16 +95,30 @@ export default async function* checkDeploymentStatus(
|
||||
return yield { type: 'error', payload: deploymentUpdate.error };
|
||||
}
|
||||
|
||||
if (isReady(deploymentUpdate)) {
|
||||
debug('Deployment state changed to READY');
|
||||
return yield { type: 'ready', payload: deploymentUpdate };
|
||||
if (isReady(deploymentUpdate) && !readyEventFired) {
|
||||
debug('Deployment state changed to READY 2');
|
||||
readyEventFired = true;
|
||||
yield { type: 'ready', payload: deploymentUpdate };
|
||||
}
|
||||
|
||||
if (isFailed(deploymentUpdate)) {
|
||||
debug('Deployment has failed');
|
||||
if (isAliasAssigned(deploymentUpdate)) {
|
||||
debug('Deployment alias assigned');
|
||||
return yield { type: 'alias-assigned', payload: deploymentUpdate };
|
||||
}
|
||||
|
||||
const aliasError = isAliasError(deploymentUpdate);
|
||||
|
||||
if (isFailed(deploymentUpdate) || aliasError) {
|
||||
debug(
|
||||
aliasError
|
||||
? 'Alias assignment error has occurred'
|
||||
: 'Deployment has failed'
|
||||
);
|
||||
return yield {
|
||||
type: 'error',
|
||||
payload: deploymentUpdate.error || deploymentUpdate,
|
||||
payload: aliasError
|
||||
? deploymentUpdate.aliasError
|
||||
: deploymentUpdate.error || deploymentUpdate,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,6 +54,8 @@ export interface Deployment {
|
||||
};
|
||||
target: string;
|
||||
alias: string[];
|
||||
aliasAssigned: boolean;
|
||||
aliasError: string | null;
|
||||
}
|
||||
|
||||
export interface DeploymentBuild {
|
||||
@@ -117,6 +119,7 @@ export interface DeploymentOptions {
|
||||
sessionAffinity?: 'ip' | 'random';
|
||||
config?: { [key: string]: any };
|
||||
debug?: boolean;
|
||||
apiUrl?: string;
|
||||
}
|
||||
|
||||
export interface NowJsonOptions {
|
||||
|
||||
@@ -26,9 +26,9 @@ const isClientNetworkError = (err: Error | DeploymentError) => {
|
||||
|
||||
export default async function* upload(
|
||||
files: Map<string, DeploymentFile>,
|
||||
options: Options,
|
||||
options: Options
|
||||
): AsyncIterableIterator<any> {
|
||||
const { token, teamId, debug: isDebug } = options;
|
||||
const { token, teamId, debug: isDebug, apiUrl } = options;
|
||||
const debug = createDebug(isDebug);
|
||||
|
||||
if (!files && !token && !teamId) {
|
||||
@@ -51,7 +51,7 @@ export default async function* upload(
|
||||
}
|
||||
} else {
|
||||
// If the deployment has succeeded here, don't continue
|
||||
if (event.type === 'ready') {
|
||||
if (event.type === 'alias-assigned') {
|
||||
debug('Deployment succeeded on file check');
|
||||
|
||||
return yield event;
|
||||
@@ -103,6 +103,7 @@ export default async function* upload(
|
||||
},
|
||||
body: stream,
|
||||
teamId,
|
||||
apiUrl,
|
||||
},
|
||||
isDebug
|
||||
);
|
||||
@@ -184,7 +185,7 @@ export default async function* upload(
|
||||
try {
|
||||
debug('Starting deployment creation');
|
||||
for await (const event of deploy(files, options)) {
|
||||
if (event.type === 'ready') {
|
||||
if (event.type === 'alias-assigned') {
|
||||
debug('Deployment is ready');
|
||||
return yield event;
|
||||
}
|
||||
|
||||
@@ -11,11 +11,10 @@ import { Sema } from 'async-sema';
|
||||
import { readFile } from 'fs-extra';
|
||||
const semaphore = new Sema(10);
|
||||
|
||||
export const API_FILES = 'https://api.zeit.co/v2/now/files';
|
||||
export const API_DEPLOYMENTS = 'https://api.zeit.co/v9/now/deployments';
|
||||
export const API_DEPLOYMENTS_LEGACY = 'https://api.zeit.co/v3/now/deployments';
|
||||
export const API_DELETE_DEPLOYMENTS_LEGACY =
|
||||
'https://api.zeit.co/v2/now/deployments';
|
||||
export const API_FILES = '/v2/now/files';
|
||||
export const API_DEPLOYMENTS = '/v10/now/deployments';
|
||||
export const API_DEPLOYMENTS_LEGACY = '/v3/now/deployments';
|
||||
export const API_DELETE_DEPLOYMENTS_LEGACY = '/v2/now/deployments';
|
||||
|
||||
export const EVENTS = new Set([
|
||||
// File events
|
||||
@@ -26,6 +25,7 @@ export const EVENTS = new Set([
|
||||
// Deployment events
|
||||
'created',
|
||||
'ready',
|
||||
'alias-assigned',
|
||||
'warning',
|
||||
'error',
|
||||
// Build events
|
||||
@@ -109,6 +109,9 @@ export const fetch = async (
|
||||
const debug = createDebug(debugEnabled);
|
||||
let time: number;
|
||||
|
||||
url = `${opts.apiUrl || 'https://api.zeit.co'}${url}`;
|
||||
delete opts.apiUrl;
|
||||
|
||||
if (opts.teamId) {
|
||||
const parsedUrl = parseUrl(url, true);
|
||||
const query = parsedUrl.query;
|
||||
|
||||
@@ -14,3 +14,7 @@ export const isFailed = ({
|
||||
export const isDone = (
|
||||
buildOrDeployment: Deployment | DeploymentBuild
|
||||
): boolean => isReady(buildOrDeployment) || isFailed(buildOrDeployment);
|
||||
export const isAliasAssigned = (deployment: Deployment): boolean =>
|
||||
Boolean(deployment.aliasAssigned);
|
||||
export const isAliasError = (deployment: Deployment): boolean =>
|
||||
Boolean(deployment.aliasError);
|
||||
|
||||
30
packages/now-client/tests/common.ts
Normal file
30
packages/now-client/tests/common.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
import fetch from 'node-fetch';
|
||||
const str = 'aHR0cHM6Ly9hcGktdG9rZW4tZmFjdG9yeS56ZWl0LnNo';
|
||||
|
||||
async function fetchTokenWithRetry(url: string, retries = 3): Promise<string> {
|
||||
try {
|
||||
const res = await fetch(url);
|
||||
const data = await res.json();
|
||||
return data.token;
|
||||
} catch (error) {
|
||||
console.log(`Failed to fetch token. Retries remaining: ${retries}`);
|
||||
if (retries === 0) {
|
||||
throw error;
|
||||
}
|
||||
await sleep(500);
|
||||
return fetchTokenWithRetry(url, retries - 1);
|
||||
}
|
||||
}
|
||||
|
||||
export async function generateNewToken(): Promise<string> {
|
||||
const token = await fetchTokenWithRetry(
|
||||
Buffer.from(str, 'base64').toString()
|
||||
);
|
||||
return token;
|
||||
}
|
||||
|
||||
export function sleep(ms: number) {
|
||||
return new Promise(resolve => {
|
||||
setTimeout(resolve, ms);
|
||||
});
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
// zeit-support user
|
||||
export const TOKEN = 'HRp5EAN0TZBnSUBIleD3ZrMW'
|
||||
@@ -1,19 +1,24 @@
|
||||
import path from 'path';
|
||||
import { TOKEN } from './constants';
|
||||
import { generateNewToken } from './common';
|
||||
import { fetch, API_DEPLOYMENTS } from '../src/utils';
|
||||
import { Deployment } from './types';
|
||||
import { createDeployment } from '../src/index';
|
||||
|
||||
describe('create v2 deployment', () => {
|
||||
let deployment: Deployment;
|
||||
let token = '';
|
||||
|
||||
beforeEach(async () => {
|
||||
token = await generateNewToken();
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
if (deployment) {
|
||||
const response = await fetch(
|
||||
`${API_DEPLOYMENTS}/${deployment.id}`,
|
||||
TOKEN,
|
||||
token,
|
||||
{
|
||||
method: 'DELETE'
|
||||
method: 'DELETE',
|
||||
}
|
||||
);
|
||||
expect(response.status).toEqual(200);
|
||||
@@ -24,8 +29,8 @@ describe('create v2 deployment', () => {
|
||||
for await (const event of createDeployment(
|
||||
path.resolve(__dirname, 'fixtures', 'v2'),
|
||||
{
|
||||
token: TOKEN,
|
||||
name: 'now-client-tests-v2'
|
||||
token,
|
||||
name: 'now-client-tests-v2',
|
||||
}
|
||||
)) {
|
||||
if (event.type === 'warning') {
|
||||
@@ -43,8 +48,8 @@ describe('create v2 deployment', () => {
|
||||
for await (const event of createDeployment(
|
||||
path.resolve(__dirname, 'fixtures', 'v2'),
|
||||
{
|
||||
token: TOKEN,
|
||||
name: 'now-client-tests-v2'
|
||||
token,
|
||||
name: 'now-client-tests-v2',
|
||||
}
|
||||
)) {
|
||||
if (event.type === 'file_count') {
|
||||
@@ -62,8 +67,8 @@ describe('create v2 deployment', () => {
|
||||
for await (const event of createDeployment(
|
||||
path.resolve(__dirname, 'fixtures', 'v2'),
|
||||
{
|
||||
token: TOKEN,
|
||||
name: 'now-client-tests-v2'
|
||||
token,
|
||||
name: 'now-client-tests-v2',
|
||||
}
|
||||
)) {
|
||||
if (event.type === 'ready') {
|
||||
|
||||
@@ -1,77 +1,83 @@
|
||||
import path from 'path'
|
||||
import { TOKEN } from './constants'
|
||||
import { fetch, API_DELETE_DEPLOYMENTS_LEGACY } from '../src/utils'
|
||||
import { Deployment } from './types'
|
||||
import { createLegacyDeployment } from '../src/index'
|
||||
import path from 'path';
|
||||
import { generateNewToken } from './common';
|
||||
import { fetch, API_DELETE_DEPLOYMENTS_LEGACY } from '../src/utils';
|
||||
import { Deployment } from './types';
|
||||
import { createLegacyDeployment } from '../src/index';
|
||||
|
||||
describe('create v1 deployment', () => {
|
||||
let deployment: Deployment | undefined
|
||||
let deployment: Deployment | undefined;
|
||||
let token = '';
|
||||
|
||||
beforeEach(async () => {
|
||||
token = await generateNewToken();
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
if (deployment) {
|
||||
const response = await fetch(
|
||||
`${API_DELETE_DEPLOYMENTS_LEGACY}/${deployment.deploymentId || deployment.uid}`,
|
||||
TOKEN,
|
||||
`${API_DELETE_DEPLOYMENTS_LEGACY}/${deployment.deploymentId ||
|
||||
deployment.uid}`,
|
||||
token,
|
||||
{
|
||||
method: 'DELETE'
|
||||
method: 'DELETE',
|
||||
}
|
||||
)
|
||||
expect(response.status).toEqual(200)
|
||||
deployment = undefined
|
||||
);
|
||||
expect(response.status).toEqual(200);
|
||||
deployment = undefined;
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
it('will create a v1 static deployment', async () => {
|
||||
for await (const event of createLegacyDeployment(
|
||||
path.resolve(__dirname, 'fixtures', 'v1', 'static'),
|
||||
{
|
||||
token: TOKEN,
|
||||
name: 'now-client-tests-v1-static'
|
||||
token,
|
||||
name: 'now-client-tests-v1-static',
|
||||
}
|
||||
)) {
|
||||
if (event.type === 'ready') {
|
||||
deployment = event.payload
|
||||
deployment = event.payload;
|
||||
if (deployment) {
|
||||
expect(deployment.readyState || deployment.state).toEqual('READY')
|
||||
break
|
||||
expect(deployment.readyState || deployment.state).toEqual('READY');
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
it('will create a v1 npm deployment', async () => {
|
||||
for await (const event of createLegacyDeployment(
|
||||
path.resolve(__dirname, 'fixtures', 'v1', 'npm'),
|
||||
{
|
||||
token: TOKEN,
|
||||
name: 'now-client-tests-v1-npm'
|
||||
token,
|
||||
name: 'now-client-tests-v1-npm',
|
||||
}
|
||||
)) {
|
||||
if (event.type === 'ready') {
|
||||
deployment = event.payload
|
||||
deployment = event.payload;
|
||||
if (deployment) {
|
||||
expect(deployment.readyState || deployment.state).toEqual('READY')
|
||||
break
|
||||
expect(deployment.readyState || deployment.state).toEqual('READY');
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
it('will create a v1 Docker deployment', async () => {
|
||||
for await (const event of createLegacyDeployment(
|
||||
path.resolve(__dirname, 'fixtures', 'v1', 'docker'),
|
||||
{
|
||||
token: TOKEN,
|
||||
name: 'now-client-tests-v1-docker'
|
||||
token,
|
||||
name: 'now-client-tests-v1-docker',
|
||||
}
|
||||
)) {
|
||||
if (event.type === 'ready') {
|
||||
deployment = event.payload
|
||||
deployment = event.payload;
|
||||
if (deployment) {
|
||||
expect(deployment.readyState || deployment.state).toEqual('READY')
|
||||
break
|
||||
expect(deployment.readyState || deployment.state).toEqual('READY');
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
});
|
||||
});
|
||||
|
||||
32
packages/now-client/tests/paths.test.ts
Normal file
32
packages/now-client/tests/paths.test.ts
Normal file
@@ -0,0 +1,32 @@
|
||||
import { generateNewToken } from './common';
|
||||
import { createDeployment } from '../src/index';
|
||||
|
||||
describe('path handling', () => {
|
||||
let token = '';
|
||||
|
||||
beforeEach(async () => {
|
||||
token = await generateNewToken();
|
||||
});
|
||||
|
||||
it('will fali with a relative path', async () => {
|
||||
try {
|
||||
await createDeployment('./fixtures/v2/now.json', {
|
||||
token,
|
||||
name: 'now-client-tests-v2',
|
||||
});
|
||||
} catch (e) {
|
||||
expect(e.code).toEqual('invalid_path');
|
||||
}
|
||||
});
|
||||
|
||||
it('will fali with an array of relative paths', async () => {
|
||||
try {
|
||||
await createDeployment(['./fixtures/v2/now.json'], {
|
||||
token,
|
||||
name: 'now-client-tests-v2',
|
||||
});
|
||||
} catch (e) {
|
||||
expect(e.code).toEqual('invalid_path');
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -1 +1 @@
|
||||
jest.setTimeout(120000)
|
||||
jest.setTimeout(120000);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@now/next",
|
||||
"version": "1.0.4",
|
||||
"version": "1.0.5",
|
||||
"license": "MIT",
|
||||
"main": "./dist/index",
|
||||
"homepage": "https://zeit.co/docs/v2/deployments/official-builders/next-js-now-next",
|
||||
|
||||
@@ -715,7 +715,7 @@ export const build = async ({
|
||||
{
|
||||
// This ensures we only match known emitted-by-Next.js files and not
|
||||
// user-emitted files which may be missing a hash in their filename.
|
||||
src: '/_next/static/(?:[^/]+/pages|chunks|runtime)/.+',
|
||||
src: '/_next/static/(?:[^/]+/pages|chunks|runtime|css|media)/.+',
|
||||
// Next.js assets contain a hash or entropy in their filenames, so they
|
||||
// are guaranteed to be unique and cacheable indefinitely.
|
||||
headers: { 'cache-control': 'public,max-age=31536000,immutable' },
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@now/python",
|
||||
"version": "0.3.2",
|
||||
"version": "0.3.3",
|
||||
"main": "./dist/index.js",
|
||||
"license": "MIT",
|
||||
"homepage": "https://zeit.co/docs/v2/deployments/official-builders/python-now-python",
|
||||
|
||||
@@ -16,6 +16,14 @@ import {
|
||||
|
||||
async function pipInstall(pipPath: string, workDir: string, ...args: string[]) {
|
||||
const target = '.';
|
||||
// See: https://github.com/pypa/pip/issues/4222#issuecomment-417646535
|
||||
//
|
||||
// Disable installing to the Python user install directory, which is
|
||||
// the default behavior on Debian systems and causes error:
|
||||
//
|
||||
// distutils.errors.DistutilsOptionError: can't combine user with
|
||||
// prefix, exec_prefix/home, or install_(plat)base
|
||||
process.env.PIP_USER = '0';
|
||||
debug(
|
||||
`Running "pip install --disable-pip-version-check --target ${target} --upgrade ${args.join(
|
||||
' '
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@now/routing-utils",
|
||||
"version": "1.3.0",
|
||||
"version": "1.3.1",
|
||||
"description": "ZEIT Now routing utilities",
|
||||
"main": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
|
||||
@@ -135,11 +135,9 @@ export function getTransformedRoutes({
|
||||
}
|
||||
} else {
|
||||
routes = [];
|
||||
let cleanUrlsRewrites: Route[] | undefined;
|
||||
if (typeof cleanUrls !== 'undefined') {
|
||||
const cleanUrls = convertCleanUrls(filePaths);
|
||||
cleanUrlsRewrites = cleanUrls.rewrites;
|
||||
routes.push(...cleanUrls.redirects);
|
||||
if (cleanUrls) {
|
||||
const clean = convertCleanUrls(filePaths);
|
||||
routes.push(...clean.redirects);
|
||||
}
|
||||
if (typeof trailingSlash !== 'undefined') {
|
||||
routes.push(...convertTrailingSlash(trailingSlash));
|
||||
@@ -150,16 +148,8 @@ export function getTransformedRoutes({
|
||||
if (typeof headers !== 'undefined') {
|
||||
routes.push(...convertHeaders(headers));
|
||||
}
|
||||
if (typeof cleanUrlsRewrites !== 'undefined') {
|
||||
routes.push(...cleanUrlsRewrites);
|
||||
}
|
||||
if (
|
||||
typeof cleanUrlsRewrites !== 'undefined' ||
|
||||
typeof rewrites !== 'undefined'
|
||||
) {
|
||||
routes.push({ handle: 'filesystem' });
|
||||
}
|
||||
if (typeof rewrites !== 'undefined') {
|
||||
routes.push({ handle: 'filesystem' });
|
||||
routes.push(...convertRewrites(rewrites));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -451,8 +451,6 @@ describe('getTransformedRoutes', () => {
|
||||
headers: { Location: '/support' },
|
||||
status: 302,
|
||||
},
|
||||
{ src: '^/index$', dest: '/index.html', continue: true },
|
||||
{ src: '^/support$', dest: '/support.html', continue: true },
|
||||
{ handle: 'filesystem' },
|
||||
{ src: '^/v1$', dest: '/v2/api.py', continue: true },
|
||||
];
|
||||
|
||||
Reference in New Issue
Block a user