neonctl 2.4.0 → 2.5.0

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.
@@ -135,7 +135,9 @@ function applyMigrations({ options, appName, connectionString, }) {
135
135
  }
136
136
  }
137
137
  async function deployApp({ props, options, devBranchName, project, appName, environmentVariables, }) {
138
- let { data: { branches }, } = await props.apiClient.listProjectBranches(project.id);
138
+ let { data: { branches }, } = await props.apiClient.listProjectBranches({
139
+ projectId: project.id,
140
+ });
139
141
  branches = branches.filter((branch) => branch.name !== devBranchName);
140
142
  let branchId;
141
143
  if (branches.length === 0) {
@@ -179,14 +179,16 @@ export const handler = (args) => {
179
179
  return args;
180
180
  };
181
181
  const list = async (props) => {
182
- const { data } = await props.apiClient.listProjectBranches(props.projectId);
182
+ const { data } = await props.apiClient.listProjectBranches({
183
+ projectId: props.projectId,
184
+ });
183
185
  writer(props).end(data.branches, {
184
186
  fields: BRANCH_FIELDS,
185
187
  });
186
188
  };
187
189
  const create = async (props) => {
188
190
  const branches = await props.apiClient
189
- .listProjectBranches(props.projectId)
191
+ .listProjectBranches({ projectId: props.projectId })
190
192
  .then(({ data }) => data.branches);
191
193
  const parentProps = (() => {
192
194
  if (!props.parent) {
package/commands/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import * as auth from './auth.js';
2
2
  import * as projects from './projects.js';
3
3
  import * as ipAllow from './ip_allow.js';
4
+ import * as vpcEndpoints from './vpc_endpoints.js';
4
5
  import * as users from './user.js';
5
6
  import * as orgs from './orgs.js';
6
7
  import * as branches from './branches.js';
@@ -16,6 +17,7 @@ export default [
16
17
  orgs,
17
18
  projects,
18
19
  ipAllow,
20
+ vpcEndpoints,
19
21
  branches,
20
22
  databases,
21
23
  roles,
@@ -10,7 +10,7 @@ export const PROJECT_FIELDS = [
10
10
  'region_id',
11
11
  'created_at',
12
12
  ];
13
- const REGIONS = [
13
+ export const REGIONS = [
14
14
  'aws-us-west-2',
15
15
  'aws-ap-southeast-1',
16
16
  'aws-ap-southeast-2',
@@ -64,7 +64,6 @@ const fetchSchema = async (pointInTime, database, props) => {
64
64
  projectId: props.projectId,
65
65
  branchId: pointInTime.branchId,
66
66
  db_name: database.name,
67
- role: database.owner_name,
68
67
  ...pointInTimeParams(pointInTime),
69
68
  })
70
69
  .then((response) => response.data.sql ?? '');
@@ -128,7 +127,9 @@ export const parseSchemaDiffParams = async (props) => {
128
127
  props.baseBranch = props.branch;
129
128
  }
130
129
  else if (props.branch) {
131
- const { data } = await props.apiClient.listProjectBranches(props.projectId);
130
+ const { data } = await props.apiClient.listProjectBranches({
131
+ projectId: props.projectId,
132
+ });
132
133
  const contextBranch = data.branches.find((b) => b.id === props.branch || b.name === props.branch);
133
134
  if (contextBranch?.parent_id == undefined) {
134
135
  throw new Error(`No branch specified. Your context branch (${props.branch}) has no parent, so no comparison is possible.`);
@@ -137,7 +138,9 @@ export const parseSchemaDiffParams = async (props) => {
137
138
  props.compareSource = '^parent';
138
139
  }
139
140
  else {
140
- const { data } = await props.apiClient.listProjectBranches(props.projectId);
141
+ const { data } = await props.apiClient.listProjectBranches({
142
+ projectId: props.projectId,
143
+ });
141
144
  const defaultBranch = data.branches.find((b) => b.default);
142
145
  if (defaultBranch?.parent_id == undefined) {
143
146
  throw new Error('No branch specified. Include a base branch or add a set-context branch to continue. Your default branch has no parent, so no comparison is possible.');
@@ -0,0 +1,134 @@
1
+ import { writer } from '../writer.js';
2
+ import { fillSingleProject, fillSingleOrg } from '../utils/enrichers.js';
3
+ import { REGIONS } from './projects.js';
4
+ import { log } from '../log.js';
5
+ const VPC_ENDPOINT_FIELDS = ['vpc_endpoint_id', 'label'];
6
+ const VPC_ENDPOINT_DETAILS_FIELDS = [
7
+ 'vpc_endpoint_id',
8
+ 'label',
9
+ 'state',
10
+ 'num_restricted_projects',
11
+ 'example_restricted_projects',
12
+ ];
13
+ export const command = 'vpc';
14
+ export const describe = 'Manage VPC endpoints and project VPC restrictions';
15
+ export const builder = (argv) => {
16
+ return argv
17
+ .usage('$0 vpc <sub-command> [options]')
18
+ .command('endpoint', 'Manage VPC endpoints.\n' +
19
+ 'See: https://neon.tech/docs/guides/neon-private-networking\n' +
20
+ 'After adding an endpoint to an organization, client connections will be accepted\n' +
21
+ 'from the corresponding VPC for all projects in the organization, unless overridden\n' +
22
+ 'by a project-level VPC endpoint restriction.', (yargs) => {
23
+ return yargs
24
+ .options({
25
+ 'org-id': {
26
+ describe: 'Organization ID',
27
+ type: 'string',
28
+ },
29
+ 'region-id': {
30
+ describe: `The region ID. Possible values: ${REGIONS.join(', ')}`,
31
+ type: 'string',
32
+ demandOption: true,
33
+ },
34
+ })
35
+ .middleware(fillSingleOrg)
36
+ .command('list', 'List configured VPC endpoints for this organization.', (yargs) => yargs, async (args) => {
37
+ await listOrg(args);
38
+ })
39
+ .command({
40
+ command: 'assign <id>',
41
+ aliases: ['update <id>', 'add <id>'],
42
+ describe: 'Add or update a VPC endpoint for this organization.\n' +
43
+ 'Note: Azure regions are not yet supported.',
44
+ builder: (yargs) => yargs.options({
45
+ label: {
46
+ describe: 'An optional descriptive label for the VPC endpoint',
47
+ type: 'string',
48
+ },
49
+ }),
50
+ handler: async (args) => {
51
+ await assignOrg(args);
52
+ },
53
+ })
54
+ .command('remove <id>', 'Remove a VPC endpoint from this organization.', (yargs) => yargs, async (args) => {
55
+ await removeOrg(args);
56
+ })
57
+ .command('status <id>', 'Get the status of a VPC endpoint for this organization.', (yargs) => yargs, async (args) => {
58
+ await statusOrg(args);
59
+ });
60
+ })
61
+ .command('project', 'Manage project-level VPC endpoint restrictions.\n' +
62
+ 'By default, connections are accepted from any VPC configured at the organization level.\n' +
63
+ 'A project-level VPC endpoint restriction can be used to restrict connections to a specific VPC.', (yargs) => {
64
+ return yargs
65
+ .options({
66
+ 'project-id': {
67
+ describe: 'Project ID',
68
+ type: 'string',
69
+ },
70
+ })
71
+ .middleware(fillSingleProject)
72
+ .command('list', 'List VPC endpoint restrictions for this project.', (yargs) => yargs, async (args) => {
73
+ await listProject(args);
74
+ })
75
+ .command({
76
+ command: 'restrict <id>',
77
+ aliases: ['update <id>'],
78
+ describe: 'Configure or update a VPC endpoint restriction for this project.',
79
+ builder: (yargs) => yargs.options({
80
+ label: {
81
+ describe: 'An optional descriptive label for the VPC endpoint restriction',
82
+ type: 'string',
83
+ },
84
+ }),
85
+ handler: async (args) => {
86
+ await assignProject(args);
87
+ },
88
+ })
89
+ .command('remove <id>', 'Remove a VPC endpoint restriction from this project.', (yargs) => yargs, async (args) => {
90
+ await removeProject(args);
91
+ });
92
+ });
93
+ };
94
+ const listOrg = async (props) => {
95
+ const { data } = await props.apiClient.listOrganizationVpcEndpoints(props.orgId, props.regionId);
96
+ writer(props).end(data.endpoints, {
97
+ fields: VPC_ENDPOINT_FIELDS,
98
+ });
99
+ };
100
+ const assignOrg = async (props) => {
101
+ const vpcEndpointAssignment = {
102
+ label: props.label || '',
103
+ };
104
+ const { data } = await props.apiClient.assignOrganizationVpcEndpoint(props.orgId, props.regionId, props.id, vpcEndpointAssignment);
105
+ writer(props).end(data, { fields: [] });
106
+ if (props.regionId.startsWith('azure')) {
107
+ log.info('VPC endpoint configuration is not supported for Azure regions');
108
+ }
109
+ };
110
+ const removeOrg = async (props) => {
111
+ const { data } = await props.apiClient.deleteOrganizationVpcEndpoint(props.orgId, props.regionId, props.id);
112
+ writer(props).end(data, { fields: [] });
113
+ };
114
+ const statusOrg = async (props) => {
115
+ const { data } = await props.apiClient.getOrganizationVpcEndpointDetails(props.orgId, props.regionId, props.id);
116
+ writer(props).end(data, { fields: VPC_ENDPOINT_DETAILS_FIELDS });
117
+ };
118
+ const listProject = async (props) => {
119
+ const { data } = await props.apiClient.listProjectVpcEndpoints(props.projectId);
120
+ writer(props).end(data.endpoints, {
121
+ fields: VPC_ENDPOINT_FIELDS,
122
+ });
123
+ };
124
+ const assignProject = async (props) => {
125
+ const vpcEndpointAssignment = {
126
+ label: props.label || '',
127
+ };
128
+ const { data } = await props.apiClient.assignProjectVpcEndpoint(props.projectId, props.id, vpcEndpointAssignment);
129
+ writer(props).end(data, { fields: [] });
130
+ };
131
+ const removeProject = async (props) => {
132
+ const { data } = await props.apiClient.deleteProjectVpcEndpoint(props.projectId, props.id);
133
+ writer(props).end(data, { fields: [] });
134
+ };
@@ -0,0 +1,69 @@
1
+ import { describe } from 'vitest';
2
+ import { test } from '../test_utils/fixtures';
3
+ describe('vpc-endpoints', () => {
4
+ test('list org VPC endpoints', async ({ testCliCommand }) => {
5
+ await testCliCommand(['vpc', 'endpoint', 'list', '--org-id', '1', '--region-id', 'test'], { mockDir: 'single_org' });
6
+ });
7
+ test('list org VPC endpoints implicit org', async ({ testCliCommand }) => {
8
+ await testCliCommand(['vpc', 'endpoint', 'list', '--region-id', 'test'], {
9
+ mockDir: 'single_org',
10
+ });
11
+ });
12
+ test('update org VPC endpoint', async ({ testCliCommand }) => {
13
+ await testCliCommand([
14
+ 'vpc',
15
+ 'endpoint',
16
+ 'update',
17
+ 'vpc-test',
18
+ '--label',
19
+ 'newlabel',
20
+ '--region-id',
21
+ 'test',
22
+ ], { mockDir: 'single_org' });
23
+ });
24
+ test('delete org VPC endpoint', async ({ testCliCommand }) => {
25
+ await testCliCommand(['vpc', 'endpoint', 'remove', 'vpc-test', '--region-id', 'test'], { mockDir: 'single_org' });
26
+ });
27
+ test('get org VPC endpoint status', async ({ testCliCommand }) => {
28
+ await testCliCommand(['vpc', 'endpoint', 'status', 'vpc-test', '--region-id', 'test'], { mockDir: 'single_org' });
29
+ });
30
+ test('set org VPC endpoint in azure', async ({ testCliCommand }) => {
31
+ await testCliCommand([
32
+ 'vpc',
33
+ 'endpoint',
34
+ 'update',
35
+ 'vpc-test',
36
+ '--label',
37
+ 'newlabel',
38
+ '--region-id',
39
+ 'azure-test',
40
+ ], {
41
+ mockDir: 'single_org',
42
+ stderr: 'INFO: VPC endpoint configuration is not supported for Azure regions',
43
+ });
44
+ });
45
+ test('list project VPC endpoint restrictions', async ({ testCliCommand }) => {
46
+ await testCliCommand([
47
+ 'vpc',
48
+ 'project',
49
+ 'list',
50
+ '--region-id',
51
+ 'test',
52
+ '--project-id',
53
+ 'test-project-123456',
54
+ ], { mockDir: 'single_org' });
55
+ });
56
+ test('list project VPC endpoint restrictions with implicit project', async ({ testCliCommand, }) => {
57
+ await testCliCommand(['vpc', 'project', 'list', '--region-id', 'test'], {
58
+ mockDir: 'single_org',
59
+ });
60
+ });
61
+ test('set project VPC endpoint restrictions', async ({ testCliCommand }) => {
62
+ await testCliCommand(['vpc', 'project', 'update', 'vpc-test', '--label', 'newlabel'], { mockDir: 'single_org' });
63
+ });
64
+ test('delete project VPC endpoint restrictions', async ({ testCliCommand, }) => {
65
+ await testCliCommand(['vpc', 'project', 'remove', 'vpc-test'], {
66
+ mockDir: 'single_org',
67
+ });
68
+ });
69
+ });
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "url": "git+ssh://git@github.com/neondatabase/neonctl.git"
6
6
  },
7
7
  "type": "module",
8
- "version": "2.4.0",
8
+ "version": "2.5.0",
9
9
  "description": "CLI tool for NeonDB Cloud management",
10
10
  "main": "index.js",
11
11
  "author": "NeonDB",
@@ -54,7 +54,7 @@
54
54
  "vitest": "^1.6.0"
55
55
  },
56
56
  "dependencies": {
57
- "@neondatabase/api-client": "^1.10.0",
57
+ "@neondatabase/api-client": "1.11.2",
58
58
  "@segment/analytics-node": "^1.0.0-beta.26",
59
59
  "axios": "^1.4.0",
60
60
  "axios-debug-log": "^1.0.0",
package/parameters.gen.js CHANGED
@@ -35,14 +35,34 @@ export const projectCreateRequest = {
35
35
  description: "If true, the list will be applied only to protected branches.",
36
36
  demandOption: false,
37
37
  },
38
- 'project.settings.allowed_ips.primary_branch_only': {
38
+ 'project.settings.enable_logical_replication': {
39
39
  type: "boolean",
40
- description: "DEPRECATED: Use `protected_branches_only`.\nIf true, the list will be applied only to the default branch.\n",
40
+ description: "Sets wal_level=logical for all compute endpoints in this project.\nAll active endpoints will be suspended.\nOnce enabled, logical replication cannot be disabled.\n",
41
41
  demandOption: false,
42
42
  },
43
- 'project.settings.enable_logical_replication': {
43
+ 'project.settings.maintenance_window.weekdays': {
44
+ type: "array",
45
+ description: "A list of weekdays when the maintenance window is active.\nEncoded as ints, where 1 - Monday, and 7 - Sunday.\n",
46
+ demandOption: true,
47
+ },
48
+ 'project.settings.maintenance_window.start_time': {
49
+ type: "string",
50
+ description: "Start time of the maintenance window, in the format of \"HH:MM\". Uses UTC.\n",
51
+ demandOption: true,
52
+ },
53
+ 'project.settings.maintenance_window.end_time': {
54
+ type: "string",
55
+ description: "End time of the maintenance window, in the format of \"HH:MM\". Uses UTC.\n",
56
+ demandOption: true,
57
+ },
58
+ 'project.settings.block_public_connections': {
44
59
  type: "boolean",
45
- description: "Sets wal_level=logical for all compute endpoints in this project.\nAll active endpoints will be suspended.\nOnce enabled, logical replication cannot be disabled.\n",
60
+ description: "When set, connections from the public internet\nare disallowed. This supersedes the AllowedIPs list.\nThis parameter is under active development and its semantics may change in the future.\n",
61
+ demandOption: false,
62
+ },
63
+ 'project.settings.block_vpc_connections': {
64
+ type: "boolean",
65
+ description: "When set, connections using VPC endpoints are disallowed.\nThis parameter is under active development and its semantics may change in the future.\n",
46
66
  demandOption: false,
47
67
  },
48
68
  'project.name': {
@@ -52,24 +72,23 @@ export const projectCreateRequest = {
52
72
  },
53
73
  'project.branch.name': {
54
74
  type: "string",
55
- description: "The branch name. If not specified, the default branch name will be used.\n",
75
+ description: "The default branch name. If not specified, the default branch name, `main`, will be used.\n",
56
76
  demandOption: false,
57
77
  },
58
78
  'project.branch.role_name': {
59
79
  type: "string",
60
- description: "The role name. If not specified, the default role name will be used.\n",
80
+ description: "The role name. If not specified, the default role name, `{database_name}_owner`, will be used.\n",
61
81
  demandOption: false,
62
82
  },
63
83
  'project.branch.database_name': {
64
84
  type: "string",
65
- description: "The database name. If not specified, the default database name will be used.\n",
85
+ description: "The database name. If not specified, the default database name, `neondb`, will be used.\n",
66
86
  demandOption: false,
67
87
  },
68
88
  'project.provisioner': {
69
89
  type: "string",
70
- description: "The Neon compute provisioner.\nSpecify the `k8s-neonvm` provisioner to create a compute endpoint that supports Autoscaling.\n",
90
+ description: "The Neon compute provisioner.\nSpecify the `k8s-neonvm` provisioner to create a compute endpoint that supports Autoscaling.\n\nProvisioner can be one of the following values:\n* k8s-pod\n* k8s-neonvm\n\nClients must expect, that any string value that is not documented in the description above should be treated as a error. UNKNOWN value if safe to treat as an error too.\n",
71
91
  demandOption: false,
72
- choices: ["k8s-pod", "k8s-neonvm"],
73
92
  },
74
93
  'project.region_id': {
75
94
  type: "string",
@@ -83,7 +102,7 @@ export const projectCreateRequest = {
83
102
  },
84
103
  'project.pg_version': {
85
104
  type: "number",
86
- description: "The major Postgres version number. Currently supported versions are `14`, `15`, and `16`.",
105
+ description: "The major Postgres version number. Currently supported versions are `14`, `15`, `16`, and `17`.",
87
106
  demandOption: false,
88
107
  },
89
108
  'project.store_passwords': {
@@ -93,7 +112,7 @@ export const projectCreateRequest = {
93
112
  },
94
113
  'project.history_retention_seconds': {
95
114
  type: "number",
96
- description: "The number of seconds to retain the point-in-time restore (PITR) backup history for this project.\nThe default is 604800 seconds (7 days).\n",
115
+ description: "The number of seconds to retain the shared history for all branches in this project.\nThe default is 1 day (86400 seconds).\n",
97
116
  demandOption: false,
98
117
  },
99
118
  'project.org_id': {
@@ -138,14 +157,34 @@ export const projectUpdateRequest = {
138
157
  description: "If true, the list will be applied only to protected branches.",
139
158
  demandOption: false,
140
159
  },
141
- 'project.settings.allowed_ips.primary_branch_only': {
160
+ 'project.settings.enable_logical_replication': {
142
161
  type: "boolean",
143
- description: "DEPRECATED: Use `protected_branches_only`.\nIf true, the list will be applied only to the default branch.\n",
162
+ description: "Sets wal_level=logical for all compute endpoints in this project.\nAll active endpoints will be suspended.\nOnce enabled, logical replication cannot be disabled.\n",
144
163
  demandOption: false,
145
164
  },
146
- 'project.settings.enable_logical_replication': {
165
+ 'project.settings.maintenance_window.weekdays': {
166
+ type: "array",
167
+ description: "A list of weekdays when the maintenance window is active.\nEncoded as ints, where 1 - Monday, and 7 - Sunday.\n",
168
+ demandOption: true,
169
+ },
170
+ 'project.settings.maintenance_window.start_time': {
171
+ type: "string",
172
+ description: "Start time of the maintenance window, in the format of \"HH:MM\". Uses UTC.\n",
173
+ demandOption: true,
174
+ },
175
+ 'project.settings.maintenance_window.end_time': {
176
+ type: "string",
177
+ description: "End time of the maintenance window, in the format of \"HH:MM\". Uses UTC.\n",
178
+ demandOption: true,
179
+ },
180
+ 'project.settings.block_public_connections': {
147
181
  type: "boolean",
148
- description: "Sets wal_level=logical for all compute endpoints in this project.\nAll active endpoints will be suspended.\nOnce enabled, logical replication cannot be disabled.\n",
182
+ description: "When set, connections from the public internet\nare disallowed. This supersedes the AllowedIPs list.\nThis parameter is under active development and its semantics may change in the future.\n",
183
+ demandOption: false,
184
+ },
185
+ 'project.settings.block_vpc_connections': {
186
+ type: "boolean",
187
+ description: "When set, connections using VPC endpoints are disallowed.\nThis parameter is under active development and its semantics may change in the future.\n",
149
188
  demandOption: false,
150
189
  },
151
190
  'project.name': {
@@ -160,7 +199,7 @@ export const projectUpdateRequest = {
160
199
  },
161
200
  'project.history_retention_seconds': {
162
201
  type: "number",
163
- description: "The number of seconds to retain the point-in-time restore (PITR) backup history for this project.\nThe default is 604800 seconds (7 days).\n",
202
+ description: "The number of seconds to retain the shared history for all branches in this project.\nThe default is 1 day (604800 seconds).\n",
164
203
  demandOption: false,
165
204
  },
166
205
  };
@@ -195,6 +234,17 @@ export const branchCreateRequest = {
195
234
  description: "Whether the branch is protected\n",
196
235
  demandOption: false,
197
236
  },
237
+ 'branch.archived': {
238
+ type: "boolean",
239
+ description: "Whether to create the branch as archived\n",
240
+ demandOption: false,
241
+ },
242
+ 'branch.schema_initialization_type': {
243
+ type: "string",
244
+ description: "The type of schema initialization. Defines how the schema is initialized, currently only empty is supported. This parameter is under\nactive development and may change its semantics in the future.\n",
245
+ demandOption: false,
246
+ choices: ["empty"],
247
+ },
198
248
  };
199
249
  export const branchCreateRequestEndpointOptions = {
200
250
  'type': {
@@ -205,9 +255,8 @@ export const branchCreateRequestEndpointOptions = {
205
255
  },
206
256
  'provisioner': {
207
257
  type: "string",
208
- description: "The Neon compute provisioner.\nSpecify the `k8s-neonvm` provisioner to create a compute endpoint that supports Autoscaling.\n",
258
+ description: "The Neon compute provisioner.\nSpecify the `k8s-neonvm` provisioner to create a compute endpoint that supports Autoscaling.\n\nProvisioner can be one of the following values:\n* k8s-pod\n* k8s-neonvm\n\nClients must expect, that any string value that is not documented in the description above should be treated as a error. UNKNOWN value if safe to treat as an error too.\n",
209
259
  demandOption: false,
210
- choices: ["k8s-pod", "k8s-neonvm"],
211
260
  },
212
261
  'suspend_timeout_seconds': {
213
262
  type: "number",
@@ -246,9 +295,8 @@ export const endpointCreateRequest = {
246
295
  },
247
296
  'endpoint.provisioner': {
248
297
  type: "string",
249
- description: "The Neon compute provisioner.\nSpecify the `k8s-neonvm` provisioner to create a compute endpoint that supports Autoscaling.\n",
298
+ description: "The Neon compute provisioner.\nSpecify the `k8s-neonvm` provisioner to create a compute endpoint that supports Autoscaling.\n\nProvisioner can be one of the following values:\n* k8s-pod\n* k8s-neonvm\n\nClients must expect, that any string value that is not documented in the description above should be treated as a error. UNKNOWN value if safe to treat as an error too.\n",
250
299
  demandOption: false,
251
- choices: ["k8s-pod", "k8s-neonvm"],
252
300
  },
253
301
  'endpoint.pooler_enabled': {
254
302
  type: "boolean",
@@ -280,14 +328,13 @@ export const endpointCreateRequest = {
280
328
  export const endpointUpdateRequest = {
281
329
  'endpoint.branch_id': {
282
330
  type: "string",
283
- description: "The destination branch ID. The destination branch must not have an exsiting read-write endpoint.\n",
331
+ description: "DEPRECATED: This field will be removed in a future release.\nThe destination branch ID. The destination branch must not have an exsiting read-write endpoint.\n",
284
332
  demandOption: false,
285
333
  },
286
334
  'endpoint.provisioner': {
287
335
  type: "string",
288
- description: "The Neon compute provisioner.\nSpecify the `k8s-neonvm` provisioner to create a compute endpoint that supports Autoscaling.\n",
336
+ description: "The Neon compute provisioner.\nSpecify the `k8s-neonvm` provisioner to create a compute endpoint that supports Autoscaling.\n\nProvisioner can be one of the following values:\n* k8s-pod\n* k8s-neonvm\n\nClients must expect, that any string value that is not documented in the description above should be treated as a error. UNKNOWN value if safe to treat as an error too.\n",
289
337
  demandOption: false,
290
- choices: ["k8s-pod", "k8s-neonvm"],
291
338
  },
292
339
  'endpoint.pooler_enabled': {
293
340
  type: "boolean",
@@ -4,7 +4,9 @@ export const branchIdResolve = async ({ branch, apiClient, projectId, }) => {
4
4
  if (looksLikeBranchId(branch)) {
5
5
  return branch;
6
6
  }
7
- const { data } = await apiClient.listProjectBranches(projectId);
7
+ const { data } = await apiClient.listProjectBranches({
8
+ projectId,
9
+ });
8
10
  const branchData = data.branches.find((b) => b.name === branch);
9
11
  if (!branchData) {
10
12
  throw new Error(`Branch ${branch} not found.\nAvailable branches: ${data.branches
@@ -24,7 +26,9 @@ export const branchIdFromProps = async (props) => {
24
26
  projectId: props.projectId,
25
27
  });
26
28
  }
27
- const { data } = await props.apiClient.listProjectBranches(props.projectId);
29
+ const { data } = await props.apiClient.listProjectBranches({
30
+ projectId: props.projectId,
31
+ });
28
32
  const defaultBranch = data.branches.find((b) => b.default);
29
33
  if (defaultBranch) {
30
34
  return defaultBranch.id;
@@ -47,3 +51,16 @@ export const fillSingleProject = async (props) => {
47
51
  projectId: data.projects[0].id,
48
52
  };
49
53
  };
54
+ export const fillSingleOrg = async (props) => {
55
+ if (props.orgId) {
56
+ return props;
57
+ }
58
+ const { data } = await props.apiClient.getCurrentUserOrganizations();
59
+ if (data.organizations.length === 0) {
60
+ throw new Error('No organizations found');
61
+ }
62
+ if (data.organizations.length > 1) {
63
+ throw new Error(`Multiple organizations found, please provide one with the --org-id option`);
64
+ }
65
+ return { ...props, orgId: data.organizations[0].id };
66
+ };