Skip to content

Commit 13c3e98

Browse files
authored
Merge pull request #276 from quantcdn/feat/redirect-delete
Feat: Add redirect delete handling.
2 parents 02fd0f0 + 1975917 commit 13c3e98

4 files changed

Lines changed: 97 additions & 22 deletions

File tree

‎src/commands/delete.js‎

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ const { text, confirm, isCancel } = require('@clack/prompts');
99
const color = require('picocolors');
1010
const config = require('../config');
1111
const client = require('../quant-client');
12+
const deleteResponse = require('../helper/deleteResponse');
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: 56 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,12 @@
44
* @usage
55
* quant redirect <from> <to> [status]
66
*/
7-
const { text, select, isCancel } = require('@clack/prompts');
7+
const { text, select, isCancel, confirm } = require('@clack/prompts');
8+
const color = require('picocolors');
89
const config = require('../config');
910
const client = require('../quant-client');
1011
const isMD5Match = require('../helper/is-md5-match');
12+
const deleteResponse = require('../helper/deleteResponse');
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]
33-
});
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
47+
})
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+
module.exports = 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)