Sindbad~EG File Manager
'use strict';
const Boom = require('@hapi/boom');
const Bounce = require('@hapi/bounce');
const Hoek = require('@hapi/hoek');
const internals = {};
exports.reserved = [
'abandon',
'authenticated',
'close',
'context',
'continue',
'entity',
'redirect',
'realm',
'request',
'response',
'state',
'unauthenticated',
'unstate'
];
exports.symbols = {
abandon: Symbol('abandon'),
close: Symbol('close'),
continue: Symbol('continue')
};
exports.Manager = class {
constructor() {
this._toolkit = internals.toolkit();
}
async execute(method, request, options) {
const h = new this._toolkit(request, options);
const bind = options.bind ?? null;
try {
let operation;
if (bind) {
operation = method.call(bind, request, h);
}
else if (options.args) {
operation = method(request, h, ...options.args);
}
else {
operation = method(request, h);
}
var response = await exports.timed(operation, options);
}
catch (err) {
if (Bounce.isSystem(err)) {
response = Boom.badImplementation(err);
}
else if (!Bounce.isError(err)) {
response = Boom.badImplementation('Cannot throw non-error object', err);
}
else {
response = Boom.boomify(err);
}
}
// Process response
if (options.ignoreResponse) {
return response;
}
if (response === undefined) {
response = Boom.badImplementation(`${method.name} method did not return a value, a promise, or throw an error`);
}
if (options.continue &&
response === exports.symbols.continue) {
if (options.continue === 'undefined') {
return;
}
// 'null'
response = null;
}
if (options.auth &&
response instanceof internals.Auth) {
return response;
}
if (typeof response !== 'symbol') {
response = request._core.Response.wrap(response, request);
if (!response.isBoom && response._state === 'init') {
await response._prepare();
}
}
return response;
}
decorate(name, method) {
this._toolkit.prototype[name] = method;
}
failAction(request, failAction, err, options) {
const retain = options.retain ? err : undefined;
if (failAction === 'ignore') {
return retain;
}
if (failAction === 'log') {
request._log(options.tags, err);
return retain;
}
if (failAction === 'error') {
throw err;
}
return this.execute(failAction, request, { realm: request.route.realm, args: [options.details ?? err] });
}
};
exports.timed = function (method, options) {
if (!options.timeout) {
return method;
}
const timer = new Promise((resolve, reject) => {
const handler = () => {
reject(Boom.internal(`${options.name} timed out`));
};
setTimeout(handler, options.timeout);
});
return Promise.race([timer, method]);
};
/*
const handler = function (request, h) {
result / h.response(result) -> result // Not allowed before handler
h.response(result).takeover() -> result (respond)
h.continue -> null // Defaults to null only in handler and pre, not allowed in auth
throw error / h.response(error) -> error (respond) // failAction override in pre
<undefined> -> badImplementation (respond)
// Auth only (scheme.payload and scheme.response use the same interface as pre-handler extension methods)
h.unauthenticated(error, data) -> error (respond) + data
h.authenticated(data ) -> (continue) + data
};
*/
internals.toolkit = function () {
const Toolkit = class {
constructor(request, options) {
this.context = options.bind;
this.realm = options.realm;
this.request = request;
this._auth = options.auth;
}
response(result) {
Hoek.assert(!result || typeof result !== 'object' || typeof result.then !== 'function', 'Cannot wrap a promise');
Hoek.assert(result instanceof Error === false, 'Cannot wrap an error');
Hoek.assert(typeof result !== 'symbol', 'Cannot wrap a symbol');
return this.request._core.Response.wrap(result, this.request);
}
redirect(location) {
return this.response('').redirect(location);
}
entity(options) {
Hoek.assert(options, 'Entity method missing required options');
Hoek.assert(options.etag || options.modified, 'Entity methods missing required options key');
this.request._entity = options;
const entity = this.request._core.Response.entity(options.etag, options);
if (this.request._core.Response.unmodified(this.request, entity)) {
return this.response().code(304).takeover();
}
}
state(name, value, options) {
this.request._setState(name, value, options);
}
unstate(name, options) {
this.request._clearState(name, options);
}
authenticated(data) {
Hoek.assert(this._auth, 'Method not supported outside of authentication');
Hoek.assert(data?.credentials, 'Authentication data missing credentials information');
return new internals.Auth(null, data);
}
unauthenticated(error, data) {
Hoek.assert(this._auth, 'Method not supported outside of authentication');
Hoek.assert(!data || data.credentials, 'Authentication data missing credentials information');
return new internals.Auth(error, data);
}
};
Toolkit.prototype.abandon = exports.symbols.abandon;
Toolkit.prototype.close = exports.symbols.close;
Toolkit.prototype.continue = exports.symbols.continue;
return Toolkit;
};
internals.Auth = class {
constructor(error, data) {
this.isAuth = true;
this.error = error;
this.data = data;
}
};
Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists