mirror of
https://github.com/LukeHagar/vercel.git
synced 2025-12-24 19:00:03 +00:00
Compare commits
2 Commits
@vercel/cl
...
storage-cl
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7efe60d1dd | ||
|
|
c82399d6bf |
2
.changeset/good-bobcats-dream.md
Normal file
2
.changeset/good-bobcats-dream.md
Normal file
@@ -0,0 +1,2 @@
|
||||
---
|
||||
---
|
||||
@@ -1,12 +1,5 @@
|
||||
# @vercel-internals/types
|
||||
|
||||
## 1.0.15
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`65dec5b7e`](https://github.com/vercel/vercel/commit/65dec5b7e752f4da8fe0ffdb25215170453f6f8b)]:
|
||||
- @vercel/build-utils@7.2.4
|
||||
|
||||
## 1.0.14
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"private": true,
|
||||
"name": "@vercel-internals/types",
|
||||
"version": "1.0.15",
|
||||
"version": "1.0.14",
|
||||
"types": "index.d.ts",
|
||||
"main": "index.d.ts",
|
||||
"files": [
|
||||
@@ -10,7 +10,7 @@
|
||||
"dependencies": {
|
||||
"@types/node": "14.14.31",
|
||||
"@vercel-internals/constants": "1.0.4",
|
||||
"@vercel/build-utils": "7.2.4",
|
||||
"@vercel/build-utils": "7.2.3",
|
||||
"@vercel/routing-utils": "3.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -1,11 +1,5 @@
|
||||
# @vercel/build-utils
|
||||
|
||||
## 7.2.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Select Node.js version based on what's available in build-container ([#10822](https://github.com/vercel/vercel/pull/10822))
|
||||
|
||||
## 7.2.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/build-utils",
|
||||
"version": "7.2.4",
|
||||
"version": "7.2.3",
|
||||
"license": "Apache-2.0",
|
||||
"main": "./dist/index.js",
|
||||
"types": "./dist/index.d.js",
|
||||
|
||||
@@ -1,11 +1,8 @@
|
||||
import { statSync } from 'fs';
|
||||
import { intersects, validRange } from 'semver';
|
||||
import { NodeVersion } from '../types';
|
||||
import { NowBuildError } from '../errors';
|
||||
import debug from '../debug';
|
||||
|
||||
export type NodeVersionMajor = ReturnType<typeof getOptions>[number]['major'];
|
||||
|
||||
function getOptions() {
|
||||
const options = [
|
||||
{ major: 18, range: '18.x', runtime: 'nodejs18.x' },
|
||||
@@ -49,21 +46,6 @@ function getOptions() {
|
||||
return options;
|
||||
}
|
||||
|
||||
function isNodeVersionAvailable(version: NodeVersion): boolean {
|
||||
try {
|
||||
return statSync(`/node${version.major}`).isDirectory();
|
||||
} catch {
|
||||
// ENOENT, or any other error, we don't care about
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
export function getAvailableNodeVersions(): NodeVersionMajor[] {
|
||||
return getOptions()
|
||||
.filter(isNodeVersionAvailable)
|
||||
.map(n => n.major);
|
||||
}
|
||||
|
||||
function getHint(isAuto = false) {
|
||||
const { major, range } = getLatestNodeVersion();
|
||||
return isAuto
|
||||
@@ -71,22 +53,8 @@ function getHint(isAuto = false) {
|
||||
: `Please set "engines": { "node": "${range}" } in your \`package.json\` file to use Node.js ${major}.`;
|
||||
}
|
||||
|
||||
export function getLatestNodeVersion(availableVersions?: NodeVersionMajor[]) {
|
||||
const all = getOptions();
|
||||
if (availableVersions) {
|
||||
// Return the first node version that is definitely
|
||||
// available in the build-container.
|
||||
for (const version of all) {
|
||||
for (const major of availableVersions) {
|
||||
if (version.major === major) {
|
||||
return version;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// As a fallback for local `vc build` and the tests,
|
||||
// return the first node version if none is found.
|
||||
return all[0];
|
||||
export function getLatestNodeVersion() {
|
||||
return getOptions()[0];
|
||||
}
|
||||
|
||||
export function getDiscontinuedNodeVersions(): NodeVersion[] {
|
||||
@@ -95,10 +63,9 @@ export function getDiscontinuedNodeVersions(): NodeVersion[] {
|
||||
|
||||
export async function getSupportedNodeVersion(
|
||||
engineRange: string | undefined,
|
||||
isAuto = false,
|
||||
availableVersions?: NodeVersionMajor[]
|
||||
isAuto = false
|
||||
): Promise<NodeVersion> {
|
||||
let selection: NodeVersion | undefined;
|
||||
let selection: NodeVersion = getLatestNodeVersion();
|
||||
|
||||
if (engineRange) {
|
||||
const found =
|
||||
@@ -107,12 +74,7 @@ export async function getSupportedNodeVersion(
|
||||
// the array is already in order so return the first
|
||||
// match which will be the newest version of node
|
||||
selection = o;
|
||||
return (
|
||||
intersects(o.range, engineRange) &&
|
||||
(availableVersions?.length
|
||||
? availableVersions.includes(o.major)
|
||||
: true)
|
||||
);
|
||||
return intersects(o.range, engineRange);
|
||||
});
|
||||
if (!found) {
|
||||
throw new NowBuildError({
|
||||
@@ -125,10 +87,6 @@ export async function getSupportedNodeVersion(
|
||||
}
|
||||
}
|
||||
|
||||
if (!selection) {
|
||||
selection = getLatestNodeVersion(availableVersions);
|
||||
}
|
||||
|
||||
if (isDiscontinued(selection)) {
|
||||
const intro = `Node.js Version "${selection.range}" is discontinued and must be upgraded.`;
|
||||
throw new NowBuildError({
|
||||
|
||||
@@ -9,11 +9,7 @@ import { deprecate } from 'util';
|
||||
import debug from '../debug';
|
||||
import { NowBuildError } from '../errors';
|
||||
import { Meta, PackageJson, NodeVersion, Config } from '../types';
|
||||
import {
|
||||
getSupportedNodeVersion,
|
||||
getLatestNodeVersion,
|
||||
getAvailableNodeVersions,
|
||||
} from './node-version';
|
||||
import { getSupportedNodeVersion, getLatestNodeVersion } from './node-version';
|
||||
import { readConfigFile } from './read-config-file';
|
||||
import { cloneEnv } from '../clone-env';
|
||||
|
||||
@@ -242,10 +238,9 @@ export async function getNodeVersion(
|
||||
destPath: string,
|
||||
nodeVersionFallback = process.env.VERCEL_PROJECT_SETTINGS_NODE_VERSION,
|
||||
config: Config = {},
|
||||
meta: Meta = {},
|
||||
availableVersions = getAvailableNodeVersions()
|
||||
meta: Meta = {}
|
||||
): Promise<NodeVersion> {
|
||||
const latest = getLatestNodeVersion(availableVersions);
|
||||
const latest = getLatestNodeVersion();
|
||||
if (meta.isDev) {
|
||||
// Use the system-installed version of `node` in PATH for `vercel dev`
|
||||
return { ...latest, runtime: 'nodejs' };
|
||||
@@ -271,7 +266,7 @@ export async function getNodeVersion(
|
||||
nodeVersion = node;
|
||||
isAuto = false;
|
||||
}
|
||||
return getSupportedNodeVersion(nodeVersion, isAuto, availableVersions);
|
||||
return getSupportedNodeVersion(nodeVersion, isAuto);
|
||||
}
|
||||
|
||||
export async function scanParentDirs(
|
||||
|
||||
36
packages/build-utils/test/unit.test.ts
vendored
36
packages/build-utils/test/unit.test.ts
vendored
@@ -127,27 +127,6 @@ it('should allow nodejs18.x', async () => {
|
||||
expect(await getSupportedNodeVersion('>=16')).toHaveProperty('major', 18);
|
||||
});
|
||||
|
||||
it('should not allow nodejs20.x when not available', async () => {
|
||||
// Simulates AL2 build-container
|
||||
await expect(
|
||||
getSupportedNodeVersion('20.x', true, [14, 16, 18])
|
||||
).rejects.toThrow(
|
||||
'Found invalid Node.js Version: "20.x". Please set Node.js Version to 18.x in your Project Settings to use Node.js 18.'
|
||||
);
|
||||
});
|
||||
|
||||
it('should not allow nodejs18.x when not available', async () => {
|
||||
// Simulates AL2023 build-container
|
||||
try {
|
||||
process.env.VERCEL_ALLOW_NODEJS20 = '1';
|
||||
await expect(getSupportedNodeVersion('18.x', true, [20])).rejects.toThrow(
|
||||
'Found invalid Node.js Version: "18.x". Please set Node.js Version to 20.x in your Project Settings to use Node.js 20.'
|
||||
);
|
||||
} finally {
|
||||
delete process.env.VERCEL_ALLOW_NODEJS20;
|
||||
}
|
||||
});
|
||||
|
||||
it('should ignore node version in vercel dev getNodeVersion()', async () => {
|
||||
expect(
|
||||
await getNodeVersion(
|
||||
@@ -256,21 +235,6 @@ it('should get latest node version', async () => {
|
||||
expect(getLatestNodeVersion()).toHaveProperty('major', 18);
|
||||
});
|
||||
|
||||
it('should get latest node version with Node 18.x in build-container', async () => {
|
||||
// Simulates AL2 build-container
|
||||
expect(getLatestNodeVersion([14, 16, 18])).toHaveProperty('major', 18);
|
||||
});
|
||||
|
||||
it('should get latest node version with Node 20.x in build-container', async () => {
|
||||
// Simulates AL2023 build-container
|
||||
try {
|
||||
process.env.VERCEL_ALLOW_NODEJS20 = '1';
|
||||
expect(getLatestNodeVersion([20])).toHaveProperty('major', 20);
|
||||
} finally {
|
||||
delete process.env.VERCEL_ALLOW_NODEJS20;
|
||||
}
|
||||
});
|
||||
|
||||
it('should throw for discontinued versions', async () => {
|
||||
// Mock a future date so that Node 8 and 10 become discontinued
|
||||
const realDateNow = Date.now.bind(global.Date);
|
||||
|
||||
@@ -1,14 +1,5 @@
|
||||
# vercel
|
||||
|
||||
## 32.5.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`65dec5b7e`](https://github.com/vercel/vercel/commit/65dec5b7e752f4da8fe0ffdb25215170453f6f8b)]:
|
||||
- @vercel/build-utils@7.2.4
|
||||
- @vercel/node@3.0.10
|
||||
- @vercel/static-build@2.0.11
|
||||
|
||||
## 32.5.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "vercel",
|
||||
"version": "32.5.4",
|
||||
"version": "32.5.3",
|
||||
"preferGlobal": true,
|
||||
"license": "Apache-2.0",
|
||||
"description": "The command-line interface for Vercel",
|
||||
@@ -17,6 +17,7 @@
|
||||
"test-dev": "pnpm test test/dev/",
|
||||
"coverage": "codecov",
|
||||
"build": "node scripts/build.mjs",
|
||||
"watch": "node scripts/build.mjs --watch",
|
||||
"dev": "ts-node ./src/index.ts",
|
||||
"type-check": "tsc --noEmit"
|
||||
},
|
||||
@@ -31,17 +32,17 @@
|
||||
"node": ">= 16"
|
||||
},
|
||||
"dependencies": {
|
||||
"@vercel/build-utils": "7.2.4",
|
||||
"@vercel/build-utils": "7.2.3",
|
||||
"@vercel/fun": "1.1.0",
|
||||
"@vercel/go": "3.0.3",
|
||||
"@vercel/hydrogen": "1.0.1",
|
||||
"@vercel/next": "4.0.14",
|
||||
"@vercel/node": "3.0.10",
|
||||
"@vercel/node": "3.0.9",
|
||||
"@vercel/python": "4.1.0",
|
||||
"@vercel/redwood": "2.0.5",
|
||||
"@vercel/remix-builder": "2.0.11",
|
||||
"@vercel/ruby": "2.0.2",
|
||||
"@vercel/static-build": "2.0.11",
|
||||
"@vercel/static-build": "2.0.10",
|
||||
"chokidar": "3.3.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -88,8 +89,8 @@
|
||||
"@types/yauzl-promise": "2.1.0",
|
||||
"@vercel-internals/constants": "1.0.4",
|
||||
"@vercel-internals/get-package-json": "1.0.0",
|
||||
"@vercel-internals/types": "1.0.15",
|
||||
"@vercel/client": "13.0.8",
|
||||
"@vercel-internals/types": "1.0.14",
|
||||
"@vercel/client": "13.0.7",
|
||||
"@vercel/error-utils": "2.0.2",
|
||||
"@vercel/frameworks": "2.0.3",
|
||||
"@vercel/fs-detectors": "5.1.3",
|
||||
|
||||
@@ -40,6 +40,7 @@ export const help = () => `
|
||||
projects Manages your Projects
|
||||
rm | remove [id] Removes a deployment
|
||||
secrets [name] Manages your global Secrets, for use in Environment Variables
|
||||
stores Manages your Stores
|
||||
teams Manages your teams
|
||||
whoami Shows the username of the currently logged in user
|
||||
|
||||
|
||||
@@ -38,4 +38,5 @@ export default new Map([
|
||||
['team', 'teams'],
|
||||
['teams', 'teams'],
|
||||
['whoami', 'whoami'],
|
||||
['stores', 'stores'],
|
||||
]);
|
||||
|
||||
62
packages/cli/src/commands/stores/command.ts
Normal file
62
packages/cli/src/commands/stores/command.ts
Normal file
@@ -0,0 +1,62 @@
|
||||
import { Command } from '../help';
|
||||
import { packageName } from '../../util/pkg-name';
|
||||
|
||||
export const storesCommand: Command = {
|
||||
name: 'stores',
|
||||
description: 'CRUD commands for stores.',
|
||||
arguments: [
|
||||
{
|
||||
name: 'command',
|
||||
required: true,
|
||||
},
|
||||
],
|
||||
subcommands: [
|
||||
{
|
||||
name: 'create',
|
||||
description: 'Create a new store',
|
||||
arguments: [],
|
||||
options: [
|
||||
{
|
||||
name: 'type',
|
||||
description: 'Set the store type to create',
|
||||
shorthand: 't',
|
||||
type: 'string',
|
||||
deprecated: false,
|
||||
multi: false,
|
||||
},
|
||||
{
|
||||
name: 'name',
|
||||
description: 'Set the name of your new store',
|
||||
shorthand: 'n',
|
||||
type: 'string',
|
||||
deprecated: false,
|
||||
multi: false,
|
||||
},
|
||||
],
|
||||
examples: [
|
||||
{
|
||||
name: 'Create a new store',
|
||||
value: [`${packageName} store create`],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'list',
|
||||
description: 'List all your stores',
|
||||
arguments: [],
|
||||
options: [],
|
||||
examples: [],
|
||||
},
|
||||
],
|
||||
options: [
|
||||
{
|
||||
name: 'yes',
|
||||
description: 'Skip the confirmation prompts',
|
||||
shorthand: 'y',
|
||||
type: 'boolean',
|
||||
deprecated: false,
|
||||
multi: false,
|
||||
},
|
||||
],
|
||||
examples: [],
|
||||
};
|
||||
183
packages/cli/src/commands/stores/create.ts
Normal file
183
packages/cli/src/commands/stores/create.ts
Normal file
@@ -0,0 +1,183 @@
|
||||
import type { ProjectLinked, ProjectNotLinked } from '@vercel-internals/types';
|
||||
|
||||
import Client from '../../util/client';
|
||||
import list from '../../util/input/list';
|
||||
import text from '../../util/input/text';
|
||||
import { createStore } from '../../util/stores/create-store';
|
||||
import { linkStore } from '../../util/stores/link-store';
|
||||
|
||||
type Options = {
|
||||
'--type': string;
|
||||
'--name': string;
|
||||
};
|
||||
|
||||
type CreateOptions = {
|
||||
client: Client;
|
||||
projectLink: ProjectLinked | ProjectNotLinked;
|
||||
opts: Partial<Options>;
|
||||
};
|
||||
|
||||
const VALID_STORE_TYPES = { blob: 'blob', kv: 'kv', postgres: 'postgres' };
|
||||
|
||||
function validStoreType(storetype: string) {
|
||||
return Object.values(VALID_STORE_TYPES).includes(storetype);
|
||||
}
|
||||
|
||||
async function inquireStoreType({
|
||||
client,
|
||||
opts,
|
||||
}: CreateOptions): Promise<string | undefined> {
|
||||
const storeType =
|
||||
opts['--type'] ??
|
||||
(await list(client, {
|
||||
choices: [
|
||||
{
|
||||
name: 'Blob - Fast object storage',
|
||||
value: VALID_STORE_TYPES.blob,
|
||||
short: VALID_STORE_TYPES.blob,
|
||||
},
|
||||
{
|
||||
name: 'KV - Durable Redis',
|
||||
value: VALID_STORE_TYPES.kv,
|
||||
short: VALID_STORE_TYPES.kv,
|
||||
},
|
||||
{
|
||||
name: 'Postgres - Serverless SQL',
|
||||
value: VALID_STORE_TYPES.postgres,
|
||||
short: VALID_STORE_TYPES.postgres,
|
||||
},
|
||||
],
|
||||
message: 'What kind of store do you want to create?',
|
||||
}));
|
||||
|
||||
if (!validStoreType(storeType)) {
|
||||
const validTypes = Object.values(VALID_STORE_TYPES).join(', ');
|
||||
client.output.error(
|
||||
`Received invalid store type '${storeType}'. Valid types are: ${validTypes}.`
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!storeType) {
|
||||
client.output.log('Canceled');
|
||||
return;
|
||||
}
|
||||
|
||||
return storeType;
|
||||
}
|
||||
|
||||
function validStoreName(storename: string) {
|
||||
return storename.length > 5;
|
||||
}
|
||||
|
||||
async function inquireStoreName(
|
||||
storeType: string,
|
||||
{ opts, client, projectLink }: CreateOptions
|
||||
): Promise<string | undefined> {
|
||||
const name =
|
||||
opts['--name'] ??
|
||||
(await text({
|
||||
label: 'Select a store name: ',
|
||||
validateValue: validStoreName,
|
||||
initialValue:
|
||||
projectLink.status === 'linked'
|
||||
? `${projectLink.project.name}-${storeType}`
|
||||
: `my-${storeType}-store`,
|
||||
}));
|
||||
|
||||
if (!validStoreName(name)) {
|
||||
client.output.error(
|
||||
`Invalid store name '${name}'. Store names must be at least 6 characters long.`
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!name) {
|
||||
client.output.log('No name input');
|
||||
return;
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
const POSTGRES_REGIONS = [
|
||||
'aws-us-east-1',
|
||||
'aws-us-east-2',
|
||||
'aws-us-west-2',
|
||||
'aws-eu-central-1',
|
||||
'aws-ap-southeast-1',
|
||||
];
|
||||
|
||||
async function creaetPostgresStore(name: string, { client }: CreateOptions) {
|
||||
const { region } = await client.prompt({
|
||||
type: 'list',
|
||||
name: 'region',
|
||||
message:
|
||||
'In which region should your database reads and writes take place?',
|
||||
choices: POSTGRES_REGIONS,
|
||||
default: POSTGRES_REGIONS[0],
|
||||
});
|
||||
|
||||
return createStore({ client, payload: { name, region }, type: 'postgres' });
|
||||
}
|
||||
|
||||
async function maybeLinkStore(
|
||||
{ id, name }: { id: string; name: string },
|
||||
{ client, projectLink }: CreateOptions
|
||||
): Promise<boolean> {
|
||||
if (projectLink.status === 'not_linked') {
|
||||
client.output.print(
|
||||
`\nYou can link the store later in the Vercel dashboard.`
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const linked = await linkStore({ client, link: projectLink, name, id });
|
||||
|
||||
if (!linked) {
|
||||
client.output.error('Failed to link store');
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
export async function create(options: CreateOptions) {
|
||||
const { client } = options;
|
||||
|
||||
const type = await inquireStoreType(options);
|
||||
if (!type) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
const name = await inquireStoreName(type, options);
|
||||
if (!name) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
let result;
|
||||
|
||||
switch (type) {
|
||||
case 'blob':
|
||||
result = await createStore({ client, payload: { name }, type: 'blob' });
|
||||
break;
|
||||
case 'kv':
|
||||
result = await createStore({ client, payload: { name }, type: 'redis' });
|
||||
break;
|
||||
case 'postgres':
|
||||
result = await creaetPostgresStore(name, options);
|
||||
}
|
||||
|
||||
if (!result) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
const linked = await maybeLinkStore(result, options);
|
||||
if (!linked) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
70
packages/cli/src/commands/stores/index.ts
Normal file
70
packages/cli/src/commands/stores/index.ts
Normal file
@@ -0,0 +1,70 @@
|
||||
import Client from '../../util/client';
|
||||
import getArgs from '../../util/get-args';
|
||||
import getInvalidSubcommand from '../../util/get-invalid-subcommand';
|
||||
import getSubcommand from '../../util/get-subcommand';
|
||||
import handleError from '../../util/handle-error';
|
||||
import { getLinkedProject } from '../../util/projects/link';
|
||||
import { help } from '../help';
|
||||
|
||||
import { storesCommand } from './command';
|
||||
import { create } from './create';
|
||||
import { list } from './list';
|
||||
|
||||
const COMMAND_CONFIG = {
|
||||
create: ['create'],
|
||||
list: ['list', 'ls'],
|
||||
};
|
||||
|
||||
export const STORAGE_API_PATH = '/v1/storage';
|
||||
|
||||
export default async function main(client: Client) {
|
||||
let argv;
|
||||
|
||||
try {
|
||||
argv = getArgs(client.argv.slice(2), {
|
||||
'--name': String,
|
||||
'--n': '--name',
|
||||
|
||||
'--type': String,
|
||||
'--t': '--type',
|
||||
});
|
||||
} catch (error) {
|
||||
handleError(error);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (argv['--help']) {
|
||||
client.output.print(
|
||||
help(storesCommand, { columns: client.stderr.columns })
|
||||
);
|
||||
return 2;
|
||||
}
|
||||
|
||||
const subArgs = argv._.slice(1);
|
||||
const { subcommand } = getSubcommand(subArgs, COMMAND_CONFIG);
|
||||
const { cwd, output } = client;
|
||||
|
||||
const link = await getLinkedProject(client, cwd);
|
||||
|
||||
if (link.status === 'error') {
|
||||
return link.exitCode;
|
||||
}
|
||||
|
||||
if (link.status === 'linked') {
|
||||
client.config.currentTeam =
|
||||
link.org.type === 'team' ? link.org.id : undefined;
|
||||
}
|
||||
|
||||
switch (subcommand) {
|
||||
case 'create':
|
||||
return create({ opts: argv, client, projectLink: link });
|
||||
case 'list':
|
||||
return list({ client });
|
||||
default:
|
||||
output.error(getInvalidSubcommand(COMMAND_CONFIG));
|
||||
client.output.print(
|
||||
help(storesCommand, { columns: client.stderr.columns })
|
||||
);
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
26
packages/cli/src/commands/stores/list.ts
Normal file
26
packages/cli/src/commands/stores/list.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import Client from '../../util/client';
|
||||
import { listStores } from '../../util/stores/list-stores';
|
||||
import table from 'text-table';
|
||||
|
||||
type ListOptions = {
|
||||
client: Client;
|
||||
};
|
||||
|
||||
export async function list({ client }: ListOptions) {
|
||||
const stores = await listStores({ client });
|
||||
|
||||
if (!stores) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
client.output.print(
|
||||
`\n${table([
|
||||
['Type', 'Name', 'Id'],
|
||||
...stores
|
||||
.sort((a, b) => (a.type > b.type ? 1 : -1))
|
||||
.map(store => [store.type, store.name, store.id]),
|
||||
])}\n`
|
||||
);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -597,6 +597,9 @@ const main = async () => {
|
||||
case 'whoami':
|
||||
func = require('./commands/whoami').default;
|
||||
break;
|
||||
case 'stores':
|
||||
func = require('./commands/stores').default;
|
||||
break;
|
||||
default:
|
||||
func = null;
|
||||
break;
|
||||
|
||||
50
packages/cli/src/util/stores/create-store.ts
Normal file
50
packages/cli/src/util/stores/create-store.ts
Normal file
@@ -0,0 +1,50 @@
|
||||
import chalk from 'chalk';
|
||||
|
||||
import { JSONObject } from '@vercel-internals/types';
|
||||
|
||||
import { STORAGE_API_PATH } from '../../commands/stores';
|
||||
import Client from '../client';
|
||||
import stamp from '../output/stamp';
|
||||
|
||||
type CreateBlobResponse = {
|
||||
store: {
|
||||
id: string;
|
||||
name: string;
|
||||
};
|
||||
};
|
||||
|
||||
export async function createStore(options: {
|
||||
client: Client;
|
||||
|
||||
type: 'blob' | 'redis' | 'postgres';
|
||||
payload: JSONObject;
|
||||
}) {
|
||||
const { client, type, payload } = options;
|
||||
|
||||
const pullStamp = stamp();
|
||||
|
||||
client.output.spinner('creating Blob store');
|
||||
|
||||
try {
|
||||
const { store } = await client.fetch<CreateBlobResponse>(
|
||||
`${STORAGE_API_PATH}/stores/${type}`,
|
||||
{ method: 'POST', body: payload }
|
||||
);
|
||||
|
||||
client.output.success(
|
||||
`Created blob store ${chalk.bold(store.name)} ${chalk.gray(pullStamp())}`
|
||||
);
|
||||
|
||||
return {
|
||||
id: store.id,
|
||||
name: store.name,
|
||||
};
|
||||
} catch (error) {
|
||||
if (error instanceof Error) {
|
||||
client.output.error(`Failed to create store: ${error.message}`);
|
||||
return;
|
||||
}
|
||||
|
||||
client.output.error(`Failed to create store: ${error}`);
|
||||
}
|
||||
}
|
||||
63
packages/cli/src/util/stores/link-store.ts
Normal file
63
packages/cli/src/util/stores/link-store.ts
Normal file
@@ -0,0 +1,63 @@
|
||||
import chalk from 'chalk';
|
||||
|
||||
import { ProjectLinked } from '@vercel-internals/types';
|
||||
|
||||
import Client from '../client';
|
||||
import { STORAGE_API_PATH } from '../../commands/stores';
|
||||
import confirm from '../input/confirm';
|
||||
import { getCommandName } from '../pkg-name';
|
||||
|
||||
export async function linkStore(options: {
|
||||
name: string;
|
||||
id: string;
|
||||
client: Client;
|
||||
link: ProjectLinked;
|
||||
}) {
|
||||
const {
|
||||
client,
|
||||
name,
|
||||
id,
|
||||
link: { project, org },
|
||||
} = options;
|
||||
|
||||
const shouldLink = await confirm(
|
||||
client,
|
||||
`Should the ${chalk.bold(name)} store be linked to the ${chalk.bold(
|
||||
project.name
|
||||
)} project?`,
|
||||
true
|
||||
);
|
||||
|
||||
if (!shouldLink) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
client.output.spinner('linking store');
|
||||
|
||||
await client.fetch(`${STORAGE_API_PATH}/stores/${id}/connections`, {
|
||||
accountId: org.id,
|
||||
method: 'POST',
|
||||
body: {
|
||||
projectId: project.id,
|
||||
envVarEnvironments: ['production', 'preview', 'development'],
|
||||
},
|
||||
});
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
|
||||
client.output.success(
|
||||
`Linked blob store ${chalk.bold(name)} to project ${chalk.bold(
|
||||
project.name
|
||||
)}\n`
|
||||
);
|
||||
|
||||
client.output.print(
|
||||
`Run ${getCommandName(
|
||||
'env pull'
|
||||
)} to download the newly created env variables.`
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
||||
32
packages/cli/src/util/stores/list-stores.ts
Normal file
32
packages/cli/src/util/stores/list-stores.ts
Normal file
@@ -0,0 +1,32 @@
|
||||
import Client from '../client';
|
||||
import { STORAGE_API_PATH } from '../../commands/stores';
|
||||
|
||||
type ListStoresResponse = {
|
||||
stores: {
|
||||
name: string;
|
||||
id: string;
|
||||
createdAt: number;
|
||||
type: string;
|
||||
}[];
|
||||
};
|
||||
|
||||
export async function listStores(options: { client: Client }) {
|
||||
const { client } = options;
|
||||
|
||||
client.output.spinner('fetching store list');
|
||||
|
||||
try {
|
||||
const response = await client.fetch<ListStoresResponse>(
|
||||
`${STORAGE_API_PATH}/stores`
|
||||
);
|
||||
|
||||
return response.stores;
|
||||
} catch (error) {
|
||||
if (error instanceof Error) {
|
||||
client.output.error(`Failed to fetch blob list: ${error.message}`);
|
||||
return;
|
||||
}
|
||||
|
||||
client.output.error(`Failed to fetch blob list: ${error}`);
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,5 @@
|
||||
# @vercel/client
|
||||
|
||||
## 13.0.8
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`65dec5b7e`](https://github.com/vercel/vercel/commit/65dec5b7e752f4da8fe0ffdb25215170453f6f8b)]:
|
||||
- @vercel/build-utils@7.2.4
|
||||
|
||||
## 13.0.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/client",
|
||||
"version": "13.0.8",
|
||||
"version": "13.0.7",
|
||||
"main": "dist/index.js",
|
||||
"typings": "dist/index.d.ts",
|
||||
"homepage": "https://vercel.com",
|
||||
@@ -37,7 +37,7 @@
|
||||
"typescript": "4.9.5"
|
||||
},
|
||||
"dependencies": {
|
||||
"@vercel/build-utils": "7.2.4",
|
||||
"@vercel/build-utils": "7.2.3",
|
||||
"@vercel/routing-utils": "3.1.0",
|
||||
"@zeit/fetch": "5.2.0",
|
||||
"async-retry": "1.2.3",
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
"@types/minimatch": "3.0.5",
|
||||
"@types/node": "14.18.33",
|
||||
"@types/semver": "7.3.10",
|
||||
"@vercel/build-utils": "7.2.4",
|
||||
"@vercel/build-utils": "7.2.3",
|
||||
"jest-junit": "16.0.0",
|
||||
"typescript": "4.9.5"
|
||||
}
|
||||
|
||||
@@ -1,12 +1,5 @@
|
||||
# @vercel/gatsby-plugin-vercel-builder
|
||||
|
||||
## 2.0.10
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`65dec5b7e`](https://github.com/vercel/vercel/commit/65dec5b7e752f4da8fe0ffdb25215170453f6f8b)]:
|
||||
- @vercel/build-utils@7.2.4
|
||||
|
||||
## 2.0.9
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/gatsby-plugin-vercel-builder",
|
||||
"version": "2.0.10",
|
||||
"version": "2.0.9",
|
||||
"main": "dist/index.js",
|
||||
"files": [
|
||||
"dist",
|
||||
@@ -20,7 +20,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@sinclair/typebox": "0.25.24",
|
||||
"@vercel/build-utils": "7.2.4",
|
||||
"@vercel/build-utils": "7.2.3",
|
||||
"@vercel/routing-utils": "3.1.0",
|
||||
"esbuild": "0.14.47",
|
||||
"etag": "1.8.1",
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
"@types/node-fetch": "^2.3.0",
|
||||
"@types/tar": "6.1.5",
|
||||
"@types/yauzl-promise": "2.1.0",
|
||||
"@vercel/build-utils": "7.2.4",
|
||||
"@vercel/build-utils": "7.2.3",
|
||||
"async-retry": "1.3.3",
|
||||
"execa": "^1.0.0",
|
||||
"fs-extra": "^7.0.0",
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
"devDependencies": {
|
||||
"@types/jest": "27.5.1",
|
||||
"@types/node": "14.18.33",
|
||||
"@vercel/build-utils": "7.2.4",
|
||||
"@vercel/build-utils": "7.2.3",
|
||||
"execa": "3.2.0",
|
||||
"fs-extra": "11.1.0",
|
||||
"jest-junit": "16.0.0"
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
"@types/semver": "6.0.0",
|
||||
"@types/text-table": "0.2.1",
|
||||
"@types/webpack-sources": "3.2.0",
|
||||
"@vercel/build-utils": "7.2.4",
|
||||
"@vercel/build-utils": "7.2.3",
|
||||
"@vercel/routing-utils": "3.1.0",
|
||||
"async-sema": "3.0.1",
|
||||
"buffer-crc32": "0.2.13",
|
||||
|
||||
@@ -1,12 +1,5 @@
|
||||
# @vercel/node
|
||||
|
||||
## 3.0.10
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`65dec5b7e`](https://github.com/vercel/vercel/commit/65dec5b7e752f4da8fe0ffdb25215170453f6f8b)]:
|
||||
- @vercel/build-utils@7.2.4
|
||||
|
||||
## 3.0.9
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/node",
|
||||
"version": "3.0.10",
|
||||
"version": "3.0.9",
|
||||
"license": "Apache-2.0",
|
||||
"main": "./dist/index",
|
||||
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/node-js",
|
||||
@@ -24,7 +24,7 @@
|
||||
"@edge-runtime/primitives": "4.0.5",
|
||||
"@edge-runtime/vm": "3.1.7",
|
||||
"@types/node": "14.18.33",
|
||||
"@vercel/build-utils": "7.2.4",
|
||||
"@vercel/build-utils": "7.2.3",
|
||||
"@vercel/error-utils": "2.0.2",
|
||||
"@vercel/nft": "0.24.2",
|
||||
"@vercel/static-config": "3.0.0",
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
"@types/jest": "27.4.1",
|
||||
"@types/node": "14.18.33",
|
||||
"@types/which": "3.0.0",
|
||||
"@vercel/build-utils": "7.2.4",
|
||||
"@vercel/build-utils": "7.2.3",
|
||||
"execa": "^1.0.0",
|
||||
"fs-extra": "11.1.1",
|
||||
"jest-junit": "16.0.0",
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
"@types/aws-lambda": "8.10.19",
|
||||
"@types/node": "14.18.33",
|
||||
"@types/semver": "6.0.0",
|
||||
"@vercel/build-utils": "7.2.4",
|
||||
"@vercel/build-utils": "7.2.3",
|
||||
"execa": "3.2.0",
|
||||
"fs-extra": "11.1.0",
|
||||
"jest-junit": "16.0.0"
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
"@types/jest": "27.5.1",
|
||||
"@types/node": "14.18.33",
|
||||
"@types/semver": "7.3.13",
|
||||
"@vercel/build-utils": "7.2.4",
|
||||
"@vercel/build-utils": "7.2.3",
|
||||
"jest-junit": "16.0.0",
|
||||
"path-to-regexp": "6.2.1",
|
||||
"semver": "7.5.2"
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
"devDependencies": {
|
||||
"@types/fs-extra": "8.0.0",
|
||||
"@types/semver": "6.0.0",
|
||||
"@vercel/build-utils": "7.2.4",
|
||||
"@vercel/build-utils": "7.2.3",
|
||||
"execa": "2.0.4",
|
||||
"fs-extra": "^7.0.1",
|
||||
"jest-junit": "16.0.0",
|
||||
|
||||
@@ -1,12 +1,5 @@
|
||||
# @vercel/static-build
|
||||
|
||||
## 2.0.11
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies []:
|
||||
- @vercel/gatsby-plugin-vercel-builder@2.0.10
|
||||
|
||||
## 2.0.10
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/static-build",
|
||||
"version": "2.0.11",
|
||||
"version": "2.0.10",
|
||||
"license": "Apache-2.0",
|
||||
"main": "./dist/index",
|
||||
"homepage": "https://vercel.com/docs/build-step",
|
||||
@@ -21,7 +21,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@vercel/gatsby-plugin-vercel-analytics": "1.0.11",
|
||||
"@vercel/gatsby-plugin-vercel-builder": "2.0.10",
|
||||
"@vercel/gatsby-plugin-vercel-builder": "2.0.9",
|
||||
"@vercel/static-config": "3.0.0",
|
||||
"ts-morph": "12.0.0"
|
||||
},
|
||||
@@ -35,7 +35,7 @@
|
||||
"@types/node-fetch": "2.5.4",
|
||||
"@types/promise-timeout": "1.3.0",
|
||||
"@types/semver": "7.3.13",
|
||||
"@vercel/build-utils": "7.2.4",
|
||||
"@vercel/build-utils": "7.2.3",
|
||||
"@vercel/error-utils": "2.0.2",
|
||||
"@vercel/frameworks": "2.0.3",
|
||||
"@vercel/fs-detectors": "5.1.3",
|
||||
|
||||
38
pnpm-lock.yaml
generated
38
pnpm-lock.yaml
generated
@@ -186,7 +186,7 @@ importers:
|
||||
specifier: 1.0.4
|
||||
version: link:../constants
|
||||
'@vercel/build-utils':
|
||||
specifier: 7.2.4
|
||||
specifier: 7.2.3
|
||||
version: link:../../packages/build-utils
|
||||
'@vercel/routing-utils':
|
||||
specifier: 3.1.0
|
||||
@@ -310,7 +310,7 @@ importers:
|
||||
packages/cli:
|
||||
dependencies:
|
||||
'@vercel/build-utils':
|
||||
specifier: 7.2.4
|
||||
specifier: 7.2.3
|
||||
version: link:../build-utils
|
||||
'@vercel/fun':
|
||||
specifier: 1.1.0
|
||||
@@ -325,7 +325,7 @@ importers:
|
||||
specifier: 4.0.14
|
||||
version: link:../next
|
||||
'@vercel/node':
|
||||
specifier: 3.0.10
|
||||
specifier: 3.0.9
|
||||
version: link:../node
|
||||
'@vercel/python':
|
||||
specifier: 4.1.0
|
||||
@@ -340,7 +340,7 @@ importers:
|
||||
specifier: 2.0.2
|
||||
version: link:../ruby
|
||||
'@vercel/static-build':
|
||||
specifier: 2.0.11
|
||||
specifier: 2.0.10
|
||||
version: link:../static-build
|
||||
chokidar:
|
||||
specifier: 3.3.1
|
||||
@@ -476,10 +476,10 @@ importers:
|
||||
specifier: 1.0.0
|
||||
version: link:../../internals/get-package-json
|
||||
'@vercel-internals/types':
|
||||
specifier: 1.0.15
|
||||
specifier: 1.0.14
|
||||
version: link:../../internals/types
|
||||
'@vercel/client':
|
||||
specifier: 13.0.8
|
||||
specifier: 13.0.7
|
||||
version: link:../client
|
||||
'@vercel/error-utils':
|
||||
specifier: 2.0.2
|
||||
@@ -722,7 +722,7 @@ importers:
|
||||
packages/client:
|
||||
dependencies:
|
||||
'@vercel/build-utils':
|
||||
specifier: 7.2.4
|
||||
specifier: 7.2.3
|
||||
version: link:../build-utils
|
||||
'@vercel/routing-utils':
|
||||
specifier: 3.1.0
|
||||
@@ -923,7 +923,7 @@ importers:
|
||||
specifier: 7.3.10
|
||||
version: 7.3.10
|
||||
'@vercel/build-utils':
|
||||
specifier: 7.2.4
|
||||
specifier: 7.2.3
|
||||
version: link:../build-utils
|
||||
jest-junit:
|
||||
specifier: 16.0.0
|
||||
@@ -948,7 +948,7 @@ importers:
|
||||
specifier: 0.25.24
|
||||
version: 0.25.24
|
||||
'@vercel/build-utils':
|
||||
specifier: 7.2.4
|
||||
specifier: 7.2.3
|
||||
version: link:../build-utils
|
||||
'@vercel/routing-utils':
|
||||
specifier: 3.1.0
|
||||
@@ -1015,7 +1015,7 @@ importers:
|
||||
specifier: 2.1.0
|
||||
version: 2.1.0
|
||||
'@vercel/build-utils':
|
||||
specifier: 7.2.4
|
||||
specifier: 7.2.3
|
||||
version: link:../build-utils
|
||||
async-retry:
|
||||
specifier: 1.3.3
|
||||
@@ -1064,7 +1064,7 @@ importers:
|
||||
specifier: 14.18.33
|
||||
version: 14.18.33
|
||||
'@vercel/build-utils':
|
||||
specifier: 7.2.4
|
||||
specifier: 7.2.3
|
||||
version: link:../build-utils
|
||||
execa:
|
||||
specifier: 3.2.0
|
||||
@@ -1125,7 +1125,7 @@ importers:
|
||||
specifier: 3.2.0
|
||||
version: 3.2.0
|
||||
'@vercel/build-utils':
|
||||
specifier: 7.2.4
|
||||
specifier: 7.2.3
|
||||
version: link:../build-utils
|
||||
'@vercel/routing-utils':
|
||||
specifier: 3.1.0
|
||||
@@ -1212,7 +1212,7 @@ importers:
|
||||
specifier: 14.18.33
|
||||
version: 14.18.33
|
||||
'@vercel/build-utils':
|
||||
specifier: 7.2.4
|
||||
specifier: 7.2.3
|
||||
version: link:../build-utils
|
||||
'@vercel/error-utils':
|
||||
specifier: 2.0.2
|
||||
@@ -1321,7 +1321,7 @@ importers:
|
||||
specifier: 3.0.0
|
||||
version: 3.0.0
|
||||
'@vercel/build-utils':
|
||||
specifier: 7.2.4
|
||||
specifier: 7.2.3
|
||||
version: link:../build-utils
|
||||
execa:
|
||||
specifier: ^1.0.0
|
||||
@@ -1358,7 +1358,7 @@ importers:
|
||||
specifier: 6.0.0
|
||||
version: 6.0.0
|
||||
'@vercel/build-utils':
|
||||
specifier: 7.2.4
|
||||
specifier: 7.2.3
|
||||
version: link:../build-utils
|
||||
execa:
|
||||
specifier: 3.2.0
|
||||
@@ -1395,7 +1395,7 @@ importers:
|
||||
specifier: 7.3.13
|
||||
version: 7.3.13
|
||||
'@vercel/build-utils':
|
||||
specifier: 7.2.4
|
||||
specifier: 7.2.3
|
||||
version: link:../build-utils
|
||||
jest-junit:
|
||||
specifier: 16.0.0
|
||||
@@ -1439,7 +1439,7 @@ importers:
|
||||
specifier: 6.0.0
|
||||
version: 6.0.0
|
||||
'@vercel/build-utils':
|
||||
specifier: 7.2.4
|
||||
specifier: 7.2.3
|
||||
version: link:../build-utils
|
||||
execa:
|
||||
specifier: 2.0.4
|
||||
@@ -1460,7 +1460,7 @@ importers:
|
||||
specifier: 1.0.11
|
||||
version: link:../gatsby-plugin-vercel-analytics
|
||||
'@vercel/gatsby-plugin-vercel-builder':
|
||||
specifier: 2.0.10
|
||||
specifier: 2.0.9
|
||||
version: link:../gatsby-plugin-vercel-builder
|
||||
'@vercel/static-config':
|
||||
specifier: 3.0.0
|
||||
@@ -1497,7 +1497,7 @@ importers:
|
||||
specifier: 7.3.13
|
||||
version: 7.3.13
|
||||
'@vercel/build-utils':
|
||||
specifier: 7.2.4
|
||||
specifier: 7.2.3
|
||||
version: link:../build-utils
|
||||
'@vercel/error-utils':
|
||||
specifier: 2.0.2
|
||||
|
||||
13
utils/build.mjs
vendored
13
utils/build.mjs
vendored
@@ -1,7 +1,7 @@
|
||||
import execa from 'execa';
|
||||
import ts from 'typescript';
|
||||
import path from 'node:path';
|
||||
import { build } from 'esbuild';
|
||||
import { build, context } from 'esbuild';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
|
||||
function parseTsConfig(tsconfigPath) {
|
||||
@@ -44,7 +44,7 @@ export async function esbuild(opts = {}, cwd = process.cwd()) {
|
||||
|
||||
let outdir = opts.outfile ? undefined : tsconfig.options.outDir;
|
||||
|
||||
await build({
|
||||
const buildOptions = {
|
||||
entryPoints,
|
||||
format: 'cjs',
|
||||
outdir,
|
||||
@@ -52,7 +52,14 @@ export async function esbuild(opts = {}, cwd = process.cwd()) {
|
||||
target: ts.ScriptTarget[tsconfig.options.target],
|
||||
sourcemap: tsconfig.options.sourceMap,
|
||||
...opts,
|
||||
});
|
||||
};
|
||||
|
||||
if (process.argv.includes('--watch')) {
|
||||
const buildContext = await context({ logLevel: 'info', ...buildOptions });
|
||||
await buildContext.watch();
|
||||
} else {
|
||||
await build(buildOptions);
|
||||
}
|
||||
}
|
||||
|
||||
export async function tsc() {
|
||||
|
||||
Reference in New Issue
Block a user