Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 8 additions & 13 deletions src/commands/delete.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const { text, confirm, isCancel } = require('@clack/prompts');
const color = require('picocolors');
const config = require('../config');
const client = require('../quant-client');
const deleteResponse = require('../helper/deleteResponse');

const command = {
command: 'delete <path>',
Expand Down Expand Up @@ -100,19 +101,13 @@ const command = {
} catch (err) {
// If we have a response in the error message, try to parse it
try {
const match = err.message.match(/Response: (.*)/s);
if (match) {
const responseData = JSON.parse(match[1]);

// Check if this was actually a successful deletion
if (!responseData.error && responseData.meta && responseData.meta[0]) {
const meta = responseData.meta[0];
if (meta.deleted) {
return color.green(`Successfully removed [${args.path}]`);
}
if (meta.deleted_timestamp) {
return color.dim(`Path [${args.path}] was already deleted`);
}
const [ok, message] = deleteResponse(err);
if (ok) {
if (message === "success") {
return color.green(`Successfully removed [${args.path}]`);
}
if (message === "already deleted") {
return color.dim(`Path [${args.path}] was already deleted`);
}
}
} catch (parseError) {
Expand Down
62 changes: 56 additions & 6 deletions src/commands/redirect.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@
* @usage
* quant redirect <from> <to> [status]
*/
const { text, select, isCancel } = require('@clack/prompts');
const { text, select, isCancel, confirm } = require('@clack/prompts');
const color = require('picocolors');
const config = require('../config');
const client = require('../quant-client');
const isMD5Match = require('../helper/is-md5-match');
const deleteResponse = require('../helper/deleteResponse');

const command = {
command: 'redirect <from> <to> [status]',
Expand All @@ -30,11 +32,34 @@ const command = {
type: 'number',
default: 302,
choices: [301, 302, 303, 307, 308]
});
})
.option('delete', {
describe: 'Delete the redirect',
alias: ['d'],
type: 'boolean',
default: false
})
.option('force', {
describe: 'Delete without confirmation',
alias: ['f'],
type: 'boolean',
default: false
})
},

async promptArgs(providedArgs = {}) {
let isDelete = providedArgs.delete === true;
let from = providedArgs.from;

if (isDelete) {
from = await text({
message: 'Enter URL to redirect from',
validate: value => !value ? 'From URL is required' : undefined
});
if (isCancel(from)) return null;
return { from, to: null, status: null, delete: true, force: providedArgs.force}
}

if (!from) {
from = await text({
message: 'Enter URL to redirect from',
Expand Down Expand Up @@ -68,7 +93,7 @@ const command = {
if (isCancel(status)) return null;
}

return { from, to, status };
return { from, to, status, delete: false, force: false };
},

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

try {
await quant.redirect(args.from, args.to, null, status);
return `Created redirect from ${args.from} to ${args.to} (${status})`;
if (args.delete) {
if (!args.force) {
const shouldDelete = await confirm({
message: 'This will delete the redirect. Are you sure?',
initialValue: false,
active: 'Yes',
inactive: 'No'
});
if (isCancel(shouldDelete) || !shouldDelete) {
throw new Error('Operation cancelled');
}
}
await quant.delete(args.from);
return color.green(`Deleted redirect from ${args.from}`);
} else {
await quant.redirect(args.from, args.to, null, status);
return color.green(`Created redirect from ${args.from} to ${args.to} (${status})`);
}
} catch (err) {
const [ok, message] = deleteResponse(err);
if (ok) {
if (message === "success") {
return color.green("Redirect was deleted");
}
if (message === "already deleted") {
return color.dim("Redirect was already deleted");
}
}
if (isMD5Match(err)) {
return `Skipped redirect from ${args.from} to ${args.to} (already exists)`;
return color.dim(`Skipped redirect from ${args.from} to ${args.to} (already exists)`);
}
throw new Error(`Failed to create redirect: ${err.message}`);
}
Expand Down
30 changes: 30 additions & 0 deletions src/helper/deleteResponse.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/**
* Handle the delete response.
*/

/**
* Handle the delete response.
* @param {*} error
* @returns [boolean, string]
* - Success, if the delete was successful
* - Message, the message from the response
*/
const deleteResponse = function(error) {
const reponseData = error.message && error.message.match(/Response: (.*)/s);
if (reponseData) {
const responseData = JSON.parse(reponseData[1]);
if (responseData.meta && responseData.meta[0]) {
const meta = responseData.meta[0];
if (meta.deleted) {
return [true, "success"];
}
if (meta.deleted_timestamp) {
return [true, "already deleted"];
}
}
}

return [false, "unknown error"];
}

module.exports = deleteResponse;
6 changes: 3 additions & 3 deletions tests/unit/commands/redirect.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ describe('Redirect Command', () => {
};

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

Expand Down Expand Up @@ -88,7 +88,7 @@ describe('Redirect Command', () => {
};

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

it('should handle missing args', async () => {
Expand Down Expand Up @@ -176,7 +176,7 @@ describe('Redirect Command', () => {
};

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