'use strict'; var getDomainInfo = require('../lib/utils').getDomainInfo; function deserialize(results) { var config = { apis: {}, apps: {}, domains: {} }; results.apis.forEach(function (api) { config.apis[api.id] = api; api.domains = []; api.domainIds = []; api.domainsMap = {}; }); results.apps.forEach(function (app) { config.apps[app.id] = app; app.domains = []; app.domainIds = []; app.domainsMap = {}; }); results.domains.forEach(function (domain) { config.domains[domain.id] = domain; domain.apis = []; domain.apiIds = []; domain.apps = []; domain.appIds = []; //domain.appsMap = null; }); results.apisDomains.forEach(function (ad) { var api = config.apis[ad.apiId]; var domain = config.domains[ad.domainId]; if (api && !api.domainsMap[domain.id]) { api.domainIds.push(domain.id); api.domainsMap[domain.id] = domain; api.domains.push(domain); } if (!domain) { return; } 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) { var app = config.apps[ad.appId]; var domain = config.domains[ad.domainId]; if (app && !app.domainsMap[domain.id]) { app.domainIds.push(domain.id); app.domainsMap[domain.id] = domain; app.domains.push(domain); } if (!domain) { return; } 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; } function sortApps(a, b) { // hlen isn't important in this current use of the sorter, // but is important for an alternate version var hlen = b.hostname.length - a.hostname.length; var plen = b.pathname.length - a.pathname.length; // A directory could be named example.com, example.com# example.com## // to indicate order of preference (for API addons, for example) var dlen = (b.priority || b.dirname.length) - (a.priority || a.dirname.length); if (!hlen) { if (!plen) { return dlen; } return plen; } return hlen; } function getVhostsMap(config) { var vhosts = []; var vhostsMap = {}; Object.keys(config.domains).forEach(function (domainname) { var domain = config.domains[domainname]; var info = getDomainInfo(domainname); domain.hostname = info.hostname; domain.pathname = '/' + (info.pathname || ''); domain.dirname = info.dirname; vhosts.push(domain); }); vhosts.sort(sortApps); vhosts.forEach(function (domain) { if (!vhostsMap[domain.hostname]) { vhostsMap[domain.hostname] = { hostname: domain.hostname, id: domain.id, pathnamesMap: {}, pathnames: [] }; } if (!vhostsMap[domain.hostname].pathnamesMap[domain.pathname]) { vhostsMap[domain.hostname].pathnamesMap[domain.pathname] = { pathname: domain.pathname , packagedApis: [] , packagedPages: [] }; vhostsMap[domain.hostname].pathnames.push(vhostsMap[domain.hostname].pathnamesMap[domain.pathname]); } 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; } module.exports.deserialize = deserialize; module.exports.getVhostsMap = getVhostsMap; module.exports.create = function (db) { var wrap = require('masterquest-sqlite3'); var dir = [ // // Collections // { tablename: 'apis' , idname: 'id' // com.example , unique: ['id'] // name // LDS Account, Radio , indices: ['createdAt', 'updatedAt', 'deletedAt', 'revokedAt', 'name'] } , { tablename: 'apps' , idname: 'id' // com.example , unique: ['id'] , indices: ['createdAt', 'updatedAt', 'deletedAt', 'revokedAt', 'name'] } , { tablename: 'domains' , idname: 'id' // api.coolaj86.com#radio , unique: ['id'] , indices: ['createdAt', 'updatedAt', 'deletedAt', 'revokedAt', 'name', 'token', 'accountId'] } // // Joins // , { tablename: 'apis_domains' , idname: 'id' // hash(api_id + domain_id) , unique: ['id'] , indices: ['createdAt', 'updatedAt', 'deletedAt', 'apiId', 'domainId'] // TODO auto-form relations , hasMany: ['apis', 'domains'] } , { tablename: 'apps_domains' , idname: 'id' // hash(domain_id + app_id) , unique: ['id'] , indices: ['createdAt', 'updatedAt', 'deletedAt', 'appId', 'domainId'] // TODO auto-form relations , hasMany: ['apps', 'domains'] } /* , { tablename: 'accounts_apis' , idname: 'id' // hash(account_id + api_id) , unique: ['id'] , indices: ['createdAt', 'updatedAt', 'deletedAt', 'accountId', 'apiId'] // TODO auto-form relations , hasMany: ['accounts', 'apis'] } , { tablename: 'accounts_domains' , idname: 'id' // hash(account_id + domain_id) , unique: ['id'] , indices: ['createdAt', 'updatedAt', 'deletedAt', 'accountId', 'domainId'] // TODO auto-form relations , hasMany: ['accounts', 'domains'] } , { tablename: 'accounts_apps' , idname: 'id' // hash(account_id + static_id) , unique: ['id'] , indices: ['createdAt', 'updatedAt', 'deletedAt', 'accountId', 'staticId'] // TODO auto-form relations , hasMany: ['accounts', 'apps'] } */ ]; return wrap.wrap(db, dir).then(function (models) { models.Config = { get: function () { var PromiseA = require('bluebird'); return PromiseA.all([ models.Apis.find(null, { limit: 10000 }) , models.Apps.find(null, { limit: 10000 }) , models.Domains.find(null, { limit: 10000 }) , models.ApisDomains.find(null, { limit: 10000 }) , models.AppsDomains.find(null, { limit: 10000 }) ]).then(function (args) { var results = { apis: args[0] , apps: args[1] , domains: args[2] , apisDomains: args[3] , appsDomains: args[4] }; // create fixture with which to test // console.log(JSON.stringify(results)); return getVhostsMap(deserialize(results)); }); } }; return models; }); };