353 lines
12 KiB
JavaScript
353 lines
12 KiB
JavaScript
#include commitment.js
|
|
#include xhr.js
|
|
|
|
const Flashii = function(baseUrl) {
|
|
if(typeof baseUrl !== 'string')
|
|
throw new Error('baseUrl must be a string');
|
|
if(baseUrl.indexOf('//') === 0)
|
|
baseUrl = window.location.protocol + baseUrl;
|
|
|
|
const sortArray = typeof Array.prototype.toSorted === 'function'
|
|
? array => array.toSorted()
|
|
: array => {
|
|
array = array.slice();
|
|
array.sort();
|
|
return array;
|
|
};
|
|
|
|
const convertFields = fields => {
|
|
if(fields === true)
|
|
return '*';
|
|
|
|
if(Array.isArray(fields))
|
|
return sortArray(fields).join(',');
|
|
|
|
if(typeof fields === 'string')
|
|
return fields;
|
|
|
|
return null;
|
|
};
|
|
|
|
const createUrl = (path, fields=null) => {
|
|
const url = baseUrl + path;
|
|
const params = {};
|
|
|
|
if(fields)
|
|
params['fields'] = convertFields(fields);
|
|
|
|
return {
|
|
setParam(name, value) {
|
|
params[name] = value;
|
|
},
|
|
deleteParam(name) {
|
|
delete params[name];
|
|
},
|
|
toString() {
|
|
let str = url;
|
|
|
|
const queryParts = [];
|
|
for(const name in params)
|
|
if(params.hasOwnProperty(name))
|
|
queryParts.push(encodeURIComponent(name) + '=' + encodeURIComponent(params[name]));
|
|
if(queryParts.length > 0)
|
|
str += (str.indexOf('?') < 0 ? '?' : '&') + queryParts.join('&');
|
|
|
|
return str;
|
|
},
|
|
};
|
|
};
|
|
|
|
const send = ({
|
|
method,
|
|
path,
|
|
fresh=false,
|
|
params=null,
|
|
fields=null,
|
|
body=null,
|
|
headers=null,
|
|
type='json',
|
|
authed=false,
|
|
}) => {
|
|
return new Commitment((success, fail) => {
|
|
const url = createUrl(path, fields);
|
|
if(params)
|
|
for(const name in params) {
|
|
if(name === 'fields' || params[name] === null || params[name] === undefined)
|
|
continue;
|
|
|
|
url.setParam(name, params[name]);
|
|
}
|
|
|
|
headers ??= {};
|
|
if(fresh) headers['Cache-Control'] = 'no-cache';
|
|
|
|
const options = { type, headers, authed };
|
|
|
|
$xhr.send(method, url, options, body)
|
|
.success(success)
|
|
.fail(fail)
|
|
.run();
|
|
});
|
|
};
|
|
|
|
const fii = {};
|
|
|
|
fii.v1 = {};
|
|
|
|
const verifyChatServerId = id => {
|
|
if(typeof id === 'number')
|
|
id = id.toString();
|
|
if(/^([^0-9]+)$/gu.test(id))
|
|
throw new Error('id argument is not an acceptable chat server id.');
|
|
return id;
|
|
};
|
|
|
|
fii.v1.chat = {};
|
|
fii.v1.chat.login = function({ redirect=null, assign=true }) {
|
|
return new Commitment(success => {
|
|
redirect ??= `${location.protocol}//${location.host}`;
|
|
if(typeof redirect !== 'string')
|
|
throw new Error('redirect must a string.');
|
|
|
|
const url = createUrl('/v1/chat/login');
|
|
url.setParam('redirect', redirect);
|
|
|
|
// intentionally does not call success
|
|
if(assign)
|
|
location.assign(url);
|
|
else
|
|
success(url);
|
|
});
|
|
};
|
|
fii.v1.chat.servers = function({ proto=null, secure=null, fields=null, fresh=false }) {
|
|
return new Commitment((success, fail) => {
|
|
const params = {};
|
|
|
|
if(proto !== null && typeof proto !== 'string')
|
|
throw new Error('proto must be a string or null');
|
|
params['proto'] = proto;
|
|
|
|
if(secure !== null)
|
|
params['secure'] = secure ? '1' : '0';
|
|
|
|
send({ method: 'GET', path: '/v1/chat/servers', fields, fresh, params })
|
|
.success(({ status, body }) => {
|
|
if(status === 400)
|
|
throw new Error('An argument contains an unsupported value.');
|
|
if(status > 299)
|
|
throw new Error(`Failed to fetch chat server list with error code ${status}.`);
|
|
|
|
success(body);
|
|
})
|
|
.fail(fail)
|
|
.run();
|
|
});
|
|
};
|
|
fii.v1.chat.servers.server = function({ id, fields=null, fresh=false }) {
|
|
return new Commitment((success, fail) => {
|
|
id = verifyChatServerId(id);
|
|
|
|
send({ method: 'GET', path: `/v1/chat/servers/${id}`, fields, fresh })
|
|
.success(({ status, body }) => {
|
|
if(status === 400)
|
|
throw new Error('Fields argument contains unsupported value.');
|
|
if(status === 404)
|
|
throw new Error('No chat server with that id could be found.');
|
|
if(status > 299)
|
|
throw new Error(`Failed to fetch chat server with error code ${status}.`);
|
|
|
|
success(body);
|
|
})
|
|
.fail(fail)
|
|
.run();
|
|
});
|
|
};
|
|
fii.v1.chat.servers.recommended = function({ proto, secure=null, fields=null, fresh=false }) {
|
|
return new Commitment((success, fail) => {
|
|
if(typeof proto !== 'string')
|
|
throw new Error('proto must be a string');
|
|
|
|
const params = { proto };
|
|
if(secure !== null)
|
|
params['secure'] = secure ? '1' : '0';
|
|
|
|
send({ method: 'GET', path: '/v1/chat/servers/recommended', fields, fresh, params })
|
|
.success(({ status, body }) => {
|
|
if(status === 400)
|
|
throw new Error('An argument contains an unsupported value.');
|
|
if(status === 404)
|
|
throw new Error('Was unable to determine a server based on the requested parameters.');
|
|
if(status > 299)
|
|
throw new Error(`Failed to fetch recommended chat server with error code ${status}.`);
|
|
|
|
success(body);
|
|
})
|
|
.fail(fail)
|
|
.run();
|
|
});
|
|
};
|
|
fii.v1.chat.token = function() {
|
|
return new Commitment((success, fail) => {
|
|
send({ method: 'GET', path: '/v1/chat/token', authed: true, fresh: true })
|
|
.success(({ status, body }) => {
|
|
if(status === 403)
|
|
throw new Error('You must be logged in to use chat.');
|
|
if(status > 299)
|
|
throw new Error(`Failed to fetch authorization token with error code ${status}.`);
|
|
|
|
success(body);
|
|
})
|
|
.fail(fail)
|
|
.run();
|
|
});
|
|
};
|
|
|
|
const verifyColourPresetName = name => {
|
|
if(/^([^A-Za-z0-9\-_]+)$/gu.test(name))
|
|
throw new Error('name argument is not an acceptable colour preset name.');
|
|
return name;
|
|
};
|
|
|
|
fii.v1.colours = {};
|
|
fii.v1.colours.presets = function({ fields=null, fresh=false }) {
|
|
return new Commitment((success, fail) => {
|
|
send({ method: 'GET', path: '/v1/colours/presets', fields, fresh })
|
|
.success(({ status, body }) => {
|
|
if(status === 400)
|
|
throw new Error('Fields argument contains unsupported value.');
|
|
if(status > 299)
|
|
throw new Error(`Failed to fetch colour presets with error code ${status}.`);
|
|
|
|
success(body);
|
|
})
|
|
.fail(fail)
|
|
.run();
|
|
});
|
|
};
|
|
fii.v1.colours.presets.preset = function({ name, fields=null, fresh=false }) {
|
|
return new Commitment((success, fail) => {
|
|
name = verifyColourPresetName(name);
|
|
|
|
send({ method: 'GET', path: `/v1/colours/presets/${name}`, fields, fresh })
|
|
.success(({ status, body }) => {
|
|
if(status === 400)
|
|
throw new Error('Fields argument contains unsupported value.');
|
|
if(status === 404)
|
|
throw new Error('Requested colour preset does not exist.');
|
|
if(status > 299)
|
|
throw new Error(`Failed to fetch colour preset "${name}" with error code ${status}.`);
|
|
|
|
success(body);
|
|
})
|
|
.fail(fail)
|
|
.run();
|
|
});
|
|
};
|
|
|
|
const verifyEmoticonId = id => {
|
|
if(typeof id === 'number')
|
|
id = id.toString();
|
|
if(/^([^0-9]+)$/gu.test(id))
|
|
throw new Error('id argument is not an acceptable emoticon id.');
|
|
return id;
|
|
};
|
|
|
|
fii.v1.emotes = function({ fields=null, fresh=false }) {
|
|
return new Commitment((success, fail) => {
|
|
send({ method: 'GET', path: '/v1/emotes', fields, fresh })
|
|
.success(({ status, body }) => {
|
|
if(status === 400)
|
|
throw new Error('Fields argument contains unsupported value.');
|
|
if(status > 299)
|
|
throw new Error(`Failed to fetch emoticons with error code ${status}.`);
|
|
|
|
success(body);
|
|
})
|
|
.fail(fail)
|
|
.run();
|
|
});
|
|
};
|
|
fii.v1.emotes.emote = function({ id, fields=null, fresh=false }) {
|
|
return new Commitment((success, fail) => {
|
|
id = verifyEmoticonId(id);
|
|
|
|
send({ method: 'GET', path: `/v1/emotes/${id}`, fields, fresh })
|
|
.success(({ status, body }) => {
|
|
if(status === 400)
|
|
throw new Error('Fields argument contains unsupported value.');
|
|
if(status === 404)
|
|
throw new Error('Requested emoticon does not exist.');
|
|
if(status > 299)
|
|
throw new Error(`Failed to fetch emoticon "${id}" with error code ${status}.`);
|
|
|
|
success(body);
|
|
})
|
|
.fail(fail)
|
|
.run();
|
|
});
|
|
};
|
|
fii.v1.emotes.emote.strings = function({ id, fields=null, fresh=false }) {
|
|
return new Commitment((success, fail) => {
|
|
id = verifyEmoticonId(id);
|
|
|
|
send({ method: 'GET', path: `/v1/emotes/${id}/strings`, fields, fresh })
|
|
.success(({ status, body }) => {
|
|
if(status === 400)
|
|
throw new Error('Fields argument contains unsupported value.');
|
|
if(status === 404)
|
|
throw new Error('Requested emoticon does not exist.');
|
|
if(status > 299)
|
|
throw new Error(`Failed to fetch emoticon "${id}" with error code ${status}.`);
|
|
|
|
success(body);
|
|
})
|
|
.fail(fail)
|
|
.run();
|
|
});
|
|
};
|
|
|
|
const verifyKaomojiId = id => {
|
|
if(typeof id === 'number')
|
|
id = id.toString();
|
|
if(/^([^0-9]+)$/gu.test(id))
|
|
throw new Error('id argument is not an acceptable kaomoji id.');
|
|
return id;
|
|
};
|
|
|
|
fii.v1.kaomoji = function({ as=null, fields=null, fresh=false }) {
|
|
return new Commitment((success, fail) => {
|
|
send({ method: 'GET', path: '/v1/kaomoji', params: { as }, fields, fresh })
|
|
.success(({ status, body }) => {
|
|
if(status === 400)
|
|
throw new Error('As or fields argument contains unsupported value.');
|
|
if(status > 299)
|
|
throw new Error(`Failed to fetch kaomoji with error code ${status}.`);
|
|
|
|
success(body);
|
|
})
|
|
.fail(fail)
|
|
.run();
|
|
});
|
|
};
|
|
fii.v1.kaomoji.kaomoji = function({ id, fields=null, fresh=false }) {
|
|
return new Commitment((success, fail) => {
|
|
id = verifyKaomojiId(id);
|
|
|
|
send({ method: 'GET', path: `/v1/kaomoji/${id}`, fields, fresh })
|
|
.success(({ status, body }) => {
|
|
if(status === 400)
|
|
throw new Error('Fields argument contains unsupported value.');
|
|
if(status === 404)
|
|
throw new Error('Requested kaomoji does not exist.');
|
|
if(status > 299)
|
|
throw new Error(`Failed to fetch kaomoji "${id}" with error code ${status}.`);
|
|
|
|
success(body);
|
|
})
|
|
.fail(fail)
|
|
.run();
|
|
});
|
|
};
|
|
|
|
return fii;
|
|
};
|