mirror of
https://codeberg.org/buzzcode2007/FCC-Project-URLShortener.git
synced 2025-05-21 03:06:34 +00:00
Create the API and management
This commit is contained in:
parent
02709cccf4
commit
31e074a5a8
3 changed files with 213 additions and 0 deletions
95
scripts/API.js
Executable file
95
scripts/API.js
Executable file
|
@ -0,0 +1,95 @@
|
|||
// Import modules
|
||||
var URLManage = require(`./database/URLs`).URLManage;
|
||||
var Messaging = require(`./utilities/messaging`).Messaging;
|
||||
const bodyParser = require('body-parser');
|
||||
|
||||
class ShortenAPI {
|
||||
/*
|
||||
Paths used by this API.
|
||||
*/
|
||||
#paths = {
|
||||
"create": ["/api/shorturl"],
|
||||
"access": ["/:ID", "/api/shorturl/:ID"]
|
||||
}
|
||||
|
||||
/*
|
||||
Create the URL shortener parser API.
|
||||
|
||||
@param {Express} INSTANCE - The Express instance
|
||||
*/
|
||||
constructor (INSTANCE) {
|
||||
this[`instance`] = INSTANCE;
|
||||
this[`instance`].use(bodyParser.json());
|
||||
this[`instance`].use(bodyParser.urlencoded({extended: true}));
|
||||
|
||||
this[`management`] = new URLManage;
|
||||
|
||||
this.prepareRedirect();
|
||||
this.startCreation();
|
||||
}
|
||||
|
||||
/*
|
||||
Redirect from the short link.
|
||||
*/
|
||||
prepareRedirect() {
|
||||
const findRedirect = (REQUEST, RESPONSE) => {
|
||||
const redirectBrowser = (URL) => {
|
||||
return((URL) ? RESPONSE.redirect(URL) : null);
|
||||
}
|
||||
|
||||
try {
|
||||
((Object.keys(REQUEST.params).length)
|
||||
? REQUEST.params.ID
|
||||
: false) ?
|
||||
this[`management`].open(REQUEST.params.ID, redirectBrowser)
|
||||
: false;
|
||||
} catch(ERR) {
|
||||
Messaging.exception(RESPONSE, ERR);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
this.#paths[`access`].forEach((PATH) => {
|
||||
this[`instance`].get(PATH, findRedirect)
|
||||
console.log(`Redirection ready on ${PATH}.`);
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
Enable receiving requests.
|
||||
*/
|
||||
startCreation() {
|
||||
const redirect = (REQUEST, RESPONSE) => {
|
||||
try {
|
||||
let QUERY = {};
|
||||
if ((REQUEST.body) ? Object.keys(REQUEST.body).length : false) {
|
||||
QUERY = REQUEST.body;
|
||||
} else if ((REQUEST.query) ? Object.keys(REQUEST.query).length : false) {
|
||||
QUERY = REQUEST.query;
|
||||
}
|
||||
|
||||
let RESULT = {};
|
||||
RESULT[`original_url`] = QUERY[`url`];
|
||||
|
||||
|
||||
const sendRedirect = (HASH) => {
|
||||
RESULT[`short_url`] = HASH;
|
||||
RESPONSE.json(RESULT);
|
||||
}
|
||||
|
||||
this[`management`].create(RESULT[`original_url`], sendRedirect);
|
||||
} catch(ERR) {
|
||||
Messaging.exception(RESPONSE, ERR);
|
||||
};
|
||||
};
|
||||
|
||||
[`get`, `post`].forEach((METHOD) => {
|
||||
this.#paths[`create`].forEach((PATH) => {
|
||||
this[`instance`][METHOD](PATH, redirect);
|
||||
console.log(`Creation ready on ${PATH} for method ${METHOD}.`)
|
||||
});
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {ShortenAPI};
|
97
scripts/database/URLs.js
Executable file
97
scripts/database/URLs.js
Executable file
|
@ -0,0 +1,97 @@
|
|||
const Mongoose = require(`mongoose`);
|
||||
const DBManagement = require(`./management`).DBManagement;
|
||||
const URLs = require(`../utilities/URLs`).URLs;
|
||||
const CustomErrors = require(`../utilities/errors`).CustomErrors;
|
||||
const HashTools = require(`../utilities/hash`).HashTools;
|
||||
|
||||
class URLManage extends DBManagement {
|
||||
/*
|
||||
Begin the URL management and connection.
|
||||
*/
|
||||
constructor () {
|
||||
super(`localhost:27017`);
|
||||
|
||||
this.schema = new Mongoose.Schema({
|
||||
"original": {"type": String, "required": true},
|
||||
"shortened": {"type": String, "required": true}
|
||||
});
|
||||
|
||||
this[`state`].then(() => {this.model = this[`connection`].model(`URL`, this[`schema`]);})
|
||||
};
|
||||
|
||||
/*
|
||||
Open the original URL given an identifier.
|
||||
|
||||
@param {string} ID the ID
|
||||
@param {function} done the callback function when successful
|
||||
@return {string} the original URL
|
||||
*/
|
||||
open (ID, done) {
|
||||
this.state.then(() => {
|
||||
this.model.findOne({"shortened": ID}).then((DATA) => {
|
||||
console.log((DATA) ? `Lengthened shortened URL with ID ${ID} to ${DATA[`original`]}.` : `No shortened URL with ID ${ID}.`);
|
||||
return done((DATA) ? DATA[`original`] : null);
|
||||
}).catch((ERR) => {
|
||||
throw ERR;
|
||||
})
|
||||
}).catch((ERROR) => {throw new CustomErrors.DBProblem(ERROR.message)});
|
||||
};
|
||||
|
||||
/*
|
||||
Search for a short link given a URL.
|
||||
|
||||
@param {string} URL the URL to shorten
|
||||
@param {function} done the callback function when successful
|
||||
@return {string} ID the ID
|
||||
*/
|
||||
search(URL, done) {
|
||||
// Throw an error for an incorrect URL.
|
||||
if (!URLs.test(URL)) {
|
||||
throw new CustomErrors.URL(null, URL);
|
||||
};
|
||||
|
||||
this.state.then(() => {
|
||||
this.model.findOne({"original": URL}).then((DATA) => {
|
||||
console.log((DATA) ? `The ID ${DATA[`shortened`]} refers to ${URL}.` : `No ID pertains to ${URL}.`);
|
||||
return done((DATA) ? DATA[`shortened`] : null);
|
||||
}).catch((ERR) => {
|
||||
throw ERR;
|
||||
});
|
||||
}).catch((ERROR) => {throw new CustomErrors.DBProblem(ERROR.message)})
|
||||
};
|
||||
|
||||
/*
|
||||
Shorten the URL.
|
||||
|
||||
@param {string} URL the URL to shorten
|
||||
@param {function} done the callback function
|
||||
@return {string} ID the ID
|
||||
*/
|
||||
create(URL, done) {
|
||||
// Throw an error for an incorrect URL.
|
||||
if (!URLs.test(URL)) {
|
||||
throw new CustomErrors.URL(null, URL);
|
||||
};
|
||||
|
||||
let ENTRY = {"original": URL};
|
||||
const save = (ID) => {
|
||||
(ID)
|
||||
? done(ID)
|
||||
: HashTools.digest(URL, {"output": "Number"}).then((HASH) => {
|
||||
ENTRY[`shortened`] = HASH;
|
||||
|
||||
let DOCUMENT = new this.model(ENTRY);
|
||||
|
||||
this.state.then(() => {
|
||||
DOCUMENT.save().then((DATA) => {done(HASH)}).catch((ERR) => {throw ERR;})
|
||||
}).catch((ERROR) => {throw new CustomErrors.DBProblem(ERROR.message)});
|
||||
});
|
||||
}
|
||||
|
||||
this.search((ENTRY[`original`]), save);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
module.exports = {URLManage};
|
21
scripts/database/management.js
Normal file
21
scripts/database/management.js
Normal file
|
@ -0,0 +1,21 @@
|
|||
const Mongoose = require(`mongoose`);
|
||||
const CustomErrors = require(`../utilities/errors`).CustomErrors;
|
||||
|
||||
class DBManagement {
|
||||
/*
|
||||
Begin the connection.
|
||||
|
||||
@param {string} DOMAIN the domain
|
||||
@param {string} DBNAME the database name
|
||||
*/
|
||||
constructor (DOMAIN, DBNAME) {
|
||||
const throwError = (ERROR) => {throw ERROR;};
|
||||
|
||||
this[`state`] = Mongoose.connect(`mongodb://${DOMAIN}/${(DBNAME) ? DBNAME : ""}`, { useNewUrlParser: true, useUnifiedTopology: true }).then((CONNECTION) => {
|
||||
this[`connection`] = CONNECTION.connection;
|
||||
console.log(`Connection successful.`);
|
||||
}).catch(throwError);
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = {DBManagement};
|
Loading…
Add table
Add a link
Reference in a new issue