"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.UrlPatternMatcher = void 0; var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _lodash = _interopRequireDefault(require("lodash")); var _2 = require("."); var _full_request_component = require("./full_request_component"); /* * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one * or more contributor license agreements. Licensed under the Elastic License * 2.0 and the Server Side Public License, v 1; you may not use this file except * in compliance with, at your election, the Elastic License 2.0 or the Server * Side Public License, v 1. */ /** * @param parametrizedComponentFactories a dict of the following structure * that will be used as a fall back for pattern parameters (i.e.: {index}) * { * indices: function (part, parent) { * return new SharedComponent(part, parent) * } * } * @constructor */ class UrlPatternMatcher { // This is not really a component, just a handy container to make iteration logic simpler constructor(parametrizedComponentFactories) { (0, _defineProperty2.default)(this, "getTopLevelComponents", function (method) { const methodRoot = this[method]; if (!methodRoot) { return []; } return methodRoot.rootComponent.next; }); // We'll group endpoints by the methods which are attached to them, //to avoid suggesting endpoints that are incompatible with the //method that the user has entered. ['HEAD', 'GET', 'PUT', 'POST', 'DELETE'].forEach(method => { this[method] = { rootComponent: new _2.SharedComponent('ROOT'), parametrizedComponentFactories: parametrizedComponentFactories || { getComponent: () => {} } }; }); } addEndpoint(pattern, endpoint) { endpoint.methods.forEach(method => { let c; let activeComponent = this[method].rootComponent; if (endpoint.template) { new _full_request_component.FullRequestComponent(pattern + '[body]', activeComponent, endpoint.template); } const endpointComponents = endpoint.url_components || {}; const partList = pattern.split('/'); _lodash.default.each(partList, (part, partIndex) => { if (part.search(/^{.+}$/) >= 0) { part = part.substr(1, part.length - 2); if (activeComponent.getComponent(part)) { // we already have something for this, reuse activeComponent = activeComponent.getComponent(part); return; } // a new path, resolve. if (c = endpointComponents[part]) { // endpoint specific. Support list if (Array.isArray(c)) { c = new _2.ListComponent(part, c, activeComponent); } else if (_lodash.default.isObject(c) && c.type === 'list') { c = new _2.ListComponent(part, c.list, activeComponent, c.multiValued, c.allow_non_valid); } else { console.warn('incorrectly configured url component ', part, ' in endpoint', endpoint); c = new _2.SharedComponent(part); } } else if (c = this[method].parametrizedComponentFactories.getComponent(part)) { // c is a f c = c(part, activeComponent); } else { // just accept whatever with not suggestions c = new _2.SimpleParamComponent(part, activeComponent); } activeComponent = c; } else { // not pattern let lookAhead = part; let s; for (partIndex++; partIndex < partList.length; partIndex++) { s = partList[partIndex]; if (s.indexOf('{') >= 0) { break; } lookAhead += '/' + s; } if (activeComponent.getComponent(part)) { // we already have something for this, reuse activeComponent = activeComponent.getComponent(part); activeComponent.addOption(lookAhead); } else { c = new _2.ConstantComponent(part, activeComponent, lookAhead); activeComponent = c; } } }); // mark end of endpoint path new _2.AcceptEndpointComponent(endpoint, activeComponent); }); } } exports.UrlPatternMatcher = UrlPatternMatcher;