neonctl 1.29.1 → 1.29.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (184) hide show
  1. package/analytics.js +78 -0
  2. package/api.js +35 -0
  3. package/auth.js +101 -0
  4. package/{src/cli.ts → cli.js} +0 -1
  5. package/commands/auth.js +102 -0
  6. package/commands/auth.test.js +42 -0
  7. package/commands/branches.js +303 -0
  8. package/commands/branches.test.js +321 -0
  9. package/commands/connection_string.js +158 -0
  10. package/commands/connection_string.test.js +253 -0
  11. package/commands/databases.js +79 -0
  12. package/commands/databases.test.js +51 -0
  13. package/commands/help.test.js +11 -0
  14. package/{src/commands/index.ts → commands/index.js} +10 -11
  15. package/commands/ip_allow.js +135 -0
  16. package/commands/ip_allow.test.js +78 -0
  17. package/commands/operations.js +28 -0
  18. package/commands/operations.test.js +11 -0
  19. package/commands/projects.js +186 -0
  20. package/commands/projects.test.js +132 -0
  21. package/commands/roles.js +57 -0
  22. package/commands/roles.test.js +42 -0
  23. package/commands/set_context.js +22 -0
  24. package/commands/set_context.test.js +53 -0
  25. package/commands/user.js +15 -0
  26. package/config.js +11 -0
  27. package/context.js +48 -0
  28. package/env.js +6 -0
  29. package/errors.js +16 -0
  30. package/help.js +146 -0
  31. package/index.js +168 -0
  32. package/log.js +15 -0
  33. package/package.json +1 -1
  34. package/parameters.gen.js +322 -0
  35. package/pkg.js +3 -45
  36. package/test_utils/mock_server.js +16 -0
  37. package/test_utils/oauth_server.js +9 -0
  38. package/test_utils/test_cli_command.js +80 -0
  39. package/types.js +1 -0
  40. package/utils/enrichers.js +49 -0
  41. package/utils/formats.js +5 -0
  42. package/utils/formats.test.js +32 -0
  43. package/utils/middlewares.js +20 -0
  44. package/utils/point_in_time.js +50 -0
  45. package/utils/psql.js +24 -0
  46. package/utils/string.js +5 -0
  47. package/utils/ui.js +59 -0
  48. package/writer.js +87 -0
  49. package/writer.test.js +86 -0
  50. package/.bump +0 -1
  51. package/.editorconfig +0 -7
  52. package/.eslintrc.cjs +0 -15
  53. package/.github/workflows/commitlint.yml +0 -46
  54. package/.github/workflows/pr.yml +0 -25
  55. package/.github/workflows/release.yml +0 -30
  56. package/.husky/commit-msg +0 -4
  57. package/.husky/pre-commit +0 -4
  58. package/.nvmrc +0 -1
  59. package/.prettierignore +0 -3
  60. package/.prettierrc.json +0 -3
  61. package/.releaserc.json +0 -47
  62. package/LICENSE +0 -202
  63. package/commitlint.config.cjs +0 -7
  64. package/generateOptionsFromSpec.ts +0 -68
  65. package/jest/setup.js +0 -5
  66. package/jest.config.ts +0 -199
  67. package/mocks/bin/psql.cjs +0 -9
  68. package/mocks/main/projects/GET.js +0 -27
  69. package/mocks/main/projects/POST.js +0 -22
  70. package/mocks/main/projects/shared/GET.js +0 -16
  71. package/mocks/main/projects/test/DELETE.json +0 -7
  72. package/mocks/main/projects/test/GET.json +0 -13
  73. package/mocks/main/projects/test/PATCH.js +0 -18
  74. package/mocks/main/projects/test/branches/GET.json +0 -25
  75. package/mocks/main/projects/test/branches/POST.js +0 -83
  76. package/mocks/main/projects/test/branches/br-cloudy-branch-12345678/DELETE.json +0 -7
  77. package/mocks/main/projects/test/branches/br-cloudy-branch-12345678/GET.json +0 -9
  78. package/mocks/main/projects/test/branches/br-cloudy-branch-12345678/PATCH.js +0 -14
  79. package/mocks/main/projects/test/branches/br-cloudy-branch-12345678/databases/GET.json +0 -6
  80. package/mocks/main/projects/test/branches/br-cloudy-branch-12345678/databases/POST.js +0 -13
  81. package/mocks/main/projects/test/branches/br-cloudy-branch-12345678/databases/test_db/DELETE.json +0 -6
  82. package/mocks/main/projects/test/branches/br-cloudy-branch-12345678/endpoints/GET.json +0 -26
  83. package/mocks/main/projects/test/branches/br-cloudy-branch-12345678/endpoints/POST.json +0 -6
  84. package/mocks/main/projects/test/branches/br-cloudy-branch-12345678/roles/GET.json +0 -3
  85. package/mocks/main/projects/test/branches/br-cloudy-branch-12345678/roles/POST.js +0 -14
  86. package/mocks/main/projects/test/branches/br-cloudy-branch-12345678/roles/test_role/DELETE.json +0 -6
  87. package/mocks/main/projects/test/branches/br-cloudy-branch-12345678/roles/test_role/reveal_password/GET.json +0 -3
  88. package/mocks/main/projects/test/branches/br-cloudy-branch-12345678/set_as_primary/POST.json +0 -9
  89. package/mocks/main/projects/test/branches/br-numbered-branch-123456/GET.json +0 -10
  90. package/mocks/main/projects/test/branches/br-sunny-branch-123456/DELETE.json +0 -7
  91. package/mocks/main/projects/test/branches/br-sunny-branch-123456/GET.json +0 -10
  92. package/mocks/main/projects/test/branches/br-sunny-branch-123456/PATCH.js +0 -14
  93. package/mocks/main/projects/test/branches/br-sunny-branch-123456/databases/GET.json +0 -6
  94. package/mocks/main/projects/test/branches/br-sunny-branch-123456/databases/POST.js +0 -13
  95. package/mocks/main/projects/test/branches/br-sunny-branch-123456/databases/test_db/DELETE.json +0 -6
  96. package/mocks/main/projects/test/branches/br-sunny-branch-123456/endpoints/GET.json +0 -26
  97. package/mocks/main/projects/test/branches/br-sunny-branch-123456/endpoints/POST.json +0 -6
  98. package/mocks/main/projects/test/branches/br-sunny-branch-123456/restore/POST.js +0 -16
  99. package/mocks/main/projects/test/branches/br-sunny-branch-123456/roles/GET.json +0 -3
  100. package/mocks/main/projects/test/branches/br-sunny-branch-123456/roles/POST.js +0 -14
  101. package/mocks/main/projects/test/branches/br-sunny-branch-123456/roles/test_role/DELETE.json +0 -6
  102. package/mocks/main/projects/test/branches/br-sunny-branch-123456/roles/test_role/reveal_password/GET.json +0 -3
  103. package/mocks/main/projects/test/branches/br-sunny-branch-123456/set_as_primary/POST.json +0 -9
  104. package/mocks/main/projects/test/endpoints/GET.json +0 -9
  105. package/mocks/main/projects/test/endpoints/POST.js +0 -32
  106. package/mocks/main/projects/test/endpoints/test_endpoint_id/DELETE.json +0 -7
  107. package/mocks/main/projects/test/endpoints/test_endpoint_id/GET.json +0 -9
  108. package/mocks/main/projects/test/endpoints/test_endpoint_id/PATCH.js +0 -17
  109. package/mocks/main/projects/test/operations/GET.json +0 -22
  110. package/mocks/main/users/me/GET.json +0 -5
  111. package/mocks/restore/projects/test/branches/GET.json +0 -21
  112. package/mocks/restore/projects/test/branches/br-another-branch-123456/GET.json +0 -6
  113. package/mocks/restore/projects/test/branches/br-another-branch-123456/restore/POST.js +0 -13
  114. package/mocks/restore/projects/test/branches/br-any-branch-123456/GET.json +0 -6
  115. package/mocks/restore/projects/test/branches/br-parent-tots-123456/GET.json +0 -7
  116. package/mocks/restore/projects/test/branches/br-parent-tots-123456/restore/POST.js +0 -14
  117. package/mocks/restore/projects/test/branches/br-self-tolsn-123456/GET.json +0 -6
  118. package/mocks/restore/projects/test/branches/br-self-tolsn-123456/restore/POST.js +0 -15
  119. package/mocks/single_project/projects/GET.json +0 -10
  120. package/mocks/single_project/projects/test-project-123456/GET.json +0 -14
  121. package/mocks/single_project/projects/test-project-123456/branches/GET.json +0 -11
  122. package/mocks/single_project/projects/test-project-123456/branches/br-main-branch-123456/databases/GET.json +0 -3
  123. package/mocks/single_project/projects/test-project-123456/branches/br-main-branch-123456/endpoints/GET.json +0 -10
  124. package/mocks/single_project/projects/test-project-123456/branches/br-main-branch-123456/roles/GET.json +0 -3
  125. package/mocks/single_project/projects/test-project-123456/branches/br-main-branch-123456/roles/test_role/reveal_password/GET.json +0 -3
  126. package/rollup.config.js +0 -20
  127. package/snapshots/commands/branches.test.snap +0 -221
  128. package/snapshots/commands/connection_string.test.snap +0 -70
  129. package/snapshots/commands/databases.test.snap +0 -20
  130. package/snapshots/commands/ip_allow.test.snap +0 -55
  131. package/snapshots/commands/operations.test.snap +0 -17
  132. package/snapshots/commands/projects.test.snap +0 -141
  133. package/snapshots/commands/roles.test.snap +0 -19
  134. package/snapshots/commands/set_context.test.snap +0 -30
  135. package/snapshots/writer.test.snap +0 -60
  136. package/snapshotsResolver.cjs +0 -32
  137. package/src/analytics.ts +0 -95
  138. package/src/api.ts +0 -44
  139. package/src/auth.ts +0 -137
  140. package/src/commands/auth.test.ts +0 -62
  141. package/src/commands/auth.ts +0 -148
  142. package/src/commands/branches.test.ts +0 -354
  143. package/src/commands/branches.ts +0 -451
  144. package/src/commands/connection_string.test.ts +0 -250
  145. package/src/commands/connection_string.ts +0 -210
  146. package/src/commands/databases.test.ts +0 -55
  147. package/src/commands/databases.ts +0 -129
  148. package/src/commands/help.test.ts +0 -13
  149. package/src/commands/ip_allow.test.ts +0 -86
  150. package/src/commands/ip_allow.ts +0 -202
  151. package/src/commands/operations.test.ts +0 -13
  152. package/src/commands/operations.ts +0 -41
  153. package/src/commands/projects.test.ts +0 -147
  154. package/src/commands/projects.ts +0 -275
  155. package/src/commands/roles.test.ts +0 -46
  156. package/src/commands/roles.ts +0 -100
  157. package/src/commands/set_context.test.ts +0 -64
  158. package/src/commands/set_context.ts +0 -27
  159. package/src/commands/user.ts +0 -21
  160. package/src/config.ts +0 -22
  161. package/src/context.ts +0 -61
  162. package/src/env.ts +0 -7
  163. package/src/errors.ts +0 -24
  164. package/src/help.ts +0 -185
  165. package/src/index.ts +0 -180
  166. package/src/log.ts +0 -16
  167. package/src/parameters.gen.ts +0 -332
  168. package/src/pkg.ts +0 -9
  169. package/src/test_utils/mock_server.ts +0 -27
  170. package/src/test_utils/oauth_server.ts +0 -10
  171. package/src/test_utils/test_cli_command.ts +0 -117
  172. package/src/types.ts +0 -25
  173. package/src/utils/enrichers.ts +0 -73
  174. package/src/utils/formats.test.ts +0 -41
  175. package/src/utils/formats.ts +0 -11
  176. package/src/utils/middlewares.ts +0 -23
  177. package/src/utils/point_in_time.ts +0 -86
  178. package/src/utils/psql.ts +0 -29
  179. package/src/utils/string.ts +0 -8
  180. package/src/utils/ui.ts +0 -64
  181. package/src/writer.test.ts +0 -98
  182. package/src/writer.ts +0 -131
  183. package/tsconfig.json +0 -17
  184. /package/{src/callback.html → callback.html} +0 -0
@@ -1,21 +0,0 @@
1
- import yargs from 'yargs';
2
-
3
- import { CommonProps } from '../types.js';
4
- import { writer } from '../writer.js';
5
-
6
- export const command = 'me';
7
- export const describe = 'Show current user';
8
- export const builder = (yargs: yargs.Argv) =>
9
- yargs.option('context-file', {
10
- hidden: true,
11
- });
12
- export const handler = async (args: CommonProps) => {
13
- await me(args);
14
- };
15
-
16
- const me = async (props: CommonProps) => {
17
- const { data } = await props.apiClient.getCurrentUserInfo();
18
- writer(props).end(data, {
19
- fields: ['login', 'email', 'name', 'projects_limit'],
20
- });
21
- };
package/src/config.ts DELETED
@@ -1,22 +0,0 @@
1
- import { join } from 'node:path';
2
- import { homedir } from 'node:os';
3
- import { existsSync, mkdirSync } from 'node:fs';
4
- import yargs from 'yargs';
5
-
6
- import { isCi } from './env.js';
7
-
8
- export const CREDENTIALS_FILE = 'credentials.json';
9
-
10
- export const defaultDir = join(
11
- process.env.XDG_CONFIG_HOME || join(homedir(), '.config'),
12
- 'neonctl',
13
- );
14
-
15
- export const ensureConfigDir = async ({
16
- 'config-dir': configDir,
17
- 'force-auth': forceAuth,
18
- }: yargs.Arguments<{ 'config-dir': string }>) => {
19
- if (!existsSync(configDir) && (!isCi() || forceAuth)) {
20
- mkdirSync(configDir, { recursive: true });
21
- }
22
- };
package/src/context.ts DELETED
@@ -1,61 +0,0 @@
1
- import { accessSync, readFileSync, writeFileSync } from 'node:fs';
2
- import { homedir } from 'node:os';
3
- import { normalize, resolve } from 'node:path';
4
- import yargs from 'yargs';
5
-
6
- export type Context = {
7
- projectId?: string;
8
- branchId?: string;
9
- };
10
-
11
- const CONTEXT_FILE = '.neon';
12
- const CHECK_FILES = [CONTEXT_FILE, 'package.json', '.git'];
13
-
14
- const wrapWithContextFile = (dir: string) => resolve(dir, CONTEXT_FILE);
15
-
16
- export const currentContextFile = () => {
17
- const cwd = process.cwd();
18
- let currentDir = cwd;
19
- const root = normalize('/');
20
- const home = homedir();
21
- while (currentDir !== root && currentDir !== home) {
22
- for (const file of CHECK_FILES) {
23
- try {
24
- accessSync(resolve(currentDir, file));
25
- return wrapWithContextFile(currentDir);
26
- } catch (e) {
27
- // ignore
28
- }
29
- }
30
- currentDir = resolve(currentDir, '..');
31
- }
32
-
33
- return wrapWithContextFile(cwd);
34
- };
35
-
36
- export const readContextFile = (file: string): Context => {
37
- try {
38
- return JSON.parse(readFileSync(file, 'utf-8'));
39
- } catch (e) {
40
- return {};
41
- }
42
- };
43
-
44
- export const enrichFromContext = (
45
- args: yargs.Arguments<{ contextFile: string }>,
46
- ) => {
47
- if (args._[0] === 'set-context') {
48
- return;
49
- }
50
- const context = readContextFile(args.contextFile);
51
- if (!args.branch && !args.id && !args.name) {
52
- args.branch = context.branchId;
53
- }
54
- if (!args.projectId) {
55
- args.projectId = context.projectId;
56
- }
57
- };
58
-
59
- export const updateContextFile = (file: string, context: Context) => {
60
- writeFileSync(file, JSON.stringify(context, null, 2));
61
- };
package/src/env.ts DELETED
@@ -1,7 +0,0 @@
1
- export const isCi = () => {
2
- return process.env.CI !== 'false' && Boolean(process.env.CI);
3
- };
4
-
5
- export const isDebug = () => {
6
- return Boolean(process.env.DEBUG);
7
- };
package/src/errors.ts DELETED
@@ -1,24 +0,0 @@
1
- export type ErrorCode =
2
- | 'REQUEST_TIMEOUT'
3
- | 'AUTH_FAILED'
4
- | 'API_ERROR'
5
- | 'UNKNOWN_COMMAND'
6
- | 'MISSING_ARGUMENT'
7
- | 'UNKNOWN_ERROR';
8
-
9
- const ERROR_MATCHERS = [
10
- [/^Unknown command: (.*)$/, 'UNKNOWN_COMMAND'],
11
- [/^Missing required argument: (.*)$/, 'MISSING_ARGUMENT'],
12
- ] as const;
13
- export const matchErrorCode = (message?: string): ErrorCode => {
14
- if (!message) {
15
- return 'UNKNOWN_ERROR';
16
- }
17
- for (const [matcher, code] of ERROR_MATCHERS) {
18
- const match = message.match(matcher);
19
- if (match) {
20
- return code;
21
- }
22
- }
23
- return 'UNKNOWN_ERROR';
24
- };
package/src/help.ts DELETED
@@ -1,185 +0,0 @@
1
- import yargs from 'yargs';
2
- import cliui from 'cliui';
3
- import chalk from 'chalk';
4
-
5
- import {
6
- consumeBlockIfMatches,
7
- consumeNextMatching,
8
- drawPointer,
9
- splitColumns,
10
- } from './utils/ui.js';
11
-
12
- // target width for the leftmost column
13
- const SPACE_WIDTH = 20;
14
-
15
- const formatHelp = (help: string) => {
16
- const lines = help.split('\n');
17
- const result = [] as string[];
18
- // full command, like `neonctl projects list`
19
- const topLevelCommand = consumeNextMatching(lines, /^.*/);
20
-
21
- if (topLevelCommand) {
22
- result.push(
23
- chalk.bold(
24
- topLevelCommand.replace('[options]', chalk.reset.green('[options]')),
25
- ),
26
- );
27
- result.push('');
28
- }
29
-
30
- // commands description block
31
- // example command to see: neonctl projects
32
- const commandsBlock = consumeBlockIfMatches(lines, /^Commands:/);
33
- if (commandsBlock.length > 0) {
34
- const header = commandsBlock.shift() as string;
35
- result.push(header);
36
- const ui = cliui({
37
- width: 0,
38
- });
39
- commandsBlock.forEach((line) => {
40
- if (line.match(/^\s{3,}/)) {
41
- ui.div(
42
- {
43
- text: '',
44
- width: SPACE_WIDTH,
45
- padding: [0, 0, 0, 0],
46
- },
47
- { text: line.trim(), padding: [0, 0, 0, 0] },
48
- );
49
- return;
50
- }
51
-
52
- const [command, description] = splitColumns(line);
53
-
54
- // patch the previous command if it was multiline
55
- if (!description && ui.rows.length > 1) {
56
- ui.rows[ui.rows.length - 2][0].text += command;
57
- return;
58
- }
59
-
60
- ui.div(chalk.cyan(command));
61
- ui.div(
62
- {
63
- text: chalk.gray(drawPointer(SPACE_WIDTH)),
64
- width: SPACE_WIDTH,
65
- padding: [0, 0, 0, 0],
66
- },
67
- { text: description, padding: [0, 0, 0, 2] },
68
- );
69
- });
70
- result.push(ui.toString());
71
- result.push('');
72
- }
73
-
74
- // positional args block
75
- // example command to see: neonctl branches rename
76
- const positionalsBlock = consumeBlockIfMatches(lines, /Positionals:/);
77
- if (positionalsBlock.length > 0) {
78
- const header = positionalsBlock.shift() as string;
79
- result.push(header);
80
- const ui = cliui({
81
- width: 0,
82
- });
83
- positionalsBlock.forEach((line) => {
84
- const [positional, description] = splitColumns(line);
85
- ui.div(
86
- {
87
- text: positional,
88
- width: SPACE_WIDTH,
89
- padding: [0, 2, 0, 0],
90
- },
91
- {
92
- text: description,
93
- padding: [0, 0, 0, 0],
94
- },
95
- );
96
- });
97
- result.push(ui.toString());
98
- result.push('');
99
- }
100
-
101
- // command description
102
- // example command to see: neonctl projects list
103
- const descritpionBlock = consumeBlockIfMatches(lines, /^(?!.*options:)/i);
104
- if (descritpionBlock.length > 0) {
105
- result.push(...descritpionBlock);
106
- result.push('');
107
- }
108
-
109
- while (true) {
110
- // there are two options blocks: global and specific
111
- // example to see both: neonctl projects create
112
- const optionsBlock = consumeBlockIfMatches(lines, /.*options:/i);
113
- if (optionsBlock.length === 0) {
114
- break;
115
- }
116
- result.push(optionsBlock.shift() as string);
117
- optionsBlock.forEach((line) => {
118
- const [option, description] = splitColumns(line);
119
- const ui = cliui({
120
- width: 0,
121
- });
122
- if (option.startsWith('-')) {
123
- ui.div({
124
- text: chalk.green(option),
125
- padding: [0, 0, 0, 0],
126
- });
127
- ui.div(
128
- {
129
- text: chalk.gray(drawPointer(SPACE_WIDTH)),
130
- width: SPACE_WIDTH,
131
- padding: [0, 2, 0, 0],
132
- },
133
- {
134
- text: chalk.rgb(210, 210, 210)(description ?? ''),
135
- padding: [0, 0, 0, 0],
136
- },
137
- );
138
- } else {
139
- ui.div(
140
- {
141
- padding: [0, 0, 0, 0],
142
- text: '',
143
- width: SPACE_WIDTH,
144
- },
145
- {
146
- text: chalk.rgb(210, 210, 210)(option),
147
- padding: [0, 0, 0, 0],
148
- },
149
- );
150
- }
151
-
152
- result.push(ui.toString());
153
- });
154
- result.push('');
155
- }
156
-
157
- const exampleBlock = consumeBlockIfMatches(lines, /Examples:/);
158
- if (exampleBlock.length > 0) {
159
- result.push(exampleBlock.shift() as string);
160
- const ui = cliui({
161
- width: 0,
162
- });
163
- for (const line of exampleBlock) {
164
- const [command, description] = splitColumns(line);
165
- ui.div({
166
- text: chalk.bold(command),
167
- padding: [0, 0, 0, 0],
168
- });
169
- ui.div({
170
- text: chalk.reset(description),
171
- padding: [0, 0, 0, 2],
172
- });
173
- }
174
- result.push(ui.toString());
175
- }
176
-
177
- return [...result, ...lines];
178
- };
179
-
180
- export const showHelp = async (argv: yargs.Argv) => {
181
- // add wrap to ensure that there are no line breaks
182
- const help = await argv.getHelp();
183
- process.stderr.write(formatHelp(help).join('\n') + '\n');
184
- process.exit(0);
185
- };
package/src/index.ts DELETED
@@ -1,180 +0,0 @@
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 DELETED
@@ -1,16 +0,0 @@
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
- };