ro
1e37580869
dropped in js from the old site to begin the process of wiring up the API, but this time around, scripts will be served directly in browswer rather than being transpiled through NPM/Babel, eliminating the need for NPM. also scripting will new modularized and served specifically for the requirements of the page loading it. no more front loading everything. only script that is needed for that page will be retrieved. if no scripting is needed, none will be loaded. The only casualty so far has been syntax highlighting due to prismjs still being a common js module, but either this will be replaced with another library or a custom syntax enginge will be created at a later date
433 lines
13 KiB
JavaScript
433 lines
13 KiB
JavaScript
//** REQUEST TYPES **//
|
|
export const REQUEST_TYPE_POST = 'POST';
|
|
export const REQUEST_TYPE_GET = 'GET';
|
|
export const REQUEST_TYPE_PUT = 'PUT';
|
|
export const REQUEST_TYPE_DELETE = 'DELETE';
|
|
//** POST CONTENT TYPES **//
|
|
export const CONTENT_TYPE_JSON = 'json';
|
|
export const CONTENT_TYPE_FORM = 'x-www-form-urlencoded';
|
|
//** API URLS **//
|
|
export const API_STATUS = '/api/v1/status';
|
|
export const API_GET_SETTINGS = '/api/v1/settings/site';
|
|
export const API_GET_MEMBER_INFO = '/api/v1/settings/member';
|
|
export const API_NEW_PAGE = '/api/v1/page/create';
|
|
export const API_EDIT_PAGE = '/api/v1/page/write';
|
|
export const API_DELETE_PAGE = '/api/v1/page/delete';
|
|
export const API_SETTINGS_SYNC = '/api/v1/settings/sync';
|
|
export const API_PUBLISH_PAGES = '/api/v1/settings/publish';
|
|
export const API_NAV_SYNC = '/api/v1/settings/nav-sync';
|
|
export const API_REINDEX_PAGES = '/api/v1/settings/reindex';
|
|
export const API_SEND_MAIL = '/api/v1/mailer';
|
|
export const API_LOGIN = '/api/v1/login';
|
|
//** API TASKS **//
|
|
export const AUTH_STATUS = 'getAuthStatus';
|
|
export const TASK_SETTINGS_WRITE = 'writeSettings';
|
|
export const TASK_PUBLISH_SITE = 'publishSite';
|
|
export const TASK_PAGE_CREATE = 'createNewPage';
|
|
export const TASK_PAGE_EDIT = 'editPage';
|
|
export const TASK_PAGE_DELETE = 'deletePage';
|
|
export const TASK_SEND_MAIL = 'sendMail';
|
|
export const TASK_REINDEX_PAGE = 'reIndexPages';
|
|
export const TASK_SYNC_SETTNIGS = 'syncSite';
|
|
export const TASK_SYNC_NAV = 'syncNav';
|
|
export const TASK_GET_SETTINGS = 'getSiteSettings';
|
|
export const TASK_GET_MEMBER_INFO = 'getMemberInfo';
|
|
//** API STATUS **//
|
|
export const API_ACCESS_GOOD = 'apiUseAuthorized';
|
|
export const API_ACCESS_BAD = 'apiUseNotAuthorized';
|
|
|
|
/**
|
|
* A can of methods used to edit install settings, navigation pages and content pages
|
|
*/
|
|
|
|
class FipamoAdminAPI {
|
|
/**
|
|
* @constructor
|
|
* @param {string} baseURL - url of site; uses local when empty
|
|
* @param {object} progressBar - element to be used to display upload progress
|
|
*/
|
|
constructor(baseURL = null, progressBar = null) {
|
|
this.percentComplete = 0; //for later
|
|
this.baseURL = null;
|
|
this.progressBar = progressBar;
|
|
this.status = false;
|
|
if (baseURL) this.baseURL = baseURL;
|
|
//asks server if a session is active
|
|
this._request(this.baseURL ? this.baseURL + API_STATUS : API_STATUS).then(
|
|
response => {
|
|
if (response.type === API_ACCESS_GOOD) {
|
|
this.token = response.token;
|
|
} else {
|
|
//don't set token
|
|
//console.log("NO TOKEN");
|
|
}
|
|
}
|
|
);
|
|
}
|
|
/**
|
|
* Promise method for authenticating and starting a session\
|
|
* **POST**`/api/v1/login`
|
|
* @param {Object[]} data - json object that contains data for set up
|
|
* @param {string} data[].handle - handle for site user
|
|
* @param {string} data[].password - password for site user
|
|
* @example
|
|
* api.login(data).then(response=>{
|
|
* console.log("RESPONSE", response);
|
|
* })
|
|
* @returns {object} json object that contains type and status of login request
|
|
```
|
|
{
|
|
"message":"Example Message of Affirmation or what you're missing!",
|
|
"type":"exampleType",
|
|
}
|
|
```
|
|
*/
|
|
login(data) {
|
|
return new Promise((resolve, reject) => {
|
|
this.baseURL ? (data.remote = true) : (data.remote = false);
|
|
this.key ? (data.key = this.key) : (data.key = null);
|
|
this._request(
|
|
this.baseURL ? this.baseURL + API_LOGIN : API_LOGIN,
|
|
AUTH_STATUS,
|
|
REQUEST_TYPE_POST,
|
|
CONTENT_TYPE_JSON,
|
|
data
|
|
)
|
|
.then(result => {
|
|
resolve(result);
|
|
})
|
|
.catch(err => {
|
|
reject(err);
|
|
});
|
|
});
|
|
}
|
|
/**
|
|
* Method for saving site and navigation settings\
|
|
* **POST**`/api/v1/settings/:task`
|
|
* @param {string} task - settings being synced `config | navigation`
|
|
* @param {object[]} data - json object that contains settings data for [site] or [nav]
|
|
* @param {string} data[].global.base_url - base url for site [site]
|
|
* @param {string} data[].global.title - site title [site]
|
|
* @param {string} data[].global.descriptions - brief site summary [site]
|
|
* @param {string} data[].global.background - url for site feature image for header [site]
|
|
* @param {boolean} data[].global.private - privacy state for site [disabled] [site]
|
|
* @param {boolean} data[].global.renderOnSave - property for publishing site when page saved [disabled] [site]
|
|
* @param {string} data[].global.theme - current theme for site [site]
|
|
* @param {boolean} data[].global.externalAPI - toggle for external API access [site]
|
|
* @param {string} data[].member.handle - current member handle [site]
|
|
* @param {string} data[].member.email - current member email [site]
|
|
* @param {string} data[].email.active - current email protocol being used [site]
|
|
* @param {string} data[].email.smtp.domain - url of smtp service being [site]
|
|
* @param {string} data[].email.smtp.email - email account of smtp service [site]
|
|
* @param {string} data[].email.smtp.password - password for email of smtp service [site]
|
|
* @param {string} data[].email.mailgun.domain - mailgun domain url [site]
|
|
* @param {string} data[].email.mailgun.key - mailgun key [site]
|
|
*
|
|
* @param {string} data[].item.title - page title [nav]
|
|
* @param {string} data[].item.slug - url safe title [nav]
|
|
* @param {string} data[].item.uuid - unique identifier [nav]
|
|
* @param {string} data[].item.path - directory path to associated markdown file [nav]
|
|
* @example
|
|
* api.sync(TASK, data).then(response=>{
|
|
* console.log("RESPONSE", response);
|
|
* })
|
|
* @returns {object} json object that contains type and status of sync request
|
|
```
|
|
*
|
|
{
|
|
"message":"Example Message of Affirmation!",
|
|
"type":"exampleType",
|
|
}
|
|
```
|
|
*/
|
|
sync(task, data) {
|
|
return new Promise((resolve, reject) => {
|
|
let url = '';
|
|
switch (task) {
|
|
case 'syncSite':
|
|
url = API_SETTINGS_SYNC;
|
|
break;
|
|
case 'syncNav':
|
|
url = API_NAV_SYNC;
|
|
break;
|
|
}
|
|
this._request(
|
|
this.baseURL ? this.baseURL + url : url,
|
|
TASK_SETTINGS_WRITE,
|
|
REQUEST_TYPE_POST,
|
|
CONTENT_TYPE_JSON,
|
|
data
|
|
)
|
|
.then(result => {
|
|
resolve(result);
|
|
})
|
|
.catch(err => {
|
|
reject(err);
|
|
});
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Method for retrieving user authorizing user login
|
|
* @param {object[]} data - json object that contains task
|
|
* @param {string} data[].task - publishing task
|
|
* @example
|
|
* api.publish(TASK).then(response=>{
|
|
* console.log("RESPONSE", response);
|
|
* })
|
|
* @returns {object} json object that contains type and status of publis request
|
|
* ```
|
|
{
|
|
"message":"Example Message of Affirmation!",
|
|
"type":"exampleType",
|
|
}
|
|
* ```
|
|
*/
|
|
publish(data) {
|
|
return new Promise((resolve, reject) => {
|
|
this._request(
|
|
//API_PUBLISH_PAGES,
|
|
this.baseURL ? this.baseURL + API_PUBLISH_PAGES : API_PUBLISH_PAGES,
|
|
TASK_PUBLISH_SITE,
|
|
REQUEST_TYPE_POST,
|
|
CONTENT_TYPE_JSON,
|
|
data
|
|
)
|
|
.then(result => {
|
|
resolve(result);
|
|
})
|
|
.catch(err => {
|
|
reject(err);
|
|
});
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Method for handling page creating and editing\
|
|
* **POST**`/api/v1/page/:task`
|
|
* @param {string} task - current page action
|
|
* @param {object[]} form - form object that contains info for current page being edited/created
|
|
* @param {string} form[].id - sequence id for page, leave empty for new page
|
|
* @param {string} form[].uuid - unique identifier for page, leave empty for new page
|
|
* @param {string} form[].layout - current page layout
|
|
* @param {string} form[].current_title - saved url save title for persistence when changing title, leave empty for new page
|
|
* @param {string} form[].content - markdown body of page
|
|
* @param {string} form[].title - current title of page
|
|
* @param {string} form[].created - date page was created, leave empty for new page
|
|
* @param {string} form[].slug - url safe string of page title
|
|
* @param {string} form[].tags - comma separated list of tags
|
|
* @param {boolean} form[].menu - property that indicates page is included in site menu
|
|
* @param {boolean} form[].featured - property that indicates page is featured
|
|
* @param {boolean} form[].published - property that indicates page is public
|
|
* @param {string} form[].form_token - hidden property to authenticate form submission
|
|
* @param {input} form[].feature_image - main image for page
|
|
* @example
|
|
* api.pageActions(TASK, data).then(response=>{
|
|
* console.log("RESPONSE", response);
|
|
* })
|
|
* @returns {object} json object that contains type and status of page edit request
|
|
```
|
|
{
|
|
"message":"Example Message of Affirmation!",
|
|
"type":"exampleType",
|
|
}
|
|
```
|
|
*/
|
|
pageActions(task, data) {
|
|
let url, event, content;
|
|
switch (task) {
|
|
case TASK_PAGE_CREATE:
|
|
url = API_NEW_PAGE;
|
|
event = TASK_PAGE_CREATE;
|
|
content = CONTENT_TYPE_JSON;
|
|
break;
|
|
case TASK_PAGE_EDIT:
|
|
url = API_EDIT_PAGE;
|
|
event = TASK_PAGE_EDIT;
|
|
content = CONTENT_TYPE_JSON;
|
|
break;
|
|
|
|
case TASK_PAGE_DELETE:
|
|
url = API_DELETE_PAGE;
|
|
event = TASK_PAGE_DELETE;
|
|
content = CONTENT_TYPE_JSON;
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if (this.baseURL) {
|
|
//data.key = this.key;
|
|
data.remote = true;
|
|
} else {
|
|
data.remote = false;
|
|
}
|
|
|
|
return new Promise((resolve, reject) => {
|
|
this._request(
|
|
this.baseURL ? this.baseURL + url : url,
|
|
event,
|
|
REQUEST_TYPE_POST,
|
|
content,
|
|
data
|
|
)
|
|
.then(result => {
|
|
resolve(result);
|
|
})
|
|
.catch(err => {
|
|
reject(err);
|
|
});
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Method for sending mail (if completed in settings)\
|
|
* **POST**`/api/v1/mailer`
|
|
* @param {object[]} message - json object that contains items to be included in main site navigation
|
|
* @param {string} message[].content - message to send
|
|
* @example
|
|
* api.sendMail(message).then(response=>{
|
|
* console.log("RESPONSE", response);
|
|
* })
|
|
* @returns {object} json object that contains type and status of page edit request
|
|
```
|
|
{
|
|
"message":"Example Message of Affirmation!",
|
|
"type":"exampleType"
|
|
}
|
|
```
|
|
*/
|
|
sendMail(message) {
|
|
return new Promise((resolve, reject) => {
|
|
this._request(
|
|
this.baseURL ? this.baseURL + API_SEND_MAIL : API_SEND_MAIL,
|
|
TASK_SEND_MAIL,
|
|
REQUEST_TYPE_POST,
|
|
CONTENT_TYPE_JSON,
|
|
message
|
|
)
|
|
.then(result => {
|
|
resolve(result);
|
|
})
|
|
.catch(err => {
|
|
reject(err);
|
|
});
|
|
});
|
|
}
|
|
|
|
/**
|
|
* *Promise method for retrieving site and member info*\
|
|
* **GET** `/api/v1/settings/:type`
|
|
* @param {string} type - type of info requested ['site'|'member'];
|
|
* @example
|
|
* api.getInfo("type").then(data=>{
|
|
console.log("Info Object", data);
|
|
* })
|
|
* @returns {object} json object that contains data for requested information
|
|
*
|
|
* *info object example*
|
|
* ```
|
|
{
|
|
"message":"message of affirmation!",
|
|
"task":"type of info request",
|
|
"data":json-data-object,
|
|
}
|
|
* ```
|
|
*/
|
|
|
|
getInfo(type) {
|
|
let url, task;
|
|
if (type == 'site') {
|
|
url = API_GET_SETTINGS;
|
|
task = TASK_GET_SETTINGS;
|
|
} else {
|
|
url = API_GET_MEMBER_INFO;
|
|
task = TASK_GET_MEMBER_INFO;
|
|
}
|
|
return new Promise((resolve, reject) => {
|
|
this._request(this.baseURL ? this.baseURL + url : url, task)
|
|
.then(result => {
|
|
resolve(result);
|
|
})
|
|
.catch(err => {
|
|
reject(err);
|
|
});
|
|
});
|
|
}
|
|
|
|
//--------------------------
|
|
// private
|
|
//--------------------------
|
|
_request(
|
|
requestURL,
|
|
eventType,
|
|
requestType = REQUEST_TYPE_GET,
|
|
contentType = CONTENT_TYPE_JSON,
|
|
requestData = null
|
|
) {
|
|
var self = this;
|
|
return new Promise(function (resolve, reject) {
|
|
var request = new XMLHttpRequest();
|
|
request.upload.addEventListener('progress', e =>
|
|
self.handleLoadProgress(e, self.progressBar)
|
|
);
|
|
request.open(requestType, requestURL, true);
|
|
request.onload = () => {
|
|
if (request.status == 200) {
|
|
let response = JSON.parse(request['response']);
|
|
resolve(response);
|
|
} else {
|
|
let error = JSON.parse(request['response']);
|
|
reject(error);
|
|
}
|
|
};
|
|
if (requestType == REQUEST_TYPE_PUT || requestType == REQUEST_TYPE_POST) {
|
|
if (
|
|
eventType === TASK_SETTINGS_WRITE ||
|
|
eventType === TASK_PAGE_EDIT ||
|
|
eventType === TASK_PAGE_CREATE ||
|
|
eventType === TASK_PAGE_DELETE ||
|
|
eventType === TASK_PUBLISH_SITE ||
|
|
eventType === TASK_REINDEX_PAGE
|
|
)
|
|
request.setRequestHeader('fipamo-access-token', self.token);
|
|
|
|
switch (contentType) {
|
|
case CONTENT_TYPE_JSON:
|
|
request.setRequestHeader(
|
|
'Content-type',
|
|
'application/' + contentType
|
|
);
|
|
request.send(JSON.stringify(requestData));
|
|
break;
|
|
case CONTENT_TYPE_FORM:
|
|
request.send(requestData);
|
|
break;
|
|
}
|
|
} else {
|
|
if (
|
|
eventType === TASK_GET_SETTINGS ||
|
|
eventType === TASK_GET_MEMBER_INFO
|
|
) {
|
|
request.setRequestHeader('fipamo-access-token', self.token);
|
|
}
|
|
request.send();
|
|
}
|
|
});
|
|
}
|
|
|
|
//--------------------------
|
|
// event handlers
|
|
//--------------------------
|
|
handleLoadProgress(e, progressBar) {
|
|
let percent = Math.ceil((e.loaded / e.total) * 100);
|
|
//if a progress bar element is present, talk to it
|
|
if (progressBar != null) {
|
|
progressBar.style.width = percent + '%';
|
|
}
|
|
}
|
|
}
|
|
|
|
export { FipamoAdminAPI as default };
|