Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/dev', v1.1.0
Browse files Browse the repository at this point in the history
  • Loading branch information
m-mohr committed Aug 13, 2020
2 parents 90cf255 + 063f53a commit 95f15f9
Show file tree
Hide file tree
Showing 9 changed files with 654 additions and 15 deletions.
10 changes: 6 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@

A set of common JavaScript functionalities for [openEO](http://openeo.org).

The [master branch](https://github.com/Open-EO/openeo-api/tree/master) is the 'stable' version of library, which is currently version **1.0.0**.
The [master branch](https://github.com/Open-EO/openeo-api/tree/master) is the 'stable' version of library, which is currently version **1.1.0**.
The [draft branch](https://github.com/Open-EO/openeo-api/tree/draft) is where active development takes place.

[![Build Status](https://travis-ci.org/Open-EO/openeo-js-commons.svg?branch=master)](https://travis-ci.org/Open-EO/openeo-js-commons)
![Dependencies](https://img.shields.io/librariesio/release/npm/@openeo/js-commons)
![Minified Size](https://img.shields.io/bundlephobia/min/@openeo/js-commons/1.0.0)
![Minzipped Size](https://img.shields.io/bundlephobia/minzip/@openeo/js-commons/1.0.0)
![Minified Size](https://img.shields.io/bundlephobia/min/@openeo/js-commons/1.1.0)
![Minzipped Size](https://img.shields.io/bundlephobia/minzip/@openeo/js-commons/1.1.0)
![Supported API Versions](https://img.shields.io/github/package-json/apiVersions/Open-Eo/openeo-js-commons/master)

## Features
Expand All @@ -21,6 +21,8 @@ The [draft branch](https://github.com/Open-EO/openeo-api/tree/draft) is where ac
- UDF Runtimes
- Back-end feature detection
- Validate, compare and prioritize version numbers (e.g. for well-known discovery)
- Process specification parsing utilities
- Other Utils

**Note:**
- Process graph parsing has been moved to [openeo-js-processgraphs](https://github.com/Open-EO/openeo-js-processgraphs).
Expand All @@ -38,4 +40,4 @@ In a web environment you can include the library as follows:
<script src="https://cdn.jsdelivr.net/npm/@openeo/js-commons@1/dist/main.min.js"></script>
```

More information can be found in the [**JS commons documentation**](https://open-eo.github.io/openeo-js-commons/1.0.0/).
More information can be found in the [**JS commons documentation**](https://open-eo.github.io/openeo-js-commons/1.1.0/).
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@openeo/js-commons",
"version": "1.0.0",
"version": "1.1.0",
"apiVersions": [
"0.4.x",
"1.0.x"
Expand Down Expand Up @@ -38,7 +38,8 @@
"webpack-cli": "^3.3.12"
},
"dependencies": {
"compare-versions": "^3.6.0"
"compare-versions": "^3.6.0",
"fast-deep-equal": "^3.1.3"
},
"scripts": {
"docs": "jsdoc src -r -d docs/ -P package.json -R README.md",
Expand Down
2 changes: 2 additions & 0 deletions src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@ const MigrateCapabilities = require('./migrate/capabilities');
const MigrateCollections = require('./migrate/collections');
const MigrateProcesses = require('./migrate/processes');
// Others
const ProcessUtils = require('./processUtils');
const Versions = require('./versions');
const Utils = require('./utils');

module.exports = {
MigrateCapabilities,
MigrateCollections,
MigrateProcesses,
ProcessUtils,
Versions,
Utils,
};
4 changes: 2 additions & 2 deletions src/migrate/capabilities.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,10 @@ class MigrateCapabilities {
}
// Now we are really guessing
else if (Array.isArray(capabilities.endpoints)) {
if (capabilities.endpoints.filter(e => e.path === '/file_formats' || e.path === '/conformance' || e.path === '/files').length > 0) {
if (capabilities.endpoints.find(e => e.path === '/file_formats' || e.path === '/conformance' || e.path === '/files')) {
return "1.0.0";
}
else if (capabilities.endpoints.filter(e => e.path === '/output_formats' || e.path === '/files/{user_id}').length > 0) {
else if (capabilities.endpoints.find(e => e.path === '/output_formats' || e.path === '/files/{user_id}')) {
return "0.4.2";
}
else if (!capabilities.backend_version && !capabilities.title && !capabilities.description && !capabilities.links) {
Expand Down
7 changes: 3 additions & 4 deletions src/migrate/collections.js
Original file line number Diff line number Diff line change
Expand Up @@ -177,10 +177,9 @@ class MigrateCollections {
max: val.extent[1]
};
}
else { // val.value is an array
let is2dArray = val.values.filter(v => !Array.isArray(v)).length === 0;
if (is2dArray) {
if (val.values.length < 2) {
else { // val.values is an array
if (val.values.findIndex(v => !Array.isArray(v)) === -1) {
if (val.values.length <= 1) {
props[key] = val.values[0];
}
else {
Expand Down
188 changes: 188 additions & 0 deletions src/processUtils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
const Utils = require('./utils.js');

/**
* Utilities to parse process specs and JSON schemas.
*
* @class
*/
class ProcessUtils {

/**
* From a "complex" JSON Schema with allOf/anyOf/oneOf, make separate schemas.
*
* So afterwards each schema has it's own array entry.
* It merges allOf, resolves anyOf/oneOf into separate schemas.
* May also split the JSON Schema type arrays into separate entries by setting `splitTypes` to `true`.
*
* @param {object|array} schemas - The JSON Schema(s) to convert
* @returns {array}
*/
static normalizeJsonSchema(schemas, splitTypes = false) {
// Make schemas always an array
if (Utils.isObject(schemas)) {
schemas = [schemas];
}
else if (Array.isArray(schemas)) {
schemas = schemas;
}
else {
schemas = [];
}

// Merge allOf, resolve anyOf/oneOf into separate schemas
let normalized = [];
for(let schema of schemas) {
if (Array.isArray(schema.allOf)) {
normalized.push(Object.assign({}, ...schema.allOf));
}
else if (Array.isArray(schema.oneOf) || Array.isArray(schema.anyOf)) {
let copy = Utils.omitFromObject(schema, ['oneOf', 'anyOf']);
let subSchemas = schema.oneOf || schema.anyOf;
for(let subSchema of subSchemas) {
normalized.push(Object.assign({}, copy, subSchema));
}
}
else {
normalized.push(schema);
}
}

if (!splitTypes) {
return normalized;
}

// Split type field into separate schemas
schemas = [];
for(let schema of normalized) {
if (Array.isArray(schema.type)) {
/* jshint ignore:start */
schemas = schemas.concat(schema.type.map(type => Object.assign({}, schema, {type: type})));
/* jshint ignore:end */
}
else {
schemas.push(schema);
}
}

return schemas;
}

/**
* Returns the callback parameters for a given process parameter.
*
* @param {object} processParameter - The process parameter spec to parse.
* @returns {array}
* @throws {Error}
*/
static getCallbackParameters(processParameter) {
if (!Utils.isObject(processParameter) || !processParameter.schema) {
return [];
}

let schemas = ProcessUtils.normalizeJsonSchema(processParameter.schema);

let cbParams = [];
for(let schema of schemas) {
if (Array.isArray(schema.parameters)) {
if (cbParams.length > 0 && !Utils.equals(cbParams, schema.parameters)) {
throw new Error("Multiple schemas with different callback parameters found.");
}
cbParams = schema.parameters;
}
}

return cbParams;
}

/**
* Returns the callback parameters for a given process parameter from a full process spec.
*
* @param {object} process - The process to parse.
* @param {string} parameterName - The name of the parameter to get the callback parameters for.
* @returns {array}
* @throws {Error}
*/
static getCallbackParametersForProcess(process, parameterName) {
if (!Utils.isObject(process) || !Array.isArray(process.parameters)) {
return [];
}

let param = process.parameters.find(p => p.name === parameterName);
return ProcessUtils.getCallbackParameters(param);
}

/**
* Returns *all* the native JSON data types allowed for the schema.
*
* @param {object} schema
* @param {boolean} anyIsEmpty
* @returns {array}
*/
static getNativeTypesForJsonSchema(schema, anyIsEmpty = false) {
if (Utils.isObject(schema) && Array.isArray(schema.type)) {
// Remove duplicate and invalid types
let validTypes = Utils.unique(schema.type).filter(type => ProcessUtils.JSON_SCHEMA_TYPES.includes(type));
if (validTypes.length > 0 && validTypes.length < ProcessUtils.JSON_SCHEMA_TYPES.length) {
return validTypes;
}
else {
return anyIsEmpty ? [] : ProcessUtils.JSON_SCHEMA_TYPES;
}
}
else if (Utils.isObject(schema) && typeof schema.type === 'string' && ProcessUtils.JSON_SCHEMA_TYPES.includes(schema.type)) {
return [schema.type];
}
else {
return anyIsEmpty ? [] : ProcessUtils.JSON_SCHEMA_TYPES;
}
}

/**
* Returns the schema for a property of an object or an element of an array.
*
* If you want to retrieve the schema for a specific key, use the parameter `key`.
*
* @param {object} schema - The JSON schema to parse.
* @param {string|integer|null} key - If you want to retrieve the schema for a specific key, otherwise null.
* @returns {object} - JSON Schema
*/
static getElementJsonSchema(schema, key = null) {
let types = ProcessUtils.getNativeTypesForJsonSchema(schema);
if (Utils.isObject(schema) && types.includes('array') && typeof key !== 'string') {
if (Utils.isObject(schema.items)) {
// Array with one schema for all items: https://json-schema.org/understanding-json-schema/reference/array.html#id5
return schema.items;
}
else if (Array.isArray(schema.items)) {
// Tuple validation: https://json-schema.org/understanding-json-schema/reference/array.html#id6
if (key !== null && Utils.isObject(schema.items[key])) {
return schema.items[key];
}
else if (Utils.isObject(schema.additionalItems)) {
return schema.additionalItems;
}
}
}
if (Utils.isObject(schema) && types.includes('object')) {
if (key !== null && Utils.isObject(schema.properties) && Utils.isObject(schema.properties[key])) {
return schema.properties[key];
}
else if (Utils.isObject(schema.additionalProperties)) {
return schema.additionalProperties;
}
// ToDo: No support for patternProperties yet
}

return {};
}

}

/**
* A list of all allowed JSON Schema type values.
*
* @type {array}
*/
ProcessUtils.JSON_SCHEMA_TYPES = ['string', 'number', 'integer', 'boolean', 'array', 'object', 'null'];

module.exports = ProcessUtils;
Loading

0 comments on commit 95f15f9

Please sign in to comment.