odata-query
Advanced tools
Comparing version 3.3.5 to 4.0.0-0
@@ -16,2 +16,3 @@ 'use strict'; | ||
groupBy = _ref.groupBy, | ||
transform = _ref.transform, | ||
orderBy = _ref.orderBy, | ||
@@ -26,4 +27,2 @@ top = _ref.top, | ||
var builtFilter = buildFilter(count instanceof Object ? count : filter); | ||
var path = ''; | ||
@@ -36,15 +35,13 @@ var params = {}; | ||
if (groupBy) { | ||
var applyParam = []; | ||
if (filter || count instanceof Object) { | ||
var builtFilter = buildFilter(count instanceof Object ? count : filter); | ||
if (builtFilter) { | ||
applyParam.push('filter(' + builtFilter + ')'); | ||
params.$filter = builtFilter; | ||
} | ||
// TODO: Support `groupBy` subproperties using '/' or '.' | ||
applyParam.push('groupby((' + groupBy + '),aggregate(Id with countdistinct as Total))'); | ||
params.$apply = applyParam.join('/'); | ||
} else if (builtFilter) { | ||
params.$filter = builtFilter; | ||
} | ||
if (transform) { | ||
params.$apply = buildTransforms(transform); | ||
} | ||
if (top) { | ||
@@ -143,3 +140,3 @@ params.$top = top; | ||
if (["number", "string", "boolean"].indexOf(typeof value === 'undefined' ? 'undefined' : _typeof(value)) !== -1 || value instanceof Date) { | ||
if (["number", "string", "boolean"].indexOf(typeof value === 'undefined' ? 'undefined' : _typeof(value)) !== -1 || value instanceof Date || value === null) { | ||
// Simple key/value handled as equals operator | ||
@@ -185,4 +182,4 @@ result.push(propName + ' eq ' + handleValue(value)); | ||
}); | ||
} else if (value == null) { | ||
// Ignore/omit filter if `null` or `undefined` | ||
} else if (value === undefined) { | ||
// Ignore/omit filter if value is `undefined` | ||
} else { | ||
@@ -262,2 +259,63 @@ throw new Error('Unexpected value type: ' + value); | ||
function buildTransforms(transforms) { | ||
// Wrap single object an array for simplified processing | ||
var transformsArray = Array.isArray(transforms) ? transforms : [transforms]; | ||
return transformsArray.map(function (transform) { | ||
return Object.keys(transform).map(function (transformKey) { | ||
var transformValue = transform[transformKey]; | ||
switch (transformKey) { | ||
case 'aggregate': | ||
return 'aggregate(' + buildAggregate(transformValue) + ')'; | ||
case 'filter': | ||
return 'filter(' + buildFilter(transformValue) + ')'; | ||
case 'groupby': // support both cases | ||
case 'groupBy': | ||
return 'groupby(' + buildGroupBy(transformValue) + ')'; | ||
default: | ||
// TODO: support as many of the following: | ||
// topcount, topsum, toppercent, | ||
// bottomsum, bottomcount, bottompercent, | ||
// identity, concat, expand, search, compute, isdefined | ||
throw new Error('Unsupported transform: \'' + transformKey + '\''); | ||
} | ||
}).join('/'); | ||
}).join('/'); | ||
} | ||
function buildAggregate(aggregate) { | ||
// Wrap single object an array for simplified processing | ||
var aggregateArray = Array.isArray(aggregate) ? aggregate : [aggregate]; | ||
return aggregateArray.map(function (aggregateItem) { | ||
return Object.keys(aggregateItem).map(function (aggregateKey) { | ||
var aggregateValue = aggregateItem[aggregateKey]; | ||
// TODO: Are these always required? Can/should we default them if so? | ||
if (aggregateValue.with === undefined) { | ||
throw new Error('\'with\' property required for \'' + aggregateKey + '\''); | ||
} | ||
if (aggregateValue.as === undefined) { | ||
throw new Error('\'as\' property required for \'' + aggregateKey + '\''); | ||
} | ||
return aggregateKey + ' with ' + aggregateValue.with + ' as ' + aggregateValue.as; | ||
}); | ||
}).join(','); | ||
} | ||
function buildGroupBy(groupBy) { | ||
if (groupBy.properties === undefined) { | ||
throw new Error('\'properties\' property required for groupBy:\'' + aggregateKey + '\''); | ||
} | ||
var result = '(' + groupBy.properties.join(',') + ')'; | ||
if (groupBy.transform) { | ||
result += ',' + buildTransforms(groupBy.transform); | ||
} | ||
return result; | ||
} | ||
function buildOrderBy(orderBy) { | ||
@@ -264,0 +322,0 @@ if (typeof orderBy === 'number') { |
{ | ||
"name": "odata-query", | ||
"version": "3.3.5", | ||
"version": "4.0.0-0", | ||
"author": "Sean Lynch <techniq35@gmail.com>", | ||
@@ -5,0 +5,0 @@ "license": "MIT", |
@@ -58,3 +58,3 @@ # odata-query | ||
- [Functions](#functions-1) | ||
- [Grouping / aggregation](#grouping--aggregation) | ||
- [Transforms](#transforms) | ||
@@ -320,4 +320,5 @@ ### Filtering | ||
const count = true; | ||
buildQuery({ count }) | ||
=> '?$count=true' | ||
const filter = { PropName: 1} | ||
buildQuery({ count, filter }) | ||
=> '?$count=true&$filter=PropName eq 1' | ||
``` | ||
@@ -381,3 +382,82 @@ | ||
### Grouping / aggregation | ||
Coming soon | ||
### Transforms | ||
Transforms can be passed as an object or an array (useful when applying the same transform more than once, such as `filter`) | ||
Aggregations | ||
```js | ||
const transform = { | ||
aggregate: { | ||
Amount: { | ||
with: 'sum', | ||
as: 'Total' | ||
} | ||
} | ||
}; | ||
buildQuery({ transform }); | ||
=> '?$apply=aggregate(Amount with sum as Total)'; | ||
``` | ||
Supported aggregations: `sum`, `min`, `max`, `average`, `countdistinct` | ||
Group by (simple) | ||
```js | ||
const transform = [{ | ||
groupBy: { | ||
properties: ['SomeProp'], | ||
} | ||
}] | ||
buildQuery({ transform }); | ||
=> '?$apply=groupby((SomeProp))'; | ||
``` | ||
Group by with aggregation | ||
```js | ||
const transform = { | ||
groupBy: { | ||
properties: ['SomeProp'], | ||
transform: { | ||
aggregate: { | ||
Id: { | ||
with: 'countdistinct', | ||
as: 'Total' | ||
} | ||
} | ||
} | ||
} | ||
} | ||
buildQuery({ transform }); | ||
=> '?$apply=groupby((SomeProp),aggregate(Id with countdistinct as Total))'; | ||
``` | ||
Group by with filtering before and after | ||
```js | ||
const transform = [{ | ||
filter: { | ||
PropName: 1 | ||
} | ||
},{ | ||
groupBy: { | ||
properties: ['SomeProp'], | ||
transform: [{ | ||
aggregate: { | ||
Id: { | ||
with: 'countdistinct', | ||
as: 'Total' | ||
} | ||
} | ||
}] | ||
} | ||
},{ | ||
filter: { | ||
Total: { ge: 5 } | ||
} | ||
}] | ||
buildQuery({ transform }); | ||
=> '?$apply=filter(PropName eq 1)/groupby((SomeProp),aggregate(Id with countdistinct as Total))/filter(Total ge 5)'; | ||
``` | ||
Supported transforms: `aggregate`, `groupby`, `filter`. Additional transforms may be added later | ||
## OData specs | ||
- [OData Version 4.0. Part 1: Protocol Plus Errata 03](http://docs.oasis-open.org/odata/odata/v4.0/odata-v4.0-part1-protocol.html) | ||
- [OData Version 4.0. Part 2: URL Conventions Plus Errata 03](http://docs.oasis-open.org/odata/odata/v4.0/odata-v4.0-part2-url-conventions.html) | ||
- [OData Extension for Data Aggregation Version 4.0](http://docs.oasis-open.org/odata/odata-data-aggregation-ext/v4.0/odata-data-aggregation-ext-v4.0.html) |
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
25176
293
460
2