neonctl 2.20.3 → 2.21.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/commands/auth.js +3 -2
- package/commands/init.js +40 -2
- package/commands/init.test.js +41 -5
- package/package.json +2 -2
package/commands/auth.js
CHANGED
|
@@ -16,8 +16,9 @@ export const builder = (yargs) => yargs.option('context-file', {
|
|
|
16
16
|
export const handler = async (args) => {
|
|
17
17
|
await authFlow(args);
|
|
18
18
|
};
|
|
19
|
-
export const authFlow = async ({ configDir, oauthHost, clientId, apiHost, forceAuth, allowUnsafeTls, }) => {
|
|
20
|
-
|
|
19
|
+
export const authFlow = async ({ configDir, oauthHost, clientId, apiHost, forceAuth, 'force-auth': forceAuthKebab, allowUnsafeTls, }) => {
|
|
20
|
+
const allowInteractiveAuth = forceAuth ?? forceAuthKebab;
|
|
21
|
+
if (!allowInteractiveAuth && isCi()) {
|
|
21
22
|
throw new Error('Cannot run interactive auth in CI');
|
|
22
23
|
}
|
|
23
24
|
const tokenSet = await auth({
|
package/commands/init.js
CHANGED
|
@@ -1,15 +1,53 @@
|
|
|
1
1
|
import { init } from 'neon-init';
|
|
2
2
|
import { sendError } from '../analytics.js';
|
|
3
|
+
import { log } from '../log.js';
|
|
4
|
+
const AGENT_FLAG_VALUES = ['cursor', 'copilot', 'claude'];
|
|
5
|
+
function parseAgentToEditor(value) {
|
|
6
|
+
const normalized = value.trim().toLowerCase();
|
|
7
|
+
switch (normalized) {
|
|
8
|
+
case 'cursor':
|
|
9
|
+
return 'Cursor';
|
|
10
|
+
case 'github-copilot':
|
|
11
|
+
case 'copilot':
|
|
12
|
+
case 'vs code':
|
|
13
|
+
case 'vscode':
|
|
14
|
+
case 'vs-code':
|
|
15
|
+
return 'VS Code';
|
|
16
|
+
case 'claude-code':
|
|
17
|
+
case 'claude cli':
|
|
18
|
+
case 'claude-cli':
|
|
19
|
+
case 'claude':
|
|
20
|
+
return 'Claude CLI';
|
|
21
|
+
default:
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
3
25
|
export const command = 'init';
|
|
4
26
|
export const describe = 'Initialize a project with Neon using your AI coding assistant';
|
|
5
27
|
export const builder = (yargs) => yargs
|
|
6
28
|
.option('context-file', {
|
|
7
29
|
hidden: true,
|
|
30
|
+
})
|
|
31
|
+
.option('agent', {
|
|
32
|
+
alias: 'a',
|
|
33
|
+
type: 'string',
|
|
34
|
+
describe: 'Agent to configure (cursor, copilot, code).',
|
|
8
35
|
})
|
|
9
36
|
.strict(false);
|
|
10
|
-
export const handler = async () => {
|
|
37
|
+
export const handler = async (argv) => {
|
|
38
|
+
let options;
|
|
39
|
+
const agentArg = argv.agent;
|
|
40
|
+
if (agentArg !== undefined) {
|
|
41
|
+
const editor = parseAgentToEditor(agentArg);
|
|
42
|
+
if (editor === null) {
|
|
43
|
+
log.error(`Invalid --agent value: "${agentArg}". Supported: ${AGENT_FLAG_VALUES.join(', ')}`);
|
|
44
|
+
process.exit(1);
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
options = { agent: editor };
|
|
48
|
+
}
|
|
11
49
|
try {
|
|
12
|
-
await init();
|
|
50
|
+
await init(options);
|
|
13
51
|
}
|
|
14
52
|
catch {
|
|
15
53
|
const exitError = new Error(`failed to run neon-init`);
|
package/commands/init.test.js
CHANGED
|
@@ -1,20 +1,56 @@
|
|
|
1
|
-
import { describe, expect, test, vi } from 'vitest';
|
|
1
|
+
import { afterEach, describe, expect, test, vi } from 'vitest';
|
|
2
2
|
// Mock dependencies that require package.json
|
|
3
3
|
vi.mock('../analytics.js', () => ({
|
|
4
4
|
sendError: vi.fn(),
|
|
5
5
|
trackEvent: vi.fn(),
|
|
6
6
|
closeAnalytics: vi.fn(),
|
|
7
7
|
}));
|
|
8
|
+
vi.mock('../log.js', () => ({
|
|
9
|
+
log: { error: vi.fn(), info: vi.fn(), warning: vi.fn(), debug: vi.fn() },
|
|
10
|
+
}));
|
|
8
11
|
// Mock neon-init
|
|
9
12
|
vi.mock('neon-init', () => ({
|
|
10
13
|
init: vi.fn().mockResolvedValue(undefined),
|
|
11
14
|
}));
|
|
12
15
|
describe('init', () => {
|
|
13
|
-
|
|
16
|
+
const exitSpy = vi
|
|
17
|
+
.spyOn(process, 'exit')
|
|
18
|
+
.mockImplementation((() => undefined));
|
|
19
|
+
afterEach(() => {
|
|
20
|
+
vi.clearAllMocks();
|
|
21
|
+
});
|
|
22
|
+
test('should call neon-init with no options when agent is omitted', async () => {
|
|
23
|
+
const { handler } = await import('./init.js');
|
|
24
|
+
const { init } = await import('neon-init');
|
|
25
|
+
await handler({});
|
|
26
|
+
expect(init).toHaveBeenCalledTimes(1);
|
|
27
|
+
expect(init).toHaveBeenCalledWith(undefined);
|
|
28
|
+
});
|
|
29
|
+
test('should call neon-init with { agent: "Cursor" } when --agent cursor', async () => {
|
|
30
|
+
const { handler } = await import('./init.js');
|
|
31
|
+
const { init } = await import('neon-init');
|
|
32
|
+
await handler({ agent: 'cursor' });
|
|
33
|
+
expect(init).toHaveBeenCalledWith({ agent: 'Cursor' });
|
|
34
|
+
});
|
|
35
|
+
test('should call neon-init with { agent: "VS Code" } when --agent copilot', async () => {
|
|
36
|
+
const { handler } = await import('./init.js');
|
|
37
|
+
const { init } = await import('neon-init');
|
|
38
|
+
await handler({ agent: 'copilot' });
|
|
39
|
+
expect(init).toHaveBeenCalledWith({ agent: 'VS Code' });
|
|
40
|
+
});
|
|
41
|
+
test('should call neon-init with { agent: "Claude CLI" } when --agent claude', async () => {
|
|
42
|
+
const { handler } = await import('./init.js');
|
|
43
|
+
const { init } = await import('neon-init');
|
|
44
|
+
await handler({ agent: 'claude' });
|
|
45
|
+
expect(init).toHaveBeenCalledWith({ agent: 'Claude CLI' });
|
|
46
|
+
});
|
|
47
|
+
test('should log error and exit 1 when --agent is invalid', async () => {
|
|
14
48
|
const { handler } = await import('./init.js');
|
|
15
49
|
const { init } = await import('neon-init');
|
|
16
|
-
await
|
|
17
|
-
|
|
18
|
-
expect(init).
|
|
50
|
+
const { log } = await import('../log.js');
|
|
51
|
+
await handler({ agent: 'invalid-agent' });
|
|
52
|
+
expect(init).not.toHaveBeenCalled();
|
|
53
|
+
expect(log.error).toHaveBeenCalledWith('Invalid --agent value: "invalid-agent". Supported: cursor, copilot, claude');
|
|
54
|
+
expect(exitSpy).toHaveBeenCalledWith(1);
|
|
19
55
|
});
|
|
20
56
|
});
|
package/package.json
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"url": "git+ssh://git@github.com/neondatabase/neonctl.git"
|
|
6
6
|
},
|
|
7
7
|
"type": "module",
|
|
8
|
-
"version": "2.
|
|
8
|
+
"version": "2.21.1",
|
|
9
9
|
"description": "CLI tool for NeonDB Cloud management",
|
|
10
10
|
"main": "index.js",
|
|
11
11
|
"author": "NeonDB",
|
|
@@ -62,7 +62,7 @@
|
|
|
62
62
|
"cli-table": "^0.3.11",
|
|
63
63
|
"crypto-random-string": "^5.0.0",
|
|
64
64
|
"diff": "^5.2.0",
|
|
65
|
-
"neon-init": "^0.
|
|
65
|
+
"neon-init": "^0.13.1",
|
|
66
66
|
"open": "^10.1.0",
|
|
67
67
|
"openid-client": "^6.8.1",
|
|
68
68
|
"prompts": "2.4.2",
|