Skip to content

Commit

Permalink
Merge pull request #183 from balena-io-modules/add-support-to-odata-fns
Browse files Browse the repository at this point in the history
Add support for calling odata fns
  • Loading branch information
otaviojacobi authored Oct 9, 2024
2 parents 7374567 + befd5b2 commit 97e6fda
Show file tree
Hide file tree
Showing 2 changed files with 129 additions and 0 deletions.
26 changes: 26 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -746,6 +746,27 @@ const handleFilterOperator = <
filterStr = `${operator.slice(1)}(${alias}:${filterStr})`;
return addParentKey(filterStr, parentKey, '/');
}
case '$fn': {
const filterx = filter as FilterType<typeof operator, T>;
if (typeof filterx.$scope !== 'string') {
throw new Error(
`Function expression (${operator}) $scope must be a string.`,
);
}
const scope = escapeResource(filterx.$scope);

if (typeof filterx.$method !== 'string') {
throw new Error(
`Function expression (${operator}) $method must be a string.`,
);
}
const method = escapeResource(filterx.$method);

const args = filterx.$args?.map((v) => `${escapeValue(v)}`) ?? [];

const filterStr = `${scope}.${method}(` + args.join(',') + ')';
return addParentKey(filterStr, parentKey, '/');
}
// break
default:
throw new Error(`Unrecognised operator: '${operator}'`);
Expand Down Expand Up @@ -1962,6 +1983,11 @@ type FilterOperations<T extends Resource['Read']> = {
$ceiling?: FilterFunctionValue<T>;
$isof?: FilterFunctionValue<T>;
$cast?: FilterFunctionValue<T>;
$fn?: {
$scope: string;
$method: string;
$args?: Primitive[];
};
};

type AllFilterOperations<T extends Resource['Read']> = FilterOperations<T> &
Expand Down
103 changes: 103 additions & 0 deletions test/filter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1007,3 +1007,106 @@ testLambda('$any');

// Test $all
testLambda('$all');

// Test $fn calls
testFilter(
{
a: {
$fn: {
$scope: 'E',
$method: 'f',
},
},
},
'a/E.f()',
);

testFilter(
{
a: {
$fn: {
$scope: '$E',
$method: '$f',
},
},
},
'a/%24E.%24f()',
);

testFilter(
{
a: {
$fn: {
$scope: 'E',
$method: 'f',
$args: [null, 'arg1'],
},
},
},
`a/E.f(null,'arg1')`,
);

testFilter(
{
$or: {
o: {
$fn: {
$scope: 'E',
$method: 'f',
},
},
$and: {
a: true,
b: {
$any: {
$alias: 'c',
$expr: {
c: {
d: {
$fn: {
$scope: 'E',
$method: 'f',
},
},
},
},
},
},
},
},
},
'(o/E.f()) or ((a eq true) and (b/any(c:c/d/E.f())))',
);

testFilter(
{
$or: {
o: {
$fn: {
$scope: 'E',
$method: 'f',
},
},
$and: {
a: true,
b: {
$any: {
$alias: 'c',
$expr: {
c: {
d: {
$fn: {
$scope: 'B',
$method: 'k',
$args: ['arg1', 'arg2'],
},
},
},
},
},
},
},
},
},
`(o/E.f()) or ((a eq true) and (b/any(c:c/d/B.k('arg1','arg2'))))`,
);

0 comments on commit 97e6fda

Please sign in to comment.