| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| 'use strict' |
| |
| const BaseOperation = require('./base_operation') |
| const messages = require('./messages') |
| const names = require('./names') |
| const CREATE_PARAMS = ['relpath', 'operation', 'action'] |
| |
| class Routes extends BaseOperation { |
| constructor (client, routeApiPathMapper) { |
| super(client) |
| if (typeof routeApiPathMapper === 'function') { |
| this.routeApiPathMapper = routeApiPathMapper |
| } else if (routeApiPathMapper) { |
| throw new Error('Illegal parameter, must be a function.') |
| } |
| } |
| |
| routeMgmtApiPath (path) { |
| if (this.routeApiPathMapper) { |
| return this.routeApiPathMapper(path) |
| } else { |
| return `web/whisk.system/apimgmt/${path}` |
| } |
| } |
| |
| get (options) { |
| options = options || {} |
| options.basepath = this.basepath(options) |
| |
| return this.list(this.qs(options, ['basepath'])) |
| } |
| |
| list (options) { |
| options = options || {} |
| if (this.hasBasepath(options)) { |
| options.basepath = this.calculateBasepath(options) |
| } |
| |
| const qs = this.qs(options, ['relpath', 'basepath', 'operation', 'limit', 'skip']) |
| return this.client.request('GET', this.routeMgmtApiPath('getApi'), { qs }) |
| } |
| |
| qs (options, names) { |
| const result = super.qs(options, names) |
| |
| if (this.hasAccessToken()) { |
| result.accesstoken = this.client.options.apigwToken |
| result.spaceguid = this.client.options.apigwSpaceGuid |
| } |
| |
| return result |
| } |
| |
| hasBasepath (options) { |
| return !!(options.name || options.basepath) |
| } |
| |
| basepath (options) { |
| if (!this.hasBasepath(options)) { |
| throw new Error(messages.MISSING_BASEPATH_ERROR) |
| } |
| |
| return this.calculateBasepath(options) |
| } |
| |
| calculateBasepath (options) { |
| if (options.name && options.basepath) { |
| throw new Error(messages.INVALID_BASEPATH_ERROR) |
| } |
| |
| return options.basepath || options.name |
| } |
| |
| missingBasepath (options) { |
| return !(options.name || options.basepath) |
| } |
| |
| delete (options) { |
| options = options || {} |
| options.basepath = this.basepath(options) |
| |
| const qs = this.qs(options, ['relpath', 'basepath', 'operation']) |
| qs.force = true |
| return this.client.request('DELETE', this.routeMgmtApiPath('deleteApi'), { qs }) |
| } |
| |
| create (options) { |
| const body = this.createBody(options || {}) |
| const qs = this.qs(options, ['responsetype']) |
| return this.client.request('POST', this.routeMgmtApiPath('createApi'), { body, qs }) |
| } |
| |
| createBody (options) { |
| if (options.swagger) { |
| return { apidoc: { namespace: '_', swagger: options.swagger } } |
| } |
| |
| const missing = CREATE_PARAMS.filter(param => !(options || {}).hasOwnProperty(param)) |
| |
| if (missing.length) { |
| throw new Error(`Missing mandatory parameters: ${missing.join(', ')}`) |
| } |
| |
| return this.routeSwaggerDefinition(options) |
| } |
| |
| routeSwaggerDefinition (params) { |
| const apidoc = { |
| namespace: '_', |
| gatewayBasePath: this.routeBasepath(params), |
| gatewayPath: params.relpath, |
| gatewayMethod: params.operation, |
| id: `API:_:${this.routeBasepath(params)}`, |
| action: this.routeSwaggerAction(params) |
| } |
| |
| const pathParameters = this.parsePathParameters(params.relpath) |
| |
| if (pathParameters.length) { |
| apidoc.pathParameters = pathParameters.map(this.createPathParameter) |
| } |
| |
| if (params.name) { |
| apidoc.apiName = params.name |
| } |
| |
| return { apidoc } |
| } |
| |
| routeSwaggerAction (params) { |
| const id = names.parseId(params.action) |
| let namespace = decodeURIComponent(this.namespace(params)) |
| if (params.action.startsWith('/')) { |
| namespace = names.parseNamespace(params.action) |
| } |
| |
| const body = { |
| name: id, |
| namespace: namespace, |
| backendMethod: `GET`, |
| backendUrl: this.actionUrlPath(id, namespace), |
| authkey: this.client.options.apiKey |
| } |
| |
| if (params.secure_key) { |
| body.secureKey = params.secure_key |
| } |
| |
| return body |
| } |
| |
| routeBasepath (params) { |
| return params.basepath || '/' |
| } |
| |
| actionUrlPath (id, namespace) { |
| // web action path must contain package identifier. uses default for |
| // non-explicit package. |
| if (!id.includes('/')) { |
| id = `default/${id}` |
| } |
| |
| return this.client.pathUrl(`web/${namespace}/${id}.http`) |
| } |
| |
| hasAccessToken () { |
| return !!this.client.options.apigwToken |
| } |
| |
| // return list of path parameters from paths |
| // e.g. /book/{id} |
| // Multiple parameters are supported. |
| parsePathParameters (path) { |
| const regex = /{([^}]+)\}/g |
| const findAllParams = p => { |
| const ids = [] |
| let id = regex.exec(p) |
| while (id) { |
| ids.push(id[1]) |
| id = regex.exec(p) |
| } |
| return ids |
| } |
| |
| return path.split('/') |
| .map(findAllParams) |
| .reduce((sum, el) => sum.concat(el), []) |
| } |
| |
| createPathParameter (name) { |
| return { |
| name: name, |
| in: 'path', |
| description: `Default description for '${name}'`, |
| required: true, |
| type: 'string' |
| } |
| } |
| } |
| |
| module.exports = Routes |