New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@openeo/js-commons

Package Overview
Dependencies
Maintainers
1
Versions
27
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@openeo/js-commons - npm Package Compare versions

Comparing version 0.4.0-beta.2 to 0.4.0

dist/main.min.js

1885

dist/main.js

@@ -1,1 +0,1884 @@

!function(e,t){if("object"==typeof exports&&"object"==typeof module)module.exports=t(require("ajv"));else if("function"==typeof define&&define.amd)define(["ajv"],t);else{var r="object"==typeof exports?t(require("ajv")):t(e.ajv);for(var s in r)("object"==typeof exports?exports:e)[s]=r[s]}}(window,function(e){return function(e){var t={};function r(s){if(t[s])return t[s].exports;var a=t[s]={i:s,l:!1,exports:{}};return e[s].call(a.exports,a,a.exports,r),a.l=!0,a.exports}return r.m=e,r.c=t,r.d=function(e,t,s){r.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:s})},r.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var s=Object.create(null);if(r.r(s),Object.defineProperty(s,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var a in e)r.d(s,a,function(t){return e[t]}.bind(null,a));return s},r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,"a",t),t},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r.p="",r(r.s=7)}([function(e,t,r){const s=r(9);var a={compareVersion(e,t){try{return s(e,t)}catch(e){return null}},isObject:e=>"object"==typeof e&&e===Object(e)&&!Array.isArray(e),size:e=>"object"==typeof e&&null!==e?Array.isArray(e)?e.length:Object.keys(e).length:0,replacePlaceholders(e,t={}){if("string"==typeof e&&this.isObject(t))for(var r in t)e=e.replace("{"+r+"}",t[r]);return e},mergeDeep(e,...t){if(!t.length)return e;const r=t.shift();if(this.isObject(e)&&this.isObject(r))for(const t in r)this.isObject(r[t])?(e[t]||(e[t]={}),this.mergeDeep(e[t],r[t])):e[t]=r[t];return this.mergeDeep(e,...t)}};e.exports=a},function(e,t,r){const s=r(0),a={MultipleResultNodes:"Multiple result nodes specified for process graph.",StartNodeMissing:"No start nodes found for process graph.",ResultNodeMissing:"No result node found for process graph.",MultipleResultNodesCallback:"Multiple result nodes specified for the callback in the process '{process_id}' (node: '{node_id}').",StartNodeMissingCallback:"No start nodes found for the callback in the process '{process_id}' (node: '{node_id}')'.",ResultNodeMissingCallback:"No result node found for the callback in the process '{process_id}' (node: '{node_id}').",ReferencedNodeMissing:"Referenced node '{node_id}' doesn't exist.",NodeIdInvalid:"Invalid node id specified in process graph.",NodeInvalid:"Process graph node '{node_id}' is not a valid object.",ProcessIdMissing:"Process graph node '{node_id}' doesn't contain a process id.",CallbackArgumentInvalid:"Invalid callback argument '{argument}' requested in the process '{process_id}' (node: '{node_id}').",ProcessUnsupported:"Process '{process}' is not supported.",ProcessArgumentUnsupported:"Process '{process}' does not support argument '{argument}'.",ProcessArgumentRequired:"Process '{process}' requires argument '{argument}'.",ProcessArgumentInvalid:"The argument '{argument}' in process '{process}' is invalid: {reason}",VariableValueMissing:"No value specified for process graph variable '{variable_id}'.",VariableDefaultValueTypeInvalid:"The default value specified for the process graph variable '{variable_id}' is not of type '{type}'.",VariableValueTypeInvalid:"The value specified for the process graph variable '{variable_id}' is not of type '{type}'.",VariableIdInvalid:"A specified variable ID is not valid.",VariableTypeInvalid:"The data type specified for the process graph variable '{variable_id}' is invalid. Must be one of: string, boolean, number, array or object."};e.exports=class extends Error{constructor(e,t={}){super(),this.code=e,this.variables=t,"string"==typeof a[e]&&(this.message=s.replacePlaceholders(a[e],t))}toJSON(){return{code:this.code,message:this.message}}}},function(e,t,r){const s=r(1),a=r(0);e.exports=class e{constructor(e,t,r){if("string"!=typeof t||0===t.length)throw new s("NodeIdInvalid");if(!a.isObject(e))throw new s("NodeInvalid",{node_id:t});if("string"!=typeof e.process_id)throw new s("ProcessIdMissing",{node_id:t});this.id=t,this.processGraph=r,this.process_id=e.process_id,this.arguments=e.arguments||{},this.isResultNode=e.result||!1,this.expectsFrom=[],this.passesTo=[],this.result=null,this.resultsAvailableFrom=[]}getProcessGraph(){return this.processGraph}getArgumentNames(){return Object.keys(this.arguments)}hasArgument(e){return e in this.arguments}getArgumentType(t){return e.getType(this.arguments[t])}getRawArgument(e){return this.arguments[e]}getRawArgumentValue(t){var r=this.arguments[t];switch(e.getType(r)){case"result":return r.from_node;case"callback":return r.callback;case"callback-argument":return r.from_argument;default:return r}}getArgument(e,t){return void 0===this.arguments[e]?t:this.processArgument(this.arguments[e])}processArgument(t){switch(e.getType(t)){case"result":return this.processGraph.getNode(t.from_node).getResult();case"callback":return t.callback;case"callback-argument":return this.processGraph.getParameter(t.from_argument);case"variable":return this.processGraph.getVariableValue(t.variable_id);case"array":case"object":for(var r in t)t[r]=this.processArgument(t[r]);return t;default:return t}}static getType(e,t="null"){return"object"==typeof e?null===e?t:Array.isArray(e)?"array":e.hasOwnProperty("callback")?"callback":e.hasOwnProperty("variable_id")?"variable":e.hasOwnProperty("from_node")?"result":e.hasOwnProperty("from_argument")?"callback-argument":"object":typeof e}isStartNode(){return 0===this.expectsFrom.length}addPreviousNode(e){this.expectsFrom.push(e)}getPreviousNodes(){return this.expectsFrom}addNextNode(e){this.passesTo.push(e)}getNextNodes(){return this.passesTo}reset(){this.result=null,this.resultsAvailableFrom=[]}setResult(e){this.result=e}getResult(){return this.result}solveDependency(e){return null!==e&&this.expectsFrom.includes(e)&&this.resultsAvailableFrom.push(e),this.expectsFrom.length===this.resultsAvailableFrom.length}}},function(e,t,r){const s=r(4),a=r(1),i=r(2),o=r(5),n=r(0);e.exports=class{constructor(e,t=null){this.schema=e,this.jsonSchema=null===t?new s:t}async validate(e){var t=e.getArgumentNames().filter(e=>void 0===this.schema.parameters[e]);if(t.length>0)throw new a("ProcessArgumentUnsupported",{process:this.schema.id,argument:t[0]});for(let t in this.schema.parameters){let r=this.schema.parameters[t],s=e.getRawArgument(t);if(await this.validateArgument(s,e,t,r))continue;let i=await this.jsonSchema.validateJson(s,r.schema);if(i.length>0)throw new a("ProcessArgumentInvalid",{process:this.schema.id,argument:t,reason:i.join("; ")})}}async validateArgument(e,t,r,l){let c=i.getType(e);if(e instanceof o)return await e.validate(!0),!0;switch(c){case"undefined":if(l.required)throw new a("ProcessArgumentRequired",{process:this.schema.id,argument:r});return!0;case"callback-argument":var d=t.getProcessGraph().getCallbackParameters();if(n.isObject(d)&&d.hasOwnProperty(e.from_argument))return s.isSchemaCompatible(l.schema,d[e.from_argument]);throw new a("CallbackArgumentInvalid",{argument:e.from_argument,node_id:t.id,process_id:this.schema.id});case"variable":var p={type:e.type||"string"};return s.isSchemaCompatible(l.schema,p);case"result":try{var u=t.getProcessGraph(),h=u.getNode(e.from_node).process_id,v=u.getProcess(h);return s.isSchemaCompatible(l.schema,v.schema.returns.schema)}catch(e){}break;case"array":case"object":for(var g in e)await this.validateArgument(e[g],t,r);return!0}return!1}async execute(e){throw"execute not implemented yet"}test(){throw"test not implemented yet"}}},function(e,t,r){const s=r(12),a=r(0);e.exports=class e{constructor(e){var t={schemaId:"auto",format:"full",formats:{"band-name":{type:"string",validate:this.validateBandName.bind(this)},"bounding-box":{type:"object",validate:this.validateBoundingBox.bind(this)},callback:{type:"object",validate:this.validateCallback.bind(this)},"collection-id":{type:"string",validate:this.validateCollectionId.bind(this)},"epsg-code":{type:"integer",validate:this.validateEpsgCode.bind(this)},geojson:{type:"object",validate:this.validateGeoJson.bind(this)},"job-id":{type:"string",async:!0,validate:this.validateJobId.bind(this)},kernel:{type:"array",validate:this.validateKernel.bind(this)},"output-format":{type:"string",validate:this.validateOutputFormat.bind(this)},"output-format-options":{type:"array",validate:this.validateOutputFormatOptions.bind(this)},"process-graph-id":{type:"string",async:!0,validate:this.validateProcessGraphId.bind(this)},"process-graph-variables":{type:"array",validate:this.validateProcessGraphVariables.bind(this)},"proj-definition":{type:"string",validate:this.validateProjDefinition.bind(this)},"raster-cube":{type:"object",validate:this.validateRasterCube.bind(this)},"temporal-interval":{type:"array",validate:this.validateTemporalInterval.bind(this)},"temporal-intervals":{type:"array",validate:this.validateTemporalIntervals.bind(this)},"vector-cube":{type:"object",validate:this.validateVectorCube.bind(this)}}};this.ajv=new s(t),this.ajv.addKeyword("parameters",{dependencies:["type","format"],metaSchema:{type:"object",additionalProperties:{type:"object"}},valid:!0,errors:!0}),a.isObject(e)&&(this.collectionResolver=e.collectionResolver||null,this.jobResolver=e.jobResolver||null,this.pgResolver=e.pgResolver||null,this.outputFormats=e.outputFormats||null)}async validateJson(e,t){var r=Object.assign({},t);r.$async=!0,void 0===t.$schema&&(r.$schema="http://json-schema.org/draft-07/schema#");try{return await this.ajv.validate(r,e),[]}catch(e){if(Array.isArray(e.errors))return e.errors.map(e=>e.message);throw e}}validateJsonSchema(e){void 0===e.$schema&&((e=Object.assign({},e)).$schema="http://json-schema.org/draft-07/schema#");return this.ajv.compile(e).errors||[]}setCollectionResolver(e){this.collectionResolver=e}setJobResolver(e){this.jobResolver=e}setStoredProcessGraphResolver(e){this.pgResolver=e}setOutputFormats(e){for(var t in this.outputFormats={},e)this.outputFormats[t.toUpperCase()]=e[t]}validateBandName(e){return!0}validateBoundingBox(e){return!0}validateCallback(e){return!0}async validateCollectionId(e){return"function"!=typeof this.collectionResolver||this.collectionResolver(e)}validateEpsgCode(e){return!0}validateGeoJson(e){if("string"!=typeof e.type)throw new s.ValidationError([{message:"Invalid GeoJSON specified (no type property)."}]);return!0}async validateJobId(e){return"function"!=typeof this.jobResolver||this.jobResolver(e)}validateKernel(e){return!0}validateOutputFormat(e){return!a.isObject(this.outputFormats)||e.toUpperCase()in this.outputFormats}validateOutputFormatOptions(e){return!0}async validateProcessGraphId(e){if("function"==typeof this.pgResolver)return this.pgResolver(e)}validateProcessGraphVariables(e){return!0}validateProjDefinition(e){return!0}validateRasterCube(e){return!0}validateTemporalInterval(e){return!0}validateTemporalIntervals(e){return!0}validateVectorCube(e){return!0}static isSchemaCompatible(e,t){return!0}static async getTypeForValue(t,r){var s=new e,a=[];for(var i in t){0===(await s.validateJson(r,t[i])).length&&a.push(i)}return a.length>1?a:a[0]}}},function(e,t,r){const s=r(6),a=r(1),i=r(2),o=r(0),n=["string","number","boolean","array","object"];e.exports=class e{constructor(e,t){this.json=o.mergeDeep({},e),this.processRegistry=t,this.nodes=[],this.startNodes={},this.resultNode=null,this.childrenProcessGraphs=[],this.parentNode=null,this.parentParameterName=null,this.variables={},this.parsed=!1,this.validated=!1,this.errors=new s,this.parameters={}}toJSON(){return this.json}createNodeInstance(e,t,r){return new i(e,t,r)}createProcessGraphInstance(t){return new e(t,this.processRegistry)}setParent(e,t){this.parentNode=e,this.parentParameterName=t}isValid(){return this.validated&&0===this.errors.count()}addError(e){this.errors.add(e)}parse(){if(!this.parsed){for(var e in this.json)this.nodes[e]=this.createNodeInstance(this.json[e],e,this);for(var e in this.nodes){var t=this.nodes[e];if(t.isResultNode){if(null!==this.resultNode)throw this.parentNode?new a("MultipleResultNodesCallback",{node_id:this.parentNode.id,process_id:this.parentNode.process_id}):new a("MultipleResultNodes");this.resultNode=t}this.parseArguments(e,t)}if(!this.findStartNodes())throw this.parentNode?new a("StartNodeMissingCallback",{node_id:this.parentNode.id,process_id:this.parentNode.process_id}):new a("StartNodeMissing");if(null===this.resultNode)throw this.parentNode?new a("ResultNodeMissingCallback",{node_id:this.parentNode.id,process_id:this.parentNode.process_id}):new a("ResultNodeMissing");this.parsed=!0}}async validate(e=!0){if(this.validated)return null;this.validated=!0;try{this.parse()}catch(e){this.addError(e)}return await this.validateNodes(this.getStartNodes(),e),this.errors}async execute(e=null){return await this.validate(),this.reset(),this.setParameters(e),await this.executeNodes(this.getStartNodes()),this.getResultNode()}async validateNodes(e,t,r=null){if(0!==e.length){var a=e.map(async e=>{if(e.solveDependency(r)){try{await this.validateNode(e)}catch(e){if(e instanceof s){if(this.errors.merge(e),t)throw e.first()}else if(this.addError(e),t)throw e}await this.validateNodes(e.getNextNodes(),t,e)}});await Promise.all(a)}}async validateNode(e){var t=this.getProcess(e);return await t.validate(e)}async executeNodes(e,t=null){if(0!==e.length){var r=e.map(async e=>{if(e.solveDependency(t)){var r=await this.executeNode(e);e.setResult(r),await this.executeNodes(e.getNextNodes(),e)}});return Promise.all(r)}}async executeNode(e){var t=this.getProcess(e);return await t.execute(e)}parseArguments(e,t,r){for(var s in void 0===r&&(r=t.arguments),r){var a=r[s];switch(i.getType(a)){case"result":this.connectNodes(t,a.from_node);break;case"variable":this.parseVariable(a);break;case"callback":a.callback=this.createProcessGraph(a.callback,t,s);break;case"callback-argument":this.parseCallbackArgument(t,a.from_argument);break;case"array":case"object":this.parseArguments(e,t,a)}}}parseCallbackArgument(e,t){}createProcessGraph(e,t,r){var s=this.createProcessGraphInstance(e);return s.setParent(t,r),s.parse(),this.childrenProcessGraphs.push(s),s}parseVariable(e){if("string"!=typeof e.variable_id)throw new a("VariableIdInvalid");var t={};if(void 0!==e.type&&!n.includes(e.type))throw new a("VariableTypeInvalid",e);t.type=void 0!==e.type?e.type:"string";var r=i.getType(e.default);if("undefined"!==r){if(r!==t.type)throw new a("VariableDefaultValueTypeInvalid",e);t.value=e.default}}setParameters(e){"object"==typeof e&&null!==e&&(this.parameters=e)}getParameter(e){return this.parameters[e]}setVariableValues(e){for(var t in e)this.setVariable(t,e[t])}setVariableValue(e,t){"object"!=typeof this.variables[e]&&(this.variables[e]={}),this.variables[e].value=t}getVariableValue(e){var t=this.variables[e];if("object"!=typeof t||void 0===t.value)throw new a("VariableValueMissing",{variable_id:e});if(i.getType(t.value)!==t.type)throw new a("VariableValueTypeInvalid",{variable_id:e,type:t.type});return this.variables[e].value}connectNodes(e,t){var r=this.nodes[t];if(void 0===r)throw new a("ReferencedNodeMissing",{node_id:t});e.addPreviousNode(r),r.addNextNode(e)}findStartNodes(){var e=!1;for(var t in this.nodes){var r=this.nodes[t];r.isStartNode()&&(this.startNodes[t]=r,e=!0)}return e}reset(){for(var e in this.nodes)this.nodes[e].reset();this.childrenProcessGraphs.forEach(e=>e.reset())}getResultNode(){return this.resultNode}getStartNodes(){return Object.values(this.startNodes)}getStartNodeIds(){return Object.keys(this.startNodes)}getNode(e){return this.nodes[e]}getNodes(){return this.nodes}getJson(){return this.json}getErrors(){return this.errors}getProcess(e){var t=this.processRegistry.get(e.process_id);if(null===t)throw new a("ProcessUnsupported",{process:e.process_id});return t}getCallbackParameters(){if(!this.parentNode||!this.parentParameterName)return{};var e=this.getProcess(this.parentNode).schema.parameters[this.parentParameterName].schema;if(o.isObject(e.parameters))return e.parameters;var t={},r=e.anyOf||e.oneOf||e.allOf;if(Array.isArray(r))for(let e in r){var s=r[e];o.isObject(s.parameters)&&Object.assign(t,s.parameters)}return t}}},function(e,t){e.exports=class{constructor(){this.errors=[]}first(){return this.errors[0]}merge(e){this.errors.concat(e.getAll())}add(e){this.errors.push(e)}count(){return this.errors.length}toJSON(){return this.errors.map(e=>"function"==typeof e.toJSON?e.toJSON():{code:"InternalError",message:e.message})}getMessage(){var e="";for(var t in this.errors)e+=parseInt(t)+1+". "+this.errors[t].message+"\r\n";return e.trim()}getAll(){return this.errors}}},function(e,t,r){const s=r(8),a=r(10),i=r(11),o=r(3),n=r(4),l=r(5),c=r(1),d=r(2),p=r(13),u=r(6),h=r(14),v=r(0);e.exports={MigrateCapabilities:s,MigrateCollections:a,MigrateProcesses:i,BaseProcess:o,JsonSchemaValidator:n,ProcessGraph:l,ProcessGraphError:c,ProcessGraphNode:d,ProcessRegistry:p,ErrorList:u,FeatureList:h,Utils:v}},function(e,t,r){const s=r(0);var a={guessApiVersion:e=>"string"==typeof e.version?e.version:"string"==typeof e.api_version?e.api_version:e.backend_version||e.title||e.description||e.links?"0.4":"0.3",convertCapabilitiesToLatestSpec:function(e,t=null,r="Unknown"){var a=Object.assign({},e);return null===t&&(t=this.guessApiVersion(a)),0===s.compareVersion(t,"0.3.x")&&void 0!==a.version&&delete a.version,void 0!==a.billing&&(a.billing=this.convertBillingToLatestSpec(a.billing,t)),a.endpoints=this.convertEndpointsToLatestSpec(a.endpoints,t),"string"!=typeof a.api_version&&(a.api_version="0.4.0"),"string"!=typeof a.backend_version&&(a.backend_version="Unknown"),"string"!=typeof a.title&&(a.title=r),"string"!=typeof a.description&&(a.description="No description provided."),a},convertBillingToLatestSpec:function(e,t){var r=Object.assign({},e);return 0===s.compareVersion(t,"0.3.x")&&Array.isArray(r.plans)&&(r.plans=r.plans.map(e=>("boolean"!=typeof e.paid&&(e.paid=!0,"string"==typeof e.name&&e.name.toLowerCase().includes("free")&&(e.paid=!1)),e))),r},convertEndpointsToLatestSpec:function(e,t){var r=[];return Array.isArray(e)&&(r=e.slice(0)),s.compareVersion(t,"0.3.x"),r},convertOutputFormatsToLatestSpec:function(e,t){var r=Object.assign({},e);return 0===s.compareVersion(t,"0.3.x")&&"object"==typeof r.formats&&null!==r.formats?r.formats:r},convertServiceTypesToLatestSpec:function(e,t){var r=Object.assign({},e);return s.compareVersion(t,"0.3.x"),r}};e.exports=a},function(e,t,r){var s,a,i;a=[],void 0===(i="function"==typeof(s=function(){var e=/^v?(?:\d+)(\.(?:[x*]|\d+)(\.(?:[x*]|\d+)(\.(?:[x*]|\d+))?(?:-[\da-z\-]+(?:\.[\da-z\-]+)*)?(?:\+[\da-z\-]+(?:\.[\da-z\-]+)*)?)?)?$/i;function t(e){var t,r,s=e.replace(/^v/,"").replace(/\+.*$/,""),a=(r="-",-1===(t=s).indexOf(r)?t.length:t.indexOf(r)),i=s.substring(0,a).split(".");return i.push(s.substring(a+1)),i}function r(e){return isNaN(Number(e))?e:Number(e)}function s(t){if("string"!=typeof t)throw new TypeError("Invalid argument expected string");if(!e.test(t))throw new Error("Invalid argument not valid semver ('"+t+"' received)")}return function(e,a){[e,a].forEach(s);for(var i=t(e),o=t(a),n=0;n<Math.max(i.length-1,o.length-1);n++){var l=parseInt(i[n]||0,10),c=parseInt(o[n]||0,10);if(l>c)return 1;if(c>l)return-1}var d=i[i.length-1],p=o[o.length-1];if(d&&p){var u=d.split(".").map(r),h=p.split(".").map(r);for(n=0;n<Math.max(u.length,h.length);n++){if(void 0===u[n]||"string"==typeof h[n]&&"number"==typeof u[n])return-1;if(void 0===h[n]||"string"==typeof u[n]&&"number"==typeof h[n])return 1;if(u[n]>h[n])return 1;if(h[n]>u[n])return-1}}else if(d||p)return d?-1:1;return 0}})?s.apply(t,a):s)||(e.exports=i)},function(e,t,r){const s=r(0);var a={guessCollectionSpecVersion(e){var t="0.4";return void 0===e.id&&void 0!==e.name&&(t="0.3"),t},convertCollectionToLatestSpec:function(e,t=null){var r=Object.assign({},e);if(!Object.keys(r).length)return r;if(null===t&&(t=this.guessCollectionSpecVersion(r)),0===s.compareVersion(t,"0.3.x")){if(r.id=r.name,delete r.name,r.stac_version="0.6.1",Array.isArray(r.provider)&&(r.providers=r.provider,delete r.provider),"object"!=typeof r.properties&&(r.properties={}),null!==r["eo:bands"]&&"object"==typeof r["eo:bands"]&&!Array.isArray(r["eo:bands"])){var a=[];for(var i in r["eo:bands"]){var o=Object.assign({},r["eo:bands"][i]);o.name=i,void 0!==o.resolution&&void 0===o.gsd&&(o.gsd=o.resolution,delete o.resolution),void 0!==o.wavelength&&void 0===o.center_wavelength&&(o.center_wavelength=o.wavelength,delete o.wavelength),a.push(o)}r["eo:bands"]=a}for(var i in r)i.includes(":")&&(r.properties[i]=r[i],delete r[i])}return r}};e.exports=a},function(e,t,r){const s=r(0);var a={guessProcessSpecVersion(e){var t="0.4";return void 0===e.id&&void 0!==e.name&&(t="0.3"),t},convertProcessToLatestSpec:function(e,t=null){var r=Object.assign({},e);if(null===t&&(t=this.guessProcessSpecVersion(r)),0===s.compareVersion(t,"0.3.x")){if(r.id=r.name,delete r.name,"object"==typeof r.parameters)for(var a in r.parameters)if(void 0!==r.parameters[a].mime_type){var i=Object.assign({},r.parameters[a]);i.media_type=i.mime_type,delete i.mime_type,r.parameters[a]=i}if("object"==typeof r.returns&&void 0!==r.returns.mime_type&&(r.returns.media_type=r.returns.mime_type,delete r.returns.mime_type),"object"==typeof r.exceptions)for(var a in r.exceptions){var o=r.exceptions[a];void 0===o.message&&(r.exceptions[a]=Object.assign({},o,{message:o.description}))}if("object"==typeof r.examples){var n=[];for(var a in r.examples){var l=r.examples[a],c={title:l.summary||a,description:l.description};l.process_graph&&(c.process_graph=l.process_graph),n.push(c)}r.examples=n}if("object"==typeof r.parameters&&!Array.isArray(r.parameter_order)){var d=Object.keys(r.parameters);d.length>1&&(r.parameter_order=d)}}return r}};e.exports=a},function(t,r){t.exports=e},function(e,t,r){const s=r(3),a=r(0);e.exports=class{constructor(){this.processes={}}addFromResponse(e){for(var t in e.processes){var r=e.processes[t];this.processes[r.id]=new s(r)}}count(){return a.size(this.processes)}get(e){var t=e.toLowerCase();return void 0!==this.processes[t]?this.processes[t]:null}getProcessSchemas(){return Object.values(this.processes).map(e=>e.schema)}}},function(e,t,r){const s=r(0);var a={features:{"Basic functionality":["get /collections","get /collections/{}","get /processes","get /output_formats"],"Authenticate with HTTP Basic":["get /credentials/basic"],"Authenticate with OpenID Connect":["get /credentials/oidc"],"Batch processing":["get /jobs","post /jobs","get /jobs/{}","delete /jobs/{}","get /jobs/{}/results","post /jobs/{}/results"],"Estimate processing costs":["get /jobs/{}/estimate"],"Preview processing results":["post /result"],"Secondary web services":["get /service_types","get /services","post /services","get /services/{}","delete /services/{}"],"File storage":["get /files/{}","get /files/{}/{}","put /files/{}/{}","delete /files/{}/{}"],"Stored process graphs":["get /process_graphs","post /process_graphs","get /process_graphs/{}","delete /process_graphs/{}"],"Validate process graphs":["post /validation"],"Notifications and monitoring":["get /subscription"],"User defined functions (UDF)":["get /udf_runtimes"]},legacyFeatures:{"post /result":{"post /preview":["0.3.*"]}},getListForVersion(e){var t={};for(var r in this.features)for(var s in t[r]=[],this.features[r]){var a=this.findLegacyEndpoint(e,this.features[r][s]);t[r].push(a)}return t},findLegacyEndpoint(e,t,r=null){if(null!==r&&(t=this.endpointToString(r,t)),"object"==typeof this.legacyFeatures[t]){var a=this.legacyFeatures[t];for(var i in a)for(var o in a[i]){var n=a[i][o];if(0===s.compareVersion(e,n))return i}}return t},getFeatures(){return Object.keys(this.features)},getFeatureCount(){return Object.keys(this.features).length},endpointsToStringList(e){var t=[];for(let r in e)for(let s in e[r].methods)t.push(this.endpointToString(e[r].methods[s],e[r].path));return t},endpointToString:(e,t)=>(e+" "+t.replace(/{[^}]+}/g,"{}")).toLowerCase(),getReport(e,t,r=!0){var s=0,a=r?this.endpointsToStringList(e):e,i=this.getListForVersion(t);return Object.keys(i).forEach(e=>{let t=i[e];switch(t.filter(e=>!a.includes(e)).length){case 0:i[e]=2,s++;break;case t.length:i[e]=0;break;default:i[e]=1}}),{count:s,list:i}}};e.exports=a}])});
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory(require("ajv"));
else if(typeof define === 'function' && define.amd)
define(["ajv"], factory);
else {
var a = typeof exports === 'object' ? factory(require("ajv")) : factory(root["ajv"]);
for(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i];
}
})(window, function(__WEBPACK_EXTERNAL_MODULE__12__) {
return /******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter });
/******/ }
/******/ };
/******/
/******/ // define __esModule on exports
/******/ __webpack_require__.r = function(exports) {
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ }
/******/ Object.defineProperty(exports, '__esModule', { value: true });
/******/ };
/******/
/******/ // create a fake namespace object
/******/ // mode & 1: value is a module id, require it
/******/ // mode & 2: merge all properties of value into the ns
/******/ // mode & 4: return value when already ns object
/******/ // mode & 8|1: behave like require
/******/ __webpack_require__.t = function(value, mode) {
/******/ if(mode & 1) value = __webpack_require__(value);
/******/ if(mode & 8) return value;
/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
/******/ var ns = Object.create(null);
/******/ __webpack_require__.r(ns);
/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value });
/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
/******/ return ns;
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 7);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports, __webpack_require__) {
const compareVersions = __webpack_require__(9);
var Utils = {
compareVersion(v1, v2) {
try {
return compareVersions(v1, v2);
} catch (error) {
return null;
}
},
isObject(obj) {
return (typeof obj === 'object' && obj === Object(obj) && !Array.isArray(obj));
},
size(obj) {
if (typeof obj === 'object' && obj !== null) {
if (Array.isArray(obj)) {
return obj.length;
}
else {
return Object.keys(obj).length;
}
}
return 0;
},
replacePlaceholders(message, variables = {}) {
if (typeof message === 'string' && this.isObject(variables)) {
for(var placeholder in variables) {
message = message.replace('{' + placeholder + '}', variables[placeholder]);
}
}
return message;
}
};
module.exports = Utils;
/***/ }),
/* 1 */
/***/ (function(module, exports, __webpack_require__) {
const Utils = __webpack_require__(0);
const MESSAGES = {
"MultipleResultNodes": "Multiple result nodes specified for process graph.",
"StartNodeMissing": "No start nodes found for process graph.",
"ResultNodeMissing": "No result node found for process graph.",
"MultipleResultNodesCallback": "Multiple result nodes specified for the callback in the process '{process_id}' (node: '{node_id}').",
"StartNodeMissingCallback": "No start nodes found for the callback in the process '{process_id}' (node: '{node_id}')'.",
"ResultNodeMissingCallback": "No result node found for the callback in the process '{process_id}' (node: '{node_id}').",
"ReferencedNodeMissing": "Referenced node '{node_id}' doesn't exist.",
"NodeIdInvalid": "Invalid node id specified in process graph.",
"NodeInvalid": "Process graph node '{node_id}' is not a valid object.",
"ProcessIdMissing": "Process graph node '{node_id}' doesn't contain a process id.",
"CallbackArgumentInvalid": "Invalid callback argument '{argument}' requested in the process '{process_id}' (node: '{node_id}').",
"ProcessUnsupported": "Process '{process}' is not supported.",
"ProcessArgumentUnsupported": "Process '{process}' does not support argument '{argument}'.",
"ProcessArgumentRequired": "Process '{process}' requires argument '{argument}'.",
"ProcessArgumentInvalid": "The argument '{argument}' in process '{process}' is invalid: {reason}",
"VariableValueMissing": "No value specified for process graph variable '{variable_id}'.",
"VariableDefaultValueTypeInvalid": "The default value specified for the process graph variable '{variable_id}' is not of type '{type}'.",
"VariableValueTypeInvalid": "The value specified for the process graph variable '{variable_id}' is not of type '{type}'.",
"VariableIdInvalid": "A specified variable ID is not valid.",
"VariableTypeInvalid": "The data type specified for the process graph variable '{variable_id}' is invalid. Must be one of: string, boolean, number, array or object.",
};
module.exports = class ProcessGraphError extends Error {
constructor(codeOrMsg, variables = {}) {
super();
this.variables = variables;
if (typeof MESSAGES[codeOrMsg] === 'string') {
this.code = codeOrMsg;
this.message = Utils.replacePlaceholders(MESSAGES[codeOrMsg], variables);
}
else {
this.code = codeOrMsg.replace(/[^\w\d]+/g, '');
this.message = codeOrMsg;
}
}
toJSON() {
return {
code: this.code,
message: this.message
};
}
};
/***/ }),
/* 2 */
/***/ (function(module, exports, __webpack_require__) {
const ProcessGraphError = __webpack_require__(1);
const Utils = __webpack_require__(0);
module.exports = class ProcessGraphNode {
constructor(json, id, parent) {
if (typeof id !== 'string' || id.length === 0) {
throw new ProcessGraphError('NodeIdInvalid');
}
if (!Utils.isObject(json)) {
throw new ProcessGraphError('NodeInvalid', {node_id: id});
}
if (typeof json.process_id !== 'string') {
throw new ProcessGraphError('ProcessIdMissing', {node_id: id});
}
this.id = id;
this.processGraph = parent;
this.process_id = json.process_id;
this.arguments = Utils.isObject(json.arguments) ? JSON.parse(JSON.stringify(json.arguments)) : {};
this.isResultNode = json.result || false;
this.expectsFrom = [];
this.passesTo = [];
this.result = null;
this.resultsAvailableFrom = [];
}
getProcessGraph() {
return this.processGraph;
}
getArgumentNames() {
return Object.keys(this.arguments);
}
hasArgument(name) {
return (name in this.arguments);
}
getArgumentType(name) {
return ProcessGraphNode.getType(this.arguments[name]);
}
getRawArgument(name) {
return this.arguments[name];
}
getRawArgumentValue(name) {
var arg = this.arguments[name];
switch(ProcessGraphNode.getType(arg)) {
case 'result':
return arg.from_node;
case 'callback':
return arg.callback;
case 'callback-argument':
return arg.from_argument;
default:
return arg;
}
}
getArgument(name, defaultValue = undefined) {
if (typeof this.arguments[name] === 'undefined') {
return defaultValue;
}
return this.processArgument(this.arguments[name]);
}
processArgument(arg) {
var type = ProcessGraphNode.getType(arg);
switch(type) {
case 'result':
return this.processGraph.getNode(arg.from_node).getResult();
case 'callback':
return arg.callback;
case 'callback-argument':
return this.processGraph.getParameter(arg.from_argument);
case 'variable':
return this.processGraph.getVariableValue(arg.variable_id);
case 'array':
case 'object':
for(var i in arg) {
arg[i] = this.processArgument(arg[i]);
}
return arg;
default:
return arg;
}
}
static getType(obj, reportNullAs = 'null') {
if (typeof obj === 'object') {
if (obj === null) {
return reportNullAs;
}
else if (Array.isArray(obj)) {
return 'array';
}
else if(obj.hasOwnProperty("callback")) {
return 'callback';
}
else if(obj.hasOwnProperty("variable_id")) {
return 'variable';
}
else if(obj.hasOwnProperty("from_node")) {
return 'result';
}
else if(obj.hasOwnProperty("from_argument")) {
return 'callback-argument';
}
else {
return 'object';
}
}
return (typeof obj);
}
isStartNode() {
return (this.expectsFrom.length === 0);
}
addPreviousNode(node) {
this.expectsFrom.push(node);
}
getPreviousNodes() {
return this.expectsFrom;
}
addNextNode(node) {
this.passesTo.push(node);
}
getNextNodes() {
return this.passesTo;
}
reset() {
this.result = null;
this.resultsAvailableFrom = [];
}
setResult(result) {
this.result = result;
}
getResult() {
return this.result;
}
solveDependency(dependencyNode) {
if (dependencyNode !== null && this.expectsFrom.includes(dependencyNode)) {
this.resultsAvailableFrom.push(dependencyNode);
}
return (this.expectsFrom.length === this.resultsAvailableFrom.length); // all dependencies solved?
}
};
/***/ }),
/* 3 */
/***/ (function(module, exports, __webpack_require__) {
const JsonSchemaValidator = __webpack_require__(4);
const ProcessGraphError = __webpack_require__(1);
const ProcessGraphNode = __webpack_require__(2);
const ProcessGraph = __webpack_require__(5);
module.exports = class BaseProcess {
constructor(schema, validator = null) {
this.schema = schema;
if (validator === null) {
this.jsonSchema = new JsonSchemaValidator();
}
else {
this.jsonSchema = validator;
}
}
async validate(node) {
// Check for arguments we don't support and throw error
var unsupportedArgs = node.getArgumentNames().filter(name => (typeof this.schema.parameters[name] === 'undefined'));
if (unsupportedArgs.length > 0) {
throw new ProcessGraphError('ProcessArgumentUnsupported', {
process: this.schema.id,
argument: unsupportedArgs[0]
});
}
// Validate against JSON Schema
for(let name in this.schema.parameters) {
let param = this.schema.parameters[name];
let arg = node.getRawArgument(name);
if (await this.validateArgument(arg, node, name, param)) {
continue;
}
// Validate against JSON schema
let errors = await this.jsonSchema.validateJson(arg, param.schema);
if (errors.length > 0) {
throw new ProcessGraphError('ProcessArgumentInvalid', {
process: this.schema.id,
argument: name,
reason: errors.join("; ")
});
}
}
}
async validateArgument(arg, node, parameterName, param) {
let argType = ProcessGraphNode.getType(arg);
if (arg instanceof ProcessGraph) {
await arg.validate(true);
return true;
}
switch(argType) {
// Check whether parameter is required
case 'undefined':
if (param.required) {
throw new ProcessGraphError('ProcessArgumentRequired', {
process: this.schema.id,
argument: parameterName
});
}
return true; // Parameter not set, nothing to validate against
case 'callback-argument':
var cbParams = node.getProcessGraph().getCallbackParameters();
// No need for further checks, callback argument is validated in processgraph.js: see parseCallbackArgument()
return JsonSchemaValidator.isSchemaCompatible(param.schema, cbParams[arg.from_argument]);
case 'variable':
var variableSchema = {
type: arg.type || 'string'
};
return JsonSchemaValidator.isSchemaCompatible(param.schema, variableSchema);
case 'result':
try {
var pg = node.getProcessGraph();
var process_id = pg.getNode(arg.from_node).process_id;
var process = pg.getProcess(process_id);
return JsonSchemaValidator.isSchemaCompatible(param.schema, process.schema.returns.schema);
} catch (e) {}
break;
case 'array':
case 'object':
// ToDo: Check how we can validate arrays and objects that have references to callback arguments, variables and node results in them...
// See issue https://github.com/Open-EO/openeo-js-commons/issues/5
// for(var i in arg) {
// await this.validateArgument(arg[i], node, parameterName, param);
// }
return true;
}
return false;
}
/* istanbul ignore next */
async execute(/*node*/) {
throw "execute not implemented yet";
}
/* istanbul ignore next */
test() {
// Run the tests from the examples
throw "test not implemented yet";
}
};
/***/ }),
/* 4 */
/***/ (function(module, exports, __webpack_require__) {
const ajv = __webpack_require__(12);
const Utils = __webpack_require__(0);
module.exports = class JsonSchemaValidator {
constructor() {
var ajvOptions = {
schemaId: 'auto',
format: 'full',
formats: {
// See issue https://github.com/Open-EO/openeo-js-commons/issues/4 for information on why ajv doesn't support non-string validation
'band-name': {type: 'string', async: true, validate: this.validateBandName.bind(this)},
'bounding-box': {type: 'object', async: true, validate: this.validateBoundingBox.bind(this)}, // Currently not supported by ajv 6.10
'callback': {type: 'object', async: true, validate: this.validateCallback.bind(this)}, // Currently not supported by ajv 6.10
'collection-id': {type: 'string', async: true, validate: this.validateCollectionId.bind(this)},
'epsg-code': {type: 'integer', async: true, validate: this.validateEpsgCode.bind(this)}, // Currently not supported by ajv 6.10
'geojson': {type: 'object', async: true, validate: this.validateGeoJson.bind(this)}, // Currently not supported by ajv 6.10
'job-id': {type: 'string', async: true, validate: this.validateJobId.bind(this)},
'kernel': {type: 'array', async: true, validate: this.validateKernel.bind(this)}, // Currently not supported by ajv 6.10
'output-format': {type: 'string', async: true, validate: this.validateOutputFormat.bind(this)},
'output-format-options': {type: 'array', async: true, validate: this.validateOutputFormatOptions.bind(this)}, // Currently not supported by ajv 6.10
'process-graph-id': {type: 'string', async: true, validate: this.validateProcessGraphId.bind(this)},
'process-graph-variables': {type: 'array', async: true, validate: this.validateProcessGraphVariables.bind(this)}, // Currently not supported by ajv 6.10
'proj-definition': {type: 'string', async: true, validate: this.validateProjDefinition.bind(this)},
'raster-cube': {type: 'object', async: true, validate: this.validateRasterCube.bind(this)}, // Currently not supported by ajv 6.10
'temporal-interval': {type: 'array', async: true, validate: this.validateTemporalInterval.bind(this)}, // Currently not supported by ajv 6.10
'temporal-intervals': {type: 'array', async: true, validate: this.validateTemporalIntervals.bind(this)}, // Currently not supported by ajv 6.10
'vector-cube': {type: 'object', async: true, validate: this.validateVectorCube.bind(this)} // Currently not supported by ajv 6.10
}
};
this.ajv = new ajv(ajvOptions);
this.ajv.addKeyword('parameters', {
dependencies: [
"type",
"format"
],
metaSchema: {
type: "object",
additionalProperties: {
type: "object"
}
},
valid: true,
errors: true
});
this.outputFormats = null;
this.geoJsonValidator = null;
}
async validateJson(json, schema) {
// Make sure we don't alter the process registry
var clonedSchema = Object.assign({}, schema);
clonedSchema.$async = true;
if (typeof clonedSchema.$schema === 'undefined') {
// Set applicable JSON Schema draft version if not already set
clonedSchema.$schema = "http://json-schema.org/draft-07/schema#";
}
try {
await this.ajv.validate(clonedSchema, json);
return [];
} catch (e) {
if (Array.isArray(e.errors)) {
return e.errors.map(e => e.message);
}
else {
throw e;
}
}
}
validateJsonSchema(schema) {
// Set applicable JSON SChema draft version if not already set
if (typeof schema.$schema === 'undefined') {
schema = Object.assign({}, schema); // Make sure we don't alter the process registry
schema.$schema = "http://json-schema.org/draft-07/schema#";
}
let result = this.ajv.compile(schema);
return result.errors || [];
}
// Pass the content of https://geojson.org/schema/GeoJSON.json
setGeoJsonSchema(schema) {
var gjv = new ajv();
this.geoJsonValidator = gjv.compile(schema);
}
// Expects API compatible output formats (see GET /output_formats).
setOutputFormats(outputFormats) {
this.outputFormats = {};
for (var key in outputFormats) {
this.outputFormats[key.toUpperCase()] = outputFormats[key];
}
}
/* istanbul ignore next */
async validateBandName(/*data*/) {
// Can't validate band name without knowing/loading the data.
// => To be overridden by end-user application.
return true;
}
/* istanbul ignore next */
async validateBoundingBox(/*data*/) {
// Nothing to validate, schema is (usually) delivered by processes.
return true;
}
/* istanbul ignore next */
async validateCallback(/*data*/) {
// This should be checked by process graph parsing automatically.
// Otherwise to be overridden by end-user application.
return true;
}
/* istanbul ignore next */
async validateCollectionId(/*data*/) {
// To be overridden by end-user application.
return true;
}
async validateEpsgCode(data) {
// Rough check for valid numbers as we don't want to maintain a full epsg code list in this repo.
// Fully validation to be implemented by end-user application by overriding this method.
if (data >= 2000) {
return true;
}
throw new ajv.ValidationError([{
message: "Invalid EPSG code specified."
}]);
}
async validateGeoJson(data) {
if (this.geoJsonValidator !== null) {
if (!this.geoJsonValidator(data)) {
throw new ajv.ValidationError(ajv.errors);
}
return true;
}
else {
// A very rough GeoJSON validation if no GeoJSON schema is available.
if (typeof data.type !== 'string') {
throw new ajv.ValidationError([{
message: "Invalid GeoJSON specified (no type property)."
}]);
}
switch(data.type) {
case "Point":
case "MultiPoint":
case "LineString":
case "MultiLineString":
case "Polygon":
case "MultiPolygon":
if (!Array.isArray(data.coordinates)) {
throw new ajv.ValidationError([{
message: "Invalid GeoJSON specified (Geometry has no valid coordinates member)."
}]);
}
return true;
case "GeometryCollection":
if (!Array.isArray(data.geometries)) {
throw new ajv.ValidationError([{
message: "Invalid GeoJSON specified (GeometryCollection has no valid geometries member)."
}]);
}
return true;
case "Feature":
if (data.geometry !== null && !Utils.isObject(data.geometry)) {
throw new ajv.ValidationError([{
message: "Invalid GeoJSON specified (Feature has no valid geometry member)."
}]);
}
if (data.properties !== null && !Utils.isObject(data.properties)) {
throw new ajv.ValidationError([{
message: "Invalid GeoJSON specified (Feature has no valid properties member)."
}]);
}
return true;
case "FeatureCollection":
if (!Array.isArray(data.features)) {
throw new ajv.ValidationError([{
message: "Invalid GeoJSON specified (FeatureCollection has no valid features member)."
}]);
}
return true;
default:
throw new ajv.ValidationError([{
message: "Invalid GeoJSON type specified."
}]);
}
}
}
/* istanbul ignore next */
async validateJobId(/*data*/) {
// To be overridden by end-user application
return true;
}
/* istanbul ignore next */
async validateKernel(/*data*/) {
// ToDo? / To be overridden by end-user application
return true;
}
async validateOutputFormat(data) {
if (Utils.isObject(this.outputFormats) && !(data.toUpperCase() in this.outputFormats)) {
throw new ajv.ValidationError([{
message: "Output format not supported."
}]);
}
return true;
}
/* istanbul ignore next */
async validateOutputFormatOptions(/*data*/) {
// This depends on the output format specified and can't be fully validated without knowning the chosen output format.
return true;
}
/* istanbul ignore next */
async validateProcessGraphId(/*data*/) {
// To be overridden by end-user application
return true;
}
/* istanbul ignore next */
async validateProcessGraphVariables(/*data*/) {
// Nothing to validate against...
return true;
}
async validateProjDefinition(data) {
// To be overridden by end-user application, just doing a very basic check here.
if (!data.toLowerCase().includes("+proj")) {
throw new ajv.ValidationError([{
message: "Invalid PROJ string specified (doesn't contain '+proj')."
}]);
}
return true;
}
/* istanbul ignore next */
async validateRasterCube(/*data*/) {
// This is usually a reference to a process result as we haven't specified any JSON encoding for raster cubes.
return true;
}
async validateTemporalInterval(/*data*/) {
// ToDo: Fully check against schema, most is already checked by JSON Schemas itself, but check for example that
// both can't be null at the same time or the first element is > the second element.
return true;
}
async validateTemporalIntervals(data) {
var invalid = data.filter(x => !this.validateTemporalInterval(x));
return invalid.length === 0;
}
/* istanbul ignore next */
async validateVectorCube(/*data*/) {
// This is usually a reference to a process result as we haven't specified any JSON encoding for raster cubes.
return true;
}
// Checks whether the valueSchema is compatible to the paramSchema.
// So would a value compatible with valueSchema be accepted by paramSchema?
static isSchemaCompatible(paramSchema, valueSchema, strict = false) {
var paramSchemas = this._convertSchemaToArray(paramSchema);
var valueSchemas = this._convertSchemaToArray(valueSchema);
var compatible = paramSchemas.filter(ps => {
for(var i in valueSchemas) {
var vs = valueSchemas[i];
if (typeof ps.type !== 'string' || (!strict && typeof vs.type !== 'string')) { // "any" type is always compatible
return true;
}
else if (ps.type === vs.type || (ps.type === 'number' && vs.type === 'integer') || (!strict && ps.type === 'integer' && vs.type === 'number')) {
if (ps.type === 'array' && Utils.isObject(ps.items) && Utils.isObject(vs.items)) {
if (JsonSchemaValidator.isSchemaCompatible(ps.items, vs.items, strict)) {
return true;
}
}
else if (ps.type === 'object' && Utils.isObject(ps.properties) && Utils.isObject(vs.properties)) {
// ToDo: Check properties, required properties etc.
return true;
}
else if (!strict && (typeof ps.format !== 'string' || typeof vs.format !== 'string')) {
return true;
}
else if (typeof ps.format !== 'string') { // types without format always accepts the same type with a format
return true;
}
else if (ps.format === vs.format) {
return true;
}
}
}
return false;
});
return compatible.length > 0;
}
static _convertSchemaToArray(schema) {
var schemas = [];
// ToDo: schema.not and schema.allOf is not supported - see also class constructor of ProcessSchema in processSchema.js of openeo-web-editor.
if (schema.oneOf || schema.anyOf) {
schemas = (schema.oneOf || schema.anyOf);
}
else if (Array.isArray(schema.type)) {
schemas = schema.type.map(t => Object.assign({}, schema, {type: t}));
}
else {
schemas = [schema];
}
return schemas;
}
/**
* Returns the indices of provided JSON Schemas that the provided values matches against.
*
* Returns a single index if a single type is mathcing.
* Returns undefined if no valid type is found.
* Returns an array of indices if multiple types are found.
*
* @param {Array} types - Array of JSON schemas
* @param {*} value - A value
* @return {(string[]|string|undefined)} - Returns matching indices, see description.
*/
static async getTypeForValue(types, value) {
var validator = new JsonSchemaValidator();
var potentialTypes = [];
for(var i in types) {
var errors = await validator.validateJson(value, types[i]);
if (errors.length === 0) {
potentialTypes.push(String(i));
}
}
return potentialTypes.length > 1 ? potentialTypes : potentialTypes[0];
}
};
/***/ }),
/* 5 */
/***/ (function(module, exports, __webpack_require__) {
const ErrorList = __webpack_require__(6);
const ProcessGraphError = __webpack_require__(1);
const ProcessGraphNode = __webpack_require__(2);
const Utils = __webpack_require__(0);
const VARIABLE_TYPES = ['string', 'number', 'boolean', 'array', 'object'];
module.exports = class ProcessGraph {
constructor(jsonProcessGraph, processRegistry) {
this.json = jsonProcessGraph;
this.processRegistry = processRegistry;
this.nodes = [];
this.startNodes = {};
this.resultNode = null;
this.childrenProcessGraphs = [];
this.parentNode = null;
this.parentParameterName = null;
this.variables = {};
this.parsed = false;
this.validated = false;
this.errors = new ErrorList();
this.parameters = {};
}
toJSON() {
return this.json;
}
createNodeInstance(json, id, parent) {
return new ProcessGraphNode(json, id, parent);
}
createProcessGraphInstance(json) {
return new ProcessGraph(json, this.processRegistry);
}
setParent(node, parameterName) {
this.parentNode = node;
this.parentParameterName = parameterName;
}
isValid() {
return this.validated && this.errors.count() === 0;
}
addError(error) {
this.errors.add(error);
}
parse() {
if (this.parsed) {
return;
}
for(let id in this.json) {
this.nodes[id] = this.createNodeInstance(this.json[id], id, this);
}
for(let id in this.nodes) {
var node = this.nodes[id];
if (node.isResultNode) {
if (this.resultNode !== null) {
throw this.parentNode ? new ProcessGraphError('MultipleResultNodesCallback', {node_id: this.parentNode.id, process_id: this.parentNode.process_id}) : new ProcessGraphError('MultipleResultNodes');
}
this.resultNode = node;
}
this.parseArguments(id, node);
}
if (!this.findStartNodes()) {
throw this.parentNode ? new ProcessGraphError('StartNodeMissingCallback', {node_id: this.parentNode.id, process_id: this.parentNode.process_id}) : new ProcessGraphError('StartNodeMissing');
}
if (this.resultNode === null) {
throw this.parentNode ? new ProcessGraphError('ResultNodeMissingCallback', {node_id: this.parentNode.id, process_id: this.parentNode.process_id}) : new ProcessGraphError('ResultNodeMissing');
}
this.parsed = true;
}
async validate(throwOnErrors = true) {
if (this.validated) {
return null;
}
this.validated = true;
// Parse
try {
this.parse();
} catch (error) {
this.addError(error);
}
// Validate
await this.validateNodes(this.getStartNodes(), throwOnErrors);
return this.errors;
}
async execute(parameters = null) {
await this.validate();
this.reset();
this.setParameters(parameters);
await this.executeNodes(this.getStartNodes());
return this.getResultNode();
}
async validateNodes(nodes, throwsOnErrors, previousNode = null) {
if (nodes.length === 0) {
return;
}
var promises = nodes.map(async (node) => {
// Validate this node after all dependencies are available
if (!node.solveDependency(previousNode)) {
return;
}
// Get process and validate
try {
await this.validateNode(node);
} catch (e) {
if (e instanceof ErrorList) {
this.errors.merge(e);
if (throwsOnErrors) {
throw e.first();
}
}
else {
this.addError(e);
if (throwsOnErrors) {
throw e;
}
}
}
await this.validateNodes(node.getNextNodes(), throwsOnErrors, node);
});
await Promise.all(promises);
}
async validateNode(node) {
var process = this.getProcess(node);
return await process.validate(node);
}
async executeNodes(nodes, previousNode = null) {
if (nodes.length === 0) {
return;
}
var promises = nodes.map(async (node) => {
// Execute this node after all dependencies are available
if (!node.solveDependency(previousNode)) {
return;
}
var result = await this.executeNode(node);
node.setResult(result);
// Execute next nodes in chain
await this.executeNodes(node.getNextNodes(), node);
});
return Promise.all(promises);
}
async executeNode(node) {
var process = this.getProcess(node);
return await process.execute(node);
}
parseArguments(nodeId, node, args) {
if (typeof args === 'undefined') {
args = node.arguments;
}
for(var argumentName in args) {
var arg = args[argumentName];
var type = ProcessGraphNode.getType(arg);
switch(type) {
case 'result':
this.connectNodes(node, arg.from_node);
break;
case 'variable':
this.parseVariable(arg);
break;
case 'callback':
arg.callback = this.createProcessGraph(arg.callback, node, argumentName);
break;
case 'callback-argument':
this.parseCallbackArgument(node, arg.from_argument);
break;
case 'array':
case 'object':
this.parseArguments(nodeId, node, arg);
break;
}
}
}
parseCallbackArgument(node, name) {
var cbParams = this.getCallbackParameters();
if (!Utils.isObject(cbParams) || !cbParams.hasOwnProperty(name)) {
throw new ProcessGraphError('CallbackArgumentInvalid', {
argument: name,
node_id: node.id,
process_id: node.process_id
});
}
}
createProcessGraph(json, node, argumentName) {
var pg = this.createProcessGraphInstance(json);
pg.setParent(node, argumentName);
pg.parse();
this.childrenProcessGraphs.push(pg);
return pg;
}
parseVariable(variable) {
// Check whether the variable id is valid
if (typeof variable.variable_id !== 'string') {
throw new ProcessGraphError('VariableIdInvalid');
}
var obj = {};
// Check whether the data type is valid
if (typeof variable.type !== 'undefined' && !VARIABLE_TYPES.includes(variable.type)) {
throw new ProcessGraphError('VariableTypeInvalid', variable);
}
obj.type = typeof variable.type !== 'undefined' ? variable.type : 'string';
// Check whether the defult value has the correct data type
var defaultType = ProcessGraphNode.getType(variable.default);
if (defaultType !== 'undefined') {
if (defaultType !== obj.type) {
throw new ProcessGraphError('VariableDefaultValueTypeInvalid', variable);
}
else {
obj.value = variable.default;
}
}
}
setParameters(parameters) {
if (typeof parameters === 'object' && parameters !== null) {
this.parameters = parameters;
}
}
getParameter(name) {
return this.parameters[name];
}
setVariableValues(variables) {
for(var i in variables) {
this.setVariable(i, variables[i]);
}
}
setVariableValue(id, value) {
if (typeof this.variables[id] !== 'object') {
this.variables[id] = {};
}
this.variables[id].value = value;
}
getVariableValue(id) {
var variable = this.variables[id];
if (typeof variable !== 'object' || typeof variable.value === 'undefined') {
throw new ProcessGraphError('VariableValueMissing', {variable_id: id});
}
var type = ProcessGraphNode.getType(variable.value);
if (type !== variable.type) {
throw new ProcessGraphError('VariableValueTypeInvalid', {variable_id: id, type: variable.type});
}
return this.variables[id].value;
}
connectNodes(node, prevNodeId) {
var prevNode = this.nodes[prevNodeId];
if (typeof prevNode === 'undefined') {
throw new ProcessGraphError('ReferencedNodeMissing', {node_id: prevNodeId});
}
node.addPreviousNode(prevNode);
prevNode.addNextNode(node);
}
findStartNodes() {
var found = false;
for(var id in this.nodes) {
var node = this.nodes[id];
if (node.isStartNode()) {
this.startNodes[id] = node;
found = true;
}
}
return found;
}
reset() {
for(var id in this.nodes) {
this.nodes[id].reset();
}
this.childrenProcessGraphs.forEach(child => child.reset());
}
getResultNode() {
return this.resultNode;
}
getStartNodes() {
return Object.values(this.startNodes);
}
getStartNodeIds() {
return Object.keys(this.startNodes);
}
getNode(nodeId) {
return this.nodes[nodeId];
}
getNodes() {
return this.nodes;
}
getErrors() {
return this.errors;
}
getProcess(node) {
var process = this.processRegistry.get(node.process_id);
if (process === null) {
throw new ProcessGraphError('ProcessUnsupported', {process: node.process_id});
}
return process;
}
getCallbackParameters() {
if (!this.parentNode || !this.parentParameterName) {
return {};
}
var process = this.getProcess(this.parentNode);
var schema = process.schema.parameters[this.parentParameterName].schema;
if (Utils.isObject(schema.parameters)) {
return schema.parameters;
}
// ToDo: If a process parameter supports multiple different callbacks, i.e. reduce with either an array of two separate values, this
// can't be separated accordingly and we just return all potential values. So it might happen that people get a successful validation
// but they used the wrong callback parameters.
// See issue https://github.com/Open-EO/openeo-js-commons/issues/6
var cbParams = {};
var choice = schema.anyOf || schema.oneOf || schema.allOf;
if (Array.isArray(choice)) {
for(let i in choice) {
var p = choice[i];
if (Utils.isObject(p.parameters)) {
Object.assign(cbParams, p.parameters);
}
}
}
return cbParams;
}
};
/***/ }),
/* 6 */
/***/ (function(module, exports) {
module.exports = class ErrorList {
constructor() {
this.errors = [];
}
first() {
return this.errors[0] || null;
}
last() {
return this.errors[this.errors.length-1] || null;
}
merge(errorList) {
this.errors = this.errors.concat(errorList.getAll());
}
add(error) {
this.errors.push(error);
}
count() {
return this.errors.length;
}
toJSON() {
return this.errors.map(e => {
if (typeof e.toJSON === 'function') {
return e.toJSON();
}
else {
return {
code: 'InternalError',
message: e.message
};
}
});
}
getMessage() {
var msg = '';
for (var i in this.errors) {
msg += (parseInt(i, 10)+1) + ". " + this.errors[i].message + "\r\n";
}
return msg.trim();
}
getAll() {
return this.errors;
}
};
/***/ }),
/* 7 */
/***/ (function(module, exports, __webpack_require__) {
// Migrations
const MigrateCapabilities = __webpack_require__(8);
const MigrateCollections = __webpack_require__(10);
const MigrateProcesses = __webpack_require__(11);
// Process graphs
const BaseProcess = __webpack_require__(3);
const JsonSchemaValidator = __webpack_require__(4);
const ProcessGraph = __webpack_require__(5);
const ProcessGraphError = __webpack_require__(1);
const ProcessGraphNode = __webpack_require__(2);
const ProcessRegistry = __webpack_require__(13);
// Others
const ErrorList = __webpack_require__(6);
const FeatureList = __webpack_require__(14);
const Utils = __webpack_require__(0);
module.exports = {
MigrateCapabilities,
MigrateCollections,
MigrateProcesses,
BaseProcess,
JsonSchemaValidator,
ProcessGraph,
ProcessGraphError,
ProcessGraphNode,
ProcessRegistry,
ErrorList,
FeatureList,
Utils
};
/***/ }),
/* 8 */
/***/ (function(module, exports, __webpack_require__) {
const Utils = __webpack_require__(0);
var MigrateCapabilities = {
guessApiVersion(capabilties) {
if (typeof capabilties.version === 'string') {
return capabilties.version;
}
else if (typeof capabilties.api_version === 'string') {
return capabilties.api_version;
}
else if (capabilties.backend_version || capabilties.title || capabilties.description || capabilties.links) {
return "0.4";
}
else {
// This is a wild guess
return "0.3";
}
},
// Always returns a copy of the input object
convertCapabilitiesToLatestSpec(originalCapabilities, version = null, title = "Unknown") {
var capabilities = Object.assign({}, originalCapabilities);
if (version === null) {
version = this.guessApiVersion(capabilities);
}
// convert v0.3 capabilities to v0.4 format
if (Utils.compareVersion(version, "0.3.x") === 0) {
// version => api_version
if (typeof capabilities.version !== 'undefined') {
delete capabilities.version;
}
}
// Convert billing plans
if (typeof capabilities.billing !== 'undefined') {
capabilities.billing = this.convertBillingToLatestSpec(capabilities.billing, version);
}
// Convert endpoints
capabilities.endpoints = this.convertEndpointsToLatestSpec(capabilities.endpoints, version);
// Add missing fields with somewhat useful data
if (typeof capabilities.api_version !== 'string') {
capabilities.api_version = "0.4.0";
}
if (typeof capabilities.backend_version !== 'string') {
capabilities.backend_version = "Unknown";
}
if (typeof capabilities.title !== 'string') {
capabilities.title = title;
}
if (typeof capabilities.description !== 'string') {
capabilities.description = "No description provided.";
}
return capabilities;
},
// Always returns a copy of the input object
convertBillingToLatestSpec(originalBilling, version) {
var billing = Object.assign({}, originalBilling);
// convert v0.3 billing info to v0.4 format
if (Utils.compareVersion(version, "0.3.x") === 0) {
// Add paid flag to billing plans
if (Array.isArray(billing.plans)) {
billing.plans = billing.plans.map(plan => {
if (typeof plan.paid !== 'boolean') {
plan.paid = true;
if (typeof plan.name === 'string' && plan.name.toLowerCase().includes('free')) {
plan.paid = false;
}
}
return plan;
});
}
}
return billing;
},
// Always returns a copy of the input object
convertEndpointsToLatestSpec(originalEndpoints, version) {
var endpoints = [];
if (Array.isArray(originalEndpoints)) {
endpoints = originalEndpoints.slice(0);
}
// convert v0.3 service types to v0.4 format
if (Utils.compareVersion(version, "0.3.x") === 0) {
// Nothing to do as nothing has changed.
}
return endpoints;
},
// Always returns a copy of the input object
convertOutputFormatsToLatestSpec(originalFormats, version) {
var formats = Object.assign({}, originalFormats);
// convert v0.3 output formats to v0.4 format
if (Utils.compareVersion(version, "0.3.x") === 0) {
if (typeof formats.formats === 'object' && formats.formats !== null) {
return formats.formats;
}
}
return formats;
},
// Always returns a copy of the input object
convertServiceTypesToLatestSpec(originalTypes, version) {
var types = Object.assign({}, originalTypes);
// convert v0.3 service types to v0.4 format
if (Utils.compareVersion(version, "0.3.x") === 0) {
// Nothing to do as nothing has changed.
}
return types;
}
};
module.exports = MigrateCapabilities;
/***/ }),
/* 9 */
/***/ (function(module, exports, __webpack_require__) {
var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/* global define */
(function (root, factory) {
/* istanbul ignore next */
if (true) {
!(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory),
__WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ?
(__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__),
__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
} else {}
}(this, function () {
var semver = /^v?(?:\d+)(\.(?:[x*]|\d+)(\.(?:[x*]|\d+)(\.(?:[x*]|\d+))?(?:-[\da-z\-]+(?:\.[\da-z\-]+)*)?(?:\+[\da-z\-]+(?:\.[\da-z\-]+)*)?)?)?$/i;
function indexOrEnd(str, q) {
return str.indexOf(q) === -1 ? str.length : str.indexOf(q);
}
function split(v) {
var c = v.replace(/^v/, '').replace(/\+.*$/, '');
var patchIndex = indexOrEnd(c, '-');
var arr = c.substring(0, patchIndex).split('.');
arr.push(c.substring(patchIndex + 1));
return arr;
}
function tryParse(v) {
return isNaN(Number(v)) ? v : Number(v);
}
function validate(version) {
if (typeof version !== 'string') {
throw new TypeError('Invalid argument expected string');
}
if (!semver.test(version)) {
throw new Error('Invalid argument not valid semver (\''+version+'\' received)');
}
}
return function compareVersions(v1, v2) {
[v1, v2].forEach(validate);
var s1 = split(v1);
var s2 = split(v2);
for (var i = 0; i < Math.max(s1.length - 1, s2.length - 1); i++) {
var n1 = parseInt(s1[i] || 0, 10);
var n2 = parseInt(s2[i] || 0, 10);
if (n1 > n2) return 1;
if (n2 > n1) return -1;
}
var sp1 = s1[s1.length - 1];
var sp2 = s2[s2.length - 1];
if (sp1 && sp2) {
var p1 = sp1.split('.').map(tryParse);
var p2 = sp2.split('.').map(tryParse);
for (i = 0; i < Math.max(p1.length, p2.length); i++) {
if (p1[i] === undefined || typeof p2[i] === 'string' && typeof p1[i] === 'number') return -1;
if (p2[i] === undefined || typeof p1[i] === 'string' && typeof p2[i] === 'number') return 1;
if (p1[i] > p2[i]) return 1;
if (p2[i] > p1[i]) return -1;
}
} else if (sp1 || sp2) {
return sp1 ? -1 : 1;
}
return 0;
};
}));
/***/ }),
/* 10 */
/***/ (function(module, exports, __webpack_require__) {
const Utils = __webpack_require__(0);
var MigrateCollections = {
guessCollectionSpecVersion(c) {
var version = "0.4";
// Try to guess a version
if (typeof c.id === 'undefined' && typeof c.name !== 'undefined') { // No id defined, probably v0.3
version = "0.3";
}
return version;
},
// Always returns a copy of the input collection object
convertCollectionToLatestSpec(originalCollection, version = null) {
var collection = Object.assign({}, originalCollection);
if (!Object.keys(collection).length) {
return collection;
}
if (version === null) {
version = this.guessCollectionSpecVersion(collection);
}
// convert v0.3 processes to v0.4 format
if (Utils.compareVersion(version, "0.3.x") === 0) {
// name => id
collection.id = collection.name;
delete collection.name;
// Add stac_version
collection.stac_version = '0.6.1';
// Rename provider => providers
if (Array.isArray(collection.provider)) {
collection.providers = collection.provider;
delete collection.provider;
}
if (typeof collection.properties !== 'object') {
collection.properties = {};
}
// Migrate eo:bands
if (collection['eo:bands'] !== null && typeof collection['eo:bands'] === 'object' && !Array.isArray(collection['eo:bands'])) {
var bands = [];
for(let key in collection['eo:bands']) {
var band = Object.assign({}, collection['eo:bands'][key]);
band.name = key;
if (typeof band.resolution !== 'undefined' && typeof band.gsd === 'undefined') {
band.gsd = band.resolution;
delete band.resolution;
}
if (typeof band.wavelength !== 'undefined' && typeof band.center_wavelength === 'undefined') {
band.center_wavelength = band.wavelength;
delete band.wavelength;
}
bands.push(band);
}
collection['eo:bands'] = bands;
}
// Move all other properties into properties.
for (let key in collection) {
if (key.includes(':')) {
collection.properties[key] = collection[key];
delete collection[key];
}
}
}
return collection;
}
};
module.exports = MigrateCollections;
/***/ }),
/* 11 */
/***/ (function(module, exports, __webpack_require__) {
const Utils = __webpack_require__(0);
var MigrateProcesses = {
guessProcessSpecVersion(p) {
var version = "0.4";
// Try to guess a version
if (typeof p.id === 'undefined' && typeof p.name !== 'undefined') { // No id defined, probably v0.3
version = "0.3";
}
return version;
},
// Always returns a copy of the input process object
convertProcessToLatestSpec(originalProcess, version = null) {
var process = Object.assign({}, originalProcess);
if (version === null) {
version = this.guessProcessSpecVersion(process);
}
// convert v0.3 processes to v0.4 format
if (Utils.compareVersion(version, "0.3.x") === 0) {
// name => id
process.id = process.name;
delete process.name;
// mime_type => media_type
if (typeof process.parameters === 'object') {
for(var key in process.parameters) {
if (typeof process.parameters[key].mime_type !== 'undefined') {
var param = Object.assign({}, process.parameters[key]);
param.media_type = param.mime_type;
delete param.mime_type;
process.parameters[key] = param;
}
}
}
if (typeof process.returns === 'object' && typeof process.returns.mime_type !== 'undefined') {
process.returns.media_type = process.returns.mime_type;
delete process.returns.mime_type;
}
// exception object
if (typeof process.exceptions === 'object') {
for(let key in process.exceptions) {
var e = process.exceptions[key];
if (typeof e.message === 'undefined') {
process.exceptions[key] = Object.assign({}, e, {
message: e.description
});
}
}
}
// examples object
if (typeof process.examples === 'object') {
var examples = [];
for(let key in process.examples) {
var old = process.examples[key];
var example = {
title: old.summary || key,
description: old.description
};
if (old.process_graph) {
example.process_graph = old.process_graph;
}
examples.push(example);
}
process.examples = examples;
}
// Fill parameter order
if (typeof process.parameters === 'object' && !Array.isArray(process.parameter_order)) {
var parameter_order = Object.keys(process.parameters);
if (parameter_order.length > 1) {
process.parameter_order = parameter_order;
}
}
}
return process;
}
};
module.exports = MigrateProcesses;
/***/ }),
/* 12 */
/***/ (function(module, exports) {
module.exports = __WEBPACK_EXTERNAL_MODULE__12__;
/***/ }),
/* 13 */
/***/ (function(module, exports, __webpack_require__) {
const BaseProcess = __webpack_require__(3);
const Utils = __webpack_require__(0);
module.exports = class ProcessRegistry {
constructor() {
// Keys added to this object must be lowercase!
this.processes = {};
}
addFromResponse(response) {
for(var i in response.processes) {
this.add(response.processes[i]);
}
}
add(process) {
this.processes[process.id] = new BaseProcess(process);
}
count() {
return Utils.size(this.processes);
}
get(id) {
var pid = id.toLowerCase();
if (typeof this.processes[pid] !== 'undefined') {
return this.processes[pid];
}
return null;
}
getSchema(id) {
var p = this.get(id);
return p !== null ? p.schema : null;
}
getProcessSchemas() {
return Object.values(this.processes).map(impl => impl.schema);
}
};
/***/ }),
/* 14 */
/***/ (function(module, exports, __webpack_require__) {
const Utils = __webpack_require__(0);
var FeatureList = {
// Manual assignment of the endpoints above to individual features.
// A functionality is considered supported when ALL of the corresponding endpoints are supported.
features: {
'Basic functionality': [
'get /collections',
'get /collections/{}',
'get /processes',
'get /output_formats'
],
'Authenticate with HTTP Basic': [ // TODO: Remove later because this auth method should not be used
'get /credentials/basic',
// 'get /me' // not necessarily needed (just outputs metadata)
],
'Authenticate with OpenID Connect': [ // TODO: Remove later because the user doesn't care HOW the auth works
'get /credentials/oidc',
// 'get /me' // not necessarily needed (just outputs metadata)
],
'Batch processing': [
'get /jobs',
'post /jobs',
'get /jobs/{}',
// 'patch /jobs/{}', // not necessarily needed (can be achieved by deleting and re-creating)
'delete /jobs/{}',
'get /jobs/{}/results',
'post /jobs/{}/results',
// 'delete /jobs/{}/results' // not necessarily needed (can be deleted by deleting the entire job)
],
'Estimate processing costs': [
'get /jobs/{}/estimate'
],
'Preview processing results': [
'post /result'
],
'Secondary web services': [
'get /service_types',
'get /services',
'post /services',
'get /services/{}',
// 'patch /services/{}', // not necessarily needed (can be achieved by deleting and re-creating)
'delete /services/{}',
],
'File storage': [
'get /files/{}',
'get /files/{}/{}',
'put /files/{}/{}',
'delete /files/{}/{}'
],
'Stored process graphs': [
'get /process_graphs',
'post /process_graphs',
'get /process_graphs/{}',
// 'patch /process_graphs/{}', // not necessarily needed (can be achieved by deleting and re-creating)
'delete /process_graphs/{}'
],
'Validate process graphs': [
'post /validation',
],
'Notifications and monitoring': [
'get /subscription'
],
'User defined functions (UDF)': [
'get /udf_runtimes'
]
},
legacyFeatures: {
'post /result': {
'post /preview': ["0.3.*"]
}
},
getListForVersion(version) {
var list = {};
for(var feature in this.features) {
list[feature] = [];
for(var i in this.features[feature]) {
var endpoint = this.findLegacyEndpoint(version, this.features[feature][i]);
list[feature].push(endpoint);
}
}
return list;
},
findLegacyEndpoint(version, endpoint, method = null) {
if (method !== null) {
endpoint = this.endpointToString(method, endpoint);
}
if (typeof this.legacyFeatures[endpoint] === 'object') {
var legacy = this.legacyFeatures[endpoint];
for(var legacyEndpoint in legacy) {
for(var i in legacy[legacyEndpoint]) {
var legacyVersion = legacy[legacyEndpoint][i];
if (Utils.compareVersion(version, legacyVersion) === 0) {
return legacyEndpoint;
}
}
}
}
return endpoint;
},
getFeatures() {
return Object.keys(this.features);
},
getFeatureCount() {
return Object.keys(this.features).length;
},
endpointsToStringList(endpoints) {
var list = [];
for(let i in endpoints) {
for(let j in endpoints[i].methods) {
list.push(this.endpointToString(endpoints[i].methods[j], endpoints[i].path));
}
}
return list;
},
endpointToString(method, path) {
// allow arbitrary parameter names => don't care about content in curly brackets
let request = method + ' ' + path.replace(/{[^}]+}/g, '{}');
return request.toLowerCase();
},
getReport(endpoints, version, convert = true) {
var supportedFeatureCount = 0;
var supportedEndpoints = convert ? this.endpointsToStringList(endpoints) : endpoints;
var status = this.getListForVersion(version);
// Assign each functionality a supported flag (0 = none, 1 = partially, 2 = fully)
Object.keys(status).forEach(key => {
let requiredEndpoints = status[key];
// Get a list of unsupported, but required endpoints
let unsupported = requiredEndpoints.filter(requiredEndpoint => !supportedEndpoints.includes(requiredEndpoint));
switch(unsupported.length) {
// No unsupported endpoints => fully supported
case 0:
status[key] = 2;
supportedFeatureCount++;
break;
// All endpoints are unsupported
case requiredEndpoints.length:
status[key] = 0;
break;
// Some endpoints are supported => partially supported
default:
status[key] = 1;
}
});
return {
count: supportedFeatureCount,
list: status
};
}
};
module.exports = FeatureList;
/***/ })
/******/ ]);
});

31

package.json
{
"name": "@openeo/js-commons",
"version": "0.4.0-beta.2",
"version": "0.4.0",
"author": "openEO Consortium",

@@ -12,2 +12,3 @@ "contributors": [

"license": "Apache-2.0",
"homepage": "http://openeo.org",
"bugs": {

@@ -25,16 +26,11 @@ "url": "https://github.com/open-eo/openeo-js-commons/issues"

],
"scripts": {
"build": "npx webpack",
"test": "jest --env=jsdom",
"test_node": "jest --env=node"
},
"peerDependencies": {
"ajv": "^6.10.0"
},
"dependencies": {
"compare-versions": "^3.4.0"
},
"devDependencies": {
"jest": "^24.5.0",
"jest": "^24.7.1",
"jest-html-reporter": "^2.5.0",
"jsdoc": "^3.5.5",
"jshint": "^2.10.2",
"unminified-webpack-plugin": "^2.0.0",
"webpack": "^4.30.0",

@@ -44,7 +40,12 @@ "webpack-bundle-analyzer": "^3.3.2",

},
"browserslist": [
"> 3%",
"last 2 versions",
"not ie < 11"
]
"dependencies": {
"compare-versions": "^3.4.0"
},
"scripts": {
"docs": "jsdoc src -r -d docs/ -P package.json -R README.md",
"build": "npx webpack",
"compat": "jshint src",
"test": "jest --env=jsdom",
"test_node": "jest --env=node"
}
}
# openeo-js-commons
A set of common JavaScript functionalities for [openEO](http://openeo.org).
**Version: 0.4.0-beta.1**, supports openEO API v0.4.0.
[![Build Status](https://travis-ci.org/Open-EO/openeo-js-commons.svg?branch=master)](https://travis-ci.org/Open-EO/openeo-js-commons)
This library's version is **0.4.0** and supports **openEO API version 0.4.x**. Legacy versions are available as releases.
## Features
- Converting responses to the latest API version is supported for:
- Capabilities
- Collections
- Processes
- Output Formats
- Service Types
- Capabilities
- Collections
- Processes
- Output Formats
- Service Types
- Feature detection
- Process graph handling:
- Parsing a process graph
- Validation based on the JSON Schemas
- Framework to implement process graph execution
- Parsing a process graph
- Validation based on the JSON Schemas
- Framework to implement process graph execution
- JSON Schema validation for Process parameters and return values

@@ -28,10 +30,12 @@

```html
<script src="https://cdn.jsdelivr.net/npm/@openeo/js-commons@0.4/dist/main.min.js"></script>
```
<script src="https://cdn.jsdelivr.net/npm/@openeo/js-commons@0.4.0/dist/main.min.js"></script>
```
This library has a peer dependency to `ajv`, so if you'd like to use process graph validation or execution you need to include `ajv` (v6.10) in your package.json or include it in your web page:
```html
<script src="https://cdn.jsdelivr.net/npm/ajv@6.10/lib/ajv.min.js"></script>
```
<script src="https://cdn.jsdelivr.net/npm/ajv@6.10.0/lib/ajv.min.js"></script>
```
More information can be found in the [**JS commons documentation**](https://open-eo.github.io/openeo-js-commons/0.4.0/).

@@ -8,7 +8,11 @@ module.exports = class ErrorList {

first() {
return this.errors[0];
return this.errors[0] || null;
}
last() {
return this.errors[this.errors.length-1] || null;
}
merge(errorList) {
this.errors.concat(errorList.getAll());
this.errors = this.errors.concat(errorList.getAll());
}

@@ -41,3 +45,3 @@

for (var i in this.errors) {
msg += (parseInt(i)+1) + ". " + this.errors[i].message + "\r\n";
msg += (parseInt(i, 10)+1) + ". " + this.errors[i].message + "\r\n";
}

@@ -51,2 +55,2 @@ return msg.trim();

}
};

@@ -15,7 +15,7 @@ const Utils = require('./utils.js');

'get /credentials/basic',
// 'get /me' // not necessarily needed (just outputs metadata)
// 'get /me' // not necessarily needed (just outputs metadata)
],
'Authenticate with OpenID Connect': [ // TODO: Remove later because the user doesn't care HOW the auth works
'get /credentials/oidc',
// 'get /me' // not necessarily needed (just outputs metadata)
// 'get /me' // not necessarily needed (just outputs metadata)
],

@@ -26,7 +26,7 @@ 'Batch processing': [

'get /jobs/{}',
// 'patch /jobs/{}', // not necessarily needed (can be achieved by deleting and re-creating)
// 'patch /jobs/{}', // not necessarily needed (can be achieved by deleting and re-creating)
'delete /jobs/{}',
'get /jobs/{}/results',
'post /jobs/{}/results',
// 'delete /jobs/{}/results' // not necessarily needed (can be deleted by deleting the entire job)
// 'delete /jobs/{}/results' // not necessarily needed (can be deleted by deleting the entire job)
],

@@ -44,3 +44,3 @@ 'Estimate processing costs': [

'get /services/{}',
// 'patch /services/{}', // not necessarily needed (can be achieved by deleting and re-creating)
// 'patch /services/{}', // not necessarily needed (can be achieved by deleting and re-creating)
'delete /services/{}',

@@ -58,3 +58,3 @@ ],

'get /process_graphs/{}',
// 'patch /process_graphs/{}', // not necessarily needed (can be achieved by deleting and re-creating)
// 'patch /process_graphs/{}', // not necessarily needed (can be achieved by deleting and re-creating)
'delete /process_graphs/{}'

@@ -79,3 +79,3 @@ ],

getListForVersion(version) {
getListForVersion(version) {
var list = {};

@@ -82,0 +82,0 @@ for(var feature in this.features) {

@@ -22,3 +22,3 @@ const Utils = require('../utils.js');

// Always returns a copy of the input object
convertCapabilitiesToLatestSpec: function(originalCapabilities, version = null, title = "Unknown") {
convertCapabilitiesToLatestSpec(originalCapabilities, version = null, title = "Unknown") {
var capabilities = Object.assign({}, originalCapabilities);

@@ -61,3 +61,3 @@ if (version === null) {

// Always returns a copy of the input object
convertBillingToLatestSpec: function(originalBilling, version) {
convertBillingToLatestSpec(originalBilling, version) {
var billing = Object.assign({}, originalBilling);

@@ -84,3 +84,3 @@ // convert v0.3 billing info to v0.4 format

// Always returns a copy of the input object
convertEndpointsToLatestSpec: function(originalEndpoints, version) {
convertEndpointsToLatestSpec(originalEndpoints, version) {
var endpoints = [];

@@ -98,3 +98,3 @@ if (Array.isArray(originalEndpoints)) {

// Always returns a copy of the input object
convertOutputFormatsToLatestSpec: function(originalFormats, version) {
convertOutputFormatsToLatestSpec(originalFormats, version) {
var formats = Object.assign({}, originalFormats);

@@ -111,3 +111,3 @@ // convert v0.3 output formats to v0.4 format

// Always returns a copy of the input object
convertServiceTypesToLatestSpec: function(originalTypes, version) {
convertServiceTypesToLatestSpec(originalTypes, version) {
var types = Object.assign({}, originalTypes);

@@ -114,0 +114,0 @@ // convert v0.3 service types to v0.4 format

@@ -15,3 +15,3 @@ const Utils = require('../utils.js');

// Always returns a copy of the input collection object
convertCollectionToLatestSpec: function(originalCollection, version = null) {
convertCollectionToLatestSpec(originalCollection, version = null) {
var collection = Object.assign({}, originalCollection);

@@ -43,3 +43,3 @@ if (!Object.keys(collection).length) {

var bands = [];
for(var key in collection['eo:bands']) {
for(let key in collection['eo:bands']) {
var band = Object.assign({}, collection['eo:bands'][key]);

@@ -60,3 +60,3 @@ band.name = key;

// Move all other properties into properties.
for (var key in collection) {
for (let key in collection) {
if (key.includes(':')) {

@@ -63,0 +63,0 @@ collection.properties[key] = collection[key];

@@ -15,3 +15,3 @@ const Utils = require('../utils.js');

// Always returns a copy of the input process object
convertProcessToLatestSpec: function(originalProcess, version = null) {
convertProcessToLatestSpec(originalProcess, version = null) {
var process = Object.assign({}, originalProcess);

@@ -44,3 +44,3 @@ if (version === null) {

if (typeof process.exceptions === 'object') {
for(var key in process.exceptions) {
for(let key in process.exceptions) {
var e = process.exceptions[key];

@@ -57,3 +57,3 @@ if (typeof e.message === 'undefined') {

var examples = [];
for(var key in process.examples) {
for(let key in process.examples) {
var old = process.examples[key];

@@ -60,0 +60,0 @@ var example = {

@@ -28,9 +28,13 @@ const Utils = require('../utils');

constructor(code, variables = {}) {
constructor(codeOrMsg, variables = {}) {
super();
this.code = code;
this.variables = variables;
if (typeof MESSAGES[code] === 'string') {
this.message = Utils.replacePlaceholders(MESSAGES[code], variables);
if (typeof MESSAGES[codeOrMsg] === 'string') {
this.code = codeOrMsg;
this.message = Utils.replacePlaceholders(MESSAGES[codeOrMsg], variables);
}
else {
this.code = codeOrMsg.replace(/[^\w\d]+/g, '');
this.message = codeOrMsg;
}
}

@@ -42,5 +46,5 @@

message: this.message
}
};
}
}
};

@@ -6,3 +6,3 @@ const ajv = require('ajv');

constructor(options) {
constructor() {
var ajvOptions = {

@@ -12,19 +12,20 @@ schemaId: 'auto',

formats: {
'band-name': {type: 'string', validate: this.validateBandName.bind(this)},
'bounding-box': {type: 'object', validate: this.validateBoundingBox.bind(this)},
'callback': {type: 'object', validate: this.validateCallback.bind(this)},
'collection-id': {type: 'string', validate: this.validateCollectionId.bind(this)},
'epsg-code': {type: 'integer', validate: this.validateEpsgCode.bind(this)},
'geojson': {type: 'object', validate: this.validateGeoJson.bind(this)},
// See issue https://github.com/Open-EO/openeo-js-commons/issues/4 for information on why ajv doesn't support non-string validation
'band-name': {type: 'string', async: true, validate: this.validateBandName.bind(this)},
'bounding-box': {type: 'object', async: true, validate: this.validateBoundingBox.bind(this)}, // Currently not supported by ajv 6.10
'callback': {type: 'object', async: true, validate: this.validateCallback.bind(this)}, // Currently not supported by ajv 6.10
'collection-id': {type: 'string', async: true, validate: this.validateCollectionId.bind(this)},
'epsg-code': {type: 'integer', async: true, validate: this.validateEpsgCode.bind(this)}, // Currently not supported by ajv 6.10
'geojson': {type: 'object', async: true, validate: this.validateGeoJson.bind(this)}, // Currently not supported by ajv 6.10
'job-id': {type: 'string', async: true, validate: this.validateJobId.bind(this)},
'kernel': {type: 'array', validate: this.validateKernel.bind(this)},
'output-format': {type: 'string', validate: this.validateOutputFormat.bind(this)},
'output-format-options': {type: 'array', validate: this.validateOutputFormatOptions.bind(this)},
'kernel': {type: 'array', async: true, validate: this.validateKernel.bind(this)}, // Currently not supported by ajv 6.10
'output-format': {type: 'string', async: true, validate: this.validateOutputFormat.bind(this)},
'output-format-options': {type: 'array', async: true, validate: this.validateOutputFormatOptions.bind(this)}, // Currently not supported by ajv 6.10
'process-graph-id': {type: 'string', async: true, validate: this.validateProcessGraphId.bind(this)},
'process-graph-variables': {type: 'array', validate: this.validateProcessGraphVariables.bind(this)},
'proj-definition': {type: 'string', validate: this.validateProjDefinition.bind(this)},
'raster-cube': {type: 'object', validate: this.validateRasterCube.bind(this)},
'temporal-interval': {type: 'array', validate: this.validateTemporalInterval.bind(this)},
'temporal-intervals': {type: 'array', validate: this.validateTemporalIntervals.bind(this)},
'vector-cube': {type: 'object', validate: this.validateVectorCube.bind(this)}
'process-graph-variables': {type: 'array', async: true, validate: this.validateProcessGraphVariables.bind(this)}, // Currently not supported by ajv 6.10
'proj-definition': {type: 'string', async: true, validate: this.validateProjDefinition.bind(this)},
'raster-cube': {type: 'object', async: true, validate: this.validateRasterCube.bind(this)}, // Currently not supported by ajv 6.10
'temporal-interval': {type: 'array', async: true, validate: this.validateTemporalInterval.bind(this)}, // Currently not supported by ajv 6.10
'temporal-intervals': {type: 'array', async: true, validate: this.validateTemporalIntervals.bind(this)}, // Currently not supported by ajv 6.10
'vector-cube': {type: 'object', async: true, validate: this.validateVectorCube.bind(this)} // Currently not supported by ajv 6.10
}

@@ -48,8 +49,4 @@ };

if (Utils.isObject(options)) {
this.collectionResolver = options.collectionResolver || null,
this.jobResolver = options.jobResolver || null;
this.pgResolver = options.pgResolver || null;
this.outputFormats = options.outputFormats || null;
}
this.outputFormats = null;
this.geoJsonValidator = null;
}

@@ -60,6 +57,6 @@

var clonedSchema = Object.assign({}, schema);
clonedSchema["$async"] = true;
if (typeof schema["$schema"] === 'undefined') {
// Set applicable JSON SChema draft version if not already set
clonedSchema["$schema"] = "http://json-schema.org/draft-07/schema#";
clonedSchema.$async = true;
if (typeof clonedSchema.$schema === 'undefined') {
// Set applicable JSON Schema draft version if not already set
clonedSchema.$schema = "http://json-schema.org/draft-07/schema#";
}

@@ -82,5 +79,5 @@

// Set applicable JSON SChema draft version if not already set
if (typeof schema["$schema"] === 'undefined') {
var schema = Object.assign({}, schema); // Make sure we don't alter the process registry
schema["$schema"] = "http://json-schema.org/draft-07/schema#";
if (typeof schema.$schema === 'undefined') {
schema = Object.assign({}, schema); // Make sure we don't alter the process registry
schema.$schema = "http://json-schema.org/draft-07/schema#";
}

@@ -92,17 +89,8 @@

// callback is an async function accepting a single parameter, which is the requested collection id. Must return a boolean (true = found, false = not found).
setCollectionResolver(callback) {
this.collectionResolver = callback;
// Pass the content of https://geojson.org/schema/GeoJSON.json
setGeoJsonSchema(schema) {
var gjv = new ajv();
this.geoJsonValidator = gjv.compile(schema);
}
// callback is an async function accepting a single parameter, which is the requested job id. Must return a boolean (true = found, false = not found).
setJobResolver(callback) {
this.jobResolver = callback;
}
// callback is an async function accepting a single parameter, which is the requested process graph id. Must return a boolean (true = found, false = not found).
setStoredProcessGraphResolver(callback) {
this.pgResolver = callback;
}
// Expects API compatible output formats (see GET /output_formats).

@@ -116,84 +104,172 @@ setOutputFormats(outputFormats) {

validateBandName(data) {
return true; // ToDo
/* istanbul ignore next */
async validateBandName(/*data*/) {
// Can't validate band name without knowing/loading the data.
// => To be overridden by end-user application.
return true;
}
validateBoundingBox(data) {
return true; // ToDo: Fully check against bounding box schema
/* istanbul ignore next */
async validateBoundingBox(/*data*/) {
// Nothing to validate, schema is (usually) delivered by processes.
return true;
}
validateCallback(data) {
return true; // ToDo
/* istanbul ignore next */
async validateCallback(/*data*/) {
// This should be checked by process graph parsing automatically.
// Otherwise to be overridden by end-user application.
return true;
}
async validateCollectionId(data) {
if (typeof this.collectionResolver === 'function') {
return this.collectionResolver(data);
}
/* istanbul ignore next */
async validateCollectionId(/*data*/) {
// To be overridden by end-user application.
return true;
}
validateEpsgCode(data) {
return true; // ToDo
async validateEpsgCode(data) {
// Rough check for valid numbers as we don't want to maintain a full epsg code list in this repo.
// Fully validation to be implemented by end-user application by overriding this method.
if (data >= 2000) {
return true;
}
throw new ajv.ValidationError([{
message: "Invalid EPSG code specified."
}]);
}
validateGeoJson(data) {
if (typeof data.type !== 'string') { // ToDo: Fully check against GeoJSON schema
throw new ajv.ValidationError([{
message: "Invalid GeoJSON specified (no type property)."
}]);
async validateGeoJson(data) {
if (this.geoJsonValidator !== null) {
if (!this.geoJsonValidator(data)) {
throw new ajv.ValidationError(ajv.errors);
}
return true;
}
else {
// A very rough GeoJSON validation if no GeoJSON schema is available.
if (typeof data.type !== 'string') {
throw new ajv.ValidationError([{
message: "Invalid GeoJSON specified (no type property)."
}]);
}
switch(data.type) {
case "Point":
case "MultiPoint":
case "LineString":
case "MultiLineString":
case "Polygon":
case "MultiPolygon":
if (!Array.isArray(data.coordinates)) {
throw new ajv.ValidationError([{
message: "Invalid GeoJSON specified (Geometry has no valid coordinates member)."
}]);
}
return true;
case "GeometryCollection":
if (!Array.isArray(data.geometries)) {
throw new ajv.ValidationError([{
message: "Invalid GeoJSON specified (GeometryCollection has no valid geometries member)."
}]);
}
return true;
case "Feature":
if (data.geometry !== null && !Utils.isObject(data.geometry)) {
throw new ajv.ValidationError([{
message: "Invalid GeoJSON specified (Feature has no valid geometry member)."
}]);
}
if (data.properties !== null && !Utils.isObject(data.properties)) {
throw new ajv.ValidationError([{
message: "Invalid GeoJSON specified (Feature has no valid properties member)."
}]);
}
return true;
case "FeatureCollection":
if (!Array.isArray(data.features)) {
throw new ajv.ValidationError([{
message: "Invalid GeoJSON specified (FeatureCollection has no valid features member)."
}]);
}
return true;
default:
throw new ajv.ValidationError([{
message: "Invalid GeoJSON type specified."
}]);
}
}
}
/* istanbul ignore next */
async validateJobId(/*data*/) {
// To be overridden by end-user application
return true;
}
async validateJobId(data) {
if (typeof this.jobResolver === 'function') {
return this.jobResolver(data);
}
/* istanbul ignore next */
async validateKernel(/*data*/) {
// ToDo? / To be overridden by end-user application
return true;
}
validateKernel(data) {
return true; // ToDo
}
validateOutputFormat(data) {
async validateOutputFormat(data) {
if (Utils.isObject(this.outputFormats) && !(data.toUpperCase() in this.outputFormats)) {
return false;
throw new ajv.ValidationError([{
message: "Output format not supported."
}]);
}
return true;
}
validateOutputFormatOptions(data) {
return true; // ToDO: This depends on the output format specified and can't be fully validated without knowning the chosen output format.
/* istanbul ignore next */
async validateOutputFormatOptions(/*data*/) {
// This depends on the output format specified and can't be fully validated without knowning the chosen output format.
return true;
}
async validateProcessGraphId(data) {
if (typeof this.pgResolver === 'function') {
return this.pgResolver(data);
}
/* istanbul ignore next */
async validateProcessGraphId(/*data*/) {
// To be overridden by end-user application
return true;
}
validateProcessGraphVariables(data) {
return true; // ToDo
/* istanbul ignore next */
async validateProcessGraphVariables(/*data*/) {
// Nothing to validate against...
return true;
}
validateProjDefinition(data) {
return true; // ToDo
async validateProjDefinition(data) {
// To be overridden by end-user application, just doing a very basic check here.
if (!data.toLowerCase().includes("+proj")) {
throw new ajv.ValidationError([{
message: "Invalid PROJ string specified (doesn't contain '+proj')."
}]);
}
return true;
}
validateRasterCube(data) {
return true; // ToDo
/* istanbul ignore next */
async validateRasterCube(/*data*/) {
// This is usually a reference to a process result as we haven't specified any JSON encoding for raster cubes.
return true;
}
validateTemporalInterval(data) {
return true; // ToDo: Fully check against schema (Array, two elements, both being null or date-time or date or time). Can't be both null...
async validateTemporalInterval(/*data*/) {
// ToDo: Fully check against schema, most is already checked by JSON Schemas itself, but check for example that
// both can't be null at the same time or the first element is > the second element.
return true;
}
validateTemporalIntervals(data) {
return true; // ToDo: Fully chack against schema (Array of the schema above)
async validateTemporalIntervals(data) {
var invalid = data.filter(x => !this.validateTemporalInterval(x));
return invalid.length === 0;
}
validateVectorCube(data) {
return true; // ToDo
/* istanbul ignore next */
async validateVectorCube(/*data*/) {
// This is usually a reference to a process result as we haven't specified any JSON encoding for raster cubes.
return true;
}

@@ -203,6 +279,65 @@

// So would a value compatible with valueSchema be accepted by paramSchema?
static isSchemaCompatible(paramSchema, valueSchema) {
return true; // ToDo: Implement
static isSchemaCompatible(paramSchema, valueSchema, strict = false) {
var paramSchemas = this._convertSchemaToArray(paramSchema);
var valueSchemas = this._convertSchemaToArray(valueSchema);
var compatible = paramSchemas.filter(ps => {
for(var i in valueSchemas) {
var vs = valueSchemas[i];
if (typeof ps.type !== 'string' || (!strict && typeof vs.type !== 'string')) { // "any" type is always compatible
return true;
}
else if (ps.type === vs.type || (ps.type === 'number' && vs.type === 'integer') || (!strict && ps.type === 'integer' && vs.type === 'number')) {
if (ps.type === 'array' && Utils.isObject(ps.items) && Utils.isObject(vs.items)) {
if (JsonSchemaValidator.isSchemaCompatible(ps.items, vs.items, strict)) {
return true;
}
}
else if (ps.type === 'object' && Utils.isObject(ps.properties) && Utils.isObject(vs.properties)) {
// ToDo: Check properties, required properties etc.
return true;
}
else if (!strict && (typeof ps.format !== 'string' || typeof vs.format !== 'string')) {
return true;
}
else if (typeof ps.format !== 'string') { // types without format always accepts the same type with a format
return true;
}
else if (ps.format === vs.format) {
return true;
}
}
}
return false;
});
return compatible.length > 0;
}
static _convertSchemaToArray(schema) {
var schemas = [];
// ToDo: schema.not and schema.allOf is not supported - see also class constructor of ProcessSchema in processSchema.js of openeo-web-editor.
if (schema.oneOf || schema.anyOf) {
schemas = (schema.oneOf || schema.anyOf);
}
else if (Array.isArray(schema.type)) {
schemas = schema.type.map(t => Object.assign({}, schema, {type: t}));
}
else {
schemas = [schema];
}
return schemas;
}
/**
* Returns the indices of provided JSON Schemas that the provided values matches against.
*
* Returns a single index if a single type is mathcing.
* Returns undefined if no valid type is found.
* Returns an array of indices if multiple types are found.
*
* @param {Array} types - Array of JSON schemas
* @param {*} value - A value
* @return {(string[]|string|undefined)} - Returns matching indices, see description.
*/
static async getTypeForValue(types, value) {

@@ -214,3 +349,3 @@ var validator = new JsonSchemaValidator();

if (errors.length === 0) {
potentialTypes.push(i);
potentialTypes.push(String(i));
}

@@ -221,2 +356,2 @@ }

}
};

@@ -20,3 +20,3 @@ const ProcessGraphError = require('./error');

this.process_id = json.process_id;
this.arguments = json.arguments || {};
this.arguments = Utils.isObject(json.arguments) ? JSON.parse(JSON.stringify(json.arguments)) : {};
this.isResultNode = json.result || false;

@@ -159,2 +159,2 @@ this.expectsFrom = [];

}
};

@@ -5,3 +5,2 @@ const JsonSchemaValidator = require('./jsonschema');

const ProcessGraph = require('./processgraph');
const Utils = require('../utils');

@@ -69,12 +68,4 @@ module.exports = class BaseProcess {

var cbParams = node.getProcessGraph().getCallbackParameters();
if (Utils.isObject(cbParams) && cbParams.hasOwnProperty(arg.from_argument)) {
return JsonSchemaValidator.isSchemaCompatible(param.schema, cbParams[arg.from_argument]);
}
else {
throw new ProcessGraphError('CallbackArgumentInvalid', {
argument: arg.from_argument,
node_id: node.id,
process_id: this.schema.id
});
}
// No need for further checks, callback argument is validated in processgraph.js: see parseCallbackArgument()
return JsonSchemaValidator.isSchemaCompatible(param.schema, cbParams[arg.from_argument]);
case 'variable':

@@ -95,7 +86,8 @@ var variableSchema = {

case 'object':
for(var i in arg) {
await this.validateArgument(arg[i], node, parameterName);
}
return true; // ToDo: Remove this and check how we can validate arrays and objects that have references to callback arguments, variables and node results in them...
break;
// ToDo: Check how we can validate arrays and objects that have references to callback arguments, variables and node results in them...
// See issue https://github.com/Open-EO/openeo-js-commons/issues/5
// for(var i in arg) {
// await this.validateArgument(arg[i], node, parameterName, param);
// }
return true;
}

@@ -106,6 +98,8 @@

async execute(node) {
/* istanbul ignore next */
async execute(/*node*/) {
throw "execute not implemented yet";
}
/* istanbul ignore next */
test() {

@@ -112,0 +106,0 @@ // Run the tests from the examples

@@ -11,3 +11,3 @@ const ErrorList = require('../errorlist');

constructor(jsonProcessGraph, processRegistry) {
this.json = Utils.mergeDeep({}, jsonProcessGraph);
this.json = jsonProcessGraph;
this.processRegistry = processRegistry;

@@ -27,3 +27,2 @@ this.nodes = [];

// Important: This avoids circular reference errors
toJSON() {

@@ -59,7 +58,7 @@ return this.json;

for(var id in this.json) {
for(let id in this.json) {
this.nodes[id] = this.createNodeInstance(this.json[id], id, this);
}
for(var id in this.nodes) {
for(let id in this.nodes) {
var node = this.nodes[id];

@@ -209,3 +208,10 @@

parseCallbackArgument(node, name) {
// ToDo: Parse callback argument
var cbParams = this.getCallbackParameters();
if (!Utils.isObject(cbParams) || !cbParams.hasOwnProperty(name)) {
throw new ProcessGraphError('CallbackArgumentInvalid', {
argument: name,
node_id: node.id,
process_id: node.process_id
});
}
}

@@ -330,6 +336,2 @@

getJson() {
return this.json;
}
getErrors() {

@@ -361,2 +363,3 @@ return this.errors;

// but they used the wrong callback parameters.
// See issue https://github.com/Open-EO/openeo-js-commons/issues/6

@@ -363,0 +366,0 @@ var cbParams = {};

@@ -13,7 +13,10 @@ const BaseProcess = require('./process');

for(var i in response.processes) {
var p = response.processes[i];
this.processes[p.id] = new BaseProcess(p);
this.add(response.processes[i]);
}
}
add(process) {
this.processes[process.id] = new BaseProcess(process);
}
count() {

@@ -31,2 +34,7 @@ return Utils.size(this.processes);

getSchema(id) {
var p = this.get(id);
return p !== null ? p.schema : null;
}
getProcessSchemas() {

@@ -33,0 +41,0 @@ return Object.values(this.processes).map(impl => impl.schema);

@@ -36,25 +36,2 @@ const compareVersions = require('compare-versions');

return message;
},
mergeDeep(target, ...sources) {
if (!sources.length) {
return target;
}
const source = sources.shift();
if (this.isObject(target) && this.isObject(source)) {
for (const key in source) {
if (this.isObject(source[key])) {
if (!target[key]) {
target[key] = {};
}
this.mergeDeep(target[key], source[key]);
}
else {
target[key] = source[key];
}
}
}
return this.mergeDeep(target, ...sources);
}

@@ -61,0 +38,0 @@

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc