neonctl 2.37.1 → 2.38.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.
Files changed (159) hide show
  1. package/README.md +15 -700
  2. package/bin/cli.js +3 -0
  3. package/package.json +8 -75
  4. package/dist/analytics.js +0 -168
  5. package/dist/api.js +0 -720
  6. package/dist/auth.js +0 -125
  7. package/dist/callback.html +0 -60
  8. package/dist/cli.js +0 -9
  9. package/dist/commands/api.js +0 -278
  10. package/dist/commands/auth.js +0 -214
  11. package/dist/commands/bootstrap.js +0 -481
  12. package/dist/commands/branches.js +0 -488
  13. package/dist/commands/bucket.js +0 -549
  14. package/dist/commands/checkout.js +0 -321
  15. package/dist/commands/config.js +0 -626
  16. package/dist/commands/connection_string.js +0 -172
  17. package/dist/commands/data_api.js +0 -284
  18. package/dist/commands/databases.js +0 -82
  19. package/dist/commands/deploy.js +0 -26
  20. package/dist/commands/dev.js +0 -698
  21. package/dist/commands/diff.js +0 -222
  22. package/dist/commands/env.js +0 -189
  23. package/dist/commands/functions.js +0 -373
  24. package/dist/commands/index.js +0 -62
  25. package/dist/commands/init.js +0 -73
  26. package/dist/commands/inspect.js +0 -65
  27. package/dist/commands/ip_allow.js +0 -137
  28. package/dist/commands/link.js +0 -1121
  29. package/dist/commands/neon_auth.js +0 -1028
  30. package/dist/commands/operations.js +0 -28
  31. package/dist/commands/orgs.js +0 -24
  32. package/dist/commands/projects.js +0 -413
  33. package/dist/commands/psql.js +0 -62
  34. package/dist/commands/roles.js +0 -65
  35. package/dist/commands/schema_diff.js +0 -151
  36. package/dist/commands/set_context.js +0 -29
  37. package/dist/commands/snapshots.js +0 -455
  38. package/dist/commands/status.js +0 -40
  39. package/dist/commands/user.js +0 -15
  40. package/dist/commands/vpc_endpoints.js +0 -134
  41. package/dist/config.js +0 -11
  42. package/dist/config_format.js +0 -72
  43. package/dist/context.js +0 -231
  44. package/dist/current_branch_fast_path.js +0 -55
  45. package/dist/dev/env.js +0 -244
  46. package/dist/dev/functions.js +0 -70
  47. package/dist/dev/inputs.js +0 -63
  48. package/dist/dev/runtime.js +0 -146
  49. package/dist/env.js +0 -36
  50. package/dist/env_file.js +0 -159
  51. package/dist/errors.js +0 -80
  52. package/dist/functions_api.js +0 -48
  53. package/dist/help.js +0 -146
  54. package/dist/index.js +0 -240
  55. package/dist/log.js +0 -18
  56. package/dist/parameters.gen.js +0 -480
  57. package/dist/pkg.js +0 -25
  58. package/dist/psql/cli.js +0 -53
  59. package/dist/psql/command/cmd_cond.js +0 -437
  60. package/dist/psql/command/cmd_connect.js +0 -820
  61. package/dist/psql/command/cmd_copy.js +0 -1035
  62. package/dist/psql/command/cmd_describe.js +0 -1815
  63. package/dist/psql/command/cmd_format.js +0 -948
  64. package/dist/psql/command/cmd_io.js +0 -2193
  65. package/dist/psql/command/cmd_lo.js +0 -393
  66. package/dist/psql/command/cmd_meta.js +0 -969
  67. package/dist/psql/command/cmd_misc.js +0 -187
  68. package/dist/psql/command/cmd_pipeline.js +0 -1148
  69. package/dist/psql/command/cmd_restrict.js +0 -171
  70. package/dist/psql/command/cmd_show.js +0 -766
  71. package/dist/psql/command/dispatch.js +0 -343
  72. package/dist/psql/command/inputQueue.js +0 -42
  73. package/dist/psql/command/shared.js +0 -71
  74. package/dist/psql/complete/filenames.js +0 -139
  75. package/dist/psql/complete/index.js +0 -104
  76. package/dist/psql/complete/matcher.js +0 -315
  77. package/dist/psql/complete/psqlVars.js +0 -249
  78. package/dist/psql/complete/queries.js +0 -493
  79. package/dist/psql/complete/rules.js +0 -2424
  80. package/dist/psql/core/common.js +0 -1253
  81. package/dist/psql/core/help.js +0 -576
  82. package/dist/psql/core/mainloop.js +0 -1360
  83. package/dist/psql/core/prompt.js +0 -439
  84. package/dist/psql/core/settings.js +0 -686
  85. package/dist/psql/core/sqlHelp.js +0 -1066
  86. package/dist/psql/core/startup.js +0 -846
  87. package/dist/psql/core/syncVars.js +0 -116
  88. package/dist/psql/core/variables.js +0 -287
  89. package/dist/psql/describe/formatters.js +0 -1330
  90. package/dist/psql/describe/processNamePattern.js +0 -270
  91. package/dist/psql/describe/queries.js +0 -2452
  92. package/dist/psql/describe/versionGate.js +0 -44
  93. package/dist/psql/index.js +0 -2030
  94. package/dist/psql/io/history.js +0 -299
  95. package/dist/psql/io/input.js +0 -120
  96. package/dist/psql/io/lineEditor/buffer.js +0 -325
  97. package/dist/psql/io/lineEditor/complete.js +0 -227
  98. package/dist/psql/io/lineEditor/filename.js +0 -159
  99. package/dist/psql/io/lineEditor/index.js +0 -893
  100. package/dist/psql/io/lineEditor/keymap.js +0 -745
  101. package/dist/psql/io/lineEditor/vt100.js +0 -363
  102. package/dist/psql/io/pgpass.js +0 -202
  103. package/dist/psql/io/pgservice.js +0 -194
  104. package/dist/psql/io/psqlrc.js +0 -422
  105. package/dist/psql/print/aligned.js +0 -1748
  106. package/dist/psql/print/asciidoc.js +0 -230
  107. package/dist/psql/print/crosstab.js +0 -463
  108. package/dist/psql/print/csv.js +0 -76
  109. package/dist/psql/print/html.js +0 -240
  110. package/dist/psql/print/json.js +0 -96
  111. package/dist/psql/print/latex.js +0 -379
  112. package/dist/psql/print/pager.js +0 -267
  113. package/dist/psql/print/troff.js +0 -240
  114. package/dist/psql/print/unaligned.js +0 -99
  115. package/dist/psql/print/units.js +0 -188
  116. package/dist/psql/scanner/slash.js +0 -515
  117. package/dist/psql/scanner/sql.js +0 -914
  118. package/dist/psql/scanner/stringutils.js +0 -394
  119. package/dist/psql/types/backslash.js +0 -1
  120. package/dist/psql/types/connection.js +0 -1
  121. package/dist/psql/types/index.js +0 -7
  122. package/dist/psql/types/printer.js +0 -1
  123. package/dist/psql/types/repl.js +0 -1
  124. package/dist/psql/types/scanner.js +0 -24
  125. package/dist/psql/types/settings.js +0 -1
  126. package/dist/psql/types/variables.js +0 -1
  127. package/dist/psql/wire/connection.js +0 -2857
  128. package/dist/psql/wire/copy.js +0 -108
  129. package/dist/psql/wire/notify.js +0 -59
  130. package/dist/psql/wire/pipeline.js +0 -521
  131. package/dist/psql/wire/protocol.js +0 -466
  132. package/dist/psql/wire/sasl.js +0 -294
  133. package/dist/psql/wire/tls.js +0 -602
  134. package/dist/storage_api.js +0 -147
  135. package/dist/test_utils/fixtures.js +0 -121
  136. package/dist/test_utils/oauth_server.js +0 -9
  137. package/dist/types.js +0 -1
  138. package/dist/utils/ai_gateway_notice.js +0 -180
  139. package/dist/utils/api_enums.js +0 -33
  140. package/dist/utils/auth.js +0 -5
  141. package/dist/utils/branch_notice.js +0 -22
  142. package/dist/utils/branch_picker.js +0 -103
  143. package/dist/utils/compute_units.js +0 -28
  144. package/dist/utils/config_diff.js +0 -185
  145. package/dist/utils/enrichers.js +0 -161
  146. package/dist/utils/esbuild.js +0 -158
  147. package/dist/utils/formats.js +0 -18
  148. package/dist/utils/git_diff.js +0 -90
  149. package/dist/utils/inspect_db.js +0 -153
  150. package/dist/utils/inspect_queries.js +0 -372
  151. package/dist/utils/middlewares.js +0 -20
  152. package/dist/utils/openapi.js +0 -114
  153. package/dist/utils/package_manager.js +0 -68
  154. package/dist/utils/point_in_time.js +0 -56
  155. package/dist/utils/psql.js +0 -120
  156. package/dist/utils/string.js +0 -5
  157. package/dist/utils/ui.js +0 -59
  158. package/dist/utils/zip.js +0 -4
  159. package/dist/writer.js +0 -97
@@ -1,172 +0,0 @@
1
- import { EndpointType } from "../utils/api_enums.js";
2
- import { branchIdFromProps, fillSingleProject } from "../utils/enrichers.js";
3
- import { parsePITBranch } from "../utils/point_in_time.js";
4
- import { psql } from "../utils/psql.js";
5
- import { writer } from "../writer.js";
6
- export const SSL_MODES = [
7
- "require",
8
- "verify-ca",
9
- "verify-full",
10
- "omit",
11
- ];
12
- export const command = "connection-string [branch]";
13
- export const aliases = ["cs"];
14
- export const describe = "Get connection string";
15
- export const builder = (argv) => {
16
- return argv
17
- .usage("$0 connection-string [branch] [options]")
18
- .example("$0 cs main", "Get connection string for the main branch")
19
- .example("$0 cs main@2024-01-01T00:00:00Z", "Get connection string for the main branch at a specific point in time")
20
- .example("$0 cs main@0/234235", "Get connection string for the main branch at a specific LSN")
21
- .positional("branch", {
22
- 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"`,
23
- type: "string",
24
- })
25
- .options({
26
- "project-id": {
27
- type: "string",
28
- describe: "Project ID",
29
- },
30
- "role-name": {
31
- type: "string",
32
- describe: "Role name",
33
- },
34
- "database-name": {
35
- type: "string",
36
- describe: "Database name",
37
- },
38
- pooled: {
39
- type: "boolean",
40
- describe: "Use pooled connection",
41
- default: false,
42
- },
43
- prisma: {
44
- type: "boolean",
45
- describe: "Use connection string for Prisma setup",
46
- default: false,
47
- },
48
- "endpoint-type": {
49
- type: "string",
50
- choices: Object.values(EndpointType),
51
- describe: "Endpoint type",
52
- },
53
- extended: {
54
- type: "boolean",
55
- describe: "Show extended information",
56
- },
57
- psql: {
58
- type: "boolean",
59
- describe: "Connect to a database via psql using connection string",
60
- default: false,
61
- },
62
- fallback: {
63
- type: "boolean",
64
- describe: "Force the embedded TypeScript psql fallback (for testing)",
65
- default: false,
66
- hidden: true,
67
- },
68
- ssl: {
69
- type: "string",
70
- choices: SSL_MODES,
71
- default: "require",
72
- describe: "SSL mode",
73
- },
74
- })
75
- .middleware(fillSingleProject);
76
- };
77
- export const handler = async (props) => {
78
- const projectId = props.projectId;
79
- const parsedPIT = props.branch
80
- ? parsePITBranch(props.branch)
81
- : { tag: "head", branch: "" };
82
- if (props.branch) {
83
- props.branch = parsedPIT.branch;
84
- }
85
- const branchId = await branchIdFromProps(props);
86
- const { data: { endpoints }, } = await props.apiClient.listProjectBranchEndpoints(projectId, branchId);
87
- const matchEndpointType = props.endpointType ?? EndpointType.ReadWrite;
88
- let endpoint = endpoints.find((e) => e.type === matchEndpointType);
89
- if (!endpoint && props.endpointType == null) {
90
- endpoint = endpoints[0];
91
- }
92
- if (!endpoint) {
93
- throw new Error(`No ${props.endpointType ?? ""} endpoint found for the branch: ${branchId}`);
94
- }
95
- const role = props.roleName ||
96
- (await props.apiClient
97
- .listProjectBranchRoles(projectId, branchId)
98
- .then(({ data }) => {
99
- if (data.roles.length === 0) {
100
- throw new Error(`No roles found for the branch: ${branchId}`);
101
- }
102
- if (data.roles.length === 1) {
103
- return data.roles[0].name;
104
- }
105
- throw new Error(`Multiple roles found for the branch, please provide one with the --role-name option: ${data.roles
106
- .map((r) => r.name)
107
- .join(", ")}`);
108
- }));
109
- const { data: { databases: branchDatabases }, } = await props.apiClient.listProjectBranchDatabases(projectId, branchId);
110
- const database = props.databaseName ||
111
- (() => {
112
- if (branchDatabases.length === 0) {
113
- throw new Error(`No databases found for the branch: ${branchId}`);
114
- }
115
- if (branchDatabases.length === 1) {
116
- return branchDatabases[0].name;
117
- }
118
- throw new Error(`Multiple databases found for the branch, please provide one with the --database-name option: ${branchDatabases
119
- .map((d) => d.name)
120
- .join(", ")}`);
121
- })();
122
- if (!branchDatabases.find((d) => d.name === database)) {
123
- throw new Error(`Database not found: ${database}`);
124
- }
125
- const { data: { password }, } = await props.apiClient.getProjectBranchRolePassword(props.projectId, endpoint.branch_id, role);
126
- let host = props.pooled
127
- ? endpoint.host.replace(endpoint.id, `${endpoint.id}-pooler`)
128
- : endpoint.host;
129
- if (parsedPIT.tag !== "head") {
130
- host = endpoint.host.replace(endpoint.id, endpoint.branch_id);
131
- }
132
- const connectionString = new URL(`postgresql://${host}`);
133
- connectionString.pathname = database;
134
- connectionString.username = role;
135
- connectionString.password = password;
136
- if (props.prisma) {
137
- connectionString.searchParams.set("connect_timeout", "30");
138
- if (props.pooled) {
139
- connectionString.searchParams.set("pool_timeout", "30");
140
- connectionString.searchParams.set("pgbouncer", "true");
141
- }
142
- }
143
- if (props.ssl !== "omit") {
144
- connectionString.searchParams.set("sslmode", props.ssl);
145
- connectionString.searchParams.set("channel_binding", "require");
146
- }
147
- if (parsedPIT.tag === "lsn") {
148
- connectionString.searchParams.set("options", `neon_lsn:${parsedPIT.lsn}`);
149
- }
150
- else if (parsedPIT.tag === "timestamp") {
151
- connectionString.searchParams.set("options", `neon_timestamp:${parsedPIT.timestamp}`);
152
- }
153
- if (props.psql) {
154
- const psqlArgs = props["--"];
155
- await psql(connectionString.toString(), psqlArgs, {
156
- mode: props.fallback ? "ts" : "auto",
157
- });
158
- }
159
- else if (props.extended) {
160
- writer(props).end({
161
- connection_string: connectionString.toString(),
162
- host,
163
- role,
164
- password,
165
- database,
166
- options: connectionString.searchParams.toString(),
167
- }, { fields: ["host", "role", "password", "database"] });
168
- }
169
- else {
170
- process.stdout.write(connectionString.toString() + "\n");
171
- }
172
- };
@@ -1,284 +0,0 @@
1
- import { isNeonApiError, retryOnLock } from "../api.js";
2
- import { log } from "../log.js";
3
- import { branchIdFromProps, fillSingleProject, resolveSingleDatabase, } from "../utils/enrichers.js";
4
- import { writer } from "../writer.js";
5
- const SETTINGS_FIELDS = [
6
- "db_aggregates_enabled",
7
- "db_anon_role",
8
- "db_extra_search_path",
9
- "db_max_rows",
10
- "db_schemas",
11
- "jwt_role_claim_key",
12
- "jwt_cache_max_lifetime",
13
- "openapi_mode",
14
- "server_cors_allowed_origins",
15
- "server_timing_enabled",
16
- ];
17
- const settingsFlags = {
18
- "db-aggregates-enabled": {
19
- type: "boolean",
20
- describe: "Enable aggregate functions in queries",
21
- },
22
- "db-anon-role": {
23
- type: "string",
24
- describe: "Database role used for anonymous (unauthenticated) requests",
25
- },
26
- "db-extra-search-path": {
27
- type: "string",
28
- describe: "Extra schemas appended to the search path",
29
- },
30
- "db-max-rows": {
31
- type: "number",
32
- describe: "Maximum number of rows returned by a single request",
33
- },
34
- "db-schemas": {
35
- type: "string",
36
- describe: "Comma-separated list of schemas exposed via the Data API",
37
- },
38
- "jwt-role-claim-key": {
39
- type: "string",
40
- describe: "JWT claim path used to extract the role",
41
- },
42
- "jwt-cache-max-lifetime": {
43
- type: "number",
44
- describe: "Maximum JWT cache lifetime in seconds",
45
- },
46
- "openapi-mode": {
47
- type: "string",
48
- choices: ["ignore-privileges", "disabled"],
49
- describe: "OpenAPI mode",
50
- },
51
- "server-cors-allowed-origins": {
52
- type: "string",
53
- describe: "CORS allowed origins",
54
- },
55
- "server-timing-enabled": {
56
- type: "boolean",
57
- describe: "Enable Server-Timing response headers",
58
- },
59
- };
60
- export const command = "data-api";
61
- export const describe = "Manage the Neon Data API for a database";
62
- export const builder = (argv) => argv
63
- .usage("$0 data-api <sub-command> [options]")
64
- .options({
65
- "project-id": {
66
- describe: "Project ID",
67
- type: "string",
68
- },
69
- branch: {
70
- describe: "Branch ID or name",
71
- type: "string",
72
- },
73
- database: {
74
- describe: "Database name",
75
- type: "string",
76
- },
77
- })
78
- .middleware(fillSingleProject)
79
- .command("create", "Provision the Neon Data API for a database", (yargs) => yargs.options({
80
- "auth-provider": {
81
- type: "string",
82
- choices: ["neon_auth", "external"],
83
- describe: "Authentication provider",
84
- },
85
- "jwks-url": {
86
- type: "string",
87
- describe: "URL that lists the JWKS (used with external auth)",
88
- },
89
- "provider-name": {
90
- type: "string",
91
- describe: "Name of the auth provider (e.g. Clerk, Stytch, Auth0)",
92
- },
93
- "jwt-audience": {
94
- type: "string",
95
- describe: "Expected JWT audience claim",
96
- },
97
- "add-default-grants": {
98
- type: "boolean",
99
- describe: "Grant all permissions on tables in the public schema to authenticated users",
100
- },
101
- "skip-auth-schema": {
102
- type: "boolean",
103
- describe: "Skip creating the auth schema and RLS functions",
104
- },
105
- ...settingsFlags,
106
- }), (args) => create(args))
107
- .command("get", "Show the Neon Data API status and settings", (yargs) => yargs, (args) => get(args))
108
- .command("update", "Update Neon Data API settings (merges with current settings by default)", (yargs) => yargs.options({
109
- replace: {
110
- type: "boolean",
111
- default: false,
112
- describe: "Replace settings with only the flags provided. Omitted settings revert to server defaults.",
113
- },
114
- ...settingsFlags,
115
- }), (args) => update(args))
116
- .command("refresh-schema", "Refresh the Data API schema cache without changing settings", (yargs) => yargs, (args) => refreshSchema(args))
117
- .command("delete", "Tear down the Neon Data API for a database", (yargs) => yargs, (args) => deleteDataApi(args));
118
- export const handler = (args) => {
119
- return args;
120
- };
121
- const TOP_LEVEL_CREATE_FIELDS = [
122
- "auth_provider",
123
- "jwks_url",
124
- "provider_name",
125
- "jwt_audience",
126
- "add_default_grants",
127
- "skip_auth_schema",
128
- ];
129
- const argKey = (snake) => snake.replace(/_/g, "-");
130
- const buildSettings = (args) => {
131
- const settings = {};
132
- for (const field of SETTINGS_FIELDS) {
133
- const value = args[argKey(field)];
134
- if (value === undefined)
135
- continue;
136
- if (field === "db_schemas" && typeof value === "string") {
137
- settings[field] = value
138
- .split(",")
139
- .map((s) => s.trim())
140
- .filter(Boolean);
141
- }
142
- else {
143
- settings[field] = value;
144
- }
145
- }
146
- return Object.keys(settings).length > 0
147
- ? settings
148
- : undefined;
149
- };
150
- const buildCreateBody = (args) => {
151
- const body = {};
152
- for (const field of TOP_LEVEL_CREATE_FIELDS) {
153
- const value = args[argKey(field)];
154
- if (value !== undefined)
155
- body[field] = value;
156
- }
157
- const settings = buildSettings(args);
158
- if (settings)
159
- body.settings = settings;
160
- return body;
161
- };
162
- const create = async (props) => {
163
- const branchId = await branchIdFromProps(props);
164
- const database = await resolveSingleDatabase({
165
- apiClient: props.apiClient,
166
- projectId: props.projectId,
167
- branchId,
168
- database: props.database,
169
- });
170
- const body = buildCreateBody(props);
171
- const { data } = await retryOnLock(() => props.apiClient.createProjectBranchDataApi(props.projectId, branchId, database, body));
172
- writer(props).end(data, { fields: ["url"] });
173
- };
174
- const GET_FIELDS = ["url", "status", "db_schemas"];
175
- const get = async (props) => {
176
- const branchId = await branchIdFromProps(props);
177
- const database = await resolveSingleDatabase({
178
- apiClient: props.apiClient,
179
- projectId: props.projectId,
180
- branchId,
181
- database: props.database,
182
- });
183
- const { data } = await props.apiClient.getProjectBranchDataApi(props.projectId, branchId, database);
184
- // Drop available_schemas from json/yaml output (not part of the public surface).
185
- const { available_schemas: _ignored, ...publicData } = data;
186
- // For table output, flatten db_schemas onto the top-level for column rendering.
187
- const tableRow = {
188
- url: publicData.url,
189
- status: publicData.status,
190
- db_schemas: (publicData.settings?.db_schemas ?? []).join(", "),
191
- };
192
- if (props.output === "json" || props.output === "yaml") {
193
- writer(props).end(publicData, {
194
- fields: ["url", "status", "settings"],
195
- });
196
- return;
197
- }
198
- writer(props).end(tableRow, { fields: GET_FIELDS });
199
- };
200
- const update = async (props) => {
201
- const branchId = await branchIdFromProps(props);
202
- const database = await resolveSingleDatabase({
203
- apiClient: props.apiClient,
204
- projectId: props.projectId,
205
- branchId,
206
- database: props.database,
207
- });
208
- const userSettings = buildSettings(props);
209
- if (!userSettings) {
210
- throw new Error("No settings flags provided. Pass at least one setting flag to update, or use `data-api refresh-schema` to refresh the schema cache without changing settings.");
211
- }
212
- let settings;
213
- if (props.replace) {
214
- settings = userSettings;
215
- }
216
- else {
217
- let current;
218
- try {
219
- const { data } = await props.apiClient.getProjectBranchDataApi(props.projectId, branchId, database);
220
- current = data.settings ?? undefined;
221
- }
222
- catch (err) {
223
- if (isNeonApiError(err) && err.status === 404) {
224
- throw new Error(`Data API is not provisioned for ${database} on branch ${branchId}. Run \`neonctl data-api create\` first.`);
225
- }
226
- throw err;
227
- }
228
- if (!current) {
229
- throw new Error(`Could not read current Data API settings for ${database} on branch ${branchId}. Retry, or pass --replace to overwrite.`);
230
- }
231
- settings = { ...current, ...(userSettings ?? {}) };
232
- }
233
- const body = {};
234
- if (settings)
235
- body.settings = settings;
236
- try {
237
- await retryOnLock(() => props.apiClient.updateProjectBranchDataApi(props.projectId, branchId, database, body));
238
- }
239
- catch (err) {
240
- if (isNeonApiError(err) && err.status === 404) {
241
- throw new Error(`Data API is not provisioned for ${database} on branch ${branchId}. Run \`neonctl data-api create\` first.`);
242
- }
243
- throw err;
244
- }
245
- log.info(`Data API settings updated for ${database} on branch ${branchId}`);
246
- };
247
- const refreshSchema = async (props) => {
248
- const branchId = await branchIdFromProps(props);
249
- const database = await resolveSingleDatabase({
250
- apiClient: props.apiClient,
251
- projectId: props.projectId,
252
- branchId,
253
- database: props.database,
254
- });
255
- try {
256
- await retryOnLock(() => props.apiClient.updateProjectBranchDataApi(props.projectId, branchId, database, {}));
257
- }
258
- catch (err) {
259
- if (isNeonApiError(err) && err.status === 404) {
260
- throw new Error(`Data API is not provisioned for ${database} on branch ${branchId}. Run \`neonctl data-api create\` first.`);
261
- }
262
- throw err;
263
- }
264
- log.info(`Data API schema cache refreshed for ${database} on branch ${branchId}`);
265
- };
266
- const deleteDataApi = async (props) => {
267
- const branchId = await branchIdFromProps(props);
268
- const database = await resolveSingleDatabase({
269
- apiClient: props.apiClient,
270
- projectId: props.projectId,
271
- branchId,
272
- database: props.database,
273
- });
274
- try {
275
- await retryOnLock(() => props.apiClient.deleteProjectBranchDataApi(props.projectId, branchId, database));
276
- }
277
- catch (err) {
278
- if (isNeonApiError(err) && err.status === 404) {
279
- throw new Error(`Data API is not provisioned for ${database} on branch ${branchId}.`);
280
- }
281
- throw err;
282
- }
283
- log.info(`Data API deleted for ${database} on branch ${branchId}`);
284
- };
@@ -1,82 +0,0 @@
1
- import { retryOnLock } from "../api.js";
2
- import { branchIdFromProps, fillSingleProject } from "../utils/enrichers.js";
3
- import { writer } from "../writer.js";
4
- export const DATABASE_FIELDS = ["name", "owner_name", "created_at"];
5
- export const command = "databases";
6
- export const describe = "Manage databases";
7
- export const aliases = ["database", "db"];
8
- export const builder = (argv) => argv
9
- .usage("$0 databases <sub-command> [options]")
10
- .options({
11
- "project-id": {
12
- describe: "Project ID",
13
- type: "string",
14
- },
15
- branch: {
16
- describe: "Branch ID or name",
17
- type: "string",
18
- },
19
- })
20
- .middleware(fillSingleProject)
21
- .command("list", "List databases", (yargs) => yargs, (args) => list(args))
22
- .command("create", "Create a database", (yargs) => yargs.options({
23
- name: {
24
- describe: "Database name",
25
- type: "string",
26
- demandOption: true,
27
- },
28
- "owner-name": {
29
- describe: "Owner name",
30
- type: "string",
31
- },
32
- }), (args) => create(args))
33
- .command("delete <database>", "Delete a database", (yargs) => yargs, (args) => deleteDb(args));
34
- export const handler = (args) => {
35
- return args;
36
- };
37
- export const list = async (props) => {
38
- const branchId = await branchIdFromProps(props);
39
- const { data } = await props.apiClient.listProjectBranchDatabases(props.projectId, branchId);
40
- writer(props).end(data.databases, {
41
- fields: DATABASE_FIELDS,
42
- });
43
- };
44
- export const create = async (props) => {
45
- const branchId = await branchIdFromProps(props);
46
- const owner = props.ownerName ??
47
- (await props.apiClient
48
- .listProjectBranchRoles(props.projectId, branchId)
49
- .then(({ data }) => {
50
- if (data.roles.length === 0) {
51
- throw new Error(`No roles found in branch ${branchId}`);
52
- }
53
- if (data.roles.length > 1) {
54
- throw new Error(`More than one role found in branch ${branchId}. Please specify the owner name. Roles: ${data.roles
55
- .map((r) => r.name)
56
- .join(", ")}`);
57
- }
58
- return data.roles[0].name;
59
- }));
60
- if (!owner) {
61
- throw new Error("No owner found");
62
- }
63
- const { data } = await retryOnLock(() => props.apiClient.createProjectBranchDatabase(props.projectId, branchId, {
64
- database: {
65
- name: props.name,
66
- owner_name: owner,
67
- },
68
- }));
69
- writer(props).end(data.database, {
70
- fields: DATABASE_FIELDS,
71
- });
72
- };
73
- export const deleteDb = async (props) => {
74
- const branchId = await branchIdFromProps(props);
75
- const { data } = await retryOnLock(() => props.apiClient.deleteProjectBranchDatabase(props.projectId, branchId, props.database));
76
- // A 204 (database already gone) carries no body; only a 200 returns it.
77
- if (data) {
78
- writer(props).end(data.database, {
79
- fields: DATABASE_FIELDS,
80
- });
81
- }
82
- };
@@ -1,26 +0,0 @@
1
- import { fillSingleProject } from "../utils/enrichers.js";
2
- import { applyCmd, applyFlags, envFlag, envPullFlag, } from "./config.js";
3
- export const command = "deploy";
4
- export const describe = "Apply a neon.ts policy to a branch (alias for `config apply`)";
5
- export const builder = (argv) => argv
6
- .usage("$0 deploy [options]")
7
- .options({
8
- "project-id": {
9
- describe: "Project ID",
10
- type: "string",
11
- },
12
- branch: {
13
- describe: "Branch ID or name",
14
- type: "string",
15
- },
16
- config: {
17
- describe: "Path to a neon.ts policy (defaults to walking up from cwd)",
18
- type: "string",
19
- },
20
- ...envFlag,
21
- ...applyFlags,
22
- ...envPullFlag,
23
- })
24
- .middleware(fillSingleProject)
25
- .strict();
26
- export const handler = (props) => applyCmd(props);