@balena/odata-to-abstract-sql 7.1.6 → 7.1.7

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.
package/.lintstagedrc CHANGED
@@ -1,7 +1,4 @@
1
1
  {
2
- "*.js": [
3
- "balena-lint --fix"
4
- ],
5
2
  "*.ts": [
6
3
  "balena-lint --fix"
7
4
  ]
@@ -1,3 +1,71 @@
1
+ - commits:
2
+ - subject: "Tests: convert test/filterby to typescript"
3
+ hash: 92d206795a7e7f60da03a874785f364d995a2180
4
+ body: ""
5
+ footer:
6
+ Change-type: patch
7
+ change-type: patch
8
+ author: Pagan Gazzard
9
+ nested: []
10
+ - subject: "Tests: convert test/expand to typescript"
11
+ hash: 04c310f3383173b67d69af394582c48e8724feb0
12
+ body: ""
13
+ footer:
14
+ Change-type: patch
15
+ change-type: patch
16
+ author: Pagan Gazzard
17
+ nested: []
18
+ - subject: "Tests: convert test/orderby to typescript"
19
+ hash: a95840abc03109b1c719bed30b1e388c31fa69e0
20
+ body: ""
21
+ footer:
22
+ Change-type: patch
23
+ change-type: patch
24
+ author: Pagan Gazzard
25
+ nested: []
26
+ - subject: "Tests: convert test/resource_parsing to typescript"
27
+ hash: e70202afdfa112c4e182abaf8ab7ff843faf56a8
28
+ body: ""
29
+ footer:
30
+ Change-type: patch
31
+ change-type: patch
32
+ author: Pagan Gazzard
33
+ nested: []
34
+ - subject: "Tests: convert test/select to typescript"
35
+ hash: 12d873a51539f043143738fb632fb0d44952c6bc
36
+ body: ""
37
+ footer:
38
+ Change-type: patch
39
+ change-type: patch
40
+ author: Pagan Gazzard
41
+ nested: []
42
+ - subject: "Tests: convert test/paging to typescript"
43
+ hash: a74eb53a5c4f0728d5aabb6e6e9748bd6ef28a86
44
+ body: ""
45
+ footer:
46
+ Change-type: patch
47
+ change-type: patch
48
+ author: Pagan Gazzard
49
+ nested: []
50
+ - subject: "Tests: convert test/stress to typescript"
51
+ hash: 43402fa7238daa8c200781bdd42a29a409676fbc
52
+ body: ""
53
+ footer:
54
+ Change-type: patch
55
+ change-type: patch
56
+ author: Pagan Gazzard
57
+ nested: []
58
+ - subject: "Tests: convert test/chai-sql to typescript"
59
+ hash: d9d203864ef9d29f7a993c69b4951e575bf8a0c1
60
+ body: ""
61
+ footer:
62
+ Change-type: patch
63
+ change-type: patch
64
+ author: Pagan Gazzard
65
+ nested: []
66
+ version: 7.1.7
67
+ title: ""
68
+ date: 2025-04-02T14:01:23.215Z
1
69
  - commits:
2
70
  - subject: Support path expressions of resources with 0..1 cardinality in
3
71
  $select/$filter/$orderby
@@ -55,7 +123,7 @@
55
123
  nested: []
56
124
  version: 7.1.6
57
125
  title: ""
58
- date: 2025-03-28T05:44:00.263Z
126
+ date: 2025-03-28T05:47:18.848Z
59
127
  - commits:
60
128
  - subject: Fix translation of Resource -> Table when using a computed term
61
129
  hash: 1ece1c36cee6650d5ec72ba767842bb15fdcc953
@@ -1804,6 +1872,7 @@
1804
1872
 
1805
1873
 
1806
1874
 
1875
+
1807
1876
  As balena-lint
1808
1877
  rejects `new
1809
1878
  Boolean()`, `new
@@ -1831,6 +1900,7 @@
1831
1900
 
1832
1901
 
1833
1902
 
1903
+
1834
1904
  As engine and npm is
1835
1905
  now required as part
1836
1906
  of package.json we
@@ -1873,6 +1943,7 @@
1873
1943
 
1874
1944
 
1875
1945
 
1946
+
1876
1947
  Ensure that the
1877
1948
  input passed in for
1878
1949
  JSON types is either
@@ -1978,6 +2049,7 @@
1978
2049
 
1979
2050
 
1980
2051
 
2052
+
1981
2053
  This also deprecates
1982
2054
  the legacy version
1983
2055
  footer:
@@ -2011,6 +2083,7 @@
2011
2083
 
2012
2084
 
2013
2085
 
2086
+
2014
2087
  It can in fact be a
2015
2088
  lot of different
2016
2089
  things and that is
@@ -2045,6 +2118,7 @@
2045
2118
 
2046
2119
 
2047
2120
 
2121
+
2048
2122
  We know what type
2049
2123
  they return and they
2050
2124
  should be explicitly
@@ -2084,6 +2158,7 @@
2084
2158
 
2085
2159
 
2086
2160
 
2161
+
2087
2162
  Update
2088
2163
  @balena/sbvr-types
2089
2164
  from 3.4.18 to 3.5.0
@@ -2234,6 +2309,7 @@
2234
2309
 
2235
2310
 
2236
2311
 
2312
+
2237
2313
  This also deprecates
2238
2314
  the legacy use of
2239
2315
  direct true/false
package/CHANGELOG.md CHANGED
@@ -4,6 +4,17 @@ All notable changes to this project will be documented in this file
4
4
  automatically by Versionist. DO NOT EDIT THIS FILE MANUALLY!
5
5
  This project adheres to [Semantic Versioning](http://semver.org/).
6
6
 
7
+ ## 7.1.7 - 2025-04-02
8
+
9
+ * Tests: convert test/filterby to typescript [Pagan Gazzard]
10
+ * Tests: convert test/expand to typescript [Pagan Gazzard]
11
+ * Tests: convert test/orderby to typescript [Pagan Gazzard]
12
+ * Tests: convert test/resource_parsing to typescript [Pagan Gazzard]
13
+ * Tests: convert test/select to typescript [Pagan Gazzard]
14
+ * Tests: convert test/paging to typescript [Pagan Gazzard]
15
+ * Tests: convert test/stress to typescript [Pagan Gazzard]
16
+ * Tests: convert test/chai-sql to typescript [Pagan Gazzard]
17
+
7
18
  ## 7.1.6 - 2025-03-28
8
19
 
9
20
 
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@balena/odata-to-abstract-sql",
3
- "version": "7.1.6",
3
+ "version": "7.1.7",
4
4
  "description": "A consumer of the OData parser, written in OMeta",
5
5
  "type": "commonjs",
6
6
  "main": "out/odata-to-abstract-sql.js",
7
7
  "scripts": {
8
- "lint": "balena-lint -e js -e ts src test && tsc --noEmit && tsc --noEmit --project tsconfig.js.json",
9
- "lint-fix": "balena-lint -e js -e ts --fix src test",
8
+ "lint": "balena-lint src test && tsc --noEmit && tsc --noEmit --project tsconfig.js.json",
9
+ "lint-fix": "balena-lint --fix src test",
10
10
  "pretest": "npm run prepare",
11
11
  "test": "mocha && npm run lint",
12
12
  "prepublish": "require-npm4-to-publish",
@@ -47,13 +47,14 @@
47
47
  "recursive": true,
48
48
  "require": "ts-node/register/transpile-only",
49
49
  "bail": true,
50
- "_": "test/*.js"
50
+ "exclude": "test/**/*.d.ts",
51
+ "_": "test/**/*.ts"
51
52
  },
52
53
  "engines": {
53
54
  "node": ">=20.14.0",
54
55
  "npm": ">=10.7.0"
55
56
  },
56
57
  "versionist": {
57
- "publishedAt": "2025-03-28T05:44:01.363Z"
58
+ "publishedAt": "2025-04-02T14:01:23.667Z"
58
59
  }
59
60
  }
@@ -5,6 +5,19 @@ import fs from 'fs';
5
5
  import { createTranslator } from '@balena/lf-to-abstract-sql';
6
6
  import { SBVRParser } from '@balena/sbvr-parser';
7
7
  import sbvrTypes from '@balena/sbvr-types';
8
+ import type {
9
+ AliasNode,
10
+ BindNode,
11
+ BooleanNode,
12
+ CountNode,
13
+ DateNode,
14
+ DateTruncNode,
15
+ DurationNode,
16
+ NullNode,
17
+ NumberNode,
18
+ ReferencedFieldNode,
19
+ TextNode,
20
+ } from '@balena/abstract-sql-compiler';
8
21
 
9
22
  chai.use(chaiThings);
10
23
 
@@ -15,12 +28,12 @@ chai.use(function ($chai, utils) {
15
28
  const obj = utils.flag(this, 'object');
16
29
  return expect(obj).to.be.an.instanceof(Array);
17
30
  });
18
- const queryType = (type) =>
31
+ const queryType = (type: string) =>
19
32
  function () {
20
33
  const obj = utils.flag(this, 'object');
21
34
  return expect(obj).to.contain.something.that.equals(type);
22
35
  };
23
- const bodyClause = (bodyType) =>
36
+ const bodyClause = (bodyType: string) =>
24
37
  function (...bodyClauses) {
25
38
  const obj = utils.flag(this, 'object');
26
39
  if (bodyClauses.length === 0) {
@@ -39,7 +52,7 @@ chai.use(function ($chai, utils) {
39
52
  }
40
53
  return this;
41
54
  };
42
- const multiBodyClause = (bodyType) =>
55
+ const multiBodyClause = (bodyType: string) =>
43
56
  function (...bodyClauses) {
44
57
  const obj = utils.flag(this, 'object');
45
58
  expect(obj).to.contain.something.that.deep.equals(
@@ -48,7 +61,7 @@ chai.use(function ($chai, utils) {
48
61
  );
49
62
  return this;
50
63
  };
51
- const binaryClause = (bodyType) =>
64
+ const binaryClause = (bodyType: string) =>
52
65
  function (...bodyClauses) {
53
66
  const obj = utils.flag(this, 'object');
54
67
  for (let i = 0; i < bodyClauses.length; i++) {
@@ -112,7 +125,7 @@ chai.use(function ($chai, utils) {
112
125
  utils.addMethod(assertionPrototype, 'offset', bodyClause('Offset'));
113
126
  });
114
127
 
115
- const generateClientModel = function (input) {
128
+ const generateClientModel = function (input: string) {
116
129
  const typeVocab = fs.readFileSync(
117
130
  require.resolve('@balena/sbvr-types/Type.sbvr'),
118
131
  'utf8',
@@ -149,25 +162,36 @@ clientModel.tables['copilot'].fields.push({
149
162
  computed: ['Text', 'Junior'],
150
163
  });
151
164
 
152
- const odataNameToSqlName = (odataName) =>
165
+ const odataNameToSqlName = (odataName: string) =>
153
166
  odataName.replace(/__/g, '-').replace(/_/g, ' ');
154
167
 
155
- export function sqlNameToOdataName(sqlName) {
168
+ export function sqlNameToOdataName(sqlName: string) {
156
169
  return sqlName.replace(/-/g, '__').replace(/ /g, '_');
157
170
  }
158
171
 
172
+ type AbstractSqlBind =
173
+ | BindNode
174
+ | NullNode
175
+ | DateTruncNode
176
+ | ReferencedFieldNode
177
+ | DurationNode;
159
178
  export function operandToAbstractSQLFactory(
160
- binds = [],
179
+ binds: Array<BooleanNode | NumberNode | DateNode | NullNode | TextNode> = [],
161
180
  defaultResource = 'pilot',
162
181
  defaultParentAlias = defaultResource,
163
182
  ) {
164
- let operandToAbstractSQL;
165
- return (operandToAbstractSQL = function (
166
- operand,
183
+ const operandToAbstractSQL = function (
184
+ operand:
185
+ | string
186
+ | number
187
+ | boolean
188
+ | Date
189
+ | [string, string, string]
190
+ | { abstractsql: AbstractSqlBind },
167
191
  resource = defaultResource,
168
192
  parentAlias = defaultParentAlias,
169
- ) {
170
- if (operand.abstractsql != null) {
193
+ ): AbstractSqlBind | AbstractSqlBind[] {
194
+ if (typeof operand === 'object' && 'abstractsql' in operand) {
171
195
  return operand.abstractsql;
172
196
  }
173
197
  if (typeof operand === 'boolean') {
@@ -183,7 +207,6 @@ export function operandToAbstractSQLFactory(
183
207
  return ['Bind', binds.length - 1];
184
208
  }
185
209
  if (typeof operand === 'string') {
186
- let mapping;
187
210
  if (operand === 'null') {
188
211
  return ['Null'];
189
212
  }
@@ -191,13 +214,13 @@ export function operandToAbstractSQLFactory(
191
214
  return operand
192
215
  .slice(1, -1)
193
216
  .split(',')
194
- .map(function (op) {
217
+ .map(function (op): AbstractSqlBind {
195
218
  const n = parseInt(op, 10);
196
219
  if (Number.isFinite(n)) {
197
- return operandToAbstractSQL(n);
220
+ return operandToAbstractSQL(n) as AbstractSqlBind;
198
221
  }
199
222
 
200
- return operandToAbstractSQL(op);
223
+ return operandToAbstractSQL(op) as AbstractSqlBind;
201
224
  });
202
225
  }
203
226
 
@@ -208,6 +231,7 @@ export function operandToAbstractSQLFactory(
208
231
  ]);
209
232
  return ['Bind', binds.length - 1];
210
233
  }
234
+ let mapping;
211
235
  const fieldParts = operand.split('/');
212
236
  if (fieldParts.length > 1) {
213
237
  let alias = parentAlias;
@@ -241,10 +265,10 @@ export function operandToAbstractSQLFactory(
241
265
  return [
242
266
  'DateTrunc',
243
267
  ['EmbeddedText', 'milliseconds'],
244
- ['ReferencedField'].concat(mapping),
268
+ ['ReferencedField', ...mapping] as ReferencedFieldNode,
245
269
  ];
246
270
  }
247
- return ['ReferencedField'].concat(mapping);
271
+ return ['ReferencedField', ...mapping] as ReferencedFieldNode;
248
272
  }
249
273
  if (Array.isArray(operand)) {
250
274
  return operandToAbstractSQL(...operand);
@@ -253,10 +277,11 @@ export function operandToAbstractSQLFactory(
253
277
  return ['Duration', operand];
254
278
  }
255
279
  throw new Error('Unknown operand type: ' + operand);
256
- });
280
+ };
281
+ return operandToAbstractSQL;
257
282
  }
258
283
 
259
- export const operandToOData = function (operand) {
284
+ export const operandToOData = function (operand): string {
260
285
  if (operand.odata != null) {
261
286
  return operand.odata;
262
287
  }
@@ -267,7 +292,7 @@ export const operandToOData = function (operand) {
267
292
  return operandToOData(operand[0]);
268
293
  }
269
294
  if (operand !== null && typeof operand === 'object') {
270
- const duration = [];
295
+ const duration: string[] = [];
271
296
  let t = false;
272
297
  if (operand.negative) {
273
298
  duration.push('-');
@@ -302,7 +327,7 @@ export const operandToOData = function (operand) {
302
327
  return operand;
303
328
  };
304
329
 
305
- export const shortenAlias = function (alias) {
330
+ export const shortenAlias = function (alias: string) {
306
331
  while (alias.length >= 64) {
307
332
  alias = alias
308
333
  .replace(/(^|[^-])pilot/, '$1pi')
@@ -312,7 +337,11 @@ export const shortenAlias = function (alias) {
312
337
  };
313
338
 
314
339
  export const aliasFields = (function () {
315
- const aliasField = function (resourceAlias, verb, field) {
340
+ const aliasField = function (
341
+ resourceAlias: string,
342
+ verb: string,
343
+ field: Fields[number],
344
+ ): Fields[number] {
316
345
  if (field[0] === 'ReferencedField') {
317
346
  return [
318
347
  field[0],
@@ -321,12 +350,16 @@ export const aliasFields = (function () {
321
350
  ];
322
351
  }
323
352
  if (field[0] === 'Alias') {
324
- return ['Alias', aliasField(resourceAlias, verb, field[1]), field[2]];
353
+ return [
354
+ 'Alias',
355
+ aliasField(resourceAlias, verb, field[1]) as ReferencedFieldNode,
356
+ field[2],
357
+ ];
325
358
  } else {
326
359
  return field;
327
360
  }
328
361
  };
329
- return function (resourceAlias, fields, verb) {
362
+ return function (resourceAlias: string, fields: Fields, verb?: string) {
330
363
  if (verb != null) {
331
364
  verb = verb + '-';
332
365
  } else {
@@ -336,7 +369,9 @@ export const aliasFields = (function () {
336
369
  };
337
370
  })();
338
371
 
339
- export const pilotFields = [
372
+ type Fields = Array<ReferencedFieldNode | AliasNode<ReferencedFieldNode>>;
373
+
374
+ export const pilotFields: Fields = [
340
375
  ['Alias', ['ReferencedField', 'pilot', 'created at'], 'created_at'],
341
376
  ['Alias', ['ReferencedField', 'pilot', 'modified at'], 'modified_at'],
342
377
  ['ReferencedField', 'pilot', 'id'],
@@ -359,21 +394,21 @@ export const pilotFields = [
359
394
  ],
360
395
  ];
361
396
 
362
- export const licenceFields = [
397
+ export const licenceFields: Fields = [
363
398
  ['Alias', ['ReferencedField', 'licence', 'created at'], 'created_at'],
364
399
  ['Alias', ['ReferencedField', 'licence', 'modified at'], 'modified_at'],
365
400
  ['ReferencedField', 'licence', 'id'],
366
401
  ['ReferencedField', 'licence', 'name'],
367
402
  ];
368
403
 
369
- export const planeFields = [
404
+ export const planeFields: Fields = [
370
405
  ['Alias', ['ReferencedField', 'plane', 'created at'], 'created_at'],
371
406
  ['Alias', ['ReferencedField', 'plane', 'modified at'], 'modified_at'],
372
407
  ['ReferencedField', 'plane', 'id'],
373
408
  ['ReferencedField', 'plane', 'name'],
374
409
  ];
375
410
 
376
- export const pilotCanFlyPlaneFields = [
411
+ export const pilotCanFlyPlaneFields: Fields = [
377
412
  [
378
413
  'Alias',
379
414
  ['ReferencedField', 'pilot-can fly-plane', 'created at'],
@@ -393,7 +428,7 @@ export const pilotCanFlyPlaneFields = [
393
428
  ['ReferencedField', 'pilot-can fly-plane', 'id'],
394
429
  ];
395
430
 
396
- export const teamFields = [
431
+ export const teamFields: Fields = [
397
432
  ['Alias', ['ReferencedField', 'team', 'created at'], 'created_at'],
398
433
  ['Alias', ['ReferencedField', 'team', 'modified at'], 'modified_at'],
399
434
  [
@@ -403,9 +438,11 @@ export const teamFields = [
403
438
  ],
404
439
  ];
405
440
 
406
- export const $count = [['Alias', ['Count', '*'], '$count']];
441
+ export const $count: [AliasNode<CountNode>] = [
442
+ ['Alias', ['Count', '*'], '$count'],
443
+ ];
407
444
 
408
- export const copilotFields = [
445
+ export const copilotFields: Fields = [
409
446
  ['Alias', ['ReferencedField', 'copilot', 'created at'], 'created_at'],
410
447
  ['Alias', ['ReferencedField', 'copilot', 'modified at'], 'modified_at'],
411
448
  ['ReferencedField', 'copilot', 'id'],
@@ -557,10 +557,6 @@ test('/pilot?$expand=licence/$count($top=5)', (result) => {
557
557
  // Alias tests
558
558
  (function () {
559
559
  const remainingPilotFields = _.reject(pilotFields, function (field) {
560
- if (field.length === 2) {
561
- // @ts-expect-error Assign field with stil valid AbstractSql
562
- field = field[1];
563
- }
564
560
  return field[2] === 'pilot';
565
561
  });
566
562
  const recursions = 9;
@@ -16,11 +16,11 @@ let operandToAbstractSQLFactory = $operandToAbstractSQLFactory;
16
16
  import test from './test';
17
17
  import _ from 'lodash';
18
18
 
19
- let operandToAbstractSQL = null;
19
+ let operandToAbstractSQL: ReturnType<typeof operandToAbstractSQLFactory>;
20
20
 
21
21
  const run = (function () {
22
22
  let running = false;
23
- return function (keyBinds, fn) {
23
+ return function (keyBinds, fn?) {
24
24
  if (fn == null) {
25
25
  fn = keyBinds;
26
26
  keyBinds = [];
@@ -99,7 +99,7 @@ const createMethodCall = function (method, ...args) {
99
99
  method +
100
100
  '(' +
101
101
  (() => {
102
- const result = [];
102
+ const result: string[] = [];
103
103
  for (arg of args) {
104
104
  result.push(operandToOData(arg));
105
105
  }
@@ -125,7 +125,7 @@ const createMethodCall = function (method, ...args) {
125
125
  };
126
126
  };
127
127
 
128
- const operandTest = (lhs, op, rhs) =>
128
+ const operandTest = (lhs, op?, rhs?) =>
129
129
  run(function () {
130
130
  const { odata, abstractsql } = createExpression(lhs, op, rhs);
131
131
  test('/pilot?$filter=' + odata, (result) => {
@@ -230,7 +230,7 @@ test(`/pilot?$filter=startswith(p/name,'test1')`, (result) => {
230
230
  });
231
231
  });
232
232
 
233
- const navigatedOperandTest = (lhs, op, rhs) => {
233
+ const navigatedOperandTest = (lhs, op?, rhs?) => {
234
234
  run(function () {
235
235
  const { odata, abstractsql } = createExpression(lhs, op, rhs);
236
236
  test('/pilot?$filter=' + odata, (result) => {
@@ -268,10 +268,10 @@ const navigatedOperandTest = (lhs, op, rhs) => {
268
268
  });
269
269
  };
270
270
 
271
- const methodTest = (...args) =>
271
+ const methodTest = (...args: Parameters<typeof createMethodCall>) =>
272
272
  run(() => operandTest(createMethodCall(...args)));
273
273
 
274
- const navigatedMethodTest = (...args) =>
274
+ const navigatedMethodTest = (...args: Parameters<typeof createMethodCall>) =>
275
275
  run(() => {
276
276
  navigatedOperandTest(createMethodCall(...args));
277
277
  });
@@ -9,8 +9,8 @@ import _ from 'lodash';
9
9
 
10
10
  const operandToAbstractSQL = operandToAbstractSQLFactory();
11
11
 
12
- const pilotName = _.filter(pilotFields, { 2: 'name' })[0];
13
- const pilotAge = _.filter(pilotFields, { 2: 'age' })[0];
12
+ const pilotName = pilotFields.filter((field) => field[2] === 'name')[0];
13
+ const pilotAge = pilotFields.filter((field) => field[2] === 'age')[0];
14
14
  test('/pilot?$select=name', (result) => {
15
15
  it('should select name from pilot', () => {
16
16
  expect(result).to.be.a.query.that.selects([pilotName]).from('pilot');
package/tsconfig.js.json CHANGED
@@ -3,12 +3,11 @@
3
3
  "compilerOptions": {
4
4
  "noImplicitAny": false,
5
5
  "noImplicitThis": false,
6
- "strictFunctionTypes": false,
7
- "checkJs": true
6
+ "strictFunctionTypes": false
8
7
  },
9
8
  "include": [
10
9
  "*",
11
- "src/*",
10
+ "src/**/*",
12
11
  "test/**/*"
13
12
  ],
14
13
  }
package/tsconfig.json CHANGED
@@ -11,8 +11,7 @@
11
11
  "sourceMap": true,
12
12
  "declaration": true,
13
13
  "skipLibCheck": true,
14
- "outDir": "out",
15
- "allowJs": true
14
+ "outDir": "out"
16
15
  },
17
16
  "include": ["src/**/*"],
18
17
  "exclude": ["node_modules"]
File without changes
File without changes
File without changes