Skip to content

Commit 83a6125

Browse files
committed
Merge upstream: add deleteResponse helper
- Resolve conflicts keeping ESM syntax - Add deleteResponse helper for delete/redirect commands - Convert helper to ESM exports
2 parents 7ae99db + 718cbe0 commit 83a6125

File tree

4 files changed

+96
-21
lines changed

4 files changed

+96
-21
lines changed

src/commands/delete.js

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { text, confirm, isCancel } from '@clack/prompts';
99
import color from 'picocolors';
1010
import config from '../config.js';
1111
import client from '../quant-client.js';
12+
import deleteResponse from '../helper/deleteResponse.js';
1213

1314
const command = {
1415
command: 'delete <path>',
@@ -100,19 +101,13 @@ const command = {
100101
} catch (err) {
101102
// If we have a response in the error message, try to parse it
102103
try {
103-
const match = err.message.match(/Response: (.*)/s);
104-
if (match) {
105-
const responseData = JSON.parse(match[1]);
106-
107-
// Check if this was actually a successful deletion
108-
if (!responseData.error && responseData.meta && responseData.meta[0]) {
109-
const meta = responseData.meta[0];
110-
if (meta.deleted) {
111-
return color.green(`Successfully removed [${args.path}]`);
112-
}
113-
if (meta.deleted_timestamp) {
114-
return color.dim(`Path [${args.path}] was already deleted`);
115-
}
104+
const [ok, message] = deleteResponse(err);
105+
if (ok) {
106+
if (message === 'success') {
107+
return color.green(`Successfully removed [${args.path}]`);
108+
}
109+
if (message === 'already deleted') {
110+
return color.dim(`Path [${args.path}] was already deleted`);
116111
}
117112
}
118113
} catch (_parseError) {

src/commands/redirect.js

Lines changed: 55 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,12 @@
44
* @usage
55
* quant redirect <from> <to> [status]
66
*/
7-
import { text, select, isCancel } from '@clack/prompts';
7+
import { text, select, isCancel, confirm } from '@clack/prompts';
8+
import color from 'picocolors';
89
import config from '../config.js';
910
import client from '../quant-client.js';
1011
import isMD5Match from '../helper/is-md5-match.js';
12+
import deleteResponse from '../helper/deleteResponse.js';
1113

1214
const command = {
1315
command: 'redirect <from> <to> [status]',
@@ -30,11 +32,34 @@ const command = {
3032
type: 'number',
3133
default: 302,
3234
choices: [301, 302, 303, 307, 308]
35+
})
36+
.option('delete', {
37+
describe: 'Delete the redirect',
38+
alias: ['d'],
39+
type: 'boolean',
40+
default: false
41+
})
42+
.option('force', {
43+
describe: 'Delete without confirmation',
44+
alias: ['f'],
45+
type: 'boolean',
46+
default: false
3347
});
3448
},
3549

3650
async promptArgs(providedArgs = {}) {
51+
let isDelete = providedArgs.delete === true;
3752
let from = providedArgs.from;
53+
54+
if (isDelete) {
55+
from = await text({
56+
message: 'Enter URL to redirect from',
57+
validate: value => !value ? 'From URL is required' : undefined
58+
});
59+
if (isCancel(from)) return null;
60+
return { from, to: null, status: null, delete: true, force: providedArgs.force};
61+
}
62+
3863
if (!from) {
3964
from = await text({
4065
message: 'Enter URL to redirect from',
@@ -68,7 +93,7 @@ const command = {
6893
if (isCancel(status)) return null;
6994
}
7095

71-
return { from, to, status };
96+
return { from, to, status, delete: false, force: false };
7297
},
7398

7499
async handler(args) {
@@ -89,11 +114,36 @@ const command = {
89114
const status = args.status || 302;
90115

91116
try {
92-
await quant.redirect(args.from, args.to, null, status);
93-
return `Created redirect from ${args.from} to ${args.to} (${status})`;
117+
if (args.delete) {
118+
if (!args.force) {
119+
const shouldDelete = await confirm({
120+
message: 'This will delete the redirect. Are you sure?',
121+
initialValue: false,
122+
active: 'Yes',
123+
inactive: 'No'
124+
});
125+
if (isCancel(shouldDelete) || !shouldDelete) {
126+
throw new Error('Operation cancelled');
127+
}
128+
}
129+
await quant.delete(args.from);
130+
return color.green(`Deleted redirect from ${args.from}`);
131+
} else {
132+
await quant.redirect(args.from, args.to, null, status);
133+
return color.green(`Created redirect from ${args.from} to ${args.to} (${status})`);
134+
}
94135
} catch (err) {
136+
const [ok, message] = deleteResponse(err);
137+
if (ok) {
138+
if (message === 'success') {
139+
return color.green('Redirect was deleted');
140+
}
141+
if (message === 'already deleted') {
142+
return color.dim('Redirect was already deleted');
143+
}
144+
}
95145
if (isMD5Match(err)) {
96-
return `Skipped redirect from ${args.from} to ${args.to} (already exists)`;
146+
return color.dim(`Skipped redirect from ${args.from} to ${args.to} (already exists)`);
97147
}
98148
throw new Error(`Failed to create redirect: ${err.message}`);
99149
}

src/helper/deleteResponse.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/**
2+
* Handle the delete response.
3+
*/
4+
5+
/**
6+
* Handle the delete response.
7+
* @param {*} error
8+
* @returns [boolean, string]
9+
* - Success, if the delete was successful
10+
* - Message, the message from the response
11+
*/
12+
const deleteResponse = function(error) {
13+
const reponseData = error.message && error.message.match(/Response: (.*)/s);
14+
if (reponseData) {
15+
const responseData = JSON.parse(reponseData[1]);
16+
if (responseData.meta && responseData.meta[0]) {
17+
const meta = responseData.meta[0];
18+
if (meta.deleted) {
19+
return [true, 'success'];
20+
}
21+
if (meta.deleted_timestamp) {
22+
return [true, 'already deleted'];
23+
}
24+
}
25+
}
26+
27+
return [false, 'unknown error'];
28+
};
29+
30+
export default deleteResponse;

tests/unit/commands/redirect.test.mjs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ describe('Redirect Command', () => {
5757
};
5858

5959
const result = await redirect.handler.call(context, args);
60-
expect(result).to.equal('Created redirect from /old-path to /new-path (301)');
60+
expect(result).to.include('Created redirect from /old-path to /new-path (301)');
6161
expect(mockClientInstance._history.post.length).to.equal(1);
6262
});
6363

@@ -88,7 +88,7 @@ describe('Redirect Command', () => {
8888
};
8989

9090
const result = await redirect.handler.call(context, args);
91-
expect(result).to.equal('Skipped redirect from /old-path to /new-path (already exists)');
91+
expect(result).to.include('Skipped redirect from /old-path to /new-path (already exists)');
9292
});
9393

9494
it('should handle missing args', async () => {
@@ -176,7 +176,7 @@ describe('Redirect Command', () => {
176176
};
177177

178178
const result = await redirect.handler.call(context, args);
179-
expect(result).to.equal('Created redirect from /old-path to /new-path (302)');
179+
expect(result).to.include('Created redirect from /old-path to /new-path (302)');
180180
expect(mockClientInstance._history.post.length).to.equal(1);
181181
const [call] = mockClientInstance._history.post;
182182
expect(call.headers['Quant-Status']).to.equal(302);

0 commit comments

Comments
 (0)