From 14c82f2d929d67d74b90140e45ca8bf8821f25dc Mon Sep 17 00:00:00 2001 From: Otavio Jacobi Date: Mon, 20 Jan 2025 14:37:34 -0300 Subject: [PATCH] Compile in as (= ANY($singleListBinding)) Update @balena/abstract-sql-compiler from 10.1.0 to 10.2.0 Update @balena/odata-parser from 3.1.2 to 4.1.0 Update @balena/odata-to-abstract sql from 7.0.1 to 7.1.0 Change-type: patch --- package.json | 6 +++--- src/sbvr-api/abstract-sql.ts | 37 +++++++++++++++++++++++++++--------- 2 files changed, 31 insertions(+), 12 deletions(-) diff --git a/package.json b/package.json index 7640261af..a2ff633db 100644 --- a/package.json +++ b/package.json @@ -26,12 +26,12 @@ "generate-types": "node ./bin/sbvr-compiler.js generate-types ./src/sbvr-api/user.sbvr ./src/sbvr-api/user.ts && node ./bin/sbvr-compiler.js generate-types ./src/migrator/migrations.sbvr ./src/migrator/migrations.ts && node ./bin/sbvr-compiler.js generate-types ./src/sbvr-api/dev.sbvr ./src/sbvr-api/dev.ts && node ./bin/sbvr-compiler.js generate-types ./src/tasks/tasks.sbvr ./src/tasks/tasks.ts && balena-lint -t tsconfig.dev.json --fix ./src/sbvr-api/user.ts ./src/migrator/migrations.ts ./src/sbvr-api/dev.ts" }, "dependencies": { - "@balena/abstract-sql-compiler": "^10.1.0", + "@balena/abstract-sql-compiler": "^10.2.0", "@balena/abstract-sql-to-typescript": "^5.1.0", "@balena/env-parsing": "^1.2.0", "@balena/lf-to-abstract-sql": "^5.0.3", - "@balena/odata-parser": "^3.1.2", - "@balena/odata-to-abstract-sql": "^7.0.1", + "@balena/odata-parser": "^4.1.0", + "@balena/odata-to-abstract-sql": "^7.1.0", "@balena/sbvr-parser": "^1.4.6", "@balena/sbvr-types": "^9.1.0", "@types/body-parser": "^1.19.5", diff --git a/src/sbvr-api/abstract-sql.ts b/src/sbvr-api/abstract-sql.ts index bb309bd34..5f983405a 100644 --- a/src/sbvr-api/abstract-sql.ts +++ b/src/sbvr-api/abstract-sql.ts @@ -1,5 +1,6 @@ import _ from 'lodash'; +import type { Engines } from '@balena/abstract-sql-compiler'; import AbstractSQLCompiler from '@balena/abstract-sql-compiler'; import type { BindKey } from '@balena/odata-parser'; import { @@ -78,7 +79,7 @@ export const getAndCheckBindValues = async ( return await Promise.all( bindings.map(async (binding) => { let fieldName = ''; - let field: { dataType: string }; + let dataType: string; let value: any; if (binding[0] === 'Bind') { const bindValue = binding[1]; @@ -103,7 +104,7 @@ export const getAndCheckBindValues = async ( if (maybeField == null) { throw new Error(`Could not find field '${fieldName}'`); } - field = maybeField; + dataType = maybeField.dataType; } else if (Number.isInteger(bindValue)) { if (bindValue >= odataBinds.length) { console.error( @@ -112,9 +113,7 @@ export const getAndCheckBindValues = async ( ); throw new Error('Invalid binding'); } - let dataType; [dataType, value] = odataBinds[bindValue]; - field = { dataType }; } else if (typeof bindValue === 'string') { if (!Object.hasOwn(odataBinds, bindValue)) { console.error( @@ -123,16 +122,12 @@ export const getAndCheckBindValues = async ( ); throw new Error('Invalid binding'); } - let dataType; [dataType, value] = odataBinds[bindValue as BindKey]; - field = { dataType }; } else { throw new Error(`Unknown binding: ${binding}`); } } else { - let dataType; [dataType, value] = binding; - field = { dataType }; } if (value === undefined) { @@ -140,7 +135,7 @@ export const getAndCheckBindValues = async ( } try { - return await AbstractSQLCompiler[engine].dataTypeValidate(value, field); + return await validateBindingType(engine, value, dataType); } catch (err: any) { throw new BadRequestError(`"${fieldName}" ${err.message}`); } @@ -148,6 +143,30 @@ export const getAndCheckBindValues = async ( ); }; +const validateBindingType = async ( + engine: Engines, + $value: any, + $dataType: string, +): Promise => { + if ($dataType === 'List') { + if (!Array.isArray($value)) { + throw new Error('List value binding must be an array'); + } + return await Promise.all( + $value.map(async ([dataType, value]: [string, any]) => { + // Null is a special case for list values + if (dataType === 'Null') { + return null; + } + return await validateBindingType(engine, value, dataType); + }), + ); + } + return await AbstractSQLCompiler[engine].dataTypeValidate($value, { + dataType: $dataType, + }); +}; + const checkModifiedFields = ( ruleReferencedFields: AbstractSQLCompiler.RuleReferencedFields, modifiedFields: AbstractSQLCompiler.ModifiedFields,