neonctl 2.18.1 → 2.19.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.
@@ -1,4 +1,4 @@
1
- import { EndpointType } from '@neondatabase/api-client';
1
+ import { EndpointType, } from '@neondatabase/api-client';
2
2
  import { branchIdFromProps, fillSingleProject } from '../utils/enrichers.js';
3
3
  import { writer } from '../writer.js';
4
4
  import { psql } from '../utils/psql.js';
@@ -38,6 +38,10 @@ export const builder = (argv) => {
38
38
  describe: 'List projects of a given organization',
39
39
  type: 'string',
40
40
  },
41
+ 'recoverable-only': {
42
+ describe: 'List only deleted projects within their deletion grace period',
43
+ type: 'boolean',
44
+ },
41
45
  }), async (args) => {
42
46
  await handleMissingOrgId(args, list);
43
47
  })
@@ -123,6 +127,9 @@ export const builder = (argv) => {
123
127
  })
124
128
  .command('delete <id>', 'Delete a project', (yargs) => yargs, async (args) => {
125
129
  await deleteProject(args);
130
+ })
131
+ .command('recover <id>', 'Recovers a deleted project during the deletion grace period', (yargs) => yargs, async (args) => {
132
+ await recover(args);
126
133
  })
127
134
  .command('get <id>', 'Get a project', (yargs) => yargs, async (args) => {
128
135
  await get(args);
@@ -140,6 +147,7 @@ const list = async (props) => {
140
147
  const { data } = await fn({
141
148
  limit: PROJECTS_LIST_LIMIT,
142
149
  org_id: props.orgId,
150
+ recoverable: props.recoverableOnly,
143
151
  cursor,
144
152
  });
145
153
  result.push(...data.projects);
@@ -152,16 +160,21 @@ const list = async (props) => {
152
160
  return result;
153
161
  };
154
162
  const ownedProjects = await getList(props.apiClient.listProjects);
155
- const sharedProjects = props.orgId
163
+ const sharedProjects = props.orgId || props.recoverableOnly
156
164
  ? []
157
165
  : await getList(props.apiClient.listSharedProjects);
158
166
  const out = writer(props);
159
167
  out.write(ownedProjects, {
160
- fields: PROJECT_FIELDS,
168
+ fields: props.recoverableOnly
169
+ ? [...PROJECT_FIELDS, 'deleted_at', 'recoverable_until']
170
+ : PROJECT_FIELDS,
161
171
  title: 'Projects',
162
- emptyMessage: "You don't have any projects yet. See how to create a new project:\n> neonctl projects create --help",
172
+ emptyMessage: props.recoverableOnly
173
+ ? "You don't have any recoverable projects."
174
+ : "You don't have any projects yet. See how to create a new project:\n> neon projects create --help",
163
175
  });
164
- if (!props.orgId) {
176
+ if (!props.orgId && !props.recoverableOnly) {
177
+ // We don't list shared projects when listing recoverable projects
165
178
  out.write(sharedProjects, {
166
179
  fields: PROJECT_FIELDS,
167
180
  title: 'Shared with you',
@@ -271,6 +284,10 @@ const update = async (props) => {
271
284
  });
272
285
  writer(props).end(data.project, { fields: PROJECT_FIELDS });
273
286
  };
287
+ const recover = async (props) => {
288
+ const { data } = await props.apiClient.recoverProject(props.id);
289
+ writer(props).end(data.project, { fields: PROJECT_FIELDS });
290
+ };
274
291
  const get = async (props) => {
275
292
  const { data } = await props.apiClient.getProject(props.id);
276
293
  writer(props).end(data.project, { fields: PROJECT_FIELDS });
@@ -10,6 +10,9 @@ describe('projects', () => {
10
10
  test('list with org id', async ({ testCliCommand }) => {
11
11
  await testCliCommand(['projects', 'list', '--org-id', 'org-2']);
12
12
  });
13
+ test('list recoverable projects', async ({ testCliCommand }) => {
14
+ await testCliCommand(['projects', 'list', '--recoverable-only']);
15
+ });
13
16
  test('create', async ({ testCliCommand }) => {
14
17
  await testCliCommand(['projects', 'create', '--name', 'test_project']);
15
18
  });
@@ -102,6 +105,9 @@ describe('projects', () => {
102
105
  test('delete', async ({ testCliCommand }) => {
103
106
  await testCliCommand(['projects', 'delete', 'test']);
104
107
  });
108
+ test('recover deleted project', async ({ testCliCommand }) => {
109
+ await testCliCommand(['projects', 'recover', 'test']);
110
+ });
105
111
  test('update name', async ({ testCliCommand }) => {
106
112
  await testCliCommand([
107
113
  'projects',
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.18.1",
8
+ "version": "2.19.0",
9
9
  "description": "CLI tool for NeonDB Cloud management",
10
10
  "main": "index.js",
11
11
  "author": "NeonDB",
@@ -53,7 +53,7 @@
53
53
  "vitest": "^1.6.0"
54
54
  },
55
55
  "dependencies": {
56
- "@neondatabase/api-client": "2.2.0",
56
+ "@neondatabase/api-client": "2.6.0",
57
57
  "@segment/analytics-node": "^1.0.0-beta.26",
58
58
  "@yao-pkg/pkg": "^6.10.0",
59
59
  "axios": "^1.4.0",
package/parameters.gen.js CHANGED
@@ -123,7 +123,7 @@ export const projectCreateRequest = {
123
123
  },
124
124
  'project.pg_version': {
125
125
  type: "number",
126
- description: "The major Postgres version number. Currently supported versions are `14`, `15`, `16`, and `17`.",
126
+ description: "The major Postgres version number. Currently supported versions are `14`, `15`, `16`, `17`, and `18`.",
127
127
  demandOption: false,
128
128
  },
129
129
  'project.store_passwords': {
@@ -288,7 +288,7 @@ export const branchCreateRequest = {
288
288
  },
289
289
  'branch.expires_at': {
290
290
  type: "string",
291
- description: "The timestamp when the branch is scheduled to expire and be automatically deleted. Must be set by the client following the [RFC 3339, section 5.6](https://tools.ietf.org/html/rfc3339#section-5.6) format with precision up to seconds (such as 2025-06-09T18:02:16Z). Deletion is performed by a background job and may not occur exactly at the specified time.\n\nThis feature is still under development and not yet generally available.\n",
291
+ description: "The timestamp when the branch is scheduled to expire and be automatically deleted. Must be set by the client following the [RFC 3339, section 5.6](https://tools.ietf.org/html/rfc3339#section-5.6) format with precision up to seconds (such as 2025-06-09T18:02:16Z). Deletion is performed by a background job and may not occur exactly at the specified time.\n\nAccess to this feature is currently limited to participants in the Early Access Program.\n",
292
292
  demandOption: false,
293
293
  },
294
294
  };
@@ -299,6 +299,16 @@ export const branchCreateRequestEndpointOptions = {
299
299
  demandOption: true,
300
300
  choices: ["read_only", "read_write"],
301
301
  },
302
+ 'settings.preload_libraries.use_defaults': {
303
+ type: "boolean",
304
+ description: undefined,
305
+ demandOption: false,
306
+ },
307
+ 'settings.preload_libraries.enabled_libraries': {
308
+ type: "array",
309
+ description: undefined,
310
+ demandOption: false,
311
+ },
302
312
  'provisioner': {
303
313
  type: "string",
304
314
  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",
@@ -323,7 +333,7 @@ export const branchUpdateRequest = {
323
333
  },
324
334
  'branch.expires_at': {
325
335
  type: "string",
326
- description: "The timestamp when the branch is scheduled to expire and be automatically deleted. Must be set by the client following the [RFC 3339, section 5.6](https://tools.ietf.org/html/rfc3339#section-5.6) format with precision up to seconds (such as 2025-06-09T18:02:16Z). Deletion is performed by a background job and may not occur exactly at the specified time. If this field is set to null, the expiration timestamp is removed.\n\nThis feature is still under development and not yet generally available.\n",
336
+ description: "The timestamp when the branch is scheduled to expire and be automatically deleted. Must be set by the client following the [RFC 3339, section 5.6](https://tools.ietf.org/html/rfc3339#section-5.6) format with precision up to seconds (such as 2025-06-09T18:02:16Z). Deletion is performed by a background job and may not occur exactly at the specified time. If this field is set to null, the expiration timestamp is removed.\n\nAccess to this feature is currently limited to participants in the Early Access Program.\n",
327
337
  demandOption: false,
328
338
  },
329
339
  };
@@ -344,6 +354,16 @@ export const endpointCreateRequest = {
344
354
  demandOption: true,
345
355
  choices: ["read_only", "read_write"],
346
356
  },
357
+ 'endpoint.settings.preload_libraries.use_defaults': {
358
+ type: "boolean",
359
+ description: undefined,
360
+ demandOption: false,
361
+ },
362
+ 'endpoint.settings.preload_libraries.enabled_libraries': {
363
+ type: "array",
364
+ description: undefined,
365
+ demandOption: false,
366
+ },
347
367
  'endpoint.provisioner': {
348
368
  type: "string",
349
369
  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",
@@ -392,6 +412,16 @@ export const endpointUpdateRequest = {
392
412
  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",
393
413
  demandOption: false,
394
414
  },
415
+ 'endpoint.settings.preload_libraries.use_defaults': {
416
+ type: "boolean",
417
+ description: undefined,
418
+ demandOption: false,
419
+ },
420
+ 'endpoint.settings.preload_libraries.enabled_libraries': {
421
+ type: "array",
422
+ description: undefined,
423
+ demandOption: false,
424
+ },
395
425
  'endpoint.pooler_enabled': {
396
426
  type: "boolean",
397
427
  description: "Whether to enable connection pooling for the compute endpoint\n",