neonctl 2.9.2 → 2.10.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/commands/projects.js +73 -2
- package/package.json +1 -1
package/commands/projects.js
CHANGED
|
@@ -4,6 +4,9 @@ import { writer } from '../writer.js';
|
|
|
4
4
|
import { psql } from '../utils/psql.js';
|
|
5
5
|
import { updateContextFile } from '../context.js';
|
|
6
6
|
import { getComputeUnits } from '../utils/compute_units.js';
|
|
7
|
+
import { isAxiosError } from 'axios';
|
|
8
|
+
import prompts from 'prompts';
|
|
9
|
+
import { isCi } from '../env.js';
|
|
7
10
|
export const PROJECT_FIELDS = [
|
|
8
11
|
'id',
|
|
9
12
|
'name',
|
|
@@ -36,7 +39,7 @@ export const builder = (argv) => {
|
|
|
36
39
|
type: 'string',
|
|
37
40
|
},
|
|
38
41
|
}), async (args) => {
|
|
39
|
-
await
|
|
42
|
+
await handleMissingOrgId(args, list);
|
|
40
43
|
})
|
|
41
44
|
.command('create', 'Create a project', (yargs) => yargs.options({
|
|
42
45
|
'block-public-connections': {
|
|
@@ -84,7 +87,7 @@ export const builder = (argv) => {
|
|
|
84
87
|
type: 'string',
|
|
85
88
|
},
|
|
86
89
|
}), async (args) => {
|
|
87
|
-
await
|
|
90
|
+
await handleMissingOrgId(args, create);
|
|
88
91
|
})
|
|
89
92
|
.command('update <id>', 'Update a project', (yargs) => yargs.options({
|
|
90
93
|
'block-vpc-connections': {
|
|
@@ -252,3 +255,71 @@ const get = async (props) => {
|
|
|
252
255
|
const { data } = await props.apiClient.getProject(props.id);
|
|
253
256
|
writer(props).end(data.project, { fields: PROJECT_FIELDS });
|
|
254
257
|
};
|
|
258
|
+
const handleMissingOrgId = async (args, cmd) => {
|
|
259
|
+
try {
|
|
260
|
+
await cmd(args);
|
|
261
|
+
}
|
|
262
|
+
catch (err) {
|
|
263
|
+
if (!isCi() && isOrgIdError(err)) {
|
|
264
|
+
const orgId = await selectOrg(args);
|
|
265
|
+
await cmd({ ...args, orgId });
|
|
266
|
+
}
|
|
267
|
+
else {
|
|
268
|
+
throw err;
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
};
|
|
272
|
+
const isOrgIdError = (err) => {
|
|
273
|
+
return (isAxiosError(err) &&
|
|
274
|
+
err.response?.status == 400 &&
|
|
275
|
+
err.response?.data?.message?.includes('org_id is required'));
|
|
276
|
+
};
|
|
277
|
+
const selectOrg = async (props) => {
|
|
278
|
+
const { data: { organizations }, } = await props.apiClient.getCurrentUserOrganizations();
|
|
279
|
+
if (!organizations?.length) {
|
|
280
|
+
throw new Error(`You don't belong to any organizations. Please create an organization first.`);
|
|
281
|
+
}
|
|
282
|
+
const { orgId } = await prompts({
|
|
283
|
+
onState: onPromptState,
|
|
284
|
+
type: 'select',
|
|
285
|
+
name: 'orgId',
|
|
286
|
+
message: `What organization would you like to use?`,
|
|
287
|
+
choices: organizations.map((org) => ({
|
|
288
|
+
title: `${org.name} (${org.id})`,
|
|
289
|
+
value: org.id,
|
|
290
|
+
})),
|
|
291
|
+
initial: 0,
|
|
292
|
+
});
|
|
293
|
+
const { save } = await prompts({
|
|
294
|
+
onState: onPromptState,
|
|
295
|
+
type: 'confirm',
|
|
296
|
+
name: 'save',
|
|
297
|
+
message: `Would you like to use this organization by default?`,
|
|
298
|
+
initial: true,
|
|
299
|
+
});
|
|
300
|
+
if (save) {
|
|
301
|
+
updateContextFile(props.contextFile, { orgId });
|
|
302
|
+
writer(props).text(`
|
|
303
|
+
The organization ID has been saved in ${props.contextFile}
|
|
304
|
+
|
|
305
|
+
If you'd like to change the default organization later, use
|
|
306
|
+
|
|
307
|
+
neonctl set-context --org-id <org_id>
|
|
308
|
+
|
|
309
|
+
Or to clear the context file and forget the default organization
|
|
310
|
+
|
|
311
|
+
neonctl set-context
|
|
312
|
+
|
|
313
|
+
`);
|
|
314
|
+
}
|
|
315
|
+
return orgId;
|
|
316
|
+
};
|
|
317
|
+
const onPromptState = (state) => {
|
|
318
|
+
if (state.aborted) {
|
|
319
|
+
// If we don't re-enable the terminal cursor before exiting
|
|
320
|
+
// the program, the cursor will remain hidden
|
|
321
|
+
process.stdout.write('\x1B[?25h');
|
|
322
|
+
process.stdout.write('\n');
|
|
323
|
+
process.exit(1);
|
|
324
|
+
}
|
|
325
|
+
};
|