neonctl 2.6.0 → 2.7.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.
@@ -80,6 +80,11 @@ export const builder = (argv) => argv
80
80
  hidden: true,
81
81
  default: '{}',
82
82
  },
83
+ 'schema-only': {
84
+ describe: 'Create a schema-only branch. Requires exactly one read-write compute.',
85
+ type: 'boolean',
86
+ default: false,
87
+ },
83
88
  }), (args) => create(args))
84
89
  .command('reset <id|name>', 'Reset a branch', (yargs) => yargs.options({
85
90
  parent: {
@@ -218,10 +223,20 @@ const create = async (props) => {
218
223
  }
219
224
  return { parent_id: branch.id };
220
225
  })();
226
+ // Validate schema-only branch requirements
227
+ if (props.schemaOnly) {
228
+ if (!props.compute) {
229
+ throw new Error('Schema-only branches require a compute endpoint');
230
+ }
231
+ if (props.type !== EndpointType.ReadWrite) {
232
+ throw new Error('Schema-only branches require a read-write compute endpoint');
233
+ }
234
+ }
221
235
  const { data } = await retryOnLock(() => props.apiClient.createProjectBranch(props.projectId, {
222
236
  branch: {
223
237
  name: props.name,
224
238
  ...parentProps,
239
+ ...(props.schemaOnly ? { init_source: 'schema-only' } : {}),
225
240
  },
226
241
  endpoints: props.compute
227
242
  ? [
@@ -136,6 +136,50 @@ describe('branches', () => {
136
136
  '0.5-2',
137
137
  ]);
138
138
  });
139
+ test('create schema-only branch', async ({ testCliCommand }) => {
140
+ await testCliCommand([
141
+ 'branches',
142
+ 'create',
143
+ '--project-id',
144
+ 'test',
145
+ '--name',
146
+ 'test_branch',
147
+ '--schema-only',
148
+ ]);
149
+ });
150
+ test('create schema-only branch fails without compute', async ({ testCliCommand, }) => {
151
+ await testCliCommand([
152
+ 'branches',
153
+ 'create',
154
+ '--project-id',
155
+ 'test',
156
+ '--name',
157
+ 'test_branch',
158
+ '--schema-only',
159
+ '--no-compute',
160
+ ], {
161
+ mockDir: 'main',
162
+ code: 1,
163
+ stderr: 'ERROR: Schema-only branches require a compute endpoint',
164
+ });
165
+ });
166
+ test('create schema-only branch fails with read-only compute', async ({ testCliCommand, }) => {
167
+ await testCliCommand([
168
+ 'branches',
169
+ 'create',
170
+ '--project-id',
171
+ 'test',
172
+ '--name',
173
+ 'test_branch',
174
+ '--schema-only',
175
+ '--type',
176
+ 'read_only',
177
+ ], {
178
+ mockDir: 'main',
179
+ code: 1,
180
+ stderr: 'ERROR: Schema-only branches require a read-write compute endpoint',
181
+ });
182
+ });
139
183
  /* delete */
140
184
  test('delete by id', async ({ testCliCommand }) => {
141
185
  await testCliCommand([
@@ -1,5 +1,5 @@
1
1
  import { log } from '../log.js';
2
- import { projectCreateRequest } from '../parameters.gen.js';
2
+ import { projectCreateRequest, projectUpdateRequest, } from '../parameters.gen.js';
3
3
  import { writer } from '../writer.js';
4
4
  import { psql } from '../utils/psql.js';
5
5
  import { updateContextFile } from '../context.js';
@@ -77,14 +77,26 @@ export const builder = (argv) => {
77
77
  await create(args);
78
78
  })
79
79
  .command('update <id>', 'Update a project', (yargs) => yargs.options({
80
- name: {
81
- describe: projectCreateRequest['project.name'].description,
82
- type: 'string',
80
+ 'block-vpc-connections': {
81
+ describe: projectUpdateRequest['project.settings.block_vpc_connections']
82
+ .description +
83
+ ' Use --block-vpc-connections=false to set the value to false.',
84
+ type: 'boolean',
85
+ },
86
+ 'block-public-connections': {
87
+ describe: projectUpdateRequest['project.settings.block_public_connections']
88
+ .description +
89
+ ' Use --block-public-connections=false to set the value to false.',
90
+ type: 'boolean',
83
91
  },
84
92
  cu: {
85
93
  describe: 'The number of Compute Units. Could be a fixed size (e.g. "2") or a range delimited by a dash (e.g. "0.5-3").',
86
94
  type: 'string',
87
95
  },
96
+ name: {
97
+ describe: projectUpdateRequest['project.name'].description,
98
+ type: 'string',
99
+ },
88
100
  }), async (args) => {
89
101
  await update(args);
90
102
  })
@@ -189,6 +201,18 @@ const deleteProject = async (props) => {
189
201
  };
190
202
  const update = async (props) => {
191
203
  const project = {};
204
+ if (props.blockPublicConnections !== undefined) {
205
+ if (!project.settings) {
206
+ project.settings = {};
207
+ }
208
+ project.settings.block_public_connections = props.blockPublicConnections;
209
+ }
210
+ if (props.blockVpcConnections !== undefined) {
211
+ if (!project.settings) {
212
+ project.settings = {};
213
+ }
214
+ project.settings.block_vpc_connections = props.blockVpcConnections;
215
+ }
192
216
  if (props.name) {
193
217
  project.name = props.name;
194
218
  }
package/commands/roles.js CHANGED
@@ -25,6 +25,10 @@ export const builder = (argv) => argv
25
25
  type: 'string',
26
26
  demandOption: true,
27
27
  },
28
+ 'no-login': {
29
+ describe: 'Create a passwordless role that cannot login',
30
+ boolean: true,
31
+ },
28
32
  }), (args) => create(args))
29
33
  .command('delete <role>', 'Delete a role', (yargs) => yargs, (args) => deleteRole(args));
30
34
  export const handler = (args) => {
@@ -42,6 +46,7 @@ export const create = async (props) => {
42
46
  const { data } = await retryOnLock(() => props.apiClient.createProjectBranchRole(props.projectId, branchId, {
43
47
  role: {
44
48
  name: props.name,
49
+ no_login: props['no-login'],
45
50
  },
46
51
  }));
47
52
  writer(props).end(data.role, {
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.6.0",
8
+ "version": "2.7.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.11.2",
57
+ "@neondatabase/api-client": "1.12.0",
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
@@ -97,7 +97,7 @@ export const projectCreateRequest = {
97
97
  },
98
98
  'project.default_endpoint_settings.suspend_timeout_seconds': {
99
99
  type: "number",
100
- 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",
100
+ description: "Duration of inactivity in seconds after which the compute endpoint is\nautomatically suspended. The value `0` means use the default value.\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[Scale to zero configuration](https://neon.tech/docs/manage/endpoints#scale-to-zero-configuration).\n",
101
101
  demandOption: false,
102
102
  },
103
103
  'project.pg_version': {
@@ -194,7 +194,7 @@ export const projectUpdateRequest = {
194
194
  },
195
195
  'project.default_endpoint_settings.suspend_timeout_seconds': {
196
196
  type: "number",
197
- 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",
197
+ description: "Duration of inactivity in seconds after which the compute endpoint is\nautomatically suspended. The value `0` means use the default value.\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[Scale to zero configuration](https://neon.tech/docs/manage/endpoints#scale-to-zero-configuration).\n",
198
198
  demandOption: false,
199
199
  },
200
200
  'project.history_retention_seconds': {
@@ -239,11 +239,10 @@ export const branchCreateRequest = {
239
239
  description: "Whether to create the branch as archived\n",
240
240
  demandOption: false,
241
241
  },
242
- 'branch.schema_initialization_type': {
242
+ 'branch.init_source': {
243
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",
244
+ description: "The initialization source type for the branch. Valid values are `schema-only` and `parent-data`.\nThis parameter is under active development and may change its semantics in the future.\n",
245
245
  demandOption: false,
246
- choices: ["empty"],
247
246
  },
248
247
  };
249
248
  export const branchCreateRequestEndpointOptions = {
@@ -260,7 +259,7 @@ export const branchCreateRequestEndpointOptions = {
260
259
  },
261
260
  'suspend_timeout_seconds': {
262
261
  type: "number",
263
- 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",
262
+ description: "Duration of inactivity in seconds after which the compute endpoint is\nautomatically suspended. The value `0` means use the default value.\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[Scale to zero configuration](https://neon.tech/docs/manage/endpoints#scale-to-zero-configuration).\n",
264
263
  demandOption: false,
265
264
  },
266
265
  };
@@ -321,14 +320,14 @@ export const endpointCreateRequest = {
321
320
  },
322
321
  'endpoint.suspend_timeout_seconds': {
323
322
  type: "number",
324
- 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",
323
+ description: "Duration of inactivity in seconds after which the compute endpoint is\nautomatically suspended. The value `0` means use the default value.\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[Scale to zero configuration](https://neon.tech/docs/manage/endpoints#scale-to-zero-configuration).\n",
325
324
  demandOption: false,
326
325
  },
327
326
  };
328
327
  export const endpointUpdateRequest = {
329
328
  'endpoint.branch_id': {
330
329
  type: "string",
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",
330
+ description: "DEPRECATED: This field will be removed in a future release.\nThe destination branch ID. The destination branch must not have an existing read-write endpoint.\n",
332
331
  demandOption: false,
333
332
  },
334
333
  'endpoint.provisioner': {
@@ -359,14 +358,14 @@ export const endpointUpdateRequest = {
359
358
  },
360
359
  'endpoint.suspend_timeout_seconds': {
361
360
  type: "number",
362
- 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",
361
+ description: "Duration of inactivity in seconds after which the compute endpoint is\nautomatically suspended. The value `0` means use the default value.\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[Scale to zero configuration](https://neon.tech/docs/manage/endpoints#scale-to-zero-configuration).\n",
363
362
  demandOption: false,
364
363
  },
365
364
  };
366
365
  export const databaseCreateRequest = {
367
366
  'database.name': {
368
367
  type: "string",
369
- description: "The name of the datbase\n",
368
+ description: "The name of the database\n",
370
369
  demandOption: true,
371
370
  },
372
371
  'database.owner_name': {
@@ -381,4 +380,9 @@ export const roleCreateRequest = {
381
380
  description: "The role name. Cannot exceed 63 bytes in length.\n",
382
381
  demandOption: true,
383
382
  },
383
+ 'role.no_login': {
384
+ type: "boolean",
385
+ description: "Whether to create a role that cannot login.\n",
386
+ demandOption: false,
387
+ },
384
388
  };