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.
Files changed (184) hide show
  1. package/.bump +1 -0
  2. package/.editorconfig +7 -0
  3. package/.eslintrc.cjs +15 -0
  4. package/.github/workflows/commitlint.yml +46 -0
  5. package/.github/workflows/pr.yml +25 -0
  6. package/.github/workflows/release.yml +30 -0
  7. package/.husky/commit-msg +4 -0
  8. package/.husky/pre-commit +4 -0
  9. package/.nvmrc +1 -0
  10. package/.prettierignore +3 -0
  11. package/.prettierrc.json +3 -0
  12. package/.releaserc.json +47 -0
  13. package/LICENSE +202 -0
  14. package/commitlint.config.cjs +7 -0
  15. package/generateOptionsFromSpec.ts +68 -0
  16. package/jest/setup.js +5 -0
  17. package/jest.config.ts +199 -0
  18. package/mocks/bin/psql.cjs +9 -0
  19. package/mocks/main/projects/GET.js +27 -0
  20. package/mocks/main/projects/POST.js +22 -0
  21. package/mocks/main/projects/shared/GET.js +16 -0
  22. package/mocks/main/projects/test/DELETE.json +7 -0
  23. package/mocks/main/projects/test/GET.json +13 -0
  24. package/mocks/main/projects/test/PATCH.js +18 -0
  25. package/mocks/main/projects/test/branches/GET.json +25 -0
  26. package/mocks/main/projects/test/branches/POST.js +83 -0
  27. package/mocks/main/projects/test/branches/br-cloudy-branch-12345678/DELETE.json +7 -0
  28. package/mocks/main/projects/test/branches/br-cloudy-branch-12345678/GET.json +9 -0
  29. package/mocks/main/projects/test/branches/br-cloudy-branch-12345678/PATCH.js +14 -0
  30. package/mocks/main/projects/test/branches/br-cloudy-branch-12345678/databases/GET.json +6 -0
  31. package/mocks/main/projects/test/branches/br-cloudy-branch-12345678/databases/POST.js +13 -0
  32. package/mocks/main/projects/test/branches/br-cloudy-branch-12345678/databases/test_db/DELETE.json +6 -0
  33. package/mocks/main/projects/test/branches/br-cloudy-branch-12345678/endpoints/GET.json +26 -0
  34. package/mocks/main/projects/test/branches/br-cloudy-branch-12345678/endpoints/POST.json +6 -0
  35. package/mocks/main/projects/test/branches/br-cloudy-branch-12345678/roles/GET.json +3 -0
  36. package/mocks/main/projects/test/branches/br-cloudy-branch-12345678/roles/POST.js +14 -0
  37. package/mocks/main/projects/test/branches/br-cloudy-branch-12345678/roles/test_role/DELETE.json +6 -0
  38. package/mocks/main/projects/test/branches/br-cloudy-branch-12345678/roles/test_role/reveal_password/GET.json +3 -0
  39. package/mocks/main/projects/test/branches/br-cloudy-branch-12345678/set_as_primary/POST.json +9 -0
  40. package/mocks/main/projects/test/branches/br-numbered-branch-123456/GET.json +10 -0
  41. package/mocks/main/projects/test/branches/br-sunny-branch-123456/DELETE.json +7 -0
  42. package/mocks/main/projects/test/branches/br-sunny-branch-123456/GET.json +10 -0
  43. package/mocks/main/projects/test/branches/br-sunny-branch-123456/PATCH.js +14 -0
  44. package/mocks/main/projects/test/branches/br-sunny-branch-123456/databases/GET.json +6 -0
  45. package/mocks/main/projects/test/branches/br-sunny-branch-123456/databases/POST.js +13 -0
  46. package/mocks/main/projects/test/branches/br-sunny-branch-123456/databases/test_db/DELETE.json +6 -0
  47. package/mocks/main/projects/test/branches/br-sunny-branch-123456/endpoints/GET.json +26 -0
  48. package/mocks/main/projects/test/branches/br-sunny-branch-123456/endpoints/POST.json +6 -0
  49. package/mocks/main/projects/test/branches/br-sunny-branch-123456/restore/POST.js +16 -0
  50. package/mocks/main/projects/test/branches/br-sunny-branch-123456/roles/GET.json +3 -0
  51. package/mocks/main/projects/test/branches/br-sunny-branch-123456/roles/POST.js +14 -0
  52. package/mocks/main/projects/test/branches/br-sunny-branch-123456/roles/test_role/DELETE.json +6 -0
  53. package/mocks/main/projects/test/branches/br-sunny-branch-123456/roles/test_role/reveal_password/GET.json +3 -0
  54. package/mocks/main/projects/test/branches/br-sunny-branch-123456/set_as_primary/POST.json +9 -0
  55. package/mocks/main/projects/test/endpoints/GET.json +9 -0
  56. package/mocks/main/projects/test/endpoints/POST.js +32 -0
  57. package/mocks/main/projects/test/endpoints/test_endpoint_id/DELETE.json +7 -0
  58. package/mocks/main/projects/test/endpoints/test_endpoint_id/GET.json +9 -0
  59. package/mocks/main/projects/test/endpoints/test_endpoint_id/PATCH.js +17 -0
  60. package/mocks/main/projects/test/operations/GET.json +22 -0
  61. package/mocks/main/users/me/GET.json +5 -0
  62. package/mocks/restore/projects/test/branches/GET.json +21 -0
  63. package/mocks/restore/projects/test/branches/br-another-branch-123456/GET.json +6 -0
  64. package/mocks/restore/projects/test/branches/br-another-branch-123456/restore/POST.js +13 -0
  65. package/mocks/restore/projects/test/branches/br-any-branch-123456/GET.json +6 -0
  66. package/mocks/restore/projects/test/branches/br-parent-tots-123456/GET.json +7 -0
  67. package/mocks/restore/projects/test/branches/br-parent-tots-123456/restore/POST.js +14 -0
  68. package/mocks/restore/projects/test/branches/br-self-tolsn-123456/GET.json +6 -0
  69. package/mocks/restore/projects/test/branches/br-self-tolsn-123456/restore/POST.js +15 -0
  70. package/mocks/single_project/projects/GET.json +10 -0
  71. package/mocks/single_project/projects/test-project-123456/GET.json +14 -0
  72. package/mocks/single_project/projects/test-project-123456/branches/GET.json +11 -0
  73. package/mocks/single_project/projects/test-project-123456/branches/br-main-branch-123456/databases/GET.json +3 -0
  74. package/mocks/single_project/projects/test-project-123456/branches/br-main-branch-123456/endpoints/GET.json +10 -0
  75. package/mocks/single_project/projects/test-project-123456/branches/br-main-branch-123456/roles/GET.json +3 -0
  76. package/mocks/single_project/projects/test-project-123456/branches/br-main-branch-123456/roles/test_role/reveal_password/GET.json +3 -0
  77. package/package.json +7 -6
  78. package/pkg.js +45 -3
  79. package/rollup.config.js +20 -0
  80. package/snapshots/commands/branches.test.snap +221 -0
  81. package/snapshots/commands/connection_string.test.snap +70 -0
  82. package/snapshots/commands/databases.test.snap +20 -0
  83. package/snapshots/commands/ip_allow.test.snap +55 -0
  84. package/snapshots/commands/operations.test.snap +17 -0
  85. package/snapshots/commands/projects.test.snap +141 -0
  86. package/snapshots/commands/roles.test.snap +19 -0
  87. package/snapshots/commands/set_context.test.snap +30 -0
  88. package/snapshots/writer.test.snap +60 -0
  89. package/snapshotsResolver.cjs +32 -0
  90. package/src/analytics.ts +95 -0
  91. package/src/api.ts +44 -0
  92. package/src/auth.ts +137 -0
  93. package/{cli.js → src/cli.ts} +1 -0
  94. package/src/commands/auth.test.ts +62 -0
  95. package/src/commands/auth.ts +148 -0
  96. package/src/commands/branches.test.ts +354 -0
  97. package/src/commands/branches.ts +451 -0
  98. package/src/commands/connection_string.test.ts +250 -0
  99. package/src/commands/connection_string.ts +210 -0
  100. package/src/commands/databases.test.ts +55 -0
  101. package/src/commands/databases.ts +129 -0
  102. package/src/commands/help.test.ts +13 -0
  103. package/{commands/index.js → src/commands/index.ts} +11 -10
  104. package/src/commands/ip_allow.test.ts +86 -0
  105. package/src/commands/ip_allow.ts +202 -0
  106. package/src/commands/operations.test.ts +13 -0
  107. package/src/commands/operations.ts +41 -0
  108. package/src/commands/projects.test.ts +147 -0
  109. package/src/commands/projects.ts +275 -0
  110. package/src/commands/roles.test.ts +46 -0
  111. package/src/commands/roles.ts +100 -0
  112. package/src/commands/set_context.test.ts +64 -0
  113. package/src/commands/set_context.ts +27 -0
  114. package/src/commands/user.ts +21 -0
  115. package/src/config.ts +22 -0
  116. package/src/context.ts +61 -0
  117. package/src/env.ts +7 -0
  118. package/src/errors.ts +24 -0
  119. package/src/help.ts +185 -0
  120. package/src/index.ts +180 -0
  121. package/src/log.ts +16 -0
  122. package/src/parameters.gen.ts +332 -0
  123. package/src/pkg.ts +9 -0
  124. package/src/test_utils/mock_server.ts +27 -0
  125. package/src/test_utils/oauth_server.ts +10 -0
  126. package/src/test_utils/test_cli_command.ts +117 -0
  127. package/src/types.ts +25 -0
  128. package/src/utils/enrichers.ts +73 -0
  129. package/src/utils/formats.test.ts +41 -0
  130. package/src/utils/formats.ts +11 -0
  131. package/src/utils/middlewares.ts +23 -0
  132. package/src/utils/point_in_time.ts +86 -0
  133. package/src/utils/psql.ts +29 -0
  134. package/src/utils/string.ts +8 -0
  135. package/src/utils/ui.ts +64 -0
  136. package/src/writer.test.ts +98 -0
  137. package/src/writer.ts +131 -0
  138. package/tsconfig.json +17 -0
  139. package/analytics.js +0 -78
  140. package/api.js +0 -35
  141. package/auth.js +0 -101
  142. package/commands/auth.js +0 -102
  143. package/commands/auth.test.js +0 -42
  144. package/commands/branches.js +0 -311
  145. package/commands/branches.test.js +0 -321
  146. package/commands/connection_string.js +0 -137
  147. package/commands/connection_string.test.js +0 -204
  148. package/commands/databases.js +0 -79
  149. package/commands/databases.test.js +0 -51
  150. package/commands/help.test.js +0 -11
  151. package/commands/ip_allow.js +0 -135
  152. package/commands/ip_allow.test.js +0 -78
  153. package/commands/operations.js +0 -28
  154. package/commands/operations.test.js +0 -11
  155. package/commands/projects.js +0 -156
  156. package/commands/projects.test.js +0 -116
  157. package/commands/roles.js +0 -57
  158. package/commands/roles.test.js +0 -42
  159. package/commands/set_context.js +0 -22
  160. package/commands/set_context.test.js +0 -53
  161. package/commands/user.js +0 -15
  162. package/config.js +0 -11
  163. package/context.js +0 -48
  164. package/env.js +0 -6
  165. package/errors.js +0 -16
  166. package/help.js +0 -146
  167. package/index.js +0 -168
  168. package/log.js +0 -15
  169. package/parameters.gen.js +0 -302
  170. package/test_utils/mock_server.js +0 -16
  171. package/test_utils/oauth_server.js +0 -9
  172. package/test_utils/test_cli_command.js +0 -80
  173. package/types.js +0 -1
  174. package/utils/enrichers.js +0 -49
  175. package/utils/formats.js +0 -5
  176. package/utils/formats.test.js +0 -32
  177. package/utils/middlewares.js +0 -20
  178. package/utils/point_in_time.js +0 -44
  179. package/utils/psql.js +0 -24
  180. package/utils/string.js +0 -5
  181. package/utils/ui.js +0 -59
  182. package/writer.js +0 -87
  183. package/writer.test.js +0 -86
  184. /package/{callback.html → src/callback.html} +0 -0
package/src/index.ts ADDED
@@ -0,0 +1,180 @@
1
+ import { basename } from 'node:path';
2
+ import yargs from 'yargs';
3
+ import { hideBin } from 'yargs/helpers';
4
+ import axiosDebug from 'axios-debug-log';
5
+ axiosDebug({
6
+ request(debug, config) {
7
+ debug(`${config.method?.toUpperCase()} ${config.url}`);
8
+ },
9
+ response(debug, response) {
10
+ debug(`${response.status} ${response.statusText}`);
11
+ },
12
+ error(debug, error) {
13
+ debug(error);
14
+ },
15
+ });
16
+ import { Api } from '@neondatabase/api-client';
17
+
18
+ import { ensureAuth } from './commands/auth.js';
19
+ import { defaultDir, ensureConfigDir } from './config.js';
20
+ import { log } from './log.js';
21
+ import { defaultClientID } from './auth.js';
22
+ import { fillInArgs } from './utils/middlewares.js';
23
+ import pkg from './pkg.js';
24
+ import commands from './commands/index.js';
25
+ import { analyticsMiddleware, sendError } from './analytics.js';
26
+ import { isAxiosError } from 'axios';
27
+ import { matchErrorCode } from './errors.js';
28
+ import { showHelp } from './help.js';
29
+ import { currentContextFile, enrichFromContext } from './context.js';
30
+
31
+ const NO_SUBCOMMANDS_VERBS = [
32
+ 'auth',
33
+ 'me',
34
+ 'cs',
35
+ 'connection-string',
36
+ 'set-context',
37
+ ];
38
+
39
+ let builder = yargs(hideBin(process.argv));
40
+ builder = builder
41
+ .scriptName(pkg.name)
42
+ .locale('en')
43
+ .usage('$0 <command> [options]')
44
+ .parserConfiguration({
45
+ 'populate--': true,
46
+ })
47
+ .help()
48
+ .option('output', {
49
+ alias: 'o',
50
+ group: 'Global options:',
51
+ describe: 'Set output format',
52
+ type: 'string',
53
+ choices: ['json', 'yaml', 'table'],
54
+ default: 'table',
55
+ })
56
+ .option('api-host', {
57
+ describe: 'The API host',
58
+ hidden: true,
59
+ default: process.env.NEON_API_HOST ?? 'https://console.neon.tech/api/v2',
60
+ })
61
+ // Setup config directory
62
+ .option('config-dir', {
63
+ describe: 'Path to config directory',
64
+ group: 'Global options:',
65
+ type: 'string',
66
+ default: defaultDir,
67
+ })
68
+ .option('force-auth', {
69
+ describe: 'Force authentication',
70
+ type: 'boolean',
71
+ hidden: true,
72
+ default: false,
73
+ })
74
+ .middleware(ensureConfigDir)
75
+ .options({
76
+ 'oauth-host': {
77
+ description: 'URL to Neon OAuth host',
78
+ hidden: true,
79
+ default: process.env.NEON_OAUTH_HOST ?? 'https://oauth2.neon.tech',
80
+ },
81
+ 'client-id': {
82
+ description: 'OAuth client id',
83
+ hidden: true,
84
+ type: 'string',
85
+ default: defaultClientID,
86
+ },
87
+ 'api-key': {
88
+ describe: 'API key',
89
+ group: 'Global options:',
90
+ type: 'string',
91
+ default: process.env.NEON_API_KEY ?? '',
92
+ },
93
+ apiClient: {
94
+ hidden: true,
95
+ coerce: (v) => v as Api<unknown>,
96
+ default: null as unknown as Api<unknown>,
97
+ },
98
+ 'context-file': {
99
+ describe: 'Context file',
100
+ type: 'string',
101
+ default: currentContextFile,
102
+ },
103
+ })
104
+ .middleware((args) => fillInArgs(args), true)
105
+ .help(false)
106
+ .group('help', 'Global options:')
107
+ .option('help', {
108
+ describe: 'Show help',
109
+ type: 'boolean',
110
+ default: false,
111
+ })
112
+ .alias('help', 'h')
113
+ .middleware(async (args) => {
114
+ if (
115
+ args.help ||
116
+ (args._.length === 1 &&
117
+ !NO_SUBCOMMANDS_VERBS.includes(args._[0] as string))
118
+ ) {
119
+ await showHelp(builder);
120
+ }
121
+ })
122
+ .middleware(ensureAuth)
123
+ .middleware(enrichFromContext as any)
124
+ .command(commands as any)
125
+ .strictCommands()
126
+ .option('analytics', {
127
+ describe: 'Manage analytics. Example: --no-analytics, --analytics false',
128
+ group: 'Global options:',
129
+ type: 'boolean',
130
+ default: true,
131
+ })
132
+ .middleware(analyticsMiddleware, true)
133
+ .group('version', 'Global options:')
134
+ .alias('version', 'v')
135
+ .completion()
136
+ .scriptName(basename(process.argv[1]) === 'neon' ? 'neon' : 'neonctl')
137
+ .epilog(
138
+ 'For more information, visit https://neon.tech/docs/reference/neon-cli',
139
+ )
140
+ .wrap(null)
141
+ .fail(async (msg, err) => {
142
+ if (process.argv.some((arg) => arg === '--help' || arg === '-h')) {
143
+ await showHelp(builder);
144
+ process.exit(0);
145
+ }
146
+
147
+ if (isAxiosError(err)) {
148
+ if (err.code === 'ECONNABORTED') {
149
+ log.error('Request timed out');
150
+ sendError(err, 'REQUEST_TIMEOUT');
151
+ } else if (err.response?.status === 401) {
152
+ sendError(err, 'AUTH_FAILED');
153
+ log.error('Authentication failed, please run `neonctl auth`');
154
+ } else {
155
+ if (err.response?.data?.message) {
156
+ log.error(err.response?.data?.message);
157
+ }
158
+ log.debug(
159
+ 'status: %d %s | path: %s',
160
+ err.response?.status,
161
+ err.response?.statusText,
162
+ err.request?.path,
163
+ );
164
+ sendError(err, 'API_ERROR');
165
+ }
166
+ } else {
167
+ sendError(err || new Error(msg), matchErrorCode(msg || err?.message));
168
+ log.error(msg || err?.message);
169
+ }
170
+ err?.stack && log.debug('Stack: %s', err.stack);
171
+ process.exit(1);
172
+ });
173
+
174
+ (async () => {
175
+ const args = await builder.argv;
176
+ if (args._.length === 0 || args.help) {
177
+ await showHelp(builder);
178
+ process.exit(0);
179
+ }
180
+ })();
package/src/log.ts ADDED
@@ -0,0 +1,16 @@
1
+ import { format } from 'node:util';
2
+ import { isDebug } from './env.js';
3
+
4
+ export const log = {
5
+ debug: (...args: unknown[]) => {
6
+ if (isDebug()) {
7
+ process.stderr.write(`DEBUG: ${format(...args)}\n`);
8
+ }
9
+ },
10
+ info: (...args: unknown[]) => {
11
+ process.stderr.write(`INFO: ${format(...args)}\n`);
12
+ },
13
+ error: (...args: unknown[]) => {
14
+ process.stderr.write(`ERROR: ${format(...args)}\n`);
15
+ },
16
+ };
@@ -0,0 +1,332 @@
1
+ // FILE IS GENERATED, DO NOT EDIT
2
+
3
+ export const projectCreateRequest = {
4
+ 'project.settings.quota.active_time_seconds': {
5
+ type: "number",
6
+ description: "The total amount of wall-clock time allowed to be spent by the project's compute endpoints.\n",
7
+ demandOption: false,
8
+ },
9
+ 'project.settings.quota.compute_time_seconds': {
10
+ type: "number",
11
+ description: "The total amount of CPU seconds allowed to be spent by the project's compute endpoints.\n",
12
+ demandOption: false,
13
+ },
14
+ 'project.settings.quota.written_data_bytes': {
15
+ type: "number",
16
+ description: "Total amount of data written to all of a project's branches.\n",
17
+ demandOption: false,
18
+ },
19
+ 'project.settings.quota.data_transfer_bytes': {
20
+ type: "number",
21
+ description: "Total amount of data transferred from all of a project's branches using the proxy.\n",
22
+ demandOption: false,
23
+ },
24
+ 'project.settings.quota.logical_size_bytes': {
25
+ type: "number",
26
+ description: "Limit on the logical size of every project's branch.\n",
27
+ demandOption: false,
28
+ },
29
+ 'project.settings.allowed_ips.ips': {
30
+ type: "array",
31
+ description: "A list of IP addresses that are allowed to connect to the endpoint.",
32
+ demandOption: false,
33
+ },
34
+ 'project.settings.allowed_ips.primary_branch_only': {
35
+ type: "boolean",
36
+ description: "If true, the list will be applied only to the primary branch.",
37
+ demandOption: true,
38
+ },
39
+ 'project.settings.enable_logical_replication': {
40
+ type: "boolean",
41
+ description: "Sets wal_level=logical for all compute endpoints in this project.\nAll active endpoints will be suspended.\nOnce enabled, logical replication cannot be disabled.\n",
42
+ demandOption: false,
43
+ },
44
+ 'project.name': {
45
+ type: "string",
46
+ description: "The project name",
47
+ demandOption: false,
48
+ },
49
+ 'project.branch.name': {
50
+ type: "string",
51
+ description: "The branch name. If not specified, the default branch name will be used.\n",
52
+ demandOption: false,
53
+ },
54
+ 'project.branch.role_name': {
55
+ type: "string",
56
+ description: "The role name. If not specified, the default role name will be used.\n",
57
+ demandOption: false,
58
+ },
59
+ 'project.branch.database_name': {
60
+ type: "string",
61
+ description: "The database name. If not specified, the default database name will be used.\n",
62
+ demandOption: false,
63
+ },
64
+ 'project.provisioner': {
65
+ type: "string",
66
+ description: "The Neon compute provisioner.\nSpecify the `k8s-neonvm` provisioner to create a compute endpoint that supports Autoscaling.\n",
67
+ demandOption: false,
68
+ choices: ["k8s-pod","k8s-neonvm"],
69
+ },
70
+ 'project.region_id': {
71
+ type: "string",
72
+ description: "The region identifier. Refer to our [Regions](https://neon.tech/docs/introduction/regions) documentation for supported regions. Values are specified in this format: `aws-us-east-1`\n",
73
+ demandOption: false,
74
+ },
75
+ 'project.default_endpoint_settings.suspend_timeout_seconds': {
76
+ type: "number",
77
+ description: "Duration of inactivity in seconds after which the compute endpoint is\nautomatically suspended. The value `0` means use the global default.\nThe value `-1` means never suspend. The default value is `300` seconds (5 minutes).\nThe minimum value is `60` seconds (1 minute).\nThe maximum value is `604800` seconds (1 week). For more information, see\n[Auto-suspend configuration](https://neon.tech/docs/manage/endpoints#auto-suspend-configuration).\n",
78
+ demandOption: false,
79
+ },
80
+ 'project.pg_version': {
81
+ type: "number",
82
+ description: "The major Postgres version number. Currently supported versions are `14`, `15`, and `16`.",
83
+ demandOption: false,
84
+ },
85
+ 'project.store_passwords': {
86
+ type: "boolean",
87
+ description: "Whether or not passwords are stored for roles in the Neon project. Storing passwords facilitates access to Neon features that require authorization.\n",
88
+ demandOption: false,
89
+ },
90
+ 'project.history_retention_seconds': {
91
+ type: "number",
92
+ description: "The number of seconds to retain the point-in-time restore (PITR) backup history for this project.\nThe default is 604800 seconds (7 days).\n",
93
+ demandOption: false,
94
+ },
95
+ } as const;
96
+
97
+ export const projectUpdateRequest = {
98
+ 'project.settings.quota.active_time_seconds': {
99
+ type: "number",
100
+ description: "The total amount of wall-clock time allowed to be spent by the project's compute endpoints.\n",
101
+ demandOption: false,
102
+ },
103
+ 'project.settings.quota.compute_time_seconds': {
104
+ type: "number",
105
+ description: "The total amount of CPU seconds allowed to be spent by the project's compute endpoints.\n",
106
+ demandOption: false,
107
+ },
108
+ 'project.settings.quota.written_data_bytes': {
109
+ type: "number",
110
+ description: "Total amount of data written to all of a project's branches.\n",
111
+ demandOption: false,
112
+ },
113
+ 'project.settings.quota.data_transfer_bytes': {
114
+ type: "number",
115
+ description: "Total amount of data transferred from all of a project's branches using the proxy.\n",
116
+ demandOption: false,
117
+ },
118
+ 'project.settings.quota.logical_size_bytes': {
119
+ type: "number",
120
+ description: "Limit on the logical size of every project's branch.\n",
121
+ demandOption: false,
122
+ },
123
+ 'project.settings.allowed_ips.ips': {
124
+ type: "array",
125
+ description: "A list of IP addresses that are allowed to connect to the endpoint.",
126
+ demandOption: false,
127
+ },
128
+ 'project.settings.allowed_ips.primary_branch_only': {
129
+ type: "boolean",
130
+ description: "If true, the list will be applied only to the primary branch.",
131
+ demandOption: true,
132
+ },
133
+ 'project.settings.enable_logical_replication': {
134
+ type: "boolean",
135
+ description: "Sets wal_level=logical for all compute endpoints in this project.\nAll active endpoints will be suspended.\nOnce enabled, logical replication cannot be disabled.\n",
136
+ demandOption: false,
137
+ },
138
+ 'project.name': {
139
+ type: "string",
140
+ description: "The project name",
141
+ demandOption: false,
142
+ },
143
+ 'project.default_endpoint_settings.suspend_timeout_seconds': {
144
+ type: "number",
145
+ description: "Duration of inactivity in seconds after which the compute endpoint is\nautomatically suspended. The value `0` means use the global default.\nThe value `-1` means never suspend. The default value is `300` seconds (5 minutes).\nThe minimum value is `60` seconds (1 minute).\nThe maximum value is `604800` seconds (1 week). For more information, see\n[Auto-suspend configuration](https://neon.tech/docs/manage/endpoints#auto-suspend-configuration).\n",
146
+ demandOption: false,
147
+ },
148
+ 'project.history_retention_seconds': {
149
+ type: "number",
150
+ description: "The number of seconds to retain the point-in-time restore (PITR) backup history for this project.\nThe default is 604800 seconds (7 days).\n",
151
+ demandOption: false,
152
+ },
153
+ } as const;
154
+
155
+ export const branchCreateRequest = {
156
+ 'endpoints': {
157
+ type: "array",
158
+ description: undefined,
159
+ demandOption: false,
160
+ },
161
+ 'branch.parent_id': {
162
+ type: "string",
163
+ description: "The `branch_id` of the parent branch. If omitted or empty, the branch will be created from the project's primary branch.\n",
164
+ demandOption: false,
165
+ },
166
+ 'branch.name': {
167
+ type: "string",
168
+ description: "The branch name\n",
169
+ demandOption: false,
170
+ },
171
+ 'branch.parent_lsn': {
172
+ type: "string",
173
+ description: "A Log Sequence Number (LSN) on the parent branch. The branch will be created with data from this LSN.\n",
174
+ demandOption: false,
175
+ },
176
+ 'branch.parent_timestamp': {
177
+ type: "string",
178
+ description: "A timestamp identifying a point in time on the parent branch. The branch will be created with data starting from this point in time.\nThe timestamp must be provided in ISO 8601 format; for example: `2024-02-26T12:00:00Z`.\n",
179
+ demandOption: false,
180
+ },
181
+ 'branch.protected': {
182
+ type: "boolean",
183
+ description: "Whether the branch is protected\n",
184
+ demandOption: false,
185
+ },
186
+ } as const;
187
+
188
+ export const branchCreateRequestEndpointOptions = {
189
+ 'type': {
190
+ type: "string",
191
+ description: "The compute endpoint type. Either `read_write` or `read_only`.\nThe `read_only` compute endpoint type is not yet supported.\n",
192
+ demandOption: true,
193
+ choices: ["read_only","read_write"],
194
+ },
195
+ 'provisioner': {
196
+ type: "string",
197
+ description: "The Neon compute provisioner.\nSpecify the `k8s-neonvm` provisioner to create a compute endpoint that supports Autoscaling.\n",
198
+ demandOption: false,
199
+ choices: ["k8s-pod","k8s-neonvm"],
200
+ },
201
+ 'suspend_timeout_seconds': {
202
+ type: "number",
203
+ description: "Duration of inactivity in seconds after which the compute endpoint is\nautomatically suspended. The value `0` means use the global default.\nThe value `-1` means never suspend. The default value is `300` seconds (5 minutes).\nThe minimum value is `60` seconds (1 minute).\nThe maximum value is `604800` seconds (1 week). For more information, see\n[Auto-suspend configuration](https://neon.tech/docs/manage/endpoints#auto-suspend-configuration).\n",
204
+ demandOption: false,
205
+ },
206
+ } as const;
207
+
208
+ export const branchUpdateRequest = {
209
+ 'branch.name': {
210
+ type: "string",
211
+ description: undefined,
212
+ demandOption: false,
213
+ },
214
+ 'branch.protected': {
215
+ type: "boolean",
216
+ description: undefined,
217
+ demandOption: false,
218
+ },
219
+ } as const;
220
+
221
+ export const endpointCreateRequest = {
222
+ 'endpoint.branch_id': {
223
+ type: "string",
224
+ description: "The ID of the branch the compute endpoint will be associated with\n",
225
+ demandOption: true,
226
+ },
227
+ 'endpoint.region_id': {
228
+ type: "string",
229
+ description: "The region where the compute endpoint will be created. Only the project's `region_id` is permitted.\n",
230
+ demandOption: false,
231
+ },
232
+ 'endpoint.type': {
233
+ type: "string",
234
+ description: "The compute endpoint type. Either `read_write` or `read_only`.\nThe `read_only` compute endpoint type is not yet supported.\n",
235
+ demandOption: true,
236
+ choices: ["read_only","read_write"],
237
+ },
238
+ 'endpoint.provisioner': {
239
+ type: "string",
240
+ description: "The Neon compute provisioner.\nSpecify the `k8s-neonvm` provisioner to create a compute endpoint that supports Autoscaling.\n",
241
+ demandOption: false,
242
+ choices: ["k8s-pod","k8s-neonvm"],
243
+ },
244
+ 'endpoint.pooler_enabled': {
245
+ type: "boolean",
246
+ description: "Whether to enable connection pooling for the compute endpoint\n",
247
+ demandOption: false,
248
+ },
249
+ 'endpoint.pooler_mode': {
250
+ type: "string",
251
+ description: "The connection pooler mode. Neon supports PgBouncer in `transaction` mode only.\n",
252
+ demandOption: false,
253
+ choices: ["transaction"],
254
+ },
255
+ 'endpoint.disabled': {
256
+ type: "boolean",
257
+ description: "Whether to restrict connections to the compute endpoint.\nEnabling this option schedules a suspend compute operation.\nA disabled compute endpoint cannot be enabled by a connection or\nconsole action. However, the compute endpoint is periodically\nenabled by check_availability operations.\n",
258
+ demandOption: false,
259
+ },
260
+ 'endpoint.passwordless_access': {
261
+ type: "boolean",
262
+ description: "NOT YET IMPLEMENTED. Whether to permit passwordless access to the compute endpoint.\n",
263
+ demandOption: false,
264
+ },
265
+ 'endpoint.suspend_timeout_seconds': {
266
+ type: "number",
267
+ description: "Duration of inactivity in seconds after which the compute endpoint is\nautomatically suspended. The value `0` means use the global default.\nThe value `-1` means never suspend. The default value is `300` seconds (5 minutes).\nThe minimum value is `60` seconds (1 minute).\nThe maximum value is `604800` seconds (1 week). For more information, see\n[Auto-suspend configuration](https://neon.tech/docs/manage/endpoints#auto-suspend-configuration).\n",
268
+ demandOption: false,
269
+ },
270
+ } as const;
271
+
272
+ export const endpointUpdateRequest = {
273
+ 'endpoint.branch_id': {
274
+ type: "string",
275
+ description: "The destination branch ID. The destination branch must not have an exsiting read-write endpoint.\n",
276
+ demandOption: false,
277
+ },
278
+ 'endpoint.provisioner': {
279
+ type: "string",
280
+ description: "The Neon compute provisioner.\nSpecify the `k8s-neonvm` provisioner to create a compute endpoint that supports Autoscaling.\n",
281
+ demandOption: false,
282
+ choices: ["k8s-pod","k8s-neonvm"],
283
+ },
284
+ 'endpoint.pooler_enabled': {
285
+ type: "boolean",
286
+ description: "Whether to enable connection pooling for the compute endpoint\n",
287
+ demandOption: false,
288
+ },
289
+ 'endpoint.pooler_mode': {
290
+ type: "string",
291
+ description: "The connection pooler mode. Neon supports PgBouncer in `transaction` mode only.\n",
292
+ demandOption: false,
293
+ choices: ["transaction"],
294
+ },
295
+ 'endpoint.disabled': {
296
+ type: "boolean",
297
+ description: "Whether to restrict connections to the compute endpoint.\nEnabling this option schedules a suspend compute operation.\nA disabled compute endpoint cannot be enabled by a connection or\nconsole action. However, the compute endpoint is periodically\nenabled by check_availability operations.\n",
298
+ demandOption: false,
299
+ },
300
+ 'endpoint.passwordless_access': {
301
+ type: "boolean",
302
+ description: "NOT YET IMPLEMENTED. Whether to permit passwordless access to the compute endpoint.\n",
303
+ demandOption: false,
304
+ },
305
+ 'endpoint.suspend_timeout_seconds': {
306
+ type: "number",
307
+ description: "Duration of inactivity in seconds after which the compute endpoint is\nautomatically suspended. The value `0` means use the global default.\nThe value `-1` means never suspend. The default value is `300` seconds (5 minutes).\nThe minimum value is `60` seconds (1 minute).\nThe maximum value is `604800` seconds (1 week). For more information, see\n[Auto-suspend configuration](https://neon.tech/docs/manage/endpoints#auto-suspend-configuration).\n",
308
+ demandOption: false,
309
+ },
310
+ } as const;
311
+
312
+ export const databaseCreateRequest = {
313
+ 'database.name': {
314
+ type: "string",
315
+ description: "The name of the datbase\n",
316
+ demandOption: true,
317
+ },
318
+ 'database.owner_name': {
319
+ type: "string",
320
+ description: "The name of the role that owns the database\n",
321
+ demandOption: true,
322
+ },
323
+ } as const;
324
+
325
+ export const roleCreateRequest = {
326
+ 'role.name': {
327
+ type: "string",
328
+ description: "The role name. Cannot exceed 63 bytes in length.\n",
329
+ demandOption: true,
330
+ },
331
+ } as const;
332
+
package/src/pkg.ts ADDED
@@ -0,0 +1,9 @@
1
+ import { readFileSync } from 'node:fs';
2
+ import { fileURLToPath } from 'node:url';
3
+
4
+ export default JSON.parse(
5
+ readFileSync(
6
+ fileURLToPath(new URL('./package.json', import.meta.url)),
7
+ 'utf-8',
8
+ ),
9
+ );
@@ -0,0 +1,27 @@
1
+ import emocks from 'emocks';
2
+ import express from 'express';
3
+ import { Server } from 'node:http';
4
+ import { AddressInfo } from 'node:net';
5
+ import { join } from 'node:path';
6
+ import { log } from '../log';
7
+
8
+ export const runMockServer = async (mockDir: string) =>
9
+ new Promise<Server>((resolve) => {
10
+ const app = express();
11
+ app.use(express.json());
12
+ app.use(
13
+ '/',
14
+ emocks(join(process.cwd(), 'mocks', mockDir), {
15
+ '404': (req, res) => res.status(404).send({ message: 'Not Found' }),
16
+ }),
17
+ );
18
+
19
+ const server = app.listen(0);
20
+ server.on('listening', () => {
21
+ resolve(server);
22
+ log.info(
23
+ 'Mock server listening at %d',
24
+ (server.address() as AddressInfo).port,
25
+ );
26
+ });
27
+ });
@@ -0,0 +1,10 @@
1
+ import { log } from '../log';
2
+ import { OAuth2Server } from 'oauth2-mock-server';
3
+
4
+ export const startOauthServer = async () => {
5
+ const server = new OAuth2Server();
6
+ await server.issuer.keys.generate('RS256');
7
+ await server.start(0, 'localhost');
8
+ log.info('Started OAuth server');
9
+ return server;
10
+ };