@tutorflow/cli 0.1.2 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +400 -89
- package/dist/client.d.ts +7 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +53 -19
- package/dist/client.js.map +1 -1
- package/dist/commands/agent.d.ts +3 -0
- package/dist/commands/agent.d.ts.map +1 -0
- package/dist/commands/agent.js +123 -0
- package/dist/commands/agent.js.map +1 -0
- package/dist/commands/auth.d.ts.map +1 -1
- package/dist/commands/auth.js +48 -45
- package/dist/commands/auth.js.map +1 -1
- package/dist/commands/config.d.ts.map +1 -1
- package/dist/commands/config.js +34 -45
- package/dist/commands/config.js.map +1 -1
- package/dist/commands/course.d.ts.map +1 -1
- package/dist/commands/course.js +61 -75
- package/dist/commands/course.js.map +1 -1
- package/dist/commands/evaluate.d.ts.map +1 -1
- package/dist/commands/evaluate.js +49 -55
- package/dist/commands/evaluate.js.map +1 -1
- package/dist/commands/module.d.ts +3 -0
- package/dist/commands/module.d.ts.map +1 -0
- package/dist/commands/module.js +108 -0
- package/dist/commands/module.js.map +1 -0
- package/dist/commands/platform.d.ts +3 -0
- package/dist/commands/platform.d.ts.map +1 -0
- package/dist/commands/platform.js +36 -0
- package/dist/commands/platform.js.map +1 -0
- package/dist/commands/slide.d.ts.map +1 -1
- package/dist/commands/slide.js +65 -76
- package/dist/commands/slide.js.map +1 -1
- package/dist/commands/test.d.ts +3 -0
- package/dist/commands/test.d.ts.map +1 -0
- package/dist/commands/test.js +119 -0
- package/dist/commands/test.js.map +1 -0
- package/dist/commands/video.d.ts.map +1 -1
- package/dist/commands/video.js +66 -78
- package/dist/commands/video.js.map +1 -1
- package/dist/index.js +24 -2
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +75 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/output.d.ts +15 -2
- package/dist/utils/output.d.ts.map +1 -1
- package/dist/utils/output.js +66 -22
- package/dist/utils/output.js.map +1 -1
- package/dist/utils/runtime.d.ts +39 -0
- package/dist/utils/runtime.d.ts.map +1 -0
- package/dist/utils/runtime.js +105 -0
- package/dist/utils/runtime.js.map +1 -0
- package/package.json +18 -2
package/dist/client.js
CHANGED
|
@@ -3,37 +3,71 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.ApiClient = void 0;
|
|
4
4
|
const undici_1 = require("undici");
|
|
5
5
|
const config_1 = require("./config");
|
|
6
|
+
const runtime_1 = require("./utils/runtime");
|
|
7
|
+
const DEFAULT_BASE_URL = 'https://api.tutorflow.io';
|
|
8
|
+
/**
|
|
9
|
+
* Resolution order (env wins so CI/agents can override config without
|
|
10
|
+
* touching ~/.tutorflow/config.json):
|
|
11
|
+
*
|
|
12
|
+
* 1. TUTORFLOW_API_KEY / TUTORFLOW_BASE_URL env vars
|
|
13
|
+
* 2. ~/.tutorflow/config.json
|
|
14
|
+
* 3. baseUrl default
|
|
15
|
+
*/
|
|
16
|
+
async function resolveConfig() {
|
|
17
|
+
const fileConfig = await (0, config_1.readConfig)();
|
|
18
|
+
return {
|
|
19
|
+
apiKey: process.env.TUTORFLOW_API_KEY ?? fileConfig.apiKey ?? '',
|
|
20
|
+
baseUrl: process.env.TUTORFLOW_BASE_URL ?? fileConfig.baseUrl ?? DEFAULT_BASE_URL,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
6
23
|
class ApiClient {
|
|
7
24
|
constructor(config) {
|
|
8
|
-
this.config = config || {
|
|
9
|
-
apiKey: '',
|
|
10
|
-
baseUrl: 'https://api.tutorflow.io',
|
|
11
|
-
};
|
|
25
|
+
this.config = config || { apiKey: '', baseUrl: DEFAULT_BASE_URL };
|
|
12
26
|
}
|
|
13
27
|
static async create() {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
28
|
+
return new ApiClient(await resolveConfig());
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Like `create` but throws CliError if no API key is resolvable. Use this
|
|
32
|
+
* in any command that talks to the API so we get a single, consistent
|
|
33
|
+
* "not authenticated" path.
|
|
34
|
+
*/
|
|
35
|
+
static async createAuthenticated() {
|
|
36
|
+
const config = await resolveConfig();
|
|
37
|
+
if (!config.apiKey) {
|
|
38
|
+
throw new runtime_1.CliError('Not authenticated. Run "tutorflow auth login --api-key <key>" or set TUTORFLOW_API_KEY.', { code: 'EAUTH', exitCode: 1 });
|
|
39
|
+
}
|
|
40
|
+
return new ApiClient(config);
|
|
19
41
|
}
|
|
20
|
-
async request(method, endpoint, body) {
|
|
42
|
+
async request(method, endpoint, body, headers) {
|
|
21
43
|
const url = `${this.config.baseUrl}${endpoint}`;
|
|
22
|
-
const headers = {
|
|
23
|
-
'Content-Type': 'application/json',
|
|
24
|
-
'X-API-Key': this.config.apiKey,
|
|
25
|
-
};
|
|
26
44
|
const init = {
|
|
27
45
|
method,
|
|
28
|
-
headers
|
|
46
|
+
headers: {
|
|
47
|
+
'Content-Type': 'application/json',
|
|
48
|
+
'X-API-Key': this.config.apiKey,
|
|
49
|
+
...headers,
|
|
50
|
+
},
|
|
29
51
|
};
|
|
30
|
-
if (body)
|
|
52
|
+
if (body)
|
|
31
53
|
init.body = JSON.stringify(body);
|
|
54
|
+
let response;
|
|
55
|
+
try {
|
|
56
|
+
response = await (0, undici_1.fetch)(url, init);
|
|
57
|
+
}
|
|
58
|
+
catch (err) {
|
|
59
|
+
throw new runtime_1.CliError(`Network error reaching ${url}: ${err instanceof Error ? err.message : String(err)}`, { code: 'ENETWORK' });
|
|
60
|
+
}
|
|
61
|
+
const text = await response.text();
|
|
62
|
+
let data = text;
|
|
63
|
+
try {
|
|
64
|
+
data = text.length ? JSON.parse(text) : {};
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
// non-JSON response; keep as text
|
|
32
68
|
}
|
|
33
|
-
const response = await (0, undici_1.fetch)(url, init);
|
|
34
|
-
const data = await response.json();
|
|
35
69
|
if (!response.ok) {
|
|
36
|
-
throw new
|
|
70
|
+
throw new runtime_1.CliError(`API error ${response.status}: ${typeof data === 'string' ? data : JSON.stringify(data)}`, { code: `EHTTP_${response.status}` });
|
|
37
71
|
}
|
|
38
72
|
return data;
|
|
39
73
|
}
|
package/dist/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":";;;AAAA,mCAAyC;AACzC,qCAAsC;
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../src/commands/agent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAuBpC,wBAAgB,YAAY,IAAI,OAAO,CAiKtC"}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.agentCommand = agentCommand;
|
|
4
|
+
const commander_1 = require("commander");
|
|
5
|
+
const prompts_1 = require("@clack/prompts");
|
|
6
|
+
const client_1 = require("../client");
|
|
7
|
+
const config_1 = require("../config");
|
|
8
|
+
const output_1 = require("../utils/output");
|
|
9
|
+
const runtime_1 = require("../utils/runtime");
|
|
10
|
+
const DEFAULT_BASE_URL = 'https://api.tutorflow.io';
|
|
11
|
+
function agentCommand() {
|
|
12
|
+
const agent = new commander_1.Command('agent').description('Manage TutorFlow agent platform account');
|
|
13
|
+
agent
|
|
14
|
+
.command('register')
|
|
15
|
+
.description('Self-register a TutorFlow Platform workspace and receive an API key')
|
|
16
|
+
.option('--name <name>', 'Workspace display name')
|
|
17
|
+
.option('--slug <slug>', 'Unique workspace slug')
|
|
18
|
+
.option('--email <email>', 'Contact email for the workspace')
|
|
19
|
+
.option('--agent-identity <identity>', 'Optional agent identity string')
|
|
20
|
+
.option('--no-save', 'Do not save the returned API key to ~/.tutorflow/config.json')
|
|
21
|
+
.action((0, runtime_1.command)(async (options) => {
|
|
22
|
+
const name = await requiredOptionOrPrompt(options.name, 'Workspace display name:', '--name <name>');
|
|
23
|
+
const slug = await requiredOptionOrPrompt(options.slug, 'Workspace slug:', '--slug <slug>');
|
|
24
|
+
const baseUrl = await resolveBaseUrl();
|
|
25
|
+
const client = await client_1.ApiClient.create();
|
|
26
|
+
const body = {
|
|
27
|
+
name,
|
|
28
|
+
slug,
|
|
29
|
+
email: options.email,
|
|
30
|
+
agentIdentity: options.agentIdentity,
|
|
31
|
+
};
|
|
32
|
+
Object.keys(body).forEach((key) => {
|
|
33
|
+
if (body[key] === undefined || body[key] === '')
|
|
34
|
+
delete body[key];
|
|
35
|
+
});
|
|
36
|
+
const response = await client.request('POST', '/v1/platform/agent/register', body);
|
|
37
|
+
if (options.save !== false) {
|
|
38
|
+
await (0, config_1.updateConfig)({ apiKey: response.apiKey, baseUrl });
|
|
39
|
+
}
|
|
40
|
+
(0, output_1.printResult)(response);
|
|
41
|
+
}));
|
|
42
|
+
agent
|
|
43
|
+
.command('account')
|
|
44
|
+
.description('Show the authenticated agent account')
|
|
45
|
+
.action((0, runtime_1.command)(async () => {
|
|
46
|
+
const client = await client_1.ApiClient.createAuthenticated();
|
|
47
|
+
const response = await client.request('GET', '/v1/platform/agent/account');
|
|
48
|
+
(0, output_1.printResult)(response);
|
|
49
|
+
}));
|
|
50
|
+
const billing = new commander_1.Command('billing').description('Manage agent billing');
|
|
51
|
+
billing
|
|
52
|
+
.command('status')
|
|
53
|
+
.description('Show billing status and currently restricted actions')
|
|
54
|
+
.action((0, runtime_1.command)(async () => {
|
|
55
|
+
const client = await client_1.ApiClient.createAuthenticated();
|
|
56
|
+
const response = await client.request('GET', '/v1/platform/agent/billing/status');
|
|
57
|
+
(0, output_1.printResult)(response);
|
|
58
|
+
}));
|
|
59
|
+
billing
|
|
60
|
+
.command('session')
|
|
61
|
+
.description('Create a TutorFlow-hosted checkout session URL')
|
|
62
|
+
.action((0, runtime_1.command)(async () => {
|
|
63
|
+
const client = await client_1.ApiClient.createAuthenticated();
|
|
64
|
+
const response = await client.request('POST', '/v1/platform/agent/billing/session');
|
|
65
|
+
(0, output_1.printResult)(response);
|
|
66
|
+
}));
|
|
67
|
+
agent.addCommand(billing);
|
|
68
|
+
const checkout = new commander_1.Command('checkout').description('Use public checkout token endpoints');
|
|
69
|
+
checkout
|
|
70
|
+
.command('info')
|
|
71
|
+
.description('Read workspace info for a TutorFlow checkout token')
|
|
72
|
+
.requiredOption('--token <token>', 'Checkout token from agent billing session URL')
|
|
73
|
+
.action((0, runtime_1.command)(async (options) => {
|
|
74
|
+
const client = await client_1.ApiClient.create();
|
|
75
|
+
const qs = new URLSearchParams({ token: options.token });
|
|
76
|
+
const response = await client.request('GET', `/v1/platform/agent/checkout?${qs.toString()}`);
|
|
77
|
+
(0, output_1.printResult)(response);
|
|
78
|
+
}));
|
|
79
|
+
checkout
|
|
80
|
+
.command('create')
|
|
81
|
+
.description('Create a Stripe Checkout URL from a TutorFlow checkout token')
|
|
82
|
+
.requiredOption('--token <token>', 'Checkout token from agent billing session URL')
|
|
83
|
+
.requiredOption('--amount-usd <amount>', 'Top-up amount in USD')
|
|
84
|
+
.action((0, runtime_1.command)(async (options) => {
|
|
85
|
+
const amountUsd = Number.parseFloat(options.amountUsd);
|
|
86
|
+
if (!Number.isFinite(amountUsd)) {
|
|
87
|
+
throw new runtime_1.CliError('--amount-usd must be a number', {
|
|
88
|
+
code: 'EINVAL',
|
|
89
|
+
exitCode: 2,
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
const client = await client_1.ApiClient.create();
|
|
93
|
+
const response = await client.request('POST', '/v1/platform/agent/checkout', { token: options.token, amountUsd });
|
|
94
|
+
(0, output_1.printResult)(response);
|
|
95
|
+
}));
|
|
96
|
+
agent.addCommand(checkout);
|
|
97
|
+
const verifyEmail = new commander_1.Command('verify-email').description('Manage agent email verification');
|
|
98
|
+
verifyEmail
|
|
99
|
+
.command('resend')
|
|
100
|
+
.description('Resend the platform email verification message')
|
|
101
|
+
.action((0, runtime_1.command)(async () => {
|
|
102
|
+
const client = await client_1.ApiClient.createAuthenticated();
|
|
103
|
+
const response = await client.request('POST', '/v1/platform/agent/verify-email/resend');
|
|
104
|
+
(0, output_1.printResult)(response);
|
|
105
|
+
}));
|
|
106
|
+
agent.addCommand(verifyEmail);
|
|
107
|
+
return agent;
|
|
108
|
+
}
|
|
109
|
+
async function requiredOptionOrPrompt(value, message, flagHint) {
|
|
110
|
+
if (value?.trim())
|
|
111
|
+
return value.trim();
|
|
112
|
+
(0, runtime_1.requireInteractive)(`Pass ${flagHint}.`);
|
|
113
|
+
const result = await (0, prompts_1.text)({ message });
|
|
114
|
+
if (!result || typeof result === 'symbol') {
|
|
115
|
+
throw new runtime_1.CliError('Cancelled', { code: 'ECANCELLED', exitCode: 130 });
|
|
116
|
+
}
|
|
117
|
+
return result;
|
|
118
|
+
}
|
|
119
|
+
async function resolveBaseUrl() {
|
|
120
|
+
const fileConfig = await (0, config_1.readConfig)();
|
|
121
|
+
return process.env.TUTORFLOW_BASE_URL ?? fileConfig.baseUrl ?? DEFAULT_BASE_URL;
|
|
122
|
+
}
|
|
123
|
+
//# sourceMappingURL=agent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent.js","sourceRoot":"","sources":["../../src/commands/agent.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAUpC,wBAAgB,WAAW,IAAI,OAAO,CAiFrC"}
|
package/dist/commands/auth.js
CHANGED
|
@@ -1,72 +1,75 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
3
|
exports.authCommand = authCommand;
|
|
7
4
|
const commander_1 = require("commander");
|
|
8
5
|
const prompts_1 = require("@clack/prompts");
|
|
9
|
-
const chalk_1 = __importDefault(require("chalk"));
|
|
10
6
|
const config_1 = require("../config");
|
|
7
|
+
const runtime_1 = require("../utils/runtime");
|
|
8
|
+
const output_1 = require("../utils/output");
|
|
11
9
|
function authCommand() {
|
|
12
10
|
const auth = new commander_1.Command('auth').description('Manage authentication');
|
|
13
11
|
auth
|
|
14
12
|
.command('login')
|
|
15
13
|
.description('Authenticate with your API key')
|
|
16
|
-
.
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
14
|
+
.option('--api-key <key>', 'API key (overrides interactive prompt; also reads TUTORFLOW_API_KEY)')
|
|
15
|
+
.action((0, runtime_1.command)(async (options) => {
|
|
16
|
+
let apiKey = options.apiKey ?? process.env.TUTORFLOW_API_KEY;
|
|
17
|
+
if (!apiKey) {
|
|
18
|
+
(0, runtime_1.requireInteractive)('Pass --api-key <key> or set TUTORFLOW_API_KEY.');
|
|
19
|
+
const result = await (0, prompts_1.password)({ message: 'Enter your TutorFlow API key:' });
|
|
20
|
+
if (typeof result === 'symbol') {
|
|
21
|
+
throw new runtime_1.CliError('Authentication cancelled', { code: 'ECANCELLED', exitCode: 130 });
|
|
24
22
|
}
|
|
25
|
-
|
|
26
|
-
console.log(chalk_1.default.green('✓ Authentication successful!'));
|
|
27
|
-
console.log(chalk_1.default.gray(`API key saved to ~/.tutorflow/config.json`));
|
|
23
|
+
apiKey = result;
|
|
28
24
|
}
|
|
29
|
-
|
|
30
|
-
|
|
25
|
+
if (!apiKey || !apiKey.trim()) {
|
|
26
|
+
throw new runtime_1.CliError('API key is empty', { code: 'EINVAL', exitCode: 2 });
|
|
31
27
|
}
|
|
32
|
-
|
|
28
|
+
await (0, config_1.updateConfig)({ apiKey });
|
|
29
|
+
(0, output_1.printStatus)('Authentication successful', 'success');
|
|
30
|
+
(0, output_1.printResult)({ ok: true, apiKeyPreview: `${apiKey.slice(0, 10)}...` });
|
|
31
|
+
}));
|
|
33
32
|
auth
|
|
34
33
|
.command('logout')
|
|
35
34
|
.description('Remove stored credentials')
|
|
36
|
-
.
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
35
|
+
.option('-f, --force', 'Skip confirmation prompt')
|
|
36
|
+
.action((0, runtime_1.command)(async (options) => {
|
|
37
|
+
if (!options.force) {
|
|
38
|
+
// In non-interactive mode require --force so we never block silently.
|
|
39
|
+
if (!process.stdin.isTTY) {
|
|
40
|
+
throw new runtime_1.CliError('Pass --force to logout in non-interactive mode.', {
|
|
41
|
+
code: 'ENOINTERACTIVE',
|
|
42
|
+
exitCode: 2,
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
const confirmed = await (0, prompts_1.confirm)({ message: 'Remove stored credentials?' });
|
|
46
|
+
if (!confirmed || typeof confirmed === 'symbol') {
|
|
47
|
+
(0, output_1.printStatus)('Cancelled');
|
|
43
48
|
return;
|
|
44
49
|
}
|
|
45
|
-
await (0, config_1.deleteConfig)();
|
|
46
|
-
console.log(chalk_1.default.green('✓ Credentials removed'));
|
|
47
|
-
}
|
|
48
|
-
catch (error) {
|
|
49
|
-
console.error(chalk_1.default.red('✗ Failed to logout'), error);
|
|
50
50
|
}
|
|
51
|
-
|
|
51
|
+
await (0, config_1.deleteConfig)();
|
|
52
|
+
(0, output_1.printStatus)('Credentials removed', 'success');
|
|
53
|
+
if ((0, runtime_1.isJsonMode)())
|
|
54
|
+
(0, output_1.printResult)({ ok: true });
|
|
55
|
+
}));
|
|
52
56
|
auth
|
|
53
57
|
.command('whoami')
|
|
54
58
|
.description('Show current authenticated workspace')
|
|
55
|
-
.action(async () => {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
}
|
|
62
|
-
console.log(chalk_1.default.green('✓ Authenticated as:'));
|
|
63
|
-
console.log(chalk_1.default.gray(` API Key: ${config.apiKey.slice(0, 10)}...`));
|
|
64
|
-
console.log(chalk_1.default.gray(` Base URL: ${config.baseUrl || 'https://api.tutorflow.io'}`));
|
|
65
|
-
}
|
|
66
|
-
catch (error) {
|
|
67
|
-
console.error(chalk_1.default.red('✗ Error:'), error);
|
|
59
|
+
.action((0, runtime_1.command)(async () => {
|
|
60
|
+
const fileConfig = await (0, config_1.readConfig)();
|
|
61
|
+
const apiKey = process.env.TUTORFLOW_API_KEY ?? fileConfig.apiKey;
|
|
62
|
+
const baseUrl = process.env.TUTORFLOW_BASE_URL ?? fileConfig.baseUrl ?? 'https://api.tutorflow.io';
|
|
63
|
+
if (!apiKey) {
|
|
64
|
+
throw new runtime_1.CliError('Not authenticated', { code: 'EAUTH', exitCode: 1 });
|
|
68
65
|
}
|
|
69
|
-
|
|
66
|
+
(0, output_1.printResult)({
|
|
67
|
+
authenticated: true,
|
|
68
|
+
apiKeyPreview: `${apiKey.slice(0, 10)}...`,
|
|
69
|
+
baseUrl,
|
|
70
|
+
source: process.env.TUTORFLOW_API_KEY ? 'env' : 'config',
|
|
71
|
+
});
|
|
72
|
+
}));
|
|
70
73
|
return auth;
|
|
71
74
|
}
|
|
72
75
|
//# sourceMappingURL=auth.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/commands/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/commands/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAOpC,wBAAgB,aAAa,IAAI,OAAO,CA4CvC"}
|
package/dist/commands/config.js
CHANGED
|
@@ -1,65 +1,54 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
3
|
exports.configCommand = configCommand;
|
|
7
4
|
const commander_1 = require("commander");
|
|
8
|
-
const chalk_1 = __importDefault(require("chalk"));
|
|
9
5
|
const config_1 = require("../config");
|
|
6
|
+
const output_1 = require("../utils/output");
|
|
7
|
+
const runtime_1 = require("../utils/runtime");
|
|
8
|
+
const VALID_KEYS = ['apiKey', 'baseUrl', 'workspace'];
|
|
10
9
|
function configCommand() {
|
|
11
10
|
const config = new commander_1.Command('config').description('Manage CLI configuration');
|
|
12
11
|
config
|
|
13
12
|
.command('set <key> <value>')
|
|
14
13
|
.description('Set a configuration value')
|
|
15
|
-
.action(async (key, value) => {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
if (!validKeys.includes(key)) {
|
|
19
|
-
console.log(chalk_1.default.red(`✗ Unknown config key: ${key}`));
|
|
20
|
-
console.log(chalk_1.default.gray(`Valid keys: ${validKeys.join(', ')}`));
|
|
21
|
-
return;
|
|
22
|
-
}
|
|
23
|
-
const updatePayload = {};
|
|
24
|
-
updatePayload[key] = value;
|
|
25
|
-
await (0, config_1.updateConfig)(updatePayload);
|
|
26
|
-
console.log(chalk_1.default.green(`✓ Config updated: ${key}`));
|
|
27
|
-
}
|
|
28
|
-
catch (error) {
|
|
29
|
-
console.error(chalk_1.default.red('✗ Failed to update config'), error);
|
|
14
|
+
.action((0, runtime_1.command)(async (key, value) => {
|
|
15
|
+
if (!VALID_KEYS.includes(key)) {
|
|
16
|
+
throw new runtime_1.CliError(`Unknown config key "${key}". Valid keys: ${VALID_KEYS.join(', ')}`, { code: 'EINVAL', exitCode: 2 });
|
|
30
17
|
}
|
|
31
|
-
|
|
18
|
+
const updated = await (0, config_1.updateConfig)({ [key]: value });
|
|
19
|
+
(0, output_1.printResult)({ key, value: maskIfSecret(key, value), config: maskConfig(updated) });
|
|
20
|
+
}));
|
|
32
21
|
config
|
|
33
22
|
.command('get [key]')
|
|
34
|
-
.description('Get a configuration value')
|
|
35
|
-
.action(async (key) => {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
if (key) {
|
|
39
|
-
|
|
40
|
-
if (value === undefined) {
|
|
41
|
-
console.log(chalk_1.default.gray(`Config key not set: ${key}`));
|
|
42
|
-
}
|
|
43
|
-
else {
|
|
44
|
-
console.log(`${key}=${value}`);
|
|
45
|
-
}
|
|
23
|
+
.description('Get a configuration value (or all if no key)')
|
|
24
|
+
.action((0, runtime_1.command)(async (key) => {
|
|
25
|
+
const cfg = await (0, config_1.readConfig)();
|
|
26
|
+
if (key) {
|
|
27
|
+
if (!VALID_KEYS.includes(key)) {
|
|
28
|
+
throw new runtime_1.CliError(`Unknown config key "${key}". Valid keys: ${VALID_KEYS.join(', ')}`, { code: 'EINVAL', exitCode: 2 });
|
|
46
29
|
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
if (k === 'apiKey' && v) {
|
|
51
|
-
console.log(chalk_1.default.gray(` ${k}: ${v.slice(0, 10)}...`));
|
|
52
|
-
}
|
|
53
|
-
else {
|
|
54
|
-
console.log(chalk_1.default.gray(` ${k}: ${v}`));
|
|
55
|
-
}
|
|
56
|
-
});
|
|
30
|
+
const value = cfg[key];
|
|
31
|
+
if (value === undefined) {
|
|
32
|
+
throw new runtime_1.CliError(`Config key not set: ${key}`, { code: 'ENOTFOUND', exitCode: 1 });
|
|
57
33
|
}
|
|
34
|
+
(0, output_1.printResult)({ [key]: maskIfSecret(key, value) });
|
|
58
35
|
}
|
|
59
|
-
|
|
60
|
-
|
|
36
|
+
else {
|
|
37
|
+
(0, output_1.printResult)(maskConfig(cfg));
|
|
61
38
|
}
|
|
62
|
-
});
|
|
39
|
+
}));
|
|
63
40
|
return config;
|
|
64
41
|
}
|
|
42
|
+
function maskIfSecret(key, value) {
|
|
43
|
+
if (key === 'apiKey' && value.length > 10)
|
|
44
|
+
return `${value.slice(0, 10)}...`;
|
|
45
|
+
return value;
|
|
46
|
+
}
|
|
47
|
+
function maskConfig(cfg) {
|
|
48
|
+
return {
|
|
49
|
+
apiKey: cfg.apiKey ? maskIfSecret('apiKey', cfg.apiKey) : undefined,
|
|
50
|
+
baseUrl: cfg.baseUrl,
|
|
51
|
+
workspace: cfg.workspace,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
65
54
|
//# sourceMappingURL=config.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/commands/config.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/commands/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"course.d.ts","sourceRoot":"","sources":["../../src/commands/course.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAkBpC,wBAAgB,aAAa,IAAI,OAAO,
|
|
1
|
+
{"version":3,"file":"course.d.ts","sourceRoot":"","sources":["../../src/commands/course.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAkBpC,wBAAgB,aAAa,IAAI,OAAO,CA2GvC"}
|