diff --git a/src/connection.js b/src/connection.js index 2216456..ed61f6b 100644 --- a/src/connection.js +++ b/src/connection.js @@ -8,7 +8,7 @@ const AuthProvider = require('./authprovider'); const BasicProvider = require('./basicprovider'); const OidcProvider = require('./oidcprovider'); -const Capabilities = require('./capabilities'); +const { GdcCapabilities } = require('./gdc'); const FileTypes = require('./filetypes'); const UserFile = require('./userfile'); const Job = require('./job'); @@ -18,6 +18,7 @@ const Service = require('./service'); const Builder = require('./builder/builder'); const BuilderNode = require('./builder/node'); + const CONFORMANCE_RELS = [ 'conformance', 'http://www.opengis.net/def/rel/ogc/1.0/conformance' @@ -119,7 +120,7 @@ class Connection { } } - this.capabilitiesObject = new Capabilities(data); + this.capabilitiesObject = new GdcCapabilities(data); return this.capabilitiesObject; } diff --git a/src/gdc.js b/src/gdc.js new file mode 100644 index 0000000..7d4a749 --- /dev/null +++ b/src/gdc.js @@ -0,0 +1,179 @@ +const Capabilities = require("./capabilities"); +const Utils = require('@openeo/js-commons/src/utils'); +const StacMigrate = require('@radiantearth/stac-migrate'); + +class GdcCapabilities extends Capabilities { + + constructor(data) { + super(data); + this.checkConformance(); + } + + hasConformance(uri) { + if(!Array.isArray(this.data.conformsTo)) { + return false; + } + return this.data.conformsTo.includes(uri); + } + + checkConformance() { + if (!Array.isArray(this.data.endpoints)) { + this.data.endpoints = []; + } + if (this.hasConformance('http://www.opengis.net/spec/ogcapi-coverages-1/0.0/conf/geodata-coverage')) { + this.data.endpoints.push({ + "path": "/collections", + "methods": [ + "GET" + ] + }); + this.data.endpoints.push({ + "path": "/collections/{collection_id}", + "methods": [ + "GET" + ] + }); + } + if (this.hasConformance('http://www.opengis.net/spec/ogcapi-processes-1/1.0/conf/core')) { + this.data.endpoints.push({ + "path": "/processes", + "methods": [ + "GET" + ] + }); + } + this.init(); + } + + /** + * Initializes the class. + * + * @protected + */ + init() { + if (Array.isArray(this.data.endpoints)) { + super.init(); + } + } + + /** + * Validates the capabilities. + * + * Throws an error in case of an issue, otherwise just passes. + * + * @protected + * @throws {Error} + */ + validate() { + if(!Utils.isObject(this.data)) { + throw new Error("No capabilities retrieved."); + } + } + + /** + * Returns the GDC API version implemented by the back-end. + * + * @returns {string} openEO API version number. + */ + apiVersion() { + return "1.0.0"; // this.data.gdc_version; + } + + isEndpoint(options, method, endpoint) { + if (options.method !== method) { + return false; + } + if (endpoint.includes('{}')) { + let pattern = '^' + endpoint.replace('{}', '[^/]+') + '$'; + let regex = new RegExp(pattern); + return regex.test(options.url); + } + return endpoint === options.url; + } + + /** + * Migrates a response, if required. + * + * @param {AxiosResponse} response + * @param {object.} options + * @protected + * @returns {AxiosResponse} + */ + migrate(response, options) { // eslint-disable-line no-unused-vars + if (this.isEndpoint(options, 'get', '/collections')) { + response.data.collections = response.data.collections.map(collection => Migrate.collection(collection)); + } + if (this.isEndpoint(options, 'get', '/collections/{}')) { + response.data = Migrate.collection(response.data); + } + if (this.isEndpoint(options, 'get', '/processes')) { + response.data.processes = response.data.processes.map(process => Migrate.process(process)); + } + + return response; + } +} + +const Migrate = { + + collection(collection) { + if (collection.stac_version) { + return collection; + } + + // Make sure the required properties are present + collection = StacMigrate.collection(collection); + + return collection; + }, + + process(process) { + if (process.parameters || process.returns) { + return process; + } + + process.summary = process.title; + + process.parameters = []; + for(let name in process.inputs) { + let input = process.inputs[name]; + process.parameters.push({ + name, + description: `**${input.title}**\n\n${input.description}`, + schema: input.schema, + optional: typeof input.schema.default !== 'undefined' + }); + } + + process.returns = { + description: 'see process description', + schema: [] + }; + if (Utils.size(process.outputs) === 1) { + let output = Object.values(process.outputs)[0]; + process.returns = { + description: `**${output.title}**\n\n${output.description}`, + schema: output.schema + }; + } + else { + process.returns = { + description: 'see process description', + schema: [] + }; + for(let name in process.outputs) { + let output = process.outputs[name]; + let schema = Object.assign({}, output.schema, {title: output.title, description: output.description}); + process.returns.schema.push(schema); + } + } + + return process; + } + +}; + +module.exports = { + GdcCapabilities, + Migrate +}; \ No newline at end of file