allow multiple apis, broke multiple pages
This commit is contained in:
parent
f4c104bf52
commit
760f00af35
|
@ -90,7 +90,7 @@ function loadPages(pkgConf, route, req, res, next) {
|
||||||
route._promise_app = new PromiseA(function (resolve, reject) {
|
route._promise_app = new PromiseA(function (resolve, reject) {
|
||||||
fs.exists(pkgpath, function (exists) {
|
fs.exists(pkgpath, function (exists) {
|
||||||
if (!exists) {
|
if (!exists) {
|
||||||
reject(new Error("package is registered but does not exist"));
|
reject(new Error("package '" + pkgpath + "' is registered but does not exist"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,10 +103,10 @@ function loadPages(pkgConf, route, req, res, next) {
|
||||||
handlePromise(route._promise_app);
|
handlePromise(route._promise_app);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getApi(pkgConf, pkgDeps, route) {
|
function getApi(pkgConf, pkgDeps, packagedApi) {
|
||||||
var PromiseA = require('bluebird');
|
var PromiseA = require('bluebird');
|
||||||
var path = require('path');
|
var path = require('path');
|
||||||
var pkgpath = path.join(pkgConf.apipath, route.api.id/*, (route.api.version || '')*/);
|
var pkgpath = path.join(pkgConf.apipath, packagedApi.id/*, (packagedApi.api.version || '')*/);
|
||||||
|
|
||||||
// TODO needs some version stuff (which would also allow hot-loading of updates)
|
// TODO needs some version stuff (which would also allow hot-loading of updates)
|
||||||
// TODO version could be tied to sha256sum
|
// TODO version could be tied to sha256sum
|
||||||
|
@ -138,10 +138,10 @@ function getApi(pkgConf, pkgDeps, route) {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
route._apipkg = require(path.join(pkgpath, 'package.json'));
|
packagedApi._apipkg = require(path.join(pkgpath, 'package.json'));
|
||||||
route._apiname = route._apipkg.name;
|
packagedApi._apiname = packagedApi._apipkg.name;
|
||||||
if (route._apipkg.walnut) {
|
if (packagedApi._apipkg.walnut) {
|
||||||
pkgpath += '/' + route.apipkg.walnut;
|
pkgpath += '/' + packagedApi._apipkg.walnut;
|
||||||
}
|
}
|
||||||
promise = require(pkgpath).create(pkgConf, pkgDeps, myApp);
|
promise = require(pkgpath).create(pkgConf, pkgDeps, myApp);
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
|
@ -151,41 +151,41 @@ function getApi(pkgConf, pkgDeps, route) {
|
||||||
|
|
||||||
promise.then(function () {
|
promise.then(function () {
|
||||||
// TODO give pub/priv pair for app and all public keys
|
// TODO give pub/priv pair for app and all public keys
|
||||||
// route._api = require(pkgpath).create(pkgConf, pkgDeps, myApp);
|
// packagedApi._api = require(pkgpath).create(pkgConf, pkgDeps, myApp);
|
||||||
route._api = require('express')();
|
packagedApi._api = require('express')();
|
||||||
route._api_app = myApp;
|
packagedApi._api_app = myApp;
|
||||||
// TODO fix backwards compat
|
// TODO fix backwards compat
|
||||||
// /api/com.example.foo (no change)
|
// /api/com.example.foo (no change)
|
||||||
route._api.use('/', route._api_app);
|
packagedApi._api.use('/', packagedApi._api_app);
|
||||||
// /api/com.example.foo => /
|
// /api/com.example.foo => /
|
||||||
route._api.use('/api/' + route.api.id, function (req, res, next) {
|
packagedApi._api.use('/api/' + packagedApi.id, function (req, res, next) {
|
||||||
//console.log('api mangle 2:', '/api/' + route.api.id, req.url);
|
//console.log('api mangle 2:', '/api/' + packagedApi.api.id, req.url);
|
||||||
route._api_app(req, res, next);
|
packagedApi._api_app(req, res, next);
|
||||||
});
|
});
|
||||||
// /api/com.example.foo => /api
|
// /api/com.example.foo => /api
|
||||||
route._api.use('/', function (req, res, next) {
|
packagedApi._api.use('/', function (req, res, next) {
|
||||||
req.url = '/api' + req.url.slice(('/api/' + route.api.id).length);
|
req.url = '/api' + req.url.slice(('/api/' + packagedApi.id).length);
|
||||||
//console.log('api mangle 3:', req.url);
|
//console.log('api mangle 3:', req.url);
|
||||||
route._api_app(req, res, next);
|
packagedApi._api_app(req, res, next);
|
||||||
});
|
});
|
||||||
resolve(route._api);
|
resolve(packagedApi._api);
|
||||||
}, reject);
|
}, reject);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadApi(pkgConf, pkgDeps, route) {
|
function loadApi(pkgConf, pkgDeps, packagedApi) {
|
||||||
function handlePromise(p) {
|
function handlePromise(p) {
|
||||||
return p.then(function (api) {
|
return p.then(function (api) {
|
||||||
route._api = api;
|
packagedApi._api = api;
|
||||||
return api;
|
return api;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!route._promise_api) {
|
if (!packagedApi._promise_api) {
|
||||||
route._promise_api = getApi(pkgConf, pkgDeps, route);
|
packagedApi._promise_api = getApi(pkgConf, pkgDeps, packagedApi);
|
||||||
}
|
}
|
||||||
|
|
||||||
return handlePromise(route._promise_api);
|
return handlePromise(packagedApi._promise_api);
|
||||||
}
|
}
|
||||||
|
|
||||||
function layerItUp(pkgConf, router, req, res, next) {
|
function layerItUp(pkgConf, router, req, res, next) {
|
||||||
|
@ -232,42 +232,39 @@ function runApi(opts, router, req, res, next) {
|
||||||
var pkgConf = opts.config;
|
var pkgConf = opts.config;
|
||||||
var pkgDeps = opts.deps;
|
var pkgDeps = opts.deps;
|
||||||
//var Services = opts.Services;
|
//var Services = opts.Services;
|
||||||
var route;
|
var packagedApi;
|
||||||
|
|
||||||
// TODO compile packagesMap
|
// TODO compile packagesMap
|
||||||
// TODO people may want to use the framework in a non-framework way (i.e. to conceal the module name)
|
// TODO people may want to use the framework in a non-framework way (i.e. to conceal the module name)
|
||||||
router.packages.some(function (_route) {
|
router.packagedApis.some(function (_packagedApi) {
|
||||||
if (!_route.api) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var pathname = router.pathname;
|
var pathname = router.pathname;
|
||||||
if ('/' === pathname) {
|
if ('/' === pathname) {
|
||||||
pathname = '';
|
pathname = '';
|
||||||
}
|
}
|
||||||
// TODO allow for special apis that do not follow convention (.well_known, webfinger, oauth3.html, etc)
|
// TODO allow for special apis that do not follow convention (.well_known, webfinger, oauth3.html, etc)
|
||||||
if (!_route._api_re) {
|
if (!_packagedApi._api_re) {
|
||||||
_route._api_re = new RegExp(escapeStringRegexp(pathname + '/api/' + _route.api.id) + '\/([\\w\\.\\-]+)(\\/|\\?|$)');
|
_packagedApi._api_re = new RegExp(escapeStringRegexp(pathname + '/api/' + _packagedApi.id) + '\/([\\w\\.\\-]+)(\\/|\\?|$)');
|
||||||
//console.log('[api re 2]', _route._api_re);
|
//console.log('[api re 2]', _packagedApi._api_re);
|
||||||
}
|
}
|
||||||
if (_route._api_re.test(req.url)) {
|
if (_packagedApi._api_re.test(req.url)) {
|
||||||
route = _route;
|
packagedApi = _packagedApi;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!route) {
|
if (!packagedApi) {
|
||||||
//console.log('[no api route]');
|
console.log("[ODD] no api for '" + req.url + "'");
|
||||||
next();
|
next();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// appId means hash(api.id + host + path) - also called "experience"
|
||||||
Object.defineProperty(req, 'appId', {
|
Object.defineProperty(req, 'appId', {
|
||||||
enumerable: true
|
enumerable: true
|
||||||
, configurable: false
|
, configurable: false
|
||||||
, writable: false
|
, writable: false
|
||||||
// TODO this identifier may need to be non-deterministic as to transfer if a domain name changes but is still the "same" app
|
// TODO this identifier may need to be non-deterministic as to transfer if a domain name changes but is still the "same" app
|
||||||
// (i.e. a company name change. maybe auto vs manual register - just like oauth3?)
|
// (i.e. a company name change. maybe auto vs manual register - just like oauth3?)
|
||||||
, value: route.id
|
, value: packagedApi.domain.id
|
||||||
});
|
});
|
||||||
Object.defineProperty(req, 'appConfig', {
|
Object.defineProperty(req, 'appConfig', {
|
||||||
enumerable: true
|
enumerable: true
|
||||||
|
@ -292,12 +289,13 @@ function runApi(opts, router, req, res, next) {
|
||||||
// TODO freeze objects for passing them into app
|
// TODO freeze objects for passing them into app
|
||||||
//
|
//
|
||||||
|
|
||||||
if (route._api) {
|
if (packagedApi._api) {
|
||||||
route._api(req, res, next);
|
packagedApi._api(req, res, next);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
loadApi(pkgConf, pkgDeps, route).then(function (api) {
|
console.log("pkgpath", pkgConf.apipath, packagedApi.id);
|
||||||
|
loadApi(pkgConf, pkgDeps, packagedApi).then(function (api) {
|
||||||
api(req, res, next);
|
api(req, res, next);
|
||||||
}, function (err) {
|
}, function (err) {
|
||||||
console.error('[App Promise Error]');
|
console.error('[App Promise Error]');
|
||||||
|
|
|
@ -19,54 +19,61 @@ function deserialize(results) {
|
||||||
|
|
||||||
results.domains.forEach(function (domain) {
|
results.domains.forEach(function (domain) {
|
||||||
config.domains[domain.id] = domain;
|
config.domains[domain.id] = domain;
|
||||||
// as it currently stands each of these will only have one
|
|
||||||
/*
|
|
||||||
domain.apis = [];
|
domain.apis = [];
|
||||||
domain.apiIds = [];
|
domain.apiIds = [];
|
||||||
domain.apisMap = {};
|
|
||||||
domain.apps = [];
|
domain.apps = [];
|
||||||
domain.appIds = [];
|
domain.appIds = [];
|
||||||
domain.appsMap = {};
|
//domain.appsMap = null;
|
||||||
*/
|
|
||||||
domain.api = null;
|
|
||||||
domain.apiId = null;
|
|
||||||
domain.app = null;
|
|
||||||
domain.appId = null;
|
|
||||||
domain.appsMap = null;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
results.apisDomains.forEach(function (ad) {
|
results.apisDomains.forEach(function (ad) {
|
||||||
var api = config.apis[ad.apiId];
|
var api = config.apis[ad.apiId];
|
||||||
var domain = config.domains[ad.domainId];
|
var domain = config.domains[ad.domainId];
|
||||||
|
|
||||||
if (api && !api.domainsMap[domain.id]) {
|
if (api && !api.domainsMap[domain.id]) {
|
||||||
api.domainIds.push(domain.id);
|
api.domainIds.push(domain.id);
|
||||||
api.domainsMap[domain.id] = domain;
|
api.domainsMap[domain.id] = domain;
|
||||||
api.domains.push(domain);
|
api.domains.push(domain);
|
||||||
}
|
}
|
||||||
if (domain) {
|
|
||||||
if (domain.api) {
|
if (!domain) {
|
||||||
console.error("[SANITY FAIL] single domain has multiple frontends in db: '" + domain.id + "'");
|
return;
|
||||||
}
|
}
|
||||||
domain.apiId = api.id;
|
|
||||||
domain.api = api;
|
if (!api) {
|
||||||
|
console.error("NO API '" + ad.apiId + "' requested by '" + ad.domainId + "'");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
domain.apiIds.push(api.id);
|
||||||
|
domain.apis.push(api);
|
||||||
});
|
});
|
||||||
|
|
||||||
results.appsDomains.forEach(function (ad) {
|
results.appsDomains.forEach(function (ad) {
|
||||||
var app = config.apps[ad.appId];
|
var app = config.apps[ad.appId];
|
||||||
var domain = config.domains[ad.domainId];
|
var domain = config.domains[ad.domainId];
|
||||||
|
|
||||||
if (app && !app.domainsMap[domain.id]) {
|
if (app && !app.domainsMap[domain.id]) {
|
||||||
app.domainIds.push(domain.id);
|
app.domainIds.push(domain.id);
|
||||||
app.domainsMap[domain.id] = domain;
|
app.domainsMap[domain.id] = domain;
|
||||||
app.domains.push(domain);
|
app.domains.push(domain);
|
||||||
}
|
}
|
||||||
if (domain) {
|
|
||||||
if (domain.app) {
|
if (!domain) {
|
||||||
console.error("[SANITY FAIL] single domain has multiple frontends in db: '" + domain.id + "'");
|
return;
|
||||||
}
|
}
|
||||||
domain.appId = app.id;
|
|
||||||
domain.app = app;
|
if (domain.apps.length > 1) {
|
||||||
|
console.error("[TODO] multiple frontend roots for '" + domain.id + "' cannot be managed by caddy (yet)");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!app) {
|
||||||
|
console.error("NO PAGES '" + ad.appId + "' requested by '" + ad.domainId + "'");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
domain.appIds.push(app.id);
|
||||||
|
domain.apps.push(app);
|
||||||
});
|
});
|
||||||
|
|
||||||
return config;
|
return config;
|
||||||
|
@ -114,11 +121,22 @@ function getVhostsMap(config) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!vhostsMap[domain.hostname].pathnamesMap[domain.pathname]) {
|
if (!vhostsMap[domain.hostname].pathnamesMap[domain.pathname]) {
|
||||||
vhostsMap[domain.hostname].pathnamesMap[domain.pathname] = { pathname: domain.pathname, packages: [] };
|
vhostsMap[domain.hostname].pathnamesMap[domain.pathname] = {
|
||||||
|
pathname: domain.pathname
|
||||||
|
, packagedApis: []
|
||||||
|
, packagedPages: []
|
||||||
|
};
|
||||||
vhostsMap[domain.hostname].pathnames.push(vhostsMap[domain.hostname].pathnamesMap[domain.pathname]);
|
vhostsMap[domain.hostname].pathnames.push(vhostsMap[domain.hostname].pathnamesMap[domain.pathname]);
|
||||||
}
|
}
|
||||||
|
|
||||||
vhostsMap[domain.hostname].pathnamesMap[domain.pathname].packages.push(domain);
|
domain.apis.forEach(function (api) {
|
||||||
|
api.domain = domain;
|
||||||
|
vhostsMap[domain.hostname].pathnamesMap[domain.pathname].packagedApis.push(api);
|
||||||
|
});
|
||||||
|
domain.apps.forEach(function (page) {
|
||||||
|
page.domain = domain;
|
||||||
|
vhostsMap[domain.hostname].pathnamesMap[domain.pathname].packagedPages.push(page);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
return vhostsMap;
|
return vhostsMap;
|
||||||
|
|
Loading…
Reference in New Issue