neonctl 1.27.6 → 1.28.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.
@@ -249,17 +249,13 @@ const reset = async (props) => {
249
249
  throw new Error('Only resetting to parent is supported for now');
250
250
  }
251
251
  const branchId = await branchIdFromProps(props);
252
- const { data: { branch }, } = await props.apiClient.getProjectBranch(props.projectId, branchId);
253
- if (!branch.parent_id) {
252
+ const { data: { branch: { parent_id }, }, } = await props.apiClient.getProjectBranch(props.projectId, branchId);
253
+ if (!parent_id) {
254
254
  throw new Error('Branch has no parent');
255
255
  }
256
- const { data } = await retryOnLock(() => props.apiClient.request({
257
- method: 'POST',
258
- path: `/projects/${props.projectId}/branches/${branch.id}/reset`,
259
- body: {
260
- source_branch_id: branch.parent_id,
261
- preserve_under_name: props.preserveUnderName || undefined,
262
- },
256
+ const { data } = await retryOnLock(() => props.apiClient.restoreProjectBranch(props.projectId, branchId, {
257
+ source_branch_id: parent_id,
258
+ preserve_under_name: props.preserveUnderName || undefined,
263
259
  }));
264
260
  const resultBranch = data.branch;
265
261
  writer(props).end(resultBranch, {
@@ -283,17 +279,13 @@ const restore = async (props) => {
283
279
  (pointInTime.tag === 'timestamp' &&
284
280
  'timestamp ' + pointInTime.timestamp) ||
285
281
  'head'}`);
286
- const { data } = await retryOnLock(() => props.apiClient.request({
287
- method: 'POST',
288
- path: `/projects/${props.projectId}/branches/${targetBranchId}/reset`,
289
- body: {
290
- source_branch_id: pointInTime.branchId,
291
- preserve_under_name: props.preserveUnderName || undefined,
292
- ...(pointInTime.tag === 'lsn' && { source_lsn: pointInTime.lsn }),
293
- ...(pointInTime.tag === 'timestamp' && {
294
- source_timestamp: pointInTime.timestamp,
295
- }),
296
- },
282
+ const { data } = await retryOnLock(() => props.apiClient.restoreProjectBranch(props.projectId, targetBranchId, {
283
+ source_branch_id: pointInTime.branchId,
284
+ preserve_under_name: props.preserveUnderName || undefined,
285
+ ...(pointInTime.tag === 'lsn' && { source_lsn: pointInTime.lsn }),
286
+ ...(pointInTime.tag === 'timestamp' && {
287
+ source_timestamp: pointInTime.timestamp,
288
+ }),
297
289
  }));
298
290
  const branch = data.branch;
299
291
  const writeInst = writer(props).write(branch, {
@@ -95,7 +95,7 @@ const remove = async (props) => {
95
95
  const existingAllowedIps = data.project.settings?.allowed_ips;
96
96
  project.settings = {
97
97
  allowed_ips: {
98
- ips: existingAllowedIps?.ips.filter((ip) => !props.ips.includes(ip)) ?? [],
98
+ ips: existingAllowedIps?.ips?.filter((ip) => !props.ips.includes(ip)) ?? [],
99
99
  primary_branch_only: existingAllowedIps?.primary_branch_only ?? false,
100
100
  },
101
101
  };
@@ -10,7 +10,6 @@ const REGIONS = [
10
10
  'aws-eu-central-1',
11
11
  'aws-us-east-2',
12
12
  'aws-us-east-1',
13
- 'aws-il-central-1',
14
13
  ];
15
14
  const PROJECTS_LIST_LIMIT = 100;
16
15
  export const command = 'projects';
@@ -36,6 +35,14 @@ export const builder = (argv) => {
36
35
  describe: 'Connect to a new project via psql',
37
36
  default: false,
38
37
  },
38
+ database: {
39
+ describe: projectCreateRequest['project.branch.database_name'].description,
40
+ type: 'string',
41
+ },
42
+ role: {
43
+ describe: projectCreateRequest['project.branch.role_name'].description,
44
+ type: 'string',
45
+ },
39
46
  'set-context': {
40
47
  type: 'boolean',
41
48
  describe: 'Set the current context to the new project',
@@ -100,6 +107,13 @@ const create = async (props) => {
100
107
  if (props.regionId) {
101
108
  project.region_id = props.regionId;
102
109
  }
110
+ project.branch = {};
111
+ if (props.database) {
112
+ project.branch.database_name = props.database;
113
+ }
114
+ if (props.role) {
115
+ project.branch.role_name = props.role;
116
+ }
103
117
  const { data } = await props.apiClient.createProject({
104
118
  project,
105
119
  });
@@ -19,6 +19,22 @@ describe('projects', () => {
19
19
  snapshot: true,
20
20
  },
21
21
  });
22
+ testCliCommand({
23
+ name: 'create with database and role',
24
+ args: [
25
+ 'projects',
26
+ 'create',
27
+ '--name',
28
+ 'test_project',
29
+ '--database',
30
+ 'test_db',
31
+ '--role',
32
+ 'test_role',
33
+ ],
34
+ expected: {
35
+ snapshot: true,
36
+ },
37
+ });
22
38
  testCliCommand({
23
39
  name: 'create and connect with psql',
24
40
  args: ['projects', 'create', '--name', 'test_project', '--psql'],
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "url": "git@github.com:neondatabase/neonctl.git"
6
6
  },
7
7
  "type": "module",
8
- "version": "1.27.6",
8
+ "version": "1.28.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
  "typescript": "^4.7.4"
54
54
  },
55
55
  "dependencies": {
56
- "@neondatabase/api-client": "1.4.1",
56
+ "@neondatabase/api-client": "1.5.0",
57
57
  "@segment/analytics-node": "^1.0.0-beta.26",
58
58
  "axios": "^1.4.0",
59
59
  "axios-debug-log": "^1.0.0",
package/parameters.gen.js CHANGED
@@ -28,13 +28,18 @@ export const projectCreateRequest = {
28
28
  'project.settings.allowed_ips.ips': {
29
29
  type: "array",
30
30
  description: "A list of IP addresses that are allowed to connect to the endpoint.",
31
- demandOption: true,
31
+ demandOption: false,
32
32
  },
33
33
  'project.settings.allowed_ips.primary_branch_only': {
34
34
  type: "boolean",
35
35
  description: "If true, the list will be applied only to the primary branch.",
36
36
  demandOption: true,
37
37
  },
38
+ 'project.settings.enable_logical_replication': {
39
+ type: "boolean",
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
+ demandOption: false,
42
+ },
38
43
  'project.name': {
39
44
  type: "string",
40
45
  description: "The project name",
@@ -68,12 +73,12 @@ export const projectCreateRequest = {
68
73
  },
69
74
  'project.default_endpoint_settings.suspend_timeout_seconds': {
70
75
  type: "number",
71
- description: "Duration of inactivity in seconds after which the compute endpoint is\nautomatically suspended. The value `0` means use the global default.\nThe value `-1` means never suspend. The default value is `300` seconds (5 minutes).\nThe maximum value is `604800` seconds (1 week). For more information, see\n[Auto-suspend configuration](https://neon.tech/docs/manage/endpoints#auto-suspend-configuration).\n",
76
+ description: "Duration of inactivity in seconds after which the compute endpoint is\nautomatically suspended. The value `0` means use the global default.\nThe value `-1` means never suspend. The default value is `300` seconds (5 minutes).\nThe minimum value is `60` seconds (1 minute).\nThe maximum value is `604800` seconds (1 week). For more information, see\n[Auto-suspend configuration](https://neon.tech/docs/manage/endpoints#auto-suspend-configuration).\n",
72
77
  demandOption: false,
73
78
  },
74
79
  'project.pg_version': {
75
80
  type: "number",
76
- description: "The major PostgreSQL version number. Currently supported versions are `14`, `15` and `16`.",
81
+ description: "The major Postgres version number. Currently supported versions are `14`, `15`, and `16`.",
77
82
  demandOption: false,
78
83
  },
79
84
  'project.store_passwords': {
@@ -116,13 +121,18 @@ export const projectUpdateRequest = {
116
121
  'project.settings.allowed_ips.ips': {
117
122
  type: "array",
118
123
  description: "A list of IP addresses that are allowed to connect to the endpoint.",
119
- demandOption: true,
124
+ demandOption: false,
120
125
  },
121
126
  'project.settings.allowed_ips.primary_branch_only': {
122
127
  type: "boolean",
123
128
  description: "If true, the list will be applied only to the primary branch.",
124
129
  demandOption: true,
125
130
  },
131
+ 'project.settings.enable_logical_replication': {
132
+ type: "boolean",
133
+ 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",
134
+ demandOption: false,
135
+ },
126
136
  'project.name': {
127
137
  type: "string",
128
138
  description: "The project name",
@@ -130,7 +140,7 @@ export const projectUpdateRequest = {
130
140
  },
131
141
  'project.default_endpoint_settings.suspend_timeout_seconds': {
132
142
  type: "number",
133
- description: "Duration of inactivity in seconds after which the compute endpoint is\nautomatically suspended. The value `0` means use the global default.\nThe value `-1` means never suspend. The default value is `300` seconds (5 minutes).\nThe maximum value is `604800` seconds (1 week). For more information, see\n[Auto-suspend configuration](https://neon.tech/docs/manage/endpoints#auto-suspend-configuration).\n",
143
+ description: "Duration of inactivity in seconds after which the compute endpoint is\nautomatically suspended. The value `0` means use the global default.\nThe value `-1` means never suspend. The default value is `300` seconds (5 minutes).\nThe minimum value is `60` seconds (1 minute).\nThe maximum value is `604800` seconds (1 week). For more information, see\n[Auto-suspend configuration](https://neon.tech/docs/manage/endpoints#auto-suspend-configuration).\n",
134
144
  demandOption: false,
135
145
  },
136
146
  'project.history_retention_seconds': {
@@ -162,7 +172,12 @@ export const branchCreateRequest = {
162
172
  },
163
173
  'branch.parent_timestamp': {
164
174
  type: "string",
165
- description: "A timestamp identifying a point in time on the parent branch. The branch will be created with data starting from this point in time.\n",
175
+ description: "A timestamp identifying a point in time on the parent branch. The branch will be created with data starting from this point in time.\nThe timestamp must be provided in ISO 8601 format; for example: `2024-02-26T12:00:00Z`.\n",
176
+ demandOption: false,
177
+ },
178
+ 'branch.protected': {
179
+ type: "boolean",
180
+ description: "Whether the branch is protected\n",
166
181
  demandOption: false,
167
182
  },
168
183
  };
@@ -181,7 +196,7 @@ export const branchCreateRequestEndpointOptions = {
181
196
  },
182
197
  'suspend_timeout_seconds': {
183
198
  type: "number",
184
- description: "Duration of inactivity in seconds after which the compute endpoint is\nautomatically suspended. The value `0` means use the global default.\nThe value `-1` means never suspend. The default value is `300` seconds (5 minutes).\nThe maximum value is `604800` seconds (1 week). For more information, see\n[Auto-suspend configuration](https://neon.tech/docs/manage/endpoints#auto-suspend-configuration).\n",
199
+ description: "Duration of inactivity in seconds after which the compute endpoint is\nautomatically suspended. The value `0` means use the global default.\nThe value `-1` means never suspend. The default value is `300` seconds (5 minutes).\nThe minimum value is `60` seconds (1 minute).\nThe maximum value is `604800` seconds (1 week). For more information, see\n[Auto-suspend configuration](https://neon.tech/docs/manage/endpoints#auto-suspend-configuration).\n",
185
200
  demandOption: false,
186
201
  },
187
202
  };
@@ -191,6 +206,11 @@ export const branchUpdateRequest = {
191
206
  description: undefined,
192
207
  demandOption: false,
193
208
  },
209
+ 'branch.protected': {
210
+ type: "boolean",
211
+ description: undefined,
212
+ demandOption: false,
213
+ },
194
214
  };
195
215
  export const endpointCreateRequest = {
196
216
  'endpoint.branch_id': {
@@ -238,7 +258,7 @@ export const endpointCreateRequest = {
238
258
  },
239
259
  'endpoint.suspend_timeout_seconds': {
240
260
  type: "number",
241
- description: "Duration of inactivity in seconds after which the compute endpoint is\nautomatically suspended. The value `0` means use the global default.\nThe value `-1` means never suspend. The default value is `300` seconds (5 minutes).\nThe maximum value is `604800` seconds (1 week). For more information, see\n[Auto-suspend configuration](https://neon.tech/docs/manage/endpoints#auto-suspend-configuration).\n",
261
+ description: "Duration of inactivity in seconds after which the compute endpoint is\nautomatically suspended. The value `0` means use the global default.\nThe value `-1` means never suspend. The default value is `300` seconds (5 minutes).\nThe minimum value is `60` seconds (1 minute).\nThe maximum value is `604800` seconds (1 week). For more information, see\n[Auto-suspend configuration](https://neon.tech/docs/manage/endpoints#auto-suspend-configuration).\n",
242
262
  demandOption: false,
243
263
  },
244
264
  };
@@ -277,7 +297,7 @@ export const endpointUpdateRequest = {
277
297
  },
278
298
  'endpoint.suspend_timeout_seconds': {
279
299
  type: "number",
280
- description: "Duration of inactivity in seconds after which the compute endpoint is\nautomatically suspended. The value `0` means use the global default.\nThe value `-1` means never suspend. The default value is `300` seconds (5 minutes).\nThe maximum value is `604800` seconds (1 week). For more information, see\n[Auto-suspend configuration](https://neon.tech/docs/manage/endpoints#auto-suspend-configuration).\n",
300
+ description: "Duration of inactivity in seconds after which the compute endpoint is\nautomatically suspended. The value `0` means use the global default.\nThe value `-1` means never suspend. The default value is `300` seconds (5 minutes).\nThe minimum value is `60` seconds (1 minute).\nThe maximum value is `604800` seconds (1 week). For more information, see\n[Auto-suspend configuration](https://neon.tech/docs/manage/endpoints#auto-suspend-configuration).\n",
281
301
  demandOption: false,
282
302
  },
283
303
  };