@balena/abstract-sql-compiler 10.2.5 → 10.2.6-build-is-field-type-node-9aead5476c82d21b8287f191c64f812239eaf109-1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -4,29 +4,46 @@
4
4
  * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
5
5
  */
6
6
  import { expect } from 'chai';
7
+ import type { ExpectationSuccessFn } from './test';
7
8
  import test, { clientModel } from './test';
8
9
  import _ from 'lodash';
9
10
  import { odataNameToSqlName } from '@balena/odata-to-abstract-sql';
10
11
  import { pilotFields, teamFields, aliasPilotCanFlyPlaneFields } from './fields';
12
+ import type {
13
+ Binding,
14
+ DurationNode,
15
+ SqlResult,
16
+ } from '../../src/AbstractSQLCompiler';
11
17
 
12
18
  const pilotFieldsStr = pilotFields.join(', ');
13
19
  const aliasPilotCanFlyPlaneFieldsStr = aliasPilotCanFlyPlaneFields.join(', ');
14
20
  const teamFieldsStr = teamFields.join(', ');
15
21
 
16
- let parseOperandFactory = function (defaultResource) {
17
- if (defaultResource == null) {
18
- defaultResource = 'pilot';
19
- }
22
+ type ParsedOperand = {
23
+ odata: string | number | boolean;
24
+ bindings: Binding[];
25
+ sql: string;
26
+ };
27
+ type Operand =
28
+ | string
29
+ | number
30
+ | boolean
31
+ | Date
32
+ | DurationNode[1]
33
+ | ParsedOperand;
34
+
35
+ let parseOperandFactory = function (defaultResource = 'pilot') {
20
36
  let bindNo = 0;
21
- const operandToOData = function (operand) {
22
- if (operand.odata != null) {
23
- return operand.odata;
24
- }
25
- if (_.isDate(operand)) {
26
- return "datetime'" + encodeURIComponent(operand.toISOString()) + "'";
27
- }
37
+ const operandToOData = function (operand: Operand) {
28
38
  if (operand != null && typeof operand === 'object') {
29
- const duration = [];
39
+ if ('odata' in operand) {
40
+ return operand.odata;
41
+ }
42
+ if (_.isDate(operand)) {
43
+ return "datetime'" + encodeURIComponent(operand.toISOString()) + "'";
44
+ }
45
+
46
+ const duration: Array<string | number> = [];
30
47
  let t = false;
31
48
  if (operand.negative) {
32
49
  duration.push('-');
@@ -61,8 +78,8 @@ let parseOperandFactory = function (defaultResource) {
61
78
  return operand;
62
79
  };
63
80
 
64
- const operandToBindings = function (operand) {
65
- if (operand.bindings != null) {
81
+ const operandToBindings = function (operand: Operand): Binding[] {
82
+ if (typeof operand === 'object' && 'bindings' in operand) {
66
83
  return operand.bindings;
67
84
  }
68
85
  if (
@@ -76,11 +93,11 @@ let parseOperandFactory = function (defaultResource) {
76
93
  return [];
77
94
  };
78
95
 
79
- const operandToSQL = function (operand, resource) {
80
- if (resource == null) {
81
- resource = defaultResource;
82
- }
83
- if (operand.sql != null) {
96
+ const operandToSQL = function (
97
+ operand: Operand,
98
+ resource = defaultResource,
99
+ ): string {
100
+ if (typeof operand === 'object' && 'sql' in operand) {
84
101
  return operand.sql;
85
102
  }
86
103
  if (
@@ -134,17 +151,17 @@ let parseOperandFactory = function (defaultResource) {
134
151
  throw new Error('Unknown operand type: ' + operand);
135
152
  };
136
153
 
137
- return (operand) => ({
154
+ return (operand: Operand): ParsedOperand => ({
138
155
  sql: operandToSQL(operand),
139
156
  bindings: operandToBindings(operand),
140
157
  odata: operandToOData(operand),
141
158
  });
142
159
  };
143
160
 
144
- let parseOperand = null;
161
+ let parseOperand: ReturnType<typeof parseOperandFactory> | null = null;
145
162
  const run = (function () {
146
163
  let running = false;
147
- return function (fn) {
164
+ return function (fn: () => void) {
148
165
  if (!running) {
149
166
  running = true;
150
167
  parseOperand = parseOperandFactory();
@@ -178,10 +195,10 @@ const methodMaps = {
178
195
  TOLOWER: 'LOWER',
179
196
  };
180
197
 
181
- const createExpression = function (lhs, op, rhs) {
198
+ const createExpression = function (lhs: Operand, op?: Operand, rhs?: Operand) {
182
199
  let sql;
183
200
  if (lhs === 'not') {
184
- op = parseOperand(op);
201
+ op = parseOperand!(op!);
185
202
  return {
186
203
  odata: 'not(' + op.odata + ')',
187
204
  sql: 'NOT (\n\t' + op.sql + '\n)',
@@ -189,17 +206,17 @@ const createExpression = function (lhs, op, rhs) {
189
206
  };
190
207
  }
191
208
  if (rhs == null) {
192
- lhs = parseOperand(lhs);
209
+ lhs = parseOperand!(lhs);
193
210
  return {
194
211
  odata: '(' + lhs.odata + ')',
195
212
  sql: lhs.sql,
196
213
  bindings: lhs.bindings,
197
214
  };
198
215
  }
199
- lhs = parseOperand(lhs);
200
- rhs = parseOperand(rhs);
216
+ lhs = parseOperand!(lhs);
217
+ rhs = parseOperand!(rhs);
201
218
  const bindings = lhs.bindings.concat(rhs.bindings);
202
- if (['eq', 'ne'].includes(op)) {
219
+ if (op === 'eq' || op === 'ne') {
203
220
  if ([lhs.sql, rhs.sql].includes('NULL')) {
204
221
  const nullCheck = op === 'eq' ? ' IS NULL' : ' IS NOT NULL';
205
222
  if (lhs.sql === 'NULL') {
@@ -232,10 +249,10 @@ const createExpression = function (lhs, op, rhs) {
232
249
  }
233
250
  }
234
251
  } else {
235
- sql = `${lhs.sql}${sqlOps[op]} ${rhs.sql}`;
252
+ sql = `${lhs.sql}${sqlOps[op as keyof typeof sqlOps]} ${rhs.sql}`;
236
253
  }
237
254
 
238
- if (sqlOpBrackets[op]) {
255
+ if (sqlOpBrackets[op as keyof typeof sqlOpBrackets]) {
239
256
  sql = '(' + sql + ')';
240
257
  }
241
258
  return {
@@ -244,43 +261,44 @@ const createExpression = function (lhs, op, rhs) {
244
261
  bindings,
245
262
  };
246
263
  };
247
- const createMethodCall = function (method, ...args) {
248
- args = args.map((arg) => parseOperand(arg));
249
- const odata = method + '(' + args.map((arg) => arg.odata).join(',') + ')';
264
+ const createMethodCall = function (method: string, ...args: Operand[]) {
265
+ const parsedArgs = args.map((arg) => parseOperand!(arg));
266
+ const odata =
267
+ method + '(' + parsedArgs.map((arg) => arg.odata).join(',') + ')';
250
268
  method = method.toUpperCase();
251
269
  switch (method) {
252
270
  case 'CONTAINS':
253
271
  case 'SUBSTRINGOF':
254
272
  if (method === 'SUBSTRINGOF') {
255
- args.reverse();
273
+ parsedArgs.reverse();
256
274
  }
257
275
  return {
258
- sql: `${args[0].sql} LIKE ('%' || REPLACE(REPLACE(REPLACE(${args[1].sql}, '\\', '\\\\'), '_', '\\_'), '%', '\\%') || '%')`,
259
- bindings: [...args[0].bindings, ...args[1].bindings],
276
+ sql: `${parsedArgs[0].sql} LIKE ('%' || REPLACE(REPLACE(REPLACE(${parsedArgs[1].sql}, '\\', '\\\\'), '_', '\\_'), '%', '\\%') || '%')`,
277
+ bindings: [...parsedArgs[0].bindings, ...parsedArgs[1].bindings],
260
278
  odata,
261
279
  };
262
280
  case 'STARTSWITH':
263
281
  return {
264
- sql: `STARTS_WITH(${args[0].sql}, ${args[1].sql})`,
265
- bindings: [...args[0].bindings, ...args[1].bindings],
282
+ sql: `STARTS_WITH(${parsedArgs[0].sql}, ${parsedArgs[1].sql})`,
283
+ bindings: [...parsedArgs[0].bindings, ...parsedArgs[1].bindings],
266
284
  odata,
267
285
  };
268
286
  case 'ENDSWITH':
269
287
  return {
270
- sql: `${args[0].sql} LIKE ('%' || REPLACE(REPLACE(REPLACE(${args[1].sql}, '\\', '\\\\'), '_', '\\_'), '%', '\\%'))`,
271
- bindings: [...args[0].bindings, ...args[1].bindings],
288
+ sql: `${parsedArgs[0].sql} LIKE ('%' || REPLACE(REPLACE(REPLACE(${parsedArgs[1].sql}, '\\', '\\\\'), '_', '\\_'), '%', '\\%'))`,
289
+ bindings: [...parsedArgs[0].bindings, ...parsedArgs[1].bindings],
272
290
  odata,
273
291
  };
274
292
  case 'CONCAT':
275
293
  return {
276
- sql: '(' + args.map((arg) => arg.sql).join(' || ') + ')',
277
- bindings: _.flatten(args.map((arg) => arg.bindings)),
294
+ sql: '(' + parsedArgs.map((arg) => arg.sql).join(' || ') + ')',
295
+ bindings: _.flatten(parsedArgs.map((arg) => arg.bindings)),
278
296
  odata,
279
297
  };
280
298
  case 'INDEXOF':
281
299
  return {
282
- sql: 'STRPOS(' + args.map((arg) => arg.sql).join(', ') + ') - 1',
283
- bindings: _.flatten(args.map((arg) => arg.bindings)),
300
+ sql: 'STRPOS(' + parsedArgs.map((arg) => arg.sql).join(', ') + ') - 1',
301
+ bindings: _.flatten(parsedArgs.map((arg) => arg.bindings)),
284
302
  odata,
285
303
  };
286
304
  case 'NOW':
@@ -295,60 +313,66 @@ const createMethodCall = function (method, ...args) {
295
313
  case 'HOUR':
296
314
  case 'MINUTE':
297
315
  return {
298
- sql: `EXTRACT('${method}' FROM DATE_TRUNC('milliseconds', ${args[0].sql}))`,
299
- bindings: args[0].bindings,
316
+ sql: `EXTRACT('${method}' FROM DATE_TRUNC('milliseconds', ${parsedArgs[0].sql}))`,
317
+ bindings: parsedArgs[0].bindings,
300
318
  odata,
301
319
  };
302
320
  case 'SECOND':
303
321
  return {
304
- sql: `FLOOR(EXTRACT('${method}' FROM DATE_TRUNC('milliseconds', ${args[0].sql})))`,
305
- bindings: args[0].bindings,
322
+ sql: `FLOOR(EXTRACT('${method}' FROM DATE_TRUNC('milliseconds', ${parsedArgs[0].sql})))`,
323
+ bindings: parsedArgs[0].bindings,
306
324
  odata,
307
325
  };
308
326
  case 'FRACTIONALSECONDS':
309
327
  return {
310
- sql: `EXTRACT('SECOND' FROM DATE_TRUNC('milliseconds', ${args[0].sql})) - FLOOR(EXTRACT('SECOND' FROM DATE_TRUNC('milliseconds', ${args[0].sql})))`,
311
- bindings: args[0].bindings,
328
+ sql: `EXTRACT('SECOND' FROM DATE_TRUNC('milliseconds', ${parsedArgs[0].sql})) - FLOOR(EXTRACT('SECOND' FROM DATE_TRUNC('milliseconds', ${parsedArgs[0].sql})))`,
329
+ bindings: parsedArgs[0].bindings,
312
330
  odata,
313
331
  };
314
332
  case 'TIME':
315
333
  return {
316
- sql: `CAST(DATE_TRUNC('milliseconds', ${args[0].sql}) AS ${method})`,
317
- bindings: args[0].bindings,
334
+ sql: `CAST(DATE_TRUNC('milliseconds', ${parsedArgs[0].sql}) AS ${method})`,
335
+ bindings: parsedArgs[0].bindings,
318
336
  odata,
319
337
  };
320
338
  case 'TOTALSECONDS':
321
339
  return {
322
- sql: `EXTRACT(EPOCH FROM ${args[0].sql})`,
323
- bindings: args[0].bindings,
340
+ sql: `EXTRACT(EPOCH FROM ${parsedArgs[0].sql})`,
341
+ bindings: parsedArgs[0].bindings,
324
342
  odata,
325
343
  };
326
344
  case 'DATE':
327
345
  return {
328
- sql: `DATE(DATE_TRUNC('milliseconds', ${args[0].sql}))`,
329
- bindings: args[0].bindings,
346
+ sql: `DATE(DATE_TRUNC('milliseconds', ${parsedArgs[0].sql}))`,
347
+ bindings: parsedArgs[0].bindings,
330
348
  odata,
331
349
  };
332
350
  default: {
333
351
  if (Object.prototype.hasOwnProperty.call(methodMaps, method)) {
334
- method = methodMaps[method];
352
+ method = methodMaps[method as keyof typeof methodMaps];
335
353
  }
336
354
  switch (method) {
337
355
  case 'SUBSTRING':
338
- args[1].sql += ' + 1';
356
+ parsedArgs[1].sql += ' + 1';
339
357
  break;
340
358
  }
341
- const sql = method + '(' + args.map((arg) => arg.sql).join(', ') + ')';
359
+ const sql =
360
+ method + '(' + parsedArgs.map((arg) => arg.sql).join(', ') + ')';
342
361
  return {
343
362
  sql,
344
- bindings: _.flatten(args.map((arg) => arg.bindings)),
363
+ bindings: _.flatten(parsedArgs.map((arg) => arg.bindings)),
345
364
  odata,
346
365
  };
347
366
  }
348
367
  }
349
368
  };
350
369
 
351
- const operandTest = (lhs, op, rhs, override) => {
370
+ const operandTest = (
371
+ lhs: Operand,
372
+ op?: Operand,
373
+ rhs?: Operand,
374
+ override?: Partial<ParsedOperand>,
375
+ ) => {
352
376
  run(function () {
353
377
  let from;
354
378
  let { odata, sql, bindings } = createExpression(lhs, op, rhs);
@@ -392,7 +416,7 @@ WHERE ${sql}`,
392
416
  });
393
417
  };
394
418
 
395
- const methodTest = (...args) => {
419
+ const methodTest = (...args: [method: string, ...Operand[]]) => {
396
420
  run(function () {
397
421
  const { odata, sql, bindings } = createMethodCall(...args);
398
422
  test(`/pilot?$filter=${odata}`, 'GET', bindings, (result, sqlEquals) => {
@@ -566,7 +590,7 @@ WHERE ${sql}`,
566
590
  });
567
591
 
568
592
  run(function () {
569
- const { odata: keyOdata, bindings: keyBindings } = parseOperand(1);
593
+ const { odata: keyOdata, bindings: keyBindings } = parseOperand!(1);
570
594
  const { odata, bindings } = createExpression('can_fly__plane/id', 'eq', 10);
571
595
  test(
572
596
  '/pilot(' + keyOdata + ')/can_fly__plane?$filter=' + odata,
@@ -600,8 +624,8 @@ run(function () {
600
624
  10,
601
625
  );
602
626
  const name = 'Peter';
603
- const bodyBindings = [['Bind', ['pilot', 'name']], ...bindings];
604
- const insertTest = (result, sqlEquals) => {
627
+ const bodyBindings = [['Bind', ['pilot', 'name']], ...bindings] as const;
628
+ const insertTest: ExpectationSuccessFn = (result, sqlEquals) => {
605
629
  sqlEquals(
606
630
  result,
607
631
  `\
@@ -685,11 +709,11 @@ ${updateWhere}`,
685
709
  expect(result).to.be.an('array');
686
710
  });
687
711
  it('that inserts', () => {
688
- insertTest(result[0], sqlEquals);
712
+ insertTest((result as SqlResult[])[0], sqlEquals);
689
713
  });
690
714
  it('and updates', () => {
691
715
  sqlEquals(
692
- result[1].query,
716
+ (result as SqlResult[])[1],
693
717
  `\
694
718
  UPDATE "pilot"
695
719
  SET "created at" = DEFAULT,
@@ -736,11 +760,10 @@ run(function () {
736
760
  sql,
737
761
  bindings: exprBindings,
738
762
  } = createExpression('name', 'eq', `'${name}'`);
739
- const bindings = [['Bind', ['pilot', 'name']], ...exprBindings];
740
763
  test(
741
764
  `/pilot?$filter=${odata}`,
742
765
  'POST',
743
- bindings,
766
+ [['Bind', ['pilot', 'name']], ...exprBindings],
744
767
  { name },
745
768
  (result, sqlEquals) => {
746
769
  it(`should insert into pilot where '${odata}'`, () => {
@@ -767,20 +790,24 @@ WHERE EXISTS (
767
790
 
768
791
  run(function () {
769
792
  const name = 'Peter';
770
- const { odata: keyOdata, bindings: keyBindings } = parseOperand(1);
793
+ const { odata: keyOdata, bindings: keyBindings } = parseOperand!(1);
771
794
  const {
772
795
  odata,
773
796
  sql,
774
797
  bindings: exprBindings,
775
798
  } = createExpression('name', 'eq', `'${name}'`);
776
- const bodyBindings = [['Bind', ['pilot', 'name']]];
799
+ const bodyBindings = [['Bind', ['pilot', 'name']]] as const;
777
800
  const insertBindings = [
778
801
  ['Bind', ['pilot', 'id']],
779
802
  ...bodyBindings,
780
803
  ...exprBindings,
781
804
  ...keyBindings,
782
- ];
783
- const updateBindings = [...bodyBindings, ...keyBindings, ...exprBindings];
805
+ ] as const;
806
+ const updateBindings = [
807
+ ...bodyBindings,
808
+ ...keyBindings,
809
+ ...exprBindings,
810
+ ] as const;
784
811
  test(
785
812
  '/pilot(' + keyOdata + ')?$filter=' + odata,
786
813
  'PATCH',
@@ -816,7 +843,7 @@ AND "pilot"."id" IN ((
816
843
  });
817
844
  it('that inserts', () => {
818
845
  sqlEquals(
819
- result[0].query,
846
+ (result as SqlResult[])[0],
820
847
  `\
821
848
  INSERT INTO "pilot" ("id", "name")
822
849
  SELECT "$insert"."id", "$insert"."name"
@@ -835,7 +862,7 @@ WHERE EXISTS (
835
862
  });
836
863
  it('and updates', () => {
837
864
  sqlEquals(
838
- result[1].query,
865
+ (result as SqlResult[])[1],
839
866
  `\
840
867
  UPDATE "pilot"
841
868
  SET "created at" = DEFAULT,
@@ -864,7 +891,7 @@ AND "pilot"."id" IN ((
864
891
  });
865
892
 
866
893
  run(function () {
867
- const { odata: keyOdata, bindings: keyBindings } = parseOperand(1);
894
+ const { odata: keyOdata, bindings: keyBindings } = parseOperand!(1);
868
895
  const { odata, bindings, sql } = createExpression(
869
896
  createExpression(1, 'eq', 1),
870
897
  'or',
@@ -1442,14 +1469,13 @@ WHERE CURRENT_TIMESTAMP - DATE_TRUNC('milliseconds', "pilot"."created at") < INT
1442
1469
 
1443
1470
  run(function () {
1444
1471
  const odata = 'now() add now()';
1445
- test.fail(`/pilot?$filter=${odata}`, 'GET', [], (result, sqlEquals) => {
1472
+ test.fail(`/pilot?$filter=${odata}`, 'GET', [], (err) => {
1446
1473
  it(
1447
1474
  'should fail to add current_timestamp to current_timestamp where "' +
1448
1475
  odata +
1449
1476
  '"',
1450
1477
  () => {
1451
- expect(result).to.be.empty;
1452
- expect(sqlEquals).to.be.undefined;
1478
+ expect(err).to.be.instanceOf(Error);
1453
1479
  },
1454
1480
  );
1455
1481
  });
@@ -1,4 +1,5 @@
1
1
  import { expect } from 'chai';
2
+ import type { ExpectationSuccessFn } from './test';
2
3
  import test from './test';
3
4
  import * as ODataParser from '@balena/odata-parser';
4
5
  import {
@@ -9,6 +10,7 @@ import {
9
10
  aliasPilotLicenceFields,
10
11
  aliasLicenceFields,
11
12
  } from './fields';
13
+ import type { SqlResult } from '../../src/AbstractSQLRules2SQL';
12
14
  const aliasPilotFields = aliasFields(
13
15
  'plane.pilot-can fly-plane.pilot',
14
16
  pilotFields,
@@ -151,7 +153,7 @@ test(
151
153
  (result, sqlEquals) => {
152
154
  it('should insert/update the pilot with id 1', () => {
153
155
  sqlEquals(
154
- result[0].query,
156
+ (result as SqlResult[])[0],
155
157
  `\
156
158
  INSERT INTO "pilot" ("id")
157
159
  SELECT "$insert"."id"
@@ -167,7 +169,7 @@ WHERE EXISTS (
167
169
  )`,
168
170
  );
169
171
  sqlEquals(
170
- result[1].query,
172
+ (result as SqlResult[])[1],
171
173
  `\
172
174
  UPDATE "pilot"
173
175
  SET "created at" = DEFAULT,
@@ -214,12 +216,11 @@ INSERT INTO "pilot" DEFAULT VALUES`,
214
216
  });
215
217
 
216
218
  (function () {
217
- // prettier-ignore
218
- const bindings = /** @type {const} */ ([
219
+ const bindings = [
219
220
  ['Bind', ['pilot', 'is_experienced']],
220
221
  ['Bind', 0],
221
- ]);
222
- const testFunc = (result, sqlEquals) => {
222
+ ] as const;
223
+ const testFunc: ExpectationSuccessFn = (result, sqlEquals) => {
223
224
  it('should update the pilot with id 1', () => {
224
225
  sqlEquals(
225
226
  result,
@@ -266,7 +267,7 @@ test(
266
267
  (result, sqlEquals) => {
267
268
  it('should insert/update the pilot-can fly-plane with id 1', () => {
268
269
  sqlEquals(
269
- result[0].query,
270
+ (result as SqlResult[])[0],
270
271
  `\
271
272
  INSERT INTO "pilot-can fly-plane" ("id")
272
273
  SELECT "$insert"."id"
@@ -282,7 +283,7 @@ WHERE EXISTS (
282
283
  )`,
283
284
  );
284
285
  sqlEquals(
285
- result[1].query,
286
+ (result as SqlResult[])[1],
286
287
  `\
287
288
  UPDATE "pilot-can fly-plane"
288
289
  SET "created at" = DEFAULT,
@@ -325,12 +326,11 @@ INSERT INTO "pilot-can fly-plane" DEFAULT VALUES`,
325
326
  });
326
327
 
327
328
  (function () {
328
- // prettier-ignore
329
- const bindings = /** @type {const} */ ([
329
+ const bindings = [
330
330
  ['Bind', ['pilot-can fly-plane', 'pilot']],
331
331
  ['Bind', 0],
332
- ]);
333
- const testFunc = (result, sqlEquals) => {
332
+ ] as const;
333
+ const testFunc: ExpectationSuccessFn = (result, sqlEquals) => {
334
334
  it('should update the pilot with id 1', () => {
335
335
  sqlEquals(
336
336
  result,
@@ -14,8 +14,7 @@ const filterBindsNandString = _.map(
14
14
  () => 'NOT(("pilot"."id") IS NOT NULL AND ("pilot"."id") = (?))',
15
15
  ).join('\nAND ');
16
16
 
17
- // prettier-ignore
18
- const filterBinds = filterIDs.map((_n, i) => /** @type {const} */ (['Bind', i]));
17
+ const filterBinds = filterIDs.map((_n, i) => ['Bind', i] as const);
19
18
 
20
19
  let filterString = `id in (${filterIDs.join(', ')})`;
21
20
  test(
@@ -79,17 +79,18 @@ const sqlEquals = {
79
79
  },
80
80
  } satisfies Record<string, SqlEquals>;
81
81
 
82
+ type ReadonlyBinding = Readonly<AbstractSQLCompiler.Binding>;
82
83
  type ExpectedBindings = ReadonlyArray<
83
- Readonly<AbstractSQLCompiler.Binding | AbstractSQLCompiler.Binding[]>
84
+ ReadonlyBinding | readonly ReadonlyBinding[]
84
85
  >;
85
86
 
86
- type ExpectationSuccessFn = (
87
+ export type ExpectationSuccessFn = (
87
88
  result:
88
89
  | AbstractSQLCompiler.SqlResult
89
90
  | [AbstractSQLCompiler.SqlResult, AbstractSQLCompiler.SqlResult],
90
91
  sqlEquals: SqlEquals,
91
92
  ) => void;
92
- type ExpectationFailFn = (result: Error) => void;
93
+ export type ExpectationFailFn = (result: Error) => void;
93
94
  type ExpectationFn<ExpectFail extends boolean> = ExpectFail extends true
94
95
  ? ExpectationFailFn
95
96
  : ExpectationSuccessFn;
@@ -1,11 +1,12 @@
1
1
  import * as fs from 'node:fs';
2
2
  const typeVocab = fs.readFileSync(
3
3
  require.resolve('@balena/sbvr-types/Type.sbvr'),
4
+ 'utf8',
4
5
  );
5
6
  import { getTestHelpers } from './test';
6
7
  const test = getTestHelpers(typeVocab);
7
8
 
8
- const modifiedAtTrigger = (tableName) => `\
9
+ const modifiedAtTrigger = (tableName: string) => `\
9
10
  DO
10
11
  $$
11
12
  BEGIN
@@ -3,9 +3,10 @@ import { getTestHelpers } from './test';
3
3
 
4
4
  const typeVocab = fs.readFileSync(
5
5
  require.resolve('@balena/sbvr-types/Type.sbvr'),
6
+ 'utf8',
6
7
  );
7
8
 
8
- const modifiedAtTrigger = (tableName) => `\
9
+ const modifiedAtTrigger = (tableName: string) => `\
9
10
  DO
10
11
  $$
11
12
  BEGIN
@@ -24,7 +25,7 @@ END;
24
25
  $$`;
25
26
 
26
27
  describe('reference type', function () {
27
- let test;
28
+ let test: ReturnType<typeof getTestHelpers>;
28
29
  beforeEach(() => {
29
30
  test = getTestHelpers(typeVocab);
30
31
  });
@@ -37,7 +38,7 @@ Term: term
37
38
  Term: term history
38
39
  Fact Type: term history references term
39
40
  Necessity: each term history references exactly one term
40
- Reference Type: informative
41
+ Reference Type: informative
41
42
  `,
42
43
  [
43
44
  `\
@@ -81,7 +82,7 @@ CREATE TABLE IF NOT EXISTS "term history" (
81
82
  Term: term
82
83
  Term: term history
83
84
  Fact Type: term history references term
84
- Reference Type: informative
85
+ Reference Type: informative
85
86
  Necessity: each term history references exactly one term
86
87
  `,
87
88
  [
@@ -4,10 +4,7 @@ import sbvrTypes from '@balena/sbvr-types';
4
4
  import { expect } from 'chai';
5
5
  import * as AbstractSQLCompiler from '../..';
6
6
 
7
- export function getTestHelpers(builtInVocab) {
8
- if (builtInVocab == null) {
9
- builtInVocab = false;
10
- }
7
+ export function getTestHelpers(builtInVocab: string | boolean = false) {
11
8
  // eslint-disable-next-line @typescript-eslint/no-var-requires
12
9
  const SBVRParser = require('@balena/sbvr-parser').SBVRParser.createInstance();
13
10
  SBVRParser.enableReusingMemoizations(SBVRParser._sideEffectingRules);
@@ -22,7 +19,11 @@ export function getTestHelpers(builtInVocab) {
22
19
 
23
20
  let seSoFar = '';
24
21
 
25
- const runExpectation = (it, input, expectation) => {
22
+ const runExpectation = (
23
+ it: Mocha.TestFunction,
24
+ input: string,
25
+ expectation: (result: AbstractSQLCompiler.SqlModel | Error) => void,
26
+ ) => {
26
27
  it(input, function () {
27
28
  let result;
28
29
  try {
@@ -30,7 +31,7 @@ export function getTestHelpers(builtInVocab) {
30
31
  const lf = SBVRParser.matchAll(seSoFar + input, 'Process');
31
32
  const schema = LF2AbstractSQLTranslator(lf, 'Process');
32
33
  result = AbstractSQLCompiler.postgres.compileSchema(schema);
33
- } catch (e) {
34
+ } catch (e: any) {
34
35
  expectation(e);
35
36
  return;
36
37
  }
@@ -38,7 +39,13 @@ export function getTestHelpers(builtInVocab) {
38
39
  });
39
40
  };
40
41
 
41
- const runSchema = (it, input, expectation) => {
42
+ const runSchema = (
43
+ it: Mocha.TestFunction,
44
+ input: string,
45
+ expectation:
46
+ | ((result: AbstractSQLCompiler.SqlModel | Error) => void)
47
+ | string[],
48
+ ) => {
42
49
  runExpectation(it, input, function (result) {
43
50
  seSoFar += input + '\n';
44
51
  if (_.isFunction(expectation)) {
@@ -57,7 +64,13 @@ export function getTestHelpers(builtInVocab) {
57
64
  });
58
65
  };
59
66
 
60
- const runRule = (it, input, expectation) => {
67
+ const runRule = (
68
+ it: Mocha.TestFunction,
69
+ input: string,
70
+ expectation:
71
+ | ((result: AbstractSQLCompiler.SqlModel | Error) => void)
72
+ | string,
73
+ ) => {
61
74
  runExpectation(it, 'Rule: ' + input, function (result) {
62
75
  if (_.isFunction(expectation)) {
63
76
  expectation(result);
package/tsconfig.json CHANGED
@@ -14,8 +14,7 @@
14
14
  "skipLibCheck": true,
15
15
  "exactOptionalPropertyTypes": true,
16
16
  "target": "es2023",
17
- "outDir": "out",
18
- "allowJs": true
17
+ "outDir": "out"
19
18
  },
20
19
  "include": [
21
20
  "src/**/*",
package/.eslintrc.js DELETED
@@ -1,12 +0,0 @@
1
- module.exports = {
2
- extends: ['./node_modules/@balena/lint/config/.eslintrc.js'],
3
- parserOptions: {
4
- project: 'tsconfig.js.json',
5
- sourceType: 'module',
6
- },
7
- env: {
8
- // TODO: Drop this once we convert all .js tests to .ts
9
- mocha: true,
10
- },
11
- root: true,
12
- };