1 | "use strict";
|
2 | var __importDefault = (this && this.__importDefault) || function (mod) {
|
3 | return (mod && mod.__esModule) ? mod : { "default": mod };
|
4 | };
|
5 | Object.defineProperty(exports, "__esModule", { value: true });
|
6 | const node_fetch_1 = __importDefault(require("node-fetch"));
|
7 | const crypto_1 = require("crypto");
|
8 | class VercelClient {
|
9 | constructor(options) {
|
10 | this.options = options;
|
11 | }
|
12 | fetch(path, options = {}) {
|
13 | let apiPath = `https://vercel.com/api${path}`;
|
14 | if (this.options.teamId) {
|
15 | const e = encodeURIComponent;
|
16 | apiPath = apiPath.includes('?')
|
17 | ? `${apiPath}&teamId=${e(this.options.teamId)}`
|
18 | : `${apiPath}?teamId=${e(this.options.teamId)}`;
|
19 | }
|
20 | options.headers = options.headers || {
|
21 | Authorization: `Bearer ${this.options.token}`
|
22 | };
|
23 | if (options.data) {
|
24 | options.headers = {
|
25 | ...options.headers,
|
26 | 'Content-Type': 'application/json'
|
27 | };
|
28 | options.body = JSON.stringify(options.data);
|
29 | }
|
30 | return node_fetch_1.default(apiPath, options);
|
31 | }
|
32 | async fetchAndThrow(path, options) {
|
33 | const res = await this.fetch(path, options);
|
34 | if (res.status !== 200) {
|
35 | throw new Error(`Failed Vercel API call. path: ${path} status: ${res.status} error: ${await res.text()}`);
|
36 | }
|
37 | return res.json();
|
38 | }
|
39 | getMetadata() {
|
40 | const metadataApiEndpoint = `/v1/integrations/configuration/${this.options.configurationId}/metadata`;
|
41 | return this.fetchAndThrow(metadataApiEndpoint, { method: 'GET' });
|
42 | }
|
43 | setMetadata(data) {
|
44 | const metadataApiEndpoint = `/v1/integrations/configuration/${this.options.configurationId}/metadata`;
|
45 | return this.fetchAndThrow(metadataApiEndpoint, {
|
46 | method: 'POST',
|
47 | data
|
48 | });
|
49 | }
|
50 | async ensureSecret(namePrefix, value) {
|
51 | const hash = crypto_1.createHash('sha1')
|
52 | .update(value)
|
53 | .digest('hex');
|
54 | const name = `${namePrefix}-${hash.substring(0, 10)}`;
|
55 | const apiRes = await this.fetch(`/v2/now/secrets`, {
|
56 | method: 'POST',
|
57 | data: { name, value }
|
58 | });
|
59 | if (apiRes.status === 200 || apiRes.status === 409) {
|
60 | return name;
|
61 | }
|
62 | throw new Error(`Error when adding a secret: [${apiRes.status}] ${await apiRes.text()}`);
|
63 | }
|
64 | async upsertEnv(projectId, name, secretName) {
|
65 | const createRes = await this.fetch(`/v1/projects/${projectId}/env`, {
|
66 | method: 'POST',
|
67 | data: {
|
68 | key: name,
|
69 | value: `@${secretName}`
|
70 | }
|
71 | });
|
72 | if (createRes.status !== 200) {
|
73 | throw new Error(`Error when adding an env: [${createRes.status}] ${await createRes.text()}`);
|
74 | }
|
75 | }
|
76 | async removeEnv(projectId, name) {
|
77 | const deleteRes = await this.fetch(`/v1/projects/${projectId}/env/${name}`, { method: 'DELETE' });
|
78 | if (deleteRes.status !== 200 && deleteRes.status !== 404) {
|
79 | throw new Error(`Error when deleting an env: [${deleteRes.status}] ${await deleteRes.text()}`);
|
80 | }
|
81 | }
|
82 | async addConfigurationToProject(projectId) {
|
83 | const configId = this.options.configurationId;
|
84 | const addConfigRes = await this.fetch(`/projects/${projectId}/configuration?configId=${configId}`, {
|
85 | method: 'POST'
|
86 | });
|
87 | if (addConfigRes.status !== 200) {
|
88 | throw new Error(`Error adding configuration to project: [${addConfigRes.status}] ${await addConfigRes.text()}`);
|
89 | }
|
90 | }
|
91 | async removeConfigurationFromProject(projectId) {
|
92 | const configId = this.options.configurationId;
|
93 | const removeProjectRes = await this.fetch(`/projects/${projectId}/configuration?configId=${configId}`, {
|
94 | method: 'DELETE'
|
95 | });
|
96 | if (removeProjectRes.status !== 200) {
|
97 | throw new Error(`Error removing configuration from project: [${removeProjectRes.status}] ${await removeProjectRes.text()}`);
|
98 | }
|
99 | }
|
100 | }
|
101 | exports.default = VercelClient;
|