From 877ea17f70057641e5d9da81bf6538cfa7e8db79 Mon Sep 17 00:00:00 2001 From: Thodoris Greasidis Date: Fri, 4 Oct 2024 17:32:31 +0300 Subject: [PATCH 1/6] Update dependencies & tests to match Update @balena/lf-to-abstract-sql from 5.0.0 to 5.0.2 Update @balena/odata-parser from 3.0.0 to 3.1.0 Update @balena/odata-to-abstract-sql from 6.0.1 to 6.4.0 Update @balena/sbvr-parser from 1.4.3 to 1.4.6 Update @balena/sbvr-types from 7.0.1 to 9.0.2 Change-type: patch --- package.json | 30 +++++++++++++++--------------- test/odata/expand.js | 16 ++++++++-------- test/odata/filterby.js | 12 ++++++------ test/odata/paging.js | 36 ++++++++++++++++++++++-------------- 4 files changed, 51 insertions(+), 43 deletions(-) diff --git a/package.json b/package.json index 57d1126..8dea01a 100644 --- a/package.json +++ b/package.json @@ -16,27 +16,27 @@ "repository": "https://github.com/balena-io-modules/abstract-sql-compiler.git", "author": "", "dependencies": { - "@balena/sbvr-types": "^7.0.1", + "@balena/sbvr-types": "^9.0.2, ^8.0.0, ^7.0.1", "lodash": "^4.17.21" }, "devDependencies": { - "@balena/lf-to-abstract-sql": "^5.0.0", - "@balena/lint": "^8.0.0", - "@balena/odata-parser": "^3.0.0", - "@balena/odata-to-abstract-sql": "^6.0.1", - "@balena/sbvr-parser": "^1.4.3", + "@balena/lf-to-abstract-sql": "^5.0.2", + "@balena/lint": "^8.2.8", + "@balena/odata-parser": "^3.1.0", + "@balena/odata-to-abstract-sql": "^6.4.0", + "@balena/sbvr-parser": "^1.4.6", "@types/chai": "^4.3.4", - "@types/common-tags": "^1.8.1", - "@types/lodash": "^4.14.192", - "@types/mocha": "^10.0.1", - "@types/node": "^20.0.0", + "@types/common-tags": "^1.8.4", + "@types/lodash": "^4.17.10", + "@types/mocha": "^10.0.8", + "@types/node": "^20.16.10", "chai": "^4.3.7", "common-tags": "^1.8.2", - "husky": "^9.0.0", - "lint-staged": "^15.0.0", - "mocha": "^10.2.0", - "ts-node": "^10.9.1", - "typescript": "^5.4.3" + "husky": "^9.1.6", + "lint-staged": "^15.2.10", + "mocha": "^10.7.3", + "ts-node": "^10.9.2", + "typescript": "^5.6.2" }, "lint-staged": { "*.js": [ diff --git a/test/odata/expand.js b/test/odata/expand.js index 80ff4f3..e8e6b83 100644 --- a/test/odata/expand.js +++ b/test/odata/expand.js @@ -436,7 +436,7 @@ SELECT ( SELECT ${aliasLicenceFields.join(', ')} FROM "licence" AS "pilot.licence" WHERE "pilot"."licence" = "pilot.licence"."id" - LIMIT 10 + LIMIT ? ) AS "pilot.licence" ) AS "licence", ${remainingPilotFields} FROM "pilot"`, @@ -444,9 +444,9 @@ FROM "pilot"`, }); }; const url = '/pilot?$expand=licence($top=10)'; - test.postgres(url, testFunc(postgresAgg)); - test.mysql.skip(url, testFunc(mysqlAgg)); - test.websql.skip(url, testFunc(websqlAgg)); + test.postgres(url, 'GET', [['Bind', 0]], testFunc(postgresAgg)); + test.mysql.skip(url, 'GET', [['Bind', 0]], testFunc(mysqlAgg)); + test.websql.skip(url, 'GET', [['Bind', 0]], testFunc(websqlAgg)); })(); (function () { @@ -493,7 +493,7 @@ SELECT ( SELECT ${aliasLicenceFields.join(', ')} FROM "licence" AS "pilot.licence" WHERE "pilot"."licence" = "pilot.licence"."id" - OFFSET 10 + OFFSET ? ) AS "pilot.licence" ) AS "licence", ${remainingPilotFields} FROM "pilot"`, @@ -501,9 +501,9 @@ FROM "pilot"`, }); }; const url = '/pilot?$expand=licence($skip=10)'; - test.postgres(url, testFunc(postgresAgg)); - test.mysql.skip(url, testFunc(mysqlAgg)); - test.websql.skip(url, testFunc(websqlAgg)); + test.postgres(url, 'GET', [['Bind', 0]], testFunc(postgresAgg)); + test.mysql.skip(url, 'GET', [['Bind', 0]], testFunc(mysqlAgg)); + test.websql.skip(url, 'GET', [['Bind', 0]], testFunc(websqlAgg)); })(); (function () { diff --git a/test/odata/filterby.js b/test/odata/filterby.js index bbe3417..7179166 100644 --- a/test/odata/filterby.js +++ b/test/odata/filterby.js @@ -69,7 +69,7 @@ let parseOperandFactory = function (defaultResource) { typeof operand === 'boolean' || typeof operand === 'number' || _.isDate(operand) || - (typeof operand === 'string' && operand.charAt(0) === "'") + (typeof operand === 'string' && operand.startsWith("'")) ) { return [['Bind', bindNo++]]; } @@ -95,7 +95,7 @@ let parseOperandFactory = function (defaultResource) { if (operand === 'null') { return 'NULL'; } - if (operand.charAt(0) === "'") { + if (operand.startsWith("'")) { return '?'; } const fieldParts = operand.split('/'); @@ -636,7 +636,7 @@ WHERE EXISTS ( }; const updateWhere = `\ WHERE "pilot"."id" IN (( - SELECT "pilot"."id" + SELECT "pilot"."id" AS "$modifyid" FROM "pilot", "pilot-can fly-plane" AS "pilot.pilot-can fly-plane", "plane" AS "pilot.pilot-can fly-plane.plane" @@ -731,7 +731,7 @@ ${updateWhere}`, `\ DELETE FROM "pilot" WHERE "pilot"."id" IN (( - SELECT "pilot"."id" + SELECT "pilot"."id" AS "$modifyid" FROM "pilot", "pilot-can fly-plane" AS "pilot.pilot-can fly-plane", "plane" AS "pilot.pilot-can fly-plane.plane" @@ -808,7 +808,7 @@ UPDATE "pilot" SET "name" = ? WHERE ("pilot"."id") IS NOT NULL AND ("pilot"."id") = (?) AND "pilot"."id" IN (( - SELECT "pilot"."id" + SELECT "pilot"."id" AS "$modifyid" FROM "pilot" WHERE ${sql} ))`, @@ -865,7 +865,7 @@ SET "created at" = DEFAULT, "was trained by-pilot" = DEFAULT WHERE ("pilot"."id") IS NOT NULL AND ("pilot"."id") = (?) AND "pilot"."id" IN (( - SELECT "pilot"."id" + SELECT "pilot"."id" AS "$modifyid" FROM "pilot" WHERE ${sql} ))`, diff --git a/test/odata/paging.js b/test/odata/paging.js index 0359781..d2ae3bf 100644 --- a/test/odata/paging.js +++ b/test/odata/paging.js @@ -2,39 +2,47 @@ import test from './test'; import { pilotFields } from './fields'; const pilotFieldsStr = pilotFields.join(', '); -test('/pilot?$top=5', (result, sqlEquals) => { +test('/pilot?$top=5', 'GET', [['Bind', 0]], (result, sqlEquals) => { it('should select from pilot limited by 5', () => { sqlEquals( result.query, `\ SELECT ${pilotFieldsStr} FROM "pilot" -LIMIT 5`, +LIMIT ?`, ); }); }); -test('/pilot?$skip=100', (result, sqlEquals) => { +test('/pilot?$skip=100', 'GET', [['Bind', 0]], (result, sqlEquals) => { it('should select from pilot offset by 100', () => { sqlEquals( result.query, `\ SELECT ${pilotFieldsStr} FROM "pilot" -OFFSET 100`, +OFFSET ?`, ); }); }); -test('/pilot?$top=5&$skip=100', (result, sqlEquals) => { - it('should select from pilot limited by 5 and offset by 100', () => { - sqlEquals( - result.query, - `\ +test( + '/pilot?$top=5&$skip=100', + 'GET', + [ + ['Bind', 0], + ['Bind', 1], + ], + (result, sqlEquals) => { + it('should select from pilot limited by 5 and offset by 100', () => { + sqlEquals( + result.query, + `\ SELECT ${pilotFieldsStr} FROM "pilot" -LIMIT 5 -OFFSET 100`, - ); - }); -}); +LIMIT ? +OFFSET ?`, + ); + }); + }, +); From 6ea529e0daa0608860ec2840e9b0212ae91830b7 Mon Sep 17 00:00:00 2001 From: Thodoris Greasidis Date: Fri, 4 Oct 2024 17:46:58 +0300 Subject: [PATCH 2/6] Lint fixes Change-type: patch --- src/AbstractSQLOptimiser.ts | 21 +++------------------ src/AbstractSQLRules2SQL.ts | 10 +++++----- src/AbstractSQLSchemaOptimiser.ts | 4 ++-- src/referenced-fields.ts | 2 +- test/sbvr/reference-type.js | 2 +- 5 files changed, 12 insertions(+), 27 deletions(-) diff --git a/src/AbstractSQLOptimiser.ts b/src/AbstractSQLOptimiser.ts index d5fac64..00da4fe 100644 --- a/src/AbstractSQLOptimiser.ts +++ b/src/AbstractSQLOptimiser.ts @@ -323,7 +323,7 @@ const Field: MetaMatchFn = (args) => { }; const AnyNotNullValue = (args: any): boolean => { - return args != null && (args as any) !== 'Null' && args[0] !== 'Null'; + return args != null && args !== 'Null' && args[0] !== 'Null'; }; const FieldOp = @@ -603,15 +603,7 @@ const typeRules = { case 'RightJoin': case 'FullJoin': case 'CrossJoin': - tables.push( - typeRules[type](rest) as - | FromNode - | InnerJoinNode - | LeftJoinNode - | RightJoinNode - | FullJoinNode - | CrossJoinNode, - ); + tables.push(typeRules[type](rest)); break; case 'Where': case 'GroupBy': @@ -1375,14 +1367,7 @@ const typeRules = { switch (valuesType) { case 'SelectQuery': case 'UnionQuery': - values = [ - [ - 'Values', - typeRules[valuesType](valuesRest) as - | SelectQueryNode - | UnionQueryNode, - ], - ]; + values = [['Values', typeRules[valuesType](valuesRest)]]; break; default: values = [['Values', valuesArray.map(Value)] as ValuesNode]; diff --git a/src/AbstractSQLRules2SQL.ts b/src/AbstractSQLRules2SQL.ts index e73e7db..a7f21e5 100644 --- a/src/AbstractSQLRules2SQL.ts +++ b/src/AbstractSQLRules2SQL.ts @@ -38,7 +38,7 @@ type MatchFn = (args: AbstractSqlType[], indent: string) => string; let fieldOrderings: Binding[] = []; let fieldOrderingsLookup: Dictionary = {}; let engine: Engines = Engines.postgres; -let noBinds: boolean = false; +let noBinds = false; export const comparisons = { Equals: ' = ', @@ -669,7 +669,7 @@ const typeRules: Dictionary = { SelectQuery: (args, indent) => { const tables: string[] = []; const joins: string[] = []; - let select: string = ''; + let select = ''; const groups = { Where: '', GroupBy: '', @@ -869,7 +869,7 @@ const typeRules: Dictionary = { checkArgs('Cast', args, 2); const value = AnyValue(getAbstractSqlQuery(args, 0), indent); const typeName = args[1] as keyof typeof sbvrTypes; - if (!sbvrTypes[typeName] || !sbvrTypes[typeName].types[engine]) { + if (!sbvrTypes[typeName]?.types[engine]) { throw new SyntaxError(`Invalid cast type: ${typeName}`); } let type: string; @@ -1451,7 +1451,7 @@ const typeRules: Dictionary = { const tables: string[] = []; let fields: string[] = []; let values: string[] = []; - let where: string = ''; + let where = ''; for (const arg of args) { if (!isAbstractSqlQuery(arg)) { throw new SyntaxError('`UpdateQuery` args must all be arrays'); @@ -1510,7 +1510,7 @@ const typeRules: Dictionary = { }, DeleteQuery: (args, indent) => { const tables: string[] = []; - let where: string = ''; + let where = ''; for (const arg of args) { if (!isAbstractSqlQuery(arg)) { throw new SyntaxError('`DeleteQuery` args must all be arrays'); diff --git a/src/AbstractSQLSchemaOptimiser.ts b/src/AbstractSQLSchemaOptimiser.ts index 9072128..470e308 100644 --- a/src/AbstractSQLSchemaOptimiser.ts +++ b/src/AbstractSQLSchemaOptimiser.ts @@ -44,7 +44,7 @@ export const generateRuleSlug = ( export const optimizeSchema = ( abstractSqlModel: AbstractSqlModel, - createCheckConstraints: boolean = true, + createCheckConstraints = true, ): AbstractSqlModel => { abstractSqlModel.rules = abstractSqlModel.rules .map((rule): AbstractSqlQuery | undefined => { @@ -126,7 +126,7 @@ export const optimizeSchema = ( ); if (table) { table.checks ??= []; - table.checks!.push({ + table.checks.push({ description: ruleSE, name: generateRuleSlug(tableName, ruleBody), abstractSql: whereNode, diff --git a/src/referenced-fields.ts b/src/referenced-fields.ts index 8a2cacb..23e6a01 100644 --- a/src/referenced-fields.ts +++ b/src/referenced-fields.ts @@ -270,7 +270,7 @@ export const getRuleReferencedFields: EngineInstance['getRuleReferencedFields'] _.isEqual(ruleBody[2], ['Number', 0]) && isSelectQueryNode(ruleBody[1]) ) { - const select = ruleBody[1].find(isSelectNode) as SelectNode; + const select = ruleBody[1].find(isSelectNode)!; select[1] = []; $getRuleReferencedFields(referencedFields, ruleBody[1], IsSafe.Delete); } else { diff --git a/test/sbvr/reference-type.js b/test/sbvr/reference-type.js index 73cd4b2..088b029 100644 --- a/test/sbvr/reference-type.js +++ b/test/sbvr/reference-type.js @@ -29,7 +29,7 @@ describe('reference type', function () { test = getTestHelpers(typeVocab); }); - it('informative - no foreignKey for reference field', async () => { + it('informative - no foreignKey for reference field', () => { test( `\ From af8dc56b94b2b917588f5f53c2d95dab6f1f4ad9 Mon Sep 17 00:00:00 2001 From: Thodoris Greasidis Date: Fri, 4 Oct 2024 18:01:58 +0300 Subject: [PATCH 3/6] Make @balena/sbvr-types a peer dependency Change-type: major --- package.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 8dea01a..b9848b8 100644 --- a/package.json +++ b/package.json @@ -16,9 +16,11 @@ "repository": "https://github.com/balena-io-modules/abstract-sql-compiler.git", "author": "", "dependencies": { - "@balena/sbvr-types": "^9.0.2, ^8.0.0, ^7.0.1", "lodash": "^4.17.21" }, + "peerDependencies": { + "@balena/sbvr-types": "^7.1.0, ^8.0.0, ^9.0.2" + }, "devDependencies": { "@balena/lf-to-abstract-sql": "^5.0.2", "@balena/lint": "^8.2.8", From 2e399f73a7aa751abe02378990540d2ea68b522b Mon Sep 17 00:00:00 2001 From: Thodoris Greasidis Date: Fri, 4 Oct 2024 18:03:02 +0300 Subject: [PATCH 4/6] Update minimum supported nodejs version to 20.14.0 Change-type: major --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index b9848b8..42c8dd7 100644 --- a/package.json +++ b/package.json @@ -59,8 +59,8 @@ ] }, "engines": { - "node": ">=16.13.0", - "npm": ">=8.1.0" + "node": ">=20.14.0", + "npm": ">=10.7.0" }, "versionist": { "publishedAt": "2024-06-12T13:14:08.116Z" From 9fa62364ed291750c48a199b6895b1babfe1b959 Mon Sep 17 00:00:00 2001 From: Thodoris Greasidis Date: Fri, 4 Oct 2024 18:53:33 +0300 Subject: [PATCH 5/6] Update tsconfig target to es2023 Change-type: major --- tsconfig.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tsconfig.json b/tsconfig.json index 019ae41..c89a0b3 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -13,7 +13,7 @@ "declaration": true, "skipLibCheck": true, "exactOptionalPropertyTypes": true, - "target": "es2021", + "target": "es2023", "outDir": "out", "allowJs": true }, From 28c15f305c99bd1e581a93fddfc985b82d20bdf8 Mon Sep 17 00:00:00 2001 From: Thodoris Greasidis Date: Fri, 4 Oct 2024 23:21:26 +0300 Subject: [PATCH 6/6] tsconfig: Switch the module compiler option to Node16 Change-type: patch --- package.json | 1 + src/AbstractSQLCompiler.ts | 2 +- src/AbstractSQLOptimiser.ts | 2 +- src/AbstractSQLRules2SQL.ts | 2 +- src/AbstractSQLSchemaOptimiser.ts | 2 +- src/referenced-fields.ts | 2 +- test/abstract-sql/test.js | 2 +- test/odata/expand.js | 2 +- test/odata/filterby.js | 2 +- test/odata/stress.js | 2 +- test/odata/test.js | 2 +- test/sbvr/test.js | 2 +- tsconfig.json | 2 +- 13 files changed, 13 insertions(+), 12 deletions(-) diff --git a/package.json b/package.json index 42c8dd7..81bf061 100644 --- a/package.json +++ b/package.json @@ -2,6 +2,7 @@ "name": "@balena/abstract-sql-compiler", "version": "9.2.0", "description": "A translator for abstract sql into sql.", + "type": "commonjs", "main": "out/AbstractSQLCompiler.js", "types": "out/AbstractSQLCompiler.d.ts", "scripts": { diff --git a/src/AbstractSQLCompiler.ts b/src/AbstractSQLCompiler.ts index d4a36af..e8e89db 100644 --- a/src/AbstractSQLCompiler.ts +++ b/src/AbstractSQLCompiler.ts @@ -12,7 +12,7 @@ import { AbstractSQLRules2SQL } from './AbstractSQLRules2SQL'; export { Binding, SqlResult } from './AbstractSQLRules2SQL'; import type { SbvrType } from '@balena/sbvr-types'; import sbvrTypes from '@balena/sbvr-types'; -import * as _ from 'lodash'; +import _ from 'lodash'; import { optimizeSchema, generateRuleSlug } from './AbstractSQLSchemaOptimiser'; import type { ReferencedFields, diff --git a/src/AbstractSQLOptimiser.ts b/src/AbstractSQLOptimiser.ts index 00da4fe..500f801 100644 --- a/src/AbstractSQLOptimiser.ts +++ b/src/AbstractSQLOptimiser.ts @@ -1,4 +1,4 @@ -import * as _ from 'lodash'; +import _ from 'lodash'; import type { Dictionary } from 'lodash'; import type { diff --git a/src/AbstractSQLRules2SQL.ts b/src/AbstractSQLRules2SQL.ts index a7f21e5..8fde052 100644 --- a/src/AbstractSQLRules2SQL.ts +++ b/src/AbstractSQLRules2SQL.ts @@ -1,4 +1,4 @@ -import * as _ from 'lodash'; +import _ from 'lodash'; import sbvrTypes from '@balena/sbvr-types'; diff --git a/src/AbstractSQLSchemaOptimiser.ts b/src/AbstractSQLSchemaOptimiser.ts index 470e308..09bdf4b 100644 --- a/src/AbstractSQLSchemaOptimiser.ts +++ b/src/AbstractSQLSchemaOptimiser.ts @@ -7,7 +7,7 @@ export const enum Engines { import { AbstractSQLOptimiser } from './AbstractSQLOptimiser'; export { Binding, SqlResult } from './AbstractSQLRules2SQL'; import sbvrTypes from '@balena/sbvr-types'; -import * as _ from 'lodash'; +import _ from 'lodash'; import type { AbstractSqlModel, AbstractSqlQuery, diff --git a/src/referenced-fields.ts b/src/referenced-fields.ts index 23e6a01..a9e7877 100644 --- a/src/referenced-fields.ts +++ b/src/referenced-fields.ts @@ -1,4 +1,4 @@ -import * as _ from 'lodash'; +import _ from 'lodash'; import type { AbstractSqlQuery, AbstractSqlType, diff --git a/test/abstract-sql/test.js b/test/abstract-sql/test.js index 068ca83..9255ec7 100644 --- a/test/abstract-sql/test.js +++ b/test/abstract-sql/test.js @@ -1,7 +1,7 @@ import * as AbstractSQLCompiler from '../..'; import { expect } from 'chai'; -import * as _ from 'lodash'; +import _ from 'lodash'; const bindingsTest = function (actualBindings, expectedBindings) { if (expectedBindings == null) { diff --git a/test/odata/expand.js b/test/odata/expand.js index e8e6b83..ed13d50 100644 --- a/test/odata/expand.js +++ b/test/odata/expand.js @@ -6,7 +6,7 @@ import { aliasPlaneFields, aliasPilotCanFlyPlaneFields, } from './fields'; -import * as _ from 'lodash'; +import _ from 'lodash'; const postgresAgg = (field) => 'COALESCE(JSON_AGG(' + field + "), '[]')"; const mysqlAgg = (field) => "'[' || group_concat(" + field + ", ',') || ']'"; diff --git a/test/odata/filterby.js b/test/odata/filterby.js index 7179166..ce48eef 100644 --- a/test/odata/filterby.js +++ b/test/odata/filterby.js @@ -5,7 +5,7 @@ */ import { expect } from 'chai'; import test, { clientModel } from './test'; -import * as _ from 'lodash'; +import _ from 'lodash'; import { odataNameToSqlName } from '@balena/odata-to-abstract-sql'; import { pilotFields, teamFields, aliasPilotCanFlyPlaneFields } from './fields'; diff --git a/test/odata/stress.js b/test/odata/stress.js index 6288fe3..53cef76 100644 --- a/test/odata/stress.js +++ b/test/odata/stress.js @@ -1,5 +1,5 @@ import test from './test'; -import * as _ from 'lodash'; +import _ from 'lodash'; import { pilotFields } from './fields'; const pilotFieldsStr = pilotFields.join(', '); diff --git a/test/odata/test.js b/test/odata/test.js index 24c46c8..304617c 100644 --- a/test/odata/test.js +++ b/test/odata/test.js @@ -6,7 +6,7 @@ const sbvrModel = fs.readFileSync(require.resolve('../model.sbvr'), 'utf8'); import * as AbstractSQLCompiler from '../..'; import { expect } from 'chai'; -import * as _ from 'lodash'; +import _ from 'lodash'; const generateClientModel = function (input) { // eslint-disable-next-line @typescript-eslint/no-var-requires diff --git a/test/sbvr/test.js b/test/sbvr/test.js index f09e526..2671f26 100644 --- a/test/sbvr/test.js +++ b/test/sbvr/test.js @@ -1,4 +1,4 @@ -import * as _ from 'lodash'; +import _ from 'lodash'; import sbvrTypes from '@balena/sbvr-types'; import { expect } from 'chai'; diff --git a/tsconfig.json b/tsconfig.json index c89a0b3..7c4b366 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,6 +1,6 @@ { "compilerOptions": { - "module": "commonjs", + "module": "Node16", "strict": true, "strictFunctionTypes": false, "strictBindCallApply": false,