fetch service
import { Workspace } from "../workspace.js";
export default {
create(){
return (params, useContext = false) => {
if(useContext) return this.handleCall(params);
return Workspace.run(function(){
return this.fetch(params, true);
});
};
},
async handleCall(params = {}){
const normalizedParams = this.normalizeParams(params);
this.context.params = normalizedParams;
const viewName = normalizedParams._url.pathname.replace(/^\/|\/$/g, '');
let out = await this.renderGuardViews(viewName, normalizedParams);
if(out){
return out;
}
if(!viewName.match(/(^|\/)_/)){
out = this.normalizeResponse(await this.renderView(viewName != '' ? `${viewName}/index`: 'index', normalizedParams));
if(out){
return out;
}
out = this.normalizeResponse(await this.renderView(viewName, normalizedParams));
if(out){
return out;
}
}
out = await this.renderDefaultViews(viewName, normalizedParams);
if(out){
return out;
}
return [404, {'content-type': 'text/plain'}, ['Not found']];
},
async renderGuardViews(viewName, params){
const viewNameSegments = viewName != '' ? viewName.split(/\//) : [];
const candidateIndexView = [...viewNameSegments, 'index'].join('/');
const candidateDefaultView = [...viewNameSegments, 'default'].join('/');
if(!this.app.isView(candidateIndexView) && !this.app.isView(candidateDefaultView)){
viewNameSegments.pop();
}
const prefixSegments = [];
while(true){
const out = this.normalizeResponse(await this.renderView(prefixSegments.length ? [...prefixSegments, 'guard'].join('/') : 'guard', params));
if(out){
return out;
}
if(viewNameSegments.length == 0){
break;
}
prefixSegments.push(viewNameSegments.shift());
}
},
async renderDefaultViews(viewName, params){
const prefixSegments = viewName != '' ? viewName.split(/\//) : [];
while(true){
const out = this.normalizeResponse(await this.renderView(prefixSegments.length ? [...prefixSegments, 'default'].join('/') : 'default', params));
if(out){
return out;
}
if(prefixSegments.length == 0){
break;
}
prefixSegments.pop();
}
},
normalizeParams(params){
const out = { ...params }
if(!out._method){
out._method = 'get';
}
if(!params._url){
out._url = new URL('http://localhost')
}
if(!params._headers){
out._headers = {};
}
return out;
},
normalizeResponse(response){
if(!response) return;
let responseArray;
if(response && typeof response.toResponseArray == 'function'){
responseArray = response.toResponseArray();
} else if(response && !Array.isArray(response)){
responseArray = [200, {'content-type': 'text/plain'}, [`${response}`]];
} else {
responseArray = response;
}
const [ status, headers, body ] = responseArray;
const normalizedHeaders = {};
Object.keys(headers).forEach(name => {
normalizedHeaders[name.toLowerCase()] = headers[name];
})
return [ status, normalizedHeaders, body ];
}
};