neon 8.11.1 → 8.11.2
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/README.md +1 -1
- package/dist/_chunks/api-GbEaBZJ5.js +388 -0
- package/dist/_chunks/api_keys-CNnnugbQ.js +281 -0
- package/dist/_chunks/ask-DVwy0eUL.js +155 -0
- package/dist/_chunks/auth-CIUtXByB.js +495 -0
- package/dist/_chunks/bootstrap-wPZWa1sT.js +499 -0
- package/dist/_chunks/branches-BNa1xX1L.js +460 -0
- package/dist/_chunks/bucket-BCdryTkD.js +409 -0
- package/dist/_chunks/checkout-CXIOydqZ.js +348 -0
- package/dist/_chunks/claim-DqAvAvDm.js +473 -0
- package/dist/_chunks/config-BH_qRHiG.js +1113 -0
- package/dist/_chunks/connection_string-DB4awPzZ.js +154 -0
- package/dist/_chunks/credentials-BSjE9fRR.js +146 -0
- package/dist/_chunks/data_api-Djxj5ZQD.js +263 -0
- package/dist/_chunks/databases-Dok4wru7.js +84 -0
- package/dist/_chunks/deploy-D7B0Xfjg.js +33 -0
- package/dist/_chunks/dev-CSvxAecE.js +945 -0
- package/dist/_chunks/diff-DhxxbdQE.js +178 -0
- package/dist/_chunks/docs-CrVybkTP.js +197 -0
- package/dist/_chunks/env-5HS5qQGd.js +284 -0
- package/dist/_chunks/feedback-CMayyTa8.js +88 -0
- package/dist/_chunks/functions-Q0zuvtnk.js +464 -0
- package/dist/_chunks/git-H32TNt6M.js +356 -0
- package/dist/_chunks/init-BkA6RilG.js +111 -0
- package/dist/_chunks/inspect-g0wekylj.js +90 -0
- package/dist/_chunks/ip_allow-5lLFvIuE.js +106 -0
- package/dist/_chunks/link-BgtkOBws.js +936 -0
- package/dist/_chunks/logs-DWkpjzIH.js +291 -0
- package/dist/_chunks/mcp-Bo-7TKc7.js +253 -0
- package/dist/_chunks/neon_auth-CBs1_3qu.js +822 -0
- package/dist/_chunks/open-CX3BT3Tp.js +33 -0
- package/dist/_chunks/operations-D4I-AxVs.js +37 -0
- package/dist/_chunks/orgs-xGfANwHQ.js +52 -0
- package/dist/_chunks/plugins-DqD7BDO1.js +169 -0
- package/dist/_chunks/profile-yXOiKk9R.js +672 -0
- package/dist/_chunks/projects-BwI2Uo0z.js +439 -0
- package/dist/_chunks/psql-BM-doe8e.js +64 -0
- package/dist/_chunks/realtime-BRqIyGR-.js +79 -0
- package/dist/_chunks/roles-B4w3YT_7.js +79 -0
- package/dist/_chunks/set_context-DbrwoImy.js +38 -0
- package/dist/_chunks/skills-DyiBXKS3.js +255 -0
- package/dist/_chunks/snapshots-RJBzW8GM.js +338 -0
- package/dist/_chunks/status-DV8Z2kw3.js +44 -0
- package/dist/_chunks/triggers-BrRo1z4b.js +302 -0
- package/dist/_chunks/user-dlOGXbX9.js +60 -0
- package/dist/_chunks/vpc_endpoints-CNb0YfMo.js +105 -0
- package/dist/auth_recovery.js +1 -1
- package/dist/commands/api.js +1 -388
- package/dist/commands/api_keys.js +1 -281
- package/dist/commands/ask.js +1 -155
- package/dist/commands/auth.js +1 -495
- package/dist/commands/bootstrap.js +1 -499
- package/dist/commands/branches.js +1 -460
- package/dist/commands/bucket.js +1 -409
- package/dist/commands/checkout.js +1 -348
- package/dist/commands/claim.js +1 -473
- package/dist/commands/config.js +1 -1113
- package/dist/commands/connection_string.js +1 -154
- package/dist/commands/credentials.js +1 -146
- package/dist/commands/data_api.js +1 -263
- package/dist/commands/databases.js +1 -84
- package/dist/commands/deploy.js +1 -33
- package/dist/commands/dev.js +1 -945
- package/dist/commands/diff.js +1 -178
- package/dist/commands/docs.js +1 -197
- package/dist/commands/env.js +1 -284
- package/dist/commands/feedback.js +1 -88
- package/dist/commands/functions.js +1 -464
- package/dist/commands/functions_new.js +1 -1
- package/dist/commands/git.js +1 -356
- package/dist/commands/index.js +45 -45
- package/dist/commands/init.js +1 -111
- package/dist/commands/inspect.js +1 -90
- package/dist/commands/ip_allow.js +1 -106
- package/dist/commands/link.js +1 -936
- package/dist/commands/logs.js +1 -291
- package/dist/commands/mcp.js +1 -253
- package/dist/commands/neon_auth.js +1 -822
- package/dist/commands/open.js +1 -33
- package/dist/commands/operations.js +1 -37
- package/dist/commands/orgs.js +1 -52
- package/dist/commands/plugins.js +1 -169
- package/dist/commands/profile.js +1 -672
- package/dist/commands/projects.js +1 -439
- package/dist/commands/psql.js +1 -64
- package/dist/commands/realtime.js +1 -79
- package/dist/commands/roles.js +1 -79
- package/dist/commands/set_context.js +1 -38
- package/dist/commands/skills.js +1 -255
- package/dist/commands/snapshots.js +1 -338
- package/dist/commands/status.js +1 -44
- package/dist/commands/subscribe.js +1 -1
- package/dist/commands/triggers.js +1 -302
- package/dist/commands/user.js +1 -60
- package/dist/commands/vpc_endpoints.js +1 -105
- package/dist/functions/registry.js +29 -151
- package/dist/functions/source.js +42 -2
- package/dist/index.js +1 -1
- package/dist/init/auth.js +3 -3
- package/dist/init/link.js +2 -2
- package/dist/init/run.js +3 -3
- package/dist/init/tooling.js +3 -3
- package/dist/mcp/mint.js +1 -1
- package/dist/test_utils/registry.js +1 -2
- package/package.json +8 -6
|
@@ -1,439 +1 @@
|
|
|
1
|
-
|
|
2
|
-
import { isCi } from "../env.js";
|
|
3
|
-
import { log } from "../log.js";
|
|
4
|
-
import { isNeonApiError, messageFromBody } from "../api.js";
|
|
5
|
-
import { readContextFile, updateContextFile } from "../context.js";
|
|
6
|
-
import { getCliName } from "../utils/cli_name.js";
|
|
7
|
-
import { projectCreateRequest, projectUpdateRequest } from "../parameters.gen.js";
|
|
8
|
-
import { writer } from "../writer.js";
|
|
9
|
-
import { getComputeUnits } from "../utils/compute_units.js";
|
|
10
|
-
import { psql } from "../utils/psql.js";
|
|
11
|
-
import chalk from "chalk";
|
|
12
|
-
import prompts from "prompts";
|
|
13
|
-
//#region src/commands/projects.ts
|
|
14
|
-
var projects_exports = /* @__PURE__ */ __exportAll({
|
|
15
|
-
PROJECT_FIELDS: () => PROJECT_FIELDS,
|
|
16
|
-
RECOVERABLE_PROJECT_FIELDS: () => RECOVERABLE_PROJECT_FIELDS,
|
|
17
|
-
REGIONS: () => REGIONS,
|
|
18
|
-
aliases: () => aliases,
|
|
19
|
-
builder: () => builder,
|
|
20
|
-
command: () => command,
|
|
21
|
-
describe: () => describe,
|
|
22
|
-
formatDuration: () => formatDuration,
|
|
23
|
-
handler: () => handler
|
|
24
|
-
});
|
|
25
|
-
const PROJECT_FIELDS = [
|
|
26
|
-
"id",
|
|
27
|
-
"name",
|
|
28
|
-
"region_id",
|
|
29
|
-
"created_at"
|
|
30
|
-
];
|
|
31
|
-
const RECOVERABLE_PROJECT_FIELDS = [
|
|
32
|
-
"id",
|
|
33
|
-
"name",
|
|
34
|
-
"recoverable_until",
|
|
35
|
-
"deleted_at",
|
|
36
|
-
"region_id",
|
|
37
|
-
"created_at"
|
|
38
|
-
];
|
|
39
|
-
const REGIONS = [
|
|
40
|
-
"aws-us-west-2",
|
|
41
|
-
"aws-ap-southeast-1",
|
|
42
|
-
"aws-ap-southeast-2",
|
|
43
|
-
"aws-eu-central-1",
|
|
44
|
-
"aws-us-east-2",
|
|
45
|
-
"aws-us-east-1",
|
|
46
|
-
"azure-eastus2"
|
|
47
|
-
];
|
|
48
|
-
const PROJECTS_LIST_LIMIT = 100;
|
|
49
|
-
const command = "projects";
|
|
50
|
-
const describe = "Manage projects";
|
|
51
|
-
const aliases = ["project"];
|
|
52
|
-
const builder = (argv) => {
|
|
53
|
-
return argv.usage("$0 projects <sub-command> [options]").middleware((args) => {
|
|
54
|
-
args.projectId = args.id;
|
|
55
|
-
}).command("list", "List projects", (yargs) => yargs.options({
|
|
56
|
-
"org-id": {
|
|
57
|
-
describe: "List projects of a given organization",
|
|
58
|
-
type: "string"
|
|
59
|
-
},
|
|
60
|
-
"recoverable-only": {
|
|
61
|
-
describe: "List only deleted projects within their deletion grace period",
|
|
62
|
-
type: "boolean"
|
|
63
|
-
}
|
|
64
|
-
}), async (args) => {
|
|
65
|
-
await handleMissingOrgId(args, list);
|
|
66
|
-
}).command("create", "Create a project", (yargs) => yargs.options({
|
|
67
|
-
secrets: {
|
|
68
|
-
describe: "Include connection credentials in command output. Use --no-secrets to omit them",
|
|
69
|
-
type: "boolean",
|
|
70
|
-
default: true
|
|
71
|
-
},
|
|
72
|
-
"block-public-connections": {
|
|
73
|
-
describe: projectCreateRequest["project.settings.block_public_connections"].description,
|
|
74
|
-
type: "boolean"
|
|
75
|
-
},
|
|
76
|
-
"block-vpc-connections": {
|
|
77
|
-
describe: projectCreateRequest["project.settings.block_vpc_connections"].description,
|
|
78
|
-
type: "boolean"
|
|
79
|
-
},
|
|
80
|
-
hipaa: {
|
|
81
|
-
describe: projectCreateRequest["project.settings.hipaa"].description,
|
|
82
|
-
type: "boolean"
|
|
83
|
-
},
|
|
84
|
-
name: {
|
|
85
|
-
describe: projectCreateRequest["project.name"].description,
|
|
86
|
-
type: "string"
|
|
87
|
-
},
|
|
88
|
-
"region-id": {
|
|
89
|
-
describe: `The region ID. Possible values: ${REGIONS.join(", ")}`,
|
|
90
|
-
type: "string"
|
|
91
|
-
},
|
|
92
|
-
"org-id": {
|
|
93
|
-
describe: "The project's organization ID",
|
|
94
|
-
type: "string"
|
|
95
|
-
},
|
|
96
|
-
psql: {
|
|
97
|
-
type: "boolean",
|
|
98
|
-
describe: "Connect to a new project via psql",
|
|
99
|
-
default: false
|
|
100
|
-
},
|
|
101
|
-
fallback: {
|
|
102
|
-
type: "boolean",
|
|
103
|
-
describe: "Force the embedded TypeScript psql fallback (for testing)",
|
|
104
|
-
default: false,
|
|
105
|
-
hidden: true
|
|
106
|
-
},
|
|
107
|
-
database: {
|
|
108
|
-
describe: projectCreateRequest["project.branch.database_name"].description,
|
|
109
|
-
type: "string"
|
|
110
|
-
},
|
|
111
|
-
role: {
|
|
112
|
-
describe: projectCreateRequest["project.branch.role_name"].description,
|
|
113
|
-
type: "string"
|
|
114
|
-
},
|
|
115
|
-
"pg-version": {
|
|
116
|
-
describe: "Major PostgreSQL version (14–19). Version 19 is available only in regions where it has been enabled.",
|
|
117
|
-
type: "number",
|
|
118
|
-
choices: [
|
|
119
|
-
14,
|
|
120
|
-
15,
|
|
121
|
-
16,
|
|
122
|
-
17,
|
|
123
|
-
18,
|
|
124
|
-
19
|
|
125
|
-
]
|
|
126
|
-
},
|
|
127
|
-
"set-context": {
|
|
128
|
-
type: "boolean",
|
|
129
|
-
describe: "Set the current context to the new project",
|
|
130
|
-
default: false
|
|
131
|
-
},
|
|
132
|
-
cu: {
|
|
133
|
-
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\").",
|
|
134
|
-
type: "string"
|
|
135
|
-
}
|
|
136
|
-
}), async (args) => {
|
|
137
|
-
await handleMissingOrgId(args, create);
|
|
138
|
-
}).command("update <id>", "Update a project", (yargs) => yargs.options({
|
|
139
|
-
"block-vpc-connections": {
|
|
140
|
-
describe: projectUpdateRequest["project.settings.block_vpc_connections"].description + " Use --block-vpc-connections=false to set the value to false.",
|
|
141
|
-
type: "boolean"
|
|
142
|
-
},
|
|
143
|
-
"block-public-connections": {
|
|
144
|
-
describe: projectUpdateRequest["project.settings.block_public_connections"].description + " Use --block-public-connections=false to set the value to false.",
|
|
145
|
-
type: "boolean"
|
|
146
|
-
},
|
|
147
|
-
hipaa: {
|
|
148
|
-
describe: projectUpdateRequest["project.settings.hipaa"].description,
|
|
149
|
-
type: "boolean"
|
|
150
|
-
},
|
|
151
|
-
cu: {
|
|
152
|
-
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\").",
|
|
153
|
-
type: "string"
|
|
154
|
-
},
|
|
155
|
-
name: {
|
|
156
|
-
describe: projectUpdateRequest["project.name"].description,
|
|
157
|
-
type: "string"
|
|
158
|
-
},
|
|
159
|
-
"enable-logical-replication": {
|
|
160
|
-
describe: "Enable logical replication for all project endpoints. This suspends active endpoints and cannot be disabled.",
|
|
161
|
-
type: "boolean"
|
|
162
|
-
},
|
|
163
|
-
yes: {
|
|
164
|
-
type: "boolean",
|
|
165
|
-
default: false,
|
|
166
|
-
describe: "Skip the confirmation prompt when enabling logical replication."
|
|
167
|
-
}
|
|
168
|
-
}), async (args) => {
|
|
169
|
-
await update(args);
|
|
170
|
-
}).command("delete <id>", "Delete a project", (yargs) => yargs, async (args) => {
|
|
171
|
-
await deleteProject(args);
|
|
172
|
-
}).command("recover <id>", "Recovers a deleted project during the deletion grace period", (yargs) => yargs, async (args) => {
|
|
173
|
-
await recover(args);
|
|
174
|
-
}).command("get <id>", "Get a project", (yargs) => yargs, async (args) => {
|
|
175
|
-
await get(args);
|
|
176
|
-
});
|
|
177
|
-
};
|
|
178
|
-
const handler = (args) => {
|
|
179
|
-
return args;
|
|
180
|
-
};
|
|
181
|
-
const listAll = async (fetchPage) => {
|
|
182
|
-
const result = [];
|
|
183
|
-
let cursor;
|
|
184
|
-
let end = false;
|
|
185
|
-
while (!end) {
|
|
186
|
-
const { data } = await fetchPage(cursor);
|
|
187
|
-
result.push(...data.projects);
|
|
188
|
-
cursor = data.pagination?.cursor;
|
|
189
|
-
log.debug("Got %d projects, with cursor: %s", data.projects.length, cursor);
|
|
190
|
-
if (data.projects.length < PROJECTS_LIST_LIMIT) end = true;
|
|
191
|
-
}
|
|
192
|
-
return result;
|
|
193
|
-
};
|
|
194
|
-
const projectColumns = (props) => {
|
|
195
|
-
const current = readContextFile(props.contextFile).projectId;
|
|
196
|
-
return { name: (project) => project.id === current ? `${chalk.green("[current]")} ${project.name}` : project.name };
|
|
197
|
-
};
|
|
198
|
-
const list = async (props) => {
|
|
199
|
-
const query = (cursor) => ({
|
|
200
|
-
limit: PROJECTS_LIST_LIMIT,
|
|
201
|
-
org_id: props.orgId,
|
|
202
|
-
recoverable: props.recoverableOnly,
|
|
203
|
-
cursor
|
|
204
|
-
});
|
|
205
|
-
const includeShared = !props.orgId && !props.recoverableOnly;
|
|
206
|
-
const ownedRequest = listAll((cursor) => props.apiClient.listProjects(query(cursor)));
|
|
207
|
-
const sharedAbort = new AbortController();
|
|
208
|
-
const sharedRequest = includeShared ? listAll((cursor) => props.apiClient.listSharedProjects(query(cursor), { signal: sharedAbort.signal })) : void 0;
|
|
209
|
-
sharedRequest?.catch(() => void 0);
|
|
210
|
-
let ownedProjects;
|
|
211
|
-
try {
|
|
212
|
-
ownedProjects = await ownedRequest;
|
|
213
|
-
} catch (err) {
|
|
214
|
-
sharedAbort.abort();
|
|
215
|
-
throw err;
|
|
216
|
-
}
|
|
217
|
-
const sharedProjects = await sharedRequest ?? [];
|
|
218
|
-
const out = writer(props);
|
|
219
|
-
const renderColumns = projectColumns(props);
|
|
220
|
-
out.write(ownedProjects, {
|
|
221
|
-
fields: props.recoverableOnly ? RECOVERABLE_PROJECT_FIELDS : PROJECT_FIELDS,
|
|
222
|
-
title: "Projects",
|
|
223
|
-
emptyMessage: props.recoverableOnly ? "You don't have any recoverable projects." : "You don't have any projects yet. See how to create a new project:\n> neon projects create --help",
|
|
224
|
-
renderColumns
|
|
225
|
-
});
|
|
226
|
-
if (includeShared) out.write(sharedProjects, {
|
|
227
|
-
fields: PROJECT_FIELDS,
|
|
228
|
-
title: "Shared with you",
|
|
229
|
-
emptyMessage: "No projects have been shared with you",
|
|
230
|
-
renderColumns
|
|
231
|
-
});
|
|
232
|
-
out.end();
|
|
233
|
-
};
|
|
234
|
-
const create = async (props) => {
|
|
235
|
-
const project = {};
|
|
236
|
-
if (props.hipaa !== void 0) {
|
|
237
|
-
if (!project.settings) project.settings = {};
|
|
238
|
-
project.settings.hipaa = props.hipaa;
|
|
239
|
-
}
|
|
240
|
-
if (props.blockPublicConnections !== void 0) {
|
|
241
|
-
if (!project.settings) project.settings = {};
|
|
242
|
-
project.settings.block_public_connections = props.blockPublicConnections;
|
|
243
|
-
}
|
|
244
|
-
if (props.blockVpcConnections !== void 0) {
|
|
245
|
-
if (!project.settings) project.settings = {};
|
|
246
|
-
project.settings.block_vpc_connections = props.blockVpcConnections;
|
|
247
|
-
}
|
|
248
|
-
if (props.name) project.name = props.name;
|
|
249
|
-
if (props.regionId) project.region_id = props.regionId;
|
|
250
|
-
if (props.orgId) project.org_id = props.orgId;
|
|
251
|
-
project.branch = {};
|
|
252
|
-
if (props.database) project.branch.database_name = props.database;
|
|
253
|
-
if (props.role) project.branch.role_name = props.role;
|
|
254
|
-
if (props.pgVersion !== void 0) project.pg_version = props.pgVersion;
|
|
255
|
-
if (props.cu) project.default_endpoint_settings = props.cu ? getComputeUnits(props.cu) : void 0;
|
|
256
|
-
const { data } = await props.apiClient.createProject({ project });
|
|
257
|
-
if (props.setContext) updateContextFile(props.contextFile, { projectId: data.project.id });
|
|
258
|
-
const out = writer(props);
|
|
259
|
-
if (!props.secrets && (props.output === "json" || props.output === "yaml")) out.write({ project: data.project }, {
|
|
260
|
-
fields: ["project"],
|
|
261
|
-
title: "Project"
|
|
262
|
-
});
|
|
263
|
-
else {
|
|
264
|
-
out.write(data.project, {
|
|
265
|
-
fields: PROJECT_FIELDS,
|
|
266
|
-
title: "Project"
|
|
267
|
-
});
|
|
268
|
-
if (props.secrets) out.write(data.connection_uris, {
|
|
269
|
-
fields: ["connection_uri"],
|
|
270
|
-
title: "Connection URIs"
|
|
271
|
-
});
|
|
272
|
-
}
|
|
273
|
-
out.end();
|
|
274
|
-
if (props.psql) {
|
|
275
|
-
const connection_uri = data.connection_uris[0].connection_uri;
|
|
276
|
-
const psqlArgs = props["--"];
|
|
277
|
-
await psql(connection_uri, psqlArgs, { mode: props.fallback ? "ts" : "auto" });
|
|
278
|
-
}
|
|
279
|
-
};
|
|
280
|
-
const deleteProject = async (props) => {
|
|
281
|
-
const { data } = await props.apiClient.deleteProject(props.id);
|
|
282
|
-
writer(props).end(data.project, { fields: PROJECT_FIELDS });
|
|
283
|
-
};
|
|
284
|
-
const update = async (props) => {
|
|
285
|
-
const project = {};
|
|
286
|
-
if (props.enableLogicalReplication !== void 0) {
|
|
287
|
-
if (!props.enableLogicalReplication) throw new Error("Logical replication cannot be disabled once it has been enabled.");
|
|
288
|
-
if (!props.yes) {
|
|
289
|
-
if (isCi() || !process.stdin.isTTY) throw new Error("Enabling logical replication requires confirmation. Re-run interactively or pass --yes.");
|
|
290
|
-
const { proceed } = await prompts({
|
|
291
|
-
onState: onPromptState,
|
|
292
|
-
type: "confirm",
|
|
293
|
-
name: "proceed",
|
|
294
|
-
message: "Enable logical replication? This suspends active endpoints and cannot be undone.",
|
|
295
|
-
initial: false
|
|
296
|
-
});
|
|
297
|
-
if (!proceed) {
|
|
298
|
-
log.info("Logical replication was not enabled.");
|
|
299
|
-
return;
|
|
300
|
-
}
|
|
301
|
-
}
|
|
302
|
-
project.settings = { enable_logical_replication: true };
|
|
303
|
-
}
|
|
304
|
-
if (props.hipaa !== void 0) {
|
|
305
|
-
if (!project.settings) project.settings = {};
|
|
306
|
-
project.settings.hipaa = props.hipaa;
|
|
307
|
-
}
|
|
308
|
-
if (props.blockPublicConnections !== void 0) {
|
|
309
|
-
if (!project.settings) project.settings = {};
|
|
310
|
-
project.settings.block_public_connections = props.blockPublicConnections;
|
|
311
|
-
}
|
|
312
|
-
if (props.blockVpcConnections !== void 0) {
|
|
313
|
-
if (!project.settings) project.settings = {};
|
|
314
|
-
project.settings.block_vpc_connections = props.blockVpcConnections;
|
|
315
|
-
}
|
|
316
|
-
if (props.name) project.name = props.name;
|
|
317
|
-
if (props.cu) project.default_endpoint_settings = props.cu ? getComputeUnits(props.cu) : void 0;
|
|
318
|
-
const { data } = await props.apiClient.updateProject(props.id, { project });
|
|
319
|
-
writer(props).end(data.project, { fields: PROJECT_FIELDS });
|
|
320
|
-
};
|
|
321
|
-
const recover = async (props) => {
|
|
322
|
-
const { data } = await props.apiClient.recoverProject(props.id);
|
|
323
|
-
writer(props).end(data.project, { fields: PROJECT_FIELDS });
|
|
324
|
-
};
|
|
325
|
-
const get = async (props) => {
|
|
326
|
-
const { data } = await props.apiClient.getProject(props.id);
|
|
327
|
-
if (props.output === "json" || props.output === "yaml") {
|
|
328
|
-
writer(props).end(data.project, { fields: PROJECT_FIELDS });
|
|
329
|
-
return;
|
|
330
|
-
}
|
|
331
|
-
writer(props).end(projectDetails(data.project), {
|
|
332
|
-
fields: PROJECT_DETAIL_FIELDS,
|
|
333
|
-
humanTitle: "Project"
|
|
334
|
-
});
|
|
335
|
-
};
|
|
336
|
-
const PROJECT_DETAIL_FIELDS = [
|
|
337
|
-
"name",
|
|
338
|
-
"id",
|
|
339
|
-
"region_id",
|
|
340
|
-
"postgres_version",
|
|
341
|
-
"organization",
|
|
342
|
-
"default_compute",
|
|
343
|
-
"history_retention",
|
|
344
|
-
"created_at",
|
|
345
|
-
"updated_at"
|
|
346
|
-
];
|
|
347
|
-
/** Table-only view of a project; the field names become the row labels. */
|
|
348
|
-
const projectDetails = (project) => ({
|
|
349
|
-
name: project.name,
|
|
350
|
-
id: project.id,
|
|
351
|
-
region_id: project.region_id,
|
|
352
|
-
postgres_version: project.pg_version,
|
|
353
|
-
organization: project.org_id,
|
|
354
|
-
default_compute: formatComputeRange(project.default_endpoint_settings),
|
|
355
|
-
history_retention: project.history_retention_seconds === void 0 ? void 0 : formatDuration(project.history_retention_seconds),
|
|
356
|
-
created_at: project.created_at,
|
|
357
|
-
updated_at: project.updated_at
|
|
358
|
-
});
|
|
359
|
-
const formatComputeRange = (settings) => {
|
|
360
|
-
const min = settings?.autoscaling_limit_min_cu;
|
|
361
|
-
const max = settings?.autoscaling_limit_max_cu;
|
|
362
|
-
if (min === void 0 || max === void 0) return;
|
|
363
|
-
return min === max ? `${min} CU` : `${min}-${max} CU`;
|
|
364
|
-
};
|
|
365
|
-
const DURATION_UNITS = [
|
|
366
|
-
["day", 86400],
|
|
367
|
-
["hour", 3600],
|
|
368
|
-
["minute", 60]
|
|
369
|
-
];
|
|
370
|
-
const formatDuration = (seconds) => {
|
|
371
|
-
for (const [unit, size] of DURATION_UNITS) if (seconds > 0 && seconds % size === 0) {
|
|
372
|
-
const count = seconds / size;
|
|
373
|
-
return `${count} ${unit}${count === 1 ? "" : "s"}`;
|
|
374
|
-
}
|
|
375
|
-
return `${seconds} second${seconds === 1 ? "" : "s"}`;
|
|
376
|
-
};
|
|
377
|
-
const handleMissingOrgId = async (args, cmd) => {
|
|
378
|
-
try {
|
|
379
|
-
await cmd(args);
|
|
380
|
-
} catch (err) {
|
|
381
|
-
if (!isCi() && isOrgIdError(err)) {
|
|
382
|
-
const orgId = await selectOrg(args);
|
|
383
|
-
await cmd({
|
|
384
|
-
...args,
|
|
385
|
-
orgId
|
|
386
|
-
});
|
|
387
|
-
} else throw err;
|
|
388
|
-
}
|
|
389
|
-
};
|
|
390
|
-
const isOrgIdError = (err) => {
|
|
391
|
-
return isNeonApiError(err) && err.status === 400 && messageFromBody(err.data)?.includes("org_id is required");
|
|
392
|
-
};
|
|
393
|
-
const selectOrg = async (props) => {
|
|
394
|
-
const { data: { organizations } } = await props.apiClient.getCurrentUserOrganizations();
|
|
395
|
-
if (!organizations?.length) throw new Error(`You don't belong to any organizations. Please create an organization first.`);
|
|
396
|
-
const { orgId } = await prompts({
|
|
397
|
-
onState: onPromptState,
|
|
398
|
-
type: "select",
|
|
399
|
-
name: "orgId",
|
|
400
|
-
message: `What organization would you like to use?`,
|
|
401
|
-
choices: organizations.map((org) => ({
|
|
402
|
-
title: `${org.name} (${org.id})`,
|
|
403
|
-
value: org.id
|
|
404
|
-
})),
|
|
405
|
-
initial: 0
|
|
406
|
-
});
|
|
407
|
-
const { save } = await prompts({
|
|
408
|
-
onState: onPromptState,
|
|
409
|
-
type: "confirm",
|
|
410
|
-
name: "save",
|
|
411
|
-
message: `Would you like to use this organization by default?`,
|
|
412
|
-
initial: true
|
|
413
|
-
});
|
|
414
|
-
if (save) {
|
|
415
|
-
updateContextFile(props.contextFile, { orgId });
|
|
416
|
-
writer(props).text(`
|
|
417
|
-
The organization ID has been saved in ${props.contextFile}
|
|
418
|
-
|
|
419
|
-
If you'd like to change the default organization later, use
|
|
420
|
-
|
|
421
|
-
${getCliName()} link --org-id <org_id>
|
|
422
|
-
|
|
423
|
-
Or to clear the context file and forget the default organization
|
|
424
|
-
|
|
425
|
-
${getCliName()} link --clear
|
|
426
|
-
|
|
427
|
-
`);
|
|
428
|
-
}
|
|
429
|
-
return orgId;
|
|
430
|
-
};
|
|
431
|
-
const onPromptState = (state) => {
|
|
432
|
-
if (state.aborted) {
|
|
433
|
-
process.stdout.write("\x1B[?25h");
|
|
434
|
-
process.stdout.write("\n");
|
|
435
|
-
process.exit(1);
|
|
436
|
-
}
|
|
437
|
-
};
|
|
438
|
-
//#endregion
|
|
439
|
-
export { PROJECT_FIELDS, RECOVERABLE_PROJECT_FIELDS, REGIONS, aliases, builder, command, describe, formatDuration, handler, projects_exports as t };
|
|
1
|
+
export { t as PROJECT_FIELDS, n as RECOVERABLE_PROJECT_FIELDS, r as REGIONS, i as aliases, a as builder, o as command, s as describe, c as formatDuration, l as handler } from "../_chunks/projects-BwI2Uo0z.js";
|
package/dist/commands/psql.js
CHANGED
|
@@ -1,64 +1 @@
|
|
|
1
|
-
|
|
2
|
-
import { EndpointType } from "../utils/api_enums.js";
|
|
3
|
-
import { fillSingleProject } from "../utils/enrichers.js";
|
|
4
|
-
import { SSL_MODES, handler as handler$1 } from "./connection_string.js";
|
|
5
|
-
//#region src/commands/psql.ts
|
|
6
|
-
var psql_exports = /* @__PURE__ */ __exportAll({
|
|
7
|
-
builder: () => builder,
|
|
8
|
-
command: () => command,
|
|
9
|
-
describe: () => describe,
|
|
10
|
-
handler: () => handler
|
|
11
|
-
});
|
|
12
|
-
const command = "psql [branch]";
|
|
13
|
-
const describe = "Connect to a database via psql";
|
|
14
|
-
const builder = (argv) => {
|
|
15
|
-
return argv.usage("$0 psql [branch] [options] [-- psql-args]").example("$0 psql", "Connect to the default branch via psql").example("$0 psql main", "Connect to the main branch via psql").example("$0 psql main -- -c \"SELECT 1\"", "Run a single query against the main branch").example("$0 psql main@2024-01-01T00:00:00Z", "Connect to the main branch at a specific point in time").positional("branch", {
|
|
16
|
-
describe: `Branch name or id. Defaults to the default branch if omitted. Can be written in the point-in-time format: "branch@timestamp" or "branch@lsn"`,
|
|
17
|
-
type: "string"
|
|
18
|
-
}).options({
|
|
19
|
-
"project-id": {
|
|
20
|
-
type: "string",
|
|
21
|
-
describe: "Project ID"
|
|
22
|
-
},
|
|
23
|
-
"role-name": {
|
|
24
|
-
type: "string",
|
|
25
|
-
describe: "Role name"
|
|
26
|
-
},
|
|
27
|
-
"database-name": {
|
|
28
|
-
type: "string",
|
|
29
|
-
describe: "Database name"
|
|
30
|
-
},
|
|
31
|
-
pooled: {
|
|
32
|
-
type: "boolean",
|
|
33
|
-
describe: "Use pooled connection",
|
|
34
|
-
default: false
|
|
35
|
-
},
|
|
36
|
-
"endpoint-type": {
|
|
37
|
-
type: "string",
|
|
38
|
-
choices: Object.values(EndpointType),
|
|
39
|
-
describe: "Endpoint type"
|
|
40
|
-
},
|
|
41
|
-
ssl: {
|
|
42
|
-
type: "string",
|
|
43
|
-
choices: SSL_MODES,
|
|
44
|
-
default: "require",
|
|
45
|
-
describe: "SSL mode"
|
|
46
|
-
},
|
|
47
|
-
fallback: {
|
|
48
|
-
type: "boolean",
|
|
49
|
-
describe: "Force the embedded TypeScript psql fallback (for testing)",
|
|
50
|
-
default: false,
|
|
51
|
-
hidden: true
|
|
52
|
-
}
|
|
53
|
-
}).middleware(fillSingleProject);
|
|
54
|
-
};
|
|
55
|
-
const handler = async (props) => {
|
|
56
|
-
await handler$1({
|
|
57
|
-
...props,
|
|
58
|
-
psql: true,
|
|
59
|
-
prisma: false,
|
|
60
|
-
extended: false
|
|
61
|
-
});
|
|
62
|
-
};
|
|
63
|
-
//#endregion
|
|
64
|
-
export { builder, command, describe, handler, psql_exports as t };
|
|
1
|
+
export { t as builder, n as command, r as describe, i as handler } from "../_chunks/psql-BM-doe8e.js";
|
|
@@ -1,79 +1 @@
|
|
|
1
|
-
|
|
2
|
-
import { log } from "../log.js";
|
|
3
|
-
import { retryOnLock } from "../api.js";
|
|
4
|
-
import { getCliName } from "../utils/cli_name.js";
|
|
5
|
-
import { branchIdFromProps, fillSingleProject } from "../utils/enrichers.js";
|
|
6
|
-
import { builder as builder$1, handler as handler$1 } from "./subscribe.js";
|
|
7
|
-
import { defineConfig } from "@neon/config";
|
|
8
|
-
//#region src/commands/realtime.ts
|
|
9
|
-
var realtime_exports = /* @__PURE__ */ __exportAll({
|
|
10
|
-
builder: () => builder,
|
|
11
|
-
command: () => command,
|
|
12
|
-
describe: () => describe,
|
|
13
|
-
disable: () => disable,
|
|
14
|
-
enable: () => enable,
|
|
15
|
-
handler: () => handler,
|
|
16
|
-
rotateSecret: () => rotateSecret
|
|
17
|
-
});
|
|
18
|
-
const ROTATION_POLL_INTERVAL_MS = Number(process.env.NEON_REALTIME_POLL_INTERVAL_MS) || 1e3;
|
|
19
|
-
const ROTATION_POLL_TIMEOUT_MS = Number(process.env.NEON_REALTIME_POLL_TIMEOUT_MS) || 6e4;
|
|
20
|
-
/** Request Realtime provisioning or an allowed-origin update for a branch. */
|
|
21
|
-
const enable = async (props) => {
|
|
22
|
-
const realtime = props.allowedOrigins === void 0 ? true : { allowedOrigins: props.allowedOrigins };
|
|
23
|
-
defineConfig({ preview: { realtime } });
|
|
24
|
-
const branchId = await branchIdFromProps(props);
|
|
25
|
-
await retryOnLock(() => props.apiClient.enableProjectBranchRealtime(props.projectId, branchId, props.allowedOrigins === void 0 ? {} : { allowed_origins: [...props.allowedOrigins] }));
|
|
26
|
-
log.info("Realtime enable requested for branch %s.", branchId);
|
|
27
|
-
};
|
|
28
|
-
/** Request Realtime deprovisioning for a branch. */
|
|
29
|
-
const disable = async (props) => {
|
|
30
|
-
const branchId = await branchIdFromProps(props);
|
|
31
|
-
await retryOnLock(() => props.apiClient.disableProjectBranchRealtime(props.projectId, branchId));
|
|
32
|
-
log.info("Realtime disable requested for branch %s.", branchId);
|
|
33
|
-
};
|
|
34
|
-
/** Request replacement of a branch's Realtime shared secret. */
|
|
35
|
-
const rotateSecret = async (props) => {
|
|
36
|
-
const branchId = await branchIdFromProps(props);
|
|
37
|
-
await retryOnLock(() => props.apiClient.rotateProjectBranchRealtimeSecret(props.projectId, branchId));
|
|
38
|
-
log.info("Realtime secret rotation requested for branch %s.", branchId);
|
|
39
|
-
if (!props.wait) return;
|
|
40
|
-
const deadline = Date.now() + ROTATION_POLL_TIMEOUT_MS;
|
|
41
|
-
do {
|
|
42
|
-
const { data } = await props.apiClient.getProjectBranchRealtime(props.projectId, branchId);
|
|
43
|
-
if (!data.pending) {
|
|
44
|
-
log.info("Realtime secret rotation completed for branch %s.", branchId);
|
|
45
|
-
log.info("Run %s env pull --service realtime to update NEON_REALTIME_SECRET.", getCliName());
|
|
46
|
-
return;
|
|
47
|
-
}
|
|
48
|
-
const remainingMs = deadline - Date.now();
|
|
49
|
-
if (remainingMs <= 0) break;
|
|
50
|
-
await new Promise((resolve) => setTimeout(resolve, Math.min(ROTATION_POLL_INTERVAL_MS, remainingMs)));
|
|
51
|
-
} while (Date.now() < deadline);
|
|
52
|
-
throw new Error(`Timed out waiting for Realtime secret rotation on branch ${branchId}. It may still be in progress.`);
|
|
53
|
-
};
|
|
54
|
-
const command = "realtime";
|
|
55
|
-
const describe = "Manage Neon Realtime for a branch";
|
|
56
|
-
const builder = (argv) => argv.usage("$0 realtime <sub-command> [options]").options({
|
|
57
|
-
"project-id": {
|
|
58
|
-
describe: "Project ID",
|
|
59
|
-
type: "string"
|
|
60
|
-
},
|
|
61
|
-
branch: {
|
|
62
|
-
describe: "Branch ID or name",
|
|
63
|
-
type: "string"
|
|
64
|
-
}
|
|
65
|
-
}).middleware(fillSingleProject).command("enable", "Enable Realtime on a branch", (yargs) => yargs.strict().option("allowed-origin", {
|
|
66
|
-
describe: "Allowed browser origin (repeatable). \"*\" allows every origin",
|
|
67
|
-
type: "array",
|
|
68
|
-
string: true
|
|
69
|
-
}), (args) => enable({
|
|
70
|
-
...args,
|
|
71
|
-
...args.allowedOrigin !== void 0 ? { allowedOrigins: args.allowedOrigin } : {}
|
|
72
|
-
})).command("disable", "Disable Realtime on a branch", (yargs) => yargs.strict(), (args) => disable(args)).command("rotate-secret", "Replace a branch's Realtime shared secret", (yargs) => yargs.strict().option("wait", {
|
|
73
|
-
describe: "Wait for the Realtime secret rotation to finish",
|
|
74
|
-
type: "boolean",
|
|
75
|
-
default: true
|
|
76
|
-
}), (args) => rotateSecret(args)).command("subscribe <query>", "Subscribe to a live SQL query with Neon Realtime", builder$1, handler$1);
|
|
77
|
-
const handler = (_args) => {};
|
|
78
|
-
//#endregion
|
|
79
|
-
export { builder, command, describe, disable, enable, handler, rotateSecret, realtime_exports as t };
|
|
1
|
+
export { t as builder, n as command, r as describe, i as disable, a as enable, o as handler, c as rotateSecret } from "../_chunks/realtime-BRqIyGR-.js";
|
package/dist/commands/roles.js
CHANGED
|
@@ -1,79 +1 @@
|
|
|
1
|
-
|
|
2
|
-
import { retryOnLock } from "../api.js";
|
|
3
|
-
import { writer } from "../writer.js";
|
|
4
|
-
import { fillSingleProject, resolveBranchFromProps } from "../utils/enrichers.js";
|
|
5
|
-
//#region src/commands/roles.ts
|
|
6
|
-
var roles_exports = /* @__PURE__ */ __exportAll({
|
|
7
|
-
aliases: () => aliases,
|
|
8
|
-
builder: () => builder,
|
|
9
|
-
command: () => command,
|
|
10
|
-
create: () => create,
|
|
11
|
-
deleteRole: () => deleteRole,
|
|
12
|
-
describe: () => describe,
|
|
13
|
-
handler: () => handler,
|
|
14
|
-
list: () => list
|
|
15
|
-
});
|
|
16
|
-
const ROLES_FIELDS = ["name", "created_at"];
|
|
17
|
-
const CREATED_ROLE_FIELDS = [
|
|
18
|
-
"name",
|
|
19
|
-
"password",
|
|
20
|
-
"created_at"
|
|
21
|
-
];
|
|
22
|
-
const command = "roles";
|
|
23
|
-
const describe = "Manage roles";
|
|
24
|
-
const aliases = ["role"];
|
|
25
|
-
const builder = (argv) => argv.usage("$0 roles <sub-command> [options]").options({
|
|
26
|
-
"project-id": {
|
|
27
|
-
describe: "Project ID",
|
|
28
|
-
type: "string"
|
|
29
|
-
},
|
|
30
|
-
branch: {
|
|
31
|
-
describe: "Branch ID or name",
|
|
32
|
-
type: "string"
|
|
33
|
-
}
|
|
34
|
-
}).middleware(fillSingleProject).command("list", "List roles", (yargs) => yargs, (args) => list(args)).command("create", "Create a role", (yargs) => yargs.options({
|
|
35
|
-
name: {
|
|
36
|
-
describe: "Role name",
|
|
37
|
-
type: "string",
|
|
38
|
-
demandOption: true
|
|
39
|
-
},
|
|
40
|
-
"no-login": {
|
|
41
|
-
describe: "Create a passwordless role that cannot login",
|
|
42
|
-
boolean: true
|
|
43
|
-
}
|
|
44
|
-
}), (args) => create(args)).command("delete <role>", "Delete a role", (yargs) => yargs, (args) => deleteRole(args));
|
|
45
|
-
const handler = (args) => {
|
|
46
|
-
return args;
|
|
47
|
-
};
|
|
48
|
-
const list = async (props) => {
|
|
49
|
-
const { branchId, branch } = await resolveBranchFromProps(props);
|
|
50
|
-
const { data } = await props.apiClient.listProjectBranchRoles(props.projectId, branchId);
|
|
51
|
-
const branchLabel = branch?.name ?? branchId;
|
|
52
|
-
writer(props).end(data.roles, {
|
|
53
|
-
fields: ROLES_FIELDS,
|
|
54
|
-
humanTitle: `Roles on ${branchLabel}`,
|
|
55
|
-
emptyMessage: `No roles on ${branchLabel}.`
|
|
56
|
-
});
|
|
57
|
-
};
|
|
58
|
-
const create = async (props) => {
|
|
59
|
-
const noLogin = props["no-login"] === true || props.login === false;
|
|
60
|
-
const { branchId, branch } = await resolveBranchFromProps(props);
|
|
61
|
-
const { data } = await retryOnLock(() => props.apiClient.createProjectBranchRole(props.projectId, branchId, { role: {
|
|
62
|
-
name: props.name,
|
|
63
|
-
...noLogin ? { no_login: true } : {}
|
|
64
|
-
} }));
|
|
65
|
-
writer(props).end(data.role, {
|
|
66
|
-
fields: CREATED_ROLE_FIELDS,
|
|
67
|
-
humanTitle: `Role created on ${branch?.name ?? branchId}`
|
|
68
|
-
});
|
|
69
|
-
};
|
|
70
|
-
const deleteRole = async (props) => {
|
|
71
|
-
const { branchId, branch } = await resolveBranchFromProps(props);
|
|
72
|
-
const { data } = await retryOnLock(() => props.apiClient.deleteProjectBranchRole(props.projectId, branchId, props.role));
|
|
73
|
-
if (data) writer(props).end(data.role, {
|
|
74
|
-
fields: ROLES_FIELDS,
|
|
75
|
-
humanTitle: `Role deleted from ${branch?.name ?? branchId}`
|
|
76
|
-
});
|
|
77
|
-
};
|
|
78
|
-
//#endregion
|
|
79
|
-
export { aliases, builder, command, create, deleteRole, describe, handler, list, roles_exports as t };
|
|
1
|
+
export { t as aliases, n as builder, r as command, i as create, a as deleteRole, o as describe, s as handler, c as list } from "../_chunks/roles-B4w3YT_7.js";
|