mirror of
https://github.com/LukeHagar/vercel.git
synced 2025-12-09 21:07:46 +00:00
https://vercel.com/blog/zeit-is-now-vercel * Updates all org packages from `@now` to `@vercel` * Updates Now CLI package name from `now` to `vercel` * Packages contains `"bin"` entries for _both_ `vercel` and `now` in the package.json * Updates `now-client` package name to `@vercel/client` (org scoped, for authenticity) There is also a new `publish-legacy.sh` script which ensures that all the legacy package names (i.e. `now`, `now-client`, `@now/node`, etc.) will still be published as well. We will remove this legacy publishing logic on Jan 1, 2021.
1227 lines
28 KiB
TypeScript
1227 lines
28 KiB
TypeScript
import bytes from 'bytes';
|
|
import { Response } from 'node-fetch';
|
|
import { NowError } from './now-error';
|
|
import param from './output/param';
|
|
import cmd from './output/cmd';
|
|
import code from './output/code';
|
|
import { getPkgName } from './pkg-name';
|
|
|
|
/**
|
|
* This error is thrown when there is an API error with a payload. The error
|
|
* body includes the data that came in the payload plus status and a server
|
|
* message. When it's a rate limit error in includes `retryAfter`
|
|
*/
|
|
export class APIError extends Error {
|
|
status: number;
|
|
serverMessage: string;
|
|
link?: string;
|
|
retryAfter: number | null | 'never';
|
|
[key: string]: any;
|
|
|
|
constructor(message: string, response: Response, body?: object) {
|
|
super();
|
|
this.message = `${message} (${response.status})`;
|
|
this.status = response.status;
|
|
this.serverMessage = message;
|
|
this.retryAfter = null;
|
|
|
|
if (body) {
|
|
for (const field of Object.keys(body)) {
|
|
if (field !== 'message') {
|
|
// @ts-ignore
|
|
this[field] = body[field];
|
|
}
|
|
}
|
|
}
|
|
|
|
if (response.status === 429) {
|
|
const retryAfter = response.headers.get('Retry-After');
|
|
if (retryAfter) {
|
|
this.retryAfter = parseInt(retryAfter, 10);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* When you're fetching information for the current team but the client can't
|
|
* retrieve information. This means that the team was probably deleted or the
|
|
* member removed.
|
|
*/
|
|
export class TeamDeleted extends NowError<'TEAM_DELETED', {}> {
|
|
constructor() {
|
|
super({
|
|
code: 'TEAM_DELETED',
|
|
message: `Your team was deleted. You can switch to a different one using ${param(
|
|
`${getPkgName()} switch`
|
|
)}.`,
|
|
meta: {},
|
|
});
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Thrown when a user is requested to the backend but we get unauthorized
|
|
* because the token is not valid anymore.
|
|
*/
|
|
export class InvalidToken extends NowError<'NOT_AUTHORIZED', {}> {
|
|
constructor() {
|
|
super({
|
|
code: `NOT_AUTHORIZED`,
|
|
message: `The specified token is not valid`,
|
|
meta: {},
|
|
});
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Thrown when we request a user using a token but the user no longer exists,
|
|
* usually because it was deleted at some point.
|
|
*/
|
|
export class MissingUser extends NowError<'MISSING_USER', {}> {
|
|
constructor() {
|
|
super({
|
|
code: 'MISSING_USER',
|
|
message: `Not able to load user, missing from response`,
|
|
meta: {},
|
|
});
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Thrown when a user tries to add a domain that exists already for a different
|
|
* user under a different context.
|
|
*/
|
|
export class DomainAlreadyExists extends NowError<
|
|
'DOMAIN_ALREADY_EXISTS',
|
|
{ domain: string }
|
|
> {
|
|
constructor(domain: string) {
|
|
super({
|
|
code: 'DOMAIN_ALREADY_EXISTS',
|
|
meta: { domain },
|
|
message: `The domain ${domain} already exists under a different context.`,
|
|
});
|
|
}
|
|
}
|
|
|
|
/**
|
|
* When information about a domain is requested but the current user / team has no
|
|
* permissions to get that information.
|
|
*/
|
|
export class DomainPermissionDenied extends NowError<
|
|
'DOMAIN_PERMISSION_DENIED',
|
|
{ domain: string; context: string }
|
|
> {
|
|
constructor(domain: string, context: string) {
|
|
super({
|
|
code: 'DOMAIN_PERMISSION_DENIED',
|
|
meta: { domain, context },
|
|
message: `You don't have access to the domain ${domain} under ${context}.`,
|
|
});
|
|
}
|
|
}
|
|
|
|
export class DomainExternal extends NowError<
|
|
'DOMAIN_EXTERNAL',
|
|
{ domain: string }
|
|
> {
|
|
constructor(domain: string) {
|
|
super({
|
|
code: 'DOMAIN_EXTERNAL',
|
|
meta: { domain },
|
|
message: `The domain ${domain} must point to zeit.world.`,
|
|
});
|
|
}
|
|
}
|
|
|
|
/**
|
|
* When information about a domain is requested but the domain doesn't exist
|
|
*/
|
|
export class SourceNotFound extends NowError<'SOURCE_NOT_FOUND', {}> {
|
|
constructor() {
|
|
super({
|
|
code: 'SOURCE_NOT_FOUND',
|
|
meta: {},
|
|
message: `Not able to purchase. Please add a payment method using ${cmd(
|
|
`${getPkgName()} billing add`
|
|
)}.`,
|
|
});
|
|
}
|
|
}
|
|
|
|
export class InvalidTransferAuthCode extends NowError<
|
|
'INVALID_TRANSFER_AUTH_CODE',
|
|
{ domain: string; authCode: string }
|
|
> {
|
|
constructor(domain: string, authCode: string) {
|
|
super({
|
|
code: 'INVALID_TRANSFER_AUTH_CODE',
|
|
meta: { domain, authCode },
|
|
message: `The provided auth code does not match with the one expected by the current registar`,
|
|
});
|
|
}
|
|
}
|
|
|
|
export class DomainRegistrationFailed extends NowError<
|
|
'DOMAIN_REGISTRATION_FAILED',
|
|
{ domain: string }
|
|
> {
|
|
constructor(domain: string, message: string) {
|
|
super({
|
|
code: 'DOMAIN_REGISTRATION_FAILED',
|
|
meta: { domain },
|
|
message,
|
|
});
|
|
}
|
|
}
|
|
|
|
/**
|
|
* When information about a domain is requested but the domain doesn't exist
|
|
*/
|
|
export class DomainNotFound extends NowError<
|
|
'DOMAIN_NOT_FOUND',
|
|
{ domain: string }
|
|
> {
|
|
constructor(domain: string) {
|
|
super({
|
|
code: 'DOMAIN_NOT_FOUND',
|
|
meta: { domain },
|
|
message: `The domain ${domain} can't be found.`,
|
|
});
|
|
}
|
|
}
|
|
|
|
export class DomainNotVerified extends NowError<
|
|
'DOMAIN_NOT_VERIFIED',
|
|
{ domain: string }
|
|
> {
|
|
constructor(domain: string) {
|
|
super({
|
|
code: 'DOMAIN_NOT_VERIFIED',
|
|
meta: { domain },
|
|
message: `The domain ${domain} is not verified.`,
|
|
});
|
|
}
|
|
}
|
|
|
|
/**
|
|
* This error is returned when we perform a verification against the server and it
|
|
* fails for both methods. It includes in the payload the domain name and metadata
|
|
* to tell the reason why the verification failed
|
|
*/
|
|
export class DomainVerificationFailed extends NowError<
|
|
'DOMAIN_VERIFICATION_FAILED',
|
|
{
|
|
domain: string;
|
|
purchased: boolean;
|
|
txtVerification: TXTVerificationError;
|
|
nsVerification: NSVerificationError;
|
|
}
|
|
> {
|
|
constructor({
|
|
domain,
|
|
nsVerification,
|
|
txtVerification,
|
|
purchased = false,
|
|
}: {
|
|
domain: string;
|
|
nsVerification: NSVerificationError;
|
|
txtVerification: TXTVerificationError;
|
|
purchased: boolean;
|
|
}) {
|
|
super({
|
|
code: 'DOMAIN_VERIFICATION_FAILED',
|
|
meta: { domain, nsVerification, txtVerification, purchased },
|
|
message: `We can't verify the domain ${domain}. Both Name Servers and DNS TXT verifications failed.`,
|
|
});
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Helper type for DomainVerificationFailed
|
|
*/
|
|
export type NSVerificationError = {
|
|
intendedNameservers: string[];
|
|
nameservers: string[];
|
|
};
|
|
|
|
/**
|
|
* Helper type for DomainVerificationFailed
|
|
*/
|
|
export type TXTVerificationError = {
|
|
verificationRecord: string;
|
|
values: string[];
|
|
};
|
|
|
|
/**
|
|
* This error is returned when the domain is not verified by nameservers for wildcard alias.
|
|
*/
|
|
export class DomainNsNotVerifiedForWildcard extends NowError<
|
|
'DOMAIN_NS_NOT_VERIFIED_FOR_WILDCARD',
|
|
{
|
|
domain: string;
|
|
nsVerification: NSVerificationError;
|
|
}
|
|
> {
|
|
constructor({
|
|
domain,
|
|
nsVerification,
|
|
}: {
|
|
domain: string;
|
|
nsVerification: NSVerificationError;
|
|
}) {
|
|
super({
|
|
code: 'DOMAIN_NS_NOT_VERIFIED_FOR_WILDCARD',
|
|
meta: { domain, nsVerification },
|
|
message: `The domain ${domain} is not verified by nameservers for wildcard alias.`,
|
|
});
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Used when a domain is validated because we tried to add it to an account
|
|
* via API or for any other reason.
|
|
*/
|
|
export class InvalidDomain extends NowError<
|
|
'INVALID_DOMAIN',
|
|
{ domain: string }
|
|
> {
|
|
constructor(domain: string, message?: string | null) {
|
|
super({
|
|
code: 'INVALID_DOMAIN',
|
|
meta: { domain },
|
|
message: message || `The domain ${domain} is not valid.`,
|
|
});
|
|
}
|
|
}
|
|
|
|
export class NotDomainOwner extends NowError<'NOT_DOMAIN_OWNER', {}> {
|
|
constructor(message: string) {
|
|
super({
|
|
code: 'NOT_DOMAIN_OWNER',
|
|
meta: {},
|
|
message,
|
|
});
|
|
}
|
|
}
|
|
|
|
export class InvalidDeploymentId extends NowError<
|
|
'INVALID_DEPLOYMENT_ID',
|
|
{ id: string }
|
|
> {
|
|
constructor(id: string) {
|
|
super({
|
|
code: 'INVALID_DEPLOYMENT_ID',
|
|
meta: { id },
|
|
message: `The deployment id "${id}" is not valid.`,
|
|
});
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returned when the user checks the price of a domain but the TLD
|
|
* of the given name is not supported.
|
|
*/
|
|
export class UnsupportedTLD extends NowError<
|
|
'UNSUPPORTED_TLD',
|
|
{ domain: string }
|
|
> {
|
|
constructor(domain: string) {
|
|
super({
|
|
code: 'UNSUPPORTED_TLD',
|
|
meta: { domain },
|
|
message: `The TLD for domain name ${domain} is not supported.`,
|
|
});
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returned when the user tries to purchase a domain but the API returns
|
|
* an error telling that it is not available.
|
|
*/
|
|
export class DomainNotAvailable extends NowError<
|
|
'DOMAIN_NOT_AVAILABLE',
|
|
{ domain: string }
|
|
> {
|
|
constructor(domain: string) {
|
|
super({
|
|
code: 'DOMAIN_NOT_AVAILABLE',
|
|
meta: { domain },
|
|
message: `The domain ${domain} is not available to be purchased.`,
|
|
});
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returned when the domain purchase service is not available for reasons
|
|
* that are out of our control.
|
|
*/
|
|
export class DomainServiceNotAvailable extends NowError<
|
|
'DOMAIN_SERVICE_NOT_AVAILABLE',
|
|
{ domain: string }
|
|
> {
|
|
constructor(domain: string) {
|
|
super({
|
|
code: 'DOMAIN_SERVICE_NOT_AVAILABLE',
|
|
meta: { domain },
|
|
message: `The domain purchase is unavailable, try again later.`,
|
|
});
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returned when the user tries to purchase a domain but the API returns
|
|
* an error telling that it is not available.
|
|
*/
|
|
export class DomainNotTransferable extends NowError<
|
|
'DOMAIN_NOT_TRANSFERABLE',
|
|
{ domain: string }
|
|
> {
|
|
constructor(domain: string) {
|
|
super({
|
|
code: 'DOMAIN_NOT_TRANSFERABLE',
|
|
meta: { domain },
|
|
message: `The domain ${domain} is not available to be transferred.`,
|
|
});
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returned when there is an expected error during the domain purchase.
|
|
*/
|
|
export class UnexpectedDomainPurchaseError extends NowError<
|
|
'UNEXPECTED_DOMAIN_PURCHASE_ERROR',
|
|
{ domain: string }
|
|
> {
|
|
constructor(domain: string) {
|
|
super({
|
|
code: 'UNEXPECTED_DOMAIN_PURCHASE_ERROR',
|
|
meta: { domain },
|
|
message: `An unexpected error happened while purchasing.`,
|
|
});
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returned when there is an expected error charging the card.
|
|
*/
|
|
export class DomainPaymentError extends NowError<'DOMAIN_PAYMENT_ERROR', {}> {
|
|
constructor() {
|
|
super({
|
|
code: 'DOMAIN_PAYMENT_ERROR',
|
|
meta: {},
|
|
message: `Your card was declined.`,
|
|
});
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returned during purchase in alias when the domain was purchased but the
|
|
* order is pending so the alias can't be completed yet
|
|
*/
|
|
export class DomainPurchasePending extends NowError<
|
|
'DOMAIN_PURCHASE_PENDING',
|
|
{ domain: string }
|
|
> {
|
|
constructor(domain: string) {
|
|
super({
|
|
code: 'DOMAIN_PURCHASE_PENDING',
|
|
meta: { domain },
|
|
message: `The domain purchase for ${domain} is pending.`,
|
|
});
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returned any time we prompt the user to make sure an action should be performed
|
|
* and the user decides not to continue with the operation
|
|
*/
|
|
export class UserAborted extends NowError<'USER_ABORTED', {}> {
|
|
constructor() {
|
|
super({
|
|
code: 'USER_ABORTED',
|
|
meta: {},
|
|
message: `The user aborted the operation.`,
|
|
});
|
|
}
|
|
}
|
|
|
|
export class CertNotFound extends NowError<'CERT_NOT_FOUND', { id: string }> {
|
|
constructor(id: string) {
|
|
super({
|
|
code: 'CERT_NOT_FOUND',
|
|
meta: { id },
|
|
message: `The cert ${id} can't be found.`,
|
|
});
|
|
}
|
|
}
|
|
|
|
export class CertsPermissionDenied extends NowError<
|
|
'CERTS_PERMISSION_DENIED',
|
|
{ domain: string }
|
|
> {
|
|
constructor(context: string, domain: string) {
|
|
super({
|
|
code: 'CERTS_PERMISSION_DENIED',
|
|
meta: { domain },
|
|
message: `You don't have access to ${domain}'s certs under ${context}.`,
|
|
});
|
|
}
|
|
}
|
|
|
|
export class CertOrderNotFound extends NowError<
|
|
'CERT_ORDER_NOT_FOUND',
|
|
{ cns: string[] }
|
|
> {
|
|
constructor(cns: string[]) {
|
|
super({
|
|
code: 'CERT_ORDER_NOT_FOUND',
|
|
meta: { cns },
|
|
message: `No cert order could be found for cns ${cns.join(' ,')}`,
|
|
});
|
|
}
|
|
}
|
|
|
|
/**
|
|
* This error is returned when consuming an API that got rate limited because too
|
|
* many requests where performed already. It gives a retryAfter parameter with the
|
|
* time the user needs to wait.
|
|
*/
|
|
export class TooManyRequests extends NowError<
|
|
'TOO_MANY_REQUESTS',
|
|
{ api: string; retryAfter: number }
|
|
> {
|
|
constructor(api: string, retryAfter: number) {
|
|
super({
|
|
code: 'TOO_MANY_REQUESTS',
|
|
meta: { api, retryAfter },
|
|
message: `Rate limited. Too many requests to the same endpoint.`,
|
|
});
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Generic cert error that utilizes the API's response message
|
|
* for more information
|
|
*/
|
|
type CertErrorCode =
|
|
| 'bad_domains'
|
|
| 'challenge_still_pending'
|
|
| 'common_name_domain_name_mismatch'
|
|
| 'conflicting_caa_record'
|
|
| 'domain_not_verified'
|
|
| 'invalid_cn'
|
|
| 'invalid_domain'
|
|
| 'rate_limited'
|
|
| 'should_share_root_domain'
|
|
| 'unauthorized_request_error'
|
|
| 'unsupported_challenge_priority'
|
|
| 'wildcard_not_allowed'
|
|
| 'validation_running'
|
|
| 'dns_error'
|
|
| 'challenge_error'
|
|
| 'txt_record_not_found';
|
|
export class CertError extends NowError<
|
|
'CERT_ERROR',
|
|
{ cns: string[]; code: CertErrorCode; helpUrl?: string }
|
|
> {
|
|
constructor({
|
|
cns,
|
|
code,
|
|
message,
|
|
helpUrl,
|
|
}: {
|
|
cns: string[];
|
|
code: CertErrorCode;
|
|
message: string;
|
|
helpUrl?: string;
|
|
}) {
|
|
super({
|
|
code: `CERT_ERROR`,
|
|
meta: { cns, code, helpUrl },
|
|
message,
|
|
});
|
|
}
|
|
}
|
|
|
|
export class CertConfigurationError extends NowError<
|
|
'CERT_CONFIGURATION_ERROR',
|
|
{
|
|
cns: string[];
|
|
type: 'http-01' | 'dns-01';
|
|
external: boolean | null;
|
|
helpUrl?: string;
|
|
}
|
|
> {
|
|
constructor({
|
|
cns,
|
|
message,
|
|
external,
|
|
type,
|
|
helpUrl,
|
|
}: {
|
|
cns: string[];
|
|
message: string;
|
|
external: boolean | null;
|
|
type: 'http-01' | 'dns-01';
|
|
helpUrl?: string;
|
|
}) {
|
|
super({
|
|
code: `CERT_CONFIGURATION_ERROR`,
|
|
meta: { cns, helpUrl, external, type },
|
|
message,
|
|
});
|
|
}
|
|
}
|
|
|
|
/**
|
|
* This error is returned whenever an API call tries to fetch a deployment but
|
|
* the deployment doesn't exist.
|
|
*/
|
|
export class DeploymentNotFound extends NowError<
|
|
'DEPLOYMENT_NOT_FOUND',
|
|
{ id: string; context: string }
|
|
> {
|
|
constructor({ context, id = '' }: { context: string; id: string }) {
|
|
super({
|
|
code: 'DEPLOYMENT_NOT_FOUND',
|
|
meta: { id, context },
|
|
message: `Can't find the deployment ${id} under the context ${context}`,
|
|
});
|
|
}
|
|
}
|
|
|
|
/**
|
|
* This error is returned when trying to create an alias and
|
|
* the deployment isn't ready yet.
|
|
*/
|
|
export class DeploymentNotReady extends NowError<
|
|
'DEPLOYMENT_NOT_READY',
|
|
{ url: string }
|
|
> {
|
|
constructor({ url = '' }: { url: string }) {
|
|
super({
|
|
code: 'DEPLOYMENT_NOT_READY',
|
|
meta: { url },
|
|
message: `The deployment https://${url} is not ready.`,
|
|
});
|
|
}
|
|
}
|
|
|
|
export class DeploymentFailedAliasImpossible extends NowError<
|
|
'DEPLOYMENT_FAILED_ALIAS_IMPOSSIBLE',
|
|
{}
|
|
> {
|
|
constructor() {
|
|
super({
|
|
code: 'DEPLOYMENT_FAILED_ALIAS_IMPOSSIBLE',
|
|
meta: {},
|
|
message: `The deployment build has failed and cannot be aliased`,
|
|
});
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returned when the user tries to fetch explicitly a deployment but she
|
|
* has no permissions under the given context.
|
|
*/
|
|
export class DeploymentPermissionDenied extends NowError<
|
|
'DEPLOYMENT_PERMISSION_DENIED',
|
|
{ id: string; context: string }
|
|
> {
|
|
constructor(id: string, context: string) {
|
|
super({
|
|
code: 'DEPLOYMENT_PERMISSION_DENIED',
|
|
meta: { id, context },
|
|
message: `You don't have access to the deployment ${id} under ${context}.`,
|
|
});
|
|
}
|
|
}
|
|
|
|
export class DeploymentTypeUnsupported extends NowError<
|
|
'DEPLOYMENT_TYPE_UNSUPPORTED',
|
|
{}
|
|
> {
|
|
constructor() {
|
|
super({
|
|
code: 'DEPLOYMENT_TYPE_UNSUPPORTED',
|
|
meta: {},
|
|
message: `This region only accepts Serverless Docker Deployments`,
|
|
});
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returned when we try to create an alias but the API returns an error telling
|
|
* that the given alias is not valid.
|
|
*/
|
|
export class InvalidAlias extends NowError<'INVALID_ALIAS', { alias: string }> {
|
|
constructor(alias: string) {
|
|
super({
|
|
code: 'INVALID_ALIAS',
|
|
meta: { alias },
|
|
message: `The given alias ${alias} is not valid`,
|
|
});
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returned when we try to create an alias but the API failes with an error
|
|
* telling that the alias is already in use by somebody else.
|
|
*/
|
|
export class AliasInUse extends NowError<'ALIAS_IN_USE', { alias: string }> {
|
|
constructor(alias: string) {
|
|
super({
|
|
code: 'ALIAS_IN_USE',
|
|
meta: { alias },
|
|
message: `The alias is already in use`,
|
|
});
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returned when an action is performed against an API endpoint that requires
|
|
* a certificate for a domain but the domain is missing. An example would
|
|
* be alias.
|
|
*/
|
|
export class CertMissing extends NowError<'ALIAS_IN_USE', { domain: string }> {
|
|
constructor(domain: string) {
|
|
super({
|
|
code: 'ALIAS_IN_USE',
|
|
meta: { domain },
|
|
message: `The alias is already in use`,
|
|
});
|
|
}
|
|
}
|
|
|
|
export class ForbiddenScaleMinInstances extends NowError<
|
|
'FORBIDDEN_SCALE_MIN_INSTANCES',
|
|
{ url: string; max: number }
|
|
> {
|
|
constructor(url: string, max: number) {
|
|
super({
|
|
code: 'FORBIDDEN_SCALE_MIN_INSTANCES',
|
|
meta: { url, max },
|
|
message: `You can't scale to more than ${max} min instances with your current plan.`,
|
|
});
|
|
}
|
|
}
|
|
|
|
export class ForbiddenScaleMaxInstances extends NowError<
|
|
'FORBIDDEN_SCALE_MAX_INSTANCES',
|
|
{ url: string; max: number }
|
|
> {
|
|
constructor(url: string, max: number) {
|
|
super({
|
|
code: 'FORBIDDEN_SCALE_MAX_INSTANCES',
|
|
meta: { url, max },
|
|
message: `You can't scale to more than ${max} max instances with your current plan.`,
|
|
});
|
|
}
|
|
}
|
|
|
|
export class InvalidScaleMinMaxRelation extends NowError<
|
|
'INVALID_SCALE_MIN_MAX_RELATION',
|
|
{ url: string }
|
|
> {
|
|
constructor(url: string) {
|
|
super({
|
|
code: 'INVALID_SCALE_MIN_MAX_RELATION',
|
|
meta: { url },
|
|
message: `Min number of instances can't be higher than max.`,
|
|
});
|
|
}
|
|
}
|
|
|
|
export class NotSupportedMinScaleSlots extends NowError<
|
|
'NOT_SUPPORTED_MIN_SCALE_SLOTS',
|
|
{ url: string }
|
|
> {
|
|
constructor(url: string) {
|
|
super({
|
|
code: 'NOT_SUPPORTED_MIN_SCALE_SLOTS',
|
|
meta: { url },
|
|
message: `Cloud v2 does not yet support setting a non-zero min scale setting.`,
|
|
});
|
|
}
|
|
}
|
|
|
|
export class VerifyScaleTimeout extends NowError<
|
|
'VERIFY_SCALE_TIMEOUT',
|
|
{ timeout: number }
|
|
> {
|
|
constructor(timeout: number) {
|
|
super({
|
|
code: 'VERIFY_SCALE_TIMEOUT',
|
|
meta: { timeout },
|
|
message: `Instance verification timed out (${timeout}ms)`,
|
|
});
|
|
}
|
|
}
|
|
|
|
export class CantParseJSONFile extends NowError<
|
|
'CANT_PARSE_JSON_FILE',
|
|
{ file: string }
|
|
> {
|
|
constructor(file: string) {
|
|
super({
|
|
code: 'CANT_PARSE_JSON_FILE',
|
|
meta: { file },
|
|
message: `Can't parse json file`,
|
|
});
|
|
}
|
|
}
|
|
|
|
export class CantFindConfig extends NowError<
|
|
'CANT_FIND_CONFIG',
|
|
{ paths: string[] }
|
|
> {
|
|
constructor(paths: string[]) {
|
|
super({
|
|
code: 'CANT_FIND_CONFIG',
|
|
meta: { paths },
|
|
message: `Can't find a configuration file in the given locations.`,
|
|
});
|
|
}
|
|
}
|
|
|
|
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({
|
|
code: 'FILE_NOT_FOUND',
|
|
meta: { file },
|
|
message: `Can't find a file in provided location '${file}'.`,
|
|
});
|
|
}
|
|
}
|
|
|
|
export class RulesFileValidationError extends NowError<
|
|
'PATH_ALIAS_VALIDATION_ERROR',
|
|
{ location: string; message: string }
|
|
> {
|
|
constructor(location: string, message: string) {
|
|
super({
|
|
code: 'PATH_ALIAS_VALIDATION_ERROR',
|
|
meta: { location, message },
|
|
message: `The provided rules format in file for path alias are invalid`,
|
|
});
|
|
}
|
|
}
|
|
|
|
export class NoAliasInConfig extends NowError<'NO_ALIAS_IN_CONFIG', {}> {
|
|
constructor() {
|
|
super({
|
|
code: 'NO_ALIAS_IN_CONFIG',
|
|
meta: {},
|
|
message: `There is no alias set up in config file.`,
|
|
});
|
|
}
|
|
}
|
|
|
|
export class InvalidAliasInConfig extends NowError<
|
|
'INVALID_ALIAS_IN_CONFIG',
|
|
{ value: any }
|
|
> {
|
|
constructor(value: any) {
|
|
super({
|
|
code: 'INVALID_ALIAS_IN_CONFIG',
|
|
meta: { value },
|
|
message: `Invalid alias option in configuration.`,
|
|
});
|
|
}
|
|
}
|
|
|
|
export class RuleValidationFailed extends NowError<
|
|
'RULE_VALIDATION_FAILED',
|
|
{ message: string }
|
|
> {
|
|
constructor(message: string) {
|
|
super({
|
|
code: 'RULE_VALIDATION_FAILED',
|
|
meta: { message },
|
|
message: `The server validation for rules failed`,
|
|
});
|
|
}
|
|
}
|
|
|
|
export class InvalidMinForScale extends NowError<
|
|
'INVALID_MIN_FOR_SCALE',
|
|
{ value: string }
|
|
> {
|
|
constructor(value: string) {
|
|
super({
|
|
code: 'INVALID_MIN_FOR_SCALE',
|
|
meta: { value },
|
|
message: `Invalid <min> parameter "${value}". A number or "auto" were expected`,
|
|
});
|
|
}
|
|
}
|
|
|
|
export class InvalidArgsForMinMaxScale extends NowError<
|
|
'INVALID_ARGS_FOR_MIN_MAX_SCALE',
|
|
{ min: string }
|
|
> {
|
|
constructor(min: string) {
|
|
super({
|
|
code: 'INVALID_ARGS_FOR_MIN_MAX_SCALE',
|
|
meta: { min },
|
|
message: `Invalid number of arguments: expected <min> ("${min}") and [max]`,
|
|
});
|
|
}
|
|
}
|
|
|
|
export class InvalidMaxForScale extends NowError<
|
|
'INVALID_MAX_FOR_SCALE',
|
|
{ value: string }
|
|
> {
|
|
constructor(value: string) {
|
|
super({
|
|
code: 'INVALID_MAX_FOR_SCALE',
|
|
meta: { value },
|
|
message: `Invalid <max> parameter "${value}". A number or "auto" were expected`,
|
|
});
|
|
}
|
|
}
|
|
|
|
export class InvalidCert extends NowError<'INVALID_CERT', {}> {
|
|
constructor() {
|
|
super({
|
|
code: 'INVALID_CERT',
|
|
meta: {},
|
|
message: `The provided custom certificate is invalid and couldn't be added`,
|
|
});
|
|
}
|
|
}
|
|
|
|
export class DNSPermissionDenied extends NowError<
|
|
'DNS_PERMISSION_DENIED',
|
|
{ domain: string }
|
|
> {
|
|
constructor(domain: string) {
|
|
super({
|
|
code: 'DNS_PERMISSION_DENIED',
|
|
meta: { domain },
|
|
message: `You don't have access to the DNS records of ${domain}.`,
|
|
});
|
|
}
|
|
}
|
|
|
|
export class DNSInvalidPort extends NowError<'DNS_INVALID_PORT', {}> {
|
|
constructor() {
|
|
super({
|
|
code: 'DNS_INVALID_PORT',
|
|
meta: {},
|
|
message: `Invalid <port> parameter. A number was expected`,
|
|
});
|
|
}
|
|
}
|
|
|
|
export class DNSInvalidType extends NowError<
|
|
'DNS_INVALID_TYPE',
|
|
{ type: string }
|
|
> {
|
|
constructor(type: string) {
|
|
super({
|
|
code: 'DNS_INVALID_TYPE',
|
|
meta: { type },
|
|
message: `Invalid <type> parameter "${type}". Expected one of A, AAAA, ALIAS, CAA, CNAME, MX, SRV, TXT`,
|
|
});
|
|
}
|
|
}
|
|
|
|
export class DNSConflictingRecord extends NowError<
|
|
'DNS_CONFLICTING_RECORD',
|
|
{ record: string }
|
|
> {
|
|
constructor(record: string) {
|
|
super({
|
|
code: 'DNS_CONFLICTING_RECORD',
|
|
meta: { record },
|
|
message: ` A conflicting record exists "${record}".`,
|
|
});
|
|
}
|
|
}
|
|
|
|
export class DomainRemovalConflict extends NowError<
|
|
'domain_removal_conflict',
|
|
{
|
|
aliases: string[];
|
|
certs: string[];
|
|
pendingAsyncPurchase: boolean;
|
|
suffix: boolean;
|
|
transferring: boolean;
|
|
resolvable: boolean;
|
|
}
|
|
> {
|
|
constructor({
|
|
aliases,
|
|
certs,
|
|
message,
|
|
pendingAsyncPurchase,
|
|
resolvable,
|
|
suffix,
|
|
transferring,
|
|
}: {
|
|
aliases: string[];
|
|
certs: string[];
|
|
message: string;
|
|
pendingAsyncPurchase: boolean;
|
|
resolvable: boolean;
|
|
suffix: boolean;
|
|
transferring: boolean;
|
|
}) {
|
|
super({
|
|
code: 'domain_removal_conflict',
|
|
meta: {
|
|
aliases,
|
|
certs,
|
|
pendingAsyncPurchase,
|
|
suffix,
|
|
transferring,
|
|
resolvable,
|
|
},
|
|
message,
|
|
});
|
|
}
|
|
}
|
|
|
|
export class DomainMoveConflict extends NowError<
|
|
'domain_move_conflict',
|
|
{ pendingAsyncPurchase: boolean; suffix: boolean; resolvable: boolean }
|
|
> {
|
|
constructor({
|
|
message,
|
|
pendingAsyncPurchase,
|
|
resolvable,
|
|
suffix,
|
|
}: {
|
|
message: string;
|
|
pendingAsyncPurchase: boolean;
|
|
resolvable: boolean;
|
|
suffix: boolean;
|
|
}) {
|
|
super({
|
|
code: 'domain_move_conflict',
|
|
meta: {
|
|
pendingAsyncPurchase,
|
|
resolvable,
|
|
suffix,
|
|
},
|
|
message,
|
|
});
|
|
}
|
|
}
|
|
|
|
export class InvalidEmail extends NowError<'INVALID_EMAIL', { email: string }> {
|
|
constructor(email: string, message: string = 'Invalid Email') {
|
|
super({
|
|
code: 'INVALID_EMAIL',
|
|
message,
|
|
meta: { email },
|
|
});
|
|
}
|
|
}
|
|
|
|
export class AccountNotFound extends NowError<
|
|
'ACCOUNT_NOT_FOUND',
|
|
{ email: string }
|
|
> {
|
|
constructor(
|
|
email: string,
|
|
message: string = `Please sign up: https://vercel.com/signup`
|
|
) {
|
|
super({
|
|
code: 'ACCOUNT_NOT_FOUND',
|
|
message,
|
|
meta: { email },
|
|
});
|
|
}
|
|
}
|
|
|
|
export class InvalidMoveDestination extends NowError<
|
|
'INVALID_MOVE_DESTINATION',
|
|
{ destination: string }
|
|
> {
|
|
constructor(destination: string) {
|
|
super({
|
|
code: 'INVALID_MOVE_DESTINATION',
|
|
message: `Invalid move destination "${destination}"`,
|
|
meta: { destination },
|
|
});
|
|
}
|
|
}
|
|
|
|
export class InvalidMoveToken extends NowError<
|
|
'INVALID_MOVE_TOKEN',
|
|
{ token: string }
|
|
> {
|
|
constructor(token: string) {
|
|
super({
|
|
code: 'INVALID_MOVE_TOKEN',
|
|
message: `Invalid move token "${token}"`,
|
|
meta: { token },
|
|
});
|
|
}
|
|
}
|
|
|
|
export class NoBuilderCacheError extends NowError<'NO_BUILDER_CACHE', {}> {
|
|
constructor() {
|
|
super({
|
|
code: 'NO_BUILDER_CACHE',
|
|
message: 'Could not find cache directory for now-builders.',
|
|
meta: {},
|
|
});
|
|
}
|
|
}
|
|
|
|
export class LambdaSizeExceededError extends NowError<
|
|
'MAX_LAMBDA_SIZE_EXCEEDED',
|
|
{ size: number; maxLambdaSize: number }
|
|
> {
|
|
constructor(size: number, maxLambdaSize: number) {
|
|
super({
|
|
code: 'MAX_LAMBDA_SIZE_EXCEEDED',
|
|
message: `The lambda function size (${bytes(
|
|
size
|
|
).toLowerCase()}) exceeds the maximum size limit (${bytes(
|
|
maxLambdaSize
|
|
).toLowerCase()}).`,
|
|
meta: { size, maxLambdaSize },
|
|
});
|
|
}
|
|
}
|
|
|
|
export class MissingDotenvVarsError extends NowError<
|
|
'MISSING_DOTENV_VARS',
|
|
{ type: string; missing: string[] }
|
|
> {
|
|
constructor(type: string, missing: string[]) {
|
|
let message: string;
|
|
|
|
if (missing.length === 1) {
|
|
message = `Env var ${JSON.stringify(missing[0])} is not defined in ${code(
|
|
type
|
|
)} file`;
|
|
} else {
|
|
message = [
|
|
`The following env vars are not defined in ${code(type)} file:`,
|
|
...missing.map(name => ` - ${JSON.stringify(name)}`),
|
|
].join('\n');
|
|
}
|
|
|
|
message += '\nRead more: https://err.sh/now/missing-env-file';
|
|
|
|
super({
|
|
code: 'MISSING_DOTENV_VARS',
|
|
message,
|
|
meta: { type, missing },
|
|
});
|
|
}
|
|
}
|
|
|
|
export class DeploymentsRateLimited extends NowError<
|
|
'DEPLOYMENTS_RATE_LIMITED',
|
|
{}
|
|
> {
|
|
constructor(message: string) {
|
|
super({
|
|
code: 'DEPLOYMENTS_RATE_LIMITED',
|
|
meta: {},
|
|
message,
|
|
});
|
|
}
|
|
}
|
|
|
|
export class BuildsRateLimited extends NowError<'BUILDS_RATE_LIMITED', {}> {
|
|
constructor(message: string) {
|
|
super({
|
|
code: 'BUILDS_RATE_LIMITED',
|
|
meta: {},
|
|
message,
|
|
});
|
|
}
|
|
}
|
|
|
|
export class ProjectNotFound extends NowError<'PROJECT_NOT_FOUND', {}> {
|
|
constructor(nameOrId: string) {
|
|
super({
|
|
code: 'PROJECT_NOT_FOUND',
|
|
meta: {},
|
|
message: `There is no project for "${nameOrId}"`,
|
|
});
|
|
}
|
|
}
|
|
|
|
export class AliasDomainConfigured extends NowError<'DOMAIN_CONFIGURED', {}> {
|
|
constructor({ message }: { message: string }) {
|
|
super({
|
|
code: 'DOMAIN_CONFIGURED',
|
|
meta: {},
|
|
message,
|
|
});
|
|
}
|
|
}
|
|
|
|
export class MissingBuildScript extends NowError<'MISSING_BUILD_SCRIPT', {}> {
|
|
constructor({ message }: { message: string }) {
|
|
super({
|
|
code: 'MISSING_BUILD_SCRIPT',
|
|
meta: {},
|
|
message,
|
|
});
|
|
}
|
|
}
|
|
|
|
export class ConflictingFilePath extends NowError<'CONFLICTING_FILE_PATH', {}> {
|
|
constructor({ message }: { message: string }) {
|
|
super({
|
|
code: 'CONFLICTING_FILE_PATH',
|
|
meta: {},
|
|
message,
|
|
});
|
|
}
|
|
}
|
|
|
|
export class ConflictingPathSegment extends NowError<
|
|
'CONFLICTING_PATH_SEGMENT',
|
|
{}
|
|
> {
|
|
constructor({ message }: { message: string }) {
|
|
super({
|
|
code: 'CONFLICTING_PATH_SEGMENT',
|
|
meta: {},
|
|
message,
|
|
});
|
|
}
|
|
}
|
|
|
|
export class BuildError extends NowError<'BUILD_ERROR', {}> {
|
|
constructor({
|
|
message,
|
|
meta,
|
|
}: {
|
|
message: string;
|
|
meta: { entrypoint?: string };
|
|
}) {
|
|
super({
|
|
code: 'BUILD_ERROR',
|
|
meta,
|
|
message,
|
|
});
|
|
}
|
|
}
|