UNPKG

@fly/edge

Version:
104 lines 13.3 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.buildAppFromConfig = exports.buildCdn = exports.isCdnConfig = exports.isItemConfig = exports.AppConfigKey = void 0; /** @module Config */ const backends_1 = require("./backends"); const util_1 = require("../util"); const rules_1 = require("./rules"); const middleware_1 = require("./middleware"); exports.AppConfigKey = "flyEdge"; function isItemConfig(input) { if (!util_1.isObject(input)) { throw new Error("must be an object"); } if (typeof input.type !== "string" || input.type.length == 0) { throw new Error("must have a type property specifying a backend"); } return true; } exports.isItemConfig = isItemConfig; function isCdnConfig(input) { if (!util_1.isObject(input)) { throw new Error("config must be an object"); } const { backendConfigs = {}, ruleConfigs = [], middlewareConfigs = [] } = input; if (!util_1.isObject(backendConfigs)) { throw new Error("backends property must be a map of keys -> Backend definition"); } for (const [key, cfg] of Object.entries(backendConfigs)) { try { if (isItemConfig(cfg)) { backends_1.validateBackend(cfg); } } catch (error) { throw new Error(`backend config for ${key} is invalid: ${error.message || error}`); } } if (!(ruleConfigs instanceof Array)) { throw new Error("rules property must be an array of Rule definitions"); } for (const [idx, cfg] of ruleConfigs.entries()) { try { rules_1.validateRule(cfg); } catch (error) { throw new Error(`rule at index ${idx} is invalid: ${error.message || error}`); } } if (!(middlewareConfigs instanceof Array)) { throw new Error("middleware property must be an array of Middleware definitions"); } for (const [idx, cfg] of middlewareConfigs.entries()) { try { if (isItemConfig(cfg)) { middleware_1.validateMiddleware(cfg); } } catch (error) { throw new Error(`middleware at index ${idx} is invalid: ${error.message || error}`); } } return true; } exports.isCdnConfig = isCdnConfig; function buildCdn(config) { const backends = new Map(); for (const [key, cfg] of Object.entries(config.backends)) { const b = backends_1.buildBackend(cfg); backends.set(key, b); } console.log("Built backends:", Object.getOwnPropertyNames(config.backends)); let fn = rules_1.buildRules(backends, config.rules); const middleware = config.middleware; if (middleware && middleware.length > 0) { for (let i = middleware.length - 1; i >= 0; i--) { fn = middleware_1.buildMiddleware(fn, middleware[i]); } } return Object.assign(fn, { backends: backends }); } exports.buildCdn = buildCdn; function buildAppFromConfig(c) { try { const config = c || app.config[exports.AppConfigKey] || app.config['flyCDN']; // support flyCDN config key for a while if (!config) { throw new Error("flyApp config property not found"); } if (!isCdnConfig(config)) { // This is unreachable because isCdnConfig throws but typescript can't infer that so we throw too throw new Error("App config not supported"); } return buildCdn(config); } catch (error) { const fn = (...args) => { return Promise.resolve(new Response(`Invalid App Config: ${error.message || error}`)); }; return Object.assign(fn, { backends: new Map() }); } } exports.buildAppFromConfig = buildAppFromConfig; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvY29uZmlnL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLHFCQUFxQjtBQUNyQix5Q0FBMkQ7QUFDM0Qsa0NBQW1DO0FBR25DLG1DQUE2RDtBQUM3RCw2Q0FBbUU7QUFHdEQsUUFBQSxZQUFZLEdBQUcsU0FBUyxDQUFDO0FBZXRDLFNBQWdCLFlBQVksQ0FBQyxLQUFjO0lBQ3pDLElBQUksQ0FBQyxlQUFRLENBQUMsS0FBSyxDQUFDLEVBQUU7UUFDcEIsTUFBTSxJQUFJLEtBQUssQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDO0tBQ3RDO0lBRUQsSUFBSSxPQUFPLEtBQUssQ0FBQyxJQUFJLEtBQUssUUFBUSxJQUFJLEtBQUssQ0FBQyxJQUFJLENBQUMsTUFBTSxJQUFJLENBQUMsRUFBRTtRQUM1RCxNQUFNLElBQUksS0FBSyxDQUFDLGdEQUFnRCxDQUFDLENBQUM7S0FDbkU7SUFFRCxPQUFPLElBQUksQ0FBQTtBQUNiLENBQUM7QUFWRCxvQ0FVQztBQUVELFNBQWdCLFdBQVcsQ0FBQyxLQUFjO0lBQ3hDLElBQUksQ0FBQyxlQUFRLENBQUMsS0FBSyxDQUFDLEVBQUU7UUFDcEIsTUFBTSxJQUFJLEtBQUssQ0FBQywwQkFBMEIsQ0FBQyxDQUFBO0tBQzVDO0lBRUQsTUFBTSxFQUFFLGNBQWMsR0FBRyxFQUFHLEVBQUUsV0FBVyxHQUFHLEVBQUUsRUFBRSxpQkFBaUIsR0FBRyxFQUFFLEVBQUUsR0FBRyxLQUFLLENBQUM7SUFFakYsSUFBSSxDQUFDLGVBQVEsQ0FBQyxjQUFjLENBQUMsRUFBRTtRQUM3QixNQUFNLElBQUksS0FBSyxDQUFDLCtEQUErRCxDQUFDLENBQUM7S0FDbEY7SUFFRCxLQUFLLE1BQU0sQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLElBQUksTUFBTSxDQUFDLE9BQU8sQ0FBQyxjQUFjLENBQUMsRUFBRTtRQUN2RCxJQUFJO1lBQ0YsSUFB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b0JBQVksQ0FBQyxJQUFJLEdBQUcsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyx3Q0FBd0M7UUFDOUcsSUFBSSxDQUFDLE1BQU0sRUFBRTtZQUNYLE1BQU0sSUFBSSxLQUFLLENBQUMsa0NBQWtDLENBQUMsQ0FBQztTQUNyRDtRQUNELElBQUksQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLEVBQUU7WUFDeEIsaUdBQWlHO1lBQ2pHLE1BQU0sSUFBSSxLQUFLLENBQUMsMEJBQTBCLENBQUMsQ0FBQztTQUM3QztRQUNELE9BQU8sUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFBO0tBQ3hCO0lBQUMsT0FBTyxLQUFLLEVBQUU7UUFDZCxNQUFNLEVBQUUsR0FBRyxDQUFDLEdBQUcsSUFBVyxFQUFFLEVBQUU7WUFDNUIsT0FBTyxPQUFPLENBQUMsT0FBTyxDQUFDLElBQUksUUFBUSxDQUFDLHVCQUF1QixLQUFLLENBQUMsT0FBTyxJQUFJLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQztRQUN4RixDQUFDLENBQUE7UUFDRCxPQUFPLE1BQU0sQ0FBQyxNQUFNLENBQUMsRUFBRSxFQUFFLEVBQUUsUUFBUSxFQUFFLElBQUksR0FBRyxFQUF5QixFQUFDLENBQUMsQ0FBQTtLQUN4RTtBQUNILENBQUM7QUFqQkQsZ0RBaUJDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqIEBtb2R1bGUgQ29uZmlnICovXG5pbXBvcnQgeyB2YWxpZGF0ZUJhY2tlbmQsIGJ1aWxkQmFja2VuZCB9IGZyb20gXCIuL2JhY2tlbmRzXCI7XG5pbXBvcnQgeyBpc09iamVjdCB9IGZyb20gXCIuLi91dGlsXCI7XG5pbXBvcnQgeyBGZXRjaEZ1bmN0aW9uIH0gZnJvbSBcIi4uL2ZldGNoXCI7XG5pbXBvcnQgeyBQcm94eUZ1bmN0aW9uIH0gZnJvbSBcIi4uL3Byb3h5XCI7XG5pbXBvcnQgeyBSdWxlSW5mbywgdmFsaWRhdGVSdWxlLCBidWlsZFJ1bGVzIH0gZnJvbSBcIi4vcnVsZXNcIjtcbmltcG9ydCB7IGJ1aWxkTWlkZGxld2FyZSwgdmFsaWRhdGVNaWRkbGV3YXJlIH0gZnJvbSBcIi4vbWlkZGxld2FyZVwiO1xuaW1wb3J0IHsgc3RyaW5naWZ5IH0gZnJvbSBcInF1ZXJ5c3RyaW5nXCI7XG5cbmV4cG9ydCBjb25zdCBBcHBDb25maWdLZXkgPSBcImZseUVkZ2VcIjtcblxuZXhwb3J0IGludGVyZmFjZSBDZG5Db25maWcge1xuICBiYWNrZW5kczogeyBba2V5OiBzdHJpbmddOiBJdGVtQ29uZmlnIH0sXG4gIG1pZGRsZXdhcmU6IEl0ZW1Db25maWdbXSxcbiAgcnVsZXM6IFJ1bGVJbmZvW11cbn1cblxuZXhwb3J0IGludGVyZmFjZSBJdGVtQ29uZmlnIHtcbiAgdHlwZTogc3RyaW5nO1xuICBbcHJvcDogc3RyaW5nXTogdW5rbm93bjtcbn1cblxuZXhwb3J0IHR5cGUgQmFja2VuZFByb3hpZXMgPSBNYXA8c3RyaW5nLCBQcm94eUZ1bmN0aW9uPjtcblxuZXhwb3J0IGZ1bmN0aW9uIGlzSXRlbUNvbmZpZyhpbnB1dDogdW5rbm93bik6IGlucHV0IGlzIEl0ZW1Db25maWcge1xuICBpZiAoIWlzT2JqZWN0KGlucHV0KSkge1xuICAgIHRocm93IG5ldyBFcnJvcihcIm11c3QgYmUgYW4gb2JqZWN0XCIpO1xuICB9XG5cbiAgaWYgKHR5cGVvZiBpbnB1dC50eXBlICE9PSBcInN0cmluZ1wiIHx8IGlucHV0LnR5cGUubGVuZ3RoID09IDApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJtdXN0IGhhdmUgYSB0eXBlIHByb3BlcnR5IHNwZWNpZnlpbmcgYSBiYWNrZW5kXCIpO1xuICB9XG5cbiAgcmV0dXJuIHRydWVcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzQ2RuQ29uZmlnKGlucHV0OiB1bmtub3duKTogaW5wdXQgaXMgQ2RuQ29uZmlnIHtcbiAgaWYgKCFpc09iamVjdChpbnB1dCkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJjb25maWcgbXVzdCBiZSBhbiBvYmplY3RcIilcbiAgfVxuXG4gIGNvbnN0IHsgYmFja2VuZENvbmZpZ3MgPSB7IH0sIHJ1bGVDb25maWdzID0gW10sIG1pZGRsZXdhcmVDb25maWdzID0gW10gfSA9IGlucHV0O1xuXG4gIGlmICghaXNPYmplY3QoYmFja2VuZENvbmZpZ3MpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiYmFja2VuZHMgcHJvcGVydHkgbXVzdCBiZSBhIG1hcCBvZiBrZXlzIC0+IEJhY2tlbmQgZGVmaW5pdGlvblwiKTtcbiAgfVxuXG4gIGZvciAoY29uc3QgW2tleSwgY2ZnXSBvZiBPYmplY3QuZW50cmllcyhiYWNrZW5kQ29uZmlncykpIHtcbiAgICB0cnkge1xuICAgICAgaWYgKGlzSXRlbUNvbmZpZyhjZmcpKSB7XG4gICAgICAgIHZhbGlkYXRlQmFja2VuZChjZmcpO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYGJhY2tlbmQgY29uZmlnIGZvciAke2tleX0gaXMgaW52YWxpZDogJHtlcnJvci5tZXNzYWdlIHx8IGVycm9yfWApXG4gICAgfVxuICB9XG5cbiAgaWYgKCEocnVsZUNvbmZpZ3MgaW5zdGFuY2VvZiBBcnJheSkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJydWxlcyBwcm9wZXJ0eSBtdXN0IGJlIGFuIGFycmF5IG9mIFJ1bGUgZGVmaW5pdGlvbnNcIik7XG4gIH1cblxuICBmb3IgKGNvbnN0IFtpZHgsIGNmZ10gb2YgcnVsZUNvbmZpZ3MuZW50cmllcygpKSB7XG4gICAgdHJ5IHtcbiAgICAgIHZhbGlkYXRlUnVsZShjZmcpXG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgcnVsZSBhdCBpbmRleCAke2lkeH0gaXMgaW52YWxpZDogJHtlcnJvci5tZXNzYWdlIHx8IGVycm9yfWApXG4gICAgfVxuICB9XG5cbiAgaWYgKCEobWlkZGxld2FyZUNvbmZpZ3MgaW5zdGFuY2VvZiBBcnJheSkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJtaWRkbGV3YXJlIHByb3BlcnR5IG11c3QgYmUgYW4gYXJyYXkgb2YgTWlkZGxld2FyZSBkZWZpbml0aW9uc1wiKTtcbiAgfVxuXG4gIGZvciAoY29uc3QgW2lkeCwgY2ZnXSBvZiBtaWRkbGV3YXJlQ29uZmlncy5lbnRyaWVzKCkpIHtcbiAgICB0cnkge1xuICAgICAgaWYgKGlzSXRlbUNvbmZpZyhjZmcpKSB7XG4gICAgICAgIHZhbGlkYXRlTWlkZGxld2FyZShjZmcpO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYG1pZGRsZXdhcmUgYXQgaW5kZXggJHtpZHh9IGlzIGludmFsaWQ6ICR7ZXJyb3IubWVzc2FnZSB8fCBlcnJvcn1gKVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gYnVpbGRDZG4oY29uZmlnOiBDZG5Db25maWcpIHtcbiAgY29uc3QgYmFja2VuZHMgPSBuZXcgTWFwPHN0cmluZywgUHJveHlGdW5jdGlvbj4oKTtcblxuICBmb3IgKGNvbnN0IFtrZXksIGNmZ10gb2YgT2JqZWN0LmVudHJpZXMoY29uZmlnLmJhY2tlbmRzKSkge1xuICAgIGNvbnN0IGIgPSBidWlsZEJhY2tlbmQoY2ZnKTtcbiAgICBiYWNrZW5kcy5zZXQoa2V5LCBiKTtcbiAgfVxuICBjb25zb2xlLmxvZyhcIkJ1aWx0IGJhY2tlbmRzOlwiLCBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyhjb25maWcuYmFja2VuZHMpKTtcblxuICBsZXQgZm4gPSBidWlsZFJ1bGVzKGJhY2tlbmRzLCBjb25maWcucnVsZXMpXG4gIFxuICBjb25zdCBtaWRkbGV3YXJlID0gY29uZmlnLm1pZGRsZXdhcmU7XG4gIGlmIChtaWRkbGV3YXJlICYmIG1pZGRsZXdhcmUubGVuZ3RoID4gMCkge1xuICAgIGZvciAobGV0IGkgPSBtaWRkbGV3YXJlLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICBmbiA9IGJ1aWxkTWlkZGxld2FyZShmbiwgbWlkZGxld2FyZVtpXSk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIE9iamVjdC5hc3NpZ24oZm4sIHtcbiAgICBiYWNrZW5kczogYmFja2VuZHNcbiAgfSlcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGJ1aWxkQXBwRnJvbUNvbmZpZyhjPzogYW55KSB7XG4gIHRyeSB7XG4gICAgY29uc3QgY29uZmlnID0gYyB8fCBhcHAuY29uZmlnW0FwcENvbmZpZ0tleV0gfHwgYXBwLmNvbmZpZ1snZmx5Q0ROJ107IC8vIHN1cHBvcnQgZmx5Q0ROIGNvbmZpZyBrZXkgZm9yIGEgd2hpbGVcbiAgICBpZiAoIWNvbmZpZykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiZmx5QXBwIGNvbmZpZyBwcm9wZXJ0eSBub3QgZm91bmRcIik7XG4gICAgfVxuICAgIGlmICghaXNDZG5Db25maWcoY29uZmlnKSkge1xuICAgICAgLy8gVGhpcyBpcyB1bnJlYWNoYWJsZSBiZWNhdXNlIGlzQ2RuQ29uZmlnIHRocm93cyBidXQgdHlwZXNjcmlwdCBjYW4ndCBpbmZlciB0aGF0IHNvIHdlIHRocm93IHRvb1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQXBwIGNvbmZpZyBub3Qgc3VwcG9ydGVkXCIpO1xuICAgIH1cbiAgICByZXR1cm4gYnVpbGRDZG4oY29uZmlnKVxuICB9IGNhdGNoIChlcnJvcikge1xuICAgIGNvbnN0IGZuID0gKC4uLmFyZ3M6IGFueVtdKSA9PiB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKG5ldyBSZXNwb25zZShgSW52YWxpZCBBcHAgQ29uZmlnOiAke2Vycm9yLm1lc3NhZ2UgfHwgZXJyb3J9YCkpO1xuICAgIH1cbiAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihmbiwgeyBiYWNrZW5kczogbmV3IE1hcDxzdHJpbmcsIFByb3h5RnVuY3Rpb24+KCl9KVxuICB9XG59XG4iXX0=