deploylog 0.2.1 → 0.2.2
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/dist/api.js +17 -3
- package/dist/config.js +4 -2
- package/dist/index.js +22 -0
- package/package.json +1 -1
package/dist/api.js
CHANGED
|
@@ -23,11 +23,25 @@ async function request(path, options = {}) {
|
|
|
23
23
|
...options.headers,
|
|
24
24
|
},
|
|
25
25
|
});
|
|
26
|
-
const
|
|
26
|
+
const raw = await res.text();
|
|
27
|
+
let body = null;
|
|
28
|
+
if (raw) {
|
|
29
|
+
try {
|
|
30
|
+
body = JSON.parse(raw);
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
body = null;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
27
36
|
if (!res.ok) {
|
|
28
|
-
throw new ApiError(res.status,
|
|
37
|
+
throw new ApiError(res.status, body?.error?.code ?? 'UNKNOWN', body?.error?.message ?? `Request failed (${res.status})`);
|
|
38
|
+
}
|
|
39
|
+
// Reject non-JSON bodies and well-formed JSON that's missing `data` — both
|
|
40
|
+
// violate the response contract and would otherwise return undefined.
|
|
41
|
+
if (!body || body.data === undefined) {
|
|
42
|
+
throw new ApiError(res.status, 'INVALID_RESPONSE', `Server returned an unexpected response (${res.status})`);
|
|
29
43
|
}
|
|
30
|
-
return
|
|
44
|
+
return body.data;
|
|
31
45
|
}
|
|
32
46
|
export async function listProjects() {
|
|
33
47
|
return request('/projects');
|
package/dist/config.js
CHANGED
|
@@ -13,10 +13,12 @@ export function setApiKey(key) {
|
|
|
13
13
|
config.set('apiKey', key);
|
|
14
14
|
}
|
|
15
15
|
export function getApiUrl() {
|
|
16
|
-
return config.get('apiUrl') ?? 'https://deploylog.dev';
|
|
16
|
+
return (config.get('apiUrl') ?? 'https://deploylog.dev').replace(/\/+$/, '');
|
|
17
17
|
}
|
|
18
18
|
export function setApiUrl(url) {
|
|
19
|
-
|
|
19
|
+
// Normalize so request building (`${apiUrl}/api/cli${path}`) never produces a
|
|
20
|
+
// double slash from a trailing-slash paste. (BUG-012)
|
|
21
|
+
config.set('apiUrl', url.trim().replace(/\/+$/, ''));
|
|
20
22
|
}
|
|
21
23
|
export function clearConfig() {
|
|
22
24
|
config.clear();
|
package/dist/index.js
CHANGED
|
@@ -18,6 +18,20 @@ program
|
|
|
18
18
|
.option('--api-url <url>', 'API base URL (default: https://deploylog.dev)')
|
|
19
19
|
.action(async (opts) => {
|
|
20
20
|
if (opts.apiUrl) {
|
|
21
|
+
let parsed;
|
|
22
|
+
try {
|
|
23
|
+
parsed = new URL(opts.apiUrl.trim());
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
console.error(chalk.red('Invalid API URL. Provide a valid absolute URL.'));
|
|
27
|
+
process.exit(1);
|
|
28
|
+
}
|
|
29
|
+
// Require http(s) and a real host — a scheme-only value like "https://"
|
|
30
|
+
// parses but would break request URL construction.
|
|
31
|
+
if (!/^https?:$/.test(parsed.protocol) || !parsed.hostname) {
|
|
32
|
+
console.error(chalk.red('Invalid API URL. Must use http(s) and include a host.'));
|
|
33
|
+
process.exit(1);
|
|
34
|
+
}
|
|
21
35
|
setApiUrl(opts.apiUrl);
|
|
22
36
|
}
|
|
23
37
|
if (opts.key) {
|
|
@@ -175,11 +189,19 @@ program
|
|
|
175
189
|
return;
|
|
176
190
|
}
|
|
177
191
|
}
|
|
192
|
+
else if (!opts.yes) {
|
|
193
|
+
// Non-interactive shell (CI, piped stdin): there's no prompt to show,
|
|
194
|
+
// so make the unreviewed auto-proceed explicit. (BUG-019)
|
|
195
|
+
console.log(chalk.yellow('Non-interactive shell: proceeding with the AI-generated entry without confirmation.'));
|
|
196
|
+
}
|
|
178
197
|
}
|
|
179
198
|
if (!title || !body) {
|
|
180
199
|
console.error(chalk.red('Entry requires --title and --body (or --from-git / --ai-summarize to derive them).'));
|
|
181
200
|
process.exit(1);
|
|
182
201
|
}
|
|
202
|
+
if (opts.publish && opts.draft) {
|
|
203
|
+
console.log(chalk.yellow('Both --publish and --draft passed; saving as a draft.'));
|
|
204
|
+
}
|
|
183
205
|
const entry = await createEntry(slug, {
|
|
184
206
|
title,
|
|
185
207
|
body_markdown: body,
|