neonctl 1.27.6 → 1.29.1
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.
- package/.bump +1 -0
- package/.editorconfig +7 -0
- package/.eslintrc.cjs +15 -0
- package/.github/workflows/commitlint.yml +46 -0
- package/.github/workflows/pr.yml +25 -0
- package/.github/workflows/release.yml +30 -0
- package/.husky/commit-msg +4 -0
- package/.husky/pre-commit +4 -0
- package/.nvmrc +1 -0
- package/.prettierignore +3 -0
- package/.prettierrc.json +3 -0
- package/.releaserc.json +47 -0
- package/LICENSE +202 -0
- package/commitlint.config.cjs +7 -0
- package/generateOptionsFromSpec.ts +68 -0
- package/jest/setup.js +5 -0
- package/jest.config.ts +199 -0
- package/mocks/bin/psql.cjs +9 -0
- package/mocks/main/projects/GET.js +27 -0
- package/mocks/main/projects/POST.js +22 -0
- package/mocks/main/projects/shared/GET.js +16 -0
- package/mocks/main/projects/test/DELETE.json +7 -0
- package/mocks/main/projects/test/GET.json +13 -0
- package/mocks/main/projects/test/PATCH.js +18 -0
- package/mocks/main/projects/test/branches/GET.json +25 -0
- package/mocks/main/projects/test/branches/POST.js +83 -0
- package/mocks/main/projects/test/branches/br-cloudy-branch-12345678/DELETE.json +7 -0
- package/mocks/main/projects/test/branches/br-cloudy-branch-12345678/GET.json +9 -0
- package/mocks/main/projects/test/branches/br-cloudy-branch-12345678/PATCH.js +14 -0
- package/mocks/main/projects/test/branches/br-cloudy-branch-12345678/databases/GET.json +6 -0
- package/mocks/main/projects/test/branches/br-cloudy-branch-12345678/databases/POST.js +13 -0
- package/mocks/main/projects/test/branches/br-cloudy-branch-12345678/databases/test_db/DELETE.json +6 -0
- package/mocks/main/projects/test/branches/br-cloudy-branch-12345678/endpoints/GET.json +26 -0
- package/mocks/main/projects/test/branches/br-cloudy-branch-12345678/endpoints/POST.json +6 -0
- package/mocks/main/projects/test/branches/br-cloudy-branch-12345678/roles/GET.json +3 -0
- package/mocks/main/projects/test/branches/br-cloudy-branch-12345678/roles/POST.js +14 -0
- package/mocks/main/projects/test/branches/br-cloudy-branch-12345678/roles/test_role/DELETE.json +6 -0
- package/mocks/main/projects/test/branches/br-cloudy-branch-12345678/roles/test_role/reveal_password/GET.json +3 -0
- package/mocks/main/projects/test/branches/br-cloudy-branch-12345678/set_as_primary/POST.json +9 -0
- package/mocks/main/projects/test/branches/br-numbered-branch-123456/GET.json +10 -0
- package/mocks/main/projects/test/branches/br-sunny-branch-123456/DELETE.json +7 -0
- package/mocks/main/projects/test/branches/br-sunny-branch-123456/GET.json +10 -0
- package/mocks/main/projects/test/branches/br-sunny-branch-123456/PATCH.js +14 -0
- package/mocks/main/projects/test/branches/br-sunny-branch-123456/databases/GET.json +6 -0
- package/mocks/main/projects/test/branches/br-sunny-branch-123456/databases/POST.js +13 -0
- package/mocks/main/projects/test/branches/br-sunny-branch-123456/databases/test_db/DELETE.json +6 -0
- package/mocks/main/projects/test/branches/br-sunny-branch-123456/endpoints/GET.json +26 -0
- package/mocks/main/projects/test/branches/br-sunny-branch-123456/endpoints/POST.json +6 -0
- package/mocks/main/projects/test/branches/br-sunny-branch-123456/restore/POST.js +16 -0
- package/mocks/main/projects/test/branches/br-sunny-branch-123456/roles/GET.json +3 -0
- package/mocks/main/projects/test/branches/br-sunny-branch-123456/roles/POST.js +14 -0
- package/mocks/main/projects/test/branches/br-sunny-branch-123456/roles/test_role/DELETE.json +6 -0
- package/mocks/main/projects/test/branches/br-sunny-branch-123456/roles/test_role/reveal_password/GET.json +3 -0
- package/mocks/main/projects/test/branches/br-sunny-branch-123456/set_as_primary/POST.json +9 -0
- package/mocks/main/projects/test/endpoints/GET.json +9 -0
- package/mocks/main/projects/test/endpoints/POST.js +32 -0
- package/mocks/main/projects/test/endpoints/test_endpoint_id/DELETE.json +7 -0
- package/mocks/main/projects/test/endpoints/test_endpoint_id/GET.json +9 -0
- package/mocks/main/projects/test/endpoints/test_endpoint_id/PATCH.js +17 -0
- package/mocks/main/projects/test/operations/GET.json +22 -0
- package/mocks/main/users/me/GET.json +5 -0
- package/mocks/restore/projects/test/branches/GET.json +21 -0
- package/mocks/restore/projects/test/branches/br-another-branch-123456/GET.json +6 -0
- package/mocks/restore/projects/test/branches/br-another-branch-123456/restore/POST.js +13 -0
- package/mocks/restore/projects/test/branches/br-any-branch-123456/GET.json +6 -0
- package/mocks/restore/projects/test/branches/br-parent-tots-123456/GET.json +7 -0
- package/mocks/restore/projects/test/branches/br-parent-tots-123456/restore/POST.js +14 -0
- package/mocks/restore/projects/test/branches/br-self-tolsn-123456/GET.json +6 -0
- package/mocks/restore/projects/test/branches/br-self-tolsn-123456/restore/POST.js +15 -0
- package/mocks/single_project/projects/GET.json +10 -0
- package/mocks/single_project/projects/test-project-123456/GET.json +14 -0
- package/mocks/single_project/projects/test-project-123456/branches/GET.json +11 -0
- package/mocks/single_project/projects/test-project-123456/branches/br-main-branch-123456/databases/GET.json +3 -0
- package/mocks/single_project/projects/test-project-123456/branches/br-main-branch-123456/endpoints/GET.json +10 -0
- package/mocks/single_project/projects/test-project-123456/branches/br-main-branch-123456/roles/GET.json +3 -0
- package/mocks/single_project/projects/test-project-123456/branches/br-main-branch-123456/roles/test_role/reveal_password/GET.json +3 -0
- package/package.json +7 -6
- package/pkg.js +45 -3
- package/rollup.config.js +20 -0
- package/snapshots/commands/branches.test.snap +221 -0
- package/snapshots/commands/connection_string.test.snap +70 -0
- package/snapshots/commands/databases.test.snap +20 -0
- package/snapshots/commands/ip_allow.test.snap +55 -0
- package/snapshots/commands/operations.test.snap +17 -0
- package/snapshots/commands/projects.test.snap +141 -0
- package/snapshots/commands/roles.test.snap +19 -0
- package/snapshots/commands/set_context.test.snap +30 -0
- package/snapshots/writer.test.snap +60 -0
- package/snapshotsResolver.cjs +32 -0
- package/src/analytics.ts +95 -0
- package/src/api.ts +44 -0
- package/src/auth.ts +137 -0
- package/{cli.js → src/cli.ts} +1 -0
- package/src/commands/auth.test.ts +62 -0
- package/src/commands/auth.ts +148 -0
- package/src/commands/branches.test.ts +354 -0
- package/src/commands/branches.ts +451 -0
- package/src/commands/connection_string.test.ts +250 -0
- package/src/commands/connection_string.ts +210 -0
- package/src/commands/databases.test.ts +55 -0
- package/src/commands/databases.ts +129 -0
- package/src/commands/help.test.ts +13 -0
- package/{commands/index.js → src/commands/index.ts} +11 -10
- package/src/commands/ip_allow.test.ts +86 -0
- package/src/commands/ip_allow.ts +202 -0
- package/src/commands/operations.test.ts +13 -0
- package/src/commands/operations.ts +41 -0
- package/src/commands/projects.test.ts +147 -0
- package/src/commands/projects.ts +275 -0
- package/src/commands/roles.test.ts +46 -0
- package/src/commands/roles.ts +100 -0
- package/src/commands/set_context.test.ts +64 -0
- package/src/commands/set_context.ts +27 -0
- package/src/commands/user.ts +21 -0
- package/src/config.ts +22 -0
- package/src/context.ts +61 -0
- package/src/env.ts +7 -0
- package/src/errors.ts +24 -0
- package/src/help.ts +185 -0
- package/src/index.ts +180 -0
- package/src/log.ts +16 -0
- package/src/parameters.gen.ts +332 -0
- package/src/pkg.ts +9 -0
- package/src/test_utils/mock_server.ts +27 -0
- package/src/test_utils/oauth_server.ts +10 -0
- package/src/test_utils/test_cli_command.ts +117 -0
- package/src/types.ts +25 -0
- package/src/utils/enrichers.ts +73 -0
- package/src/utils/formats.test.ts +41 -0
- package/src/utils/formats.ts +11 -0
- package/src/utils/middlewares.ts +23 -0
- package/src/utils/point_in_time.ts +86 -0
- package/src/utils/psql.ts +29 -0
- package/src/utils/string.ts +8 -0
- package/src/utils/ui.ts +64 -0
- package/src/writer.test.ts +98 -0
- package/src/writer.ts +131 -0
- package/tsconfig.json +17 -0
- package/analytics.js +0 -78
- package/api.js +0 -35
- package/auth.js +0 -101
- package/commands/auth.js +0 -102
- package/commands/auth.test.js +0 -42
- package/commands/branches.js +0 -311
- package/commands/branches.test.js +0 -321
- package/commands/connection_string.js +0 -137
- package/commands/connection_string.test.js +0 -204
- package/commands/databases.js +0 -79
- package/commands/databases.test.js +0 -51
- package/commands/help.test.js +0 -11
- package/commands/ip_allow.js +0 -135
- package/commands/ip_allow.test.js +0 -78
- package/commands/operations.js +0 -28
- package/commands/operations.test.js +0 -11
- package/commands/projects.js +0 -156
- package/commands/projects.test.js +0 -116
- package/commands/roles.js +0 -57
- package/commands/roles.test.js +0 -42
- package/commands/set_context.js +0 -22
- package/commands/set_context.test.js +0 -53
- package/commands/user.js +0 -15
- package/config.js +0 -11
- package/context.js +0 -48
- package/env.js +0 -6
- package/errors.js +0 -16
- package/help.js +0 -146
- package/index.js +0 -168
- package/log.js +0 -15
- package/parameters.gen.js +0 -302
- package/test_utils/mock_server.js +0 -16
- package/test_utils/oauth_server.js +0 -9
- package/test_utils/test_cli_command.js +0 -80
- package/types.js +0 -1
- package/utils/enrichers.js +0 -49
- package/utils/formats.js +0 -5
- package/utils/formats.test.js +0 -32
- package/utils/middlewares.js +0 -20
- package/utils/point_in_time.js +0 -44
- package/utils/psql.js +0 -24
- package/utils/string.js +0 -5
- package/utils/ui.js +0 -59
- package/writer.js +0 -87
- package/writer.test.js +0 -86
- /package/{callback.html → src/callback.html} +0 -0
package/commands/branches.js
DELETED
|
@@ -1,311 +0,0 @@
|
|
|
1
|
-
import { EndpointType } from '@neondatabase/api-client';
|
|
2
|
-
import { writer } from '../writer.js';
|
|
3
|
-
import { branchCreateRequest } from '../parameters.gen.js';
|
|
4
|
-
import { retryOnLock } from '../api.js';
|
|
5
|
-
import { branchIdFromProps, branchIdResolve, fillSingleProject, } from '../utils/enrichers.js';
|
|
6
|
-
import { looksLikeBranchId, looksLikeLSN, looksLikeTimestamp, } from '../utils/formats.js';
|
|
7
|
-
import { psql } from '../utils/psql.js';
|
|
8
|
-
import { parsePointInTime } from '../utils/point_in_time.js';
|
|
9
|
-
import { log } from '../log.js';
|
|
10
|
-
const BRANCH_FIELDS = [
|
|
11
|
-
'id',
|
|
12
|
-
'name',
|
|
13
|
-
'primary',
|
|
14
|
-
'created_at',
|
|
15
|
-
'updated_at',
|
|
16
|
-
];
|
|
17
|
-
const BRANCH_FIELDS_RESET = [
|
|
18
|
-
'id',
|
|
19
|
-
'name',
|
|
20
|
-
'primary',
|
|
21
|
-
'created_at',
|
|
22
|
-
'last_reset_at',
|
|
23
|
-
];
|
|
24
|
-
export const command = 'branches';
|
|
25
|
-
export const describe = 'Manage branches';
|
|
26
|
-
export const aliases = ['branch'];
|
|
27
|
-
export const builder = (argv) => argv
|
|
28
|
-
.usage('$0 branches <sub-command> [options]')
|
|
29
|
-
.options({
|
|
30
|
-
'project-id': {
|
|
31
|
-
describe: 'Project ID',
|
|
32
|
-
type: 'string',
|
|
33
|
-
},
|
|
34
|
-
})
|
|
35
|
-
.middleware(fillSingleProject)
|
|
36
|
-
.command('list', 'List branches', (yargs) => yargs, async (args) => await list(args))
|
|
37
|
-
.command('create', 'Create a branch', (yargs) => yargs.options({
|
|
38
|
-
name: branchCreateRequest['branch.name'],
|
|
39
|
-
parent: {
|
|
40
|
-
describe: 'Parent branch name or id or timestamp or LSN. Defaults to the primary branch',
|
|
41
|
-
type: 'string',
|
|
42
|
-
},
|
|
43
|
-
compute: {
|
|
44
|
-
describe: 'Create a branch with or without a compute. By default branch is created with a read-write compute. To create a branch without compute use --no-compute',
|
|
45
|
-
type: 'boolean',
|
|
46
|
-
default: true,
|
|
47
|
-
},
|
|
48
|
-
type: {
|
|
49
|
-
describe: 'Type of compute to add',
|
|
50
|
-
type: 'string',
|
|
51
|
-
implies: 'compute',
|
|
52
|
-
default: EndpointType.ReadWrite,
|
|
53
|
-
choices: Object.values(EndpointType),
|
|
54
|
-
},
|
|
55
|
-
'suspend-timeout': {
|
|
56
|
-
describe: '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).',
|
|
57
|
-
type: 'number',
|
|
58
|
-
implies: 'compute',
|
|
59
|
-
default: 0,
|
|
60
|
-
},
|
|
61
|
-
psql: {
|
|
62
|
-
type: 'boolean',
|
|
63
|
-
describe: 'Connect to a new branch via psql',
|
|
64
|
-
default: false,
|
|
65
|
-
},
|
|
66
|
-
}), async (args) => await create(args))
|
|
67
|
-
.command('reset <id|name>', 'Reset a branch', (yargs) => yargs.options({
|
|
68
|
-
parent: {
|
|
69
|
-
describe: 'Reset to a parent branch',
|
|
70
|
-
type: 'boolean',
|
|
71
|
-
default: false,
|
|
72
|
-
},
|
|
73
|
-
'preserve-under-name': {
|
|
74
|
-
describe: 'Name under which to preserve the old branch',
|
|
75
|
-
},
|
|
76
|
-
}), async (args) => await reset(args))
|
|
77
|
-
.command('restore <target-id|name> <source>[@(timestamp|lsn)]', 'Restores a branch to a specific point in time\n<source> can be: ^self, ^parent, or <source-branch-id|name>', (yargs) => yargs
|
|
78
|
-
// we want to show meaningful help for the command
|
|
79
|
-
// but it makes yargs to fail on parsing the command
|
|
80
|
-
// so we need to fill in the missing args manually
|
|
81
|
-
.middleware((args) => {
|
|
82
|
-
args.id = args.targetId;
|
|
83
|
-
args.pointInTime = args['source@(timestamp'];
|
|
84
|
-
})
|
|
85
|
-
.usage('$0 branches restore <target-id|name> <source>[@(timestamp|lsn)]')
|
|
86
|
-
.options({
|
|
87
|
-
'preserve-under-name': {
|
|
88
|
-
describe: 'Name under which to preserve the old branch',
|
|
89
|
-
},
|
|
90
|
-
})
|
|
91
|
-
.example([
|
|
92
|
-
[
|
|
93
|
-
'$0 branches restore main br-source-branch-123456',
|
|
94
|
-
'Restores main to the head of the branch with id br-source-branch-123456',
|
|
95
|
-
],
|
|
96
|
-
[
|
|
97
|
-
'$0 branches restore main source@2021-01-01T00:00:00Z',
|
|
98
|
-
'Restores main to the timestamp 2021-01-01T00:00:00Z of the source branch',
|
|
99
|
-
],
|
|
100
|
-
[
|
|
101
|
-
'$0 branches restore my-branch ^self@0/123456',
|
|
102
|
-
'Restores my-branch to the LSN 0/123456 from its own history',
|
|
103
|
-
],
|
|
104
|
-
[
|
|
105
|
-
'$0 branches restore my-branch ^parent',
|
|
106
|
-
'Restore my-branch to the head of its parent branch',
|
|
107
|
-
],
|
|
108
|
-
]), async (args) => await restore(args))
|
|
109
|
-
.command('rename <id|name> <new-name>', 'Rename a branch', (yargs) => yargs, async (args) => await rename(args))
|
|
110
|
-
.command('set-primary <id|name>', 'Set a branch as primary', (yargs) => yargs, async (args) => await setPrimary(args))
|
|
111
|
-
.command('add-compute <id|name>', 'Add a compute to a branch', (yargs) => yargs.options({
|
|
112
|
-
type: {
|
|
113
|
-
type: 'string',
|
|
114
|
-
choices: Object.values(EndpointType),
|
|
115
|
-
describe: 'Type of compute to add',
|
|
116
|
-
default: EndpointType.ReadOnly,
|
|
117
|
-
},
|
|
118
|
-
}), async (args) => await addCompute(args))
|
|
119
|
-
.command('delete <id|name>', 'Delete a branch', (yargs) => yargs, async (args) => await deleteBranch(args))
|
|
120
|
-
.command('get <id|name>', 'Get a branch', (yargs) => yargs, async (args) => await get(args));
|
|
121
|
-
export const handler = (args) => {
|
|
122
|
-
return args;
|
|
123
|
-
};
|
|
124
|
-
const list = async (props) => {
|
|
125
|
-
const { data } = await props.apiClient.listProjectBranches(props.projectId);
|
|
126
|
-
writer(props).end(data.branches, {
|
|
127
|
-
fields: BRANCH_FIELDS,
|
|
128
|
-
});
|
|
129
|
-
};
|
|
130
|
-
const create = async (props) => {
|
|
131
|
-
const parentProps = await (() => {
|
|
132
|
-
if (!props.parent) {
|
|
133
|
-
return props.apiClient
|
|
134
|
-
.listProjectBranches(props.projectId)
|
|
135
|
-
.then(({ data }) => {
|
|
136
|
-
const branch = data.branches.find((b) => b.primary);
|
|
137
|
-
if (!branch) {
|
|
138
|
-
throw new Error('No primary branch found');
|
|
139
|
-
}
|
|
140
|
-
return { parent_id: branch.id };
|
|
141
|
-
});
|
|
142
|
-
}
|
|
143
|
-
if (looksLikeLSN(props.parent)) {
|
|
144
|
-
return { parent_lsn: props.parent };
|
|
145
|
-
}
|
|
146
|
-
if (looksLikeTimestamp(props.parent)) {
|
|
147
|
-
return { parent_timestamp: props.parent };
|
|
148
|
-
}
|
|
149
|
-
if (looksLikeBranchId(props.parent)) {
|
|
150
|
-
return { parent_id: props.parent };
|
|
151
|
-
}
|
|
152
|
-
return props.apiClient
|
|
153
|
-
.listProjectBranches(props.projectId)
|
|
154
|
-
.then(({ data }) => {
|
|
155
|
-
const branch = data.branches.find((b) => b.name === props.parent);
|
|
156
|
-
if (!branch) {
|
|
157
|
-
throw new Error(`Branch ${props.parent} not found`);
|
|
158
|
-
}
|
|
159
|
-
return { parent_id: branch.id };
|
|
160
|
-
});
|
|
161
|
-
})();
|
|
162
|
-
const { data } = await retryOnLock(() => props.apiClient.createProjectBranch(props.projectId, {
|
|
163
|
-
branch: {
|
|
164
|
-
name: props.name,
|
|
165
|
-
...parentProps,
|
|
166
|
-
},
|
|
167
|
-
endpoints: props.compute
|
|
168
|
-
? [
|
|
169
|
-
{
|
|
170
|
-
type: props.type,
|
|
171
|
-
suspend_timeout_seconds: props.suspendTimeout === 0 ? undefined : props.suspendTimeout,
|
|
172
|
-
},
|
|
173
|
-
]
|
|
174
|
-
: [],
|
|
175
|
-
}));
|
|
176
|
-
const out = writer(props);
|
|
177
|
-
out.write(data.branch, {
|
|
178
|
-
fields: BRANCH_FIELDS,
|
|
179
|
-
title: 'branch',
|
|
180
|
-
});
|
|
181
|
-
if (data.endpoints?.length > 0) {
|
|
182
|
-
out.write(data.endpoints, {
|
|
183
|
-
fields: ['id', 'created_at'],
|
|
184
|
-
title: 'endpoints',
|
|
185
|
-
});
|
|
186
|
-
}
|
|
187
|
-
if (data.connection_uris && data.connection_uris?.length > 0) {
|
|
188
|
-
out.write(data.connection_uris, {
|
|
189
|
-
fields: ['connection_uri'],
|
|
190
|
-
title: 'connection_uris',
|
|
191
|
-
});
|
|
192
|
-
}
|
|
193
|
-
out.end();
|
|
194
|
-
if (props.psql) {
|
|
195
|
-
if (!data.connection_uris || !data.connection_uris?.length) {
|
|
196
|
-
throw new Error(`Branch ${data.branch.id} doesn't have a connection uri`);
|
|
197
|
-
}
|
|
198
|
-
const connection_uri = data.connection_uris[0].connection_uri;
|
|
199
|
-
const psqlArgs = props['--'];
|
|
200
|
-
await psql(connection_uri, psqlArgs);
|
|
201
|
-
}
|
|
202
|
-
};
|
|
203
|
-
const rename = async (props) => {
|
|
204
|
-
const branchId = await branchIdFromProps(props);
|
|
205
|
-
const { data } = await retryOnLock(() => props.apiClient.updateProjectBranch(props.projectId, branchId, {
|
|
206
|
-
branch: {
|
|
207
|
-
name: props.newName,
|
|
208
|
-
},
|
|
209
|
-
}));
|
|
210
|
-
writer(props).end(data.branch, {
|
|
211
|
-
fields: BRANCH_FIELDS,
|
|
212
|
-
});
|
|
213
|
-
};
|
|
214
|
-
const setPrimary = async (props) => {
|
|
215
|
-
const branchId = await branchIdFromProps(props);
|
|
216
|
-
const { data } = await retryOnLock(() => props.apiClient.setPrimaryProjectBranch(props.projectId, branchId));
|
|
217
|
-
writer(props).end(data.branch, {
|
|
218
|
-
fields: BRANCH_FIELDS,
|
|
219
|
-
});
|
|
220
|
-
};
|
|
221
|
-
const deleteBranch = async (props) => {
|
|
222
|
-
const branchId = await branchIdFromProps(props);
|
|
223
|
-
const { data } = await retryOnLock(() => props.apiClient.deleteProjectBranch(props.projectId, branchId));
|
|
224
|
-
writer(props).end(data.branch, {
|
|
225
|
-
fields: BRANCH_FIELDS,
|
|
226
|
-
});
|
|
227
|
-
};
|
|
228
|
-
const get = async (props) => {
|
|
229
|
-
const branchId = await branchIdFromProps(props);
|
|
230
|
-
const { data } = await props.apiClient.getProjectBranch(props.projectId, branchId);
|
|
231
|
-
writer(props).end(data.branch, {
|
|
232
|
-
fields: BRANCH_FIELDS,
|
|
233
|
-
});
|
|
234
|
-
};
|
|
235
|
-
const addCompute = async (props) => {
|
|
236
|
-
const branchId = await branchIdFromProps(props);
|
|
237
|
-
const { data } = await retryOnLock(() => props.apiClient.createProjectEndpoint(props.projectId, {
|
|
238
|
-
endpoint: {
|
|
239
|
-
branch_id: branchId,
|
|
240
|
-
type: props.type,
|
|
241
|
-
},
|
|
242
|
-
}));
|
|
243
|
-
writer(props).end(data.endpoint, {
|
|
244
|
-
fields: ['id', 'host'],
|
|
245
|
-
});
|
|
246
|
-
};
|
|
247
|
-
const reset = async (props) => {
|
|
248
|
-
if (!props.parent) {
|
|
249
|
-
throw new Error('Only resetting to parent is supported for now');
|
|
250
|
-
}
|
|
251
|
-
const branchId = await branchIdFromProps(props);
|
|
252
|
-
const { data: { branch }, } = await props.apiClient.getProjectBranch(props.projectId, branchId);
|
|
253
|
-
if (!branch.parent_id) {
|
|
254
|
-
throw new Error('Branch has no parent');
|
|
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
|
-
},
|
|
263
|
-
}));
|
|
264
|
-
const resultBranch = data.branch;
|
|
265
|
-
writer(props).end(resultBranch, {
|
|
266
|
-
// need to reset types until we expose reset api
|
|
267
|
-
fields: BRANCH_FIELDS_RESET,
|
|
268
|
-
});
|
|
269
|
-
};
|
|
270
|
-
const restore = async (props) => {
|
|
271
|
-
const targetBranchId = await branchIdResolve({
|
|
272
|
-
branch: props.id,
|
|
273
|
-
projectId: props.projectId,
|
|
274
|
-
apiClient: props.apiClient,
|
|
275
|
-
});
|
|
276
|
-
const pointInTime = await parsePointInTime({
|
|
277
|
-
pointInTime: props.pointInTime,
|
|
278
|
-
targetBranchId,
|
|
279
|
-
projectId: props.projectId,
|
|
280
|
-
api: props.apiClient,
|
|
281
|
-
});
|
|
282
|
-
log.info(`Restoring branch ${targetBranchId} to the branch ${pointInTime.branchId} ${(pointInTime.tag === 'lsn' && 'LSN ' + pointInTime.lsn) ||
|
|
283
|
-
(pointInTime.tag === 'timestamp' &&
|
|
284
|
-
'timestamp ' + pointInTime.timestamp) ||
|
|
285
|
-
'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
|
-
},
|
|
297
|
-
}));
|
|
298
|
-
const branch = data.branch;
|
|
299
|
-
const writeInst = writer(props).write(branch, {
|
|
300
|
-
title: 'Restored branch',
|
|
301
|
-
fields: ['id', 'name', 'last_reset_at'],
|
|
302
|
-
});
|
|
303
|
-
if (props.preserveUnderName && branch.parent_id) {
|
|
304
|
-
const { data } = await props.apiClient.getProjectBranch(props.projectId, branch.parent_id);
|
|
305
|
-
writeInst.write(data.branch, {
|
|
306
|
-
title: 'Backup branch',
|
|
307
|
-
fields: ['id', 'name'],
|
|
308
|
-
});
|
|
309
|
-
}
|
|
310
|
-
writeInst.end();
|
|
311
|
-
};
|
|
@@ -1,321 +0,0 @@
|
|
|
1
|
-
import { describe } from '@jest/globals';
|
|
2
|
-
import { testCliCommand } from '../test_utils/test_cli_command.js';
|
|
3
|
-
describe('branches', () => {
|
|
4
|
-
/* list */
|
|
5
|
-
testCliCommand({
|
|
6
|
-
name: 'list',
|
|
7
|
-
args: ['branches', 'list', '--project-id', 'test'],
|
|
8
|
-
expected: {
|
|
9
|
-
snapshot: true,
|
|
10
|
-
},
|
|
11
|
-
});
|
|
12
|
-
/* create */
|
|
13
|
-
testCliCommand({
|
|
14
|
-
name: 'create by default with r/w endpoint',
|
|
15
|
-
args: [
|
|
16
|
-
'branches',
|
|
17
|
-
'create',
|
|
18
|
-
'--project-id',
|
|
19
|
-
'test',
|
|
20
|
-
'--name',
|
|
21
|
-
'test_branch',
|
|
22
|
-
],
|
|
23
|
-
expected: {
|
|
24
|
-
snapshot: true,
|
|
25
|
-
},
|
|
26
|
-
});
|
|
27
|
-
testCliCommand({
|
|
28
|
-
name: 'create branch and connect with psql',
|
|
29
|
-
args: [
|
|
30
|
-
'branches',
|
|
31
|
-
'create',
|
|
32
|
-
'--project-id',
|
|
33
|
-
'test',
|
|
34
|
-
'--name',
|
|
35
|
-
'test_branch',
|
|
36
|
-
'--psql',
|
|
37
|
-
],
|
|
38
|
-
expected: {
|
|
39
|
-
snapshot: true,
|
|
40
|
-
},
|
|
41
|
-
});
|
|
42
|
-
testCliCommand({
|
|
43
|
-
name: 'create branch and connect with psql and psql args',
|
|
44
|
-
args: [
|
|
45
|
-
'branches',
|
|
46
|
-
'create',
|
|
47
|
-
'--project-id',
|
|
48
|
-
'test',
|
|
49
|
-
'--name',
|
|
50
|
-
'test_branch',
|
|
51
|
-
'--psql',
|
|
52
|
-
'--',
|
|
53
|
-
'-c',
|
|
54
|
-
'SELECT 1',
|
|
55
|
-
],
|
|
56
|
-
expected: {
|
|
57
|
-
snapshot: true,
|
|
58
|
-
},
|
|
59
|
-
});
|
|
60
|
-
testCliCommand({
|
|
61
|
-
name: 'create with readonly endpoint',
|
|
62
|
-
args: [
|
|
63
|
-
'branches',
|
|
64
|
-
'create',
|
|
65
|
-
'--project-id',
|
|
66
|
-
'test',
|
|
67
|
-
'--name',
|
|
68
|
-
'test_branch',
|
|
69
|
-
'--type',
|
|
70
|
-
'read_only',
|
|
71
|
-
],
|
|
72
|
-
expected: {
|
|
73
|
-
snapshot: true,
|
|
74
|
-
},
|
|
75
|
-
});
|
|
76
|
-
testCliCommand({
|
|
77
|
-
name: 'create without endpoint',
|
|
78
|
-
args: [
|
|
79
|
-
'branches',
|
|
80
|
-
'create',
|
|
81
|
-
'--project-id',
|
|
82
|
-
'test',
|
|
83
|
-
'--name',
|
|
84
|
-
'test_branch',
|
|
85
|
-
'--no-compute',
|
|
86
|
-
],
|
|
87
|
-
expected: {
|
|
88
|
-
snapshot: true,
|
|
89
|
-
},
|
|
90
|
-
});
|
|
91
|
-
testCliCommand({
|
|
92
|
-
name: 'create with parent by name',
|
|
93
|
-
args: [
|
|
94
|
-
'branches',
|
|
95
|
-
'create',
|
|
96
|
-
'--project-id',
|
|
97
|
-
'test',
|
|
98
|
-
'--name',
|
|
99
|
-
'test_branch_with_parent_name',
|
|
100
|
-
'--parent',
|
|
101
|
-
'main',
|
|
102
|
-
],
|
|
103
|
-
expected: {
|
|
104
|
-
snapshot: true,
|
|
105
|
-
},
|
|
106
|
-
});
|
|
107
|
-
testCliCommand({
|
|
108
|
-
name: 'create with parent by lsn',
|
|
109
|
-
args: [
|
|
110
|
-
'branches',
|
|
111
|
-
'create',
|
|
112
|
-
'--project-id',
|
|
113
|
-
'test',
|
|
114
|
-
'--name',
|
|
115
|
-
'test_branch_with_parent_lsn',
|
|
116
|
-
'--parent',
|
|
117
|
-
'0/123ABC',
|
|
118
|
-
],
|
|
119
|
-
expected: {
|
|
120
|
-
snapshot: true,
|
|
121
|
-
},
|
|
122
|
-
});
|
|
123
|
-
testCliCommand({
|
|
124
|
-
name: 'create with parent by timestamp',
|
|
125
|
-
args: [
|
|
126
|
-
'branches',
|
|
127
|
-
'create',
|
|
128
|
-
'--project-id',
|
|
129
|
-
'test',
|
|
130
|
-
'--name',
|
|
131
|
-
'test_branch_with_parent_timestamp',
|
|
132
|
-
'--parent',
|
|
133
|
-
'2021-01-01T00:00:00.000Z',
|
|
134
|
-
],
|
|
135
|
-
expected: {
|
|
136
|
-
snapshot: true,
|
|
137
|
-
},
|
|
138
|
-
});
|
|
139
|
-
testCliCommand({
|
|
140
|
-
name: 'create with suspend timeout',
|
|
141
|
-
args: [
|
|
142
|
-
'branches',
|
|
143
|
-
'create',
|
|
144
|
-
'--project-id',
|
|
145
|
-
'test',
|
|
146
|
-
'--name',
|
|
147
|
-
'test_branch_with_suspend_timeout',
|
|
148
|
-
'--suspend-timeout',
|
|
149
|
-
'60',
|
|
150
|
-
],
|
|
151
|
-
expected: {
|
|
152
|
-
snapshot: true,
|
|
153
|
-
},
|
|
154
|
-
});
|
|
155
|
-
/* delete */
|
|
156
|
-
testCliCommand({
|
|
157
|
-
name: 'delete by id',
|
|
158
|
-
args: [
|
|
159
|
-
'branches',
|
|
160
|
-
'delete',
|
|
161
|
-
'br-sunny-branch-123456',
|
|
162
|
-
'--project-id',
|
|
163
|
-
'test',
|
|
164
|
-
],
|
|
165
|
-
expected: {
|
|
166
|
-
snapshot: true,
|
|
167
|
-
},
|
|
168
|
-
});
|
|
169
|
-
/* rename */
|
|
170
|
-
testCliCommand({
|
|
171
|
-
name: 'rename',
|
|
172
|
-
args: [
|
|
173
|
-
'branches',
|
|
174
|
-
'rename',
|
|
175
|
-
'test_branch',
|
|
176
|
-
'new_test_branch',
|
|
177
|
-
'--project-id',
|
|
178
|
-
'test',
|
|
179
|
-
],
|
|
180
|
-
expected: {
|
|
181
|
-
snapshot: true,
|
|
182
|
-
},
|
|
183
|
-
});
|
|
184
|
-
/* set primary */
|
|
185
|
-
testCliCommand({
|
|
186
|
-
name: 'set primary by id',
|
|
187
|
-
args: [
|
|
188
|
-
'branches',
|
|
189
|
-
'set-primary',
|
|
190
|
-
'br-sunny-branch-123456',
|
|
191
|
-
'--project-id',
|
|
192
|
-
'test',
|
|
193
|
-
],
|
|
194
|
-
expected: {
|
|
195
|
-
snapshot: true,
|
|
196
|
-
},
|
|
197
|
-
});
|
|
198
|
-
/* get */
|
|
199
|
-
testCliCommand({
|
|
200
|
-
name: 'get by id',
|
|
201
|
-
args: ['branches', 'get', 'br-sunny-branch-123456', '--project-id', 'test'],
|
|
202
|
-
expected: {
|
|
203
|
-
snapshot: true,
|
|
204
|
-
},
|
|
205
|
-
});
|
|
206
|
-
testCliCommand({
|
|
207
|
-
name: 'get by id',
|
|
208
|
-
args: [
|
|
209
|
-
'branches',
|
|
210
|
-
'get',
|
|
211
|
-
'br-cloudy-branch-12345678',
|
|
212
|
-
'--project-id',
|
|
213
|
-
'test',
|
|
214
|
-
],
|
|
215
|
-
expected: {
|
|
216
|
-
snapshot: true,
|
|
217
|
-
},
|
|
218
|
-
});
|
|
219
|
-
testCliCommand({
|
|
220
|
-
name: 'get by name',
|
|
221
|
-
args: ['branches', 'get', 'test_branch', '--project-id', 'test'],
|
|
222
|
-
expected: {
|
|
223
|
-
snapshot: true,
|
|
224
|
-
},
|
|
225
|
-
});
|
|
226
|
-
testCliCommand({
|
|
227
|
-
name: 'get by name with numeric name',
|
|
228
|
-
args: ['branches', 'get', '123', '--project-id', 'test'],
|
|
229
|
-
expected: {
|
|
230
|
-
snapshot: true,
|
|
231
|
-
},
|
|
232
|
-
});
|
|
233
|
-
/* add compute */
|
|
234
|
-
testCliCommand({
|
|
235
|
-
name: 'add compute',
|
|
236
|
-
args: ['branches', 'add-compute', 'test_branch', '--project-id', 'test'],
|
|
237
|
-
expected: {
|
|
238
|
-
snapshot: true,
|
|
239
|
-
},
|
|
240
|
-
});
|
|
241
|
-
/* reset */
|
|
242
|
-
testCliCommand({
|
|
243
|
-
name: 'reset branch to parent',
|
|
244
|
-
args: [
|
|
245
|
-
'branches',
|
|
246
|
-
'reset',
|
|
247
|
-
'test_branch',
|
|
248
|
-
'--project-id',
|
|
249
|
-
'test',
|
|
250
|
-
'--parent',
|
|
251
|
-
],
|
|
252
|
-
expected: {
|
|
253
|
-
snapshot: true,
|
|
254
|
-
},
|
|
255
|
-
});
|
|
256
|
-
/* restore */
|
|
257
|
-
testCliCommand({
|
|
258
|
-
name: 'restore branch to lsn',
|
|
259
|
-
args: [
|
|
260
|
-
'branches',
|
|
261
|
-
'restore',
|
|
262
|
-
'br-self-tolsn-123456',
|
|
263
|
-
'^self@0/123ABC',
|
|
264
|
-
'--project-id',
|
|
265
|
-
'test',
|
|
266
|
-
'--preserve-under-name',
|
|
267
|
-
'backup',
|
|
268
|
-
],
|
|
269
|
-
mockDir: 'restore',
|
|
270
|
-
expected: {
|
|
271
|
-
snapshot: true,
|
|
272
|
-
},
|
|
273
|
-
});
|
|
274
|
-
testCliCommand({
|
|
275
|
-
name: 'restore to parent branch timestamp by name',
|
|
276
|
-
args: [
|
|
277
|
-
'branches',
|
|
278
|
-
'restore',
|
|
279
|
-
'parent-tots',
|
|
280
|
-
'^parent@2021-01-01T00:00:00.000Z',
|
|
281
|
-
'--project-id',
|
|
282
|
-
'test',
|
|
283
|
-
],
|
|
284
|
-
mockDir: 'restore',
|
|
285
|
-
expected: {
|
|
286
|
-
snapshot: true,
|
|
287
|
-
},
|
|
288
|
-
});
|
|
289
|
-
testCliCommand({
|
|
290
|
-
name: 'restore to another branch head',
|
|
291
|
-
args: [
|
|
292
|
-
'branches',
|
|
293
|
-
'restore',
|
|
294
|
-
'br-another-branch-123456',
|
|
295
|
-
'br-any-branch-123456',
|
|
296
|
-
'--project-id',
|
|
297
|
-
'test',
|
|
298
|
-
],
|
|
299
|
-
mockDir: 'restore',
|
|
300
|
-
expected: {
|
|
301
|
-
snapshot: true,
|
|
302
|
-
},
|
|
303
|
-
});
|
|
304
|
-
testCliCommand({
|
|
305
|
-
name: 'restore with unexisted branch outputs error',
|
|
306
|
-
args: [
|
|
307
|
-
'branches',
|
|
308
|
-
'restore',
|
|
309
|
-
'unexisting-branch',
|
|
310
|
-
'^parent',
|
|
311
|
-
'--project-id',
|
|
312
|
-
'test',
|
|
313
|
-
],
|
|
314
|
-
mockDir: 'restore',
|
|
315
|
-
expected: {
|
|
316
|
-
code: 1,
|
|
317
|
-
stderr: `ERROR: Branch unexisting-branch not found.
|
|
318
|
-
Available branches: self-tolsn-123456, any-branch, parent-tots, another-branch`,
|
|
319
|
-
},
|
|
320
|
-
});
|
|
321
|
-
});
|