neonctl 1.29.1 → 1.29.4

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.
Files changed (184) hide show
  1. package/analytics.js +78 -0
  2. package/api.js +35 -0
  3. package/auth.js +101 -0
  4. package/{src/cli.ts → cli.js} +0 -1
  5. package/commands/auth.js +102 -0
  6. package/commands/auth.test.js +42 -0
  7. package/commands/branches.js +303 -0
  8. package/commands/branches.test.js +321 -0
  9. package/commands/connection_string.js +158 -0
  10. package/commands/connection_string.test.js +253 -0
  11. package/commands/databases.js +79 -0
  12. package/commands/databases.test.js +51 -0
  13. package/commands/help.test.js +11 -0
  14. package/{src/commands/index.ts → commands/index.js} +10 -11
  15. package/commands/ip_allow.js +135 -0
  16. package/commands/ip_allow.test.js +78 -0
  17. package/commands/operations.js +28 -0
  18. package/commands/operations.test.js +11 -0
  19. package/commands/projects.js +186 -0
  20. package/commands/projects.test.js +132 -0
  21. package/commands/roles.js +57 -0
  22. package/commands/roles.test.js +42 -0
  23. package/commands/set_context.js +22 -0
  24. package/commands/set_context.test.js +53 -0
  25. package/commands/user.js +15 -0
  26. package/config.js +11 -0
  27. package/context.js +48 -0
  28. package/env.js +6 -0
  29. package/errors.js +16 -0
  30. package/help.js +146 -0
  31. package/index.js +168 -0
  32. package/log.js +15 -0
  33. package/package.json +1 -1
  34. package/parameters.gen.js +322 -0
  35. package/pkg.js +3 -45
  36. package/test_utils/mock_server.js +16 -0
  37. package/test_utils/oauth_server.js +9 -0
  38. package/test_utils/test_cli_command.js +80 -0
  39. package/types.js +1 -0
  40. package/utils/enrichers.js +49 -0
  41. package/utils/formats.js +5 -0
  42. package/utils/formats.test.js +32 -0
  43. package/utils/middlewares.js +20 -0
  44. package/utils/point_in_time.js +50 -0
  45. package/utils/psql.js +24 -0
  46. package/utils/string.js +5 -0
  47. package/utils/ui.js +59 -0
  48. package/writer.js +87 -0
  49. package/writer.test.js +86 -0
  50. package/.bump +0 -1
  51. package/.editorconfig +0 -7
  52. package/.eslintrc.cjs +0 -15
  53. package/.github/workflows/commitlint.yml +0 -46
  54. package/.github/workflows/pr.yml +0 -25
  55. package/.github/workflows/release.yml +0 -30
  56. package/.husky/commit-msg +0 -4
  57. package/.husky/pre-commit +0 -4
  58. package/.nvmrc +0 -1
  59. package/.prettierignore +0 -3
  60. package/.prettierrc.json +0 -3
  61. package/.releaserc.json +0 -47
  62. package/LICENSE +0 -202
  63. package/commitlint.config.cjs +0 -7
  64. package/generateOptionsFromSpec.ts +0 -68
  65. package/jest/setup.js +0 -5
  66. package/jest.config.ts +0 -199
  67. package/mocks/bin/psql.cjs +0 -9
  68. package/mocks/main/projects/GET.js +0 -27
  69. package/mocks/main/projects/POST.js +0 -22
  70. package/mocks/main/projects/shared/GET.js +0 -16
  71. package/mocks/main/projects/test/DELETE.json +0 -7
  72. package/mocks/main/projects/test/GET.json +0 -13
  73. package/mocks/main/projects/test/PATCH.js +0 -18
  74. package/mocks/main/projects/test/branches/GET.json +0 -25
  75. package/mocks/main/projects/test/branches/POST.js +0 -83
  76. package/mocks/main/projects/test/branches/br-cloudy-branch-12345678/DELETE.json +0 -7
  77. package/mocks/main/projects/test/branches/br-cloudy-branch-12345678/GET.json +0 -9
  78. package/mocks/main/projects/test/branches/br-cloudy-branch-12345678/PATCH.js +0 -14
  79. package/mocks/main/projects/test/branches/br-cloudy-branch-12345678/databases/GET.json +0 -6
  80. package/mocks/main/projects/test/branches/br-cloudy-branch-12345678/databases/POST.js +0 -13
  81. package/mocks/main/projects/test/branches/br-cloudy-branch-12345678/databases/test_db/DELETE.json +0 -6
  82. package/mocks/main/projects/test/branches/br-cloudy-branch-12345678/endpoints/GET.json +0 -26
  83. package/mocks/main/projects/test/branches/br-cloudy-branch-12345678/endpoints/POST.json +0 -6
  84. package/mocks/main/projects/test/branches/br-cloudy-branch-12345678/roles/GET.json +0 -3
  85. package/mocks/main/projects/test/branches/br-cloudy-branch-12345678/roles/POST.js +0 -14
  86. package/mocks/main/projects/test/branches/br-cloudy-branch-12345678/roles/test_role/DELETE.json +0 -6
  87. package/mocks/main/projects/test/branches/br-cloudy-branch-12345678/roles/test_role/reveal_password/GET.json +0 -3
  88. package/mocks/main/projects/test/branches/br-cloudy-branch-12345678/set_as_primary/POST.json +0 -9
  89. package/mocks/main/projects/test/branches/br-numbered-branch-123456/GET.json +0 -10
  90. package/mocks/main/projects/test/branches/br-sunny-branch-123456/DELETE.json +0 -7
  91. package/mocks/main/projects/test/branches/br-sunny-branch-123456/GET.json +0 -10
  92. package/mocks/main/projects/test/branches/br-sunny-branch-123456/PATCH.js +0 -14
  93. package/mocks/main/projects/test/branches/br-sunny-branch-123456/databases/GET.json +0 -6
  94. package/mocks/main/projects/test/branches/br-sunny-branch-123456/databases/POST.js +0 -13
  95. package/mocks/main/projects/test/branches/br-sunny-branch-123456/databases/test_db/DELETE.json +0 -6
  96. package/mocks/main/projects/test/branches/br-sunny-branch-123456/endpoints/GET.json +0 -26
  97. package/mocks/main/projects/test/branches/br-sunny-branch-123456/endpoints/POST.json +0 -6
  98. package/mocks/main/projects/test/branches/br-sunny-branch-123456/restore/POST.js +0 -16
  99. package/mocks/main/projects/test/branches/br-sunny-branch-123456/roles/GET.json +0 -3
  100. package/mocks/main/projects/test/branches/br-sunny-branch-123456/roles/POST.js +0 -14
  101. package/mocks/main/projects/test/branches/br-sunny-branch-123456/roles/test_role/DELETE.json +0 -6
  102. package/mocks/main/projects/test/branches/br-sunny-branch-123456/roles/test_role/reveal_password/GET.json +0 -3
  103. package/mocks/main/projects/test/branches/br-sunny-branch-123456/set_as_primary/POST.json +0 -9
  104. package/mocks/main/projects/test/endpoints/GET.json +0 -9
  105. package/mocks/main/projects/test/endpoints/POST.js +0 -32
  106. package/mocks/main/projects/test/endpoints/test_endpoint_id/DELETE.json +0 -7
  107. package/mocks/main/projects/test/endpoints/test_endpoint_id/GET.json +0 -9
  108. package/mocks/main/projects/test/endpoints/test_endpoint_id/PATCH.js +0 -17
  109. package/mocks/main/projects/test/operations/GET.json +0 -22
  110. package/mocks/main/users/me/GET.json +0 -5
  111. package/mocks/restore/projects/test/branches/GET.json +0 -21
  112. package/mocks/restore/projects/test/branches/br-another-branch-123456/GET.json +0 -6
  113. package/mocks/restore/projects/test/branches/br-another-branch-123456/restore/POST.js +0 -13
  114. package/mocks/restore/projects/test/branches/br-any-branch-123456/GET.json +0 -6
  115. package/mocks/restore/projects/test/branches/br-parent-tots-123456/GET.json +0 -7
  116. package/mocks/restore/projects/test/branches/br-parent-tots-123456/restore/POST.js +0 -14
  117. package/mocks/restore/projects/test/branches/br-self-tolsn-123456/GET.json +0 -6
  118. package/mocks/restore/projects/test/branches/br-self-tolsn-123456/restore/POST.js +0 -15
  119. package/mocks/single_project/projects/GET.json +0 -10
  120. package/mocks/single_project/projects/test-project-123456/GET.json +0 -14
  121. package/mocks/single_project/projects/test-project-123456/branches/GET.json +0 -11
  122. package/mocks/single_project/projects/test-project-123456/branches/br-main-branch-123456/databases/GET.json +0 -3
  123. package/mocks/single_project/projects/test-project-123456/branches/br-main-branch-123456/endpoints/GET.json +0 -10
  124. package/mocks/single_project/projects/test-project-123456/branches/br-main-branch-123456/roles/GET.json +0 -3
  125. package/mocks/single_project/projects/test-project-123456/branches/br-main-branch-123456/roles/test_role/reveal_password/GET.json +0 -3
  126. package/rollup.config.js +0 -20
  127. package/snapshots/commands/branches.test.snap +0 -221
  128. package/snapshots/commands/connection_string.test.snap +0 -70
  129. package/snapshots/commands/databases.test.snap +0 -20
  130. package/snapshots/commands/ip_allow.test.snap +0 -55
  131. package/snapshots/commands/operations.test.snap +0 -17
  132. package/snapshots/commands/projects.test.snap +0 -141
  133. package/snapshots/commands/roles.test.snap +0 -19
  134. package/snapshots/commands/set_context.test.snap +0 -30
  135. package/snapshots/writer.test.snap +0 -60
  136. package/snapshotsResolver.cjs +0 -32
  137. package/src/analytics.ts +0 -95
  138. package/src/api.ts +0 -44
  139. package/src/auth.ts +0 -137
  140. package/src/commands/auth.test.ts +0 -62
  141. package/src/commands/auth.ts +0 -148
  142. package/src/commands/branches.test.ts +0 -354
  143. package/src/commands/branches.ts +0 -451
  144. package/src/commands/connection_string.test.ts +0 -250
  145. package/src/commands/connection_string.ts +0 -210
  146. package/src/commands/databases.test.ts +0 -55
  147. package/src/commands/databases.ts +0 -129
  148. package/src/commands/help.test.ts +0 -13
  149. package/src/commands/ip_allow.test.ts +0 -86
  150. package/src/commands/ip_allow.ts +0 -202
  151. package/src/commands/operations.test.ts +0 -13
  152. package/src/commands/operations.ts +0 -41
  153. package/src/commands/projects.test.ts +0 -147
  154. package/src/commands/projects.ts +0 -275
  155. package/src/commands/roles.test.ts +0 -46
  156. package/src/commands/roles.ts +0 -100
  157. package/src/commands/set_context.test.ts +0 -64
  158. package/src/commands/set_context.ts +0 -27
  159. package/src/commands/user.ts +0 -21
  160. package/src/config.ts +0 -22
  161. package/src/context.ts +0 -61
  162. package/src/env.ts +0 -7
  163. package/src/errors.ts +0 -24
  164. package/src/help.ts +0 -185
  165. package/src/index.ts +0 -180
  166. package/src/log.ts +0 -16
  167. package/src/parameters.gen.ts +0 -332
  168. package/src/pkg.ts +0 -9
  169. package/src/test_utils/mock_server.ts +0 -27
  170. package/src/test_utils/oauth_server.ts +0 -10
  171. package/src/test_utils/test_cli_command.ts +0 -117
  172. package/src/types.ts +0 -25
  173. package/src/utils/enrichers.ts +0 -73
  174. package/src/utils/formats.test.ts +0 -41
  175. package/src/utils/formats.ts +0 -11
  176. package/src/utils/middlewares.ts +0 -23
  177. package/src/utils/point_in_time.ts +0 -86
  178. package/src/utils/psql.ts +0 -29
  179. package/src/utils/string.ts +0 -8
  180. package/src/utils/ui.ts +0 -64
  181. package/src/writer.test.ts +0 -98
  182. package/src/writer.ts +0 -131
  183. package/tsconfig.json +0 -17
  184. /package/{src/callback.html → callback.html} +0 -0
@@ -1,41 +0,0 @@
1
- import yargs from 'yargs';
2
- import { fillSingleProject } from '../utils/enrichers.js';
3
-
4
- import { ProjectScopeProps } from '../types.js';
5
- import { writer } from '../writer.js';
6
-
7
- const OPERATIONS_FIELDS = ['id', 'action', 'status', 'created_at'] as const;
8
-
9
- export const command = 'operations';
10
- export const describe = 'Manage operations';
11
- export const aliases = ['operation'];
12
- export const builder = (argv: yargs.Argv) =>
13
- argv
14
- .usage('$0 operations <sub-command> [options]')
15
- .options({
16
- 'project-id': {
17
- describe: 'Project ID',
18
- type: 'string',
19
- },
20
- })
21
- .middleware(fillSingleProject as any)
22
- .command(
23
- 'list',
24
- 'List operations',
25
- (yargs) => yargs,
26
- async (args) => await list(args as any),
27
- );
28
-
29
- export const handler = (args: yargs.Argv) => {
30
- return args;
31
- };
32
-
33
- export const list = async (props: ProjectScopeProps & { limit: number }) => {
34
- const { data } = await props.apiClient.listProjectOperations({
35
- projectId: props.projectId,
36
- limit: props.limit,
37
- });
38
- writer(props).end(data.operations, {
39
- fields: OPERATIONS_FIELDS,
40
- });
41
- };
@@ -1,147 +0,0 @@
1
- import { afterAll, describe, expect, test } from '@jest/globals';
2
- import { readFileSync, rmSync } from 'node:fs';
3
- import { tmpdir } from 'node:os';
4
- import { join } from 'node:path';
5
- import { testCliCommand } from '../test_utils/test_cli_command.js';
6
-
7
- const CONTEXT_FILE = join(tmpdir(), `neon_project_create_ctx_${Date.now()}`);
8
-
9
- describe('projects', () => {
10
- testCliCommand({
11
- name: 'list',
12
- args: ['projects', 'list'],
13
- expected: {
14
- snapshot: true,
15
- },
16
- });
17
-
18
- testCliCommand({
19
- name: 'create',
20
- args: ['projects', 'create', '--name', 'test_project'],
21
- expected: {
22
- snapshot: true,
23
- },
24
- });
25
-
26
- testCliCommand({
27
- name: 'create with database and role',
28
- args: [
29
- 'projects',
30
- 'create',
31
- '--name',
32
- 'test_project',
33
- '--database',
34
- 'test_db',
35
- '--role',
36
- 'test_role',
37
- ],
38
- expected: {
39
- snapshot: true,
40
- },
41
- });
42
-
43
- testCliCommand({
44
- name: 'create and connect with psql',
45
- args: ['projects', 'create', '--name', 'test_project', '--psql'],
46
- expected: {
47
- snapshot: true,
48
- },
49
- });
50
-
51
- testCliCommand({
52
- name: 'create and connect with psql and psql args',
53
- args: [
54
- 'projects',
55
- 'create',
56
- '--name',
57
- 'test_project',
58
- '--psql',
59
- '--',
60
- '-c',
61
- 'SELECT 1',
62
- ],
63
- expected: {
64
- snapshot: true,
65
- },
66
- });
67
-
68
- testCliCommand({
69
- name: 'create project with setting the context',
70
- args: [
71
- 'projects',
72
- 'create',
73
- '--name',
74
- 'test_project',
75
- '--context-file',
76
- CONTEXT_FILE,
77
- '--set-context',
78
- ],
79
- expected: {
80
- snapshot: true,
81
- },
82
- });
83
-
84
- afterAll(() => {
85
- rmSync(CONTEXT_FILE);
86
- });
87
-
88
- test('context file should exist and contain the project id', () => {
89
- expect(readFileSync(CONTEXT_FILE, 'utf-8')).toContain('new-project-123456');
90
- });
91
-
92
- testCliCommand({
93
- name: 'delete',
94
- args: ['projects', 'delete', 'test'],
95
- expected: {
96
- snapshot: true,
97
- },
98
- });
99
-
100
- testCliCommand({
101
- name: 'update name',
102
- args: ['projects', 'update', 'test', '--name', 'test_project_new_name'],
103
- expected: {
104
- snapshot: true,
105
- },
106
- });
107
-
108
- testCliCommand({
109
- name: 'update ip allow',
110
- args: [
111
- 'projects',
112
- 'update',
113
- 'test',
114
- '--ip-allow',
115
- '127.0.0.1',
116
- '192.168.1.2/22',
117
- '--ip-primary-only',
118
- ],
119
- expected: {
120
- snapshot: true,
121
- },
122
- });
123
-
124
- testCliCommand({
125
- name: 'update ip allow primary only flag',
126
- args: ['projects', 'update', 'test', '--ip-primary-only', 'false'],
127
- expected: {
128
- snapshot: true,
129
- },
130
- });
131
-
132
- testCliCommand({
133
- name: 'update ip allow remove',
134
- args: ['projects', 'update', 'test', '--ip-allow'],
135
- expected: {
136
- snapshot: true,
137
- },
138
- });
139
-
140
- testCliCommand({
141
- name: 'get',
142
- args: ['projects', 'get', 'test'],
143
- expected: {
144
- snapshot: true,
145
- },
146
- });
147
- });
@@ -1,275 +0,0 @@
1
- import {
2
- ProjectCreateRequest,
3
- ProjectListItem,
4
- ProjectUpdateRequest,
5
- } from '@neondatabase/api-client';
6
- import yargs from 'yargs';
7
-
8
- import { log } from '../log.js';
9
- import {
10
- projectCreateRequest,
11
- projectUpdateRequest,
12
- } from '../parameters.gen.js';
13
- import { CommonProps, IdOrNameProps } from '../types.js';
14
- import { writer } from '../writer.js';
15
- import { psql } from '../utils/psql.js';
16
- import { updateContextFile } from '../context.js';
17
-
18
- const PROJECT_FIELDS = ['id', 'name', 'region_id', 'created_at'] as const;
19
-
20
- const REGIONS = [
21
- 'aws-us-west-2',
22
- 'aws-ap-southeast-1',
23
- 'aws-eu-central-1',
24
- 'aws-us-east-2',
25
- 'aws-us-east-1',
26
- ];
27
-
28
- const PROJECTS_LIST_LIMIT = 100;
29
-
30
- export const command = 'projects';
31
- export const describe = 'Manage projects';
32
- export const aliases = ['project'];
33
- export const builder = (argv: yargs.Argv) => {
34
- return argv
35
- .usage('$0 projects <sub-command> [options]')
36
- .command(
37
- 'list',
38
- 'List projects',
39
- (yargs) => yargs,
40
- async (args) => {
41
- await list(args as any);
42
- },
43
- )
44
- .command(
45
- 'create',
46
- 'Create a project',
47
- (yargs) =>
48
- yargs.options({
49
- name: {
50
- describe: projectCreateRequest['project.name'].description,
51
- type: 'string',
52
- },
53
- 'region-id': {
54
- describe: `The region ID. Possible values: ${REGIONS.join(', ')}`,
55
- type: 'string',
56
- },
57
- psql: {
58
- type: 'boolean',
59
- describe: 'Connect to a new project via psql',
60
- default: false,
61
- },
62
- database: {
63
- describe:
64
- projectCreateRequest['project.branch.database_name'].description,
65
- type: 'string',
66
- },
67
- role: {
68
- describe:
69
- projectCreateRequest['project.branch.role_name'].description,
70
- type: 'string',
71
- },
72
- 'set-context': {
73
- type: 'boolean',
74
- describe: 'Set the current context to the new project',
75
- default: false,
76
- },
77
- }),
78
- async (args) => {
79
- await create(args as any);
80
- },
81
- )
82
- .command(
83
- 'update <id>',
84
- 'Update a project',
85
- (yargs) =>
86
- yargs.options({
87
- name: {
88
- describe: projectCreateRequest['project.name'].description,
89
- type: 'string',
90
- },
91
- 'ip-allow': {
92
- describe:
93
- projectUpdateRequest['project.settings.allowed_ips.ips']
94
- .description,
95
- type: 'string',
96
- array: true,
97
- deprecated: "Deprecated. Use 'ip-allow' command",
98
- },
99
- 'ip-primary-only': {
100
- describe:
101
- projectUpdateRequest[
102
- 'project.settings.allowed_ips.primary_branch_only'
103
- ].description,
104
- type: 'boolean',
105
- deprecated: "Deprecated. Use 'ip-allow' command",
106
- },
107
- }),
108
- async (args) => {
109
- await update(args as any);
110
- },
111
- )
112
- .command(
113
- 'delete <id>',
114
- 'Delete a project',
115
- (yargs) => yargs,
116
- async (args) => {
117
- await deleteProject(args as any);
118
- },
119
- )
120
- .command(
121
- 'get <id>',
122
- 'Get a project',
123
- (yargs) => yargs,
124
- async (args) => {
125
- await get(args as any);
126
- },
127
- );
128
- };
129
- export const handler = (args: yargs.Argv) => {
130
- return args;
131
- };
132
-
133
- const list = async (props: CommonProps) => {
134
- const getList = async (
135
- fn:
136
- | typeof props.apiClient.listProjects
137
- | typeof props.apiClient.listSharedProjects,
138
- ) => {
139
- const result: ProjectListItem[] = [];
140
- let cursor: string | undefined;
141
- let end = false;
142
- while (!end) {
143
- const { data } = await fn({
144
- limit: PROJECTS_LIST_LIMIT,
145
- cursor,
146
- });
147
- result.push(...data.projects);
148
- cursor = data.pagination?.cursor;
149
- log.debug(
150
- 'Got %d projects, with cursor: %s',
151
- data.projects.length,
152
- cursor,
153
- );
154
- if (data.projects.length < PROJECTS_LIST_LIMIT) {
155
- end = true;
156
- }
157
- }
158
-
159
- return result;
160
- };
161
-
162
- const [ownedProjects, sharedProjects] = await Promise.all([
163
- getList(props.apiClient.listProjects),
164
- getList(props.apiClient.listSharedProjects),
165
- ]);
166
-
167
- const out = writer(props);
168
-
169
- out.write(ownedProjects, {
170
- fields: PROJECT_FIELDS,
171
- title: 'Projects',
172
- });
173
- out.write(sharedProjects, {
174
- fields: PROJECT_FIELDS,
175
- title: 'Shared with me',
176
- });
177
- out.end();
178
- };
179
-
180
- const create = async (
181
- props: CommonProps & {
182
- name?: string;
183
- regionId?: string;
184
- database?: string;
185
- role?: string;
186
- psql: boolean;
187
- setContext: boolean;
188
- '--'?: string[];
189
- },
190
- ) => {
191
- const project: ProjectCreateRequest['project'] = {};
192
- if (props.name) {
193
- project.name = props.name;
194
- }
195
- if (props.regionId) {
196
- project.region_id = props.regionId;
197
- }
198
- project.branch = {};
199
- if (props.database) {
200
- project.branch.database_name = props.database;
201
- }
202
- if (props.role) {
203
- project.branch.role_name = props.role;
204
- }
205
- const { data } = await props.apiClient.createProject({
206
- project,
207
- });
208
-
209
- if (props.setContext) {
210
- updateContextFile(props.contextFile, {
211
- projectId: data.project.id,
212
- branchId: data.branch.id,
213
- });
214
- }
215
-
216
- const out = writer(props);
217
- out.write(data.project, { fields: PROJECT_FIELDS, title: 'Project' });
218
- out.write(data.connection_uris, {
219
- fields: ['connection_uri'],
220
- title: 'Connection URIs',
221
- });
222
- out.end();
223
-
224
- if (props.psql) {
225
- const connection_uri = data.connection_uris[0].connection_uri;
226
- const psqlArgs = props['--'];
227
- await psql(connection_uri, psqlArgs);
228
- }
229
- };
230
-
231
- const deleteProject = async (props: CommonProps & IdOrNameProps) => {
232
- const { data } = await props.apiClient.deleteProject(props.id);
233
- writer(props).end(data.project, {
234
- fields: PROJECT_FIELDS,
235
- });
236
- };
237
-
238
- const update = async (
239
- props: CommonProps &
240
- IdOrNameProps & {
241
- name?: string;
242
- ipAllow?: string[];
243
- ipPrimaryOnly?: boolean;
244
- },
245
- ) => {
246
- const project: ProjectUpdateRequest['project'] = {};
247
- if (props.name) {
248
- project.name = props.name;
249
- }
250
- if (props.ipAllow || props.ipPrimaryOnly != undefined) {
251
- const { data } = await props.apiClient.getProject(props.id);
252
- const existingAllowedIps = data.project.settings?.allowed_ips;
253
-
254
- project.settings = {
255
- allowed_ips: {
256
- ips: props.ipAllow ?? existingAllowedIps?.ips ?? [],
257
- primary_branch_only:
258
- props.ipPrimaryOnly ??
259
- existingAllowedIps?.primary_branch_only ??
260
- false,
261
- },
262
- };
263
- }
264
-
265
- const { data } = await props.apiClient.updateProject(props.id, {
266
- project,
267
- });
268
-
269
- writer(props).end(data.project, { fields: PROJECT_FIELDS });
270
- };
271
-
272
- const get = async (props: CommonProps & IdOrNameProps) => {
273
- const { data } = await props.apiClient.getProject(props.id);
274
- writer(props).end(data.project, { fields: PROJECT_FIELDS });
275
- };
@@ -1,46 +0,0 @@
1
- import { describe } from '@jest/globals';
2
-
3
- import { testCliCommand } from '../test_utils/test_cli_command.js';
4
-
5
- describe('roles', () => {
6
- testCliCommand({
7
- name: 'list',
8
- args: ['roles', 'list', '--project-id', 'test', '--branch', 'test_branch'],
9
- expected: {
10
- snapshot: true,
11
- },
12
- });
13
-
14
- testCliCommand({
15
- name: 'create',
16
- args: [
17
- 'roles',
18
- 'create',
19
- '--project-id',
20
- 'test',
21
- '--branch',
22
- 'test_branch',
23
- '--name',
24
- 'test_role',
25
- ],
26
- expected: {
27
- snapshot: true,
28
- },
29
- });
30
-
31
- testCliCommand({
32
- name: 'delete',
33
- args: [
34
- 'roles',
35
- 'delete',
36
- 'test_role',
37
- '--project-id',
38
- 'test',
39
- '--branch',
40
- 'test_branch',
41
- ],
42
- expected: {
43
- snapshot: true,
44
- },
45
- });
46
- });
@@ -1,100 +0,0 @@
1
- import yargs from 'yargs';
2
- import { retryOnLock } from '../api.js';
3
- import { branchIdFromProps, fillSingleProject } from '../utils/enrichers.js';
4
-
5
- import { BranchScopeProps } from '../types.js';
6
- import { writer } from '../writer.js';
7
-
8
- const ROLES_FIELDS = ['name', 'created_at'] as const;
9
-
10
- export const command = 'roles';
11
- export const describe = 'Manage roles';
12
- export const aliases = ['role'];
13
- export const builder = (argv: yargs.Argv) =>
14
- argv
15
- .usage('$0 roles <sub-command> [options]')
16
- .options({
17
- 'project-id': {
18
- describe: 'Project ID',
19
- type: 'string',
20
- },
21
- branch: {
22
- describe: 'Branch ID or name',
23
- type: 'string',
24
- },
25
- })
26
- .middleware(fillSingleProject as any)
27
- .command(
28
- 'list',
29
- 'List roles',
30
- (yargs) => yargs,
31
- async (args) => await list(args as any),
32
- )
33
- .command(
34
- 'create',
35
- 'Create a role',
36
- (yargs) =>
37
- yargs.options({
38
- name: {
39
- describe: 'Role name',
40
- type: 'string',
41
- demandOption: true,
42
- },
43
- }),
44
- async (args) => await create(args as any),
45
- )
46
- .command(
47
- 'delete <role>',
48
- 'Delete a role',
49
- (yargs) => yargs,
50
- async (args) => await deleteRole(args as any),
51
- );
52
-
53
- export const handler = (args: yargs.Argv) => {
54
- return args;
55
- };
56
-
57
- export const list = async (props: BranchScopeProps) => {
58
- const branchId = await branchIdFromProps(props);
59
- const { data } = await props.apiClient.listProjectBranchRoles(
60
- props.projectId,
61
- branchId,
62
- );
63
- writer(props).end(data.roles, {
64
- fields: ROLES_FIELDS,
65
- });
66
- };
67
-
68
- export const create = async (
69
- props: BranchScopeProps & {
70
- name: string;
71
- },
72
- ) => {
73
- const branchId = await branchIdFromProps(props);
74
- const { data } = await retryOnLock(() =>
75
- props.apiClient.createProjectBranchRole(props.projectId, branchId, {
76
- role: {
77
- name: props.name,
78
- },
79
- }),
80
- );
81
- writer(props).end(data.role, {
82
- fields: ROLES_FIELDS,
83
- });
84
- };
85
-
86
- export const deleteRole = async (
87
- props: BranchScopeProps & { role: string },
88
- ) => {
89
- const branchId = await branchIdFromProps(props);
90
- const { data } = await retryOnLock(() =>
91
- props.apiClient.deleteProjectBranchRole(
92
- props.projectId,
93
- branchId,
94
- props.role,
95
- ),
96
- );
97
- writer(props).end(data.role, {
98
- fields: ROLES_FIELDS,
99
- });
100
- };
@@ -1,64 +0,0 @@
1
- import { tmpdir } from 'node:os';
2
- import { join } from 'node:path';
3
- import { rmSync, writeFileSync } from 'node:fs';
4
- import { afterAll, describe } from '@jest/globals';
5
- import { testCliCommand } from '../test_utils/test_cli_command';
6
-
7
- const CONTEXT_FILE = join(tmpdir(), `neon_${Date.now()}`);
8
-
9
- describe('set_context', () => {
10
- afterAll(() => {
11
- rmSync(CONTEXT_FILE);
12
- });
13
-
14
- describe('should set the context', () => {
15
- testCliCommand({
16
- name: 'set-context',
17
- args: [
18
- 'set-context',
19
- '--project-id',
20
- 'test',
21
- '--context-file',
22
- CONTEXT_FILE,
23
- ],
24
- });
25
-
26
- testCliCommand({
27
- name: 'list branches selecting project from the context',
28
- args: ['branches', 'list', '--context-file', CONTEXT_FILE],
29
- expected: {
30
- snapshot: true,
31
- },
32
- });
33
-
34
- const overrideContextFile = join(
35
- tmpdir(),
36
- `neon_override_ctx_${Date.now()}`,
37
- );
38
- testCliCommand({
39
- name: 'get branch id overrides context set branch',
40
- before: async () => {
41
- writeFileSync(
42
- overrideContextFile,
43
- JSON.stringify({
44
- projectId: 'test',
45
- branchId: 'br-cloudy-branch-12345678',
46
- }),
47
- );
48
- },
49
- after: async () => {
50
- rmSync(overrideContextFile);
51
- },
52
- args: [
53
- 'branches',
54
- 'get',
55
- 'br-sunny-branch-123456',
56
- '--context-file',
57
- overrideContextFile,
58
- ],
59
- expected: {
60
- snapshot: true,
61
- },
62
- });
63
- });
64
- });
@@ -1,27 +0,0 @@
1
- import yargs from 'yargs';
2
- import { Context, updateContextFile } from '../context.js';
3
- import { branchIdFromProps } from '../utils/enrichers.js';
4
- import { BranchScopeProps } from '../types.js';
5
-
6
- export const command = 'set-context';
7
- export const describe = 'Set the current context';
8
- export const builder = (argv: yargs.Argv) =>
9
- argv.usage('$0 set-context [options]').options({
10
- 'project-id': {
11
- describe: 'Project ID',
12
- type: 'string',
13
- },
14
- branch: {
15
- describe: 'Branch ID or name',
16
- type: 'string',
17
- },
18
- });
19
-
20
- export const handler = async (props: BranchScopeProps) => {
21
- const branchId = await branchIdFromProps(props);
22
- const context: Context = {
23
- projectId: props.projectId,
24
- branchId,
25
- };
26
- updateContextFile(props.contextFile, context);
27
- };