UNPKG

7.91 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3const command_1 = require("@heroku-cli/command");
4const deps_1 = require("@heroku-cli/command/lib/deps");
5const git_1 = require("@heroku-cli/command/lib/git");
6const flatten = require("lodash.flatten");
7const path = require("path");
8exports.oneDay = 60 * 60 * 24;
9class CompletionLookup {
10 constructor(cmdId, name, description) {
11 this.cmdId = cmdId;
12 this.name = name;
13 this.description = description;
14 this.blacklistMap = {
15 app: ['apps:create'],
16 space: ['spaces:create'],
17 };
18 this.keyAliasMap = {
19 key: {
20 'config:get': 'config',
21 },
22 };
23 this.commandArgsMap = {
24 key: {
25 'config:set': 'configSet',
26 }
27 };
28 }
29 get key() {
30 return this.argAlias() || this.keyAlias() || this.descriptionAlias() || this.name;
31 }
32 run() {
33 if (this.blacklisted())
34 return;
35 return exports.CompletionMapping[this.key];
36 }
37 argAlias() {
38 return this.commandArgsMap[this.name] && this.commandArgsMap[this.name][this.cmdId];
39 }
40 keyAlias() {
41 return this.keyAliasMap[this.name] && this.keyAliasMap[this.name][this.cmdId];
42 }
43 descriptionAlias() {
44 const d = this.description;
45 if (d.match(/^dyno size/))
46 return 'dynosize';
47 if (d.match(/^process type/))
48 return 'processtype';
49 }
50 blacklisted() {
51 return this.blacklistMap[this.name] && this.blacklistMap[this.name].includes(this.cmdId);
52 }
53}
54exports.CompletionLookup = CompletionLookup;
55exports.herokuGet = async (resource, ctx) => {
56 const heroku = new command_1.APIClient(ctx.config);
57 let { body } = await heroku.get(`/${resource}`, { retryAuth: false });
58 if (typeof body === 'string')
59 body = JSON.parse(body);
60 return body.map((a) => a.name).sort();
61};
62exports.AppCompletion = {
63 cacheDuration: exports.oneDay,
64 options: async (ctx) => {
65 const teams = await exports.herokuGet('teams', ctx);
66 let apps = {
67 personal: await exports.herokuGet('users/~/apps', ctx),
68 teams: flatten(await Promise.all(teams.map((team) => exports.herokuGet(`teams/${team}/apps`, ctx)))),
69 };
70 return apps.personal.concat(apps.teams);
71 },
72};
73exports.AppAddonCompletion = {
74 cacheDuration: exports.oneDay,
75 cacheKey: async (ctx) => {
76 return ctx.flags && ctx.flags.app ? `${ctx.flags.app}_addons` : '';
77 },
78 options: async (ctx) => {
79 let addons = ctx.flags && ctx.flags.app ? await exports.herokuGet(`apps/${ctx.flags.app}/addons`, ctx) : [];
80 return addons;
81 },
82};
83exports.AppDynoCompletion = {
84 cacheDuration: exports.oneDay,
85 cacheKey: async (ctx) => {
86 return ctx.flags && ctx.flags.app ? `${ctx.flags.app}_dynos` : '';
87 },
88 options: async (ctx) => {
89 let dynos = ctx.flags && ctx.flags.app ? await exports.herokuGet(`apps/${ctx.flags.app}/dynos`, ctx) : [];
90 return dynos;
91 },
92};
93exports.BuildpackCompletion = {
94 skipCache: true,
95 options: async () => {
96 return [
97 'heroku/ruby',
98 'heroku/nodejs',
99 'heroku/clojure',
100 'heroku/python',
101 'heroku/java',
102 'heroku/gradle',
103 'heroku/scala',
104 'heroku/php',
105 'heroku/go',
106 ];
107 },
108};
109const ConfigCompletion = {
110 cacheDuration: 60 * 60 * 24 * 7,
111 cacheKey: async (ctx) => {
112 return ctx.flags && ctx.flags.app ? `${ctx.flags.app}_config_vars` : '';
113 },
114 options: async (ctx) => {
115 const heroku = new command_1.APIClient(ctx.config);
116 if (ctx.flags && ctx.flags.app) {
117 let { body: configs } = await heroku.get(`/apps/${ctx.flags.app}/config-vars`, { retryAuth: false });
118 return Object.keys(configs);
119 }
120 return [];
121 },
122};
123const ConfigSetCompletion = {
124 cacheDuration: 60 * 60 * 24 * 7,
125 cacheKey: async (ctx) => {
126 return ctx.flags && ctx.flags.app ? `${ctx.flags.app}_config_set_vars` : '';
127 },
128 options: async (ctx) => {
129 const heroku = new command_1.APIClient(ctx.config);
130 if (ctx.flags && ctx.flags.app) {
131 let { body: configs } = await heroku.get(`/apps/${ctx.flags.app}/config-vars`, { retryAuth: false });
132 return Object.keys(configs).map(k => `${k}=`);
133 }
134 return [];
135 },
136};
137exports.DynoSizeCompletion = {
138 cacheDuration: exports.oneDay * 90,
139 options: async (ctx) => {
140 let sizes = await exports.herokuGet('dyno-sizes', ctx);
141 return sizes;
142 },
143};
144exports.FileCompletion = {
145 skipCache: true,
146 options: async () => {
147 let files = await deps_1.deps.file.readdir(process.cwd());
148 return files;
149 },
150};
151exports.PipelineCompletion = {
152 cacheDuration: exports.oneDay,
153 options: async (ctx) => {
154 let pipelines = await exports.herokuGet('pipelines', ctx);
155 return pipelines;
156 },
157};
158exports.ProcessTypeCompletion = {
159 skipCache: true,
160 options: async () => {
161 let types = [];
162 let procfile = path.join(process.cwd(), 'Procfile');
163 try {
164 let buff = await deps_1.deps.file.readFile(procfile);
165 types = buff
166 .toString()
167 .split('\n')
168 .map(s => {
169 if (!s)
170 return false;
171 let m = s.match(/^([A-Za-z0-9_-]+)/);
172 return m ? m[0] : false;
173 })
174 .filter(t => t);
175 }
176 catch (err) {
177 if (err.code !== 'ENOENT')
178 throw err;
179 }
180 return types;
181 },
182};
183exports.RegionCompletion = {
184 cacheDuration: exports.oneDay * 7,
185 options: async (ctx) => {
186 let regions = await exports.herokuGet('regions', ctx);
187 return regions;
188 },
189};
190exports.RemoteCompletion = {
191 skipCache: true,
192 options: async () => {
193 let remotes = git_1.getGitRemotes(git_1.configRemote());
194 return remotes.map(r => r.remote);
195 },
196};
197exports.RoleCompletion = {
198 skipCache: true,
199 options: async () => {
200 return ['admin', 'collaborator', 'member', 'owner'];
201 },
202};
203exports.ScopeCompletion = {
204 skipCache: true,
205 options: async () => {
206 return ['global', 'identity', 'read', 'write', 'read-protected', 'write-protected'];
207 },
208};
209exports.SpaceCompletion = {
210 cacheDuration: exports.oneDay,
211 options: async (ctx) => {
212 let spaces = await exports.herokuGet('spaces', ctx);
213 return spaces;
214 },
215};
216exports.StackCompletion = {
217 cacheDuration: exports.oneDay,
218 options: async (ctx) => {
219 let stacks = await exports.herokuGet('stacks', ctx);
220 return stacks;
221 },
222};
223exports.StageCompletion = {
224 skipCache: true,
225 options: async () => {
226 return ['test', 'review', 'development', 'staging', 'production'];
227 },
228};
229exports.TeamCompletion = {
230 cacheDuration: exports.oneDay,
231 options: async (ctx) => {
232 let teams = await exports.herokuGet('teams', ctx);
233 return teams;
234 },
235};
236exports.CompletionMapping = {
237 app: exports.AppCompletion,
238 addon: exports.AppAddonCompletion,
239 dyno: exports.AppDynoCompletion,
240 buildpack: exports.BuildpackCompletion,
241 config: ConfigCompletion,
242 configSet: ConfigSetCompletion,
243 dynosize: exports.DynoSizeCompletion,
244 pipeline: exports.PipelineCompletion,
245 processtype: exports.ProcessTypeCompletion,
246 region: exports.RegionCompletion,
247 remote: exports.RemoteCompletion,
248 role: exports.RoleCompletion,
249 scope: exports.ScopeCompletion,
250 space: exports.SpaceCompletion,
251 stack: exports.StackCompletion,
252 stage: exports.StageCompletion,
253 team: exports.TeamCompletion,
254};